package glslplugin.annotation.impl; import com.intellij.lang.annotation.AnnotationHolder; import glslplugin.annotation.Annotator; import glslplugin.lang.elements.expressions.GLSLExpression; import glslplugin.lang.elements.expressions.GLSLSubscriptExpression; import glslplugin.lang.elements.types.*; import org.jetbrains.annotations.NotNull; /** * Created by abigail on 08/07/15. */ public class SubscriptBoundAnnotation extends Annotator<GLSLSubscriptExpression> { @Override public void annotate(GLSLSubscriptExpression expr, AnnotationHolder holder) { GLSLExpression expression = expr.getArrayExpression(); GLSLExpression subscript = expr.getSubscript(); if (expression == null || subscript == null) return; if (!expression.getType().isValidType() || !subscript.getType().isValidType()) return; GLSLType type = subscript.getType(); if (!type.typeEquals(GLSLTypes.INT) && !type.typeEquals(GLSLTypes.UINT)) { holder.createErrorAnnotation(expr, "Subscript must be of int or uint type, found " + type.getTypename()); return; } int dimension; if (expression.getType() instanceof GLSLArrayType) { dimension = ((GLSLArrayType) expression.getType()).getDimensions()[0]; if (!subscript.isConstantValue()) { if (dimension == GLSLArrayType.UNDEFINED_SIZE_DIMENSION) { holder.createErrorAnnotation(expr, "Unsized arrays may only be indexed with constant expressions"); return; } } } else if (expression.getType() instanceof GLSLVectorType) { dimension = ((GLSLVectorType) expression.getType()).getNumComponents(); } else if (expression.getType() instanceof GLSLMatrixType) { dimension = ((GLSLMatrixType) expression.getType()).getNumColumns(); } else { holder.createErrorAnnotation(expr, "Subscripted expression must be of array, matrix or vector type"); return; } if (dimension == GLSLArrayType.UNDEFINED_SIZE_DIMENSION || dimension == GLSLArrayType.DYNAMIC_SIZE_DIMENSION) return; if (!subscript.isConstantValue()) return; Long value = (Long) subscript.getConstantValue(); assert value != null; // if !isConstantValue we've already returned if (value < 0 || value >= dimension) { holder.createErrorAnnotation(expr, "Subscript index out-of-bounds"); } } @NotNull @Override public Class<GLSLSubscriptExpression> getElementType() { return GLSLSubscriptExpression.class; } }