diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 62308cbfbbf..9d6fa60306c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25271,7 +25271,18 @@ namespace ts { } function checkExpressionWorker(node: Expression | QualifiedName, checkMode: CheckMode | undefined, forceTuple?: boolean): Type { - switch (node.kind) { + const kind = node.kind; + if (cancellationToken) { + // Only bother checking on a few construct kinds. We don't want to be excessively + // hitting the cancellation token on every node we check. + switch (kind) { + case SyntaxKind.ClassExpression: + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + cancellationToken.throwIfCancellationRequested(); + } + } + switch (kind) { case SyntaxKind.Identifier: return checkIdentifier(node); case SyntaxKind.ThisKeyword: diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 8678ba4c122..d0d617b3495 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1329,27 +1329,97 @@ namespace ts { : node; } - export function createTemplateHead(text: string) { - const node = createSynthesizedNode(SyntaxKind.TemplateHead); + let rawTextScanner: Scanner | undefined; + const invalidValueSentinel: object = {}; + + function getCookedText(kind: TemplateLiteralToken["kind"], rawText: string) { + if (!rawTextScanner) { + rawTextScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.Standard); + } + switch (kind) { + case SyntaxKind.NoSubstitutionTemplateLiteral: + rawTextScanner.setText("`" + rawText + "`"); + break; + case SyntaxKind.TemplateHead: + // tslint:disable-next-line no-invalid-template-strings + rawTextScanner.setText("`" + rawText + "${"); + break; + case SyntaxKind.TemplateMiddle: + // tslint:disable-next-line no-invalid-template-strings + rawTextScanner.setText("}" + rawText + "${"); + break; + case SyntaxKind.TemplateTail: + rawTextScanner.setText("}" + rawText + "`"); + break; + } + + let token = rawTextScanner.scan(); + if (token === SyntaxKind.CloseBracketToken) { + token = rawTextScanner.reScanTemplateToken(); + } + + if (rawTextScanner.isUnterminated()) { + rawTextScanner.setText(undefined); + return invalidValueSentinel; + } + + let tokenValue: string | undefined; + switch (token) { + case SyntaxKind.NoSubstitutionTemplateLiteral: + case SyntaxKind.TemplateHead: + case SyntaxKind.TemplateMiddle: + case SyntaxKind.TemplateTail: + tokenValue = rawTextScanner.getTokenValue(); + break; + } + + if (rawTextScanner.scan() !== SyntaxKind.EndOfFileToken) { + rawTextScanner.setText(undefined); + return invalidValueSentinel; + } + + rawTextScanner.setText(undefined); + return tokenValue; + } + + function createTemplateLiteralLikeNode(kind: TemplateLiteralToken["kind"], text: string, rawText: string | undefined) { + const node = createSynthesizedNode(kind); + node.text = text; + if (rawText === undefined || text === rawText) { + node.rawText = rawText; + } + else { + const cooked = getCookedText(kind, rawText); + if (typeof cooked === "object") { + return Debug.fail("Invalid raw text"); + } + + Debug.assert(text === cooked, "Expected argument 'text' to be the normalized (i.e. 'cooked') version of argument 'rawText'."); + node.rawText = rawText; + } + return node; + } + + export function createTemplateHead(text: string, rawText?: string) { + const node = createTemplateLiteralLikeNode(SyntaxKind.TemplateHead, text, rawText); node.text = text; return node; } - export function createTemplateMiddle(text: string) { - const node = createSynthesizedNode(SyntaxKind.TemplateMiddle); + export function createTemplateMiddle(text: string, rawText?: string) { + const node = createTemplateLiteralLikeNode(SyntaxKind.TemplateMiddle, text, rawText); node.text = text; return node; } - export function createTemplateTail(text: string) { - const node = createSynthesizedNode(SyntaxKind.TemplateTail); + export function createTemplateTail(text: string, rawText?: string) { + const node = createTemplateLiteralLikeNode(SyntaxKind.TemplateTail, text, rawText); node.text = text; return node; } - export function createNoSubstitutionTemplateLiteral(text: string) { - const node = createSynthesizedNode(SyntaxKind.NoSubstitutionTemplateLiteral); - node.text = text; + export function createNoSubstitutionTemplateLiteral(text: string, rawText?: string) { + const node = createTemplateLiteralLikeNode(SyntaxKind.NoSubstitutionTemplateLiteral, text, rawText); return node; } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 6451a4f5c96..3ce7f411e24 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2300,9 +2300,19 @@ namespace ts { return fragment; } - function parseLiteralLikeNode(kind: SyntaxKind): LiteralExpression | LiteralLikeNode { - const node = createNode(kind); + function parseLiteralLikeNode(kind: SyntaxKind): LiteralLikeNode { + const node = createNode(kind); node.text = scanner.getTokenValue(); + switch (kind) { + case SyntaxKind.NoSubstitutionTemplateLiteral: + case SyntaxKind.TemplateHead: + case SyntaxKind.TemplateMiddle: + case SyntaxKind.TemplateTail: + const isLast = kind === SyntaxKind.NoSubstitutionTemplateLiteral || kind === SyntaxKind.TemplateTail; + const tokenText = scanner.getTokenText(); + (node).rawText = tokenText.substring(1, tokenText.length - (scanner.isUnterminated() ? 0 : isLast ? 1 : 2)); + break; + } if (scanner.hasExtendedUnicodeEscape()) { node.hasExtendedUnicodeEscape = true; diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 793f6e1b1ef..b86db737879 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -3993,18 +3993,21 @@ namespace ts { * * @param node The ES6 template literal. */ - function getRawLiteral(node: LiteralLikeNode) { + function getRawLiteral(node: TemplateLiteralLikeNode) { // Find original source text, since we need to emit the raw strings of the tagged template. // The raw strings contain the (escaped) strings of what the user wrote. // Examples: `\n` is converted to "\\n", a template string with a newline to "\n". - let text = getSourceTextOfNodeFromSourceFile(currentSourceFile, node); + let text = node.rawText; + if (text === undefined) { + text = getSourceTextOfNodeFromSourceFile(currentSourceFile, node); - // text contains the original source, it will also contain quotes ("`"), dolar signs and braces ("${" and "}"), - // thus we need to remove those characters. - // First template piece starts with "`", others with "}" - // Last template piece ends with "`", others with "${" - const isLast = node.kind === SyntaxKind.NoSubstitutionTemplateLiteral || node.kind === SyntaxKind.TemplateTail; - text = text.substring(1, text.length - (isLast ? 1 : 2)); + // text contains the original source, it will also contain quotes ("`"), dolar signs and braces ("${" and "}"), + // thus we need to remove those characters. + // First template piece starts with "`", others with "}" + // Last template piece ends with "`", others with "${" + const isLast = node.kind === SyntaxKind.NoSubstitutionTemplateLiteral || node.kind === SyntaxKind.TemplateTail; + text = text.substring(1, text.length - (isLast ? 1 : 2)); + } // Newline normalization: // ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a4373b7dc01..f50eb4d6399 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1646,6 +1646,10 @@ namespace ts { hasExtendedUnicodeEscape?: boolean; } + export interface TemplateLiteralLikeNode extends LiteralLikeNode { + rawText?: string; + } + // The text property of a LiteralExpression stores the interpreted value of the literal in text form. For a StringLiteral, // or any literal of a template, this means quotes have been removed and escapes have been converted to actual characters. // For a NumericLiteral, the stored value is the toString() representation of the number. For example 1, 1.00, and 1e0 are all stored as just "1". @@ -1657,7 +1661,7 @@ namespace ts { kind: SyntaxKind.RegularExpressionLiteral; } - export interface NoSubstitutionTemplateLiteral extends LiteralExpression { + export interface NoSubstitutionTemplateLiteral extends LiteralExpression, TemplateLiteralLikeNode { kind: SyntaxKind.NoSubstitutionTemplateLiteral; } @@ -1696,17 +1700,17 @@ namespace ts { kind: SyntaxKind.BigIntLiteral; } - export interface TemplateHead extends LiteralLikeNode { + export interface TemplateHead extends TemplateLiteralLikeNode { kind: SyntaxKind.TemplateHead; parent: TemplateExpression; } - export interface TemplateMiddle extends LiteralLikeNode { + export interface TemplateMiddle extends TemplateLiteralLikeNode { kind: SyntaxKind.TemplateMiddle; parent: TemplateSpan; } - export interface TemplateTail extends LiteralLikeNode { + export interface TemplateTail extends TemplateLiteralLikeNode { kind: SyntaxKind.TemplateTail; parent: TemplateSpan; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 0bb3c799af5..96acefdf135 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -566,8 +566,6 @@ namespace ts { return emitNode && emitNode.flags || 0; } - const escapeNoSubstitutionTemplateLiteralText = compose(escapeString, escapeTemplateSubstitution); - const escapeNonAsciiNoSubstitutionTemplateLiteralText = compose(escapeNonAsciiString, escapeTemplateSubstitution); export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile, neverAsciiEscape: boolean | undefined) { // If we don't need to downlevel and we can reach the original source text using // the node's parent reference, then simply get the text as it was originally written. @@ -580,9 +578,7 @@ namespace ts { // If a NoSubstitutionTemplateLiteral appears to have a substitution in it, the original text // had to include a backslash: `not \${a} substitution`. - const escapeText = neverAsciiEscape || (getEmitFlags(node) & EmitFlags.NoAsciiEscaping) ? - node.kind === SyntaxKind.NoSubstitutionTemplateLiteral ? escapeNoSubstitutionTemplateLiteralText : escapeString : - node.kind === SyntaxKind.NoSubstitutionTemplateLiteral ? escapeNonAsciiNoSubstitutionTemplateLiteralText : escapeNonAsciiString; + const escapeText = neverAsciiEscape || (getEmitFlags(node) & EmitFlags.NoAsciiEscaping) ? escapeString : escapeNonAsciiString; // If we can't reach the original source text, use the canonical form if it's a number, // or a (possibly escaped) quoted form of the original text if it's string-like. @@ -595,15 +591,23 @@ namespace ts { return '"' + escapeText(node.text, CharacterCodes.doubleQuote) + '"'; } case SyntaxKind.NoSubstitutionTemplateLiteral: - return "`" + escapeText(node.text, CharacterCodes.backtick) + "`"; case SyntaxKind.TemplateHead: - // tslint:disable-next-line no-invalid-template-strings - return "`" + escapeText(node.text, CharacterCodes.backtick) + "${"; case SyntaxKind.TemplateMiddle: - // tslint:disable-next-line no-invalid-template-strings - return "}" + escapeText(node.text, CharacterCodes.backtick) + "${"; case SyntaxKind.TemplateTail: - return "}" + escapeText(node.text, CharacterCodes.backtick) + "`"; + const rawText = (node).rawText || escapeTemplateSubstitution(escapeText(node.text, CharacterCodes.backtick)); + switch (node.kind) { + case SyntaxKind.NoSubstitutionTemplateLiteral: + return "`" + rawText + "`"; + case SyntaxKind.TemplateHead: + // tslint:disable-next-line no-invalid-template-strings + return "`" + rawText + "${"; + case SyntaxKind.TemplateMiddle: + // tslint:disable-next-line no-invalid-template-strings + return "}" + rawText + "${"; + case SyntaxKind.TemplateTail: + return "}" + rawText + "`"; + } + break; case SyntaxKind.NumericLiteral: case SyntaxKind.BigIntLiteral: case SyntaxKind.RegularExpressionLiteral: @@ -3178,7 +3182,8 @@ namespace ts { // There is no reason for this other than that JSON.stringify does not handle it either. const doubleQuoteEscapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; const singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; - const backtickQuoteEscapedCharsRegExp = /[\\\`\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; + // Template strings should be preserved as much as possible + const backtickQuoteEscapedCharsRegExp = /[\\\`]/g; const escapedCharsMap = createMapFromTemplate({ "\t": "\\t", "\v": "\\v", diff --git a/src/harness/evaluator.ts b/src/harness/evaluator.ts index a22bdb958bc..c4cfc53069c 100644 --- a/src/harness/evaluator.ts +++ b/src/harness/evaluator.ts @@ -2,6 +2,7 @@ namespace evaluator { declare var Symbol: SymbolConstructor; const sourceFile = vpath.combine(vfs.srcFolder, "source.ts"); + const sourceFileJs = vpath.combine(vfs.srcFolder, "source.js"); function compile(sourceText: string, options?: ts.CompilerOptions) { const fs = vfs.createFromFileSystem(Harness.IO, /*ignoreCase*/ false); @@ -32,9 +33,8 @@ namespace evaluator { // Add "asyncIterator" if missing if (!ts.hasProperty(FakeSymbol, "asyncIterator")) Object.defineProperty(FakeSymbol, "asyncIterator", { value: Symbol.for("Symbol.asyncIterator"), configurable: true }); - function evaluate(result: compiler.CompilationResult, globals?: Record) { - globals = { Symbol: FakeSymbol, ...globals }; - + export function evaluateTypeScript(sourceText: string, options?: ts.CompilerOptions, globals?: Record) { + const result = compile(sourceText, options); if (ts.some(result.diagnostics)) { assert.ok(/*value*/ false, "Syntax error in evaluation source text:\n" + ts.formatDiagnostics(result.diagnostics, { getCanonicalFileName: file => file, @@ -46,6 +46,12 @@ namespace evaluator { const output = result.getOutput(sourceFile, "js")!; assert.isDefined(output); + return evaluateJavaScript(output.text, globals, output.file); + } + + export function evaluateJavaScript(sourceText: string, globals?: Record, sourceFile = sourceFileJs) { + globals = { Symbol: FakeSymbol, ...globals }; + const globalNames: string[] = []; const globalArgs: any[] = []; for (const name in globals) { @@ -55,15 +61,11 @@ namespace evaluator { } } - const evaluateText = `(function (module, exports, require, __dirname, __filename, ${globalNames.join(", ")}) { ${output.text} })`; - // tslint:disable-next-line:no-eval - const evaluateThunk = eval(evaluateText) as (module: any, exports: any, require: (id: string) => any, dirname: string, filename: string, ...globalArgs: any[]) => void; + const evaluateText = `(function (module, exports, require, __dirname, __filename, ${globalNames.join(", ")}) { ${sourceText} })`; + // tslint:disable-next-line:no-eval no-unused-expression + const evaluateThunk = (void 0, eval)(evaluateText) as (module: any, exports: any, require: (id: string) => any, dirname: string, filename: string, ...globalArgs: any[]) => void; const module: { exports: any; } = { exports: {} }; - evaluateThunk.call(globals, module, module.exports, noRequire, vpath.dirname(output.file), output.file, FakeSymbol, ...globalArgs); + evaluateThunk.call(globals, module, module.exports, noRequire, vpath.dirname(sourceFile), sourceFile, FakeSymbol, ...globalArgs); return module.exports; } - - export function evaluateTypeScript(sourceText: string, options?: ts.CompilerOptions, globals?: Record) { - return evaluate(compile(sourceText, options), globals); - } } \ No newline at end of file diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index a25256a3aec..9fd15333cc9 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -2705,8 +2705,6 @@ namespace ts.server { // It was then postponed to cleanup these script infos so that they can be reused if // the file from that old project is reopened because of opening file from here. this.removeOrphanScriptInfos(); - - this.printProjects(); } openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult { @@ -2714,6 +2712,7 @@ namespace ts.server { const { defaultConfigProject, ...result } = this.assignProjectToOpenedScriptInfo(info); this.cleanupAfterOpeningFile(defaultConfigProject); this.telemetryOnOpenFile(info); + this.printProjects(); return result; } @@ -2914,12 +2913,16 @@ namespace ts.server { this.assignOrphanScriptInfosToInferredProject(); } - // Cleanup projects - this.cleanupAfterOpeningFile(defaultConfigProjects); - - // Telemetry - forEach(openScriptInfos, info => this.telemetryOnOpenFile(info)); - this.printProjects(); + if (openScriptInfos) { + // Cleanup projects + this.cleanupAfterOpeningFile(defaultConfigProjects); + // Telemetry + openScriptInfos.forEach(info => this.telemetryOnOpenFile(info)); + this.printProjects(); + } + else if (length(closedFiles)) { + this.printProjects(); + } } /* @internal */ diff --git a/src/services/completions.ts b/src/services/completions.ts index e9a38fb1516..bf7ff041f2d 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1566,7 +1566,7 @@ namespace ts.Completions { // If you're in an interface you don't want to repeat things from super-interface. So just stop here. if (!isClassLike(decl)) return GlobalsSearch.Success; - const classElement = contextToken.parent; + const classElement = contextToken.kind === SyntaxKind.SemicolonToken ? contextToken.parent.parent : contextToken.parent; let classElementModifierFlags = isClassElement(classElement) ? getModifierFlags(classElement) : ModifierFlags.None; // If this is context token is not something we are editing now, consider if this would lead to be modifier if (contextToken.kind === SyntaxKind.Identifier && !isCurrentlyEditingNode(contextToken)) { diff --git a/src/testRunner/unittests/transform.ts b/src/testRunner/unittests/transform.ts index 376b7d16ec8..35c3ab9a942 100644 --- a/src/testRunner/unittests/transform.ts +++ b/src/testRunner/unittests/transform.ts @@ -67,6 +67,24 @@ namespace ts { }); } + function testBaselineAndEvaluate(testName: string, test: () => string, onEvaluate: (exports: any) => void) { + describe(testName, () => { + let sourceText!: string; + before(() => { + sourceText = test(); + }); + after(() => { + sourceText = undefined!; + }); + it("compare baselines", () => { + Harness.Baseline.runBaseline(`transformApi/transformsCorrectly.${testName}.js`, sourceText); + }); + it("evaluate", () => { + onEvaluate(evaluator.evaluateJavaScript(sourceText)); + }); + }); + } + testBaseline("substitution", () => { return transformSourceFile(`var a = undefined;`, [replaceUndefinedWithVoid0]); }); @@ -440,6 +458,31 @@ namespace Foo { }); + testBaselineAndEvaluate("templateSpans", () => { + return transpileModule("const x = String.raw`\n\nhello`; exports.stringLength = x.trim().length;", { + compilerOptions: { + target: ScriptTarget.ESNext, + newLine: NewLineKind.CarriageReturnLineFeed, + }, + transformers: { + before: [transformSourceFile] + } + }).outputText; + + function transformSourceFile(context: TransformationContext): Transformer { + function visitor(node: Node): VisitResult { + if (isNoSubstitutionTemplateLiteral(node)) { + return createNoSubstitutionTemplateLiteral(node.text, node.rawText); + } + else { + return visitEachChild(node, visitor, context); + } + } + return sourceFile => visitNode(sourceFile, visitor, isSourceFile); + } + }, exports => { + assert.equal(exports.stringLength, 5); + }); }); } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 4c88e5fe219..c877d7d2d9a 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -997,13 +997,16 @@ declare namespace ts { isUnterminated?: boolean; hasExtendedUnicodeEscape?: boolean; } + export interface TemplateLiteralLikeNode extends LiteralLikeNode { + rawText?: string; + } export interface LiteralExpression extends LiteralLikeNode, PrimaryExpression { _literalExpressionBrand: any; } export interface RegularExpressionLiteral extends LiteralExpression { kind: SyntaxKind.RegularExpressionLiteral; } - export interface NoSubstitutionTemplateLiteral extends LiteralExpression { + export interface NoSubstitutionTemplateLiteral extends LiteralExpression, TemplateLiteralLikeNode { kind: SyntaxKind.NoSubstitutionTemplateLiteral; } export enum TokenFlags { @@ -1020,15 +1023,15 @@ declare namespace ts { export interface BigIntLiteral extends LiteralExpression { kind: SyntaxKind.BigIntLiteral; } - export interface TemplateHead extends LiteralLikeNode { + export interface TemplateHead extends TemplateLiteralLikeNode { kind: SyntaxKind.TemplateHead; parent: TemplateExpression; } - export interface TemplateMiddle extends LiteralLikeNode { + export interface TemplateMiddle extends TemplateLiteralLikeNode { kind: SyntaxKind.TemplateMiddle; parent: TemplateSpan; } - export interface TemplateTail extends LiteralLikeNode { + export interface TemplateTail extends TemplateLiteralLikeNode { kind: SyntaxKind.TemplateTail; parent: TemplateSpan; } @@ -3921,10 +3924,10 @@ declare namespace ts { function updateConditional(node: ConditionalExpression, condition: Expression, questionToken: Token, whenTrue: Expression, colonToken: Token, whenFalse: Expression): ConditionalExpression; function createTemplateExpression(head: TemplateHead, templateSpans: ReadonlyArray): TemplateExpression; function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: ReadonlyArray): TemplateExpression; - function createTemplateHead(text: string): TemplateHead; - function createTemplateMiddle(text: string): TemplateMiddle; - function createTemplateTail(text: string): TemplateTail; - function createNoSubstitutionTemplateLiteral(text: string): NoSubstitutionTemplateLiteral; + function createTemplateHead(text: string, rawText?: string): TemplateHead; + function createTemplateMiddle(text: string, rawText?: string): TemplateMiddle; + function createTemplateTail(text: string, rawText?: string): TemplateTail; + function createNoSubstitutionTemplateLiteral(text: string, rawText?: string): NoSubstitutionTemplateLiteral; function createYield(expression?: Expression): YieldExpression; function createYield(asteriskToken: AsteriskToken | undefined, expression: Expression): YieldExpression; function updateYield(node: YieldExpression, asteriskToken: AsteriskToken | undefined, expression: Expression): YieldExpression; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index bb30ccc908d..4c28abcbbc3 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -997,13 +997,16 @@ declare namespace ts { isUnterminated?: boolean; hasExtendedUnicodeEscape?: boolean; } + export interface TemplateLiteralLikeNode extends LiteralLikeNode { + rawText?: string; + } export interface LiteralExpression extends LiteralLikeNode, PrimaryExpression { _literalExpressionBrand: any; } export interface RegularExpressionLiteral extends LiteralExpression { kind: SyntaxKind.RegularExpressionLiteral; } - export interface NoSubstitutionTemplateLiteral extends LiteralExpression { + export interface NoSubstitutionTemplateLiteral extends LiteralExpression, TemplateLiteralLikeNode { kind: SyntaxKind.NoSubstitutionTemplateLiteral; } export enum TokenFlags { @@ -1020,15 +1023,15 @@ declare namespace ts { export interface BigIntLiteral extends LiteralExpression { kind: SyntaxKind.BigIntLiteral; } - export interface TemplateHead extends LiteralLikeNode { + export interface TemplateHead extends TemplateLiteralLikeNode { kind: SyntaxKind.TemplateHead; parent: TemplateExpression; } - export interface TemplateMiddle extends LiteralLikeNode { + export interface TemplateMiddle extends TemplateLiteralLikeNode { kind: SyntaxKind.TemplateMiddle; parent: TemplateSpan; } - export interface TemplateTail extends LiteralLikeNode { + export interface TemplateTail extends TemplateLiteralLikeNode { kind: SyntaxKind.TemplateTail; parent: TemplateSpan; } @@ -3921,10 +3924,10 @@ declare namespace ts { function updateConditional(node: ConditionalExpression, condition: Expression, questionToken: Token, whenTrue: Expression, colonToken: Token, whenFalse: Expression): ConditionalExpression; function createTemplateExpression(head: TemplateHead, templateSpans: ReadonlyArray): TemplateExpression; function updateTemplateExpression(node: TemplateExpression, head: TemplateHead, templateSpans: ReadonlyArray): TemplateExpression; - function createTemplateHead(text: string): TemplateHead; - function createTemplateMiddle(text: string): TemplateMiddle; - function createTemplateTail(text: string): TemplateTail; - function createNoSubstitutionTemplateLiteral(text: string): NoSubstitutionTemplateLiteral; + function createTemplateHead(text: string, rawText?: string): TemplateHead; + function createTemplateMiddle(text: string, rawText?: string): TemplateMiddle; + function createTemplateTail(text: string, rawText?: string): TemplateTail; + function createNoSubstitutionTemplateLiteral(text: string, rawText?: string): NoSubstitutionTemplateLiteral; function createYield(expression?: Expression): YieldExpression; function createYield(asteriskToken: AsteriskToken | undefined, expression: Expression): YieldExpression; function updateYield(node: YieldExpression, asteriskToken: AsteriskToken | undefined, expression: Expression): YieldExpression; diff --git a/tests/baselines/reference/docker/azure-sdk.log b/tests/baselines/reference/docker/azure-sdk.log index 2a870effa9b..2c8c866ea20 100644 --- a/tests/baselines/reference/docker/azure-sdk.log +++ b/tests/baselines/reference/docker/azure-sdk.log @@ -2,94 +2,153 @@ Exit Code: 1 Standard output: Rush Multi-Project Build Tool 5.X.X - https://rushjs.io -Node.js version is 12.7.0 (pre-LTS) +Node.js version is 12.8.0 (pre-LTS) Starting "rush rebuild" Executing a maximum of ?simultaneous processes... +XX of XX: [@azure/identity] completed successfully in ? seconds +XX of XX: [@azure/event-processor-host] completed successfully in ? seconds +XX of XX: [@azure/abort-controller] completed successfully in ? seconds +XX of XX: [@azure/core-arm] completed successfully in ? seconds +XX of XX: [@azure/core-asynciterator-polyfill] completed successfully in ? seconds +XX of XX: [@azure/core-auth] completed successfully in ? seconds npm ERR! code ELIFECYCLE npm ERR! errno 2 -npm ERR! @azure/core-http@X.X.X-preview.2 build:tsc: `tsc -p tsconfig.es.json` +npm ERR! @azure/core-http@X.X.X-preview.3 build:tsc: `tsc -p tsconfig.es.json` npm ERR! Exit status 2 npm ERR! -npm ERR! Failed at the @azure/core-http@X.X.X-preview.2 build:tsc script. +npm ERR! Failed at the @azure/core-http@X.X.X-preview.3 build:tsc script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log ERROR: "build:tsc" exited with 2. npm ERR! code ELIFECYCLE npm ERR! errno 1 -npm ERR! @azure/core-http@X.X.X-preview.2 build:lib: `run-s build:tsc build:rollup build:minify-browser` +npm ERR! @azure/core-http@X.X.X-preview.3 build:lib: `run-s build:tsc build:rollup build:minify-browser` npm ERR! Exit status 1 npm ERR! -npm ERR! Failed at the @azure/core-http@X.X.X-preview.2 build:lib script. +npm ERR! Failed at the @azure/core-http@X.X.X-preview.3 build:lib script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log ERROR: "build:lib" exited with 1. -XX of XX: [@azure/core-tracing] completed successfully in ? seconds -XX of XX: [@azure/event-processor-host] completed successfully in ? seconds -XX of XX: [@azure/abort-controller] completed successfully in ? seconds -XX of XX: [@azure/core-asynciterator-polyfill] completed successfully in ? seconds -XX of XX: [@azure/core-auth] completed successfully in ? seconds XX of XX: [@azure/core-paging] completed successfully in ? seconds +XX of XX: [@azure/core-tracing] completed successfully in ? seconds XX of XX: [@azure/cosmos] completed successfully in ? seconds -Warning: You have changed the public API signature for this project. Updating review/service-bus.api.md +npm ERR! code ELIFECYCLE +npm ERR! errno 2 +npm ERR! @azure/keyvault-certificates@X.X.X extract-api: `tsc -p . && api-extractor run --local` +npm ERR! Exit status 2 +npm ERR! +npm ERR! Failed at the @azure/keyvault-certificates@X.X.X extract-api script. +npm ERR! This is probably not a problem with npm. There is likely additional logging output above. +npm ERR! A complete log of this run can be found in: +npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log +npm ERR! code ELIFECYCLE +npm ERR! errno 2 +npm ERR! @azure/keyvault-keys@X.X.X-preview.3 extract-api: `tsc -p . && api-extractor run --local` +npm ERR! Exit status 2 +npm ERR! +npm ERR! Failed at the @azure/keyvault-keys@X.X.X-preview.3 extract-api script. +npm ERR! This is probably not a problem with npm. There is likely additional logging output above. +npm ERR! A complete log of this run can be found in: +npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log +npm ERR! code ELIFECYCLE +npm ERR! errno 2 +npm ERR! @azure/keyvault-secrets@X.X.X-preview.4 extract-api: `tsc -p . && api-extractor run --local` +npm ERR! Exit status 2 +npm ERR! +npm ERR! Failed at the @azure/keyvault-secrets@X.X.X-preview.4 extract-api script. +npm ERR! This is probably not a problem with npm. There is likely additional logging output above. +npm ERR! A complete log of this run can be found in: +npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log +XX of XX: [@azure/service-bus] completed successfully in ? seconds XX of XX: [@azure/storage-blob] completed successfully in ? seconds XX of XX: [@azure/storage-file] completed successfully in ? seconds XX of XX: [@azure/storage-queue] completed successfully in ? seconds +XX of XX: [@azure/template] completed successfully in ? seconds XX of XX: [testhub] completed successfully in ? seconds -SUCCESS (11) +SUCCESS (15) ================================ @azure/abort-controller (? seconds) +@azure/core-arm (? seconds) @azure/core-asynciterator-polyfill (? seconds) @azure/core-auth (? seconds) @azure/core-paging (? seconds) @azure/core-tracing (? seconds) @azure/cosmos (? seconds) @azure/event-processor-host (? seconds) +@azure/identity (? seconds) +@azure/service-bus (? seconds) @azure/storage-blob (? seconds) @azure/storage-file (? seconds) @azure/storage-queue (? seconds) +@azure/template (? seconds) testhub (? seconds) ================================ -SUCCESS WITH WARNINGS (1) +BLOCKED (1) ================================ -@azure/service-bus (? seconds) -Warning: You have changed the public API signature for this project. Updating review/service-bus.api.md -================================ -BLOCKED (8) -================================ -@azure/core-amqp -@azure/core-arm @azure/event-hubs -@azure/identity -@azure/keyvault-certificates -@azure/keyvault-keys -@azure/keyvault-secrets -@azure/template ================================ -FAILURE (1) +FAILURE (5) ================================ +@azure/core-amqp ( ? seconds) +>>> @azure/core-amqp +tsc -p . && rollup -c 2>&1 +src/errors.ts(580,20): error TS7053: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof ConditionErrorNameMapper'. +src/errors.ts(604,34): error TS7053: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof SystemErrorConditionMapper'. +src/errors.ts(605,20): error TS7053: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'typeof ConditionErrorNameMapper'. +src/shims.d.ts(14,13): error TS2403: Subsequent variable declarations must have the same type. Variable 'window' must be of type 'Window & typeof globalThis', but here has type 'Window'. @azure/core-http ( ? seconds) npm ERR! code ELIFECYCLE npm ERR! errno 2 -npm ERR! @azure/core-http@X.X.X-preview.2 build:tsc: `tsc -p tsconfig.es.json` +npm ERR! @azure/core-http@X.X.X-preview.3 build:tsc: `tsc -p tsconfig.es.json` npm ERR! Exit status 2 npm ERR! -npm ERR! Failed at the @azure/core-http@X.X.X-preview.2 build:tsc script. +npm ERR! Failed at the @azure/core-http@X.X.X-preview.3 build:tsc script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log ERROR: "build:tsc" exited with 2. npm ERR! code ELIFECYCLE npm ERR! errno 1 -npm ERR! @azure/core-http@X.X.X-preview.2 build:lib: `run-s build:tsc build:rollup build:minify-browser` +npm ERR! @azure/core-http@X.X.X-preview.3 build:lib: `run-s build:tsc build:rollup build:minify-browser` npm ERR! Exit status 1 npm ERR! -npm ERR! Failed at the @azure/core-http@X.X.X-preview.2 build:lib script. +npm ERR! Failed at the @azure/core-http@X.X.X-preview.3 build:lib script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above. npm ERR! A complete log of this run can be found in: npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log ERROR: "build:lib" exited with 1. +@azure/keyvault-certificates ( ? seconds) +npm ERR! code ELIFECYCLE +npm ERR! errno 2 +npm ERR! @azure/keyvault-certificates@X.X.X extract-api: `tsc -p . && api-extractor run --local` +npm ERR! Exit status 2 +npm ERR! +npm ERR! Failed at the @azure/keyvault-certificates@X.X.X extract-api script. +npm ERR! This is probably not a problem with npm. There is likely additional logging output above. +npm ERR! A complete log of this run can be found in: +npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log +@azure/keyvault-keys ( ? seconds) +npm ERR! code ELIFECYCLE +npm ERR! errno 2 +npm ERR! @azure/keyvault-keys@X.X.X-preview.3 extract-api: `tsc -p . && api-extractor run --local` +npm ERR! Exit status 2 +npm ERR! +npm ERR! Failed at the @azure/keyvault-keys@X.X.X-preview.3 extract-api script. +npm ERR! This is probably not a problem with npm. There is likely additional logging output above. +npm ERR! A complete log of this run can be found in: +npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log +@azure/keyvault-secrets ( ? seconds) +npm ERR! code ELIFECYCLE +npm ERR! errno 2 +npm ERR! @azure/keyvault-secrets@X.X.X-preview.4 extract-api: `tsc -p . && api-extractor run --local` +npm ERR! Exit status 2 +npm ERR! +npm ERR! Failed at the @azure/keyvault-secrets@X.X.X-preview.4 extract-api script. +npm ERR! This is probably not a problem with npm. There is likely additional logging output above. +npm ERR! A complete log of this run can be found in: +npm ERR! /root/.npm/_logs/XXXX-XX-XXXXXXXXX-debug.log ================================ Error: Project(s) failed to build rush rebuild - Errors! ( ? seconds) @@ -98,14 +157,14 @@ rush rebuild - Errors! ( ? seconds) Standard error: +XX of XX: [@azure/core-amqp] failed to build! +XX of XX: [@azure/event-hubs] blocked by [@azure/core-amqp]! XX of XX: [@azure/core-http] failed to build! -XX of XX: [@azure/core-arm] blocked by [@azure/core-http]! -XX of XX: [@azure/keyvault-certificates] blocked by [@azure/core-http]! -XX of XX: [@azure/keyvault-keys] blocked by [@azure/core-http]! -XX of XX: [@azure/keyvault-secrets] blocked by [@azure/core-http]! -XX of XX: [@azure/identity] blocked by [@azure/core-http]! -XX of XX: [@azure/core-amqp] blocked by [@azure/core-http]! -XX of XX: [@azure/event-hubs] blocked by [@azure/core-http]! -XX of XX: [@azure/template] blocked by [@azure/core-http]! -XX of XX: [@azure/service-bus] completed with warnings in ? seconds +XX of XX: [@azure/keyvault-certificates] failed to build! +XX of XX: [@azure/keyvault-keys] failed to build! +XX of XX: [@azure/keyvault-secrets] failed to build! +[@azure/core-amqp] Returned error code: 2 [@azure/core-http] Returned error code: 1 +[@azure/keyvault-certificates] Returned error code: 2 +[@azure/keyvault-keys] Returned error code: 2 +[@azure/keyvault-secrets] Returned error code: 2 diff --git a/tests/baselines/reference/docker/office-ui-fabric.log b/tests/baselines/reference/docker/office-ui-fabric.log index 440a14e9044..506e180a5b8 100644 --- a/tests/baselines/reference/docker/office-ui-fabric.log +++ b/tests/baselines/reference/docker/office-ui-fabric.log @@ -426,7 +426,7 @@ lerna info Executing command in 40 packages: "yarn run build --production --lint @uifabric/foundation: [XX:XX:XX XM] x Error: Command failed: /usr/local/bin/node /office-ui-fabric-react/node_modules/jest/bin/jest.js --config /office-ui-fabric-react/packages/foundation/jest.config.js --passWithNoTests --colors @uifabric/foundation: at ChildProcess. (/office-ui-fabric-react/node_modules/just-scripts-utils/lib/exec.js:70:31) @uifabric/foundation: at ChildProcess.emit (events.js:203:13) -@uifabric/foundation: at ChildProcess.EventEmitter.emit (domain.js:494:23) +@uifabric/foundation: at ChildProcess.EventEmitter.emit (domain.js:499:23) @uifabric/foundation: at Process.ChildProcess._handle.onexit (internal/child_process.js:272:12) @uifabric/foundation: [XX:XX:XX XM] x ------------------------------------ @uifabric/foundation: [XX:XX:XX XM] x Error previously detected. See above for error messages. diff --git a/tests/baselines/reference/transformApi/transformsCorrectly.templateSpans.js b/tests/baselines/reference/transformApi/transformsCorrectly.templateSpans.js new file mode 100644 index 00000000000..00c8f992444 --- /dev/null +++ b/tests/baselines/reference/transformApi/transformsCorrectly.templateSpans.js @@ -0,0 +1,4 @@ +const x = String.raw ` + +hello`; +exports.stringLength = x.trim().length; diff --git a/tests/baselines/reference/user/TypeScript-React-Native-Starter.log b/tests/baselines/reference/user/TypeScript-React-Native-Starter.log index 87439a7c4e6..51763a2b4b8 100644 --- a/tests/baselines/reference/user/TypeScript-React-Native-Starter.log +++ b/tests/baselines/reference/user/TypeScript-React-Native-Starter.log @@ -3,7 +3,7 @@ Standard output: node_modules/@types/react-native/index.d.ts(3425,42): error TS2583: Cannot find name 'Map'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later. node_modules/@types/react-native/index.d.ts(3438,42): error TS2583: Cannot find name 'Map'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later. node_modules/@types/react-native/index.d.ts(8745,18): error TS2717: Subsequent property declarations must have the same type. Property 'geolocation' must be of type 'Geolocation', but here has type 'GeolocationStatic'. -node_modules/@types/react/index.d.ts(377,23): error TS2583: Cannot find name 'Set'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later. +node_modules/@types/react/index.d.ts(369,23): error TS2583: Cannot find name 'Set'. Do you need to change your target library? Try changing the `lib` compiler option to es2015 or later. diff --git a/tests/baselines/reference/user/async.log b/tests/baselines/reference/user/async.log index 18fb7988358..a64d3b22cb5 100644 --- a/tests/baselines/reference/user/async.log +++ b/tests/baselines/reference/user/async.log @@ -51,8 +51,6 @@ node_modules/async/autoInject.js(160,28): error TS2695: Left side of comma opera node_modules/async/autoInject.js(164,14): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/autoInject.js(168,6): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/cargo.js(62,12): error TS2304: Cannot find name 'AsyncFunction'. -node_modules/async/cargo.js(67,14): error TS2749: 'module' refers to a value, but is being used as a type here. -node_modules/async/cargo.js(67,20): error TS1005: '}' expected. node_modules/async/cargo.js(92,11): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/compose.js(8,37): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/compose.js(36,15): error TS2304: Cannot find name 'AsyncFunction'. @@ -123,8 +121,6 @@ node_modules/async/dist/async.js(1990,16): error TS2554: Expected 3 arguments, b node_modules/async/dist/async.js(2116,20): error TS2345: Argument of type 'Function | undefined' is not assignable to parameter of type 'number | undefined'. Type 'Function' is not assignable to type 'number'. node_modules/async/dist/async.js(2274,29): error TS2554: Expected 0 arguments, but got 2. -node_modules/async/dist/async.js(2425,20): error TS1005: '}' expected. -node_modules/async/dist/async.js(2450,5): error TS2740: Type '{ _tasks: DLL; concurrency: any; payload: any; saturated: () => void; unsaturated: () => void; buffer: number; empty: () => void; drain: () => void; error: () => void; started: boolean; paused: boolean; push: (data: any, callback: any) => void; ... 9 more ...; resume: () => void; }' is missing the following properties from type 'NodeModule': exports, require, id, filename, and 4 more. node_modules/async/dist/async.js(2521,9): error TS2722: Cannot invoke an object which is possibly 'undefined'. node_modules/async/dist/async.js(2564,31): error TS2345: Argument of type 'IArguments' is not assignable to parameter of type 'any[]'. Type 'IArguments' is missing the following properties from type 'any[]': pop, push, concat, join, and 26 more. @@ -157,17 +153,6 @@ node_modules/async/dist/async.js(3828,14): error TS2339: Property 'unmemoized' d node_modules/async/dist/async.js(3848,23): error TS1003: Identifier expected. node_modules/async/dist/async.js(3848,24): error TS1003: Identifier expected. node_modules/async/dist/async.js(3848,25): error TS1003: Identifier expected. -node_modules/async/dist/async.js(4059,20): error TS1005: '}' expected. -node_modules/async/dist/async.js(4095,5): error TS2322: Type '{ _tasks: DLL; concurrency: any; payload: any; saturated: () => void; unsaturated: () => void; buffer: number; empty: () => void; drain: () => void; error: () => void; started: boolean; paused: boolean; push: (data: any, callback: any) => void; ... 9 more ...; resume: () => void; }' is not assignable to type 'NodeModule'. -node_modules/async/dist/async.js(4117,20): error TS1005: '}' expected. -node_modules/async/dist/async.js(4128,7): error TS2339: Property 'push' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4133,11): error TS2339: Property 'started' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4140,19): error TS2339: Property 'drain' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4145,26): error TS2339: Property '_tasks' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4158,19): error TS2339: Property '_tasks' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4160,19): error TS2339: Property '_tasks' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4163,26): error TS2339: Property 'process' does not exist on type 'NodeModule'. -node_modules/async/dist/async.js(4167,14): error TS2339: Property 'unshift' does not exist on type 'NodeModule'. node_modules/async/dist/async.js(4381,5): error TS2322: Type 'any[] | {}' is not assignable to type 'any[]'. Type '{}' is missing the following properties from type 'any[]': length, pop, push, concat, and 28 more. node_modules/async/dist/async.js(4617,17): error TS2532: Object is possibly 'undefined'. @@ -581,11 +566,9 @@ node_modules/async/priorityQueue.js(18,15): error TS2695: Left side of comma ope node_modules/async/priorityQueue.js(23,21): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/priorityQueue.js(47,10): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/priorityQueue.js(86,12): error TS2304: Cannot find name 'AsyncFunction'. -node_modules/async/priorityQueue.js(93,20): error TS1005: '}' expected. node_modules/async/queue.js(8,18): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/queue.js(9,11): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/queue.js(91,12): error TS2304: Cannot find name 'AsyncFunction'. -node_modules/async/queue.js(97,20): error TS1005: '}' expected. node_modules/async/race.js(63,17): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/race.js(64,11): error TS2695: Left side of comma operator is unused and has no side effects. node_modules/async/race.js(67,10): error TS2695: Left side of comma operator is unused and has no side effects. diff --git a/tests/baselines/reference/user/prettier.log b/tests/baselines/reference/user/prettier.log index ff4b267a459..713126ec61b 100644 --- a/tests/baselines/reference/user/prettier.log +++ b/tests/baselines/reference/user/prettier.log @@ -1,7 +1,7 @@ Exit Code: 1 Standard output: node_modules/@typescript-eslint/typescript-estree/dist/parser.d.ts(1,8): error TS1259: Module '"/prettier/prettier/node_modules/typescript/lib/typescript"' can only be default-imported using the 'esModuleInterop' flag -src/cli/util.js(60,44): error TS2345: Argument of type 'null' is not assignable to parameter of type 'number | undefined'. +src/cli/util.js(60,44): error TS2345: Argument of type 'null' is not assignable to parameter of type 'number'. src/cli/util.js(119,38): error TS2339: Property 'sync' does not exist on type '(...args: any[]) => any'. src/cli/util.js(372,29): error TS2532: Object is possibly 'undefined'. src/cli/util.js(372,64): error TS2339: Property 'length' does not exist on type 'Ignore'. @@ -9,7 +9,7 @@ src/cli/util.js(413,36): error TS2345: Argument of type '{ dot: true; nodir: boo Object literal may only specify known properties, and 'nodir' does not exist in type 'GlobbyOptions'. src/cli/util.js(452,25): error TS2532: Object is possibly 'undefined'. src/cli/util.js(452,52): error TS2339: Property 'length' does not exist on type 'Ignore'. -src/cli/util.js(510,44): error TS2345: Argument of type 'null' is not assignable to parameter of type 'number | undefined'. +src/cli/util.js(510,44): error TS2345: Argument of type 'null' is not assignable to parameter of type 'number'. src/cli/util.js(531,37): error TS2339: Property 'grey' does not exist on type 'typeof import("../../../node_modules/chalk/types/index")'. src/cli/util.js(594,16): error TS2339: Property 'type' does not exist on type 'never'. src/cli/util.js(595,16): error TS2339: Property 'oppositeDescription' does not exist on type 'never'. diff --git a/tests/cases/fourslash/completionsClassPropertiesAfterPrivateProperty.ts b/tests/cases/fourslash/completionsClassPropertiesAfterPrivateProperty.ts new file mode 100644 index 00000000000..2efd70110b9 --- /dev/null +++ b/tests/cases/fourslash/completionsClassPropertiesAfterPrivateProperty.ts @@ -0,0 +1,12 @@ +/// + +//// interface X { +//// bla: string; +//// } +//// class Y implements X { +//// private blub = ""; +//// /**/ +//// } + + +verify.completions({ marker: "", includes: "bla", isNewIdentifierLocation: true });