Example #1
0
  /**
   * 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
  }
Example #2
0
  @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));
      }
    }
  }