diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3d040bd284e..a4c5f401321 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2278,35 +2278,10 @@ namespace ts { return result; } - function typeFormatFlagsToNodeBuilderFlags(flags: TypeFormatFlags): NodeBuilderFlags { - let result = NodeBuilderFlags.None; - if (flags === TypeFormatFlags.None) { - return result; - } - if (flags & TypeFormatFlags.NoTruncation) { - result |= NodeBuilderFlags.NoTruncation; - } - if (flags & TypeFormatFlags.UseFullyQualifiedType) { - result |= NodeBuilderFlags.UseFullyQualifiedType; - } - if (flags & TypeFormatFlags.SuppressAnyReturnType) { - result |= NodeBuilderFlags.SuppressAnyReturnType; - } - if (flags & TypeFormatFlags.WriteArrayAsGenericType) { - result |= NodeBuilderFlags.WriteArrayAsGenericType; - } - if (flags & TypeFormatFlags.WriteTypeArgumentsOfSignature) { - result |= NodeBuilderFlags.WriteTypeArgumentsOfSignature; - } - - return result; - } - function typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string { - const typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, typeFormatFlagsToNodeBuilderFlags(flags) | NodeBuilderFlags.ignoreErrors); + const typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.ignoreErrors); Debug.assert(typeNode !== undefined, "should always get typenode?"); - const newLine = NewLineKind.None; - const options = { newLine, removeComments: true }; + const options = { removeComments: true }; const writer = createTextWriter(""); const printer = createPrinter(options, writer); const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration); @@ -2318,6 +2293,30 @@ namespace ts { return result.substr(0, maxLength - "...".length) + "..."; } return result; + + function toNodeBuilderFlags(flags?: TypeFormatFlags): NodeBuilderFlags { + let result = NodeBuilderFlags.None; + if (!flags) { + return result; + } + if (flags & TypeFormatFlags.NoTruncation) { + result |= NodeBuilderFlags.NoTruncation; + } + if (flags & TypeFormatFlags.UseFullyQualifiedType) { + result |= NodeBuilderFlags.UseFullyQualifiedType; + } + if (flags & TypeFormatFlags.SuppressAnyReturnType) { + result |= NodeBuilderFlags.SuppressAnyReturnType; + } + if (flags & TypeFormatFlags.WriteArrayAsGenericType) { + result |= NodeBuilderFlags.WriteArrayAsGenericType; + } + if (flags & TypeFormatFlags.WriteTypeArgumentsOfSignature) { + result |= NodeBuilderFlags.WriteTypeArgumentsOfSignature; + } + + return result; + } } function createNodeBuilder() { @@ -2423,7 +2422,7 @@ namespace ts { } if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) { if (context.flags & NodeBuilderFlags.inObjectTypeLiteral) { - if (!context.encounteredError && !(context.flags & NodeBuilderFlags.allowThisInObjectLiteral)) { + if (!context.encounteredError && !(context.flags & NodeBuilderFlags.AllowThisInObjectLiteral)) { context.encounteredError = true; } } @@ -2455,7 +2454,7 @@ namespace ts { return inElementType ? createParenthesizedType(unionOrIntersectionTypeNode) : unionOrIntersectionTypeNode; } else { - if (!context.encounteredError && !(context.flags & NodeBuilderFlags.allowEmptyUnionOrIntersection)) { + if (!context.encounteredError && !(context.flags & NodeBuilderFlags.AllowEmptyUnionOrIntersection)) { context.encounteredError = true; } return undefined; @@ -2629,7 +2628,7 @@ namespace ts { return createTupleTypeNode(tupleConstituentNodes); } } - if (!context.encounteredError && !(context.flags & NodeBuilderFlags.allowEmptyTuple)) { + if (!context.encounteredError && !(context.flags & NodeBuilderFlags.AllowEmptyTuple)) { context.encounteredError = true; } return undefined; @@ -2901,7 +2900,7 @@ namespace ts { if (expectsIdentifier && chain.length !== 1 && !context.encounteredError - && !(context.flags & NodeBuilderFlags.allowQualifedNameInPlaceOfIdentifier)) { + && !(context.flags & NodeBuilderFlags.AllowQualifedNameInPlaceOfIdentifier)) { context.encounteredError = true; } return createEntityNameFromSymbolChain(chain, chain.length - 1); @@ -2923,7 +2922,7 @@ namespace ts { } } if (typeParameters && typeParameters.length > 0) { - if (!context.encounteredError && !(context.flags & NodeBuilderFlags.allowTypeParameterInQualifiedName)) { + if (!context.encounteredError && !(context.flags & NodeBuilderFlags.AllowTypeParameterInQualifiedName)) { context.encounteredError = true; } typeParameterNodes = toTypeArgumentNodes(typeParameters, context); @@ -2981,7 +2980,7 @@ namespace ts { if (declaration.parent && declaration.parent.kind === SyntaxKind.VariableDeclaration) { return declarationNameToString((declaration.parent).name); } - if (!context.encounteredError && !(context.flags & NodeBuilderFlags.allowAnonymousIdentifier)) { + if (!context.encounteredError && !(context.flags & NodeBuilderFlags.AllowAnonymousIdentifier)) { context.encounteredError = true; } switch (declaration.kind) { diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index d943e91b497..30e5ba1a091 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -234,12 +234,7 @@ namespace ts { writeBundle }; - /** - * If `sourceFile` is `undefined`, `node` must be a synthesized `TypeNode`. - */ - function printNode(hint: EmitHint, node: TypeNode, sourceFile: undefined): string; - function printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): string; - function printNode(hint: EmitHint, node: Node, sourceFile: SourceFile | undefined): string { + function printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): string { switch (hint) { case EmitHint.SourceFile: Debug.assert(isSourceFile(node), "Expected a SourceFile node."); @@ -269,6 +264,11 @@ namespace ts { return endPrint(); } + /** + * If `sourceFile` is `undefined`, `node` must be a synthesized `TypeNode`. + */ + function writeNode(hint: EmitHint, node: TypeNode, sourceFile: undefined, output: EmitTextWriter): void; + function writeNode(hint: EmitHint, node: Node, sourceFile: SourceFile, output: EmitTextWriter): void; function writeNode(hint: EmitHint, node: Node, sourceFile: SourceFile | undefined, output: EmitTextWriter) { const previousWriter = writer; setWriter(output); @@ -961,6 +961,7 @@ namespace ts { function emitTypeLiteral(node: TypeLiteralNode) { write("{"); + // TODO: fix added indentation so we can remove this check. if (node.members.length > 0) { emitList(node, node.members, getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineTypeLiteralMembers : ListFormat.MultiLineTypeLiteralMembers); } @@ -2525,7 +2526,7 @@ namespace ts { const firstChild = children[0]; if (firstChild === undefined) { - return !(rangeIsOnSingleLine(parentNode, currentSourceFile)); + return !rangeIsOnSingleLine(parentNode, currentSourceFile); } else if (positionIsSynthesized(parentNode.pos) || nodeIsSynthesized(firstChild)) { return synthesizedNodeStartsOnNewLine(firstChild, format); @@ -2551,7 +2552,7 @@ namespace ts { return synthesizedNodeStartsOnNewLine(previousNode, format) || synthesizedNodeStartsOnNewLine(nextNode, format); } else { - return !(rangeEndIsOnSameLineAsRangeStart(previousNode, nextNode, currentSourceFile)); + return !rangeEndIsOnSameLineAsRangeStart(previousNode, nextNode, currentSourceFile); } } else { @@ -2570,13 +2571,13 @@ namespace ts { const lastChild = lastOrUndefined(children); if (lastChild === undefined) { - return !(rangeIsOnSingleLine(parentNode, currentSourceFile)); + return !rangeIsOnSingleLine(parentNode, currentSourceFile); } else if (positionIsSynthesized(parentNode.pos) || nodeIsSynthesized(lastChild)) { return synthesizedNodeStartsOnNewLine(lastChild, format); } else { - return !(rangeEndPositionsAreOnSameLine(parentNode, lastChild, currentSourceFile)); + return !rangeEndPositionsAreOnSameLine(parentNode, lastChild, currentSourceFile); } } else { diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 97ee45aedcc..45aa14bdd2b 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -2,26 +2,6 @@ /// namespace ts { - export const nullTransformationContext: TransformationContext = { - enableEmitNotification: noop, - enableSubstitution: noop, - endLexicalEnvironment: () => undefined, - getCompilerOptions: notImplemented, - getEmitHost: notImplemented, - getEmitResolver: notImplemented, - hoistFunctionDeclaration: noop, - hoistVariableDeclaration: noop, - isEmitNotificationEnabled: notImplemented, - isSubstitutionEnabled: notImplemented, - onEmitNode: noop, - onSubstituteNode: notImplemented, - readEmitHelpers: notImplemented, - requestEmitHelper: noop, - resumeLexicalEnvironment: noop, - startLexicalEnvironment: noop, - suspendLexicalEnvironment: noop - }; - function createSynthesizedNode(kind: SyntaxKind): Node { const node = createNode(kind, -1, -1); node.flags |= NodeFlags.Synthesized; @@ -127,13 +107,18 @@ namespace ts { // Identifiers + export function createIdentifier(text: string): Identifier; + /* @internal */ + export function createIdentifier(text: string, typeArguments: TypeNode[]): Identifier; export function createIdentifier(text: string, typeArguments?: TypeNode[]): Identifier { const node = createSynthesizedNode(SyntaxKind.Identifier); node.text = escapeIdentifier(text); node.originalKeywordKind = text ? stringToToken(text) : SyntaxKind.Unknown; node.autoGenerateKind = GeneratedIdentifierKind.None; node.autoGenerateId = 0; - node.typeArguments = asNodeArray(typeArguments); + if (typeArguments) { + node.typeArguments = createNodeArray(typeArguments); + } return node; } @@ -299,13 +284,13 @@ namespace ts { // Type Elements export function createPropertySignature(modifiers: Modifier[] | undefined, name: PropertyName | string, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined): PropertySignature { - const propertySignature = createSynthesizedNode(SyntaxKind.PropertySignature) as PropertySignature; - propertySignature.modifiers = asNodeArray(modifiers); - propertySignature.name = asName(name); - propertySignature.questionToken = questionToken; - propertySignature.type = type; - propertySignature.initializer = initializer; - return propertySignature; + const node = createSynthesizedNode(SyntaxKind.PropertySignature) as PropertySignature; + node.modifiers = asNodeArray(modifiers); + node.name = asName(name); + node.questionToken = questionToken; + node.type = type; + node.initializer = initializer; + return node; } export function updatePropertySignature(node: PropertySignature, modifiers: Modifier[] | undefined, name: PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression | undefined) { @@ -2494,6 +2479,25 @@ namespace ts { /* @internal */ namespace ts { + export const nullTransformationContext: TransformationContext = { + enableEmitNotification: noop, + enableSubstitution: noop, + endLexicalEnvironment: () => undefined, + getCompilerOptions: notImplemented, + getEmitHost: notImplemented, + getEmitResolver: notImplemented, + hoistFunctionDeclaration: noop, + hoistVariableDeclaration: noop, + isEmitNotificationEnabled: notImplemented, + isSubstitutionEnabled: notImplemented, + onEmitNode: noop, + onSubstituteNode: notImplemented, + readEmitHelpers: notImplemented, + requestEmitHelper: noop, + resumeLexicalEnvironment: noop, + startLexicalEnvironment: noop, + suspendLexicalEnvironment: noop + }; // Compound nodes diff --git a/src/compiler/types.ts b/src/compiler/types.ts index df89120e441..e7e6f9ad1af 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -576,11 +576,11 @@ namespace ts { * If the identifier begins with two underscores, this will begin with three. */ text: string; - originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later + originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later /*@internal*/ autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier. - /*@internal*/ autoGenerateId?: number; // Ensures unique generated identifiers get unique names, but clones get the same name. - isInJSDocNamespace?: boolean; // if the node is a member in a JSDoc namespace - /*@internal*/ typeArguments?: NodeArray; // Only defined on synthesized nodes.Though not syntactically valid, used in emitting diagnostics. + /*@internal*/ autoGenerateId?: number; // Ensures unique generated identifiers get unique names, but clones get the same name. + isInJSDocNamespace?: boolean; // if the node is a member in a JSDoc namespace + /*@internal*/ typeArguments?: NodeArray; // Only defined on synthesized nodes.Though not syntactically valid, used in emitting diagnostics. } // Transient identifier node (marked by id === -1) @@ -2592,14 +2592,14 @@ namespace ts { SuppressAnyReturnType = 1 << 8, // If the return type is any-like, don't offer a return type. // Error handling - allowThisInObjectLiteral = 1 << 10, - allowQualifedNameInPlaceOfIdentifier = 1 << 11, - allowTypeParameterInQualifiedName = 1 << 12, - allowAnonymousIdentifier = 1 << 13, - allowEmptyUnionOrIntersection = 1 << 14, - allowEmptyTuple = 1 << 15, + AllowThisInObjectLiteral = 1 << 10, + AllowQualifedNameInPlaceOfIdentifier = 1 << 11, + AllowTypeParameterInQualifiedName = 1 << 12, + AllowAnonymousIdentifier = 1 << 13, + AllowEmptyUnionOrIntersection = 1 << 14, + AllowEmptyTuple = 1 << 15, - ignoreErrors = allowThisInObjectLiteral | allowQualifedNameInPlaceOfIdentifier | allowTypeParameterInQualifiedName | allowAnonymousIdentifier | allowEmptyUnionOrIntersection | allowEmptyTuple, + ignoreErrors = AllowThisInObjectLiteral | AllowQualifedNameInPlaceOfIdentifier | AllowTypeParameterInQualifiedName | AllowAnonymousIdentifier | AllowEmptyUnionOrIntersection | AllowEmptyTuple, // State inObjectTypeLiteral = 1 << 20, @@ -3538,8 +3538,7 @@ namespace ts { export const enum NewLineKind { CarriageReturnLineFeed = 0, - LineFeed = 1, - None = 2 + LineFeed = 1 } export interface LineAndCharacter { @@ -3964,7 +3963,6 @@ namespace ts { } export const enum EmitFlags { - None = 0, SingleLine = 1 << 0, // The contents of this node should be emitted on a single line. AdviseOnEmitNode = 1 << 1, // The printer should invoke the onEmitNode callback when printing this node. NoSubstitution = 1 << 2, // Disables further substitution of an expression. @@ -4195,7 +4193,7 @@ namespace ts { * the identifiers of the source file are used when generating unique names to avoid * collisions. */ - printNode(hint: EmitHint, node: Node, sourceFile: SourceFile | undefined): string; + printNode(hint: EmitHint, node: Node, sourceFile: SourceFile): string; /** * Prints a source file as-is, without any emit transformations. */ diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index be6b8ccee13..825465085c8 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3253,8 +3253,6 @@ namespace ts { const lineFeed = "\n"; export function getNewLineCharacter(options: CompilerOptions | PrinterOptions): string { switch (options.newLine) { - case NewLineKind.None: - return ""; case NewLineKind.CarriageReturnLineFeed: return carriageReturnLineFeed; case NewLineKind.LineFeed: diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index c9c3a3c48fa..c62af0da794 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -254,6 +254,7 @@ namespace ts { case SyntaxKind.Decorator: return updateDecorator(node, visitNode((node).expression, visitor, isExpression)); + // Type elements case SyntaxKind.PropertySignature: @@ -970,6 +971,15 @@ namespace ts { break; // Type member + + case SyntaxKind.PropertySignature: + result = reduceNodes((node).modifiers, cbNodes, result); + result = reduceNode((node).name, cbNode, result); + result = reduceNode((node).questionToken, cbNode, result); + result = reduceNode((node).type, cbNode, result); + result = reduceNode((node).initializer, cbNode, result); + break; + case SyntaxKind.PropertyDeclaration: result = reduceNodes((node).decorators, cbNodes, result); result = reduceNodes((node).modifiers, cbNodes, result); @@ -978,6 +988,8 @@ namespace ts { result = reduceNode((node).initializer, cbNode, result); break; + case SyntaxKind.PropertySignature: + case SyntaxKind.MethodDeclaration: result = reduceNodes((node).decorators, cbNodes, result); result = reduceNodes((node).modifiers, cbNodes, result); diff --git a/src/services/services.ts b/src/services/services.ts index 43d875cbf7d..ccc9f66e51a 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -360,7 +360,7 @@ namespace ts { _incrementExpressionBrand: any; _unaryExpressionBrand: any; _expressionBrand: any; - typeArguments: any; + /*@internal*/typeArguments: NodeArray; constructor(_kind: SyntaxKind.Identifier, pos: number, end: number) { super(pos, end); }