diff --git a/langserver/java/expression-resolver.js b/langserver/java/expression-resolver.js index 5e17b18..f2db082 100644 --- a/langserver/java/expression-resolver.js +++ b/langserver/java/expression-resolver.js @@ -1,6 +1,7 @@ /** * @typedef {import('./tokenizer').Token} Token * @typedef {import('./anys').ResolvedType} ResolvedType + * @typedef {import('./body-types').ResolvedIdent} ResolvedIdent */ const ParseProblem = require('./parsetypes/parse-problem'); const { TypeVariable, JavaType, PrimitiveType, NullType, ArrayType, CEIType, WildcardType, TypeVariableType, InferredTypeArgument } = require('java-mti'); @@ -117,6 +118,21 @@ function checkArrayLiteral(variable_type, value_type, tokens, problems) { } } +/** + * @param {ResolveInfo} ri + * @param {ResolvedIdent} d + * @param {'index'|'dimension'} kind + */ +function checkArrayIndex(ri, d, kind) { + const idx = d.resolveExpression(ri); + if (idx instanceof PrimitiveType) { + if (!/^[BSI]$/.test(idx.typeSignature)) { + ri.problems.push(ParseProblem.Error(d.tokens, `Expression of type '${idx.label}' is not valid as an array ${kind}`)); + } + return; + } + ri.problems.push(ParseProblem.Error(d.tokens, `Integer value expected`)); +} /** * Set of regexes to map source primitives to their destination types. @@ -250,4 +266,5 @@ function getTypeInheritanceList(type) { } exports.checkAssignment = checkAssignment; +exports.checkArrayIndex = checkArrayIndex; exports.getTypeInheritanceList = getTypeInheritanceList; diff --git a/langserver/java/expressiontypes/ArrayIndexExpression.js b/langserver/java/expressiontypes/ArrayIndexExpression.js index e06a62e..fea1599 100644 --- a/langserver/java/expressiontypes/ArrayIndexExpression.js +++ b/langserver/java/expressiontypes/ArrayIndexExpression.js @@ -4,6 +4,7 @@ */ const { Expression } = require("./Expression"); const { ArrayType } = require('java-mti'); +const { checkArrayIndex } = require('../expression-resolver'); const { AnyType } = require('../anys'); class ArrayIndexExpression extends Expression { @@ -26,6 +27,7 @@ class ArrayIndexExpression extends Expression { */ resolveExpression(ri) { const instance_type = this.instance.resolveExpression(ri); + checkArrayIndex(ri, this.index, 'index'); if (instance_type instanceof ArrayType) { return instance_type.elementType; } diff --git a/langserver/java/expressiontypes/NewExpression.js b/langserver/java/expressiontypes/NewExpression.js index d7cb952..9854fa6 100644 --- a/langserver/java/expressiontypes/NewExpression.js +++ b/langserver/java/expressiontypes/NewExpression.js @@ -6,9 +6,10 @@ * @typedef {import('java-mti').JavaType} JavaType */ const { Expression } = require("./Expression"); -const { ArrayType, PrimitiveType } = require('java-mti'); +const { ArrayType } = require('java-mti'); const { FixedLengthArrayType, SourceArrayType } = require('../source-types'); const ParseProblem = require('../parsetypes/parse-problem'); +const { checkArrayIndex } = require('../expression-resolver'); class NewArray extends Expression { /** @@ -46,14 +47,7 @@ class NewArray extends Expression { const array_type = new ArrayType(this.element_type.resolved, arrdims); fixed_dimensions.forEach(d => { - const idx = d.resolveExpression(ri); - if (idx instanceof PrimitiveType) { - if (!/^[BSI]$/.test(idx.typeSignature)) { - ri.problems.push(ParseProblem.Error(d.tokens, `Expression of type '${idx.label}' is not valid as an array dimension`)); - } - return; - } - ri.problems.push(ParseProblem.Error(d.tokens, `Integer value expected`)); + checkArrayIndex(ri, d, 'dimension'); }) return array_type; }