mirror of
https://github.com/captbaritone/webamp.git
synced 2026-01-23 18:25:30 +00:00
125 lines
3.8 KiB
JavaScript
125 lines
3.8 KiB
JavaScript
const { objects } = require("./modern/src/maki-interpreter/objects");
|
|
|
|
const classNameMappings = {
|
|
Object: "MakiObject",
|
|
"@{00000000-0000-0000-0000-000000000000}@": null,
|
|
};
|
|
|
|
function normalizeClassName(className) {
|
|
const normalized = classNameMappings[className];
|
|
return normalized === undefined ? className : normalized;
|
|
}
|
|
|
|
const objectsByName = {};
|
|
for (const value of Object.values(objects)) {
|
|
objectsByName[normalizeClassName(value.name)] = value;
|
|
}
|
|
|
|
module.exports = {
|
|
"maki-methods": {
|
|
meta: {
|
|
docs: {
|
|
description: "Ensure Maki objects match std.mi",
|
|
category: "Possible Errors",
|
|
recommended: false,
|
|
},
|
|
schema: [],
|
|
},
|
|
create: function(context) {
|
|
let currentObject = null;
|
|
return {
|
|
"ClassDeclaration:exit": function() {
|
|
currentObject = null;
|
|
},
|
|
ClassDeclaration: function(node) {
|
|
const className = node.id.name;
|
|
// https://github.com/captbaritone/webamp/pull/828#issuecomment-518023519
|
|
if (className.startsWith("Js")) {
|
|
return;
|
|
}
|
|
currentObject = objectsByName[className];
|
|
if (currentObject == null) {
|
|
context.report({
|
|
node: node.id,
|
|
message: `Unknown Maki Class \`${className}\`.`,
|
|
});
|
|
return;
|
|
}
|
|
const expectedParentClassName = normalizeClassName(
|
|
currentObject.parent
|
|
);
|
|
if (expectedParentClassName == null) {
|
|
if (node.superClass !== null) {
|
|
context.report({
|
|
node: node.id,
|
|
message: `Unexpected parent class for \`${className}\`. \`${className}\` should not extend any class.`,
|
|
});
|
|
}
|
|
// This is probably MakiObject which does not inherit from anything
|
|
return;
|
|
}
|
|
const parentClassName = node.superClass.name;
|
|
if (parentClassName !== expectedParentClassName) {
|
|
context.report({
|
|
node: node.superClass,
|
|
message: `Incorrect parent class \`${parentClassName}\`. Expected \`${expectedParentClassName}\`.`,
|
|
});
|
|
}
|
|
},
|
|
ClassBody: function() {
|
|
if (currentObject == null) {
|
|
return;
|
|
}
|
|
// TODO: Check for missing methods
|
|
},
|
|
MethodDefinition: function(node) {
|
|
if (currentObject == null) {
|
|
return;
|
|
}
|
|
const methods = {};
|
|
currentObject.functions.forEach(func => {
|
|
methods[func.name.toLowerCase()] = func;
|
|
});
|
|
|
|
const methodName = node.key.name;
|
|
// Theoretically this should only be implemented on Object, but it's
|
|
// easier to let each class implement it themselves.
|
|
if (methodName === "getclassname") {
|
|
return;
|
|
}
|
|
if (methodName === "constructor") {
|
|
return;
|
|
}
|
|
|
|
// Non-maki methods may be implemented using the `js_` prefix.
|
|
if (methodName.startsWith("js_")) {
|
|
return;
|
|
}
|
|
|
|
const func = methods[methodName];
|
|
if (func == null) {
|
|
context.report({
|
|
node: node.key,
|
|
message: `Invalid Maki method name \`${methodName}\``,
|
|
});
|
|
return;
|
|
}
|
|
/*
|
|
|
|
const args = node.value.params.map(param => param.name);
|
|
|
|
func.parameters.forEach(([, name], i) => {
|
|
const actual = args[i];
|
|
if (actual !== name) {
|
|
context.report({
|
|
node: node.value.params[i],
|
|
message: `Invalid Maki method argument name \`${actual}\`. Expected \`${name}\`.`,
|
|
});
|
|
}
|
|
});
|
|
*/
|
|
},
|
|
};
|
|
},
|
|
},
|
|
};
|