diff --git a/langserver/java/source-types.js b/langserver/java/source-types.js index 973449a..de4e81f 100644 --- a/langserver/java/source-types.js +++ b/langserver/java/source-types.js @@ -24,6 +24,39 @@ function generateShortSignature(scope_or_package_name, name) { return pkgname ?`${pkgname.replace(/\./g, '/')}/${name}` : name; } +/** + * @param {SourceType} enum_type + * @param {Map} typemap + */ +function createImplicitEnumMethods(enum_type, typemap) { + return [ + new class extends Method { + constructor() { + super(enum_type, 'values', ['public','static'], ''); + this._returnType = new ArrayType(enum_type, 1); + } + get returnType() { + return this._returnType; + } + }, + new class extends Method { + constructor() { + super(enum_type, 'valueOf', ['public','static'], ''); + this._parameters = [ + new Parameter('name', typemap.get('java/lang/String'), false) + ] + this._returnType = enum_type; + } + get parameters() { + return this._parameters; + } + get returnType() { + return this._returnType; + } + } + ]; +} + class SourceType extends CEIType { /** * @param {string} packageName @@ -55,8 +88,10 @@ class SourceType extends CEIType { this.implements_types = []; /** @type {SourceConstructor[]} */ this.constructors = []; - /** @type {SourceMethod[]} */ - this.methods = []; + /** @type {Method[]} */ + this.methods = typeKind === 'enum' + ? createImplicitEnumMethods(this, typemap) + : []; /** @type {SourceField[]} */ this.fields = []; /** @type {SourceInitialiser[]} */ @@ -65,6 +100,14 @@ class SourceType extends CEIType { this.enumValues = []; } + /** + * @returns {SourceMethod[]} + */ + get sourceMethods() { + // @ts-ignore + return this.methods.filter(m => m instanceof SourceMethod);// [...this.implicitMethods, ...this.sourceMethods]; + } + /** * * @param {Token} ident @@ -190,7 +233,11 @@ class SpecialisedSourceType extends CEIType { }; }); - this.methods = source_type.methods.map(m => { + this.methods = source_type.methods.map(method => { + if (!(method instanceof SourceMethod)) { + return method; + } + const m = method; const type = this; return new class extends Method { constructor() { diff --git a/langserver/java/validater.js b/langserver/java/validater.js index 00a2e8e..3ea395e 100644 --- a/langserver/java/validater.js +++ b/langserver/java/validater.js @@ -27,7 +27,7 @@ function validate(unit, androidLibrary) { if (parsed) probs = probs.concat(parsed.problems) }) - t.methods.forEach(m => { + t.sourceMethods.forEach(m => { const parsed = parseBody(m, resolved_types, androidLibrary); if (parsed) probs = probs.concat(parsed.problems) diff --git a/langserver/java/validation/bad-overrides.js b/langserver/java/validation/bad-overrides.js index badaa98..9909250 100644 --- a/langserver/java/validation/bad-overrides.js +++ b/langserver/java/validation/bad-overrides.js @@ -16,7 +16,7 @@ function checkOverrides(source_type, probs) { /** @type {{ann:SourceAnnotation, method:Method, method_id:string}[]} */ const overriden_methods = []; - source_type.methods.reduce((arr, method) => { + source_type.sourceMethods.reduce((arr, method) => { const ann = method.annotations.find(a => a.type.simpleTypeName === 'Override'); if (ann) { arr.push({ diff --git a/langserver/java/validation/invalid-types.js b/langserver/java/validation/invalid-types.js index 33a975a..4b16aff 100644 --- a/langserver/java/validation/invalid-types.js +++ b/langserver/java/validation/invalid-types.js @@ -26,7 +26,7 @@ function checkType(type, is_return_type, probs) { */ function checkInvalidTypes(type, probs) { type.fields.forEach(f => checkType(f.fieldTypeIdent, false, probs)); - type.methods.forEach(m => { + type.sourceMethods.forEach(m => { checkType(m.returnTypeIdent, true, probs); m.parameters.forEach(p => { checkType(p.paramTypeIdent, false, probs); diff --git a/langserver/java/validation/modifier-errors.js b/langserver/java/validation/modifier-errors.js index 33f4855..72a0a36 100644 --- a/langserver/java/validation/modifier-errors.js +++ b/langserver/java/validation/modifier-errors.js @@ -173,7 +173,7 @@ function checkTypeModifiers(type, probs) { } type.fields.forEach(field => checkFieldModifiers(field, probs)); - type.methods.forEach(method => checkMethodModifiers(type, typemods, method, probs)); + type.sourceMethods.forEach(method => checkMethodModifiers(type, typemods, method, probs)); type.constructors.forEach(ctr => checkConstructorModifiers(ctr, probs)); type.initers.forEach(initer => checkInitialiserModifiers(initer, probs)); }