Skip to content

Commit

Permalink
Fix: Stop path analyzer on unknown nodes (#13305)
Browse files Browse the repository at this point in the history
  • Loading branch information
ilyavolodin committed May 20, 2020
1 parent 89e1081 commit 68c8ee3
Show file tree
Hide file tree
Showing 4 changed files with 266 additions and 2 deletions.
3 changes: 2 additions & 1 deletion lib/linter/linter.js
Expand Up @@ -938,7 +938,8 @@ function runRules(sourceCode, configuredRules, ruleMapper, parserOptions, parser
});
});

const eventGenerator = new CodePathAnalyzer(new NodeEventGenerator(emitter));
// only run code path analyzer if the top level node is "Program", skip otherwise
const eventGenerator = nodeQueue[0].node.type === "Program" ? new CodePathAnalyzer(new NodeEventGenerator(emitter)) : new NodeEventGenerator(emitter);

nodeQueue.forEach(traversalInfo => {
currentNode = traversalInfo.node;
Expand Down
3 changes: 2 additions & 1 deletion tests/fixtures/parsers/linter-test-parsers.js
Expand Up @@ -10,5 +10,6 @@ module.exports = {
noLineError: require("./no-line-error"),
enhancedParser2: require("./enhanced-parser2"),
enhancedParser3: require("./enhanced-parser3"),
throwsWithOptions: require("./throws-with-options")
throwsWithOptions: require("./throws-with-options"),
nonJSParser: require('./non-js-parser')
};
238 changes: 238 additions & 0 deletions tests/fixtures/parsers/non-js-parser.js
@@ -0,0 +1,238 @@
/**
* Source code:
* function foo(a: number=0): Foo { }
*/

exports.parseForESLint = () => ({
ast: {
"kind": "Document",
"definitions": [
{
"kind": "ObjectTypeExtension",
"name": {
"kind": "Name",
"value": "Query",
"loc": {
"start": 12,
"end": 17
},
"type": "Name"
},
"interfaces": [],
"directives": [],
"fields": [
{
"kind": "FieldDefinition",
"name": {
"kind": "Name",
"value": "login",
"loc": {
"start": 24,
"end": 29
},
"type": "Name"
},
"arguments": [
{
"kind": "InputValueDefinition",
"name": {
"kind": "Name",
"value": "input",
"loc": {
"start": 30,
"end": 35
},
"type": "Name"
},
"type": "InputValueDefinition",
"directives": [],
"loc": {
"start": 30,
"end": 49
},
"fieldType": {
"kind": "NonNullType",
"type": "NonNullType",
"loc": {
"start": 37,
"end": 49
},
"fieldType": {
"kind": "NamedType",
"name": {
"kind": "Name",
"value": "Credentials",
"loc": {
"start": 37,
"end": 48
},
"type": "Name"
},
"loc": {
"start": 37,
"end": 48
},
"type": "NamedType"
}
}
}
],
"type": "FieldDefinition",
"directives": [],
"loc": {
"start": 24,
"end": 63
},
"fieldType": {
"kind": "NamedType",
"name": {
"kind": "Name",
"value": "UserProfile",
"loc": {
"start": 52,
"end": 63
},
"type": "Name"
},
"loc": {
"start": 52,
"end": 63
},
"type": "NamedType"
}
}
],
"loc": {
"start": 0,
"end": 65
},
"type": "ObjectTypeExtension"
},
{
"kind": "InputObjectTypeDefinition",
"name": {
"kind": "Name",
"value": "Credentials",
"loc": {
"start": 73,
"end": 84
},
"type": "Name"
},
"directives": [],
"fields": [
{
"kind": "InputValueDefinition",
"name": {
"kind": "Name",
"value": "login",
"loc": {
"start": 91,
"end": 96
},
"type": "Name"
},
"type": "InputValueDefinition",
"directives": [],
"loc": {
"start": 91,
"end": 105
},
"fieldType": {
"kind": "NonNullType",
"type": "NonNullType",
"loc": {
"start": 98,
"end": 105
},
"fieldType": {
"kind": "NamedType",
"name": {
"kind": "Name",
"value": "String",
"loc": {
"start": 98,
"end": 104
},
"type": "Name"
},
"loc": {
"start": 98,
"end": 104
},
"type": "NamedType"
}
}
},
{
"kind": "InputValueDefinition",
"name": {
"kind": "Name",
"value": "password",
"loc": {
"start": 110,
"end": 118
},
"type": "Name"
},
"type": "InputValueDefinition",
"directives": [],
"loc": {
"start": 110,
"end": 127
},
"fieldType": {
"kind": "NonNullType",
"type": "NonNullType",
"loc": {
"start": 120,
"end": 127
},
"fieldType": {
"kind": "NamedType",
"name": {
"kind": "Name",
"value": "String",
"loc": {
"start": 120,
"end": 126
},
"type": "Name"
},
"loc": {
"start": 120,
"end": 126
},
"type": "NamedType"
}
}
}
],
"loc": {
"start": 67,
"end": 129
},
"type": "InputObjectTypeDefinition"
}
],
"loc": {
"start": 0,
"end": 130
},
"type": "Document",
"tokens": [],
"comments": [],
"range": {}
},
services: {},
scopeManager: { variables: [], scopes: [{ set: new Map(), variables: [], through: [] }], getDeclaredVariables: () => {} },
visitorKeys: {
Document: ['definitions'],
ObjectTypeDefinition: ['interfaces', 'directives', 'fields'],
ObjectTypeExtension: ['interfaces', 'directives', 'fields'],
InputObjectTypeDefinition: ['directives', 'fields'],
InputValueDefinition: ['directives', 'fieldType'],
FieldDefinition: ['directives', 'fieldType', 'arguments'],
EnumTypeDefinition: ['directives', 'values']
}
});
24 changes: 24 additions & 0 deletions tests/lib/linter/linter.js
Expand Up @@ -5247,6 +5247,30 @@ var a = "test2";
assert.strictEqual(messages.length, 0);
});

it("should not throw or return errors when the custom parser returns unknown AST nodes", () => {
const code = "foo && bar %% baz";

const nodes = [];

linter.defineRule("collect-node-types", () => ({
"*"(node) {
nodes.push(node.type);
}
}));

linter.defineParser("non-js-parser", testParsers.nonJSParser);

const messages = linter.verify(code, {
parser: "non-js-parser",
rules: {
"collect-node-types": "error"
}
}, filename, true);

assert.strictEqual(messages.length, 0);
assert.isTrue(nodes.length > 0);
});

it("should strip leading line: prefix from parser error", () => {
linter.defineParser("line-error", testParsers.lineError);
const messages = linter.verify(";", { parser: "line-error" }, "filename");
Expand Down

0 comments on commit 68c8ee3

Please sign in to comment.