validate array indexes

This commit is contained in:
Dave Holoway
2020-06-18 15:57:30 +01:00
parent 1255a15bba
commit f4743e456b
3 changed files with 22 additions and 9 deletions

View File

@@ -1,6 +1,7 @@
/** /**
* @typedef {import('./tokenizer').Token} Token * @typedef {import('./tokenizer').Token} Token
* @typedef {import('./anys').ResolvedType} ResolvedType * @typedef {import('./anys').ResolvedType} ResolvedType
* @typedef {import('./body-types').ResolvedIdent} ResolvedIdent
*/ */
const ParseProblem = require('./parsetypes/parse-problem'); const ParseProblem = require('./parsetypes/parse-problem');
const { TypeVariable, JavaType, PrimitiveType, NullType, ArrayType, CEIType, WildcardType, TypeVariableType, InferredTypeArgument } = require('java-mti'); 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. * Set of regexes to map source primitives to their destination types.
@@ -250,4 +266,5 @@ function getTypeInheritanceList(type) {
} }
exports.checkAssignment = checkAssignment; exports.checkAssignment = checkAssignment;
exports.checkArrayIndex = checkArrayIndex;
exports.getTypeInheritanceList = getTypeInheritanceList; exports.getTypeInheritanceList = getTypeInheritanceList;

View File

@@ -4,6 +4,7 @@
*/ */
const { Expression } = require("./Expression"); const { Expression } = require("./Expression");
const { ArrayType } = require('java-mti'); const { ArrayType } = require('java-mti');
const { checkArrayIndex } = require('../expression-resolver');
const { AnyType } = require('../anys'); const { AnyType } = require('../anys');
class ArrayIndexExpression extends Expression { class ArrayIndexExpression extends Expression {
@@ -26,6 +27,7 @@ class ArrayIndexExpression extends Expression {
*/ */
resolveExpression(ri) { resolveExpression(ri) {
const instance_type = this.instance.resolveExpression(ri); const instance_type = this.instance.resolveExpression(ri);
checkArrayIndex(ri, this.index, 'index');
if (instance_type instanceof ArrayType) { if (instance_type instanceof ArrayType) {
return instance_type.elementType; return instance_type.elementType;
} }

View File

@@ -6,9 +6,10 @@
* @typedef {import('java-mti').JavaType} JavaType * @typedef {import('java-mti').JavaType} JavaType
*/ */
const { Expression } = require("./Expression"); const { Expression } = require("./Expression");
const { ArrayType, PrimitiveType } = require('java-mti'); const { ArrayType } = require('java-mti');
const { FixedLengthArrayType, SourceArrayType } = require('../source-types'); const { FixedLengthArrayType, SourceArrayType } = require('../source-types');
const ParseProblem = require('../parsetypes/parse-problem'); const ParseProblem = require('../parsetypes/parse-problem');
const { checkArrayIndex } = require('../expression-resolver');
class NewArray extends Expression { class NewArray extends Expression {
/** /**
@@ -46,14 +47,7 @@ class NewArray extends Expression {
const array_type = new ArrayType(this.element_type.resolved, arrdims); const array_type = new ArrayType(this.element_type.resolved, arrdims);
fixed_dimensions.forEach(d => { fixed_dimensions.forEach(d => {
const idx = d.resolveExpression(ri); checkArrayIndex(ri, d, 'dimension');
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`));
}) })
return array_type; return array_type;
} }