mirror of
https://github.com/adelphes/android-dev-ext.git
synced 2025-12-23 01:48:18 +00:00
add type variables to SourceMethod
This commit is contained in:
@@ -373,10 +373,12 @@ class MCBlock extends DeclarationBlock {
|
|||||||
super(section, simplified);
|
super(section, simplified);
|
||||||
const sm = section.sourcemap();
|
const sm = section.sourcemap();
|
||||||
this.paramBlock = section.blocks[sm.map[match[0].indexOf('R')]];
|
this.paramBlock = section.blocks[sm.map[match[0].indexOf('R')]];
|
||||||
|
this.typevarsBlock = section.blocks[sm.map[match[0].indexOf('T')]];
|
||||||
this.parsed = {
|
this.parsed = {
|
||||||
|
typevars: null,
|
||||||
parameters: null,
|
parameters: null,
|
||||||
/** @type {TextBlock[]} */
|
/** @type {TextBlock[]} */
|
||||||
errors: null,
|
errors: [],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,30 +386,7 @@ class MCBlock extends DeclarationBlock {
|
|||||||
* @return {ParameterBlock[]}
|
* @return {ParameterBlock[]}
|
||||||
*/
|
*/
|
||||||
get parameters() {
|
get parameters() {
|
||||||
if (!this.parsed.parameters) {
|
this._ensureParsed();
|
||||||
const param_block = this.paramBlock.blockArray();
|
|
||||||
parseArrayTypes(param_block);
|
|
||||||
parseAnnotations(param_block);
|
|
||||||
parseTypeArgs(param_block);
|
|
||||||
const vars = group(param_block, 'var-decl', VarDeclBlock.parseRE, markers.varDecl, false, VarDeclBlock);
|
|
||||||
this.parsed.parameters = group(param_block, 'param', ParameterBlock.parseRE, markers.parameter, false, ParameterBlock);
|
|
||||||
// parameters must be a comma-separated list
|
|
||||||
const sm = param_block.sourcemap();
|
|
||||||
if (sm.simplified.search(/^\((\s*F(\s*,\s*F)*)?\s*\)/) === 0) {
|
|
||||||
return this.parsed.parameters;
|
|
||||||
}
|
|
||||||
let invalid = sm.simplified.match(/^(\(\s*)(F?)(?:\s*,\s*F)*\s*/);
|
|
||||||
if (!invalid) {
|
|
||||||
// should never happen, but ignore
|
|
||||||
return this.parsed.parameters;
|
|
||||||
}
|
|
||||||
const token_idx = invalid[2]
|
|
||||||
? sm.map[invalid[0].length] // there's a problem with a subsequent declaration
|
|
||||||
: sm.map[invalid[1].length] // there's a problem with the first declaration
|
|
||||||
const token = param_block.blocks[token_idx];
|
|
||||||
if (!token) return this.parsed.parameters;
|
|
||||||
this.parsed.errors = [token];
|
|
||||||
}
|
|
||||||
return this.parsed.parameters;
|
return this.parsed.parameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,9 +412,43 @@ class MCBlock extends DeclarationBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get parseErrors() {
|
get parseErrors() {
|
||||||
this.parameters;
|
this._ensureParsed();
|
||||||
return this.parsed.errors;
|
return this.parsed.errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get typeVariables() {
|
||||||
|
this._ensureParsed();
|
||||||
|
return this.parsed.typevars;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ensureParsed() {
|
||||||
|
if (this.parsed.parameters) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const param_block = this.paramBlock.blockArray();
|
||||||
|
parseArrayTypes(param_block);
|
||||||
|
parseAnnotations(param_block);
|
||||||
|
parseTypeArgs(param_block);
|
||||||
|
const vars = group(param_block, 'var-decl', VarDeclBlock.parseRE, markers.varDecl, false, VarDeclBlock);
|
||||||
|
this.parsed.parameters = group(param_block, 'param', ParameterBlock.parseRE, markers.parameter, false, ParameterBlock);
|
||||||
|
// parameters must be a comma-separated list
|
||||||
|
const sm = param_block.sourcemap();
|
||||||
|
if (sm.simplified.search(/^\((\s*F(\s*,\s*F)*)?\s*\)/) !== 0) {
|
||||||
|
let invalid = sm.simplified.match(/^(\(\s*)(F?)(?:\s*,\s*F)*\s*/);
|
||||||
|
if (invalid) {
|
||||||
|
const token_idx = invalid[2]
|
||||||
|
? sm.map[invalid[0].length] // there's a problem with a subsequent declaration
|
||||||
|
: sm.map[invalid[1].length] // there's a problem with the first declaration
|
||||||
|
const token = param_block.blocks[token_idx];
|
||||||
|
if (token) {
|
||||||
|
this.parsed.errors.push(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse type arguments
|
||||||
|
this.parsed.typevars = this.typevarsBlock ? parseTypeVariables(this.typevarsBlock.blockArray()) : [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MethodBlock extends MCBlock {
|
class MethodBlock extends MCBlock {
|
||||||
@@ -631,29 +644,9 @@ class TypeDeclBlock extends DeclarationBlock {
|
|||||||
if (this.parsed.fields) {
|
if (this.parsed.fields) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.parsed.typevars = [];
|
this.parsed.typevars = this.typevars_token
|
||||||
if (this.typevars_token) {
|
? parseTypeVariables(this.typevars_token.blockArray())
|
||||||
// split the token into a list of typevars
|
: [];
|
||||||
// - each type var must be a simple ident (W), a bounded var (I)
|
|
||||||
// or anonymous (?)
|
|
||||||
this.parsed.typevars = this.typevars_token.blockArray()
|
|
||||||
.blocks.reduce((arr,b) => {
|
|
||||||
if (/^[WI?]/.test(b.simplified)) {
|
|
||||||
arr.push({
|
|
||||||
decl: b,
|
|
||||||
get name_token() {
|
|
||||||
return this.decl instanceof BoundedTypeVar
|
|
||||||
? this.decl.range.blocks[0]
|
|
||||||
: this.decl
|
|
||||||
},
|
|
||||||
get name() {
|
|
||||||
return this.name_token.source;
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return arr;
|
|
||||||
}, []);
|
|
||||||
}
|
|
||||||
const body = this.body().blockArray();
|
const body = this.body().blockArray();
|
||||||
parseArrayTypes(body);
|
parseArrayTypes(body);
|
||||||
parseTypeArgs(body);
|
parseTypeArgs(body);
|
||||||
@@ -834,6 +827,33 @@ function parseArrayTypes(sourceblocks) {
|
|||||||
group(sourceblocks, 'array-type', /\[ *\](( *\[ *\])*)/g, markers.arrayQualifier);
|
group(sourceblocks, 'array-type', /\[ *\](( *\[ *\])*)/g, markers.arrayQualifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {TextBlockArray} sourceblocks
|
||||||
|
* @returns {{decl: TextBlock|BoundedTypeVar, name_token: TextBlockArray, name: string}[]}
|
||||||
|
*/
|
||||||
|
function parseTypeVariables(sourceblocks) {
|
||||||
|
// split the token into a list of typevars
|
||||||
|
// - each type var must be a simple ident (W), a bounded var (I)
|
||||||
|
// or a wildcard (?)
|
||||||
|
return sourceblocks.blocks.reduce((arr,b) => {
|
||||||
|
if (/^[WI?]/.test(b.simplified)) {
|
||||||
|
arr.push({
|
||||||
|
decl: b,
|
||||||
|
get name_token() {
|
||||||
|
return this.decl instanceof BoundedTypeVar
|
||||||
|
? this.decl.range.blocks[0]
|
||||||
|
: this.decl
|
||||||
|
},
|
||||||
|
get name() {
|
||||||
|
return this.name_token.source;
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
function parseTypeArgs(sourceblocks) {
|
function parseTypeArgs(sourceblocks) {
|
||||||
// sort out type parameters + type arguments
|
// sort out type parameters + type arguments
|
||||||
// re = /< *[PWD?]( *T)?( *A)?( *, *[PWD]( *T)?( *A)?)* *>/g;
|
// re = /< *[PWD?]( *T)?( *A)?( *, *[PWD]( *T)?( *A)?)* *>/g;
|
||||||
|
|||||||
@@ -209,6 +209,12 @@ class SourceMethod extends Method {
|
|||||||
this._decl = decl;
|
this._decl = decl;
|
||||||
this._parameters = decl.parameters.map((p,i) => new SourceParameter(p));
|
this._parameters = decl.parameters.map((p,i) => new SourceParameter(p));
|
||||||
this._returnType = new ResolvableType(decl);
|
this._returnType = new ResolvableType(decl);
|
||||||
|
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;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -221,6 +227,10 @@ class SourceMethod extends Method {
|
|||||||
get returnType() {
|
get returnType() {
|
||||||
return this._returnType.resolved;
|
return this._returnType.resolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get typeVariables() {
|
||||||
|
return this._typevars;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SourceParameter extends Parameter {
|
class SourceParameter extends Parameter {
|
||||||
|
|||||||
Reference in New Issue
Block a user