reuse parsed tokens instead of tokenizing each method body

This commit is contained in:
Dave Holoway
2020-06-08 12:30:31 +01:00
parent bbc6007338
commit 04c0e97c81
4 changed files with 23 additions and 12 deletions

View File

@@ -8,26 +8,35 @@ const { JavaType, CEIType, PrimitiveType, ArrayType, UnresolvedType, WildcardTyp
const { SourceMethod, SourceConstructor } = require('./source-type'); const { SourceMethod, SourceConstructor } = require('./source-type');
const ResolvedImport = require('./parsetypes/resolved-import'); const ResolvedImport = require('./parsetypes/resolved-import');
const ParseProblem = require('./parsetypes/parse-problem'); const ParseProblem = require('./parsetypes/parse-problem');
const { getOperatorType, tokenize, Token } = require('./tokenizer'); const { getOperatorType, Token } = require('./tokenizer');
/** /**
* @typedef {SourceMethod|SourceConstructor} SourceMC * @typedef {SourceMethod|SourceConstructor} SourceMC
*/ */
function flattenBlocks(blocks) {
return blocks.reduce((arr,block) => {
if (block instanceof Token) {
arr.push(block);
} else {
arr = [...arr, ...flattenBlocks(block.blockArray().blocks)];
}
return arr;
}, [])
}
/** /**
* @param {string} source
* @param {SourceMC} method * @param {SourceMC} method
* @param {ResolvedImport[]} imports * @param {ResolvedImport[]} imports
* @param {Map<string,JavaType>} typemap * @param {Map<string,JavaType>} typemap
*/ */
function parseBody(source, method, imports, typemap) { function parseBody(method, imports, typemap) {
const body = method._decl.body().blockArray(); const body = method._decl.body().blockArray();
if (!body || !body.simplified.startsWith('{')) { if (!body || body.blocks[0].value !== '{') {
return null; return null;
} }
const tokenlist = new TokenList(flattenBlocks(body.blocks));
const tokens = tokenize(source, body.start, body.length);
const tokenlist = new TokenList(tokens);
let block = null; let block = null;
try { try {
statementBlock(tokenlist, [], method, imports, typemap); statementBlock(tokenlist, [], method, imports, typemap);
@@ -37,7 +46,6 @@ function parseBody(source, method, imports, typemap) {
} }
return { return {
block, block,
tokens,
problems: tokenlist.problems, problems: tokenlist.problems,
} }
} }
@@ -65,6 +73,9 @@ function addLocals(tokens, locals, new_locals) {
} }
class TokenList { class TokenList {
/**
* @param {Token[]} tokens
*/
constructor(tokens) { constructor(tokens) {
this.tokens = tokens; this.tokens = tokens;
this.idx = -1; this.idx = -1;

View File

@@ -732,7 +732,7 @@ class ImportBlock extends DeclarationBlock {
class ModuleBlock extends TextBlockArray { class ModuleBlock extends TextBlockArray {
/** /**
* @param {TextBlock[]} blocks * @param {Token[]} blocks
*/ */
constructor(blocks) { constructor(blocks) {
super('module', blocks); super('module', blocks);

View File

@@ -63,7 +63,7 @@ class TextBlock {
class TextBlockArray { class TextBlockArray {
/** /**
* @param {string} id * @param {string} id
* @param {TextBlock[]} [blocks] * @param {import('../tokenizer').Token[]} [blocks]
*/ */
constructor(id, blocks = []) { constructor(id, blocks = []) {
this.id = id; this.id = id;

View File

@@ -64,13 +64,13 @@ function validate(mod, androidLibrary) {
return; return;
} }
console.log(c.label); console.log(c.label);
const parsed = parseBody(c._owner._decl.mod.source, c, imports.resolved, imports.typemap); const parsed = parseBody(c, imports.resolved, imports.typemap);
if (parsed) if (parsed)
probs = probs.concat(parsed.problems) probs = probs.concat(parsed.problems)
}) })
t.methods.forEach(m => { t.methods.forEach(m => {
console.log(m.label); console.log(m.label);
const parsed = parseBody(m._owner._decl.mod.source, m, imports.resolved, imports.typemap); const parsed = parseBody(m, imports.resolved, imports.typemap);
if (parsed) if (parsed)
probs = probs.concat(parsed.problems) probs = probs.concat(parsed.problems)
}) })