Move transform flag aggregation to factory

This commit is contained in:
Ron Buckton
2019-09-26 16:11:06 -07:00
parent c1020ca59d
commit 9595d72b44
19 changed files with 900 additions and 1271 deletions
+9 -973
View File
File diff suppressed because it is too large Load Diff
+13 -9
View File
@@ -3653,7 +3653,7 @@ namespace ts {
}
if (type.flags & TypeFlags.BooleanLiteral) {
context.approximateLength += (<IntrinsicType>type).intrinsicName.length;
return (<IntrinsicType>type).intrinsicName === "true" ? factory.createTrue() : factory.createFalse();
return factory.createLiteralTypeNode((<IntrinsicType>type).intrinsicName === "true" ? factory.createTrue() : factory.createFalse());
}
if (type.flags & TypeFlags.UniqueESSymbol) {
if (!(context.flags & NodeBuilderFlags.AllowUniqueESSymbolType)) {
@@ -3678,7 +3678,7 @@ namespace ts {
}
if (type.flags & TypeFlags.Null) {
context.approximateLength += 4;
return factory.createKeywordTypeNode(SyntaxKind.NullKeyword);
return factory.createLiteralTypeNode(factory.createNull());
}
if (type.flags & TypeFlags.Never) {
context.approximateLength += 5;
@@ -3702,7 +3702,7 @@ namespace ts {
}
}
context.approximateLength += 4;
return factory.createThis();
return factory.createThisTypeNode();
}
const objectFlags = getObjectFlags(type);
@@ -4310,11 +4310,11 @@ namespace ts {
if (context.tracker.trackSymbol && isComputedPropertyName(node) && isLateBindableName(node)) {
trackComputedName(node, context.enclosingDeclaration, context);
}
const visited = visitEachChild(node, elideInitializerAndSetEmitFlags, nullTransformationContext, /*nodesVisitor*/ undefined, elideInitializerAndSetEmitFlags)!;
const clone = nodeIsSynthesized(visited) ? visited : getSynthesizedClone(visited);
if (clone.kind === SyntaxKind.BindingElement) {
(<BindingElement>clone).initializer = undefined;
let visited = visitEachChild(node, elideInitializerAndSetEmitFlags, nullTransformationContext, /*nodesVisitor*/ undefined, elideInitializerAndSetEmitFlags)!;
if (isBindingElement(visited)) {
visited = factory.updateBindingElement(visited, visited.dotDotDotToken, visited.propertyName, visited.name, /*initializer*/ undefined);
}
const clone = nodeIsSynthesized(visited) ? visited : getSynthesizedClone(visited);
return setEmitFlags(clone, EmitFlags.SingleLine | EmitFlags.NoAsciiEscaping);
}
}
@@ -6695,7 +6695,6 @@ namespace ts {
case SyntaxKind.ObjectKeyword:
case SyntaxKind.VoidKeyword:
case SyntaxKind.UndefinedKeyword:
case SyntaxKind.NullKeyword:
case SyntaxKind.NeverKeyword:
case SyntaxKind.LiteralType:
return true;
@@ -11058,6 +11057,9 @@ namespace ts {
}
function getTypeFromLiteralTypeNode(node: LiteralTypeNode): Type {
if (node.literal.kind === SyntaxKind.NullKeyword) {
return nullType;
}
const links = getNodeLinks(node);
if (!links.resolvedType) {
links.resolvedType = getRegularTypeOfLiteralType(checkExpression(node.literal));
@@ -11125,6 +11127,7 @@ namespace ts {
case SyntaxKind.UndefinedKeyword:
return undefinedType;
case SyntaxKind.NullKeyword:
// Although `NullKeyword` is not currently a valid TypeNode, at one point it was so we return `nullType` here defensively.
return nullType;
case SyntaxKind.NeverKeyword:
return neverType;
@@ -11132,6 +11135,7 @@ namespace ts {
return node.flags & NodeFlags.JavaScriptFile ? anyType : nonPrimitiveType;
case SyntaxKind.ThisType:
case SyntaxKind.ThisKeyword:
// Although `ThisKeyword` is not currently a valid TypeNode, at one point it was so we return the `this` type here defensively.
return getTypeFromThisTypeNode(node as ThisExpression | ThisTypeNode);
case SyntaxKind.LiteralType:
return getTypeFromLiteralTypeNode(<LiteralTypeNode>node);
@@ -26904,7 +26908,7 @@ namespace ts {
if (typeNode.kind === SyntaxKind.NeverKeyword) {
continue; // Always elide `never` from the union/intersection if possible
}
if (!strictNullChecks && (typeNode.kind === SyntaxKind.NullKeyword || typeNode.kind === SyntaxKind.UndefinedKeyword)) {
if (!strictNullChecks && (typeNode.kind === SyntaxKind.LiteralType && (typeNode as LiteralTypeNode).literal.kind === SyntaxKind.NullKeyword || typeNode.kind === SyntaxKind.UndefinedKeyword)) {
continue; // Elide null and undefined from unions for metadata, just like what we did prior to the implementation of strict null checks
}
const individualEntityName = getEntityNameForDecoratorMetadata(typeNode);
+5 -4
View File
@@ -89,17 +89,18 @@ namespace ts {
/**
* Formats an enum value as a string for debugging and debug assertions.
*/
export function formatEnum(value = 0, enumObject: any, isFlags?: boolean) {
export function formatEnum(value = 0, enumObject: any, isFlags?: boolean, filterEnum?: (enumValue: number, enumName: string) => boolean) {
const members = getEnumMembers(enumObject);
if (value === 0) {
return members.length > 0 && members[0][0] === 0 ? members[0][1] : "0";
const zeroMembers = members.filter(member => member[0] === 0);
return zeroMembers.length > 0 ? zeroMembers[0][1] : "0";
}
if (isFlags) {
let result = "";
let remainingFlags = value;
for (let i = members.length - 1; i >= 0 && remainingFlags !== 0; i--) {
const [enumValue, enumName] = members[i];
if (enumValue !== 0 && (remainingFlags & enumValue) === enumValue) {
if ((!filterEnum || filterEnum(enumValue, enumName)) && enumValue !== 0 && (remainingFlags & enumValue) === enumValue) {
remainingFlags &= ~enumValue;
result = `${enumName}${result ? "|" : ""}${result}`;
}
@@ -143,7 +144,7 @@ namespace ts {
}
export function formatTransformFlags(flags: TransformFlags | undefined): string {
return formatEnum(flags, (<any>ts).TransformFlags, /*isFlags*/ true);
return formatEnum(flags, (<any>ts).TransformFlags, /*isFlags*/ true, (_, name) => !/^Assert|Excludes$|PropagatingFlags$/.test(name));
}
export function formatEmitFlags(flags: EmitFlags | undefined): string {
-2
View File
@@ -18,7 +18,6 @@ namespace ts {
setTextRange(returnStatement, node);
const body = factory.createBlock([returnStatement], multiLine);
setTextRange(body, node);
aggregateTransformFlags(body);
return body;
}
@@ -38,7 +37,6 @@ namespace ts {
if (getStartsOnNewLine(node)) {
setStartsOnNewLine(updated, /*newLine*/ true);
}
aggregateTransformFlags(updated);
return updated;
}
File diff suppressed because it is too large Load Diff
+71 -79
View File
@@ -174,48 +174,46 @@ namespace ts {
function createExpressionForAccessorDeclaration(factory: NodeFactory, properties: NodeArray<Declaration>, property: AccessorDeclaration, receiver: Expression, multiLine: boolean) {
const { firstAccessor, getAccessor, setAccessor } = getAllAccessorDeclarations(properties, property);
if (property === firstAccessor) {
return aggregateTransformFlags(
setTextRange(
factory.createObjectDefinePropertyCall(
receiver,
createExpressionForPropertyName(factory, property.name),
factory.createPropertyDescriptor({
enumerable: true,
configurable: true,
get: getAccessor && setTextRange(
setOriginalNode(
factory.createFunctionExpression(
getAccessor.modifiers,
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
getAccessor.parameters,
/*type*/ undefined,
getAccessor.body! // TODO: GH#18217
),
getAccessor
return setTextRange(
factory.createObjectDefinePropertyCall(
receiver,
createExpressionForPropertyName(factory, property.name),
factory.createPropertyDescriptor({
enumerable: true,
configurable: true,
get: getAccessor && setTextRange(
setOriginalNode(
factory.createFunctionExpression(
getAccessor.modifiers,
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
getAccessor.parameters,
/*type*/ undefined,
getAccessor.body! // TODO: GH#18217
),
getAccessor
),
set: setAccessor && setTextRange(
setOriginalNode(
factory.createFunctionExpression(
setAccessor.modifiers,
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
setAccessor.parameters,
/*type*/ undefined,
setAccessor.body! // TODO: GH#18217
),
setAccessor
getAccessor
),
set: setAccessor && setTextRange(
setOriginalNode(
factory.createFunctionExpression(
setAccessor.modifiers,
/*asteriskToken*/ undefined,
/*name*/ undefined,
/*typeParameters*/ undefined,
setAccessor.parameters,
/*type*/ undefined,
setAccessor.body! // TODO: GH#18217
),
setAccessor
)
}, !multiLine)
),
firstAccessor
)
),
setAccessor
)
}, !multiLine)
),
firstAccessor
);
}
@@ -223,61 +221,55 @@ namespace ts {
}
function createExpressionForPropertyAssignment(factory: NodeFactory, property: PropertyAssignment, receiver: Expression) {
return aggregateTransformFlags(
setOriginalNode(
setTextRange(
factory.createAssignment(
createMemberAccessForPropertyName(factory, receiver, property.name, /*location*/ property.name),
property.initializer
),
property
return setOriginalNode(
setTextRange(
factory.createAssignment(
createMemberAccessForPropertyName(factory, receiver, property.name, /*location*/ property.name),
property.initializer
),
property
)
),
property
);
}
function createExpressionForShorthandPropertyAssignment(factory: NodeFactory, property: ShorthandPropertyAssignment, receiver: Expression) {
return aggregateTransformFlags(
setOriginalNode(
setTextRange(
factory.createAssignment(
createMemberAccessForPropertyName(factory, receiver, property.name, /*location*/ property.name),
getSynthesizedClone(property.name)
),
/*location*/ property
return setOriginalNode(
setTextRange(
factory.createAssignment(
createMemberAccessForPropertyName(factory, receiver, property.name, /*location*/ property.name),
getSynthesizedClone(property.name)
),
/*original*/ property
)
/*location*/ property
),
/*original*/ property
);
}
function createExpressionForMethodDeclaration(factory: NodeFactory, method: MethodDeclaration, receiver: Expression) {
return aggregateTransformFlags(
setOriginalNode(
setTextRange(
factory.createAssignment(
createMemberAccessForPropertyName(factory, receiver, method.name, /*location*/ method.name),
setOriginalNode(
setTextRange(
factory.createFunctionExpression(
method.modifiers,
method.asteriskToken,
/*name*/ undefined,
/*typeParameters*/ undefined,
method.parameters,
/*type*/ undefined,
method.body! // TODO: GH#18217
),
/*location*/ method
return setOriginalNode(
setTextRange(
factory.createAssignment(
createMemberAccessForPropertyName(factory, receiver, method.name, /*location*/ method.name),
setOriginalNode(
setTextRange(
factory.createFunctionExpression(
method.modifiers,
method.asteriskToken,
/*name*/ undefined,
/*typeParameters*/ undefined,
method.parameters,
/*type*/ undefined,
method.body! // TODO: GH#18217
),
/*original*/ method
)
),
/*location*/ method
/*location*/ method
),
/*original*/ method
)
),
/*original*/ method
)
/*location*/ method
),
/*original*/ method
);
}
+29 -23
View File
@@ -869,10 +869,12 @@ namespace ts {
parsingContext = 0;
identifiers = undefined!;
notParenthesizedArrow = undefined!;
factory.setSkipTransformationFlags(/*inDeclarationFile*/ false);
}
function parseSourceFileWorker(fileName: string, languageVersion: ScriptTarget, setParentNodes: boolean, scriptKind: ScriptKind): SourceFile {
const isDeclarationFile = isDeclarationFileName(fileName);
factory.setSkipTransformationFlags(isDeclarationFile);
if (isDeclarationFile) {
contextFlags |= NodeFlags.Ambient;
}
@@ -906,6 +908,7 @@ namespace ts {
fixupParentReferences(sourceFile);
}
factory.setSkipTransformationFlags(/*inDeclarationFile*/ false);
return sourceFile;
function reportPragmaDiagnostic(pos: number, end: number, diagnostic: DiagnosticMessage) {
@@ -2578,9 +2581,7 @@ namespace ts {
const defaultType = parseOptional(SyntaxKind.EqualsToken) ? parseType() : undefined;
const node = factory.createTypeParameterDeclaration(name, constraint, defaultType);
if (expression) {
node.expression = expression;
}
if (expression) factory.trackExtraneousChildNode(node, node.expression = expression);
return finishNode(node, pos);
}
@@ -2853,7 +2854,7 @@ namespace ts {
// Although type literal properties cannot not have initializers, we attempt
// to parse an initializer so we can report in the checker that an interface
// property or type literal property cannot have an initializer.
if (token() === SyntaxKind.EqualsToken) node.initializer = parseInitializer();
if (token() === SyntaxKind.EqualsToken) factory.trackExtraneousChildNode(node, node.initializer = parseInitializer());
}
parseTypeMemberSemicolon();
return withJSDoc(finishNode(node, pos), hasJSDoc);
@@ -3045,8 +3046,8 @@ namespace ts {
if (negative) {
nextToken();
}
let expression: BooleanLiteral | LiteralExpression | PrefixUnaryExpression = token() === SyntaxKind.TrueKeyword || token() === SyntaxKind.FalseKeyword
? parseTokenNode<BooleanLiteral>()
let expression: BooleanLiteral | NullLiteral | LiteralExpression | PrefixUnaryExpression = token() === SyntaxKind.TrueKeyword || token() === SyntaxKind.FalseKeyword || token() === SyntaxKind.NullKeyword
? parseTokenNode<BooleanLiteral | NullLiteral>()
: parseLiteralLikeNode(token()) as LiteralExpression;
if (negative) {
expression = finishNode(factory.createPrefix(SyntaxKind.MinusToken, expression), pos);
@@ -3107,11 +3108,11 @@ namespace ts {
case SyntaxKind.BigIntLiteral:
case SyntaxKind.TrueKeyword:
case SyntaxKind.FalseKeyword:
case SyntaxKind.NullKeyword:
return parseLiteralTypeNode();
case SyntaxKind.MinusToken:
return lookAhead(nextTokenIsNumericOrBigIntLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference();
case SyntaxKind.VoidKeyword:
case SyntaxKind.NullKeyword:
return parseTokenNode<TypeNode>();
case SyntaxKind.ThisKeyword: {
const thisKeyword = parseThisTypeNode();
@@ -4919,7 +4920,7 @@ namespace ts {
node = factory.createShorthandPropertyAssignment(name as Identifier, objectAssignmentInitializer);
// Save equals token for error reporting.
// TODO(rbuckton): Consider manufacturing this when we need to report an error as it is otherwise not useful.
if (equalsToken) node.equalsToken = equalsToken;
if (equalsToken) factory.trackExtraneousChildNode(node, node.equalsToken = equalsToken);
}
else {
parseExpected(SyntaxKind.ColonToken);
@@ -4927,10 +4928,12 @@ namespace ts {
node = factory.createPropertyAssignment(name, initializer);
}
// Decorators, Modifiers, questionToken, and exclamationToken are not supported by property assignments and are reported in the grammar checker
if (decorators) node.decorators = decorators;
if (decorators) factory.trackExtraneousChildNodes(node, node.decorators = decorators);
// TODO(rbuckton): Use this instead...
// if (modifiers) factory.trackExtraneousChildNodes(node, node.modifiers = modifiers);
if (modifiers) node.modifiers = modifiers;
if (questionToken) node.questionToken = questionToken;
if (exclamationToken) node.exclamationToken = exclamationToken;
if (questionToken) factory.trackExtraneousChildNode(node, node.questionToken = questionToken);
if (exclamationToken) factory.trackExtraneousChildNode(node, node.exclamationToken = exclamationToken);
return withJSDoc(finishNode(node, pos), hasJSDoc);
}
@@ -5742,7 +5745,7 @@ namespace ts {
parseSemicolon();
const node = factory.createVariableStatement(modifiers, declarationList);
// Decorators are not allowed on a variable statement, so we keep track of them to report them in the grammar checker.
if (decorators) node.decorators = decorators;
if (decorators) factory.trackExtraneousChildNodes(node, node.decorators = decorators);
return withJSDoc(finishNode(node, pos), hasJSDoc);
}
@@ -5778,8 +5781,8 @@ namespace ts {
const body = parseFunctionBlockOrSemicolon(SignatureFlags.None, Diagnostics.or_expected);
const node = factory.createConstructorDeclaration(decorators, modifiers, parameters, body);
// Attach `typeParameters` and `type` if they exist so that we can report them in the grammar checker.
if (typeParameters) node.typeParameters = typeParameters;
if (type) node.type = type;
if (typeParameters) factory.trackExtraneousChildNodes(node, node.typeParameters = typeParameters);
if (type) factory.trackExtraneousChildNode(node, node.type = type);
return withJSDoc(finishNode(node, pos), hasJSDoc);
}
});
@@ -5812,9 +5815,8 @@ namespace ts {
body
);
// An exclamation token on a method is invalid syntax and will be handled by the grammar checker
if (exclamationToken) {
node.exclamationToken = exclamationToken;
}
if (exclamationToken) factory.trackExtraneousChildNode(node, node.exclamationToken = exclamationToken);
return withJSDoc(finishNode(node, pos), hasJSDoc);
}
@@ -5872,8 +5874,8 @@ namespace ts {
? factory.createGetAccessorDeclaration(decorators, modifiers, name, parameters, type, body)
: factory.createSetAccessorDeclaration(decorators, modifiers, name, parameters, body);
// Keep track of `typeParameters` (for both) and `type` (for setters) if they were parsed those indicate grammar errors
if (typeParameters) node.typeParameters = typeParameters;
if (type && kind === SyntaxKind.SetAccessor) node.type = type;
if (typeParameters) factory.trackExtraneousChildNodes(node, node.typeParameters = typeParameters);
if (type && kind === SyntaxKind.SetAccessor) factory.trackExtraneousChildNode(node, node.type = type);
return withJSDoc(finishNode(node, pos), hasJSDoc);
}
@@ -6283,8 +6285,8 @@ namespace ts {
parseSemicolon();
const node = factory.createNamespaceExportDeclaration(name);
// NamespaceExportDeclaration nodes cannot have decorators or modifiers, so we attach them here so we can report them in the grammar checker
if (decorators) node.decorators = decorators;
if (modifiers) node.modifiers = modifiers;
if (decorators) factory.trackExtraneousChildNodes(node, node.decorators = decorators);
if (modifiers) factory.trackExtraneousChildNodes(node, node.modifiers = modifiers);
return withJSDoc(finishNode(node, pos), hasJSDoc);
}
@@ -6549,6 +6551,7 @@ namespace ts {
export namespace JSDocParser {
export function parseJSDocTypeExpressionForTests(content: string, start: number | undefined, length: number | undefined): { jsDocTypeExpression: JSDocTypeExpression, diagnostics: Diagnostic[] } | undefined {
initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
factory.setSkipTransformationFlags(/*value*/ true); // reset in 'clearState'
scanner.setText(content, start, length);
currentToken = scanner.scan();
const jsDocTypeExpression = parseJSDocTypeExpression();
@@ -6567,7 +6570,7 @@ namespace ts {
// Parses out a JSDoc type expression.
export function parseJSDocTypeExpression(mayOmitBraces?: boolean): JSDocTypeExpression {
const pos = getNodePos();
const saveSkipTransformationFlags = factory.setSkipTransformationFlags(/*value*/ true);
const hasBrace = (mayOmitBraces ? parseOptional : parseExpected)(SyntaxKind.OpenBraceToken);
const type = doInsideOfContext(NodeFlags.JSDoc, parseJSDocType);
if (!mayOmitBraces || hasBrace) {
@@ -6576,11 +6579,13 @@ namespace ts {
const result = factory.createJSDocTypeExpression(type);
fixupParentReferences(result);
factory.setSkipTransformationFlags(saveSkipTransformationFlags);
return finishNode(result, pos);
}
export function parseIsolatedJSDocComment(content: string, start: number | undefined, length: number | undefined): { jsDoc: JSDoc, diagnostics: Diagnostic[] } | undefined {
initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
factory.setSkipTransformationFlags(/*value*/ true); // reset in 'clearState'
const jsDoc = doInsideOfContext(NodeFlags.JSDoc, () => parseJSDocCommentWorker(start, length));
const sourceFile = <SourceFile>{ languageVariant: LanguageVariant.Standard, text: content }; // tslint:disable-line no-object-literal-type-assertion
@@ -6591,6 +6596,7 @@ namespace ts {
}
export function parseJSDocComment(parent: HasJSDoc, start: number, length: number): JSDoc | undefined {
const saveSkipTransformationFlags = factory.setSkipTransformationFlags(true);
const saveToken = currentToken;
const saveParseDiagnosticsLength = parseDiagnostics.length;
const saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
@@ -6609,7 +6615,7 @@ namespace ts {
currentToken = saveToken;
parseDiagnostics.length = saveParseDiagnosticsLength;
parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode;
factory.setSkipTransformationFlags(saveSkipTransformationFlags);
return comment;
}
+1 -3
View File
@@ -103,13 +103,12 @@ namespace ts {
expressions.push(value);
}
return aggregateTransformFlags(context.factory.inlineExpressions(expressions!)) || context.factory.createOmittedExpression();
return context.factory.inlineExpressions(expressions!) || context.factory.createOmittedExpression();
function emitExpression(expression: Expression) {
// NOTE: this completely disables source maps, but aligns with the behavior of
// `emitAssignment` in the old emitter.
setEmitFlags(expression, EmitFlags.NoNestedSourceMaps);
aggregateTransformFlags(expression);
expressions = append(expressions, expression);
}
@@ -222,7 +221,6 @@ namespace ts {
if (isIdentifier(name)) {
setEmitFlags(variable, EmitFlags.NoNestedSourceMaps);
}
aggregateTransformFlags(variable);
declarations.push(variable);
}
return declarations;
+17 -4
View File
@@ -330,10 +330,26 @@ namespace ts {
&& !(<ReturnStatement>node).expression;
}
function isOrMayContainReturnCompletion(node: Node) {
return node.transformFlags & TransformFlags.ContainsHoistedDeclarationOrCompletion
&& (isReturnStatement(node)
|| isIfStatement(node)
|| isWithStatement(node)
|| isSwitchStatement(node)
|| isCaseBlock(node)
|| isCaseClause(node)
|| isDefaultClause(node)
|| isTryStatement(node)
|| isCatchClause(node)
|| isLabeledStatement(node)
|| isIterationStatement(node, /*lookInLabeledStatements*/ false)
|| isBlock(node));
}
function shouldVisitNode(node: Node): boolean {
return (node.transformFlags & TransformFlags.ContainsES2015) !== 0
|| convertedLoopState !== undefined
|| (hierarchyFacts & HierarchyFacts.ConstructorWithCapturedSuper && (isStatement(node) || (node.kind === SyntaxKind.Block)))
|| (hierarchyFacts & HierarchyFacts.ConstructorWithCapturedSuper && isOrMayContainReturnCompletion(node))
|| (isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatement(node))
|| (getEmitFlags(node) & EmitFlags.TypeScriptClassWrapper) !== 0;
}
@@ -2330,7 +2346,6 @@ namespace ts {
// evaluated on every iteration.
const assignment = factory.createAssignment(initializer, boundValue);
if (isDestructuringAssignment(assignment)) {
aggregateTransformFlags(assignment);
statements.push(factory.createExpressionStatement(visitBinaryExpression(assignment, /*needsDestructuringValue*/ false)));
}
else {
@@ -2717,13 +2732,11 @@ namespace ts {
}
else {
const clone = convertIterationStatementCore(node, initializerFunction, factory.createBlock(bodyFunction.part, /*multiLine*/ true));
aggregateTransformFlags(clone);
loop = factory.restoreEnclosingLabel(clone, outermostLabeledStatement, convertedLoopState && resetLabel);
}
}
else {
const clone = convertIterationStatementCore(node, initializerFunction, visitNode(node.statement, visitor, isStatement, factory.liftToBlock));
aggregateTransformFlags(clone);
loop = factory.restoreEnclosingLabel(clone, outermostLabeledStatement, convertedLoopState && resetLabel);
}
+1 -1
View File
@@ -72,7 +72,7 @@ namespace ts {
currentSourceFile = undefined!;
currentModuleInfo = undefined!;
needUMDDynamicImportHelper = false;
return aggregateTransformFlags(updated);
return updated;
}
+1 -1
View File
@@ -135,7 +135,7 @@ namespace ts {
contextObject = undefined!;
hoistedStatements = undefined!;
enclosingBlockScopedContainer = undefined!;
return aggregateTransformFlags(updated);
return updated;
}
/**
+6 -7
View File
@@ -735,7 +735,6 @@ namespace ts {
emitFlags |= EmitFlags.NoTrailingSourceMap;
}
aggregateTransformFlags(classDeclaration);
setTextRange(classDeclaration, node);
setOriginalNode(classDeclaration, node);
setEmitFlags(classDeclaration, emitFlags);
@@ -850,7 +849,6 @@ namespace ts {
heritageClauses,
members
);
aggregateTransformFlags(classExpression);
setOriginalNode(classExpression, node);
setTextRange(classExpression, location);
@@ -886,7 +884,6 @@ namespace ts {
transformClassMembers(node)
);
aggregateTransformFlags(classExpression);
setOriginalNode(classExpression, node);
setTextRange(classExpression, node);
@@ -907,13 +904,13 @@ namespace ts {
if (parametersWithPropertyAssignments) {
for (const parameter of parametersWithPropertyAssignments) {
if (isIdentifier(parameter.name)) {
members.push(aggregateTransformFlags(factory.createPropertyDeclaration(
members.push(factory.createPropertyDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
parameter.name,
/*questionOrExclamationToken*/ undefined,
/*type*/ undefined,
/*initializer*/ undefined)));
/*initializer*/ undefined));
}
}
}
@@ -1501,7 +1498,6 @@ namespace ts {
switch (node.kind) {
case SyntaxKind.VoidKeyword:
case SyntaxKind.UndefinedKeyword:
case SyntaxKind.NullKeyword:
case SyntaxKind.NeverKeyword:
return factory.createVoidZero();
@@ -1542,6 +1538,9 @@ namespace ts {
case SyntaxKind.FalseKeyword:
return factory.createIdentifier("Boolean");
case SyntaxKind.NullKeyword:
return factory.createVoidZero();
default:
return Debug.failBadSyntaxKind((<LiteralTypeNode>node).literal);
}
@@ -1602,7 +1601,7 @@ namespace ts {
if (typeNode.kind === SyntaxKind.NeverKeyword) {
continue; // Always elide `never` from the union/intersection if possible
}
if (!strictNullChecks && (typeNode.kind === SyntaxKind.NullKeyword || typeNode.kind === SyntaxKind.UndefinedKeyword)) {
if (!strictNullChecks && (typeNode.kind === SyntaxKind.LiteralType && (typeNode as LiteralTypeNode).literal.kind === SyntaxKind.NullKeyword || typeNode.kind === SyntaxKind.UndefinedKeyword)) {
continue; // Elide null and undefined from unions for metadata, just like what we did prior to the implementation of strict null checks
}
const serializedIndividual = serializeTypeNode(typeNode);
+25 -21
View File
@@ -1270,6 +1270,8 @@ namespace ts {
_typeNodeBrand: any;
}
// NOTE: `this` in a type position is a `ThisTypeNode`. Either `null`, `true`, or `false` in a type position
// is a `LiteralTypeNode`. This is so that the nodes for expressions and types do not overlap.
export interface KeywordTypeNode extends TypeNode {
kind: SyntaxKind.AnyKeyword
| SyntaxKind.UnknownKeyword
@@ -1279,10 +1281,8 @@ namespace ts {
| SyntaxKind.BooleanKeyword
| SyntaxKind.StringKeyword
| SyntaxKind.SymbolKeyword
| SyntaxKind.ThisKeyword
| SyntaxKind.VoidKeyword
| SyntaxKind.UndefinedKeyword
| SyntaxKind.NullKeyword
| SyntaxKind.NeverKeyword;
}
@@ -1296,6 +1296,7 @@ namespace ts {
/* @internal */
export type LiteralImportTypeNode = ImportTypeNode & { argument: LiteralTypeNode & { literal: StringLiteral } };
// A ThisTypeNode represents the `this` keyword in a type position. This is necessary since ThisKeyword is treated as the `this` expression.
export interface ThisTypeNode extends TypeNode {
kind: SyntaxKind.ThisType;
}
@@ -1421,7 +1422,7 @@ namespace ts {
export interface LiteralTypeNode extends TypeNode {
kind: SyntaxKind.LiteralType;
literal: BooleanLiteral | LiteralExpression | PrefixUnaryExpression;
literal: NullLiteral | BooleanLiteral | LiteralExpression | PrefixUnaryExpression;
}
export interface StringLiteral extends LiteralExpression {
@@ -1506,21 +1507,21 @@ namespace ts {
_primaryExpressionBrand: any;
}
export interface NullLiteral extends PrimaryExpression, TypeNode {
export interface NullLiteral extends PrimaryExpression {
kind: SyntaxKind.NullKeyword;
}
export interface TrueLiteral extends PrimaryExpression, TypeNode {
export interface TrueLiteral extends PrimaryExpression {
kind: SyntaxKind.TrueKeyword;
}
export interface FalseLiteral extends PrimaryExpression, TypeNode {
export interface FalseLiteral extends PrimaryExpression {
kind: SyntaxKind.FalseKeyword;
}
export type BooleanLiteral = TrueLiteral | FalseLiteral;
export interface ThisExpression extends PrimaryExpression, KeywordTypeNode {
export interface ThisExpression extends PrimaryExpression {
kind: SyntaxKind.ThisKeyword;
}
@@ -5629,7 +5630,7 @@ namespace ts {
None = 0,
// Facts
// - Flags used to indicate that a node or subtree contains syntax that requires transformation.
// - Flags used to indicate that a node or subtree contains syntax that may require transformation.
ContainsTypeScript = 1 << 0,
ContainsJsx = 1 << 1,
ContainsESNext = 1 << 2,
@@ -5660,19 +5661,6 @@ namespace ts {
// It is a good reminder of how much room we have left
HasComputedFlags = 1 << 29, // Transform flags have been computed.
// Assertions
// - Bitmasks that are used to assert facts about the syntax of a node and its subtree.
AssertTypeScript = ContainsTypeScript,
AssertJsx = ContainsJsx,
AssertESNext = ContainsESNext,
AssertES2019 = ContainsES2019,
AssertES2018 = ContainsES2018,
AssertES2017 = ContainsES2017,
AssertES2016 = ContainsES2016,
AssertES2015 = ContainsES2015,
AssertGenerator = ContainsGenerator,
AssertDestructuringAssignment = ContainsDestructuringAssignment,
// Scope Exclusions
// - Bitmasks that exclude flags from propagating out of a specific context
// into the subtree flags of their container.
@@ -5929,6 +5917,22 @@ namespace ts {
/* @internal */ getConverters(): NodeConverters;
createNodeArray<T extends Node>(elements?: readonly T[], hasTrailingComma?: boolean): NodeArray<T>;
/**
* This is used by the parser to skip transform flag aggregation in Declaration files or other contexts.
* @returns The previous value.
*/
/* @internal */ setSkipTransformationFlags(value: boolean): boolean;
/**
* Tracks setting an extraneous node on a parent. This is primarily used by the parser to add invalid nodes for grammar reporting purposes and is needed to
* correctly update transform flags after a node has been created.
*/
/* @internal */ trackExtraneousChildNode(parent: Node, child: Node | undefined): void;
/**
* Tracks setting an extraneous node array on a parent. This is primarily used by the parser to add invalid nodes for grammar reporting purposes and is needed to
* correctly update transform flags after a node has been created.
*/
/* @internal */ trackExtraneousChildNodes(parent: Node, children: NodeArray<Node> | undefined): void;
//
// Literals
//
+10 -4
View File
@@ -3951,6 +3951,14 @@ namespace ts {
return flags;
}
export function getModifierFlagsNoWrite(node: Node): ModifierFlags {
if (node.modifierFlagsCache & ModifierFlags.HasComputedFlags) {
return node.modifierFlagsCache & ~ModifierFlags.HasComputedFlags;
}
return getModifierFlagsNoCache(node);
}
export function getModifierFlagsNoCache(node: Node): ModifierFlags {
let flags = modifiersToFlags(node.modifiers);
@@ -4693,7 +4701,6 @@ namespace ts {
|| kind === SyntaxKind.ThisKeyword
|| kind === SyntaxKind.VoidKeyword
|| kind === SyntaxKind.UndefinedKeyword
|| kind === SyntaxKind.NullKeyword
|| kind === SyntaxKind.NeverKeyword
|| kind === SyntaxKind.ExpressionWithTypeArguments
|| kind === SyntaxKind.JSDocAllType
@@ -6020,15 +6027,14 @@ namespace ts {
}
/* @internal */
// TODO(rbuckton): Rename to 'isParameterPropertyModifierKind'
export function isParameterPropertyModifier(kind: SyntaxKind): boolean {
export function isParameterPropertyModifierKind(kind: SyntaxKind): boolean {
return !!(modifierToFlag(kind) & ModifierFlags.ParameterPropertyModifier);
}
/* @internal */
// TODO(rbuckton): Rename to 'isClassMemberModifierKind'
export function isClassMemberModifier(idToken: SyntaxKind): boolean {
return isParameterPropertyModifier(idToken) || idToken === SyntaxKind.StaticKeyword;
return isParameterPropertyModifierKind(idToken) || idToken === SyntaxKind.StaticKeyword;
}
// Functions
-79
View File
@@ -26,7 +26,6 @@ namespace ts {
return node;
}
aggregateTransformFlags(node);
const visited = visitor(node);
if (visited === node) {
return node;
@@ -44,7 +43,6 @@ namespace ts {
}
Debug.assertNode(visitedNode, test);
aggregateTransformFlags(visitedNode!);
return <T>visitedNode;
}
@@ -110,7 +108,6 @@ namespace ts {
// Visit each original node.
for (let i = 0; i < count; i++) {
const node = nodes[i + start];
aggregateTransformFlags(node);
const visited = node !== undefined ? visitor(node) : undefined;
if (updated !== undefined || visited === undefined || visited !== node) {
if (updated === undefined) {
@@ -124,13 +121,11 @@ namespace ts {
if (isArray(visited)) {
for (const visitedNode of visited) {
Debug.assertNode(visitedNode, test);
aggregateTransformFlags(visitedNode);
updated.push(<T>visitedNode);
}
}
else {
Debug.assertNode(visited, test);
aggregateTransformFlags(visited);
updated.push(<T>visited);
}
}
@@ -1504,78 +1499,4 @@ namespace ts {
? setTextRange(factory.createNodeArray(insertStatementsAfterStandardPrologue(statements.slice(), declarations)), statements)
: insertStatementsAfterStandardPrologue(statements, declarations);
}
/**
* Aggregates the TransformFlags for a Node and its subtree.
*/
export function aggregateTransformFlags<T extends Node>(node: T): T {
aggregateTransformFlagsForNode(node);
return node;
}
/**
* Aggregates the TransformFlags for a Node and its subtree. The flags for the subtree are
* computed first, then the transform flags for the current node are computed from the subtree
* flags and the state of the current node. Finally, the transform flags of the node are
* returned, excluding any flags that should not be included in its parent node's subtree
* flags.
*/
function aggregateTransformFlagsForNode(node: Node): TransformFlags {
if (node === undefined) {
return TransformFlags.None;
}
if (node.transformFlags & TransformFlags.HasComputedFlags) {
const nodeFlags = node.transformFlags & ~getTransformFlagsSubtreeExclusions(node.kind);
switch (node.kind) {
case SyntaxKind.MethodDeclaration:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
return nodeFlags | ((node as NamedDeclaration).name!.transformFlags & TransformFlags.PropertyNamePropagatingFlags);
}
return nodeFlags;
}
const subtreeFlags = aggregateTransformFlagsForSubtree(node);
return computeTransformFlagsForNode(node, subtreeFlags);
}
function aggregateTransformFlagsForNodeArray(nodes: NodeArray<Node>): TransformFlags {
if (nodes === undefined) {
return TransformFlags.None;
}
let subtreeFlags = TransformFlags.None;
let nodeArrayFlags = TransformFlags.None;
for (const node of nodes) {
subtreeFlags |= aggregateTransformFlagsForNode(node);
nodeArrayFlags |= node.transformFlags & ~TransformFlags.HasComputedFlags;
}
nodes.transformFlags = nodeArrayFlags | TransformFlags.HasComputedFlags;
return subtreeFlags;
}
/**
* Aggregates the transform flags for the subtree of a node.
*/
function aggregateTransformFlagsForSubtree(node: Node): TransformFlags {
// We do not transform ambient declarations or types, so there is no need to
// recursively aggregate transform flags.
if (hasModifier(node, ModifierFlags.Ambient) || (isTypeNode(node) && node.kind !== SyntaxKind.ExpressionWithTypeArguments)) {
return TransformFlags.None;
}
// Aggregate the transform flags of each child.
return reduceEachChild(node, TransformFlags.None, aggregateTransformFlagsForChildNode, aggregateTransformFlagsForChildNodes);
}
/**
* Aggregates the TransformFlags of a child node with the TransformFlags of its
* siblings.
*/
function aggregateTransformFlagsForChildNode(transformFlags: TransformFlags, node: Node): TransformFlags {
return transformFlags | aggregateTransformFlagsForNode(node);
}
function aggregateTransformFlagsForChildNodes(transformFlags: TransformFlags, nodes: NodeArray<Node>): TransformFlags {
return transformFlags | aggregateTransformFlagsForNodeArray(nodes);
}
}
+1 -1
View File
@@ -107,7 +107,7 @@ namespace ts.codefix {
}
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Node, errorCode: number, program: Program, cancellationToken: CancellationToken, markSeen: NodeSeenTracker, host: LanguageServiceHost): Declaration | undefined {
if (!isParameterPropertyModifier(token.kind) && token.kind !== SyntaxKind.Identifier && token.kind !== SyntaxKind.DotDotDotToken && token.kind !== SyntaxKind.ThisKeyword) {
if (!isParameterPropertyModifierKind(token.kind) && token.kind !== SyntaxKind.Identifier && token.kind !== SyntaxKind.DotDotDotToken && token.kind !== SyntaxKind.ThisKeyword) {
return undefined;
}
+3 -3
View File
@@ -1620,7 +1620,7 @@ namespace ts.Completions {
function isConstructorParameterCompletion(node: Node): boolean {
return !!node.parent && isParameter(node.parent) && isConstructorDeclaration(node.parent.parent)
&& (isParameterPropertyModifier(node.kind) || isDeclarationName(node));
&& (isParameterPropertyModifierKind(node.kind) || isDeclarationName(node));
}
/**
@@ -1823,7 +1823,7 @@ namespace ts.Completions {
// - its name of the parameter and not being edited
// eg. constructor(a |<- this shouldnt show completion
if (!isIdentifier(contextToken) ||
isParameterPropertyModifier(keywordForNode(contextToken)) ||
isParameterPropertyModifierKind(keywordForNode(contextToken)) ||
isCurrentlyEditingNode(contextToken)) {
return false;
}
@@ -2073,7 +2073,7 @@ namespace ts.Completions {
case KeywordCompletionFilters.InterfaceElementKeywords:
return isInterfaceOrTypeLiteralCompletionKeyword(kind);
case KeywordCompletionFilters.ConstructorParameterKeywords:
return isParameterPropertyModifier(kind);
return isParameterPropertyModifierKind(kind);
case KeywordCompletionFilters.TypeAssertionKeywords:
return isTypeKeyword(kind) || kind === SyntaxKind.ConstKeyword;
case KeywordCompletionFilters.TypeKeywords:
+6 -2
View File
@@ -309,8 +309,12 @@ namespace Harness.Parallel.Host {
});
worker.process.on("exit", (code, _signal) => {
if (code !== 0) {
console.error(`Test worker process exited with nonzero exit code! Output:
${worker.accumulatedOutput}`);
if (worker.currentTasks) {
console.error(`Test worker process exited with nonzero exit code while processing '${worker.currentTasks[0].file}'! Output:\n ${worker.accumulatedOutput}`);
}
else {
console.error(`Test worker process exited with nonzero exit code! Output:\n ${worker.accumulatedOutput}`);
}
return process.exit(2);
}
});
@@ -1,8 +1,16 @@
{
"kind": "NullKeyword",
"kind": "LiteralType",
"pos": 1,
"end": 5,
"flags": "JSDoc",
"modifierFlagsCache": 0,
"transformFlags": 0
"transformFlags": 0,
"literal": {
"kind": "NullKeyword",
"pos": 1,
"end": 5,
"flags": "JSDoc",
"modifierFlagsCache": 0,
"transformFlags": 0
}
}