@amplitude/ampli
Version:
Amplitude CLI
89 lines (88 loc) • 4.16 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const lodash_1 = require("lodash");
const antlr4ts_1 = require("antlr4ts");
const ParseTreeWalker_1 = require("antlr4ts/tree/ParseTreeWalker");
const ObjectiveCLexer_1 = require("../../antlr/objc/ObjectiveCLexer");
const ObjectiveCParser_1 = require("../../antlr/objc/ObjectiveCParser");
const base_1 = require("../base");
const string_1 = require("../../util/string");
const DEFAULT_ITLY_INSTANCE_NAMES = [
'Itly', '[Itlyinstance]',
'Itly.instance', '[Itly instance]',
];
const sortByLengthDescending = (a, b) => b.length - a.length;
class ItlyListener {
constructor(eventNames, addReference, itlyInstanceNames) {
this.eventNames = eventNames;
this.addReference = addReference;
this.itlyInstanceNames = itlyInstanceNames;
this.eventClassNames = eventNames.map(e => string_1.upperCamelCase(e));
this.sortedEventMethodNames = eventNames.map(e => lodash_1.camelCase(e)).sort(sortByLengthDescending);
}
enterMessageExpression(context) {
if (!context || !context.children || context.children.length < 4) {
return;
}
const receiver = context.children[1];
if (!receiver || !(receiver instanceof ObjectiveCParser_1.ReceiverContext)) {
return;
}
const receiverName = receiver.text;
if (this.eventClassNames.includes(receiverName)) {
this.addReference(lodash_1.camelCase(receiverName), context.start.line, context.start.charPositionInLine);
return;
}
if (!this.itlyInstanceNames.includes(receiverName)) {
return;
}
const messageSelector = context.children[2];
if (!messageSelector || !(messageSelector instanceof ObjectiveCParser_1.MessageSelectorContext)
|| !messageSelector.children || messageSelector.children.length < 1) {
return;
}
const call = messageSelector.children[0];
if (!call) {
return;
}
let text = null;
if (call instanceof ObjectiveCParser_1.SelectorContext && call.text) {
text = call.text;
}
else if (call instanceof ObjectiveCParser_1.KeywordArgumentContext && call.children && call.children.length === 3) {
const selector = call.children[0];
if (selector && selector instanceof ObjectiveCParser_1.SelectorContext && selector.text) {
text = selector.text;
}
}
if (!text) {
return;
}
for (const eventMethod of this.sortedEventMethodNames) {
if (lodash_1.startsWith(text, eventMethod)) {
text = eventMethod;
break;
}
}
this.addReference(text, context.start.line, context.start.charPositionInLine);
}
}
class ObjectiveCVerifierV1 extends base_1.Verifier {
constructor(ampliInstanceNames = DEFAULT_ITLY_INSTANCE_NAMES, fileExtensionPattern = 'm', fileFilter) {
super(fileExtensionPattern, ampliInstanceNames.map(name => `[${name} `), fileFilter);
this.ampliInstanceNames = ampliInstanceNames;
}
async doVerify(eventNames, workingDirs) {
const sanitizedEventNames = eventNames.map(e => string_1.upperCamelCase(e));
return this.verifyEach((filePath, fileContents, addReference) => {
const sanitizedFileContents = fileContents.replace(/ API_AVAILABLE\(.*\)\)/g, '');
const inputStream = new antlr4ts_1.ANTLRInputStream(sanitizedFileContents);
const lexer = new ObjectiveCLexer_1.ObjectiveCLexer(inputStream);
const tokenStream = new antlr4ts_1.CommonTokenStream(lexer);
const parser = new ObjectiveCParser_1.ObjectiveCParser(tokenStream);
const listener = new ItlyListener(sanitizedEventNames, (name, row, column) => addReference({ filePath, name, row, column }), this.ampliInstanceNames);
ParseTreeWalker_1.ParseTreeWalker.DEFAULT.walk(listener, parser.translationUnit());
}, workingDirs);
}
}
exports.default = ObjectiveCVerifierV1;