/** * Clarifies array dimensions if this defines implicitly sized array by initializer. Does nothing * otherwise. */ private GLSLType clarifyArrayType(GLSLType baseType) { if (!(baseType instanceof GLSLArrayType)) return baseType; // No need to clarify non-array types final GLSLArrayType myArrayType = (GLSLArrayType) baseType; final int[] myDimensions = myArrayType.getDimensions(); { // Try clarifying using initializer list GLSLInitializer rawInitializer = getInitializer(); if (rawInitializer != null && rawInitializer instanceof GLSLInitializerList) { // Clarify using initializer list GLSLInitializerList initializerList = (GLSLInitializerList) rawInitializer; for (int i = 0; i < myDimensions.length; i++) { GLSLInitializer[] initializers = initializerList.getInitializers(); if (myDimensions[i] == GLSLArrayType.UNDEFINED_SIZE_DIMENSION) { // Can clarify that! myDimensions[i] = initializers.length; } if (initializers.length >= 1 && initializers[0] instanceof GLSLInitializerList) { initializerList = (GLSLInitializerList) initializers[0]; } else { // Can't clarify any more break; } } return baseType; // Dimensions are changed in place, so no need to create new instance } } { // Try clarifying using expression GLSLExpression rawExpression = getInitializerExpression(); if (rawExpression != null) { GLSLType type = rawExpression.getType(); if (type instanceof GLSLArrayType) { GLSLArrayType arrayType = (GLSLArrayType) type; // Great, it is being correctly initialized, try to copy as many missing dimensions as we // can final int[] dimensions = arrayType.getDimensions(); for (int i = 0; i < myDimensions.length && i < dimensions.length; i++) { if (myDimensions[i] == GLSLArrayType.UNDEFINED_SIZE_DIMENSION) { // Copy that myDimensions[i] = dimensions[i]; } } return baseType; // Dimensions are changed in place, so no need to create new instance } // else - not even valid initializer } } return baseType; // Could not clarify }
@NotNull public GLSLType getType() { GLSLDeclaration declaration = getParentDeclaration(); if (declaration == null) return GLSLTypes.UNKNOWN_TYPE; GLSLTypeSpecifier declarationType = declaration.getTypeSpecifierNode(); if (declarationType == null) return GLSLTypes.UNKNOWN_TYPE; GLSLType declaredType = declarationType.getType(); if (!declaredType.isValidType()) return GLSLTypes.UNKNOWN_TYPE; GLSLArraySpecifier[] arraySpecifiers = findChildrenByClass(GLSLArraySpecifier.class); if (arraySpecifiers.length == 0) { return clarifyArrayType(declaredType); } else { // Must _prepend_ some dimensions to the type // In: "vec4[2][4] b[3]" b is "vec4[3][2][4]", not "vec4[2][4][3]" if (declaredType instanceof GLSLArrayType) { // Already an array, must append the dimensions GLSLArrayType declaredArrayType = (GLSLArrayType) declaredType; int[] existingDimensions = declaredArrayType.getDimensions(); int[] combinedDimensions = new int[existingDimensions.length + arraySpecifiers.length]; System.arraycopy( existingDimensions, 0, combinedDimensions, arraySpecifiers.length, existingDimensions.length); for (int i = 0; i < arraySpecifiers.length; i++) { combinedDimensions[i] = arraySpecifiers[i].getDimensionSize(); } return clarifyArrayType( new GLSLArrayType(declaredArrayType.getBaseType(), combinedDimensions)); } else { int[] dimensions = new int[arraySpecifiers.length]; for (int i = 0; i < dimensions.length; i++) { dimensions[i] = arraySpecifiers[i].getDimensionSize(); } return clarifyArrayType(new GLSLArrayType(declaredType, dimensions)); } } }