|
| 1 | +// import { |
| 2 | +// TransformationContext, |
| 3 | +// EmitHint, |
| 4 | +// Node, |
| 5 | +// JsxEmit, |
| 6 | +// SyntaxKind, |
| 7 | +// SourceFile, |
| 8 | +// JsxSelfClosingElement, |
| 9 | +// JsxClosingElement, |
| 10 | +// JsxOpeningElement, |
| 11 | +// Bundle, |
| 12 | +// isPropertyAccessExpression, |
| 13 | +// isPropertyAssignment, |
| 14 | +// PropertyAccessExpression, |
| 15 | +// Expression, |
| 16 | +// createElementAccess, |
| 17 | +// setTextRange, |
| 18 | +// PropertyAssignment, |
| 19 | +// isIdentifier, |
| 20 | +// updatePropertyAssignment, |
| 21 | +// Identifier, |
| 22 | +// } from 'typescript'; |
| 23 | +// import { chainBundle, getOriginalNodeId, getNodeId } from './utilis'; |
| 24 | + |
| 25 | +// export default function hoistingTransformer( |
| 26 | +// context: TransformationContext, |
| 27 | +// ): (x: SourceFile | Bundle) => SourceFile | Bundle { |
| 28 | +// const compilerOptions = context.getCompilerOptions(); |
| 29 | + |
| 30 | +// // enable emit notification only if using --jsx preserve or react-native |
| 31 | +// let previousOnEmitNode: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void; |
| 32 | +// let noSubstitution: boolean[]; |
| 33 | + |
| 34 | +// if (compilerOptions.jsx === JsxEmit.Preserve || compilerOptions.jsx === JsxEmit.ReactNative) { |
| 35 | +// previousOnEmitNode = context.onEmitNode; |
| 36 | +// context.onEmitNode = onEmitNode; |
| 37 | +// context.enableEmitNotification(SyntaxKind.JsxOpeningElement); |
| 38 | +// context.enableEmitNotification(SyntaxKind.JsxClosingElement); |
| 39 | +// context.enableEmitNotification(SyntaxKind.JsxSelfClosingElement); |
| 40 | +// noSubstitution = []; |
| 41 | +// } |
| 42 | + |
| 43 | +// const previousOnSubstituteNode = context.onSubstituteNode; |
| 44 | +// context.onSubstituteNode = onSubstituteNode; |
| 45 | +// context.enableSubstitution(SyntaxKind.PropertyAccessExpression); |
| 46 | +// context.enableSubstitution(SyntaxKind.PropertyAssignment); |
| 47 | +// return chainBundle(transformSourceFile); |
| 48 | + |
| 49 | +// function transformSourceFile(node: SourceFile) { |
| 50 | +// return node; |
| 51 | +// } |
| 52 | + |
| 53 | +// /** |
| 54 | +// * Called by the printer just before a node is printed. |
| 55 | +// * |
| 56 | +// * @param hint A hint as to the intended usage of the node. |
| 57 | +// * @param node The node to emit. |
| 58 | +// * @param emitCallback A callback used to emit the node. |
| 59 | +// */ |
| 60 | +// function onEmitNode(hint: EmitHint, node: Node, emitCallback: (emitContext: EmitHint, node: Node) => void) { |
| 61 | +// switch (node.kind) { |
| 62 | +// case SyntaxKind.JsxOpeningElement: |
| 63 | +// case SyntaxKind.JsxClosingElement: |
| 64 | +// case SyntaxKind.JsxSelfClosingElement: |
| 65 | +// const tagName = (node as JsxOpeningElement | JsxClosingElement | JsxSelfClosingElement).tagName; |
| 66 | +// noSubstitution[getOriginalNodeId(tagName)] = true; |
| 67 | +// break; |
| 68 | +// } |
| 69 | + |
| 70 | +// previousOnEmitNode(hint, node, emitCallback); |
| 71 | +// } |
| 72 | + |
| 73 | +// /** |
| 74 | +// * Hooks node substitutions. |
| 75 | +// * |
| 76 | +// * @param hint A hint as to the intended usage of the node. |
| 77 | +// * @param node The node to substitute. |
| 78 | +// */ |
| 79 | +// function onSubstituteNode(hint: EmitHint, node: Node) { |
| 80 | +// if (getNodeId(node) && noSubstitution && noSubstitution[getNodeId(node)]) { |
| 81 | +// return previousOnSubstituteNode(hint, node); |
| 82 | +// } |
| 83 | + |
| 84 | +// node = previousOnSubstituteNode(hint, node); |
| 85 | +// if (isPropertyAccessExpression(node)) { |
| 86 | +// return substitutePropertyAccessExpression(node); |
| 87 | +// } else if (isPropertyAssignment(node)) { |
| 88 | +// return substitutePropertyAssignment(node); |
| 89 | +// } |
| 90 | +// return node; |
| 91 | +// } |
| 92 | + |
| 93 | +// /** |
| 94 | +// * Substitutes a PropertyAccessExpression whose name is a reserved word. |
| 95 | +// * |
| 96 | +// * @param node A PropertyAccessExpression |
| 97 | +// */ |
| 98 | +// function substitutePropertyAccessExpression(node: PropertyAccessExpression): Expression { |
| 99 | +// const literalName = trySubstituteReservedName(node.name); |
| 100 | +// if (literalName) { |
| 101 | +// return setTextRange(createElementAccess(node.expression, literalName), node); |
| 102 | +// } |
| 103 | +// return node; |
| 104 | +// } |
| 105 | + |
| 106 | +// /** |
| 107 | +// * Substitutes a PropertyAssignment whose name is a reserved word. |
| 108 | +// * |
| 109 | +// * @param node A PropertyAssignment |
| 110 | +// */ |
| 111 | +// function substitutePropertyAssignment(node: PropertyAssignment): PropertyAssignment { |
| 112 | +// const literalName = isIdentifier(node.name) && trySubstituteReservedName(node.name); |
| 113 | +// if (literalName) { |
| 114 | +// return updatePropertyAssignment(node, literalName, node.initializer); |
| 115 | +// } |
| 116 | +// return node; |
| 117 | +// } |
| 118 | + |
| 119 | +// /** |
| 120 | +// * If an identifier name is a reserved word, returns a string literal for the name. |
| 121 | +// * |
| 122 | +// * @param name An Identifier |
| 123 | +// */ |
| 124 | +// function trySubstituteReservedName(name: Identifier) { |
| 125 | +// const token = name.originalKeywordKind || (nodeIsSynthesized(name) ? stringToToken(idText(name)) : undefined); |
| 126 | +// if (token !== undefined && token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord) { |
| 127 | +// return setTextRange(createLiteral(name), name); |
| 128 | +// } |
| 129 | +// return undefined; |
| 130 | +// } |
| 131 | +// } |
0 commit comments