mirror of
https://github.com/adelphes/android-dev-ext.git
synced 2025-12-24 02:19:15 +00:00
allow multiple source files to be used in parsing
This commit is contained in:
@@ -193,50 +193,59 @@ function extractSourceTypes(tokens, typemap) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} source
|
||||
* @param {{uri:string, content:string, version:number}[]} docs
|
||||
* @param {SourceUnit[]} cached_units
|
||||
* @param {Map<string,CEIType>} typemap
|
||||
* @returns {SourceUnit[]}
|
||||
*/
|
||||
function parse(source, typemap) {
|
||||
const unit = new SourceUnit();
|
||||
/** @type {ParseProblem[]} */
|
||||
let problems = [];
|
||||
let tokens, timers = new Set();
|
||||
function parse(docs, cached_units, typemap) {
|
||||
|
||||
const timers = new Set();
|
||||
const time = name => (timers.add(name), console.time(name));
|
||||
const timeEnd = name => (timers.delete(name), console.timeEnd(name));
|
||||
try {
|
||||
time('tokenize');
|
||||
tokens = new TokenList(unit.tokens = tokenize(source));
|
||||
problems = tokens.problems;
|
||||
timeEnd('tokenize');
|
||||
|
||||
// in order to resolve types as we parse, we must extract the set of source types first
|
||||
const source_types = extractSourceTypes(tokens, typemap);
|
||||
time('tokenize');
|
||||
const sources = docs.reduce((arr, doc) => {
|
||||
try {
|
||||
const unit = new SourceUnit();
|
||||
unit.uri = doc.uri;
|
||||
const tokens = new TokenList(unit.tokens = tokenize(doc.content));
|
||||
arr.push({ unit, tokens });
|
||||
} catch(err) {
|
||||
}
|
||||
return arr;
|
||||
}, [])
|
||||
timeEnd('tokenize');
|
||||
|
||||
// add the cached types to the type map
|
||||
cached_units.forEach(unit => {
|
||||
unit.types.forEach(t => typemap.set(t.shortSignature, t));
|
||||
})
|
||||
|
||||
// in order to resolve types as we parse, we must extract the set of source types first
|
||||
sources.forEach(source => {
|
||||
const source_types = extractSourceTypes(source.tokens, typemap);
|
||||
// add them to the type map
|
||||
source_types.forEach(t => typemap.set(t.shortSignature, t));
|
||||
})
|
||||
|
||||
time('parse');
|
||||
parseUnit(tokens, unit, typemap);
|
||||
timeEnd('parse');
|
||||
|
||||
// once all the types have been parsed, resolve any field initialisers
|
||||
const ri = new ResolveInfo(typemap, tokens.problems);
|
||||
unit.types.forEach(t => {
|
||||
t.fields.filter(f => f.init).forEach(f => checkAssignment(ri, f.type, f.init));
|
||||
});
|
||||
|
||||
} catch(err) {
|
||||
timers.forEach(timeEnd);
|
||||
if (tokens && tokens.current) {
|
||||
addproblem(tokens, ParseProblem.Error(tokens.current, `Parse failed: ${err.message}`));
|
||||
} else {
|
||||
console.log(`Parse failed: ${err.message}`);
|
||||
// parse all the tokenized sources
|
||||
time('parse');
|
||||
sources.forEach(source => {
|
||||
try {
|
||||
parseUnit(source.tokens, source.unit, typemap);
|
||||
// once all the types have been parsed, resolve any field initialisers
|
||||
// const ri = new ResolveInfo(typemap, tokens.problems);
|
||||
// unit.types.forEach(t => {
|
||||
// t.fields.filter(f => f.init).forEach(f => checkAssignment(ri, f.type, f.init));
|
||||
// });
|
||||
} catch (err) {
|
||||
addproblem(source.tokens, ParseProblem.Error(source.tokens.current, `Parse failed: ${err.message}`));
|
||||
}
|
||||
}
|
||||
});
|
||||
timeEnd('parse');
|
||||
|
||||
return {
|
||||
unit,
|
||||
problems,
|
||||
}
|
||||
return sources.map(s => s.unit);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -555,6 +555,8 @@ class SourceImport {
|
||||
}
|
||||
|
||||
class SourceUnit {
|
||||
/** @type {string} */
|
||||
uri = '';
|
||||
/** @type {Token[]} */
|
||||
tokens = [];
|
||||
/** @type {SourcePackage} */
|
||||
@@ -614,6 +616,13 @@ class SourceUnit {
|
||||
method,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the package this unit belongs to
|
||||
*/
|
||||
get packageName() {
|
||||
return (this.package_ && this.package_.name) || '';
|
||||
}
|
||||
}
|
||||
|
||||
class SourceArrayType extends ArrayType {
|
||||
|
||||
@@ -5,22 +5,22 @@ const { parseBody } = require('./body-parser3');
|
||||
|
||||
/**
|
||||
* @param {SourceUnit} unit
|
||||
* @param {Map<string, CEIType>} androidLibrary
|
||||
* @param {Map<string, CEIType>} typemap
|
||||
*/
|
||||
function parseMethodBodies(unit, androidLibrary) {
|
||||
function parseMethodBodies(unit, typemap) {
|
||||
const resolved_types = [
|
||||
...resolveImports(androidLibrary, [], [], null).resolved,
|
||||
...resolveImports(typemap, [], [], unit.packageName).resolved,
|
||||
...unit.imports.filter(i => i.resolved).map(i => i.resolved),
|
||||
]
|
||||
unit.types.forEach(t => {
|
||||
t.initers.forEach(i => {
|
||||
i.parsed = parseBody(i, resolved_types, androidLibrary);
|
||||
i.parsed = parseBody(i, resolved_types, typemap);
|
||||
})
|
||||
t.constructors.forEach(c => {
|
||||
c.parsed = parseBody(c, resolved_types, androidLibrary);
|
||||
c.parsed = parseBody(c, resolved_types, typemap);
|
||||
})
|
||||
t.sourceMethods.forEach(m => {
|
||||
m.parsed = parseBody(m, resolved_types, androidLibrary);
|
||||
m.parsed = parseBody(m, resolved_types, typemap);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user