mirror of
https://github.com/adelphes/android-dev-ext.git
synced 2025-12-23 09:59:25 +00:00
add support for parsing enum values
This commit is contained in:
@@ -628,6 +628,17 @@ function sourceType(modifiers, tokens, scope_or_pkgname, typeKind, owner, import
|
|||||||
type.implements_types = typeIdentList(tokens, type, imports, typemap);
|
type.implements_types = typeIdentList(tokens, type, imports, typemap);
|
||||||
}
|
}
|
||||||
tokens.expectValue('{');
|
tokens.expectValue('{');
|
||||||
|
if (type.typeKind === 'enum') {
|
||||||
|
enumValueList(type, tokens, imports, typemap);
|
||||||
|
// if there are any declarations following the enum values, the values must be terminated by a semicolon
|
||||||
|
switch(tokens.current.value) {
|
||||||
|
case '}':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
semicolon(tokens);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!tokens.isValue('}')) {
|
if (!tokens.isValue('}')) {
|
||||||
typeBody(type, tokens, owner, imports, typemap);
|
typeBody(type, tokens, owner, imports, typemap);
|
||||||
tokens.expectValue('}');
|
tokens.expectValue('}');
|
||||||
@@ -932,6 +943,50 @@ function parameterDeclaration(type_vars, owner, tokens, imports, typemap) {
|
|||||||
return new SourceParameter(modifiers, type_ident, varargs, name_token);
|
return new SourceParameter(modifiers, type_ident, varargs, name_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {SourceType} type
|
||||||
|
* @param {TokenList} tokens
|
||||||
|
* @param {ResolvedImport[]} imports
|
||||||
|
* @param {Map<string,JavaType>} typemap
|
||||||
|
*/
|
||||||
|
function enumValueList(type, tokens, imports, typemap) {
|
||||||
|
for (;;) {
|
||||||
|
const ident = tokens.getIfKind('ident');
|
||||||
|
if (!ident) {
|
||||||
|
addproblem(tokens, ParseProblem.Error(tokens.current, `Identifier expected`));
|
||||||
|
}
|
||||||
|
let ctr_args = [];
|
||||||
|
if (tokens.isValue('(')) {
|
||||||
|
if (!tokens.isValue(')')) {
|
||||||
|
ctr_args = expressionList(tokens, new MethodDeclarations(), type, imports, typemap);
|
||||||
|
tokens.expectValue(')');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let anonymousEnumType = null;
|
||||||
|
if (tokens.isValue('{')) {
|
||||||
|
// anonymous enum type - just skip for now
|
||||||
|
for (let balance = 1;;) {
|
||||||
|
if (tokens.isValue('{')) {
|
||||||
|
balance++;
|
||||||
|
} else if (tokens.isValue('}')) {
|
||||||
|
if (--balance === 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else tokens.inc();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type.addEnumValue(ident, ctr_args, anonymousEnumType);
|
||||||
|
if (tokens.isValue(',')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (tokens.current.kind === 'ident') {
|
||||||
|
addproblem(tokens, ParseProblem.Error(tokens.current, `Missing comma`));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {TokenList} tokens
|
* @param {TokenList} tokens
|
||||||
* @param {MethodDeclarations} mdecls
|
* @param {MethodDeclarations} mdecls
|
||||||
@@ -1948,7 +2003,7 @@ function findIdentifier(ident, mdecls, scope, imports, typemap) {
|
|||||||
if (local || param) {
|
if (local || param) {
|
||||||
matches.variables = [local || param];
|
matches.variables = [local || param];
|
||||||
} else {
|
} else {
|
||||||
// is it a field or method in the current type (or any of the superclasses)
|
// is it a field, method or enum value in the current type (or any of the superclasses)
|
||||||
const scoped_type = scope instanceof SourceType ? scope : scope.owner;
|
const scoped_type = scope instanceof SourceType ? scope : scope.owner;
|
||||||
const types = getTypeInheritanceList(scoped_type);
|
const types = getTypeInheritanceList(scoped_type);
|
||||||
const method_sigs = new Set();
|
const method_sigs = new Set();
|
||||||
@@ -1957,6 +2012,12 @@ function findIdentifier(ident, mdecls, scope, imports, typemap) {
|
|||||||
const field = type.fields.find(f => f.name === ident);
|
const field = type.fields.find(f => f.name === ident);
|
||||||
if (field) {
|
if (field) {
|
||||||
matches.variables = [field];
|
matches.variables = [field];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const enumValue = (type instanceof SourceType) && type.enumValues.find(e => e.ident.value === ident);
|
||||||
|
if (enumValue) {
|
||||||
|
matches.variables = [enumValue];
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
matches.methods = matches.methods.concat(
|
matches.methods = matches.methods.concat(
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
const { CEIType, JavaType, PrimitiveType, Field, Method, MethodBase, Constructor, Parameter, TypeVariable } = require('java-mti');
|
const { CEIType, JavaType, PrimitiveType, Field, Method, MethodBase, Constructor, Parameter, TypeVariable } = require('java-mti');
|
||||||
const { Token } = require('./tokenizer');
|
const { Token } = require('./tokenizer');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import('./body-types').ResolvedIdent} ResolvedIdent
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {SourceType|SourceMethod|SourceConstructor|SourceInitialiser|string} scope_or_package_name
|
* @param {SourceType|SourceMethod|SourceConstructor|SourceInitialiser|string} scope_or_package_name
|
||||||
* @param {string} name
|
* @param {string} name
|
||||||
@@ -56,6 +60,18 @@ class SourceType extends CEIType {
|
|||||||
this.fields = [];
|
this.fields = [];
|
||||||
/** @type {SourceInitialiser[]} */
|
/** @type {SourceInitialiser[]} */
|
||||||
this.initers = [];
|
this.initers = [];
|
||||||
|
/** @type {SourceEnumValue[]} */
|
||||||
|
this.enumValues = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Token} ident
|
||||||
|
* @param {ResolvedIdent[]} ctr_args
|
||||||
|
* @param {SourceType} anonymousType
|
||||||
|
*/
|
||||||
|
addEnumValue(ident, ctr_args, anonymousType) {
|
||||||
|
this.enumValues.push(new SourceEnumValue(this, ident, ctr_args, anonymousType));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,6 +105,35 @@ class SourceType extends CEIType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SourceEnumValue extends Field {
|
||||||
|
/**
|
||||||
|
* @param {SourceType} owner
|
||||||
|
* @param {Token} ident
|
||||||
|
* @param {ResolvedIdent[]} ctr_args
|
||||||
|
* @param {SourceType} anonymousType
|
||||||
|
*/
|
||||||
|
constructor(owner, ident, ctr_args, anonymousType) {
|
||||||
|
super(['public','static','final'], '');
|
||||||
|
this.owner = owner;
|
||||||
|
this.ident = ident;
|
||||||
|
this.value = ctr_args;
|
||||||
|
this.anonymousType = anonymousType;
|
||||||
|
}
|
||||||
|
|
||||||
|
get label() {
|
||||||
|
// don't include the implicit modifiers in the label
|
||||||
|
return `${this.owner.simpleTypeName} ${this.name}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return this.ident.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get type() {
|
||||||
|
return this.owner;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class SourceTypeIdent {
|
class SourceTypeIdent {
|
||||||
/**
|
/**
|
||||||
* @param {Token[]} tokens
|
* @param {Token[]} tokens
|
||||||
|
|||||||
Reference in New Issue
Block a user