Skip to content
Permalink
Browse files

Fix: Handle ClassProperty and ignored node types

Close #3198
  • Loading branch information...
antross authored and molant committed Oct 28, 2019
1 parent a03165a commit 38fb41a9ac7968540f417d5f939a7a29d978cfe2
Showing with 70 additions and 16 deletions.
  1. +12 −2 packages/parser-typescript/src/parser.ts
  2. +58 −14 packages/parser-typescript/tests/tests.ts
@@ -10,9 +10,19 @@ import { base, combineWalk } from '@hint/parser-javascript/dist/src/walk';

const debug = d(__filename);

// Extend `walk` to skip over TS-specific nodes.
// Extend `walk` to skip over most TS-specific nodes.
for (const type of Object.keys(AST_NODE_TYPES)) {
if (type.startsWith('TS') && !base[type]) {
// Ensure `value` of `ClassProperty` instances is walked.
if (type === 'ClassProperty') {
base[type] = (node: any, st: any, c: any) => {
if (node.value) {
c(node.value, st);
}
};
}

// Just ignore anything else
if (!base[type]) {
base[type] = base.Identifier;
}
}
@@ -1,8 +1,10 @@
import { AST_NODE_TYPES } from '@typescript-eslint/typescript-estree';
import test from 'ava';
import { EventEmitter2 } from 'eventemitter2';
import { Engine, FetchEnd } from 'hint';
import { HTMLEvents, HTMLParse } from '@hint/parser-html';
import { CallExpression, ScriptEvents } from '@hint/parser-javascript';
import { base } from '@hint/parser-javascript/dist/src/walk';
import JSXParser from '@hint/parser-jsx';

import TypeScriptParser from '../src/parser';
@@ -25,6 +27,14 @@ const emitFetchEndTSX = async (engine: Engine<ScriptEvents & HTMLEvents>, conten
return event;
};

const getPropertyName = (node: CallExpression) => {
const callee = node.callee;
const property = callee.type === 'MemberExpression' && callee.property;
const propertyName = property && property.type === 'Identifier' && property.name;

return propertyName;
};

const mockEngine = () => {
return new EventEmitter2({
delimiter: '::',
@@ -46,19 +56,14 @@ const parseTSX = (content: string) => {
return emitFetchEndTSX(engine, content);
};

test('It can parse and skip types to walk ESTree AST nodes', async (t) => {
const content = `type Foo = { bar: string };\nconst circle: Element = document.createElement('circle')`;
const walkCallExpressions = async (content: string) => {
const { engine } = mockContext();
const nodes: CallExpression[] = [];

let res = '';
let node: CallExpression | undefined;

engine.on('parse::end::javascript', ({ ast, walk, resource }) => {
res = resource;

engine.on('parse::end::javascript', ({ ast, walk }) => {
walk.simple(ast, {
CallExpression(n) {
node = n;
nodes.push(n);
}
});
});
@@ -71,12 +76,31 @@ test('It can parse and skip types to walk ESTree AST nodes', async (t) => {
}
} as FetchEnd);

const callee = node && node.callee;
const property = callee && callee.type === 'MemberExpression' && callee.property;
const propertyName = property && property.type === 'Identifier' && property.name;
return nodes;
};

test('It can parse and skip types to walk ESTree AST nodes', async (t) => {
const nodes = await walkCallExpressions(`
type Foo = { bar: string };
const circle: Element = document.createElement('circle');
`);

t.is(res, 'https://webhint.io/test.ts');
t.is(propertyName, 'createElement');
t.is(nodes.length, 1);
t.is(getPropertyName(nodes[0]), 'createElement');
});

test('It can walk ClassProperty instances', async (t) => {
const nodes = await walkCallExpressions(`
class Foo {
public foo: string;
public bar = () => {
const circle = document.createElement('circle');
}
}
`);

t.is(nodes.length, 1);
t.is(getPropertyName(nodes[0]), 'createElement');
});

test('It can parse JSX content within TSX files', async (t) => {
@@ -96,3 +120,23 @@ test('It can parse JSX content within TSX files', async (t) => {
t.true(button.isAttributeAnExpression('type'));
t.is(button.innerHTML, 'Click Here');
});

test('All node types are known', (t) => {
const knownNodeTypes = [
'BigIntLiteral',
'ClassProperty',
'Decorator',
'ExportSpecifier',
'Import'
];

for (const type of Object.keys(AST_NODE_TYPES)) {
const isKnown = type in base || type.startsWith('TS') || knownNodeTypes.includes(type);

if (!isKnown) {
t.log(type);
}

t.true(isKnown);
}
});

0 comments on commit 38fb41a

Please sign in to comment.
You can’t perform that action at this time.