mirror of
https://github.com/adelphes/android-dev-ext.git
synced 2025-12-23 01:48:18 +00:00
67 lines
2.1 KiB
JavaScript
67 lines
2.1 KiB
JavaScript
const ParseProblem = require('../parsetypes/parse-problem');
|
|
const { SourceType } = require('../source-type');
|
|
const {CEIType} = require('java-mti');
|
|
|
|
function nonAbstractLabel(label) {
|
|
return label.replace(/\babstract /g, '');
|
|
}
|
|
|
|
/**
|
|
* @param {SourceType} source_type
|
|
* @param {*} probs
|
|
*/
|
|
function checkImplementedInterfaces(source_type, probs) {
|
|
if (source_type.implements_types.length === 0) {
|
|
return;
|
|
}
|
|
if (source_type.typeKind === 'interface') {
|
|
return;
|
|
}
|
|
if (source_type.modifiers.includes('abstract')) {
|
|
return;
|
|
}
|
|
/** @type {Set<CEIType>} */
|
|
const interfaces = new Set(), supers_done = new Set();
|
|
const supers = source_type.supers.slice();
|
|
while (supers.length) {
|
|
const s = supers.shift();
|
|
supers_done.add(s);
|
|
if (s instanceof CEIType) {
|
|
if (s.typeKind === 'interface') {
|
|
interfaces.add(s);
|
|
}
|
|
s.supers.filter(s => !supers_done.has(s)).forEach(s => supers.push(s));
|
|
}
|
|
}
|
|
|
|
const implemented = source_type.methods.map(m => `${m.name}${m.methodSignature}`);
|
|
interfaces.forEach((intf, i) => {
|
|
const missing_methods = [];
|
|
intf.methods.forEach(m => {
|
|
// default methods don't require implementing
|
|
if (m.hasImplementation) {
|
|
return;
|
|
}
|
|
const namedsig = `${m.name}${m.methodSignature}`
|
|
if (implemented.indexOf(namedsig) < 0) {
|
|
missing_methods.push(nonAbstractLabel(m.label));
|
|
}
|
|
})
|
|
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.fullyDottedTypeName}':\n${missing_methods.join('\n')}`));
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @param {SourceType[]} source_types
|
|
*/
|
|
module.exports = function(source_types) {
|
|
/** @type {ParseProblem[]} */
|
|
const probs = [];
|
|
|
|
source_types.forEach(type => checkImplementedInterfaces(type, probs));
|
|
|
|
return probs;
|
|
}
|