update to use new set of SourceX classes

This commit is contained in:
Dave Holoway
2020-06-13 15:16:35 +01:00
parent f4a18ebcdc
commit da8d37aafd
12 changed files with 244 additions and 171 deletions

View File

@@ -10,7 +10,7 @@ function checkExtends(source_type, probs) {
if (source_type.extends_types.length === 0) {
return;
}
const supertypes = source_type.extends_types.map(st => st.resolved);
const supertypes = source_type.extends_types.map(st => st.type);
const supertype = supertypes[0];
if (source_type.typeKind === 'enum') {
probs.push(ParseProblem.Error(source_type.extends_types[0].typeTokens, `Enum types cannot declare a superclass`));

View File

@@ -11,7 +11,7 @@ function checkImplements(source_type, probs) {
if (source_type.implements_types.length === 0) {
return;
}
const interfaces = source_type.implements_types.map(it => it.resolved);
const interfaces = source_type.implements_types.map(it => it.type);
if (source_type.typeKind === 'interface') {
probs.push(ParseProblem.Error(source_type.implements_types[0].typeTokens, `Interface types cannot declare an implements section`));
}

View File

@@ -1,6 +1,6 @@
const { ModuleBlock, TextBlock } = require('../parser9');
const { ModuleBlock } = require('../parser9');
const ParseProblem = require('../parsetypes/parse-problem');
const {SourceType} = require('../source-type');
const {SourceType, SourceAnnotation} = require('../source-type');
const {CEIType, Method} = require('java-mti');
function nonAbstractLabel(label) {
@@ -19,10 +19,10 @@ function checkOverrides(source_type, probs) {
return;
}
/** @type {{ann:TextBlock, method:Method, method_id:string}[]} */
/** @type {{ann:SourceAnnotation, method:Method, method_id:string}[]} */
const overriden_methods = [];
source_type.methods.reduce((arr, method) => {
const ann = method._decl.annotations.find(a => /^@\s*Override$/.test(a.source));
const ann = method.annotations.find(a => /^Override$/.test(a.annotationTypeIdent.type.simpleTypeName));
if (ann) {
arr.push({
ann,
@@ -52,7 +52,7 @@ function checkOverrides(source_type, probs) {
overriden_methods.forEach(x => {
if (!methods.has(x.method_id)) {
probs.push(ParseProblem.Error(x.ann, `${x.method.label} does not override a matching method in any inherited type or interface`));
probs.push(ParseProblem.Error(x.ann.annotationTypeIdent.typeTokens, `${x.method.label} does not override a matching method in any inherited type or interface`));
}
})
}

View File

@@ -1,11 +1,14 @@
const { ModuleBlock, TypeDeclBlock } = require('../parser9');
const { ModuleBlock } = require('../parser9');
const ParseProblem = require('../parsetypes/parse-problem');
const {SourceType} = require('../source-type');
const {JavaType, ArrayType, CEIType, TypeArgument, UnresolvedType} = require('java-mti');
const { AnyType } = require('../body-types');
const {Token} = require('../tokenizer');
const {JavaType} = require('java-mti');
/**
* @param {JavaType} type
* @param {boolean} is_return_type
* @param {Token[]} typeTokens
* @param {ParseProblem[]} probs
*/
function checkType(type, is_return_type, typeTokens, probs) {
const typesig = type.typeSignature;
@@ -26,11 +29,11 @@ function checkType(type, is_return_type, typeTokens, probs) {
* @param {*} probs
*/
function checkInvalidTypes(type, probs) {
type.fields.forEach(f => checkType(f.type, false, f._decl.typeTokens, probs));
type.fields.forEach(f => checkType(f.type, false, f.fieldType.typeTokens, probs));
type.methods.forEach(m => {
checkType(m.returnType, true, m._decl.typeTokens, probs);
checkType(m.returnType, true, m.methodTypeIdent.typeTokens, probs);
m.parameters.forEach(p => {
checkType(p.type, false, p._decl.typeTokens, probs);
checkType(p.type, false, p.paramTypeIdent.typeTokens, probs);
})
})
}

View File

@@ -22,7 +22,7 @@ function checkConstructor(source_type, probs) {
if (!superclass.constructors.find(c => c.parameterCount === 0)) {
// the source type has no declared constructors, but the superclass
// does not include a default (parameterless) constructor
probs.push(ParseProblem.Error(source_type._decl.name_token, `Type ${superclass.fullyDottedRawName} requires a constructor to be declared because the inherited class '${superclass.fullyDottedRawName}' does not define a default constructor.`));
probs.push(ParseProblem.Error(source_type.name_token, `Class '${source_type.fullyDottedRawName}' requires a constructor to be declared because the inherited class '${superclass.fullyDottedRawName}' does not define a default constructor.`));
}
}

View File

@@ -49,7 +49,7 @@ function checkImplementedInterfaces(source_type, probs) {
}
})
if (missing_methods.length) {
probs.push(ParseProblem.Error(source_type._decl.kindToken, `Non-abstract ${source_type.typeKind} '${source_type.fullyDottedRawName}' does not implement the following methods from interface '${intf.fullyDottedRawName}':\n${missing_methods.join('\n')}`));
probs.push(ParseProblem.Error(source_type.kind_token, `Non-abstract ${source_type.typeKind} '${source_type.fullyDottedRawName}' does not implement the following methods from interface '${intf.fullyDottedRawName}':\n${missing_methods.join('\n')}`));
}
});
}

View File

@@ -1,52 +0,0 @@
const { ModuleBlock, TypeDeclBlock } = require('../parser9');
const ParseProblem = require('../parsetypes/parse-problem');
const {SourceType} = require('../source-type');
const {JavaType, CEIType, TypeArgument, UnresolvedType} = require('java-mti')
/**
* @param {JavaType} type
*/
function checkType(type, typeTokens, probs) {
if (type instanceof UnresolvedType) {
probs.push(ParseProblem.Error(typeTokens, `Unknown type: ${type.label}`));
return;
}
if (type instanceof CEIType) {
type.typeVariables.forEach(tv => {
if (tv instanceof TypeArgument) {
checkType(tv.type, typeTokens, probs);
}
})
}
}
/**
* @param {SourceType} type
* @param {*} probs
*/
function checkUnresolvedTypes(type, probs) {
type.extends_types.forEach(superclass => checkType(superclass.resolved, superclass.typeTokens, probs));
type.implements_types.forEach(superintf => checkType(superintf.resolved, superintf.typeTokens, probs));
type.fields.forEach(f => checkType(f.type, f._decl.typeTokens, probs));
type.methods.forEach(m => {
checkType(m.returnType, m._decl.typeTokens, probs);
m.parameters.forEach(p => {
checkType(p.type, p._decl.typeTokens, probs);
})
})
}
/**
* @param {ModuleBlock} mod
* @param {*} imports
* @param {SourceType[]} source_types
*/
module.exports = function(mod, imports, source_types) {
/** @type {ParseProblem[]} */
const probs = [];
source_types.forEach(type => checkUnresolvedTypes(type, probs));
return probs;
}