mirror of
https://github.com/adelphes/android-dev-ext.git
synced 2025-12-23 09:59:25 +00:00
replace regex parsing with linear parsing
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
const { ModuleBlock, TypeDeclBlock } = require('../parser9');
|
||||
const { SourceType, SourceTypeIdent } = require('../source-type');
|
||||
const ParseProblem = require('../parsetypes/parse-problem');
|
||||
const {SourceType} = require('../source-type');
|
||||
|
||||
/**
|
||||
* @param {SourceType} source_type
|
||||
@@ -10,41 +9,39 @@ function checkExtends(source_type, probs) {
|
||||
if (source_type.extends_types.length === 0) {
|
||||
return;
|
||||
}
|
||||
const supertypes = source_type.extends_types.map(st => st.type);
|
||||
const supertypes = source_type.extends_types.map(st => st.resolved);
|
||||
const supertype = supertypes[0];
|
||||
if (source_type.typeKind === 'enum') {
|
||||
probs.push(ParseProblem.Error(source_type.extends_types[0].typeTokens, `Enum types cannot declare a superclass`));
|
||||
probs.push(ParseProblem.Error(source_type.extends_types[0].tokens, `Enum types cannot declare a superclass`));
|
||||
}
|
||||
if (source_type.typeKind === 'class' && supertypes.length > 1) {
|
||||
probs.push(ParseProblem.Error(source_type.extends_types[1].typeTokens, `Class types cannot inherit from more than one type`));
|
||||
probs.push(ParseProblem.Error(source_type.extends_types[1].tokens, `Class types cannot inherit from more than one type`));
|
||||
}
|
||||
if (source_type.typeKind === 'class' && supertype.typeKind !== 'class') {
|
||||
probs.push(ParseProblem.Error(source_type.extends_types[0].typeTokens, `Class '${source_type.fullyDottedRawName}' cannot inherit from ${supertype.typeKind} type: '${supertype.fullyDottedRawName}'`));
|
||||
probs.push(ParseProblem.Error(source_type.extends_types[0].tokens, `Class '${source_type.fullyDottedRawName}' cannot inherit from ${supertype.typeKind} type: '${supertype.fullyDottedRawName}'`));
|
||||
}
|
||||
if (source_type.typeKind === 'class' && supertype.typeKind === 'class' && supertype.modifiers.includes('final')) {
|
||||
probs.push(ParseProblem.Error(source_type.extends_types[0].typeTokens, `Class '${source_type.fullyDottedRawName}' cannot inherit from final class: '${supertype.fullyDottedRawName}'`));
|
||||
probs.push(ParseProblem.Error(source_type.extends_types[0].tokens, `Class '${source_type.fullyDottedRawName}' cannot inherit from final class: '${supertype.fullyDottedRawName}'`));
|
||||
}
|
||||
if (source_type.typeKind === 'class' && supertype === source_type) {
|
||||
probs.push(ParseProblem.Error(source_type.extends_types[0].typeTokens, `Class '${source_type.fullyDottedRawName}' cannot inherit from itself`));
|
||||
probs.push(ParseProblem.Error(source_type.extends_types[0].tokens, `Class '${source_type.fullyDottedRawName}' cannot inherit from itself`));
|
||||
}
|
||||
if (source_type.typeKind === 'interface') {
|
||||
supertypes.forEach((supertype, i) => {
|
||||
if (supertype.typeKind !== 'interface') {
|
||||
probs.push(ParseProblem.Error(source_type.extends_types[i].typeTokens, `Interface '${source_type.fullyDottedRawName}' cannot inherit from ${supertype.typeKind} type: '${supertype.fullyDottedRawName}'`));
|
||||
probs.push(ParseProblem.Error(source_type.extends_types[i].tokens, `Interface '${source_type.fullyDottedRawName}' cannot inherit from ${supertype.typeKind} type: '${supertype.fullyDottedRawName}'`));
|
||||
}
|
||||
if (supertype === source_type) {
|
||||
probs.push(ParseProblem.Error(source_type.extends_types[i].typeTokens, `Interface '${source_type.fullyDottedRawName}' cannot inherit from itself`));
|
||||
probs.push(ParseProblem.Error(source_type.extends_types[i].tokens, `Interface '${source_type.fullyDottedRawName}' cannot inherit from itself`));
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ModuleBlock} mod
|
||||
* @param {*} imports
|
||||
* @param {SourceType[]} source_types
|
||||
*/
|
||||
module.exports = function(mod, imports, source_types) {
|
||||
module.exports = function(source_types) {
|
||||
/** @type {ParseProblem[]} */
|
||||
const probs = [];
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
const { ModuleBlock } = require('../parser9');
|
||||
const ParseProblem = require('../parsetypes/parse-problem');
|
||||
const {SourceType} = require('../source-type');
|
||||
const { UnresolvedType } = require('java-mti');
|
||||
@@ -11,9 +10,9 @@ function checkImplements(source_type, probs) {
|
||||
if (source_type.implements_types.length === 0) {
|
||||
return;
|
||||
}
|
||||
const interfaces = source_type.implements_types.map(it => it.type);
|
||||
const interfaces = source_type.implements_types.map(it => it.resolved);
|
||||
if (source_type.typeKind === 'interface') {
|
||||
probs.push(ParseProblem.Error(source_type.implements_types[0].typeTokens, `Interface types cannot declare an implements section`));
|
||||
probs.push(ParseProblem.Error(source_type.implements_types[0].tokens, `Interface types cannot declare an implements section`));
|
||||
}
|
||||
if (source_type.typeKind === 'class') {
|
||||
interfaces.forEach((intf, i) => {
|
||||
@@ -21,18 +20,16 @@ function checkImplements(source_type, probs) {
|
||||
return;
|
||||
}
|
||||
if (intf.typeKind !== 'interface') {
|
||||
probs.push(ParseProblem.Error(source_type.implements_types[i].typeTokens, `Class '${source_type.fullyDottedRawName}' cannot implement ${intf.typeKind} type: '${intf.fullyDottedRawName}'`));
|
||||
probs.push(ParseProblem.Error(source_type.implements_types[i].tokens, `Class '${source_type.fullyDottedRawName}' cannot implement ${intf.typeKind} type: '${intf.fullyDottedRawName}'`));
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ModuleBlock} mod
|
||||
* @param {*} imports
|
||||
* @param {SourceType[]} source_types
|
||||
*/
|
||||
module.exports = function(mod, imports, source_types) {
|
||||
module.exports = function(source_types) {
|
||||
/** @type {ParseProblem[]} */
|
||||
const probs = [];
|
||||
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
const { ModuleBlock } = require('../parser9');
|
||||
const ParseProblem = require('../parsetypes/parse-problem');
|
||||
const {SourceType, SourceAnnotation} = require('../source-type');
|
||||
const {CEIType, Method} = require('java-mti');
|
||||
|
||||
function nonAbstractLabel(label) {
|
||||
return label.replace(/\babstract /g, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {SourceType} source_type
|
||||
* @param {*} probs
|
||||
@@ -22,7 +17,7 @@ function checkOverrides(source_type, probs) {
|
||||
/** @type {{ann:SourceAnnotation, method:Method, method_id:string}[]} */
|
||||
const overriden_methods = [];
|
||||
source_type.methods.reduce((arr, method) => {
|
||||
const ann = method.annotations.find(a => /^Override$/.test(a.annotationTypeIdent.type.simpleTypeName));
|
||||
const ann = method.annotations.find(a => a.type.simpleTypeName === 'Override');
|
||||
if (ann) {
|
||||
arr.push({
|
||||
ann,
|
||||
@@ -52,17 +47,15 @@ function checkOverrides(source_type, probs) {
|
||||
|
||||
overriden_methods.forEach(x => {
|
||||
if (!methods.has(x.method_id)) {
|
||||
probs.push(ParseProblem.Error(x.ann.annotationTypeIdent.typeTokens, `${x.method.label} does not override a matching method in any inherited type or interface`));
|
||||
probs.push(ParseProblem.Error(x.ann.annotationTypeIdent.tokens, `${x.method.label} does not override a matching method in any inherited type or interface`));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ModuleBlock} mod
|
||||
* @param {*} imports
|
||||
* @param {SourceType[]} source_types
|
||||
*/
|
||||
module.exports = function(mod, imports, source_types) {
|
||||
module.exports = function(source_types) {
|
||||
/** @type {ParseProblem[]} */
|
||||
const probs = [];
|
||||
|
||||
|
||||
@@ -1,26 +1,22 @@
|
||||
const { ModuleBlock } = require('../parser9');
|
||||
const { SourceType, SourceTypeIdent } = require('../source-type');
|
||||
const ParseProblem = require('../parsetypes/parse-problem');
|
||||
const {SourceType} = require('../source-type');
|
||||
const {Token} = require('../tokenizer');
|
||||
const {JavaType} = require('java-mti');
|
||||
|
||||
/**
|
||||
* @param {JavaType} type
|
||||
* @param {SourceTypeIdent} type
|
||||
* @param {boolean} is_return_type
|
||||
* @param {Token[]} typeTokens
|
||||
* @param {ParseProblem[]} probs
|
||||
*/
|
||||
function checkType(type, is_return_type, typeTokens, probs) {
|
||||
const typesig = type.typeSignature;
|
||||
function checkType(type, is_return_type, probs) {
|
||||
const typesig = type.resolved.typeSignature;
|
||||
if (/^\[*U/.test(typesig)) {
|
||||
probs.push(ParseProblem.Error(typeTokens, `Unresolved type '${type.label}'`))
|
||||
probs.push(ParseProblem.Error(type.tokens, `Unresolved type '${type.resolved.label}'`))
|
||||
return;
|
||||
}
|
||||
if (typesig === 'V' && !is_return_type) {
|
||||
probs.push(ParseProblem.Error(typeTokens, `'void' is not a valid type for variables`))
|
||||
probs.push(ParseProblem.Error(type.tokens, `'void' is not a valid type for variables`))
|
||||
}
|
||||
if (/^\[+V/.test(typesig)) {
|
||||
probs.push(ParseProblem.Error(typeTokens, `Illegal type: '${type.label}'`))
|
||||
probs.push(ParseProblem.Error(type.tokens, `Illegal type: '${type.resolved.label}'`))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,22 +25,25 @@ function checkType(type, is_return_type, typeTokens, probs) {
|
||||
* @param {*} probs
|
||||
*/
|
||||
function checkInvalidTypes(type, probs) {
|
||||
type.fields.forEach(f => checkType(f.type, false, f.fieldType.typeTokens, probs));
|
||||
type.fields.forEach(f => checkType(f.fieldTypeIdent, false, probs));
|
||||
type.methods.forEach(m => {
|
||||
checkType(m.returnType, true, m.methodTypeIdent.typeTokens, probs);
|
||||
checkType(m.returnTypeIdent, true, probs);
|
||||
m.parameters.forEach(p => {
|
||||
checkType(p.type, false, p.paramTypeIdent.typeTokens, probs);
|
||||
checkType(p.paramTypeIdent, false, probs);
|
||||
})
|
||||
})
|
||||
type.constructors.forEach(c => {
|
||||
c.parameters.forEach(p => {
|
||||
checkType(p.paramTypeIdent, false, probs);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {ModuleBlock} mod
|
||||
* @param {*} imports
|
||||
* @param {SourceType[]} source_types
|
||||
*/
|
||||
module.exports = function(mod, imports, source_types) {
|
||||
module.exports = function(source_types) {
|
||||
/** @type {ParseProblem[]} */
|
||||
const probs = [];
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
const { ModuleBlock, TypeDeclBlock } = require('../parser9');
|
||||
const ParseProblem = require('../parsetypes/parse-problem');
|
||||
const {SourceType, SourceConstructor} = require('../source-type');
|
||||
const ParseProblem = require('../parsetypes/parse-problem');
|
||||
|
||||
/**
|
||||
* @param {SourceType} source_type
|
||||
@@ -22,16 +21,14 @@ function checkConstructor(source_type, probs) {
|
||||
if (!superclass.constructors.find(c => c.parameterCount === 0)) {
|
||||
// the source type has no declared constructors, but the superclass
|
||||
// does not include a default (parameterless) constructor
|
||||
probs.push(ParseProblem.Error(source_type.name_token, `Class '${source_type.fullyDottedRawName}' requires a constructor to be declared because the inherited class '${superclass.fullyDottedRawName}' does not define a default constructor.`));
|
||||
probs.push(ParseProblem.Error(source_type.nameToken, `Class '${source_type.fullyDottedRawName}' requires a constructor to be declared because the inherited class '${superclass.fullyDottedRawName}' does not define a default constructor.`));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ModuleBlock} mod
|
||||
* @param {*} imports
|
||||
* @param {SourceType[]} source_types
|
||||
*/
|
||||
module.exports = function(mod, imports, source_types) {
|
||||
module.exports = function(source_types) {
|
||||
/** @type {ParseProblem[]} */
|
||||
const probs = [];
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
const { TextBlock, ModuleBlock, FieldBlock, MethodBlock, ConstructorBlock, InitialiserBlock, TypeDeclBlock } = require('../parser9');
|
||||
const { SourceType, SourceMethod, SourceField, SourceConstructor, SourceInitialiser } = require('../source-type');
|
||||
const { Token } = require('../tokenizer');
|
||||
const ParseProblem = require('../parsetypes/parse-problem');
|
||||
|
||||
/**
|
||||
* @param {TextBlock[]} mods
|
||||
* @param {Token[]} mods
|
||||
* @param {ParseProblem[]} probs
|
||||
*/
|
||||
function checkDuplicate(mods, probs) {
|
||||
@@ -21,7 +22,7 @@ function checkDuplicate(mods, probs) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TextBlock[]} mods
|
||||
* @param {Token[]} mods
|
||||
* @param {ParseProblem[]} probs
|
||||
*/
|
||||
function checkConflictingAccess(mods, probs) {
|
||||
@@ -49,13 +50,13 @@ function checkConflictingAccess(mods, probs) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {FieldBlock} field
|
||||
* @param {SourceField} field
|
||||
* @param {ParseProblem[]} probs
|
||||
*/
|
||||
function checkFieldModifiers(field, probs) {
|
||||
checkDuplicate(field.modifiers, probs);
|
||||
checkConflictingAccess(field.modifiers, probs);
|
||||
for (let mod of field.modifiers) {
|
||||
checkDuplicate(field.modifierTokens, probs);
|
||||
checkConflictingAccess(field.modifierTokens, probs);
|
||||
for (let mod of field.modifierTokens) {
|
||||
switch (mod.source) {
|
||||
case 'abstract':
|
||||
probs.push(ParseProblem.Error(mod, 'Field declarations cannot be abstract'));
|
||||
@@ -68,18 +69,18 @@ function checkFieldModifiers(field, probs) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TypeDeclBlock} type
|
||||
* @param {SourceType} type
|
||||
* @param {Map<string,*>} ownertypemods
|
||||
* @param {MethodBlock} method
|
||||
* @param {SourceMethod} method
|
||||
* @param {ParseProblem[]} probs
|
||||
*/
|
||||
function checkMethodModifiers(type, ownertypemods, method, probs) {
|
||||
checkDuplicate(method.modifiers, probs);
|
||||
checkConflictingAccess(method.modifiers, probs);
|
||||
checkDuplicate(method.modifierTokens, probs);
|
||||
checkConflictingAccess(method.modifierTokens, probs);
|
||||
|
||||
const allmods = new Map(method.modifiers.map(m => [m.source, m]));
|
||||
const is_interface_kind = /@?interface/.test(type.kind());
|
||||
const has_body = method.body().simplified.startsWith('B');
|
||||
const allmods = new Map(method.modifierTokens.map(m => [m.source, m]));
|
||||
const is_interface_kind = /@?interface/.test(type.typeKind);
|
||||
const has_body = method.hasImplementation;
|
||||
|
||||
if (allmods.has('abstract') && allmods.has('final')) {
|
||||
probs.push(ParseProblem.Error(allmods.get('abstract'), 'Method declarations cannot be abstract and final'));
|
||||
@@ -91,77 +92,76 @@ function checkMethodModifiers(type, ownertypemods, method, probs) {
|
||||
probs.push(ParseProblem.Error(allmods.get('abstract'), 'Method declarations marked as abstract cannot have a method body'));
|
||||
}
|
||||
if (!is_interface_kind && !allmods.has('abstract') && !allmods.has('native') && !has_body) {
|
||||
probs.push(ParseProblem.Error(method, `Method '${method.name}' must have an implementation or be defined as abstract or native`));
|
||||
probs.push(ParseProblem.Error(method.nameToken, `Method '${method.name}' must have an implementation or be defined as abstract or native`));
|
||||
}
|
||||
if (!is_interface_kind && allmods.has('abstract') && !ownertypemods.has('abstract')) {
|
||||
probs.push(ParseProblem.Error(method, `Method '${method.name}' cannot be declared abstract inside a non-abstract type`));
|
||||
probs.push(ParseProblem.Error(allmods.get('abstract'), `Method '${method.name}' cannot be declared abstract inside a non-abstract type`));
|
||||
}
|
||||
if (is_interface_kind && has_body && !allmods.has('default')) {
|
||||
probs.push(ParseProblem.Error(method, `Non-default interface methods cannot have a method body`));
|
||||
probs.push(ParseProblem.Error(method.body[0], `Non-default interface methods cannot have a method body`));
|
||||
}
|
||||
if (allmods.has('native') && has_body) {
|
||||
probs.push(ParseProblem.Error(allmods.get('native'), 'Method declarations marked as native cannot have a method body'));
|
||||
}
|
||||
// JLS8
|
||||
if (type.kind() !== 'interface' && allmods.has('default')) {
|
||||
probs.push(ParseProblem.Error(method, `Default method declarations are only allowed inside interfaces`));
|
||||
if (type.typeKind !== 'interface' && allmods.has('default')) {
|
||||
probs.push(ParseProblem.Error(allmods.get('default'), `Default method declarations are only allowed inside interfaces`));
|
||||
}
|
||||
if (allmods.has('default') && !has_body) {
|
||||
probs.push(ParseProblem.Error(method, `Default method declarations must have an implementation`));
|
||||
probs.push(ParseProblem.Error(allmods.get('default'), `Default method declarations must have an implementation`));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ConstructorBlock} field
|
||||
* @param {SourceConstructor} field
|
||||
* @param {ParseProblem[]} probs
|
||||
*/
|
||||
function checkConstructorModifiers(field, probs) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {InitialiserBlock} initialiser
|
||||
* @param {SourceInitialiser} initialiser
|
||||
* @param {ParseProblem[]} probs
|
||||
*/
|
||||
function checkInitialiserModifiers(initialiser, probs) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {TypeDeclBlock} type
|
||||
* @param {SourceType} type
|
||||
* @param {ParseProblem[]} probs
|
||||
*/
|
||||
function checkTypeModifiers(type, probs) {
|
||||
const typemods = new Map(type.modifiers.map(m => [m.source, m]));
|
||||
checkDuplicate(type.modifiers, probs);
|
||||
const typemods = new Map(type.modifierTokens.map(m => [m.source, m]));
|
||||
checkDuplicate(type.modifierTokens, probs);
|
||||
|
||||
if (type.kind() === 'interface' && typemods.has('final')) {
|
||||
if (type.typeKind === 'interface' && typemods.has('final')) {
|
||||
probs.push(ParseProblem.Error(typemods.get('final'), 'Interface declarations cannot be marked as final'));
|
||||
}
|
||||
if (type.kind() === 'enum' && typemods.has('abstract')) {
|
||||
if (type.typeKind === 'enum' && typemods.has('abstract')) {
|
||||
probs.push(ParseProblem.Error(typemods.get('abstract'), 'Enum declarations cannot be marked as abstract'));
|
||||
}
|
||||
// top-level types cannot be private, protected or static
|
||||
for (let mod of ['private','protected', 'static']) {
|
||||
if (!type.outer_type && typemods.has(mod)) {
|
||||
probs.push(ParseProblem.Error(typemods.get(mod), `Top-level declarations cannot be marked as ${mod}`));
|
||||
if (/[$]/.test(type._rawShortSignature)) {
|
||||
checkConflictingAccess(type.modifierTokens, probs);
|
||||
} else {
|
||||
// top-level types cannot be private, protected or static
|
||||
for (let mod of ['private','protected', 'static']) {
|
||||
if (typemods.has(mod)) {
|
||||
probs.push(ParseProblem.Error(typemods.get(mod), `Top-level declarations cannot be marked as ${mod}`));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type.outer_type) {
|
||||
checkConflictingAccess(type.modifiers, probs);
|
||||
}
|
||||
|
||||
type.fields.forEach(field => checkFieldModifiers(field, probs));
|
||||
type.methods.forEach(method => checkMethodModifiers(type, typemods, method, probs));
|
||||
type.constructors.forEach(ctr => checkConstructorModifiers(ctr, probs));
|
||||
//type.initialisers.forEach(initer => checkInitModifiers(initer, probs));
|
||||
// check enclosed types
|
||||
type.types.forEach(type => checkTypeModifiers(type, probs));
|
||||
type.initers.forEach(initer => checkInitialiserModifiers(initer, probs));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ModuleBlock} mod
|
||||
* @param {SourceType[]} types
|
||||
*/
|
||||
module.exports = function(mod) {
|
||||
module.exports = function(types) {
|
||||
const probs = [];
|
||||
mod.types.forEach(type => checkTypeModifiers(type, probs));
|
||||
types.forEach(type => checkTypeModifiers(type, probs));
|
||||
return probs;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
const { ModuleBlock } = require('../parser9');
|
||||
const ParseProblem = require('../parsetypes/parse-problem');
|
||||
const { SourceType } = require('../source-type');
|
||||
const {CEIType} = require('java-mti');
|
||||
@@ -49,17 +48,15 @@ function checkImplementedInterfaces(source_type, probs) {
|
||||
}
|
||||
})
|
||||
if (missing_methods.length) {
|
||||
probs.push(ParseProblem.Error(source_type.kind_token, `Non-abstract ${source_type.typeKind} '${source_type.fullyDottedRawName}' does not implement the following methods from interface '${intf.fullyDottedRawName}':\n${missing_methods.join('\n')}`));
|
||||
probs.push(ParseProblem.Error(source_type.kind_token, `Non-abstract ${source_type.typeKind} '${source_type.fullyDottedRawName}' does not implement the following methods from interface '${intf.fullyDottedTypeName}':\n${missing_methods.join('\n')}`));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ModuleBlock} mod
|
||||
* @param {*} imports
|
||||
* @param {SourceType[]} source_types
|
||||
*/
|
||||
module.exports = function(mod, imports, source_types) {
|
||||
module.exports = function(source_types) {
|
||||
/** @type {ParseProblem[]} */
|
||||
const probs = [];
|
||||
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
const { ModuleBlock } = require('../parser9');
|
||||
const { SourceUnit } = require('../source-type');
|
||||
const ParseProblem = require('../parsetypes/parse-problem');
|
||||
|
||||
/**
|
||||
* @param {ModuleBlock} mod
|
||||
* @param {{unresolved:*[]}} imports
|
||||
* @param {SourceUnit} unit
|
||||
*/
|
||||
module.exports = function(mod, imports) {
|
||||
module.exports = function(mod, unit) {
|
||||
/** @type {ParseProblem[]} */
|
||||
const probs = [];
|
||||
|
||||
imports.unresolved.forEach(import_tokens => {
|
||||
probs.push(ParseProblem.Warning(import_tokens, `Unresolved import: ${import_tokens.name}`));
|
||||
unit.imports.forEach(i => {
|
||||
if (!i.resolved)
|
||||
probs.push(ParseProblem.Warning(i.nameTokens, `Unresolved import: ${i.package_name}`));
|
||||
})
|
||||
|
||||
return probs;
|
||||
|
||||
Reference in New Issue
Block a user