Reorganize factory-related functionality, update parser to use createNodeArray

This commit is contained in:
Ron Buckton
2019-09-23 13:36:41 -07:00
parent 594a729540
commit c1020ca59d
35 changed files with 3444 additions and 2967 deletions
+1
View File
@@ -1,6 +1,7 @@
namespace ts {
// NOTE: These exports are deprecated in favor of using a `NodeFactory` instance and exist here purely for backwards compatibility reasons.
export const {
createNodeArray,
createNumericLiteral,
createBigIntLiteral,
createStringLiteral,
+7 -7
View File
@@ -3785,7 +3785,7 @@ namespace ts {
function createMappedTypeNodeFromType(type: MappedType) {
Debug.assert(!!(type.flags & TypeFlags.Object));
const readonlyToken = type.declaration.readonlyToken ? <ReadonlyToken | PlusToken | MinusToken>factory.createToken(type.declaration.readonlyToken.kind) : undefined;
const readonlyToken = type.declaration.readonlyToken ? <ReadonlyKeyword | PlusToken | MinusToken>factory.createToken(type.declaration.readonlyToken.kind) : undefined;
const questionToken = type.declaration.questionToken ? <QuestionToken | PlusToken | MinusToken>factory.createToken(type.declaration.questionToken.kind) : undefined;
let appropriateConstraintTypeNode: TypeNode;
if (isMappedTypeWithKeyofConstraintDeclaration(type)) {
@@ -4249,7 +4249,7 @@ namespace ts {
context.approximateLength += 3; // Usually a signature contributes a few more characters than this, but 3 is the minimum
const node = factory.createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode);
if (typeArguments) {
node.typeArguments = createNodeArray(typeArguments);
node.typeArguments = factory.createNodeArray(typeArguments);
}
return node;
}
@@ -4411,7 +4411,7 @@ namespace ts {
let typeParameterNodes: NodeArray<TypeParameterDeclaration> | undefined;
const targetSymbol = getTargetSymbol(symbol);
if (targetSymbol.flags & (SymbolFlags.Class | SymbolFlags.Interface | SymbolFlags.TypeAlias)) {
typeParameterNodes = createNodeArray(map(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), tp => typeParameterToDeclaration(tp, context)));
typeParameterNodes = factory.createNodeArray(map(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), tp => typeParameterToDeclaration(tp, context)));
}
return typeParameterNodes;
}
@@ -21819,14 +21819,14 @@ namespace ts {
}
if (hasRestParameter || hasSpreadArgument) {
spanArray = createNodeArray(args);
spanArray = factory.createNodeArray(args);
if (hasSpreadArgument && argCount) {
const nextArg = elementAt(args, getSpreadArgumentIndex(args) + 1) || undefined;
spanArray = createNodeArray(args.slice(max > argCount && nextArg ? args.indexOf(nextArg) : Math.min(max, args.length - 1)));
spanArray = factory.createNodeArray(args.slice(max > argCount && nextArg ? args.indexOf(nextArg) : Math.min(max, args.length - 1)));
}
}
else {
spanArray = createNodeArray(args.slice(max));
spanArray = factory.createNodeArray(args.slice(max));
}
spanArray.pos = first(spanArray).pos;
@@ -28058,7 +28058,7 @@ namespace ts {
}
}
function checkRightHandSideOfForOf(rhsExpression: Expression, awaitModifier: AwaitKeywordToken | undefined): Type {
function checkRightHandSideOfForOf(rhsExpression: Expression, awaitModifier: AwaitKeyword | undefined): Type {
const expressionType = checkNonNullExpression(rhsExpression);
const use = awaitModifier ? IterationUse.ForAwaitOf : IterationUse.ForOf;
return checkIteratedTypeOrElementType(use, expressionType, undefinedType, rhsExpression);
+7 -2
View File
@@ -2083,9 +2083,14 @@ namespace ts {
}
}
export interface OverloadOptions<A extends any[]> {
minLength?: A["length"];
maxLength?: A["length"];
}
export interface OverloadLengthOptions<A extends any[]> {
length: A["length"];
}
export type Overload<This, A extends any[], R> = ((this: This, ...args: A) => R) & OverloadOptions<A>;
export type OverloadOptions<A extends any[]> = { minLength?: A["length"], maxLength?: A["length"] };
export type OverloadLengthOptions<A extends any[]> = { length: A["length"] };
export type OverloadParameters<O extends Overload<any, any, any>> = O extends unknown ? Parameters<O> : never;
export type OverloadList<This, O extends Overload<This, any, R>[], R> = (this: This, ...args: OverloadParameters<O[number]>) => R;
+5 -5
View File
@@ -642,7 +642,7 @@ namespace ts {
!host.useCaseSensitiveFileNames()
);
sourceFile.text = "";
sourceFile.statements = createNodeArray();
sourceFile.statements = factory.createNodeArray();
return sourceFile;
});
const jsBundle = Debug.assertDefined(bundle.js);
@@ -650,7 +650,7 @@ namespace ts {
const sourceFile = sourceFiles[prologueInfo.file];
sourceFile.text = prologueInfo.text;
sourceFile.end = prologueInfo.text.length;
sourceFile.statements = createNodeArray(prologueInfo.directives.map(directive => {
sourceFile.statements = factory.createNodeArray(prologueInfo.directives.map(directive => {
const statement = createNode(SyntaxKind.ExpressionStatement, directive.pos, directive.end) as PrologueDirective;
statement.expression = createNode(SyntaxKind.StringLiteral, directive.expression.pos, directive.expression.end) as StringLiteral;
statement.expression.text = directive.expression.text;
@@ -3357,15 +3357,15 @@ namespace ts {
}
function emitJSDocTypeLiteral(lit: JSDocTypeLiteral) {
emitList(lit, createNodeArray(lit.jsDocPropertyTags), ListFormat.JSDocComment);
emitList(lit, factory.createNodeArray(lit.jsDocPropertyTags), ListFormat.JSDocComment);
}
function emitJSDocSignature(sig: JSDocSignature) {
if (sig.typeParameters) {
emitList(sig, createNodeArray(sig.typeParameters), ListFormat.JSDocComment);
emitList(sig, factory.createNodeArray(sig.typeParameters), ListFormat.JSDocComment);
}
if (sig.parameters) {
emitList(sig, createNodeArray(sig.parameters), ListFormat.JSDocComment);
emitList(sig, factory.createNodeArray(sig.parameters), ListFormat.JSDocComment);
}
if (sig.type) {
writeLine();
+35
View File
@@ -0,0 +1,35 @@
/* @internal */
namespace ts {
/* @internal */
export function createBaseNodeFactory(): BaseNodeFactory {
// tslint:disable variable-name
let NodeConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node;
let TokenConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node;
let IdentifierConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node;
let SourceFileConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node;
// tslint:enable variable-name
return {
createBaseSourceFileNode,
createBaseIdentifierNode,
createBaseTokenNode,
createBaseNode
};
function createBaseSourceFileNode(kind: SyntaxKind): Node {
return new (SourceFileConstructor || (SourceFileConstructor = objectAllocator.getSourceFileConstructor()))(kind, /*pos*/ -1, /*end*/ -1);
}
function createBaseIdentifierNode(kind: SyntaxKind): Node {
return new (IdentifierConstructor || (IdentifierConstructor = objectAllocator.getIdentifierConstructor()))(kind, /*pos*/ -1, /*end*/ -1);
}
function createBaseTokenNode(kind: SyntaxKind): Node {
return new (TokenConstructor || (TokenConstructor = objectAllocator.getTokenConstructor()))(kind, /*pos*/ -1, /*end*/ -1);
}
function createBaseNode(kind: SyntaxKind): Node {
return new (NodeConstructor || (NodeConstructor = objectAllocator.getNodeConstructor()))(kind, /*pos*/ -1, /*end*/ -1);
}
}
}
+139
View File
@@ -0,0 +1,139 @@
/* @internal */
namespace ts {
export function createNodeConverters(factory: NodeFactory): NodeConverters {
return {
convertToFunctionBlock,
convertToFunctionExpression,
convertToArrayAssignmentElement,
convertToObjectAssignmentElement,
convertToAssignmentPattern,
convertToObjectAssignmentPattern,
convertToArrayAssignmentPattern,
convertToAssignmentElementTarget,
};
function convertToFunctionBlock(node: ConciseBody, multiLine?: boolean): Block {
if (isBlock(node)) return node;
const returnStatement = factory.createReturn(node);
setTextRange(returnStatement, node);
const body = factory.createBlock([returnStatement], multiLine);
setTextRange(body, node);
aggregateTransformFlags(body);
return body;
}
function convertToFunctionExpression(node: FunctionDeclaration) {
if (!node.body) return Debug.fail(`Cannot convert a FunctionDeclaration without a body`);
const updated = factory.createFunctionExpression(
node.modifiers,
node.asteriskToken,
node.name,
node.typeParameters,
node.parameters,
node.type,
node.body
);
setOriginalNode(updated, node);
setTextRange(updated, node);
if (getStartsOnNewLine(node)) {
setStartsOnNewLine(updated, /*newLine*/ true);
}
aggregateTransformFlags(updated);
return updated;
}
function convertToArrayAssignmentElement(element: ArrayBindingOrAssignmentElement) {
if (isBindingElement(element)) {
if (element.dotDotDotToken) {
Debug.assertNode(element.name, isIdentifier);
return setOriginalNode(setTextRange(factory.createSpread(<Identifier>element.name), element), element);
}
const expression = convertToAssignmentElementTarget(element.name);
return element.initializer
? setOriginalNode(
setTextRange(
factory.createAssignment(expression, element.initializer),
element
),
element
)
: expression;
}
return cast(element, isExpression);
}
function convertToObjectAssignmentElement(element: ObjectBindingOrAssignmentElement) {
if (isBindingElement(element)) {
if (element.dotDotDotToken) {
Debug.assertNode(element.name, isIdentifier);
return setOriginalNode(setTextRange(factory.createSpreadAssignment(<Identifier>element.name), element), element);
}
if (element.propertyName) {
const expression = convertToAssignmentElementTarget(element.name);
return setOriginalNode(setTextRange(factory.createPropertyAssignment(element.propertyName, element.initializer ? factory.createAssignment(expression, element.initializer) : expression), element), element);
}
Debug.assertNode(element.name, isIdentifier);
return setOriginalNode(setTextRange(factory.createShorthandPropertyAssignment(<Identifier>element.name, element.initializer), element), element);
}
return cast(element, isObjectLiteralElementLike);
}
function convertToAssignmentPattern(node: BindingOrAssignmentPattern): AssignmentPattern {
switch (node.kind) {
case SyntaxKind.ArrayBindingPattern:
case SyntaxKind.ArrayLiteralExpression:
return convertToArrayAssignmentPattern(node);
case SyntaxKind.ObjectBindingPattern:
case SyntaxKind.ObjectLiteralExpression:
return convertToObjectAssignmentPattern(node);
}
}
function convertToObjectAssignmentPattern(node: ObjectBindingOrAssignmentPattern) {
if (isObjectBindingPattern(node)) {
return setOriginalNode(
setTextRange(
factory.createObjectLiteral(map(node.elements, convertToObjectAssignmentElement)),
node
),
node
);
}
return cast(node, isObjectLiteralExpression);
}
function convertToArrayAssignmentPattern(node: ArrayBindingOrAssignmentPattern) {
if (isArrayBindingPattern(node)) {
return setOriginalNode(
setTextRange(
factory.createArrayLiteral(map(node.elements, convertToArrayAssignmentElement)),
node
),
node
);
}
return cast(node, isArrayLiteralExpression);
}
function convertToAssignmentElementTarget(node: BindingOrAssignmentElementTarget): Expression {
if (isBindingPattern(node)) {
return convertToAssignmentPattern(node);
}
return cast(node, isExpression);
}
}
export const nullNodeConverters: NodeConverters = {
convertToFunctionBlock: notImplemented,
convertToFunctionExpression: notImplemented,
convertToArrayAssignmentElement: notImplemented,
convertToObjectAssignmentElement: notImplemented,
convertToAssignmentPattern: notImplemented,
convertToObjectAssignmentPattern: notImplemented,
convertToArrayAssignmentPattern: notImplemented,
convertToAssignmentElementTarget: notImplemented,
};
}
@@ -343,6 +343,15 @@ namespace ts {
}
}
/* @internal */
export function compareEmitHelpers(x: EmitHelper, y: EmitHelper) {
if (x === y) return Comparison.EqualTo;
if (x.priority === y.priority) return Comparison.EqualTo;
if (x.priority === undefined) return Comparison.GreaterThan;
if (y.priority === undefined) return Comparison.LessThan;
return compareValues(x.priority, y.priority);
}
/**
* @param input Template string input strings
* @param args Names which need to be made file-level unique
+270
View File
@@ -0,0 +1,270 @@
namespace ts {
/**
* Clears any EmitNode entries from parse-tree nodes.
* @param sourceFile A source file.
*/
export function disposeEmitNodes(sourceFile: SourceFile | undefined) {
// During transformation we may need to annotate a parse tree node with transient
// transformation properties. As parse tree nodes live longer than transformation
// nodes, we need to make sure we reclaim any memory allocated for custom ranges
// from these nodes to ensure we do not hold onto entire subtrees just for position
// information. We also need to reset these nodes to a pre-transformation state
// for incremental parsing scenarios so that we do not impact later emit.
sourceFile = getSourceFileOfNode(getParseTreeNode(sourceFile));
const emitNode = sourceFile && sourceFile.emitNode;
const annotatedNodes = emitNode && emitNode.annotatedNodes;
if (annotatedNodes) {
for (const node of annotatedNodes) {
node.emitNode = undefined;
}
}
}
/**
* Associates a node with the current transformation, initializing
* various transient transformation properties.
*/
/* @internal */
export function getOrCreateEmitNode(node: Node): EmitNode {
if (!node.emitNode) {
if (isParseTreeNode(node)) {
// To avoid holding onto transformation artifacts, we keep track of any
// parse tree node we are annotating. This allows us to clean them up after
// all transformations have completed.
if (node.kind === SyntaxKind.SourceFile) {
return node.emitNode = { annotatedNodes: [node] } as EmitNode;
}
const sourceFile = getSourceFileOfNode(getParseTreeNode(getSourceFileOfNode(node))) || Debug.fail("Could not determine parsed source file.");
getOrCreateEmitNode(sourceFile).annotatedNodes!.push(node);
}
node.emitNode = {} as EmitNode;
}
return node.emitNode;
}
/**
* Sets `EmitFlags.NoComments` on a node and removes any leading and trailing synthetic comments.
* @internal
*/
export function removeAllComments<T extends Node>(node: T): T {
const emitNode = getOrCreateEmitNode(node);
emitNode.flags |= EmitFlags.NoComments;
emitNode.leadingComments = undefined;
emitNode.trailingComments = undefined;
return node;
}
/**
* Sets flags that control emit behavior of a node.
*/
export function setEmitFlags<T extends Node>(node: T, emitFlags: EmitFlags) {
getOrCreateEmitNode(node).flags = emitFlags;
return node;
}
/**
* Sets flags that control emit behavior of a node.
*/
/* @internal */
export function addEmitFlags<T extends Node>(node: T, emitFlags: EmitFlags) {
const emitNode = getOrCreateEmitNode(node);
emitNode.flags = emitNode.flags | emitFlags;
return node;
}
/**
* Gets a custom text range to use when emitting source maps.
*/
export function getSourceMapRange(node: Node): SourceMapRange {
const emitNode = node.emitNode;
return (emitNode && emitNode.sourceMapRange) || node;
}
/**
* Sets a custom text range to use when emitting source maps.
*/
export function setSourceMapRange<T extends Node>(node: T, range: SourceMapRange | undefined) {
getOrCreateEmitNode(node).sourceMapRange = range;
return node;
}
/**
* Gets the TextRange to use for source maps for a token of a node.
*/
export function getTokenSourceMapRange(node: Node, token: SyntaxKind): SourceMapRange | undefined {
const emitNode = node.emitNode;
const tokenSourceMapRanges = emitNode && emitNode.tokenSourceMapRanges;
return tokenSourceMapRanges && tokenSourceMapRanges[token];
}
/**
* Sets the TextRange to use for source maps for a token of a node.
*/
export function setTokenSourceMapRange<T extends Node>(node: T, token: SyntaxKind, range: SourceMapRange | undefined) {
const emitNode = getOrCreateEmitNode(node);
const tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = []);
tokenSourceMapRanges[token] = range;
return node;
}
/**
* Gets a custom text range to use when emitting comments.
*/
/*@internal*/
export function getStartsOnNewLine(node: Node) {
const emitNode = node.emitNode;
return emitNode && emitNode.startsOnNewLine;
}
/**
* Sets a custom text range to use when emitting comments.
*/
/*@internal*/
export function setStartsOnNewLine<T extends Node>(node: T, newLine: boolean) {
getOrCreateEmitNode(node).startsOnNewLine = newLine;
return node;
}
/**
* Gets a custom text range to use when emitting comments.
*/
export function getCommentRange(node: Node) {
const emitNode = node.emitNode;
return (emitNode && emitNode.commentRange) || node;
}
/**
* Sets a custom text range to use when emitting comments.
*/
export function setCommentRange<T extends Node>(node: T, range: TextRange) {
getOrCreateEmitNode(node).commentRange = range;
return node;
}
export function getSyntheticLeadingComments(node: Node): SynthesizedComment[] | undefined {
const emitNode = node.emitNode;
return emitNode && emitNode.leadingComments;
}
export function setSyntheticLeadingComments<T extends Node>(node: T, comments: SynthesizedComment[] | undefined) {
getOrCreateEmitNode(node).leadingComments = comments;
return node;
}
export function addSyntheticLeadingComment<T extends Node>(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean) {
return setSyntheticLeadingComments(node, append<SynthesizedComment>(getSyntheticLeadingComments(node), { kind, pos: -1, end: -1, hasTrailingNewLine, text }));
}
export function getSyntheticTrailingComments(node: Node): SynthesizedComment[] | undefined {
const emitNode = node.emitNode;
return emitNode && emitNode.trailingComments;
}
export function setSyntheticTrailingComments<T extends Node>(node: T, comments: SynthesizedComment[] | undefined) {
getOrCreateEmitNode(node).trailingComments = comments;
return node;
}
export function addSyntheticTrailingComment<T extends Node>(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean) {
return setSyntheticTrailingComments(node, append<SynthesizedComment>(getSyntheticTrailingComments(node), { kind, pos: -1, end: -1, hasTrailingNewLine, text }));
}
export function moveSyntheticComments<T extends Node>(node: T, original: Node): T {
setSyntheticLeadingComments(node, getSyntheticLeadingComments(original));
setSyntheticTrailingComments(node, getSyntheticTrailingComments(original));
const emit = getOrCreateEmitNode(original);
emit.leadingComments = undefined;
emit.trailingComments = undefined;
return node;
}
/**
* Gets the constant value to emit for an expression.
*/
export function getConstantValue(node: PropertyAccessExpression | ElementAccessExpression): string | number | undefined {
const emitNode = node.emitNode;
return emitNode && emitNode.constantValue;
}
/**
* Sets the constant value to emit for an expression.
*/
export function setConstantValue(node: PropertyAccessExpression | ElementAccessExpression, value: string | number) {
const emitNode = getOrCreateEmitNode(node);
emitNode.constantValue = value;
return node;
}
/**
* Adds an EmitHelper to a node.
*/
export function addEmitHelper<T extends Node>(node: T, helper: EmitHelper): T {
const emitNode = getOrCreateEmitNode(node);
emitNode.helpers = append(emitNode.helpers, helper);
return node;
}
/**
* Add EmitHelpers to a node.
*/
export function addEmitHelpers<T extends Node>(node: T, helpers: EmitHelper[] | undefined): T {
if (some(helpers)) {
const emitNode = getOrCreateEmitNode(node);
for (const helper of helpers) {
emitNode.helpers = appendIfUnique(emitNode.helpers, helper);
}
}
return node;
}
/**
* Removes an EmitHelper from a node.
*/
export function removeEmitHelper(node: Node, helper: EmitHelper): boolean {
const emitNode = node.emitNode;
if (emitNode) {
const helpers = emitNode.helpers;
if (helpers) {
return orderedRemoveItem(helpers, helper);
}
}
return false;
}
/**
* Gets the EmitHelpers of a node.
*/
export function getEmitHelpers(node: Node): EmitHelper[] | undefined {
const emitNode = node.emitNode;
return emitNode && emitNode.helpers;
}
/**
* Moves matching emit helpers from a source node to a target node.
*/
export function moveEmitHelpers(source: Node, target: Node, predicate: (helper: EmitHelper) => boolean) {
const sourceEmitNode = source.emitNode;
const sourceEmitHelpers = sourceEmitNode && sourceEmitNode.helpers;
if (!some(sourceEmitHelpers)) return;
const targetEmitNode = getOrCreateEmitNode(target);
let helpersRemoved = 0;
for (let i = 0; i < sourceEmitHelpers.length; i++) {
const helper = sourceEmitHelpers[i];
if (predicate(helper)) {
helpersRemoved++;
targetEmitNode.helpers = appendIfUnique(targetEmitNode.helpers, helper);
}
else if (helpersRemoved > 0) {
sourceEmitHelpers[i - helpersRemoved] = helper;
}
}
if (helpersRemoved > 0) {
sourceEmitHelpers.length -= helpersRemoved;
}
}
}
File diff suppressed because it is too large Load Diff
+758
View File
@@ -0,0 +1,758 @@
namespace ts {
// Literals
export function isNumericLiteral(node: Node): node is NumericLiteral {
return node.kind === SyntaxKind.NumericLiteral;
}
export function isBigIntLiteral(node: Node): node is BigIntLiteral {
return node.kind === SyntaxKind.BigIntLiteral;
}
export function isStringLiteral(node: Node): node is StringLiteral {
return node.kind === SyntaxKind.StringLiteral;
}
export function isJsxText(node: Node): node is JsxText {
return node.kind === SyntaxKind.JsxText;
}
export function isRegularExpressionLiteral(node: Node): node is RegularExpressionLiteral {
return node.kind === SyntaxKind.RegularExpressionLiteral;
}
export function isNoSubstitutionTemplateLiteral(node: Node): node is NoSubstitutionTemplateLiteral {
return node.kind === SyntaxKind.NoSubstitutionTemplateLiteral;
}
// Pseudo-literals
export function isTemplateHead(node: Node): node is TemplateHead {
return node.kind === SyntaxKind.TemplateHead;
}
export function isTemplateMiddle(node: Node): node is TemplateMiddle {
return node.kind === SyntaxKind.TemplateMiddle;
}
export function isTemplateTail(node: Node): node is TemplateTail {
return node.kind === SyntaxKind.TemplateTail;
}
// Identifiers
export function isIdentifier(node: Node): node is Identifier {
return node.kind === SyntaxKind.Identifier;
}
// Names
export function isQualifiedName(node: Node): node is QualifiedName {
return node.kind === SyntaxKind.QualifiedName;
}
export function isComputedPropertyName(node: Node): node is ComputedPropertyName {
return node.kind === SyntaxKind.ComputedPropertyName;
}
// Signature elements
export function isTypeParameterDeclaration(node: Node): node is TypeParameterDeclaration {
return node.kind === SyntaxKind.TypeParameter;
}
// TODO(rbuckton): Rename to 'isParameterDeclaration'
export function isParameter(node: Node): node is ParameterDeclaration {
return node.kind === SyntaxKind.Parameter;
}
export function isDecorator(node: Node): node is Decorator {
return node.kind === SyntaxKind.Decorator;
}
// TypeMember
export function isPropertySignature(node: Node): node is PropertySignature {
return node.kind === SyntaxKind.PropertySignature;
}
export function isPropertyDeclaration(node: Node): node is PropertyDeclaration {
return node.kind === SyntaxKind.PropertyDeclaration;
}
export function isMethodSignature(node: Node): node is MethodSignature {
return node.kind === SyntaxKind.MethodSignature;
}
export function isMethodDeclaration(node: Node): node is MethodDeclaration {
return node.kind === SyntaxKind.MethodDeclaration;
}
export function isConstructorDeclaration(node: Node): node is ConstructorDeclaration {
return node.kind === SyntaxKind.Constructor;
}
export function isGetAccessorDeclaration(node: Node): node is GetAccessorDeclaration {
return node.kind === SyntaxKind.GetAccessor;
}
export function isSetAccessorDeclaration(node: Node): node is SetAccessorDeclaration {
return node.kind === SyntaxKind.SetAccessor;
}
export function isCallSignatureDeclaration(node: Node): node is CallSignatureDeclaration {
return node.kind === SyntaxKind.CallSignature;
}
export function isConstructSignatureDeclaration(node: Node): node is ConstructSignatureDeclaration {
return node.kind === SyntaxKind.ConstructSignature;
}
export function isIndexSignatureDeclaration(node: Node): node is IndexSignatureDeclaration {
return node.kind === SyntaxKind.IndexSignature;
}
// Type
export function isTypePredicateNode(node: Node): node is TypePredicateNode {
return node.kind === SyntaxKind.TypePredicate;
}
export function isTypeReferenceNode(node: Node): node is TypeReferenceNode {
return node.kind === SyntaxKind.TypeReference;
}
export function isFunctionTypeNode(node: Node): node is FunctionTypeNode {
return node.kind === SyntaxKind.FunctionType;
}
export function isConstructorTypeNode(node: Node): node is ConstructorTypeNode {
return node.kind === SyntaxKind.ConstructorType;
}
export function isTypeQueryNode(node: Node): node is TypeQueryNode {
return node.kind === SyntaxKind.TypeQuery;
}
export function isTypeLiteralNode(node: Node): node is TypeLiteralNode {
return node.kind === SyntaxKind.TypeLiteral;
}
export function isArrayTypeNode(node: Node): node is ArrayTypeNode {
return node.kind === SyntaxKind.ArrayType;
}
export function isTupleTypeNode(node: Node): node is TupleTypeNode {
return node.kind === SyntaxKind.TupleType;
}
export function isOptionalTypeNode(node: Node): node is OptionalTypeNode {
return node.kind === SyntaxKind.OptionalType;
}
export function isRestTypeNode(node: Node): node is RestTypeNode {
return node.kind === SyntaxKind.RestType;
}
export function isUnionTypeNode(node: Node): node is UnionTypeNode {
return node.kind === SyntaxKind.UnionType;
}
export function isIntersectionTypeNode(node: Node): node is IntersectionTypeNode {
return node.kind === SyntaxKind.IntersectionType;
}
export function isConditionalTypeNode(node: Node): node is ConditionalTypeNode {
return node.kind === SyntaxKind.ConditionalType;
}
export function isInferTypeNode(node: Node): node is InferTypeNode {
return node.kind === SyntaxKind.InferType;
}
export function isParenthesizedTypeNode(node: Node): node is ParenthesizedTypeNode {
return node.kind === SyntaxKind.ParenthesizedType;
}
export function isThisTypeNode(node: Node): node is ThisTypeNode {
return node.kind === SyntaxKind.ThisType;
}
export function isTypeOperatorNode(node: Node): node is TypeOperatorNode {
return node.kind === SyntaxKind.TypeOperator;
}
export function isIndexedAccessTypeNode(node: Node): node is IndexedAccessTypeNode {
return node.kind === SyntaxKind.IndexedAccessType;
}
export function isMappedTypeNode(node: Node): node is MappedTypeNode {
return node.kind === SyntaxKind.MappedType;
}
export function isLiteralTypeNode(node: Node): node is LiteralTypeNode {
return node.kind === SyntaxKind.LiteralType;
}
export function isImportTypeNode(node: Node): node is ImportTypeNode {
return node.kind === SyntaxKind.ImportType;
}
// Binding patterns
export function isObjectBindingPattern(node: Node): node is ObjectBindingPattern {
return node.kind === SyntaxKind.ObjectBindingPattern;
}
export function isArrayBindingPattern(node: Node): node is ArrayBindingPattern {
return node.kind === SyntaxKind.ArrayBindingPattern;
}
export function isBindingElement(node: Node): node is BindingElement {
return node.kind === SyntaxKind.BindingElement;
}
// Expression
export function isArrayLiteralExpression(node: Node): node is ArrayLiteralExpression {
return node.kind === SyntaxKind.ArrayLiteralExpression;
}
export function isObjectLiteralExpression(node: Node): node is ObjectLiteralExpression {
return node.kind === SyntaxKind.ObjectLiteralExpression;
}
export function isPropertyAccessExpression(node: Node): node is PropertyAccessExpression {
return node.kind === SyntaxKind.PropertyAccessExpression;
}
export function isElementAccessExpression(node: Node): node is ElementAccessExpression {
return node.kind === SyntaxKind.ElementAccessExpression;
}
export function isCallExpression(node: Node): node is CallExpression {
return node.kind === SyntaxKind.CallExpression;
}
export function isNewExpression(node: Node): node is NewExpression {
return node.kind === SyntaxKind.NewExpression;
}
export function isTaggedTemplateExpression(node: Node): node is TaggedTemplateExpression {
return node.kind === SyntaxKind.TaggedTemplateExpression;
}
export function isTypeAssertionExpression(node: Node): node is TypeAssertion {
return node.kind === SyntaxKind.TypeAssertionExpression;
}
export function isParenthesizedExpression(node: Node): node is ParenthesizedExpression {
return node.kind === SyntaxKind.ParenthesizedExpression;
}
export function isFunctionExpression(node: Node): node is FunctionExpression {
return node.kind === SyntaxKind.FunctionExpression;
}
export function isArrowFunction(node: Node): node is ArrowFunction {
return node.kind === SyntaxKind.ArrowFunction;
}
export function isDeleteExpression(node: Node): node is DeleteExpression {
return node.kind === SyntaxKind.DeleteExpression;
}
export function isTypeOfExpression(node: Node): node is TypeOfExpression {
return node.kind === SyntaxKind.TypeOfExpression;
}
export function isVoidExpression(node: Node): node is VoidExpression {
return node.kind === SyntaxKind.VoidExpression;
}
export function isAwaitExpression(node: Node): node is AwaitExpression {
return node.kind === SyntaxKind.AwaitExpression;
}
export function isPrefixUnaryExpression(node: Node): node is PrefixUnaryExpression {
return node.kind === SyntaxKind.PrefixUnaryExpression;
}
export function isPostfixUnaryExpression(node: Node): node is PostfixUnaryExpression {
return node.kind === SyntaxKind.PostfixUnaryExpression;
}
export function isBinaryExpression(node: Node): node is BinaryExpression {
return node.kind === SyntaxKind.BinaryExpression;
}
export function isConditionalExpression(node: Node): node is ConditionalExpression {
return node.kind === SyntaxKind.ConditionalExpression;
}
export function isTemplateExpression(node: Node): node is TemplateExpression {
return node.kind === SyntaxKind.TemplateExpression;
}
export function isYieldExpression(node: Node): node is YieldExpression {
return node.kind === SyntaxKind.YieldExpression;
}
export function isSpreadElement(node: Node): node is SpreadElement {
return node.kind === SyntaxKind.SpreadElement;
}
export function isClassExpression(node: Node): node is ClassExpression {
return node.kind === SyntaxKind.ClassExpression;
}
export function isOmittedExpression(node: Node): node is OmittedExpression {
return node.kind === SyntaxKind.OmittedExpression;
}
export function isExpressionWithTypeArguments(node: Node): node is ExpressionWithTypeArguments {
return node.kind === SyntaxKind.ExpressionWithTypeArguments;
}
export function isAsExpression(node: Node): node is AsExpression {
return node.kind === SyntaxKind.AsExpression;
}
export function isNonNullExpression(node: Node): node is NonNullExpression {
return node.kind === SyntaxKind.NonNullExpression;
}
export function isMetaProperty(node: Node): node is MetaProperty {
return node.kind === SyntaxKind.MetaProperty;
}
export function isSyntheticExpression(node: Node): node is SyntheticExpression {
return node.kind === SyntaxKind.SyntheticExpression;
}
export function isPartiallyEmittedExpression(node: Node): node is PartiallyEmittedExpression {
return node.kind === SyntaxKind.PartiallyEmittedExpression;
}
export function isCommaListExpression(node: Node): node is CommaListExpression {
return node.kind === SyntaxKind.CommaListExpression;
}
// Misc
export function isTemplateSpan(node: Node): node is TemplateSpan {
return node.kind === SyntaxKind.TemplateSpan;
}
export function isSemicolonClassElement(node: Node): node is SemicolonClassElement {
return node.kind === SyntaxKind.SemicolonClassElement;
}
// Elements
export function isBlock(node: Node): node is Block {
return node.kind === SyntaxKind.Block;
}
export function isVariableStatement(node: Node): node is VariableStatement {
return node.kind === SyntaxKind.VariableStatement;
}
export function isEmptyStatement(node: Node): node is EmptyStatement {
return node.kind === SyntaxKind.EmptyStatement;
}
export function isExpressionStatement(node: Node): node is ExpressionStatement {
return node.kind === SyntaxKind.ExpressionStatement;
}
export function isIfStatement(node: Node): node is IfStatement {
return node.kind === SyntaxKind.IfStatement;
}
export function isDoStatement(node: Node): node is DoStatement {
return node.kind === SyntaxKind.DoStatement;
}
export function isWhileStatement(node: Node): node is WhileStatement {
return node.kind === SyntaxKind.WhileStatement;
}
export function isForStatement(node: Node): node is ForStatement {
return node.kind === SyntaxKind.ForStatement;
}
export function isForInStatement(node: Node): node is ForInStatement {
return node.kind === SyntaxKind.ForInStatement;
}
export function isForOfStatement(node: Node): node is ForOfStatement {
return node.kind === SyntaxKind.ForOfStatement;
}
export function isContinueStatement(node: Node): node is ContinueStatement {
return node.kind === SyntaxKind.ContinueStatement;
}
export function isBreakStatement(node: Node): node is BreakStatement {
return node.kind === SyntaxKind.BreakStatement;
}
export function isReturnStatement(node: Node): node is ReturnStatement {
return node.kind === SyntaxKind.ReturnStatement;
}
export function isWithStatement(node: Node): node is WithStatement {
return node.kind === SyntaxKind.WithStatement;
}
export function isSwitchStatement(node: Node): node is SwitchStatement {
return node.kind === SyntaxKind.SwitchStatement;
}
export function isLabeledStatement(node: Node): node is LabeledStatement {
return node.kind === SyntaxKind.LabeledStatement;
}
export function isThrowStatement(node: Node): node is ThrowStatement {
return node.kind === SyntaxKind.ThrowStatement;
}
export function isTryStatement(node: Node): node is TryStatement {
return node.kind === SyntaxKind.TryStatement;
}
export function isDebuggerStatement(node: Node): node is DebuggerStatement {
return node.kind === SyntaxKind.DebuggerStatement;
}
export function isVariableDeclaration(node: Node): node is VariableDeclaration {
return node.kind === SyntaxKind.VariableDeclaration;
}
export function isVariableDeclarationList(node: Node): node is VariableDeclarationList {
return node.kind === SyntaxKind.VariableDeclarationList;
}
export function isFunctionDeclaration(node: Node): node is FunctionDeclaration {
return node.kind === SyntaxKind.FunctionDeclaration;
}
export function isClassDeclaration(node: Node): node is ClassDeclaration {
return node.kind === SyntaxKind.ClassDeclaration;
}
export function isInterfaceDeclaration(node: Node): node is InterfaceDeclaration {
return node.kind === SyntaxKind.InterfaceDeclaration;
}
export function isTypeAliasDeclaration(node: Node): node is TypeAliasDeclaration {
return node.kind === SyntaxKind.TypeAliasDeclaration;
}
export function isEnumDeclaration(node: Node): node is EnumDeclaration {
return node.kind === SyntaxKind.EnumDeclaration;
}
export function isModuleDeclaration(node: Node): node is ModuleDeclaration {
return node.kind === SyntaxKind.ModuleDeclaration;
}
export function isModuleBlock(node: Node): node is ModuleBlock {
return node.kind === SyntaxKind.ModuleBlock;
}
export function isCaseBlock(node: Node): node is CaseBlock {
return node.kind === SyntaxKind.CaseBlock;
}
export function isNamespaceExportDeclaration(node: Node): node is NamespaceExportDeclaration {
return node.kind === SyntaxKind.NamespaceExportDeclaration;
}
export function isImportEqualsDeclaration(node: Node): node is ImportEqualsDeclaration {
return node.kind === SyntaxKind.ImportEqualsDeclaration;
}
export function isImportDeclaration(node: Node): node is ImportDeclaration {
return node.kind === SyntaxKind.ImportDeclaration;
}
export function isImportClause(node: Node): node is ImportClause {
return node.kind === SyntaxKind.ImportClause;
}
export function isNamespaceImport(node: Node): node is NamespaceImport {
return node.kind === SyntaxKind.NamespaceImport;
}
export function isNamedImports(node: Node): node is NamedImports {
return node.kind === SyntaxKind.NamedImports;
}
export function isImportSpecifier(node: Node): node is ImportSpecifier {
return node.kind === SyntaxKind.ImportSpecifier;
}
export function isExportAssignment(node: Node): node is ExportAssignment {
return node.kind === SyntaxKind.ExportAssignment;
}
export function isExportDeclaration(node: Node): node is ExportDeclaration {
return node.kind === SyntaxKind.ExportDeclaration;
}
export function isNamedExports(node: Node): node is NamedExports {
return node.kind === SyntaxKind.NamedExports;
}
export function isExportSpecifier(node: Node): node is ExportSpecifier {
return node.kind === SyntaxKind.ExportSpecifier;
}
export function isMissingDeclaration(node: Node): node is MissingDeclaration {
return node.kind === SyntaxKind.MissingDeclaration;
}
export function isNotEmittedStatement(node: Node): node is NotEmittedStatement {
return node.kind === SyntaxKind.NotEmittedStatement;
}
/* @internal */
export function isMergeDeclarationMarker(node: Node): node is MergeDeclarationMarker {
return node.kind === SyntaxKind.MergeDeclarationMarker;
}
/* @internal */
export function isEndOfDeclarationMarker(node: Node): node is EndOfDeclarationMarker {
return node.kind === SyntaxKind.EndOfDeclarationMarker;
}
// Module References
export function isExternalModuleReference(node: Node): node is ExternalModuleReference {
return node.kind === SyntaxKind.ExternalModuleReference;
}
// JSX
export function isJsxElement(node: Node): node is JsxElement {
return node.kind === SyntaxKind.JsxElement;
}
export function isJsxSelfClosingElement(node: Node): node is JsxSelfClosingElement {
return node.kind === SyntaxKind.JsxSelfClosingElement;
}
export function isJsxOpeningElement(node: Node): node is JsxOpeningElement {
return node.kind === SyntaxKind.JsxOpeningElement;
}
export function isJsxClosingElement(node: Node): node is JsxClosingElement {
return node.kind === SyntaxKind.JsxClosingElement;
}
export function isJsxFragment(node: Node): node is JsxFragment {
return node.kind === SyntaxKind.JsxFragment;
}
export function isJsxOpeningFragment(node: Node): node is JsxOpeningFragment {
return node.kind === SyntaxKind.JsxOpeningFragment;
}
export function isJsxClosingFragment(node: Node): node is JsxClosingFragment {
return node.kind === SyntaxKind.JsxClosingFragment;
}
export function isJsxAttribute(node: Node): node is JsxAttribute {
return node.kind === SyntaxKind.JsxAttribute;
}
export function isJsxAttributes(node: Node): node is JsxAttributes {
return node.kind === SyntaxKind.JsxAttributes;
}
export function isJsxSpreadAttribute(node: Node): node is JsxSpreadAttribute {
return node.kind === SyntaxKind.JsxSpreadAttribute;
}
export function isJsxExpression(node: Node): node is JsxExpression {
return node.kind === SyntaxKind.JsxExpression;
}
// Clauses
export function isCaseClause(node: Node): node is CaseClause {
return node.kind === SyntaxKind.CaseClause;
}
export function isDefaultClause(node: Node): node is DefaultClause {
return node.kind === SyntaxKind.DefaultClause;
}
export function isHeritageClause(node: Node): node is HeritageClause {
return node.kind === SyntaxKind.HeritageClause;
}
export function isCatchClause(node: Node): node is CatchClause {
return node.kind === SyntaxKind.CatchClause;
}
// Property assignments
export function isPropertyAssignment(node: Node): node is PropertyAssignment {
return node.kind === SyntaxKind.PropertyAssignment;
}
export function isShorthandPropertyAssignment(node: Node): node is ShorthandPropertyAssignment {
return node.kind === SyntaxKind.ShorthandPropertyAssignment;
}
export function isSpreadAssignment(node: Node): node is SpreadAssignment {
return node.kind === SyntaxKind.SpreadAssignment;
}
// Enum
export function isEnumMember(node: Node): node is EnumMember {
return node.kind === SyntaxKind.EnumMember;
}
// Unparsed
// TODO(rbuckton): isUnparsedPrologue
export function isUnparsedPrepend(node: Node): node is UnparsedPrepend {
return node.kind === SyntaxKind.UnparsedPrepend;
}
// TODO(rbuckton): isUnparsedText
// TODO(rbuckton): isUnparsedInternalText
// TODO(rbuckton): isUnparsedSyntheticReference
// Top-level nodes
export function isSourceFile(node: Node): node is SourceFile {
return node.kind === SyntaxKind.SourceFile;
}
export function isBundle(node: Node): node is Bundle {
return node.kind === SyntaxKind.Bundle;
}
export function isUnparsedSource(node: Node): node is UnparsedSource {
return node.kind === SyntaxKind.UnparsedSource;
}
// TODO(rbuckton): isInputFiles
// JSDoc Elements
export function isJSDocTypeExpression(node: Node): node is JSDocTypeExpression {
return node.kind === SyntaxKind.JSDocTypeExpression;
}
export function isJSDocAllType(node: JSDocAllType): node is JSDocAllType {
return node.kind === SyntaxKind.JSDocAllType;
}
export function isJSDocUnknownType(node: Node): node is JSDocUnknownType {
return node.kind === SyntaxKind.JSDocUnknownType;
}
export function isJSDocNullableType(node: Node): node is JSDocNullableType {
return node.kind === SyntaxKind.JSDocNullableType;
}
export function isJSDocNonNullableType(node: Node): node is JSDocNonNullableType {
return node.kind === SyntaxKind.JSDocNonNullableType;
}
export function isJSDocOptionalType(node: Node): node is JSDocOptionalType {
return node.kind === SyntaxKind.JSDocOptionalType;
}
export function isJSDocFunctionType(node: Node): node is JSDocFunctionType {
return node.kind === SyntaxKind.JSDocFunctionType;
}
export function isJSDocVariadicType(node: Node): node is JSDocVariadicType {
return node.kind === SyntaxKind.JSDocVariadicType;
}
export function isJSDocNamepathType(node: Node): node is JSDocNamepathType {
return node.kind === SyntaxKind.JSDocNamepathType;
}
export function isJSDoc(node: Node): node is JSDoc {
return node.kind === SyntaxKind.JSDocComment;
}
export function isJSDocTypeLiteral(node: Node): node is JSDocTypeLiteral {
return node.kind === SyntaxKind.JSDocTypeLiteral;
}
export function isJSDocSignature(node: Node): node is JSDocSignature {
return node.kind === SyntaxKind.JSDocSignature;
}
// JSDoc Tags
export function isJSDocAugmentsTag(node: Node): node is JSDocAugmentsTag {
return node.kind === SyntaxKind.JSDocAugmentsTag;
}
export function isJSDocAuthorTag(node: Node): node is JSDocAuthorTag {
return node.kind === SyntaxKind.JSDocAuthorTag;
}
export function isJSDocClassTag(node: Node): node is JSDocClassTag {
return node.kind === SyntaxKind.JSDocClassTag;
}
export function isJSDocCallbackTag(node: Node): node is JSDocCallbackTag {
return node.kind === SyntaxKind.JSDocCallbackTag;
}
export function isJSDocEnumTag(node: Node): node is JSDocEnumTag {
return node.kind === SyntaxKind.JSDocEnumTag;
}
export function isJSDocParameterTag(node: Node): node is JSDocParameterTag {
return node.kind === SyntaxKind.JSDocParameterTag;
}
export function isJSDocReturnTag(node: Node): node is JSDocReturnTag {
return node.kind === SyntaxKind.JSDocReturnTag;
}
export function isJSDocThisTag(node: Node): node is JSDocThisTag {
return node.kind === SyntaxKind.JSDocThisTag;
}
export function isJSDocTypeTag(node: Node): node is JSDocTypeTag {
return node.kind === SyntaxKind.JSDocTypeTag;
}
export function isJSDocTemplateTag(node: Node): node is JSDocTemplateTag {
return node.kind === SyntaxKind.JSDocTemplateTag;
}
export function isJSDocTypedefTag(node: Node): node is JSDocTypedefTag {
return node.kind === SyntaxKind.JSDocTypedefTag;
}
export function isJSDocUnknownTag(node: Node): node is JSDocUnknownTag {
return node.kind === SyntaxKind.JSDocTag;
}
export function isJSDocPropertyTag(node: Node): node is JSDocPropertyTag {
return node.kind === SyntaxKind.JSDocPropertyTag;
}
// Synthesized list
/* @internal */
export function isSyntaxList(n: Node): n is SyntaxList {
return n.kind === SyntaxKind.SyntaxList;
}
}
@@ -315,7 +315,7 @@ namespace ts {
function parenthesizeExpressionsOfCommaDelimitedList(elements: NodeArray<Expression>): NodeArray<Expression> {
const result = sameMap(elements, parenthesizeExpressionForDisallowedComma);
return setTextRange(createNodeArray(result, elements.hasTrailingComma), elements);
return setTextRange(factory.createNodeArray(result, elements.hasTrailingComma), elements);
}
function parenthesizeExpressionForDisallowedComma(expression: Expression): Expression {
@@ -387,7 +387,7 @@ namespace ts {
}
function parenthesizeConstituentTypesOfUnionOrIntersectionType(members: readonly TypeNode[]): NodeArray<TypeNode> {
return createNodeArray(sameMap(members, parenthesizeMemberOfElementType));
return factory.createNodeArray(sameMap(members, parenthesizeMemberOfElementType));
}
@@ -397,12 +397,12 @@ namespace ts {
function parenthesizeTypeArguments(typeArguments: NodeArray<TypeNode> | undefined): NodeArray<TypeNode> | undefined {
if (some(typeArguments)) {
return createNodeArray(sameMap(typeArguments, parenthesizeOrdinalTypeArgument));
return factory.createNodeArray(sameMap(typeArguments, parenthesizeOrdinalTypeArgument));
}
}
}
const nullParenthesizerRules: ParenthesizerRules = {
export const nullParenthesizerRules: ParenthesizerRules = {
parenthesizeLeftSideOfBinary: (_binaryOperator, leftSide) => leftSide,
parenthesizeRightSideOfBinary: (_binaryOperator, _leftSide, rightSide) => rightSide,
parenthesizeExpressionOfComputedPropertyName: identity,
@@ -413,18 +413,14 @@ namespace ts {
parenthesizeLeftSideOfAccess: expression => cast(expression, isLeftHandSideExpression),
parenthesizeOperandOfPostfixUnary: operand => cast(operand, isLeftHandSideExpression),
parenthesizeOperandOfPrefixUnary: operand => cast(operand, isUnaryExpression),
parenthesizeExpressionsOfCommaDelimitedList: nodes => createNodeArray(nodes),
parenthesizeExpressionsOfCommaDelimitedList: nodes => cast(nodes, isNodeArray),
parenthesizeExpressionForDisallowedComma: identity,
parenthesizeExpressionOfExpressionStatement: identity,
parenthesizeConciseBodyOfArrowFunction: identity,
parenthesizeMemberOfConditionalType: identity,
parenthesizeMemberOfElementType: identity,
parenthesizeElementTypeOfArrayType: identity,
parenthesizeConstituentTypesOfUnionOrIntersectionType: nodes => createNodeArray(nodes),
parenthesizeTypeArguments: nodes => nodes && createNodeArray(nodes),
parenthesizeConstituentTypesOfUnionOrIntersectionType: nodes => cast(nodes, isNodeArray),
parenthesizeTypeArguments: nodes => nodes && cast(nodes, isNodeArray),
};
export function getNullParenthesizerRules(_factory: NodeFactory): ParenthesizerRules {
return nullParenthesizerRules;
}
}
+778
View File
@@ -0,0 +1,778 @@
/* @internal */
namespace ts {
// Compound nodes
export function createMemberAccessForPropertyName(factory: NodeFactory, target: Expression, memberName: PropertyName, location?: TextRange): MemberExpression {
if (isComputedPropertyName(memberName)) {
return setTextRange(factory.createElementAccess(target, memberName.expression), location);
}
else {
const expression = setTextRange(
isIdentifier(memberName)
? factory.createPropertyAccess(target, memberName)
: factory.createElementAccess(target, memberName),
memberName
);
getOrCreateEmitNode(expression).flags |= EmitFlags.NoNestedSourceMaps;
return expression;
}
}
function createReactNamespace(reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment) {
// To ensure the emit resolver can properly resolve the namespace, we need to
// treat this identifier as if it were a source tree node by clearing the `Synthesized`
// flag and setting a parent node.
const react = parseNodeFactory.createIdentifier(reactNamespace || "React");
// Set the parent that is in parse tree
// this makes sure that parent chain is intact for checker to traverse complete scope tree
react.parent = getParseTreeNode(parent)!;
return react;
}
function createJsxFactoryExpressionFromEntityName(factory: NodeFactory, jsxFactory: EntityName, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression {
if (isQualifiedName(jsxFactory)) {
const left = createJsxFactoryExpressionFromEntityName(factory, jsxFactory.left, parent);
const right = factory.createIdentifier(idText(jsxFactory.right));
right.escapedText = jsxFactory.right.escapedText;
return factory.createPropertyAccess(left, right);
}
else {
return createReactNamespace(idText(jsxFactory), parent);
}
}
function createJsxFactoryExpression(factory: NodeFactory, jsxFactoryEntity: EntityName | undefined, reactNamespace: string, parent: JsxOpeningLikeElement | JsxOpeningFragment): Expression {
return jsxFactoryEntity ?
createJsxFactoryExpressionFromEntityName(factory, jsxFactoryEntity, parent) :
factory.createPropertyAccess(
createReactNamespace(reactNamespace, parent),
"createElement"
);
}
export function createExpressionForJsxElement(factory: NodeFactory, jsxFactoryEntity: EntityName | undefined, reactNamespace: string, tagName: Expression, props: Expression | undefined, children: readonly Expression[] | undefined, parentElement: JsxOpeningLikeElement, location: TextRange): LeftHandSideExpression {
const argumentsList = [tagName];
if (props) {
argumentsList.push(props);
}
if (children && children.length > 0) {
if (!props) {
argumentsList.push(factory.createNull());
}
if (children.length > 1) {
for (const child of children) {
startOnNewLine(child);
argumentsList.push(child);
}
}
else {
argumentsList.push(children[0]);
}
}
return setTextRange(
factory.createCall(
createJsxFactoryExpression(factory, jsxFactoryEntity, reactNamespace, parentElement),
/*typeArguments*/ undefined,
argumentsList
),
location
);
}
export function createExpressionForJsxFragment(factory: NodeFactory, jsxFactoryEntity: EntityName | undefined, reactNamespace: string, children: readonly Expression[], parentElement: JsxOpeningFragment, location: TextRange): LeftHandSideExpression {
const tagName = factory.createPropertyAccess(
createReactNamespace(reactNamespace, parentElement),
"Fragment"
);
const argumentsList = [<Expression>tagName];
argumentsList.push(factory.createNull());
if (children && children.length > 0) {
if (children.length > 1) {
for (const child of children) {
startOnNewLine(child);
argumentsList.push(child);
}
}
else {
argumentsList.push(children[0]);
}
}
return setTextRange(
factory.createCall(
createJsxFactoryExpression(factory, jsxFactoryEntity, reactNamespace, parentElement),
/*typeArguments*/ undefined,
argumentsList
),
location
);
}
// Utilities
export function createForOfBindingStatement(factory: NodeFactory, node: ForInitializer, boundValue: Expression): Statement {
if (isVariableDeclarationList(node)) {
const firstDeclaration = first(node.declarations);
const updatedDeclaration = factory.updateVariableDeclaration(
firstDeclaration,
firstDeclaration.name,
/*typeNode*/ undefined,
boundValue
);
return setTextRange(
factory.createVariableStatement(
/*modifiers*/ undefined,
factory.updateVariableDeclarationList(node, [updatedDeclaration])
),
/*location*/ node
);
}
else {
const updatedExpression = setTextRange(factory.createAssignment(node, boundValue), /*location*/ node);
return setTextRange(factory.createExpressionStatement(updatedExpression), /*location*/ node);
}
}
export function insertLeadingStatement(factory: NodeFactory, dest: Statement, source: Statement) {
if (isBlock(dest)) {
return factory.updateBlock(dest, setTextRange(factory.createNodeArray([source, ...dest.statements]), dest.statements));
}
else {
return factory.createBlock(factory.createNodeArray([dest, source]), /*multiLine*/ true);
}
}
export function createExpressionFromEntityName(factory: NodeFactory, node: EntityName | Expression): Expression {
if (isQualifiedName(node)) {
const left = createExpressionFromEntityName(factory, node.left);
const right = getMutableClone(node.right);
return setTextRange(factory.createPropertyAccess(left, right), node);
}
else {
return getMutableClone(node);
}
}
export function createExpressionForPropertyName(factory: NodeFactory, memberName: PropertyName): Expression {
if (isIdentifier(memberName)) {
return factory.createStringLiteralFromNode(memberName);
}
else if (isComputedPropertyName(memberName)) {
return getMutableClone(memberName.expression);
}
else {
return getMutableClone(memberName);
}
}
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
),
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
),
setAccessor
)
}, !multiLine)
),
firstAccessor
)
);
}
return undefined;
}
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
),
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
),
/*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
),
/*original*/ method
)
),
/*location*/ method
),
/*original*/ method
)
);
}
export function createExpressionForObjectLiteralElementLike(factory: NodeFactory, node: ObjectLiteralExpression, property: ObjectLiteralElementLike, receiver: Expression): Expression | undefined {
switch (property.kind) {
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
return createExpressionForAccessorDeclaration(factory, node.properties, property, receiver, !!node.multiLine);
case SyntaxKind.PropertyAssignment:
return createExpressionForPropertyAssignment(factory, property, receiver);
case SyntaxKind.ShorthandPropertyAssignment:
return createExpressionForShorthandPropertyAssignment(factory, property, receiver);
case SyntaxKind.MethodDeclaration:
return createExpressionForMethodDeclaration(factory, property, receiver);
}
}
/**
* Gets whether an identifier should only be referred to by its internal name.
*/
export function isInternalName(node: Identifier) {
return (getEmitFlags(node) & EmitFlags.InternalName) !== 0;
}
/**
* Gets whether an identifier should only be referred to by its local name.
*/
export function isLocalName(node: Identifier) {
return (getEmitFlags(node) & EmitFlags.LocalName) !== 0;
}
/**
* Gets whether an identifier should only be referred to by its export representation if the
* name points to an exported symbol.
*/
export function isExportName(node: Identifier) {
return (getEmitFlags(node) & EmitFlags.ExportName) !== 0;
}
function isUseStrictPrologue(node: ExpressionStatement): boolean {
return isStringLiteral(node.expression) && node.expression.text === "use strict";
}
export function findUseStrictPrologue(statements: readonly Statement[]): Statement | undefined {
for (const statement of statements) {
if (isPrologueDirective(statement)) {
if (isUseStrictPrologue(statement)) {
return statement;
}
}
else {
break;
}
}
return undefined;
}
export function startsWithUseStrict(statements: readonly Statement[]) {
const firstStatement = firstOrUndefined(statements);
return firstStatement !== undefined
&& isPrologueDirective(firstStatement)
&& isUseStrictPrologue(firstStatement);
}
export function isCommaSequence(node: Expression): node is BinaryExpression & {operatorToken: Token<SyntaxKind.CommaToken>} | CommaListExpression {
return node.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>node).operatorToken.kind === SyntaxKind.CommaToken ||
node.kind === SyntaxKind.CommaListExpression;
}
export type OuterExpression = ParenthesizedExpression | TypeAssertion | AsExpression | NonNullExpression | PartiallyEmittedExpression;
export function isOuterExpression(node: Node, kinds = OuterExpressionKinds.All): node is OuterExpression {
switch (node.kind) {
case SyntaxKind.ParenthesizedExpression:
return (kinds & OuterExpressionKinds.Parentheses) !== 0;
case SyntaxKind.TypeAssertionExpression:
case SyntaxKind.AsExpression:
case SyntaxKind.NonNullExpression:
return (kinds & OuterExpressionKinds.Assertions) !== 0;
case SyntaxKind.PartiallyEmittedExpression:
return (kinds & OuterExpressionKinds.PartiallyEmittedExpressions) !== 0;
}
return false;
}
export function skipOuterExpressions(node: Expression, kinds?: OuterExpressionKinds): Expression;
export function skipOuterExpressions(node: Node, kinds?: OuterExpressionKinds): Node;
export function skipOuterExpressions(node: Node, kinds = OuterExpressionKinds.All) {
let previousNode: Node;
do {
previousNode = node;
if (kinds & OuterExpressionKinds.Parentheses) {
node = skipParentheses(node);
}
if (kinds & OuterExpressionKinds.Assertions) {
node = skipAssertions(node);
}
if (kinds & OuterExpressionKinds.PartiallyEmittedExpressions) {
node = skipPartiallyEmittedExpressions(node);
}
}
while (previousNode !== node);
return node;
}
export function skipAssertions(node: Expression): Expression;
export function skipAssertions(node: Node): Node;
export function skipAssertions(node: Node): Node {
while (isAssertionExpression(node) || node.kind === SyntaxKind.NonNullExpression) {
node = (<AssertionExpression | NonNullExpression>node).expression;
}
return node;
}
export function startOnNewLine<T extends Node>(node: T): T {
return setStartsOnNewLine(node, /*newLine*/ true);
}
export function getExternalHelpersModuleName(node: SourceFile) {
const parseNode = getOriginalNode(node, isSourceFile);
const emitNode = parseNode && parseNode.emitNode;
return emitNode && emitNode.externalHelpersModuleName;
}
export function hasRecordedExternalHelpers(sourceFile: SourceFile) {
const parseNode = getOriginalNode(sourceFile, isSourceFile);
const emitNode = parseNode && parseNode.emitNode;
return !!emitNode && (!!emitNode.externalHelpersModuleName || !!emitNode.externalHelpers);
}
export function createExternalHelpersImportDeclarationIfNeeded(nodeFactory: NodeFactory, helperFactory: EmitHelperFactory, sourceFile: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStar?: boolean, hasImportDefault?: boolean) {
if (compilerOptions.importHelpers && isEffectiveExternalModule(sourceFile, compilerOptions)) {
let namedBindings: NamedImportBindings | undefined;
const moduleKind = getEmitModuleKind(compilerOptions);
if (moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext) {
// use named imports
const helpers = getEmitHelpers(sourceFile);
if (helpers) {
const helperNames: string[] = [];
for (const helper of helpers) {
if (!helper.scoped) {
const importName = (helper as UnscopedEmitHelper).importName;
if (importName) {
pushIfUnique(helperNames, importName);
}
}
}
if (some(helperNames)) {
helperNames.sort(compareStringsCaseSensitive);
// Alias the imports if the names are used somewhere in the file.
// NOTE: We don't need to care about global import collisions as this is a module.
namedBindings = nodeFactory.createNamedImports(
map(helperNames, name => isFileLevelUniqueName(sourceFile, name)
? nodeFactory.createImportSpecifier(/*propertyName*/ undefined, nodeFactory.createIdentifier(name))
: nodeFactory.createImportSpecifier(nodeFactory.createIdentifier(name), helperFactory.getUnscopedHelperName(name))
)
);
const parseNode = getOriginalNode(sourceFile, isSourceFile);
const emitNode = getOrCreateEmitNode(parseNode);
emitNode.externalHelpers = true;
}
}
}
else {
// use a namespace import
const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(nodeFactory, sourceFile, compilerOptions, hasExportStarsToExportValues, hasImportStar || hasImportDefault);
if (externalHelpersModuleName) {
namedBindings = nodeFactory.createNamespaceImport(externalHelpersModuleName);
}
}
if (namedBindings) {
const externalHelpersImportDeclaration = nodeFactory.createImportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
nodeFactory.createImportClause(/*name*/ undefined, namedBindings),
nodeFactory.createStringLiteral(externalHelpersModuleNameText)
);
addEmitFlags(externalHelpersImportDeclaration, EmitFlags.NeverApplyImportHelper);
return externalHelpersImportDeclaration;
}
}
}
export function getOrCreateExternalHelpersModuleNameIfNeeded(factory: NodeFactory, node: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStarOrImportDefault?: boolean) {
if (compilerOptions.importHelpers && isEffectiveExternalModule(node, compilerOptions)) {
const externalHelpersModuleName = getExternalHelpersModuleName(node);
if (externalHelpersModuleName) {
return externalHelpersModuleName;
}
const moduleKind = getEmitModuleKind(compilerOptions);
let create = (hasExportStarsToExportValues || (compilerOptions.esModuleInterop && hasImportStarOrImportDefault))
&& moduleKind !== ModuleKind.System
&& moduleKind !== ModuleKind.ES2015
&& moduleKind !== ModuleKind.ESNext;
if (!create) {
const helpers = getEmitHelpers(node);
if (helpers) {
for (const helper of helpers) {
if (!helper.scoped) {
create = true;
break;
}
}
}
}
if (create) {
const parseNode = getOriginalNode(node, isSourceFile);
const emitNode = getOrCreateEmitNode(parseNode);
return emitNode.externalHelpersModuleName || (emitNode.externalHelpersModuleName = factory.createUniqueName(externalHelpersModuleNameText));
}
}
}
/**
* Get the name of that target module from an import or export declaration
*/
export function getLocalNameForExternalImport(factory: NodeFactory, node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration, sourceFile: SourceFile): Identifier | undefined {
const namespaceDeclaration = getNamespaceDeclarationNode(node);
if (namespaceDeclaration && !isDefaultImport(node)) {
const name = namespaceDeclaration.name;
return isGeneratedIdentifier(name) ? name : factory.createIdentifier(getSourceTextOfNodeFromSourceFile(sourceFile, name) || idText(name));
}
if (node.kind === SyntaxKind.ImportDeclaration && node.importClause) {
return factory.getGeneratedNameForNode(node);
}
if (node.kind === SyntaxKind.ExportDeclaration && node.moduleSpecifier) {
return factory.getGeneratedNameForNode(node);
}
return undefined;
}
/**
* Get the name of a target module from an import/export declaration as should be written in the emitted output.
* The emitted output name can be different from the input if:
* 1. The module has a /// <amd-module name="<new name>" />
* 2. --out or --outFile is used, making the name relative to the rootDir
* 3- The containing SourceFile has an entry in renamedDependencies for the import as requested by some module loaders (e.g. System).
* Otherwise, a new StringLiteral node representing the module name will be returned.
*/
export function getExternalModuleNameLiteral(factory: NodeFactory, importNode: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration, sourceFile: SourceFile, host: EmitHost, resolver: EmitResolver, compilerOptions: CompilerOptions) {
const moduleName = getExternalModuleName(importNode)!; // TODO: GH#18217
if (moduleName.kind === SyntaxKind.StringLiteral) {
return tryGetModuleNameFromDeclaration(importNode, host, factory, resolver, compilerOptions)
|| tryRenameExternalModule(factory, <StringLiteral>moduleName, sourceFile)
|| getSynthesizedClone(<StringLiteral>moduleName);
}
return undefined;
}
/**
* Some bundlers (SystemJS builder) sometimes want to rename dependencies.
* Here we check if alternative name was provided for a given moduleName and return it if possible.
*/
function tryRenameExternalModule(factory: NodeFactory, moduleName: LiteralExpression, sourceFile: SourceFile) {
const rename = sourceFile.renamedDependencies && sourceFile.renamedDependencies.get(moduleName.text);
return rename && factory.createStringLiteral(rename);
}
/**
* Get the name of a module as should be written in the emitted output.
* The emitted output name can be different from the input if:
* 1. The module has a /// <amd-module name="<new name>" />
* 2. --out or --outFile is used, making the name relative to the rootDir
* Otherwise, a new StringLiteral node representing the module name will be returned.
*/
export function tryGetModuleNameFromFile(factory: NodeFactory, file: SourceFile | undefined, host: EmitHost, options: CompilerOptions): StringLiteral | undefined {
if (!file) {
return undefined;
}
if (file.moduleName) {
return factory.createStringLiteral(file.moduleName);
}
if (!file.isDeclarationFile && (options.out || options.outFile)) {
return factory.createStringLiteral(getExternalModuleNameFromPath(host, file.fileName));
}
return undefined;
}
function tryGetModuleNameFromDeclaration(declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration, host: EmitHost, factory: NodeFactory, resolver: EmitResolver, compilerOptions: CompilerOptions) {
return tryGetModuleNameFromFile(factory, resolver.getExternalModuleFileFromDeclaration(declaration), host, compilerOptions);
}
/**
* Gets the initializer of an BindingOrAssignmentElement.
*/
export function getInitializerOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): Expression | undefined {
if (isDeclarationBindingElement(bindingElement)) {
// `1` in `let { a = 1 } = ...`
// `1` in `let { a: b = 1 } = ...`
// `1` in `let { a: {b} = 1 } = ...`
// `1` in `let { a: [b] = 1 } = ...`
// `1` in `let [a = 1] = ...`
// `1` in `let [{a} = 1] = ...`
// `1` in `let [[a] = 1] = ...`
return bindingElement.initializer;
}
if (isPropertyAssignment(bindingElement)) {
// `1` in `({ a: b = 1 } = ...)`
// `1` in `({ a: {b} = 1 } = ...)`
// `1` in `({ a: [b] = 1 } = ...)`
const initializer = bindingElement.initializer;
return isAssignmentExpression(initializer, /*excludeCompoundAssignment*/ true)
? initializer.right
: undefined;
}
if (isShorthandPropertyAssignment(bindingElement)) {
// `1` in `({ a = 1 } = ...)`
return bindingElement.objectAssignmentInitializer;
}
if (isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) {
// `1` in `[a = 1] = ...`
// `1` in `[{a} = 1] = ...`
// `1` in `[[a] = 1] = ...`
return bindingElement.right;
}
if (isSpreadElement(bindingElement)) {
// Recovery consistent with existing emit.
return getInitializerOfBindingOrAssignmentElement(<BindingOrAssignmentElement>bindingElement.expression);
}
}
/**
* Gets the name of an BindingOrAssignmentElement.
*/
export function getTargetOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): BindingOrAssignmentElementTarget | undefined {
if (isDeclarationBindingElement(bindingElement)) {
// `a` in `let { a } = ...`
// `a` in `let { a = 1 } = ...`
// `b` in `let { a: b } = ...`
// `b` in `let { a: b = 1 } = ...`
// `a` in `let { ...a } = ...`
// `{b}` in `let { a: {b} } = ...`
// `{b}` in `let { a: {b} = 1 } = ...`
// `[b]` in `let { a: [b] } = ...`
// `[b]` in `let { a: [b] = 1 } = ...`
// `a` in `let [a] = ...`
// `a` in `let [a = 1] = ...`
// `a` in `let [...a] = ...`
// `{a}` in `let [{a}] = ...`
// `{a}` in `let [{a} = 1] = ...`
// `[a]` in `let [[a]] = ...`
// `[a]` in `let [[a] = 1] = ...`
return bindingElement.name;
}
if (isObjectLiteralElementLike(bindingElement)) {
switch (bindingElement.kind) {
case SyntaxKind.PropertyAssignment:
// `b` in `({ a: b } = ...)`
// `b` in `({ a: b = 1 } = ...)`
// `{b}` in `({ a: {b} } = ...)`
// `{b}` in `({ a: {b} = 1 } = ...)`
// `[b]` in `({ a: [b] } = ...)`
// `[b]` in `({ a: [b] = 1 } = ...)`
// `b.c` in `({ a: b.c } = ...)`
// `b.c` in `({ a: b.c = 1 } = ...)`
// `b[0]` in `({ a: b[0] } = ...)`
// `b[0]` in `({ a: b[0] = 1 } = ...)`
return getTargetOfBindingOrAssignmentElement(<BindingOrAssignmentElement>bindingElement.initializer);
case SyntaxKind.ShorthandPropertyAssignment:
// `a` in `({ a } = ...)`
// `a` in `({ a = 1 } = ...)`
return bindingElement.name;
case SyntaxKind.SpreadAssignment:
// `a` in `({ ...a } = ...)`
return getTargetOfBindingOrAssignmentElement(<BindingOrAssignmentElement>bindingElement.expression);
}
// no target
return undefined;
}
if (isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) {
// `a` in `[a = 1] = ...`
// `{a}` in `[{a} = 1] = ...`
// `[a]` in `[[a] = 1] = ...`
// `a.b` in `[a.b = 1] = ...`
// `a[0]` in `[a[0] = 1] = ...`
return getTargetOfBindingOrAssignmentElement(<BindingOrAssignmentElement>bindingElement.left);
}
if (isSpreadElement(bindingElement)) {
// `a` in `[...a] = ...`
return getTargetOfBindingOrAssignmentElement(<BindingOrAssignmentElement>bindingElement.expression);
}
// `a` in `[a] = ...`
// `{a}` in `[{a}] = ...`
// `[a]` in `[[a]] = ...`
// `a.b` in `[a.b] = ...`
// `a[0]` in `[a[0]] = ...`
return bindingElement;
}
/**
* Determines whether an BindingOrAssignmentElement is a rest element.
*/
export function getRestIndicatorOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): BindingOrAssignmentElementRestIndicator | undefined {
switch (bindingElement.kind) {
case SyntaxKind.Parameter:
case SyntaxKind.BindingElement:
// `...` in `let [...a] = ...`
return bindingElement.dotDotDotToken;
case SyntaxKind.SpreadElement:
case SyntaxKind.SpreadAssignment:
// `...` in `[...a] = ...`
return bindingElement;
}
return undefined;
}
/**
* Gets the property name of a BindingOrAssignmentElement
*/
export function getPropertyNameOfBindingOrAssignmentElement(bindingElement: BindingOrAssignmentElement): PropertyName | undefined {
switch (bindingElement.kind) {
case SyntaxKind.BindingElement:
// `a` in `let { a: b } = ...`
// `[a]` in `let { [a]: b } = ...`
// `"a"` in `let { "a": b } = ...`
// `1` in `let { 1: b } = ...`
if (bindingElement.propertyName) {
const propertyName = bindingElement.propertyName;
return isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression)
? propertyName.expression
: propertyName;
}
break;
case SyntaxKind.PropertyAssignment:
// `a` in `({ a: b } = ...)`
// `[a]` in `({ [a]: b } = ...)`
// `"a"` in `({ "a": b } = ...)`
// `1` in `({ 1: b } = ...)`
if (bindingElement.name) {
const propertyName = bindingElement.name;
return isComputedPropertyName(propertyName) && isStringOrNumericLiteral(propertyName.expression)
? propertyName.expression
: propertyName;
}
break;
case SyntaxKind.SpreadAssignment:
// `a` in `({ ...a } = ...)`
return bindingElement.name;
}
const target = getTargetOfBindingOrAssignmentElement(bindingElement);
if (target && isPropertyName(target)) {
return isComputedPropertyName(target) && isStringOrNumericLiteral(target.expression)
? target.expression
: target;
}
Debug.fail("Invalid property name for binding element.");
}
function isStringOrNumericLiteral(node: Node): node is StringLiteral | NumericLiteral {
const kind = node.kind;
return kind === SyntaxKind.StringLiteral
|| kind === SyntaxKind.NumericLiteral;
}
/**
* Gets the elements of a BindingOrAssignmentPattern
*/
export function getElementsOfBindingOrAssignmentPattern(name: BindingOrAssignmentPattern): readonly BindingOrAssignmentElement[] {
switch (name.kind) {
case SyntaxKind.ObjectBindingPattern:
case SyntaxKind.ArrayBindingPattern:
case SyntaxKind.ArrayLiteralExpression:
// `a` in `{a}`
// `a` in `[a]`
return <readonly BindingOrAssignmentElement[]>name.elements;
case SyntaxKind.ObjectLiteralExpression:
// `a` in `{a}`
return <readonly BindingOrAssignmentElement[]>name.properties;
}
}
}
+97 -64
View File
@@ -31,7 +31,12 @@ namespace ts {
}
/* @internal */
export const parseNodeFactory = createNodeFactory(createNode, createParenthesizerRules, createNodeConverters, nullTreeStateObserver);
export const parseNodeFactory = createNodeFactory(NodeFactoryFlags.None, {
createBaseSourceFileNode: createNode,
createBaseIdentifierNode: createNode,
createBaseTokenNode: createNode,
createBaseNode: createNode
});
function visitNode<T>(cbNode: (node: Node) => T, node: Node | undefined): T | undefined {
return node && cbNode(node);
@@ -590,7 +595,16 @@ namespace ts {
// Share a single scanner across all calls to parse a source file. This helps speed things
// up by avoiding the cost of creating/compiling scanners over and over again.
const scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true);
const factory = createNodeFactory(createNode, getNullParenthesizerRules, getNullNodeConverters, nullTreeStateObserver);
const factory = createNodeFactory(NodeFactoryFlags.NoParenthesizerRules | NodeFactoryFlags.NoNodeConverters, {
createBaseSourceFileNode: kind => new SourceFileConstructor(kind, /*pos*/ 0, /*end*/ 0),
createBaseIdentifierNode: kind => new IdentifierConstructor(kind, /*pos*/ 0, /*end*/ 0),
createBaseTokenNode: kind => new TokenConstructor(kind, /*pos*/ 0, /*end*/ 0),
createBaseNode: kind => new NodeConstructor(kind, /*pos*/ 0, /*end*/ 0)
}, {
onCreateNode: _node => nodeCount++
});
const disallowInAndDecoratorContext = NodeFlags.DisallowInContext | NodeFlags.DecoratorContext;
// capture constructors in 'initializeState' to avoid null checks
@@ -601,12 +615,16 @@ namespace ts {
let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node;
// tslint:enable variable-name
let sourceFile: SourceFile;
let parseDiagnostics: DiagnosticWithLocation[];
let sourceFlags: NodeFlags;
let sourceText: string;
let languageVersion: ScriptTarget;
let scriptKind: ScriptKind;
let languageVariant: LanguageVariant;
let parseDiagnostics: DiagnosticWithDetachedLocation[];
let jsDocDiagnostics: DiagnosticWithDetachedLocation[];
let syntaxCursor: IncrementalParser.SyntaxCursor | undefined;
let currentToken: SyntaxKind;
let sourceText: string;
let nodeCount: number;
let identifiers: Map<string>;
let identifierCount: number;
@@ -728,17 +746,15 @@ namespace ts {
export function parseJsonText(fileName: string, sourceText: string, languageVersion: ScriptTarget = ScriptTarget.ES2015, syntaxCursor?: IncrementalParser.SyntaxCursor, setParentNodes?: boolean): JsonSourceFile {
initializeState(sourceText, languageVersion, syntaxCursor, ScriptKind.JSON);
// Set source file so that errors will be reported with this file name
sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON, /*isDeclaration*/ false);
sourceFile.flags = contextFlags;
sourceFlags = contextFlags;
// Prime the scanner.
nextToken();
const pos = getNodePos();
let statements, endOfFileToken;
if (token() === SyntaxKind.EndOfFileToken) {
// TODO(rbuckton): this does not create the tree correctly and transform flags won't be properly set
sourceFile.statements = createNodeArray([], pos, pos);
sourceFile.endOfFileToken = parseTokenNode<EndOfFileToken>();
statements = createNodeArray([], pos, pos);
endOfFileToken = parseTokenNode<EndOfFileToken>();
}
else {
let expression;
@@ -774,34 +790,46 @@ namespace ts {
// TODO(rbuckton): this does not create the tree correctly and transform flags won't be properly set
const statement = factory.createExpressionStatement(expression) as JsonObjectExpressionStatement;
finishNode(statement, pos);
sourceFile.statements = createNodeArray([statement], pos);
sourceFile.endOfFileToken = parseExpectedToken(SyntaxKind.EndOfFileToken, Diagnostics.Unexpected_token);
statements = createNodeArray([statement], pos);
endOfFileToken = parseExpectedToken(SyntaxKind.EndOfFileToken, Diagnostics.Unexpected_token);
}
// Set source file so that errors will be reported with this file name
const sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON, /*isDeclaration*/ false, statements, endOfFileToken);
sourceFile.flags |= sourceFlags;
if (setParentNodes) {
fixupParentReferences(sourceFile);
}
sourceFile.parseDiagnostics = parseDiagnostics;
sourceFile.parseDiagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile);
if (jsDocDiagnostics) {
sourceFile.jsDocDiagnostics = attachFileToDiagnostics(jsDocDiagnostics, sourceFile);
}
const result = sourceFile as JsonSourceFile;
clearState();
return result;
}
function initializeState(_sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor | undefined, scriptKind: ScriptKind) {
function initializeState(_sourceText: string, _languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor | undefined, _scriptKind: ScriptKind) {
NodeConstructor = objectAllocator.getNodeConstructor();
TokenConstructor = objectAllocator.getTokenConstructor();
IdentifierConstructor = objectAllocator.getIdentifierConstructor();
SourceFileConstructor = objectAllocator.getSourceFileConstructor();
sourceText = _sourceText;
languageVersion = _languageVersion;
syntaxCursor = _syntaxCursor;
scriptKind = _scriptKind;
languageVariant = getLanguageVariant(_scriptKind);
parseDiagnostics = [];
parsingContext = 0;
identifiers = createMap<string>();
identifierCount = 0;
nodeCount = 0;
sourceFlags = 0;
switch (scriptKind) {
case ScriptKind.JS:
@@ -821,7 +849,7 @@ namespace ts {
scanner.setText(sourceText);
scanner.setOnError(scanError);
scanner.setScriptTarget(languageVersion);
scanner.setLanguageVariant(getLanguageVariant(scriptKind));
scanner.setLanguageVariant(languageVariant);
}
function clearState() {
@@ -830,11 +858,16 @@ namespace ts {
scanner.setOnError(undefined);
// Clear any data. We don't want to accidentally hold onto it for too long.
parseDiagnostics = undefined!;
sourceFile = undefined!;
identifiers = undefined!;
syntaxCursor = undefined;
sourceText = undefined!;
languageVersion = undefined!;
syntaxCursor = undefined;
scriptKind = undefined!;
languageVariant = undefined!;
sourceFlags = 0;
parseDiagnostics = undefined!;
jsDocDiagnostics = undefined!;
parsingContext = 0;
identifiers = undefined!;
notParenthesizedArrow = undefined!;
}
@@ -844,27 +877,31 @@ namespace ts {
contextFlags |= NodeFlags.Ambient;
}
sourceFile = createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile);
sourceFile.flags = contextFlags;
sourceFlags = contextFlags;
// Prime the scanner.
nextToken();
const statements = parseList(ParsingContext.SourceElements, parseStatement);
Debug.assert(token() === SyntaxKind.EndOfFileToken);
const endOfFileToken = addJSDocComment(parseTokenNode<EndOfFileToken>());
const sourceFile = createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile, statements, endOfFileToken);
sourceFile.flags |= sourceFlags;
// A member of ReadonlyArray<T> isn't assignable to a member of T[] (and prevents a direct cast) - but this is where we set up those members so they can be readonly in the future
processCommentPragmas(sourceFile as {} as PragmaContext, sourceText);
processPragmasIntoFields(sourceFile as {} as PragmaContext, reportPragmaDiagnostic);
// TODO(rbuckton): this does not create the tree correctly and transform flags won't be properly set
sourceFile.statements = parseList(ParsingContext.SourceElements, parseStatement);
Debug.assert(token() === SyntaxKind.EndOfFileToken);
sourceFile.endOfFileToken = addJSDocComment(parseTokenNode());
setExternalModuleIndicator(sourceFile);
sourceFile.nodeCount = nodeCount;
sourceFile.identifierCount = identifierCount;
sourceFile.identifiers = identifiers;
sourceFile.parseDiagnostics = parseDiagnostics;
sourceFile.parseDiagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile);
if (jsDocDiagnostics) {
sourceFile.jsDocDiagnostics = attachFileToDiagnostics(jsDocDiagnostics, sourceFile);
}
setExternalModuleIndicator(sourceFile);
if (setParentNodes) {
fixupParentReferences(sourceFile);
}
@@ -872,7 +909,7 @@ namespace ts {
return sourceFile;
function reportPragmaDiagnostic(pos: number, end: number, diagnostic: DiagnosticMessage) {
parseDiagnostics.push(createFileDiagnostic(sourceFile, pos, end, diagnostic));
parseDiagnostics.push(createDetachedDiagnostic(pos, end, diagnostic));
}
}
@@ -882,7 +919,7 @@ namespace ts {
function addJSDocComment<T extends HasJSDoc>(node: T): T {
Debug.assert(!node.jsDoc); // Should only be called once per node
const jsDoc = mapDefined(getJSDocCommentRanges(node, sourceFile.text), comment => JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos));
const jsDoc = mapDefined(getJSDocCommentRanges(node, sourceText), comment => JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos));
if (jsDoc.length) node.jsDoc = jsDoc;
return node;
}
@@ -919,12 +956,12 @@ namespace ts {
}
}
function createSourceFile(fileName: string, languageVersion: ScriptTarget, scriptKind: ScriptKind, isDeclarationFile: boolean): SourceFile {
function createSourceFile(fileName: string, languageVersion: ScriptTarget, scriptKind: ScriptKind, isDeclarationFile: boolean, statements: readonly Statement[], endOfFileToken: EndOfFileToken): SourceFile {
// code from createNode is inlined here so createNode won't have to deal with special case of creating source files
// this is quite rare comparing to other nodes and createNode should be as fast as possible
const sourceFile = <SourceFile>new SourceFileConstructor(SyntaxKind.SourceFile, /*pos*/ 0, /* end */ sourceText.length);
nodeCount++;
const sourceFile = factory.createSourceFile(statements, endOfFileToken);
sourceFile.pos = 0;
sourceFile.end = sourceText.length;
sourceFile.text = sourceText;
sourceFile.bindDiagnostics = [];
sourceFile.bindSuggestionDiagnostics = undefined;
@@ -1060,7 +1097,7 @@ namespace ts {
// Don't report another error if it would just be at the same position as the last error.
const lastError = lastOrUndefined(parseDiagnostics);
if (!lastError || start !== lastError.start) {
parseDiagnostics.push(createFileDiagnostic(sourceFile, start, length, message, arg0));
parseDiagnostics.push(createDetachedDiagnostic(start, length, message, arg0));
}
// Mark that we've encountered an error. We'll set an appropriate bit on the next
@@ -1320,19 +1357,8 @@ namespace ts {
}
}
function createNode(kind: SyntaxKind): Node {
nodeCount++;
return isNodeKind(kind) || kind === SyntaxKind.Unknown ? new NodeConstructor(kind, 0, 0) :
kind === SyntaxKind.Identifier ? new IdentifierConstructor(kind, 0, 0) :
new TokenConstructor(kind, 0, 0);
}
function createNodeArray<T extends Node>(elements: T[], pos: number, end?: number): NodeArray<T> {
// Since the element list of a node array is typically created by starting with an empty array and
// repeatedly calling push(), the list may not have the optimal memory layout. We invoke slice() for
// small arrays (1 to 4 elements) to give the VM a chance to allocate an optimal representation.
const length = elements.length;
const array = <MutableNodeArray<T>>(length >= 1 && length <= 4 ? elements.slice() : elements);
const array = factory.createNodeArray(elements, /*hasTrailingComma*/ undefined);
array.pos = pos;
array.end = end === undefined ? scanner.getStartPos() : end;
return array;
@@ -2335,6 +2361,7 @@ namespace ts {
// We also do not need to check for negatives because any prefix operator would be part of a
// parent unary expression.
kind === SyntaxKind.NumericLiteral ? factory.createNumericLiteral(scanner.getTokenValue(), scanner.getNumericLiteralFlags()) :
kind === SyntaxKind.StringLiteral ? factory.createStringLiteral(scanner.getTokenValue(), /*isSingleQuote*/ undefined, scanner.hasExtendedUnicodeEscape()) :
isLiteralKind(kind) ? factory.createLiteralLikeNode(kind, scanner.getTokenValue()) :
Debug.fail();
@@ -2940,9 +2967,9 @@ namespace ts {
function parseMappedType() {
const pos = getNodePos();
parseExpected(SyntaxKind.OpenBraceToken);
let readonlyToken: ReadonlyToken | PlusToken | MinusToken | undefined;
let readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined;
if (token() === SyntaxKind.ReadonlyKeyword || token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) {
readonlyToken = parseTokenNode<ReadonlyToken | PlusToken | MinusToken>();
readonlyToken = parseTokenNode<ReadonlyKeyword | PlusToken | MinusToken>();
if (readonlyToken.kind !== SyntaxKind.ReadonlyKeyword) {
parseExpected(SyntaxKind.ReadonlyKeyword);
}
@@ -3033,7 +3060,7 @@ namespace ts {
}
function parseImportType(): ImportTypeNode {
sourceFile.flags |= NodeFlags.PossiblyContainsDynamicImport;
sourceFlags |= NodeFlags.PossiblyContainsDynamicImport;
const pos = getNodePos();
const isTypeOf = parseOptional(SyntaxKind.TypeOfKeyword);
parseExpected(SyntaxKind.ImportKeyword);
@@ -3762,7 +3789,7 @@ namespace ts {
}
// JSX overrides
if (sourceFile.languageVariant === LanguageVariant.JSX) {
if (languageVariant === LanguageVariant.JSX) {
const isArrowFunctionInJsx = lookAhead(() => {
const third = nextToken();
if (third === SyntaxKind.ExtendsKeyword) {
@@ -4182,7 +4209,7 @@ namespace ts {
return false;
case SyntaxKind.LessThanToken:
// If we are not in JSX context, we are parsing TypeAssertion which is an UnaryExpression
if (sourceFile.languageVariant !== LanguageVariant.JSX) {
if (languageVariant !== LanguageVariant.JSX) {
return false;
}
// We are in JSX context and the token is part of JSXElement.
@@ -4208,7 +4235,7 @@ namespace ts {
const pos = getNodePos();
return finishNode(factory.createPrefix(<PrefixUnaryOperator>token(), nextTokenAnd(parseLeftHandSideExpressionOrHigher)), pos);
}
else if (sourceFile.languageVariant === LanguageVariant.JSX && token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsIdentifierOrKeywordOrGreaterThan)) {
else if (languageVariant === LanguageVariant.JSX && token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsIdentifierOrKeywordOrGreaterThan)) {
// JSXElement is part of primaryExpression
return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true);
}
@@ -4266,7 +4293,7 @@ namespace ts {
// var foo3 = require("subfolder
// import * as foo1 from "module-from-node
// We want this import to be a statement rather than import call expression
sourceFile.flags |= NodeFlags.PossiblyContainsDynamicImport;
sourceFlags |= NodeFlags.PossiblyContainsDynamicImport;
expression = parseTokenNode<PrimaryExpression>();
}
else if (lookAhead(nextTokenIsDot)) {
@@ -4274,7 +4301,7 @@ namespace ts {
nextToken(); // advance past the 'import'
nextToken(); // advance past the dot
expression = finishNode(factory.createMetaProperty(SyntaxKind.ImportKeyword, parseIdentifierName()), pos);
sourceFile.flags |= NodeFlags.PossiblyContainsImportMeta;
sourceFlags |= NodeFlags.PossiblyContainsImportMeta;
}
else {
expression = parseMemberExpressionOrHigher();
@@ -6522,11 +6549,16 @@ 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);
sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS, /*isDeclarationFile*/ false);
scanner.setText(content, start, length);
currentToken = scanner.scan();
const jsDocTypeExpression = parseJSDocTypeExpression();
const diagnostics = parseDiagnostics;
const sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS, /*isDeclarationFile*/ false, [], factory.createToken(SyntaxKind.EndOfFileToken));
const diagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile);
if (jsDocDiagnostics) {
sourceFile.jsDocDiagnostics = attachFileToDiagnostics(jsDocDiagnostics, sourceFile);
}
clearState();
return jsDocTypeExpression ? { jsDocTypeExpression, diagnostics } : undefined;
@@ -6549,9 +6581,10 @@ namespace ts {
export function parseIsolatedJSDocComment(content: string, start: number | undefined, length: number | undefined): { jsDoc: JSDoc, diagnostics: Diagnostic[] } | undefined {
initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
sourceFile = <SourceFile>{ languageVariant: LanguageVariant.Standard, text: content }; // tslint:disable-line no-object-literal-type-assertion
const jsDoc = doInsideOfContext(NodeFlags.JSDoc, () => parseJSDocCommentWorker(start, length));
const diagnostics = parseDiagnostics;
const sourceFile = <SourceFile>{ languageVariant: LanguageVariant.Standard, text: content }; // tslint:disable-line no-object-literal-type-assertion
const diagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile);
clearState();
return jsDoc ? { jsDoc, diagnostics } : undefined;
@@ -6568,10 +6601,10 @@ namespace ts {
}
if (contextFlags & NodeFlags.JavaScriptFile) {
if (!sourceFile.jsDocDiagnostics) {
sourceFile.jsDocDiagnostics = [];
if (!jsDocDiagnostics) {
jsDocDiagnostics = [];
}
sourceFile.jsDocDiagnostics.push(...parseDiagnostics);
jsDocDiagnostics.push(...parseDiagnostics);
}
currentToken = saveToken;
parseDiagnostics.length = saveParseDiagnosticsLength;
+31 -7
View File
@@ -3382,13 +3382,13 @@ namespace ts {
}
}
function createPreprocessedNode(kind: SyntaxKind) {
const node = createNode(kind, -1, -1);
node.flags |= NodeFlags.Preprocessed;
return node;
}
const preprocessorNodeFactory = createNodeFactory(createPreprocessedNode, createParenthesizerRules, createNodeConverters, nullTreeStateObserver);
const preprocessorNodeFactory = createNodeFactory(NodeFactoryFlags.None, createBaseNodeFactory(), {
onCreateNode: node => {
node.flags |= NodeFlags.Preprocessed;
node.pos = -1;
node.end = -1;
}
});
/**
* Create a new 'AsyncProgram' instance. A Program is an immutable collection of 'SourceFile's and a 'CompilerOptions'
@@ -3658,4 +3658,28 @@ namespace ts {
}
return res;
}
export function isUnprocessedSourceFile(node: SourceFile) {
return !node.preprocessInfo || node === node.preprocessInfo.unprocessed;
}
export function isProcessedSourceFile(node: SourceFile) {
return !!node.preprocessInfo && node !== node.preprocessInfo.unprocessed;
}
/**
* If the source file has been preprocessed due to a plugin, gets the unprocessed
* source file. Otherwise, returns the source file.
*/
export function getUnprocessedSourceFile(node: SourceFile) {
return node.preprocessInfo ? node.preprocessInfo.unprocessed : node;
}
/**
* If the source file has been preprocessed due to a plugin, gets the processed
* source file. Otherwise, returns the source file.
*/
export function getProcessedSourceFile(node: SourceFile) {
return node.preprocessInfo ? node.preprocessInfo.processed : node;
}
}
+4 -4
View File
@@ -919,7 +919,7 @@ namespace ts {
}
addRange(members, visitNodes(node.members, classElementVisitor, isClassElement));
return setTextRange(createNodeArray(members), /*location*/ node.members);
return setTextRange(factory.createNodeArray(members), /*location*/ node.members);
}
@@ -1941,7 +1941,7 @@ namespace ts {
// End the lexical environment.
statements = mergeLexicalEnvironment(statements, endLexicalEnvironment());
const block = factory.createBlock(setTextRange(createNodeArray(statements), body.statements), /*multiLine*/ true);
const block = factory.createBlock(setTextRange(factory.createNodeArray(statements), body.statements), /*multiLine*/ true);
setTextRange(block, /*location*/ body);
setOriginalNode(block, body);
return block;
@@ -2386,7 +2386,7 @@ namespace ts {
currentNamespaceContainerName = savedCurrentNamespaceLocalName;
return factory.createBlock(
setTextRange(createNodeArray(statements), /*location*/ node.members),
setTextRange(factory.createNodeArray(statements), /*location*/ node.members),
/*multiLine*/ true
);
}
@@ -2710,7 +2710,7 @@ namespace ts {
const block = factory.createBlock(
setTextRange(
createNodeArray(statements),
factory.createNodeArray(statements),
/*location*/ statementsLocation
),
/*multiLine*/ true
+8 -3
View File
@@ -20,8 +20,14 @@
"diagnosticInformationMap.generated.ts",
"scanner.ts",
"utilities.ts",
"parenthesizerRules.ts",
"factory.ts",
"factory/parenthesizerRules.ts",
"factory/converters.ts",
"factory/base.ts",
"factory/factory.ts",
"factory/emitNode.ts",
"factory/emitHelpers.ts",
"factory/nodeTests.ts",
"factory/utilities.ts",
"parser.ts",
"commandLineParser.ts",
"moduleNameResolver.ts",
@@ -30,7 +36,6 @@
"symbolWalker.ts",
"checker.ts",
"visitor.ts",
"emitHelpers.ts",
"sourcemap.ts",
"transformers/utilities.ts",
"transformers/destructuring.ts",
+332 -139
View File
@@ -11,112 +11,6 @@ namespace ts {
end: number;
}
export type JSDocSyntaxKind =
| SyntaxKind.EndOfFileToken
| SyntaxKind.WhitespaceTrivia
| SyntaxKind.AtToken
| SyntaxKind.NewLineTrivia
| SyntaxKind.AsteriskToken
| SyntaxKind.OpenBraceToken
| SyntaxKind.CloseBraceToken
| SyntaxKind.LessThanToken
| SyntaxKind.GreaterThanToken
| SyntaxKind.OpenBracketToken
| SyntaxKind.CloseBracketToken
| SyntaxKind.EqualsToken
| SyntaxKind.CommaToken
| SyntaxKind.DotToken
| SyntaxKind.Identifier
| SyntaxKind.BacktickToken
| SyntaxKind.Unknown
| KeywordSyntaxKind;
export type KeywordSyntaxKind =
| SyntaxKind.AbstractKeyword
| SyntaxKind.AnyKeyword
| SyntaxKind.AsKeyword
| SyntaxKind.BigIntKeyword
| SyntaxKind.BooleanKeyword
| SyntaxKind.BreakKeyword
| SyntaxKind.CaseKeyword
| SyntaxKind.CatchKeyword
| SyntaxKind.ClassKeyword
| SyntaxKind.ContinueKeyword
| SyntaxKind.ConstKeyword
| SyntaxKind.ConstructorKeyword
| SyntaxKind.DebuggerKeyword
| SyntaxKind.DeclareKeyword
| SyntaxKind.DefaultKeyword
| SyntaxKind.DeleteKeyword
| SyntaxKind.DoKeyword
| SyntaxKind.ElseKeyword
| SyntaxKind.EnumKeyword
| SyntaxKind.ExportKeyword
| SyntaxKind.ExtendsKeyword
| SyntaxKind.FalseKeyword
| SyntaxKind.FinallyKeyword
| SyntaxKind.ForKeyword
| SyntaxKind.FromKeyword
| SyntaxKind.FunctionKeyword
| SyntaxKind.GetKeyword
| SyntaxKind.IfKeyword
| SyntaxKind.ImplementsKeyword
| SyntaxKind.ImportKeyword
| SyntaxKind.InKeyword
| SyntaxKind.InferKeyword
| SyntaxKind.InstanceOfKeyword
| SyntaxKind.InterfaceKeyword
| SyntaxKind.IsKeyword
| SyntaxKind.KeyOfKeyword
| SyntaxKind.LetKeyword
| SyntaxKind.ModuleKeyword
| SyntaxKind.NamespaceKeyword
| SyntaxKind.NeverKeyword
| SyntaxKind.NewKeyword
| SyntaxKind.NullKeyword
| SyntaxKind.NumberKeyword
| SyntaxKind.ObjectKeyword
| SyntaxKind.PackageKeyword
| SyntaxKind.PrivateKeyword
| SyntaxKind.ProtectedKeyword
| SyntaxKind.PublicKeyword
| SyntaxKind.ReadonlyKeyword
| SyntaxKind.RequireKeyword
| SyntaxKind.GlobalKeyword
| SyntaxKind.ReturnKeyword
| SyntaxKind.SetKeyword
| SyntaxKind.StaticKeyword
| SyntaxKind.StringKeyword
| SyntaxKind.SuperKeyword
| SyntaxKind.SwitchKeyword
| SyntaxKind.SymbolKeyword
| SyntaxKind.ThisKeyword
| SyntaxKind.ThrowKeyword
| SyntaxKind.TrueKeyword
| SyntaxKind.TryKeyword
| SyntaxKind.TypeKeyword
| SyntaxKind.TypeOfKeyword
| SyntaxKind.UndefinedKeyword
| SyntaxKind.UniqueKeyword
| SyntaxKind.UnknownKeyword
| SyntaxKind.VarKeyword
| SyntaxKind.VoidKeyword
| SyntaxKind.WhileKeyword
| SyntaxKind.WithKeyword
| SyntaxKind.YieldKeyword
| SyntaxKind.AsyncKeyword
| SyntaxKind.AwaitKeyword
| SyntaxKind.OfKeyword;
export type JsxTokenSyntaxKind =
| SyntaxKind.LessThanSlashToken
| SyntaxKind.EndOfFileToken
| SyntaxKind.ConflictMarkerTrivia
| SyntaxKind.JsxText
| SyntaxKind.JsxTextAllWhiteSpaces
| SyntaxKind.OpenBraceToken
| SyntaxKind.LessThanToken;
// token > SyntaxKind.Identifier => token is a keyword
// Also, If you add a new SyntaxKind be sure to keep the `Markers` section at the bottom in sync
export const enum SyntaxKind {
@@ -524,6 +418,209 @@ namespace ts {
/* @internal */ LastContextualKeyword = OfKeyword,
}
export type TriviaSyntaxKind =
| SyntaxKind.SingleLineCommentTrivia
| SyntaxKind.MultiLineCommentTrivia
| SyntaxKind.NewLineTrivia
| SyntaxKind.WhitespaceTrivia
| SyntaxKind.ShebangTrivia
| SyntaxKind.ConflictMarkerTrivia
;
export type LiteralSyntaxKind =
| SyntaxKind.NumericLiteral
| SyntaxKind.BigIntLiteral
| SyntaxKind.StringLiteral
| SyntaxKind.JsxText
| SyntaxKind.JsxTextAllWhiteSpaces
| SyntaxKind.RegularExpressionLiteral
| SyntaxKind.NoSubstitutionTemplateLiteral
;
export type PseudoLiteralSyntaxKind =
| SyntaxKind.TemplateHead
| SyntaxKind.TemplateMiddle
| SyntaxKind.TemplateTail
;
export type PunctuationSyntaxKind =
| SyntaxKind.OpenBraceToken
| SyntaxKind.CloseBraceToken
| SyntaxKind.OpenParenToken
| SyntaxKind.CloseParenToken
| SyntaxKind.OpenBracketToken
| SyntaxKind.CloseBracketToken
| SyntaxKind.DotToken
| SyntaxKind.DotDotDotToken
| SyntaxKind.SemicolonToken
| SyntaxKind.CommaToken
| SyntaxKind.LessThanToken
| SyntaxKind.LessThanSlashToken
| SyntaxKind.GreaterThanToken
| SyntaxKind.LessThanEqualsToken
| SyntaxKind.GreaterThanEqualsToken
| SyntaxKind.EqualsEqualsToken
| SyntaxKind.ExclamationEqualsToken
| SyntaxKind.EqualsEqualsEqualsToken
| SyntaxKind.ExclamationEqualsEqualsToken
| SyntaxKind.EqualsGreaterThanToken
| SyntaxKind.PlusToken
| SyntaxKind.MinusToken
| SyntaxKind.AsteriskToken
| SyntaxKind.AsteriskAsteriskToken
| SyntaxKind.SlashToken
| SyntaxKind.PercentToken
| SyntaxKind.PlusPlusToken
| SyntaxKind.MinusMinusToken
| SyntaxKind.LessThanLessThanToken
| SyntaxKind.GreaterThanGreaterThanToken
| SyntaxKind.GreaterThanGreaterThanGreaterThanToken
| SyntaxKind.AmpersandToken
| SyntaxKind.BarToken
| SyntaxKind.CaretToken
| SyntaxKind.ExclamationToken
| SyntaxKind.TildeToken
| SyntaxKind.AmpersandAmpersandToken
| SyntaxKind.BarBarToken
| SyntaxKind.QuestionToken
| SyntaxKind.ColonToken
| SyntaxKind.AtToken
| SyntaxKind.BacktickToken
| SyntaxKind.EqualsToken
| SyntaxKind.PlusEqualsToken
| SyntaxKind.MinusEqualsToken
| SyntaxKind.AsteriskEqualsToken
| SyntaxKind.AsteriskAsteriskEqualsToken
| SyntaxKind.SlashEqualsToken
| SyntaxKind.PercentEqualsToken
| SyntaxKind.LessThanLessThanEqualsToken
| SyntaxKind.GreaterThanGreaterThanEqualsToken
| SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken
| SyntaxKind.AmpersandEqualsToken
| SyntaxKind.BarEqualsToken
| SyntaxKind.CaretEqualsToken
;
export type KeywordSyntaxKind =
| SyntaxKind.AbstractKeyword
| SyntaxKind.AnyKeyword
| SyntaxKind.AsKeyword
| SyntaxKind.BigIntKeyword
| SyntaxKind.BooleanKeyword
| SyntaxKind.BreakKeyword
| SyntaxKind.CaseKeyword
| SyntaxKind.CatchKeyword
| SyntaxKind.ClassKeyword
| SyntaxKind.ContinueKeyword
| SyntaxKind.ConstKeyword
| SyntaxKind.ConstructorKeyword
| SyntaxKind.DebuggerKeyword
| SyntaxKind.DeclareKeyword
| SyntaxKind.DefaultKeyword
| SyntaxKind.DeleteKeyword
| SyntaxKind.DoKeyword
| SyntaxKind.ElseKeyword
| SyntaxKind.EnumKeyword
| SyntaxKind.ExportKeyword
| SyntaxKind.ExtendsKeyword
| SyntaxKind.FalseKeyword
| SyntaxKind.FinallyKeyword
| SyntaxKind.ForKeyword
| SyntaxKind.FromKeyword
| SyntaxKind.FunctionKeyword
| SyntaxKind.GetKeyword
| SyntaxKind.IfKeyword
| SyntaxKind.ImplementsKeyword
| SyntaxKind.ImportKeyword
| SyntaxKind.InKeyword
| SyntaxKind.InferKeyword
| SyntaxKind.InstanceOfKeyword
| SyntaxKind.InterfaceKeyword
| SyntaxKind.IsKeyword
| SyntaxKind.KeyOfKeyword
| SyntaxKind.LetKeyword
| SyntaxKind.ModuleKeyword
| SyntaxKind.NamespaceKeyword
| SyntaxKind.NeverKeyword
| SyntaxKind.NewKeyword
| SyntaxKind.NullKeyword
| SyntaxKind.NumberKeyword
| SyntaxKind.ObjectKeyword
| SyntaxKind.PackageKeyword
| SyntaxKind.PrivateKeyword
| SyntaxKind.ProtectedKeyword
| SyntaxKind.PublicKeyword
| SyntaxKind.ReadonlyKeyword
| SyntaxKind.RequireKeyword
| SyntaxKind.GlobalKeyword
| SyntaxKind.ReturnKeyword
| SyntaxKind.SetKeyword
| SyntaxKind.StaticKeyword
| SyntaxKind.StringKeyword
| SyntaxKind.SuperKeyword
| SyntaxKind.SwitchKeyword
| SyntaxKind.SymbolKeyword
| SyntaxKind.ThisKeyword
| SyntaxKind.ThrowKeyword
| SyntaxKind.TrueKeyword
| SyntaxKind.TryKeyword
| SyntaxKind.TypeKeyword
| SyntaxKind.TypeOfKeyword
| SyntaxKind.UndefinedKeyword
| SyntaxKind.UniqueKeyword
| SyntaxKind.UnknownKeyword
| SyntaxKind.VarKeyword
| SyntaxKind.VoidKeyword
| SyntaxKind.WhileKeyword
| SyntaxKind.WithKeyword
| SyntaxKind.YieldKeyword
| SyntaxKind.AsyncKeyword
| SyntaxKind.AwaitKeyword
| SyntaxKind.OfKeyword
;
export type TokenSyntaxKind =
| SyntaxKind.Unknown
| SyntaxKind.EndOfFileToken
| TriviaSyntaxKind
| LiteralSyntaxKind
| PseudoLiteralSyntaxKind
| PunctuationSyntaxKind
| SyntaxKind.Identifier
| KeywordSyntaxKind
;
export type JsxTokenSyntaxKind =
| SyntaxKind.LessThanSlashToken
| SyntaxKind.EndOfFileToken
| SyntaxKind.ConflictMarkerTrivia
| SyntaxKind.JsxText
| SyntaxKind.JsxTextAllWhiteSpaces
| SyntaxKind.OpenBraceToken
| SyntaxKind.LessThanToken
;
export type JSDocSyntaxKind =
| SyntaxKind.EndOfFileToken
| SyntaxKind.WhitespaceTrivia
| SyntaxKind.AtToken
| SyntaxKind.NewLineTrivia
| SyntaxKind.AsteriskToken
| SyntaxKind.OpenBraceToken
| SyntaxKind.CloseBraceToken
| SyntaxKind.LessThanToken
| SyntaxKind.GreaterThanToken
| SyntaxKind.OpenBracketToken
| SyntaxKind.CloseBracketToken
| SyntaxKind.EqualsToken
| SyntaxKind.CommaToken
| SyntaxKind.DotToken
| SyntaxKind.Identifier
| SyntaxKind.BacktickToken
| SyntaxKind.Unknown
| KeywordSyntaxKind
;
export const enum NodeFlags {
None = 0,
Let = 1 << 0, // Variable declaration
@@ -727,35 +824,78 @@ namespace ts {
/* @internal */ transformFlags: TransformFlags; // Flags for transforms, possibly undefined
}
// TODO(rbuckton): Constraint 'TKind' to 'TokenSyntaxKind'
export interface Token<TKind extends SyntaxKind> extends Node {
kind: TKind;
}
export type DotDotDotToken = Token<SyntaxKind.DotDotDotToken>;
export type QuestionToken = Token<SyntaxKind.QuestionToken>;
export type ExclamationToken = Token<SyntaxKind.ExclamationToken>;
export type ColonToken = Token<SyntaxKind.ColonToken>;
export type EqualsToken = Token<SyntaxKind.EqualsToken>;
export type AsteriskToken = Token<SyntaxKind.AsteriskToken>;
export type EqualsGreaterThanToken = Token<SyntaxKind.EqualsGreaterThanToken>;
export type EndOfFileToken = Token<SyntaxKind.EndOfFileToken> & JSDocContainer;
export type ReadonlyToken = Token<SyntaxKind.ReadonlyKeyword>;
export type AwaitKeywordToken = Token<SyntaxKind.AwaitKeyword>;
export type PlusToken = Token<SyntaxKind.PlusToken>;
export type MinusToken = Token<SyntaxKind.MinusToken>;
export interface PunctuationToken<TKind extends PunctuationSyntaxKind> extends Token<TKind> {
}
// Punctuation
export type DotDotDotToken = PunctuationToken<SyntaxKind.DotDotDotToken>;
export type QuestionToken = PunctuationToken<SyntaxKind.QuestionToken>;
export type ExclamationToken = PunctuationToken<SyntaxKind.ExclamationToken>;
export type ColonToken = PunctuationToken<SyntaxKind.ColonToken>;
export type EqualsToken = PunctuationToken<SyntaxKind.EqualsToken>;
export type AsteriskToken = PunctuationToken<SyntaxKind.AsteriskToken>;
export type EqualsGreaterThanToken = PunctuationToken<SyntaxKind.EqualsGreaterThanToken>;
export type PlusToken = PunctuationToken<SyntaxKind.PlusToken>;
export type MinusToken = PunctuationToken<SyntaxKind.MinusToken>;
export interface KeywordToken<TKind extends KeywordSyntaxKind> extends Token<TKind> {
}
/** @deprecated Use `AwaitKeyword` instead. */
export type AwaitKeywordToken = AwaitKeyword;
/** @deprecated Use `ReadonlyKeyword` instead. */
export type ReadonlyToken = ReadonlyKeyword;
export type AwaitKeyword = Token<SyntaxKind.AwaitKeyword>;
export type AbstractKeyword = Token<SyntaxKind.AbstractKeyword>;
export type AsyncKeyword = Token<SyntaxKind.AsyncKeyword>;
export type ConstKeyword = Token<SyntaxKind.ConstKeyword>;
export type DeclareKeyword = Token<SyntaxKind.DeclareKeyword>;
export type DefaultKeyword = Token<SyntaxKind.DefaultKeyword>;
export type ExportKeyword = Token<SyntaxKind.ExportKeyword>;
export type PublicKeyword = Token<SyntaxKind.PublicKeyword>;
export type PrivateKeyword = Token<SyntaxKind.PrivateKeyword>;
export type ProtectedKeyword = Token<SyntaxKind.ProtectedKeyword>;
export type ReadonlyKeyword = Token<SyntaxKind.ReadonlyKeyword>;
export type StaticKeyword = Token<SyntaxKind.StaticKeyword>;
export type Modifier
= Token<SyntaxKind.AbstractKeyword>
| Token<SyntaxKind.AsyncKeyword>
| Token<SyntaxKind.ConstKeyword>
| Token<SyntaxKind.DeclareKeyword>
| Token<SyntaxKind.DefaultKeyword>
| Token<SyntaxKind.ExportKeyword>
| Token<SyntaxKind.PublicKeyword>
| Token<SyntaxKind.PrivateKeyword>
| Token<SyntaxKind.ProtectedKeyword>
| Token<SyntaxKind.ReadonlyKeyword>
| Token<SyntaxKind.StaticKeyword>
= AbstractKeyword
| AsyncKeyword
| ConstKeyword
| DeclareKeyword
| DefaultKeyword
| ExportKeyword
| PublicKeyword
| PrivateKeyword
| ProtectedKeyword
| ReadonlyKeyword
| StaticKeyword
;
export type AccessibilityModifier =
| PublicKeyword
| PrivateKeyword
| ProtectedKeyword
;
export type ParameterPropertyModifier =
| AccessibilityModifier
| ReadonlyKeyword
;
export type ClassMemberModifier =
| AccessibilityModifier
| ReadonlyKeyword
| StaticKeyword
;
export type ModifiersArray = NodeArray<Modifier>;
@@ -956,12 +1096,14 @@ namespace ts {
initializer?: Expression; // Optional initializer
}
// TODO(rbuckton): Rename to 'BaseObjectLiteralElement'
export interface ObjectLiteralElement extends NamedDeclaration {
_objectLiteralBrand: any;
name?: PropertyName;
}
/** Unlike ObjectLiteralElement, excludes JSXAttribute and JSXSpreadAttribute. */
// TODO(rbuckton): Rename to 'ObjectLiteralElement'
export type ObjectLiteralElementLike
= PropertyAssignment
| ShorthandPropertyAssignment
@@ -1271,7 +1413,7 @@ namespace ts {
export interface MappedTypeNode extends TypeNode, Declaration {
kind: SyntaxKind.MappedType;
readonlyToken?: ReadonlyToken | PlusToken | MinusToken;
readonlyToken?: ReadonlyKeyword | PlusToken | MinusToken;
typeParameter: TypeParameterDeclaration;
questionToken?: QuestionToken | PlusToken | MinusToken;
type?: TypeNode;
@@ -2125,7 +2267,7 @@ namespace ts {
export interface ForOfStatement extends IterationStatement {
kind: SyntaxKind.ForOfStatement;
awaitModifier?: AwaitKeywordToken;
awaitModifier?: AwaitKeyword;
initializer: ForInitializer;
expression: Expression;
}
@@ -2231,17 +2373,41 @@ namespace ts {
export type ClassLikeDeclaration = ClassDeclaration | ClassExpression;
// TODO(rbuckton): Rename to 'BaseClassElement'
export interface ClassElement extends NamedDeclaration {
_classElementBrand: any;
name?: PropertyName;
}
// TODO(rbuckton): Rename to 'ClassElement' and make public
/* @internal */
export type ClassElementNode =
| ConstructorDeclaration
| PropertyDeclaration
| MethodDeclaration
| GetAccessorDeclaration
| SetAccessorDeclaration
| IndexSignatureDeclaration
| SemicolonClassElement
;
// TODO(rbuckton): Rename to 'BaseTypeElement'
export interface TypeElement extends NamedDeclaration {
_typeElementBrand: any;
name?: PropertyName;
questionToken?: QuestionToken;
}
// TODO(rbuckton): Rename to 'TypeElement' and make public
/* @internal */
export type TypeElementNode =
| PropertySignature
| MethodSignature
| ConstructSignatureDeclaration
| CallSignatureDeclaration
| IndexSignatureDeclaration
;
export interface InterfaceDeclaration extends DeclarationStatement, JSDocContainer {
kind: SyntaxKind.InterfaceDeclaration;
name: Identifier;
@@ -4721,6 +4887,13 @@ namespace ts {
length: number;
}
/* @internal*/
export interface DiagnosticWithDetachedLocation extends Diagnostic {
file: undefined;
start: number;
length: number;
}
export enum DiagnosticCategory {
Warning,
Error,
@@ -5735,6 +5908,22 @@ namespace ts {
set?: Expression;
}
/* @internal */
export interface BaseNodeFactory {
createBaseSourceFileNode(kind: SyntaxKind): Node;
createBaseIdentifierNode(kind: SyntaxKind): Node;
createBaseTokenNode(kind: SyntaxKind): Node;
createBaseNode(kind: SyntaxKind): Node;
}
/* @internal */
export const enum NodeFactoryFlags {
None = 0,
NoParenthesizerRules = 1 << 0,
NoNodeConverters = 1 << 1,
NoIndentationOnFreshPropertyAccess = 1 << 2,
}
export interface NodeFactory {
/* @internal */ getParenthesizerRules(): ParenthesizerRules;
/* @internal */ getConverters(): NodeConverters;
@@ -5747,6 +5936,7 @@ namespace ts {
createNumericLiteral(value: string | number, numericLiteralFlags?: TokenFlags): NumericLiteral;
createBigIntLiteral(value: string | PseudoBigInt): BigIntLiteral;
createStringLiteral(text: string, isSingleQuote?: boolean): StringLiteral;
/* @internal*/ createStringLiteral(text: string, isSingleQuote?: boolean, hasExtendedUnicodeEscape?: boolean): StringLiteral; // tslint:disable-line unified-signatures
createStringLiteralFromNode(sourceNode: PropertyNameLiteral, isSingleQuote?: boolean): StringLiteral;
createRegularExpressionLiteral(text: string): RegularExpressionLiteral;
@@ -5890,8 +6080,8 @@ namespace ts {
updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode;
createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
createMappedTypeNode(readonlyToken: ReadonlyToken | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode;
updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyToken | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode;
createMappedTypeNode(readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode;
updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode;
createLiteralTypeNode(literal: LiteralTypeNode["literal"]): LiteralTypeNode;
updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]): LiteralTypeNode;
@@ -6012,8 +6202,8 @@ namespace ts {
updateFor(node: ForStatement, initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement): ForStatement;
createForIn(initializer: ForInitializer, expression: Expression, statement: Statement): ForInStatement;
updateForIn(node: ForInStatement, initializer: ForInitializer, expression: Expression, statement: Statement): ForInStatement;
createForOf(awaitModifier: AwaitKeywordToken | undefined, initializer: ForInitializer, expression: Expression, statement: Statement): ForOfStatement;
updateForOf(node: ForOfStatement, awaitModifier: AwaitKeywordToken | undefined, initializer: ForInitializer, expression: Expression, statement: Statement): ForOfStatement;
createForOf(awaitModifier: AwaitKeyword | undefined, initializer: ForInitializer, expression: Expression, statement: Statement): ForOfStatement;
updateForOf(node: ForOfStatement, awaitModifier: AwaitKeyword | undefined, initializer: ForInitializer, expression: Expression, statement: Statement): ForOfStatement;
createContinue(label?: string | Identifier): ContinueStatement;
updateContinue(node: ContinueStatement, label: Identifier | undefined): ContinueStatement;
createBreak(label?: string | Identifier): BreakStatement;
@@ -6034,6 +6224,7 @@ namespace ts {
createVariableDeclaration(name: string | BindingName, type?: TypeNode, initializer?: Expression): VariableDeclaration;
createVariableDeclaration(name: string | BindingName, exclamationToken: ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): VariableDeclaration;
updateVariableDeclaration(node: VariableDeclaration, name: BindingName, type: TypeNode | undefined, initializer: Expression | undefined): VariableDeclaration;
updateVariableDeclaration(node: VariableDeclaration, name: BindingName, exclamationToken: ExclamationToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): VariableDeclaration;
createVariableDeclarationList(declarations: readonly VariableDeclaration[], flags?: NodeFlags): VariableDeclarationList;
updateVariableDeclarationList(node: VariableDeclarationList, declarations: readonly VariableDeclaration[]): VariableDeclarationList;
createFunctionDeclaration(decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined): FunctionDeclaration;
@@ -6175,6 +6366,7 @@ namespace ts {
// Top-level nodes
//
createSourceFile(statements: readonly Statement[], endOfFileToken: EndOfFileToken): SourceFile;
updateSourceFile(node: SourceFile, statements: readonly Statement[], isDeclarationFile?: boolean, referencedFiles?: readonly FileReference[], typeReferences?: readonly FileReference[], hasNoDefaultLib?: boolean, libReferences?: readonly FileReference[]): SourceFile;
//
@@ -6340,11 +6532,12 @@ namespace ts {
/* @internal */
export interface TreeStateObserver {
onSetChild(parent: Node, child: Node): void;
onSetChildren(parent: Node, children: NodeArray<Node>): void;
onFinishNode(node: Node): void;
onUpdateNode(updated: Node, original: Node): void;
onReuseNode(node: Node): void;
onCreateNode?(node: Node): void;
onSetChild?(parent: Node, child: Node): void;
onSetChildren?(parent: Node, children: NodeArray<Node>): void;
onFinishNode?(node: Node): void;
onUpdateNode?(updated: Node, original: Node): void;
onReuseNode?(node: Node): void;
}
export interface CoreTransformationContext {
+328 -885
View File
File diff suppressed because it is too large Load Diff
+33 -8
View File
@@ -84,7 +84,7 @@ namespace ts {
return nodes;
}
let updated: MutableNodeArray<T> | undefined;
let updated: T[] | undefined;
// Ensure start and count have valid values
const length = nodes.length;
@@ -96,11 +96,15 @@ namespace ts {
count = length - start;
}
let hasTrailingComma: boolean | undefined;
let pos = -1;
let end = -1;
if (start > 0 || count < length) {
// If we are not visiting all of the original nodes, we must always create a new array.
// Since this is a fragment of a node array, we do not copy over the previous location
// and will only copy over `hasTrailingComma` if we are including the last element.
updated = createNodeArray<T>([], /*hasTrailingComma*/ nodes.hasTrailingComma && start + count === length);
updated = [];
hasTrailingComma = nodes.hasTrailingComma && start + count === length;
}
// Visit each original node.
@@ -111,8 +115,10 @@ namespace ts {
if (updated !== undefined || visited === undefined || visited !== node) {
if (updated === undefined) {
// Ensure we have a copy of `nodes`, up to the current index.
updated = createNodeArray(nodes.slice(0, i), nodes.hasTrailingComma);
setTextRange(updated, nodes);
updated = nodes.slice(0, i);
hasTrailingComma = nodes.hasTrailingComma;
pos = nodes.pos;
end = nodes.end;
}
if (visited) {
if (isArray(visited)) {
@@ -131,7 +137,15 @@ namespace ts {
}
}
return updated || nodes;
if (updated) {
// TODO(rbuckton): Remove dependency on `ts.factory` in favor of a provided factory.
const updatedArray = factory.createNodeArray(updated, hasTrailingComma);
updatedArray.pos = pos;
updatedArray.end = end;
return updatedArray;
}
return nodes;
}
/**
@@ -143,10 +157,12 @@ namespace ts {
startLexicalEnvironment();
statements = visitNodes(statements, visitor, isStatementOrBlock, start);
if (ensureUseStrict && !startsWithUseStrict(statements)) {
// TODO(rbuckton): Remove dependency on `ts.factory` in favor of a provided factory.
statements = setTextRange(factory.createNodeArray([factory.createUseStrictPrologue(), ...statements]), statements);
}
const declarations = endLexicalEnvironment();
return setTextRange(createNodeArray(concatenate(declarations, statements)), statements);
// TODO(rbuckton): Remove dependency on `ts.factory` in favor of a provided factory.
return setTextRange(factory.createNodeArray(concatenate(declarations, statements)), statements);
}
/**
@@ -1483,8 +1499,9 @@ namespace ts {
return statements;
}
// TODO(rbuckton): Remove dependency on `ts.factory` in favor of a provided factory.
return isNodeArray(statements)
? setTextRange(createNodeArray(insertStatementsAfterStandardPrologue(statements.slice(), declarations)), statements)
? setTextRange(factory.createNodeArray(insertStatementsAfterStandardPrologue(statements.slice(), declarations)), statements)
: insertStatementsAfterStandardPrologue(statements, declarations);
}
@@ -1508,7 +1525,15 @@ namespace ts {
return TransformFlags.None;
}
if (node.transformFlags & TransformFlags.HasComputedFlags) {
return node.transformFlags & ~getTransformFlagsSubtreeExclusions(node.kind);
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);
@@ -14,7 +14,7 @@ namespace ts.codefix {
function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number) {
const token = getTokenAtPosition(sourceFile, pos);
const assertion = Debug.assertDefined(findAncestor(token, (n): n is AsExpression | TypeAssertion => isAsExpression(n) || isTypeAssertion(n)));
const assertion = Debug.assertDefined(findAncestor(token, (n): n is AsExpression | TypeAssertion => isAsExpression(n) || isTypeAssertionExpression(n)));
const replacement = isAsExpression(assertion)
? factory.createAsExpression(assertion.expression, factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword))
: factory.createTypeAssertion(factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword), assertion.expression);
@@ -144,7 +144,7 @@ namespace ts.codefix {
}
name = factory.createIdentifier(text);
if ((text === "Array" || text === "Promise") && !node.typeArguments) {
args = createNodeArray([factory.createTypeReferenceNode("any", emptyArray)]);
args = factory.createNodeArray([factory.createTypeReferenceNode("any", emptyArray)]);
}
else {
args = visitNodes(node.typeArguments, transformJSDocType);
+1 -1
View File
@@ -483,7 +483,7 @@ namespace ts.codefix {
getSynthesizedDeepClones(fn.typeParameters),
getSynthesizedDeepClones(fn.parameters),
getSynthesizedDeepClone(fn.type),
nodeConverters.convertToFunctionBlock(getSynthesizedDeepClone(fn.body!)));
factory.getConverters().convertToFunctionBlock(getSynthesizedDeepClone(fn.body!)));
}
function classExpressionToDeclaration(name: string | undefined, additionalModifiers: ReadonlyArray<Modifier>, cls: ClassExpression): ClassDeclaration {
@@ -70,7 +70,7 @@ namespace ts.codefix {
if (returnType) {
const entityName = getEntityNameFromTypeNode(returnType);
if (!entityName || entityName.kind !== SyntaxKind.Identifier || entityName.text !== "Promise") {
changes.replaceNode(sourceFile, returnType, factory.createTypeReferenceNode("Promise", createNodeArray([returnType])));
changes.replaceNode(sourceFile, returnType, factory.createTypeReferenceNode("Promise", factory.createNodeArray([returnType])));
}
}
changes.insertModifierBefore(sourceFile, SyntaxKind.AsyncKeyword, insertBefore);
+1 -1
View File
@@ -52,7 +52,7 @@ namespace ts.codefix {
const declaration = declarations[0];
const name = getSynthesizedDeepClone(getNameOfDeclaration(declaration), /*includeTrivia*/ false) as PropertyName;
const visibilityModifier = createVisibilityModifier(getModifierFlags(declaration));
const modifiers = visibilityModifier ? createNodeArray([visibilityModifier]) : undefined;
const modifiers = visibilityModifier ? factory.createNodeArray([visibilityModifier]) : undefined;
const type = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration));
const optional = !!(symbol.flags & SymbolFlags.Optional);
const ambient = !!(enclosingDeclaration.flags & NodeFlags.Ambient);
+1 -1
View File
@@ -318,7 +318,7 @@ namespace ts.codefix {
if (merged) oldTags[i] = merged;
return !!merged;
}));
const tag = factory.createJSDocComment(comments.join("\n"), createNodeArray([...(oldTags || emptyArray), ...unmergedNewTags]));
const tag = factory.createJSDocComment(comments.join("\n"), factory.createNodeArray([...(oldTags || emptyArray), ...unmergedNewTags]));
const jsDocNode = parent.kind === SyntaxKind.ArrowFunction ? getJsDocNodeForArrowFunction(parent) : parent;
jsDocNode.jsDoc = parent.jsDoc;
jsDocNode.jsDocCache = parent.jsDocCache;
@@ -356,7 +356,7 @@ namespace ts.refactor.convertParamsToDestructuredObject {
function getRefactorableParameters(parameters: NodeArray<ValidParameterDeclaration>): NodeArray<ValidParameterDeclaration> {
if (hasThisParameter(parameters)) {
parameters = createNodeArray(parameters.slice(1), parameters.hasTrailingComma);
parameters = factory.createNodeArray(parameters.slice(1), parameters.hasTrailingComma);
}
return parameters;
}
@@ -431,9 +431,9 @@ namespace ts.refactor.convertParamsToDestructuredObject {
copyComments(thisParameter.type, newThisParameter.type!);
}
return createNodeArray([newThisParameter, objectParameter]);
return factory.createNodeArray([newThisParameter, objectParameter]);
}
return createNodeArray([objectParameter]);
return factory.createNodeArray([objectParameter]);
function createBindingElementFromParameterDeclaration(parameterDeclaration: ValidParameterDeclaration): BindingElement {
const element = factory.createBindingElement(
+1 -1
View File
@@ -1164,7 +1164,7 @@ namespace ts.refactor.extractSymbol {
}
let returnValueProperty: string | undefined;
let ignoreReturns = false;
const statements = createNodeArray(isBlock(body) ? body.statements.slice(0) : [isStatement(body) ? body : factory.createReturn(<Expression>body)]);
const statements = factory.createNodeArray(isBlock(body) ? body.statements.slice(0) : [isStatement(body) ? body : factory.createReturn(<Expression>body)]);
// rewrite body if either there are writes that should be propagated back via return statements or there are substitutions
if (hasWritesOrVariableDeclarations || substitutions.size) {
const rewrittenStatements = visitNodes(statements, visitor).slice();
+2 -2
View File
@@ -136,12 +136,12 @@ namespace ts.refactor {
const parameter = <TypeParameterDeclaration>createNode(SyntaxKind.TypeParameter);
parameter.name = typeParameter.name;
template.typeParameters = createNodeArray([parameter]);
template.typeParameters = factory.createNodeArray([parameter]);
templates.push(template);
});
changes.insertNodeBefore(file, firstStatement, factory.createJSDocComment(/* comment */ undefined, createNodeArray(concatenate<JSDocTag>(templates, [node]))), /* blankLineBetween */ true);
changes.insertNodeBefore(file, firstStatement, factory.createJSDocComment(/* comment */ undefined, factory.createNodeArray(concatenate<JSDocTag>(templates, [node]))), /* blankLineBetween */ true);
changes.replaceNode(file, selection, factory.createTypeReferenceNode(name, typeParameters.map(id => factory.createTypeReferenceNode(id.name, /* typeArguments */ undefined))));
}
}
@@ -55,7 +55,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
const accessorModifiers = isInClassLike
? !modifierFlags || modifierFlags & ModifierFlags.Private
? getModifiers(isJS, isStatic, SyntaxKind.PublicKeyword)
: createNodeArray(factory.createModifiersFromModifierFlags(modifierFlags))
: factory.createNodeArray(factory.createModifiersFromModifierFlags(modifierFlags))
: undefined;
const fieldModifiers = isInClassLike ? getModifiers(isJS, isStatic, SyntaxKind.PrivateKeyword) : undefined;
@@ -109,7 +109,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
!isJS ? [factory.createToken(accessModifier) as Token<SyntaxKind.PublicKeyword> | Token<SyntaxKind.PrivateKeyword>] : undefined,
isStatic ? factory.createToken(SyntaxKind.StaticKeyword) : undefined
);
return modifiers && createNodeArray(modifiers);
return modifiers && factory.createNodeArray(modifiers);
}
function startsWithUnderscore(name: string): boolean {
+2 -2
View File
@@ -569,7 +569,7 @@ namespace ts.SignatureHelp {
const parameters = (typeParameters || emptyArray).map(t => createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer));
const parameterParts = mapToDisplayParts(writer => {
const thisParameter = candidateSignature.thisParameter ? [checker.symbolToParameterDeclaration(candidateSignature.thisParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)!] : [];
const params = createNodeArray([...thisParameter, ...checker.getExpandedParameters(candidateSignature).map(param => checker.symbolToParameterDeclaration(param, enclosingDeclaration, signatureHelpNodeBuilderFlags)!)]);
const params = factory.createNodeArray([...thisParameter, ...checker.getExpandedParameters(candidateSignature).map(param => checker.symbolToParameterDeclaration(param, enclosingDeclaration, signatureHelpNodeBuilderFlags)!)]);
printer.writeList(ListFormat.CallExpressionArguments, params, sourceFile, writer);
});
return { isVariadic: false, parameters, prefix: [punctuationPart(SyntaxKind.LessThanToken)], suffix: [punctuationPart(SyntaxKind.GreaterThanToken), ...parameterParts] };
@@ -580,7 +580,7 @@ namespace ts.SignatureHelp {
const printer = createPrinter({ removeComments: true });
const typeParameterParts = mapToDisplayParts(writer => {
if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) {
const args = createNodeArray(candidateSignature.typeParameters.map(p => checker.typeParameterToDeclaration(p, enclosingDeclaration)!));
const args = factory.createNodeArray(candidateSignature.typeParameters.map(p => checker.typeParameterToDeclaration(p, enclosingDeclaration)!));
printer.writeList(ListFormat.TypeParameters, args, sourceFile, writer);
}
});
+1 -1
View File
@@ -886,7 +886,7 @@ namespace ts.textChanges {
return visited;
}
// clone nodearray if necessary
const nodeArray = visited === nodes ? createNodeArray(visited.slice(0)) : visited;
const nodeArray = visited === nodes ? factory.createNodeArray(visited.slice(0)) : visited;
nodeArray.pos = getPos(nodes);
nodeArray.end = getEnd(nodes);
return nodeArray;
+1 -1
View File
@@ -1769,7 +1769,7 @@ namespace ts {
export function getSynthesizedDeepClones<T extends Node>(nodes: NodeArray<T>, includeTrivia?: boolean): NodeArray<T>;
export function getSynthesizedDeepClones<T extends Node>(nodes: NodeArray<T> | undefined, includeTrivia?: boolean): NodeArray<T> | undefined;
export function getSynthesizedDeepClones<T extends Node>(nodes: NodeArray<T> | undefined, includeTrivia = true): NodeArray<T> | undefined {
return nodes && createNodeArray(nodes.map(n => getSynthesizedDeepClone(n, includeTrivia)), nodes.hasTrailingComma);
return nodes && factory.createNodeArray(nodes.map(n => getSynthesizedDeepClone(n, includeTrivia)), nodes.hasTrailingComma);
}
/**
+3 -3
View File
@@ -1,9 +1,9 @@
namespace ts {
describe("unittests:: assert", () => {
it("deepEqual", () => {
assert.throws(() => assert.deepEqual(createNodeArray([createIdentifier("A")]), createNodeArray([createIdentifier("B")])));
assert.throws(() => assert.deepEqual(createNodeArray([], /*hasTrailingComma*/ true), createNodeArray([], /*hasTrailingComma*/ false)));
assert.deepEqual(createNodeArray([createIdentifier("A")], /*hasTrailingComma*/ true), createNodeArray([createIdentifier("A")], /*hasTrailingComma*/ true));
assert.throws(() => assert.deepEqual(factory.createNodeArray([createIdentifier("A")]), factory.createNodeArray([createIdentifier("B")])));
assert.throws(() => assert.deepEqual(factory.createNodeArray([], /*hasTrailingComma*/ true), factory.createNodeArray([], /*hasTrailingComma*/ false)));
assert.deepEqual(factory.createNodeArray([createIdentifier("A")], /*hasTrailingComma*/ true), factory.createNodeArray([createIdentifier("A")], /*hasTrailingComma*/ true));
});
it("assertNever on string has correct error", () => {
assert.throws(() => Debug.assertNever("hi" as never), "Debug Failure. Illegal value: \"hi\"");
+1 -1
View File
@@ -104,7 +104,7 @@ namespace ts {
/*heritageClauses*/ undefined,
[createProperty(
/*decorators*/ undefined,
createNodeArray([createToken(SyntaxKind.PublicKeyword)]),
factory.createNodeArray([createToken(SyntaxKind.PublicKeyword)]),
createIdentifier("prop"),
/*questionToken*/ undefined,
/*type*/ undefined,
+2 -2
View File
@@ -175,7 +175,7 @@ namespace ts {
function replaceWithClassAndNamespace() {
return (sourceFile: SourceFile) => {
const result = getMutableClone(sourceFile);
result.statements = createNodeArray([
result.statements = factory.createNodeArray([
createClassDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, "Foo", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, /*members*/ undefined!), // TODO: GH#18217
createModuleDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createIdentifier("Foo"), createModuleBlock([createEmptyStatement()]))
]);
@@ -191,7 +191,7 @@ namespace ts {
function visitNode<T extends Node>(node: T): T {
if (node.kind === SyntaxKind.ModuleBlock) {
const block = node as T & ModuleBlock;
const statements = createNodeArray([...block.statements]);
const statements = factory.createNodeArray([...block.statements]);
return updateModuleBlock(block, statements) as typeof block;
}
return visitEachChild(node, visitNode, context);