diff --git a/langserver/java/body-parser3.js b/langserver/java/body-parser3.js index 3a3e286..d3fd35f 100644 --- a/langserver/java/body-parser3.js +++ b/langserver/java/body-parser3.js @@ -6,7 +6,7 @@ */ const { JavaType, CEIType, PrimitiveType, ArrayType, UnresolvedType, TypeVariable, Field, Method } = require('java-mti'); const { SourceType, SourceTypeIdent, SourceField, SourceMethod, SourceConstructor, SourceInitialiser, SourceParameter, SourceAnnotation, - SourceUnit, SourcePackage, SourceImport } = require('./source-types2'); + SourceUnit, SourcePackage, SourceImport } = require('./source-types'); const ResolvedImport = require('./parsetypes/resolved-import'); const ParseProblem = require('./parsetypes/parse-problem'); const { tokenize, Token } = require('./tokenizer'); diff --git a/langserver/java/body-types.js b/langserver/java/body-types.js index dbb9906..c76a708 100644 --- a/langserver/java/body-types.js +++ b/langserver/java/body-types.js @@ -28,7 +28,7 @@ class Local { * @param {Token[]} modifiers * @param {string} name * @param {Token} decltoken - * @param {import('./source-type').SourceTypeIdent} typeIdent + * @param {import('./source-types').SourceTypeIdent} typeIdent * @param {number} postnamearrdims * @param {ResolvedIdent} init */ @@ -62,7 +62,7 @@ class MethodDeclarations { locals = []; /** @type {Label[]} */ labels = []; - /** @type {import('./source-types2').SourceType[]} */ + /** @type {import('./source-types').SourceType[]} */ types = []; _scopeStack = []; diff --git a/langserver/java/import-resolver.js b/langserver/java/import-resolver.js index 8352e95..b4e71da 100644 --- a/langserver/java/import-resolver.js +++ b/langserver/java/import-resolver.js @@ -80,7 +80,7 @@ function resolveSingleImport(typemap, dotted_name, is_static, on_demand, import_ * - followed by implicit packages * * @param {Map} androidLibrary - * @param {import('./source-type').SourceType[]} sourceTypes + * @param {import('./source-types').SourceType[]} sourceTypes * @param {ImportBlock[]} imports list of declared imports in the module * @param {string} package_name package name of the module * @param {string[]} [implicitPackages] list of implicit demand-load packages diff --git a/langserver/java/source-type.js b/langserver/java/source-type.js deleted file mode 100644 index ae23713..0000000 --- a/langserver/java/source-type.js +++ /dev/null @@ -1,313 +0,0 @@ -const { JavaType, ArrayType, CEIType, NullType, PrimitiveType, TypeVariableType, Constructor, Method, MethodBase, Field, Parameter, TypeVariable, UnresolvedType, signatureToType } = require('java-mti'); -const { ModuleBlock, TypeDeclBlock, FieldBlock, ConstructorBlock, MethodBlock, InitialiserBlock, ParameterBlock, TextBlock } = require('./parser9'); - -/** - * - * @param {{modifiers:TextBlock[]}} x - */ -function mapmods(x) { - return x.modifiers.map(m => m.source); -} - -/** - * - * @param {TextBlock} decl - */ -function extractTypeList(decl) { - if (!decl) { - return []; - } - const types = []; - const re = /[WD]( *[WDT.])*/g; - const declba = decl.blockArray(); - const sm = declba.sourcemap(); - for (let m; m = re.exec(sm.simplified);) { - const start = sm.map[m.index], end = sm.map[m.index + m[0].length-1]; - const block_range = declba.blocks.slice(start, end+1); - types.push(block_range); - } - return types.map(tokens => { - const decl = { - type: tokens.map(t => t.source).join(''), - typeTokens: tokens, - } - return new ResolvableType(decl); - }); -} - -class SourceType extends CEIType { - /** - * @param {ModuleBlock} mod - * @param {TypeDeclBlock} decl - * @param {string} qualified_type_name qualified $-separated type name - * @param {Map} typemap - */ - constructor(mod, decl, qualified_type_name, typemap) { - super(decl.shortSignature, decl.kind(), mapmods(decl), decl.docs); - this._typemap = typemap; - this._decl = decl; - this._dottedTypeName = qualified_type_name.replace(/\$/g, '.'); - - this.extends_types = decl.extends_decl ? extractTypeList(decl.extends_decl) : []; - this.implements_types = decl.implements_decl ? extractTypeList(decl.implements_decl) : []; - this.implicit_extend = !this.extends_types.length && !this.implements_types.length ? [typemap.get('java/lang/Object')] : []; - - this.fields = decl.fields.map(f => new SourceField(this, f)); - this.methods = decl.methods.map(m => new SourceMethod(this, m)); - - /** - * constructors coded in the source - */ - this.declaredConstructors = decl.constructors.map(c => new SourceConstructor(this, c)); - - /** - * Callable constructors for the type - if the type does not explicitly declare - * any constructors, an implicit default constructor is included - * @type {Constructor[]} - * */ - this.constructors = this.declaredConstructors; - if (!decl.constructors[0] && decl.kind() === 'class') { - // add a default public constructor if this is a class with no explicit constructors - this.constructors = [new DefaultConstructor(this)]; - } - - /** - * The class initialisers - */ - this.initers = decl.initialisers.map(i => new SourceInitialiser(this, i)); - - super.typeVariables = decl.typevars.map(tv => { - const typevar = new TypeVariable(this, tv.name); - // automatically add the Object bound - typevar.bounds.push(new TypeVariable.Bound(this, 'Ljava/lang/Object;', false)); - return typevar; - }); - /** - * Number of local/anonymous types declared in the scope of this type - * The number is used when naming them. - */ - this.localTypeCount = 0; - } - - get dottedTypeName() { - return this._dottedTypeName; - } - - get fullyDottedRawName() { - return this._decl.fullyDottedName; - } - - get fullyDottedTypeName() { - return this._decl.fullyDottedName; - } - - get supers() { - return [ - ...this.implicit_extend, - ...this.extends_types.map(t => t.resolved), - ...this.implements_types.map(t => t.resolved) - ]; - } - - /** - * @param {string} signature - * @param {TypeVariable[]} [typevars] - * @returns {JavaType} - */ - resolveType(signature, typevars = []) { - return signatureToType(signature, this._typemap, [...typevars, ...this.typeVariables]); - } -} - -class SourceField extends Field { - /** - * @param {SourceType} owner - * @param {FieldBlock} decl - */ - constructor(owner, decl) { - super(mapmods(decl), decl.docs); - this._decl = decl; - this._type = new ResolvableType(decl); - } - - get name() { - return this._decl.name; - } - - get type() { - return this._type.resolved; - } -} - -class SourceConstructor extends Constructor { - /** - * @param {SourceType} owner - * @param {ConstructorBlock} decl - */ - constructor(owner, decl) { - super(owner, mapmods(decl), decl.docs); - /** @type {SourceType} */ - this.owner = owner; - this._decl = decl; - this._parameters = decl.parameters.map((p,i) => new SourceParameter(p)); - } - - get methodSignature() { - return `(${this._parameters.map(p => p.type.typeSignature).join('')})V`; - } - - /** - * @returns {SourceParameter[]} - */ - get parameters() { - return this._parameters; - } - - /** - * @returns {SourceType} - */ - get returnType() { - return this.owner; - } -} - -class DefaultConstructor extends Constructor { - /** - * @param {SourceType} owner - */ - constructor(owner) { - super(owner, ['public'], ''); - this.owner = owner; - } - - get methodSignature() { - return `()V`; - } - - /** - * @returns {SourceType} - */ - get returnType() { - return this.owner; - } -} - - -class SourceInitialiser extends MethodBase { - /** - * @param {SourceType} owner - * @param {InitialiserBlock} decl - */ - constructor(owner, decl) { - super(owner, mapmods(decl), decl.docs); - /** @type {SourceType} */ - this.owner = owner; - this._decl = decl; - } - - /** - * @returns {SourceParameter[]} - */ - get parameters() { - return []; - } - - get returnType() { - return PrimitiveType.map.V; - } -} - -class SourceMethod extends Method { - /** - * @param {SourceType} owner - * @param {MethodBlock} decl - */ - constructor(owner, decl) { - super(owner, decl.name, mapmods(decl), decl.docs); - /** @type {SourceType} */ - this.owner = owner; - this._decl = decl; - this._parameters = decl.parameters.map((p,i) => new SourceParameter(p)); - this._returnType = new ResolvableType(decl); - /** @type {TypeVariable[]} */ - this._typevars = decl.typeVariables.map(tv => { - const typevar = new TypeVariable(owner, tv.name); - // automatically add the Object bound - typevar.bounds.push(new TypeVariable.Bound(owner, 'Ljava/lang/Object;', false)); - return typevar; - }); - } - - /** - * @returns {SourceParameter[]} - */ - get parameters() { - return this._parameters; - } - - get returnType() { - return this._returnType.resolved; - } - - get typeVariables() { - return this._typevars; - } -} - -class SourceParameter extends Parameter { - /** - * @param {ParameterBlock} decl - * @param {ResolvableType} [type] - */ - constructor(decl, type = new ResolvableType(decl)) { - super(decl.name, type, decl.isVarArgs); - this._decl = decl; - this._paramType = type; - } - - get type() { - if (this.varargs) { - // variable arity parameters are automatically an array type - return new ArrayType(this._paramType.resolved, 1); - } - return this._paramType.resolved; - } -} - -class ResolvableType extends UnresolvedType { - /** - * - * @param {{type:string, typeTokens:TextBlock[]}} decl - */ - constructor(decl) { - super(decl.type); - this._decl = decl; - /** @type {JavaType} */ - this._resolved = null; - } - - /** - * @returns {JavaType} - */ - get resolved() { - return this._resolved || this; - } - - get typeTokens() { - return this._decl.typeTokens; - } -} - -const source_types = require('./source-types2'); -exports.SourceType = source_types.SourceType; -exports.SourceTypeIdent = source_types.SourceTypeIdent; -exports.SourceField = source_types.SourceField; -exports.SourceMethod = source_types.SourceMethod; -exports.SourceParameter = source_types.SourceParameter; -exports.SourceConstructor = source_types.SourceConstructor; -exports.DefaultConstructor = DefaultConstructor; -exports.SourceInitialiser = source_types.SourceInitialiser; -exports.SourceAnnotation = source_types.SourceAnnotation; -exports.SourceUnit = source_types.SourceUnit; -exports.SourcePackage = source_types.SourcePackage; -exports.SourceImport = source_types.SourceImport; diff --git a/langserver/java/source-types2.js b/langserver/java/source-types.js similarity index 100% rename from langserver/java/source-types2.js rename to langserver/java/source-types.js diff --git a/langserver/java/typeident.js b/langserver/java/typeident.js index 6103b77..2b0ac31 100644 --- a/langserver/java/typeident.js +++ b/langserver/java/typeident.js @@ -1,5 +1,5 @@ const { ArrayType, CEIType, JavaType, PrimitiveType, MethodBase, WildcardType, TypeVariable } = require('java-mti'); -const { SourceTypeIdent, SourceMethod, SourceConstructor, SourceInitialiser } = require('./source-type'); +const { SourceTypeIdent, SourceMethod, SourceConstructor, SourceInitialiser } = require('./source-types'); const ResolvedImport = require('./parsetypes/resolved-import'); const { resolveTypeOrPackage, resolveNextTypeOrPackage } = require('./type-resolver'); const { Token } = require('./tokenizer'); diff --git a/langserver/java/validater.js b/langserver/java/validater.js index 836c343..00a2e8e 100644 --- a/langserver/java/validater.js +++ b/langserver/java/validater.js @@ -1,12 +1,12 @@ -const { JavaType } = require('java-mti'); +const { CEIType } = require('java-mti'); const { resolveImports } = require('../java/import-resolver'); -const { SourceUnit } = require('./source-type'); +const { SourceUnit } = require('./source-types'); const { parseBody } = require('./body-parser3'); - /** * @param {SourceUnit} unit - * @param {Map} androidLibrary + * @param {Map} androidLibrary + * @returns {import('./parsetypes/parse-problem')[]} */ function validate(unit, androidLibrary) { console.time('validation'); @@ -47,6 +47,7 @@ function validate(unit, androidLibrary) { require('./validation/non-implemented-interfaces'), require('./validation/bad-overrides'), require('./validation/missing-constructor'), + //require('./validation/expression-compatibility'), ]; let problems = [ module_validaters.map(v => v(unit.types, unit)), diff --git a/langserver/java/validation/bad-extends.js b/langserver/java/validation/bad-extends.js index 36a8c50..57d724b 100644 --- a/langserver/java/validation/bad-extends.js +++ b/langserver/java/validation/bad-extends.js @@ -1,4 +1,4 @@ -const { SourceType } = require('../source-type'); +const { SourceType } = require('../source-types'); const ParseProblem = require('../parsetypes/parse-problem'); const { AnyType } = require('../anys'); diff --git a/langserver/java/validation/bad-implements.js b/langserver/java/validation/bad-implements.js index b702cf3..1ffb2b3 100644 --- a/langserver/java/validation/bad-implements.js +++ b/langserver/java/validation/bad-implements.js @@ -1,5 +1,5 @@ const ParseProblem = require('../parsetypes/parse-problem'); -const {SourceType} = require('../source-type'); +const {SourceType} = require('../source-types'); const { AnyType } = require('../anys'); const { UnresolvedType } = require('java-mti'); diff --git a/langserver/java/validation/bad-overrides.js b/langserver/java/validation/bad-overrides.js index f733d22..badaa98 100644 --- a/langserver/java/validation/bad-overrides.js +++ b/langserver/java/validation/bad-overrides.js @@ -1,5 +1,5 @@ const ParseProblem = require('../parsetypes/parse-problem'); -const {SourceType, SourceAnnotation} = require('../source-type'); +const {SourceType, SourceAnnotation} = require('../source-types'); const {CEIType, Method} = require('java-mti'); /** diff --git a/langserver/java/validation/invalid-types.js b/langserver/java/validation/invalid-types.js index ec7b8ea..33a975a 100644 --- a/langserver/java/validation/invalid-types.js +++ b/langserver/java/validation/invalid-types.js @@ -1,4 +1,4 @@ -const { SourceType, SourceTypeIdent } = require('../source-type'); +const { SourceType, SourceTypeIdent } = require('../source-types'); const ParseProblem = require('../parsetypes/parse-problem'); /** diff --git a/langserver/java/validation/missing-constructor.js b/langserver/java/validation/missing-constructor.js index ce2211c..0cf8156 100644 --- a/langserver/java/validation/missing-constructor.js +++ b/langserver/java/validation/missing-constructor.js @@ -1,4 +1,4 @@ -const {SourceType, SourceConstructor} = require('../source-type'); +const {SourceType, SourceConstructor} = require('../source-types'); const ParseProblem = require('../parsetypes/parse-problem'); /** diff --git a/langserver/java/validation/modifier-errors.js b/langserver/java/validation/modifier-errors.js index a3f91f3..33f4855 100644 --- a/langserver/java/validation/modifier-errors.js +++ b/langserver/java/validation/modifier-errors.js @@ -1,4 +1,4 @@ -const { SourceType, SourceMethod, SourceParameter, SourceField, SourceConstructor, SourceInitialiser } = require('../source-type'); +const { SourceType, SourceMethod, SourceParameter, SourceField, SourceConstructor, SourceInitialiser } = require('../source-types'); const { Token } = require('../tokenizer'); const ParseProblem = require('../parsetypes/parse-problem'); diff --git a/langserver/java/validation/non-implemented-interfaces.js b/langserver/java/validation/non-implemented-interfaces.js index 376670c..e0fff29 100644 --- a/langserver/java/validation/non-implemented-interfaces.js +++ b/langserver/java/validation/non-implemented-interfaces.js @@ -1,5 +1,5 @@ const ParseProblem = require('../parsetypes/parse-problem'); -const { SourceType } = require('../source-type'); +const { SourceType } = require('../source-types'); const {CEIType} = require('java-mti'); function nonAbstractLabel(label) { diff --git a/langserver/java/validation/unresolved-imports.js b/langserver/java/validation/unresolved-imports.js index 0eb13c1..d73d890 100644 --- a/langserver/java/validation/unresolved-imports.js +++ b/langserver/java/validation/unresolved-imports.js @@ -1,4 +1,4 @@ -const { SourceUnit } = require('../source-type'); +const { SourceUnit } = require('../source-types'); const ParseProblem = require('../parsetypes/parse-problem'); /** diff --git a/langserver/server.js b/langserver/server.js index 2e92802..906ddbd 100644 --- a/langserver/server.js +++ b/langserver/server.js @@ -21,7 +21,7 @@ const { loadAndroidLibrary, CEIType } = require('java-mti'); const { ParseProblem } = require('./java/parser'); const { parse } = require('./java/body-parser3'); -const { SourceUnit } = require('./java/source-type'); +const { SourceUnit } = require('./java/source-types'); const { validate } = require('./java/validater'); /**