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 ResolvedImport = require('./parsetypes/resolved-import');
const ParseProblem = require('./parsetypes/parse-problem');
const { getOperatorType, tokenize, Token } = require('./tokenizer');
const { getOperatorType, Token } = require('./tokenizer');
/**
* @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 {ResolvedImport[]} imports
* @param {Map<string,JavaType>} typemap
*/
function parseBody(source, method, imports, typemap) {
function parseBody(method, imports, typemap) {
const body = method._decl.body().blockArray();
if (!body || !body.simplified.startsWith('{')) {
if (!body || body.blocks[0].value !== '{') {
return null;
}
const tokens = tokenize(source, body.start, body.length);
const tokenlist = new TokenList(tokens);
const tokenlist = new TokenList(flattenBlocks(body.blocks));
let block = null;
try {
statementBlock(tokenlist, [], method, imports, typemap);
@@ -37,7 +46,6 @@ function parseBody(source, method, imports, typemap) {
}
return {
block,
tokens,
problems: tokenlist.problems,
}
}
@@ -65,6 +73,9 @@ function addLocals(tokens, locals, new_locals) {
}
class TokenList {
/**
* @param {Token[]} tokens
*/
constructor(tokens) {
this.tokens = tokens;
this.idx = -1;

View File

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

View File

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

View File

@@ -64,13 +64,13 @@ function validate(mod, androidLibrary) {
return;
}
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)
probs = probs.concat(parsed.problems)
})
t.methods.forEach(m => {
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)
probs = probs.concat(parsed.problems)
})