Skip to content

Commit

Permalink
ASTVisitor: use type intersection instead of type union (#2959)
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanGoncharov committed Mar 13, 2021
1 parent 2c2d87e commit 789a98a
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 18 deletions.
18 changes: 9 additions & 9 deletions src/language/visitor.d.ts
Expand Up @@ -6,17 +6,17 @@ import { ASTNode, ASTKindToNode } from './ast';
* A visitor is provided to visit, it contains the collection of
* relevant functions to be called during the visitor's traversal.
*/
export type ASTVisitor = EnterLeave<ASTVisitFn<ASTNode>> | ShapeMapVisitor;
export type ASTVisitor = EnterLeaveVisitor<ASTNode> & KindVisitor;

interface EnterLeave<T> {
readonly enter?: T;
readonly leave?: T;
}

type ShapeMapVisitor = {
[K in keyof ASTKindToNode]?:
type KindVisitor = {
readonly [K in keyof ASTKindToNode]?:
| ASTVisitFn<ASTKindToNode[K]>
| EnterLeave<ASTVisitFn<ASTKindToNode[K]>>;
| EnterLeaveVisitor<ASTKindToNode[K]>;
};

type EnterLeaveVisitor<TVisitedNode extends ASTNode> = {
readonly enter?: ASTVisitFn<TVisitedNode>;
readonly leave?: ASTVisitFn<TVisitedNode>;
};

/**
Expand Down
20 changes: 11 additions & 9 deletions src/language/visitor.js
Expand Up @@ -7,14 +7,17 @@ import { isNode } from './ast';
* A visitor is provided to visit, it contains the collection of
* relevant functions to be called during the visitor's traversal.
*/
export type ASTVisitor =
| EnterLeave<ASTVisitFn<ASTNode>>
| ShapeMap<
ASTKindToNode,
<Node>(Node) => ASTVisitFn<Node> | EnterLeave<ASTVisitFn<Node>>,
>;
type EnterLeave<T> = {| +enter?: T, +leave?: T |};
type ShapeMap<O, F> = $Shape<$ObjMap<O, F>>;
export type ASTVisitor = $Shape<EnterLeaveVisitor<ASTNode> & KindVisitor>;

type KindVisitor = $ObjMap<
ASTKindToNode,
<Node>(Node) => ASTVisitFn<Node> | EnterLeaveVisitor<Node>,
>;

type EnterLeaveVisitor<TVisitedNode: ASTNode> = {|
+enter?: ASTVisitFn<TVisitedNode>,
+leave?: ASTVisitFn<TVisitedNode>,
|};

/**
* A visitor is comprised of visit functions, which are called on each node
Expand Down Expand Up @@ -389,7 +392,6 @@ export function getVisitFn(
return kindSpecificVisitor;
}
} else {
// $FlowFixMe[prop-missing]
const specificVisitor = isLeaving ? visitor.leave : visitor.enter;
if (specificVisitor) {
// { enter() {}, leave() {} }
Expand Down

0 comments on commit 789a98a

Please sign in to comment.