Skip to content

Commit

Permalink
set parent pointers as part of the ESTree parse
Browse files Browse the repository at this point in the history
Summary:
Do a final traversal of the AST at the end of the conversion to set the parent pointers.
In the ESLint world, these are set by ESLint just before the lint run. This isn't helpful for us because it means we can't use them within the hermes packages (like in hermes-eslint or hermes-transform).

Reviewed By: pieterv

Differential Revision: D38064433

fbshipit-source-id: 7e6d4c3556e3961797dd96d45aaa8fb01096b639
  • Loading branch information
bradzacher authored and facebook-github-bot committed Jul 22, 2022
1 parent 2d449cb commit 020072e
Show file tree
Hide file tree
Showing 16 changed files with 27 additions and 37 deletions.
10 changes: 10 additions & 0 deletions tools/hermes-parser/js/hermes-eslint/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@ function parseForESLint(
visitorKeys: VisitorKeysType,
} {
const ast = parse(code, options);

// set the parent pointers
HermesParser.SimpleTraverser.traverse(ast, {
enter(node, parent) {
// $FlowExpectedError[cannot-write]
node.parent = parent;
},
leave() {},
});

const scopeManager = analyze(ast, options);

return {
Expand Down
Empty file.
2 changes: 2 additions & 0 deletions tools/hermes-parser/js/hermes-parser/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,5 @@ export function parse(
}

export type {ParserOptions} from './ParserOptions';
export * from './traverse/SimpleTraverser';
export * from './traverse/getVisitorKeys';
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import type {ESNode} from 'hermes-estree';

import {getVisitorKeys, isNode} from '../getVisitorKeys';
import {getVisitorKeys, isNode} from './getVisitorKeys';

export type TraverserCallback = (node: ESNode, parent: ?ESNode) => void;
export type TraverserOptions = $ReadOnly<{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import type {ESNode, Program} from 'hermes-estree';

import {parseForESLint} from 'hermes-eslint';
import {SimpleTraverser} from '../../src/traverse/SimpleTraverser';
import {SimpleTraverser} from 'hermes-parser';
import {SafeEmitter} from '../../src/traverse/SafeEmitter';
import {NodeEventGenerator} from '../../src/traverse/NodeEventGenerator';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,25 +54,6 @@ describe('traverse', () => {
]);
});

it('sets the parent pointers', () => {
const code = 'const x = 1;';
const {ast, scopeManager} = parseForESLint(code);

expect(ast.body[0]).not.toHaveProperty('parent');
traverse(code, ast, scopeManager, () => ({
'*'(node) {
expect(node).toHaveProperty('parent');
if (node.type === 'Program') {
// eslint-disable-next-line jest/no-conditional-expect
expect(node.parent).toBeNull();
} else {
// eslint-disable-next-line jest/no-conditional-expect
expect(node.parent).toHaveProperty('type');
}
},
}));
});

it('passes an immutable context object', () => {
const code = 'const x = 1;';
const {ast, scopeManager} = parseForESLint(code);
Expand Down
3 changes: 2 additions & 1 deletion tools/hermes-parser/js/hermes-transform/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"esquery": "^1.4.0",
"flow-enums-runtime": "^0.0.6",
"hermes-eslint": "0.9.0",
"hermes-estree": "0.9.0"
"hermes-estree": "0.9.0",
"hermes-parser": "0.9.0"
},
"peerDependencies": {
"prettier": "^2.4.1"
Expand Down
3 changes: 1 addition & 2 deletions tools/hermes-parser/js/hermes-transform/src/detachedNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@

import type {BaseNode, ESNode} from 'hermes-estree';

import {getVisitorKeys, isNode} from './getVisitorKeys';
import {SimpleTraverser} from './traverse/SimpleTraverser';
import {SimpleTraverser, getVisitorKeys, isNode} from 'hermes-parser';

export opaque type DetachedNode<+T> = T;
export type MaybeDetachedNode<+T> = T | DetachedNode<T>;
Expand Down
2 changes: 1 addition & 1 deletion tools/hermes-parser/js/hermes-transform/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export type {TransformVisitor} from './transform/transform';
export type {TransformContext} from './transform/TransformContext';
export type {DetachedNode} from './detachedNode';

export {SimpleTraverser} from './traverse/SimpleTraverser';
export {SimpleTraverser} from 'hermes-parser';
export {traverse, traverseWithContext} from './traverse/traverse';
export {transform} from './transform/transform';
export * as t from './generated/node-types';
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ function getSortedChildNodes(node, options, resultArray) {
key !== 'precedingNode' &&
key !== 'followingNode' &&
key !== 'tokens' &&
key !== 'comments',
key !== 'comments' &&
key !== 'parent',
)
.map(([, value]) => value));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@
*/

import type {Comment, Program} from 'hermes-estree';
import {
SimpleTraverser,
SimpleTraverserBreak,
} from '../../traverse/SimpleTraverser';

import {SimpleTraverser, SimpleTraverserBreak} from 'hermes-parser';
import {getCommentsForNode, setCommentsOnNode} from '../comments/comments';

export type RemoveCommentMutation = $ReadOnly<{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import type {ESNode} from 'hermes-estree';
import type {MutationContext} from '../MutationContext';
import type {DetachedNode} from '../../detachedNode';

import {getVisitorKeys, isNode} from 'hermes-parser';
import {replaceInArray} from './utils/arrayUtils';
import {moveCommentsToNewNode} from '../comments/comments';
import {InvalidReplacementError} from '../Errors';
import {getOriginalNode} from '../../detachedNode';
import {getVisitorKeys, isNode} from '../../getVisitorKeys';

export type ReplaceNodeMutation = $ReadOnly<{
type: 'replaceNode',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import type {ESNode} from 'hermes-estree';
import type {Visitor} from '../traverse/traverse';
import type {TransformContextAdditions} from './TransformContext';

import {SimpleTraverser} from 'hermes-parser';
import * as prettier from 'prettier';
import {getTransformedAST} from './getTransformedAST';
import {SimpleTraverser} from '../traverse/SimpleTraverser';

export type TransformVisitor = Visitor<TransformContextAdditions>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import type {EmitterListener} from './SafeEmitter';
import {codeFrameColumns} from '@babel/code-frame';
import {NodeEventGenerator} from './NodeEventGenerator';
import {SafeEmitter} from './SafeEmitter';
import {SimpleTraverser} from './SimpleTraverser';
import {SimpleTraverser} from 'hermes-parser';

export type TraversalContextBase = $ReadOnly<{
/**
Expand Down Expand Up @@ -81,11 +81,9 @@ export function traverseWithContext<T = TraversalContextBase>(

let currentNode: ESNode = ast;

// set parent pointers and build up the traversal queue
// build up the traversal queue
SimpleTraverser.traverse(ast, {
enter(node, parent) {
// $FlowExpectedError[cannot-write] - hermes doesn't set this
node.parent = parent;
enter(node) {
nodeQueue.push({isEntering: true, node});
},
leave(node) {
Expand Down

0 comments on commit 020072e

Please sign in to comment.