Merge pull request #9852 from Microsoft/transforms-visitPerf

[Transforms] Address visitor performance.
This commit is contained in:
Ron Buckton
2016-07-21 17:49:44 -07:00
committed by GitHub
12 changed files with 1772 additions and 1204 deletions
+3 -1
View File
@@ -355,7 +355,9 @@ namespace ts {
export function addRange<T>(to: T[], from: T[]): void {
if (to && from) {
for (const v of from) {
to.push(v);
if (v !== undefined) {
to.push(v);
}
}
}
}
+713 -156
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -1441,6 +1441,7 @@ namespace ts {
// checked is to not pass the file to getEmitResolver.
const emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile);
performance.emit("beforeEmit");
const emitStart = performance.mark();
const emitResult = emitFiles(
@@ -1449,6 +1450,7 @@ namespace ts {
sourceFile);
performance.measure("emitTime", emitStart);
performance.emit("afterEmit");
return emitResult;
}
@@ -351,7 +351,9 @@ namespace ts {
value = ensureIdentifier(value, /*reuseIdentifierExpressions*/ true, location, emitTempVariableAssignment);
return createConditional(
createStrictEquality(value, createVoidZero()),
createToken(SyntaxKind.QuestionToken),
defaultValue,
createToken(SyntaxKind.ColonToken),
value
);
}
+44 -27
View File
@@ -1196,7 +1196,7 @@ namespace ts {
*/
function transformAccessorsToStatement(receiver: LeftHandSideExpression, accessors: AllAccessorDeclarations): Statement {
const statement = createStatement(
transformAccessorsToExpression(receiver, accessors),
transformAccessorsToExpression(receiver, accessors, /*startsOnNewLine*/ false),
/*location*/ getSourceMapRange(accessors.firstAccessor)
);
@@ -1213,7 +1213,7 @@ namespace ts {
*
* @param receiver The receiver for the member.
*/
function transformAccessorsToExpression(receiver: LeftHandSideExpression, { firstAccessor, getAccessor, setAccessor }: AllAccessorDeclarations): Expression {
function transformAccessorsToExpression(receiver: LeftHandSideExpression, { firstAccessor, getAccessor, setAccessor }: AllAccessorDeclarations, startsOnNewLine: boolean): Expression {
// To align with source maps in the old emitter, the receiver and property name
// arguments are both mapped contiguously to the accessor name.
const target = getMutableClone(receiver);
@@ -1246,7 +1246,7 @@ namespace ts {
createPropertyAssignment("configurable", createLiteral(true))
);
return createCall(
const call = createCall(
createPropertyAccess(createIdentifier("Object"), "defineProperty"),
/*typeArguments*/ undefined,
[
@@ -1255,6 +1255,10 @@ namespace ts {
createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true)
]
);
if (startsOnNewLine) {
call.startsOnNewLine = true;
}
return call;
}
/**
@@ -1895,26 +1899,27 @@ namespace ts {
// Write out the first non-computed properties, then emit the rest through indexing on the temp variable.
const expressions: Expression[] = [];
addNode(expressions,
createAssignment(
temp,
setNodeEmitFlags(
createObjectLiteral(
visitNodes(properties, visitor, isObjectLiteralElement, 0, numInitialProperties),
/*location*/ undefined,
node.multiLine
),
NodeEmitFlags.Indented
)
),
node.multiLine
const assignment = createAssignment(
temp,
setNodeEmitFlags(
createObjectLiteral(
visitNodes(properties, visitor, isObjectLiteralElement, 0, numInitialProperties),
/*location*/ undefined,
node.multiLine
),
NodeEmitFlags.Indented
)
);
if (node.multiLine) {
assignment.startsOnNewLine = true;
}
expressions.push(assignment);
addObjectLiteralMembers(expressions, node, temp, numInitialProperties);
// We need to clone the temporary identifier so that we can write it on a
// new line
addNode(expressions, getMutableClone(temp), node.multiLine);
expressions.push(node.multiLine ? startOnNewLine(getMutableClone(temp)) : temp);
return inlineExpressions(expressions);
}
@@ -2313,21 +2318,21 @@ namespace ts {
case SyntaxKind.SetAccessor:
const accessors = getAllAccessorDeclarations(node.properties, <AccessorDeclaration>property);
if (property === accessors.firstAccessor) {
addNode(expressions, transformAccessorsToExpression(receiver, accessors), node.multiLine);
expressions.push(transformAccessorsToExpression(receiver, accessors, node.multiLine));
}
break;
case SyntaxKind.PropertyAssignment:
addNode(expressions, transformPropertyAssignmentToExpression(node, <PropertyAssignment>property, receiver), node.multiLine);
expressions.push(transformPropertyAssignmentToExpression(node, <PropertyAssignment>property, receiver, node.multiLine));
break;
case SyntaxKind.ShorthandPropertyAssignment:
addNode(expressions, transformShorthandPropertyAssignmentToExpression(node, <ShorthandPropertyAssignment>property, receiver), node.multiLine);
expressions.push(transformShorthandPropertyAssignmentToExpression(node, <ShorthandPropertyAssignment>property, receiver, node.multiLine));
break;
case SyntaxKind.MethodDeclaration:
addNode(expressions, transformObjectLiteralMethodDeclarationToExpression(node, <MethodDeclaration>property, receiver), node.multiLine);
expressions.push(transformObjectLiteralMethodDeclarationToExpression(node, <MethodDeclaration>property, receiver, node.multiLine));
break;
default:
@@ -2344,8 +2349,8 @@ namespace ts {
* @param property The PropertyAssignment node.
* @param receiver The receiver for the assignment.
*/
function transformPropertyAssignmentToExpression(node: ObjectLiteralExpression, property: PropertyAssignment, receiver: Expression) {
return createAssignment(
function transformPropertyAssignmentToExpression(node: ObjectLiteralExpression, property: PropertyAssignment, receiver: Expression, startsOnNewLine: boolean) {
const expression = createAssignment(
createMemberAccessForPropertyName(
receiver,
visitNode(property.name, visitor, isPropertyName)
@@ -2353,6 +2358,10 @@ namespace ts {
visitNode(property.initializer, visitor, isExpression),
/*location*/ property
);
if (startsOnNewLine) {
expression.startsOnNewLine = true;
}
return expression;
}
/**
@@ -2362,8 +2371,8 @@ namespace ts {
* @param property The ShorthandPropertyAssignment node.
* @param receiver The receiver for the assignment.
*/
function transformShorthandPropertyAssignmentToExpression(node: ObjectLiteralExpression, property: ShorthandPropertyAssignment, receiver: Expression) {
return createAssignment(
function transformShorthandPropertyAssignmentToExpression(node: ObjectLiteralExpression, property: ShorthandPropertyAssignment, receiver: Expression, startsOnNewLine: boolean) {
const expression = createAssignment(
createMemberAccessForPropertyName(
receiver,
visitNode(property.name, visitor, isPropertyName)
@@ -2371,6 +2380,10 @@ namespace ts {
getSynthesizedClone(property.name),
/*location*/ property
);
if (startsOnNewLine) {
expression.startsOnNewLine = true;
}
return expression;
}
/**
@@ -2380,8 +2393,8 @@ namespace ts {
* @param method The MethodDeclaration node.
* @param receiver The receiver for the assignment.
*/
function transformObjectLiteralMethodDeclarationToExpression(node: ObjectLiteralExpression, method: MethodDeclaration, receiver: Expression) {
return createAssignment(
function transformObjectLiteralMethodDeclarationToExpression(node: ObjectLiteralExpression, method: MethodDeclaration, receiver: Expression, startsOnNewLine: boolean) {
const expression = createAssignment(
createMemberAccessForPropertyName(
receiver,
visitNode(method.name, visitor, isPropertyName)
@@ -2389,6 +2402,10 @@ namespace ts {
transformFunctionLikeToExpression(method, /*location*/ method, /*name*/ undefined),
/*location*/ method
);
if (startsOnNewLine) {
expression.startsOnNewLine = true;
}
return expression;
}
/**
+10 -4
View File
@@ -580,8 +580,8 @@ namespace ts {
transformAndEmitStatements(body.statements, statementOffset);
const buildResult = build();
addNodes(statements, endLexicalEnvironment());
addNode(statements, createReturn(buildResult));
addRange(statements, endLexicalEnvironment());
statements.push(createReturn(buildResult));
// Restore previous generator state
inGeneratorFunctionBody = savedInGeneratorFunctionBody;
@@ -1019,7 +1019,7 @@ namespace ts {
);
const expressions = reduceLeft(properties, reduceProperty, <Expression[]>[], numInitialProperties);
addNode(expressions, getMutableClone(temp), multiLine);
expressions.push(multiLine ? startOnNewLine(getMutableClone(temp)) : temp);
return inlineExpressions(expressions);
function reduceProperty(expressions: Expression[], property: ObjectLiteralElement) {
@@ -1029,7 +1029,13 @@ namespace ts {
}
const expression = createExpressionForObjectLiteralElement(node, property, temp);
addNode(expressions, visitNode(expression, visitor, isExpression), multiLine);
const visited = visitNode(expression, visitor, isExpression);
if (visited) {
if (multiLine) {
visited.startsOnNewLine = true;
}
expressions.push(visited);
}
return expressions;
}
}
+10 -2
View File
@@ -65,7 +65,11 @@ namespace ts {
return node;
}
return newExportClause
? createExportDeclaration(newExportClause, node.moduleSpecifier)
? createExportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
newExportClause,
node.moduleSpecifier)
: undefined;
}
@@ -92,7 +96,11 @@ namespace ts {
return undefined;
}
else if (newImportClause !== node.importClause) {
return createImportDeclaration(newImportClause, node.moduleSpecifier);
return createImportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
newImportClause,
node.moduleSpecifier);
}
}
return node;
+3 -1
View File
@@ -734,8 +734,10 @@ namespace ts {
statements.push(
setOriginalNode(
createClassDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
name,
/*typeParameters*/ undefined,
node.heritageClauses,
node.members,
/*location*/ node
@@ -908,7 +910,7 @@ namespace ts {
setNodeEmitFlags(node, NodeEmitFlags.NoSubstitution);
let transformedUnaryExpression: BinaryExpression;
if (node.kind === SyntaxKind.PostfixUnaryExpression) {
transformedUnaryExpression = createBinaryWithOperatorToken(
transformedUnaryExpression = createBinary(
operand,
createNode(operator === SyntaxKind.PlusPlusToken ? SyntaxKind.PlusEqualsToken : SyntaxKind.MinusEqualsToken),
createLiteral(1),
+25 -17
View File
@@ -197,7 +197,7 @@ namespace ts {
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, visitSourceElement);
// var __moduleName = context_1 && context_1.id;
addNode(statements,
statements.push(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
@@ -226,14 +226,14 @@ namespace ts {
// - Temporary variables will appear at the top rather than at the bottom of the file
// - Calls to the exporter for exported function declarations are grouped after
// the declarations.
addNodes(statements, endLexicalEnvironment());
addRange(statements, endLexicalEnvironment());
// Emit early exports for function declarations.
addNodes(statements, exportedFunctionDeclarations);
addRange(statements, exportedFunctionDeclarations);
const exportStarFunction = addExportStarIfNeeded(statements);
addNode(statements,
statements.push(
createReturn(
setMultiLine(
createObjectLiteral([
@@ -292,7 +292,7 @@ namespace ts {
if (exportedLocalNames) {
for (const exportedLocalName of exportedLocalNames) {
// write name of exported declaration, i.e 'export var x...'
addNode(exportedNames,
exportedNames.push(
createPropertyAssignment(
createLiteral(exportedLocalName.text),
createLiteral(true)
@@ -314,7 +314,7 @@ namespace ts {
for (const element of exportDecl.exportClause.elements) {
// write name of indirectly exported entry, i.e. 'export {x} from ...'
addNode(exportedNames,
exportedNames.push(
createPropertyAssignment(
createLiteral((element.name || element.propertyName).text),
createLiteral(true)
@@ -324,7 +324,7 @@ namespace ts {
}
const exportedNamesStorageRef = createUniqueName("exportedNames");
addNode(statements,
statements.push(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
@@ -365,7 +365,7 @@ namespace ts {
case SyntaxKind.ImportEqualsDeclaration:
Debug.assert(importVariableName !== undefined);
// save import into the local
addNode(statements,
statements.push(
createStatement(
createAssignment(importVariableName, parameterName)
)
@@ -396,7 +396,7 @@ namespace ts {
);
}
addNode(statements,
statements.push(
createStatement(
createCall(
exportFunctionForFile,
@@ -412,7 +412,7 @@ namespace ts {
// emit as:
//
// exportStar(foo_1_1);
addNode(statements,
statements.push(
createStatement(
createCall(
exportStarFunction,
@@ -426,7 +426,7 @@ namespace ts {
}
}
addNode(setters,
setters.push(
createFunctionExpression(
/*asteriskToken*/ undefined,
/*name*/ undefined,
@@ -563,7 +563,7 @@ namespace ts {
function visitExportDeclaration(node: ExportDeclaration): VisitResult<Statement> {
if (!node.moduleSpecifier) {
const statements: Statement[] = [];
addNodes(statements, map(node.exportClause.elements, visitExportSpecifier));
addRange(statements, map(node.exportClause.elements, visitExportSpecifier));
return statements;
}
@@ -612,7 +612,10 @@ namespace ts {
const isExported = hasModifier(node, ModifierFlags.Export);
const expressions: Expression[] = [];
for (const variable of node.declarationList.declarations) {
addNode(expressions, <Expression>transformVariable(variable, isExported));
const visited = <Expression>transformVariable(variable, isExported);
if (visited) {
expressions.push(visited);
}
}
if (expressions.length) {
@@ -715,12 +718,14 @@ namespace ts {
const statements: Statement[] = [];
// Rewrite the class declaration into an assignment of a class expression.
addNode(statements,
statements.push(
createStatement(
createAssignment(
name,
createClassExpression(
/*modifiers*/ undefined,
node.name,
/*typeParameters*/ undefined,
node.heritageClauses,
node.members,
/*location*/ node
@@ -736,7 +741,7 @@ namespace ts {
recordExportName(name);
}
addNode(statements, createDeclarationExport(node));
statements.push(createDeclarationExport(node));
}
return statements;
@@ -756,7 +761,10 @@ namespace ts {
if (shouldHoistLoopInitializer(initializer)) {
const expressions: Expression[] = [];
for (const variable of (<VariableDeclarationList>initializer).declarations) {
addNode(expressions, <Expression>transformVariable(variable, /*isExported*/ false));
const visited = <Expression>transformVariable(variable, /*isExported*/ false);
if (visited) {
expressions.push(visited);
}
};
return createFor(
@@ -1207,7 +1215,7 @@ namespace ts {
);
}
addNode(statements,
statements.push(
createFunctionDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
+53 -21
View File
@@ -428,6 +428,8 @@ namespace ts {
const statementOffset = addPrologueDirectives(statements, node.statements, /*ensureUseStrict*/ false, visitor);
const externalHelpersModuleName = createUniqueName(externalHelpersModuleNameText);
const externalHelpersModuleImport = createImportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)),
createLiteral(externalHelpersModuleNameText)
);
@@ -506,8 +508,10 @@ namespace ts {
// ${members}
// }
const classDeclaration = createClassDeclaration(
/*decorators*/ undefined,
visitNodes(node.modifiers, visitor, isModifier),
name,
/*typeParameters*/ undefined,
visitNodes(node.heritageClauses, visitor, isHeritageClause),
transformClassMembers(node, hasExtendsClause),
/*location*/ node
@@ -548,7 +552,11 @@ namespace ts {
}
else if (isDecoratedClass) {
if (isDefaultExternalModuleExport(node)) {
statements.push(createExportDefault(getLocalName(node)));
statements.push(createExportAssignment(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*isExportEquals*/ false,
getLocalName(node)));
}
else if (isNamedExternalModuleExport(node)) {
statements.push(createExternalModuleExport(name));
@@ -660,7 +668,9 @@ namespace ts {
// }
const classExpression: Expression = setOriginalNode(
createClassExpression(
/*modifiers*/ undefined,
name,
/*typeParameters*/ undefined,
visitNodes(node.heritageClauses, visitor, isHeritageClause),
transformClassMembers(node, hasExtendsClause),
/*location*/ location
@@ -684,7 +694,7 @@ namespace ts {
// let ${name} = ${classExpression} where name is either declaredName if the class doesn't contain self-reference
// or decoratedClassAlias if the class contain self-reference.
addNode(statements,
statements.push(
setOriginalNode(
createVariableStatement(
/*modifiers*/ undefined,
@@ -706,7 +716,7 @@ namespace ts {
// TDZ as the class.
// let ${declaredName} = ${decoratedClassAlias}
addNode(statements,
statements.push(
setOriginalNode(
createVariableStatement(
/*modifiers*/ undefined,
@@ -743,7 +753,9 @@ namespace ts {
const classExpression = setOriginalNode(
createClassExpression(
/*modifiers*/ undefined,
node.name,
/*typeParameters*/ undefined,
heritageClauses,
members,
/*location*/ node
@@ -757,15 +769,15 @@ namespace ts {
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) {
// record an alias as the class name is not in scope for statics.
enableSubstitutionForClassAliases();
classAliases[getOriginalNodeId(node)] = temp;
classAliases[getOriginalNodeId(node)] = getSynthesizedClone(temp);
}
// To preserve the behavior of the old emitter, we explicitly indent
// the body of a class with static initializers.
setNodeEmitFlags(classExpression, NodeEmitFlags.Indented | getNodeEmitFlags(classExpression));
addNode(expressions, createAssignment(temp, classExpression), true);
addNodes(expressions, generateInitializedPropertyExpressions(node, staticProperties, temp), true);
addNode(expressions, temp, true);
expressions.push(startOnNewLine(createAssignment(temp, classExpression)));
addRange(expressions, generateInitializedPropertyExpressions(node, staticProperties, temp));
expressions.push(startOnNewLine(temp));
return inlineExpressions(expressions);
}
@@ -780,8 +792,12 @@ namespace ts {
*/
function transformClassMembers(node: ClassDeclaration | ClassExpression, hasExtendsClause: boolean) {
const members: ClassElement[] = [];
addNode(members, transformConstructor(node, hasExtendsClause));
addNodes(members, visitNodes(node.members, classElementVisitor, isClassElement));
const constructor = transformConstructor(node, hasExtendsClause);
if (constructor) {
members.push(constructor);
}
addRange(members, visitNodes(node.members, classElementVisitor, isClassElement));
return createNodeArray(members, /*location*/ node.members);
}
@@ -870,7 +886,7 @@ namespace ts {
// }
//
const propertyAssignments = getParametersWithPropertyAssignments(constructor);
addNodes(statements, map(propertyAssignments, transformParameterWithPropertyAssignment));
addRange(statements, map(propertyAssignments, transformParameterWithPropertyAssignment));
}
else if (hasExtendsClause) {
Debug.assert(parameters.length === 1 && isIdentifier(parameters[0].name));
@@ -879,7 +895,7 @@ namespace ts {
//
// super(...args);
//
addNode(statements,
statements.push(
createStatement(
createCall(
createSuper(),
@@ -905,11 +921,11 @@ namespace ts {
if (constructor) {
// The class already had a constructor, so we should add the existing statements, skipping the initial super call.
addNodes(statements, visitNodes(constructor.body.statements, visitor, isStatement, indexOfFirstStatement));
addRange(statements, visitNodes(constructor.body.statements, visitor, isStatement, indexOfFirstStatement));
}
// End the lexical environment.
addNodes(statements, endLexicalEnvironment());
addRange(statements, endLexicalEnvironment());
return setMultiLine(
createBlock(
createNodeArray(
@@ -1065,6 +1081,7 @@ namespace ts {
const expressions: Expression[] = [];
for (const property of properties) {
const expression = transformInitializedProperty(node, property, receiver);
expression.startsOnNewLine = true;
setSourceMapRange(expression, moveRangePastModifiers(property));
setCommentRange(expression, property);
expressions.push(expression);
@@ -1277,8 +1294,8 @@ namespace ts {
}
const decoratorExpressions: Expression[] = [];
addNodes(decoratorExpressions, map(allDecorators.decorators, transformDecorator));
addNodes(decoratorExpressions, flatMap(allDecorators.parameters, transformDecoratorsOfParameter));
addRange(decoratorExpressions, map(allDecorators.decorators, transformDecorator));
addRange(decoratorExpressions, flatMap(allDecorators.parameters, transformDecoratorsOfParameter));
addTypeMetadata(node, decoratorExpressions);
return decoratorExpressions;
}
@@ -1874,7 +1891,9 @@ namespace ts {
createTypeOf(createIdentifier("Symbol")),
createLiteral("function")
),
createToken(SyntaxKind.QuestionToken),
createIdentifier("Symbol"),
createToken(SyntaxKind.ColonToken),
createIdentifier("Object")
);
}
@@ -1960,6 +1979,7 @@ namespace ts {
function visitExpressionWithTypeArguments(node: ExpressionWithTypeArguments): ExpressionWithTypeArguments {
const expression = visitNode(node.expression, visitor, isLeftHandSideExpression);
return createExpressionWithTypeArguments(
/*typeArguments*/ undefined,
expression,
node
);
@@ -2208,7 +2228,7 @@ namespace ts {
startLexicalEnvironment();
const visited: Expression | Block = visitNode(body, visitor, isConciseBody);
const declarations = endLexicalEnvironment();
const merged = mergeConciseBodyLexicalEnvironment(visited, declarations);
const merged = mergeFunctionBodyLexicalEnvironment(visited, declarations);
if (forceBlockFunctionBody && !isBlock(merged)) {
return createBlock([
createReturn(<Expression>merged)
@@ -2378,6 +2398,7 @@ namespace ts {
function visitAwaitExpression(node: AwaitExpression): Expression {
return setOriginalNode(
createYield(
/*asteriskToken*/ undefined,
visitNode(node.expression, visitor, isExpression),
/*location*/ node
),
@@ -2546,8 +2567,8 @@ namespace ts {
const statements: Statement[] = [];
startLexicalEnvironment();
addNodes(statements, map(node.members, transformEnumMember));
addNodes(statements, endLexicalEnvironment());
addRange(statements, map(node.members, transformEnumMember));
addRange(statements, endLexicalEnvironment());
currentNamespaceContainerName = savedCurrentNamespaceLocalName;
return createBlock(
@@ -2784,17 +2805,26 @@ namespace ts {
let blockLocation: TextRange;
const body = node.body;
if (body.kind === SyntaxKind.ModuleBlock) {
addNodes(statements, visitNodes((<ModuleBlock>body).statements, namespaceElementVisitor, isStatement));
addRange(statements, visitNodes((<ModuleBlock>body).statements, namespaceElementVisitor, isStatement));
statementsLocation = (<ModuleBlock>body).statements;
blockLocation = body;
}
else {
addNode(statements, visitModuleDeclaration(<ModuleDeclaration>body));
const result = visitModuleDeclaration(<ModuleDeclaration>body);
if (result) {
if (isArray(result)) {
addRange(statements, result);
}
else {
statements.push(result);
}
}
const moduleBlock = <ModuleBlock>getInnerMostModuleDeclarationFromDottedModule(node).body;
statementsLocation = moveRangePos(moduleBlock.statements, -1);
}
addNodes(statements, endLexicalEnvironment());
addRange(statements, endLexicalEnvironment());
currentNamespaceContainerName = savedCurrentNamespaceContainerName;
currentNamespace = savedCurrentNamespace;
@@ -2955,6 +2985,8 @@ namespace ts {
function createExternalModuleExport(exportName: Identifier) {
return createExportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
createNamedExports([
createExportSpecifier(exportName)
])
+7
View File
@@ -4057,6 +4057,13 @@ namespace ts {
return node.kind === SyntaxKind.JsxClosingElement;
}
export function isJsxTagNameExpression(node: Node): node is JsxTagNameExpression {
const kind = node.kind;
return kind === SyntaxKind.ThisKeyword
|| kind === SyntaxKind.Identifier
|| kind === SyntaxKind.PropertyAccessExpression;
}
export function isJsxChild(node: Node): node is JsxChild {
const kind = node.kind;
return kind === SyntaxKind.JsxElement
+900 -975
View File
File diff suppressed because it is too large Load Diff