Skip to content

Commit

Permalink
Fixed crash when cross-file reusing nodes for class member snippet co…
Browse files Browse the repository at this point in the history
…mpletions (#58216)
  • Loading branch information
Andarist committed Jul 4, 2024
1 parent c3efeb9 commit 3163fe7
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 5 deletions.
10 changes: 5 additions & 5 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2088,7 +2088,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
// SyntaxKind.TemplateMiddle
// SyntaxKind.TemplateTail
function emitLiteral(node: LiteralLikeNode, jsxAttributeEscape: boolean) {
const text = getLiteralTextOfNode(node, printerOptions.neverAsciiEscape, jsxAttributeEscape);
const text = getLiteralTextOfNode(node, /*sourceFile*/ undefined, printerOptions.neverAsciiEscape, jsxAttributeEscape);
if (
(printerOptions.sourceMap || printerOptions.inlineSourceMap)
&& (node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind))
Expand Down Expand Up @@ -2641,7 +2641,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
expression = skipPartiallyEmittedExpressions(expression);
if (isNumericLiteral(expression)) {
// check if numeric literal is a decimal literal that was originally written with a dot
const text = getLiteralTextOfNode(expression as LiteralExpression, /*neverAsciiEscape*/ true, /*jsxAttributeEscape*/ false);
const text = getLiteralTextOfNode(expression as LiteralExpression, /*sourceFile*/ undefined, /*neverAsciiEscape*/ true, /*jsxAttributeEscape*/ false);
// If the number will be printed verbatim and it doesn't already contain a dot or an exponent indicator, add one
// if the expression doesn't have any comments that will be emitted.
return !(expression.numericLiteralFlags & TokenFlags.WithSpecifier)
Expand Down Expand Up @@ -5169,7 +5169,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
return getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia);
}

function getLiteralTextOfNode(node: LiteralLikeNode, neverAsciiEscape: boolean | undefined, jsxAttributeEscape: boolean): string {
function getLiteralTextOfNode(node: LiteralLikeNode, sourceFile = currentSourceFile, neverAsciiEscape: boolean | undefined, jsxAttributeEscape: boolean): string {
if (node.kind === SyntaxKind.StringLiteral && (node as StringLiteral).textSourceNode) {
const textSourceNode = (node as StringLiteral).textSourceNode!;
if (isIdentifier(textSourceNode) || isPrivateIdentifier(textSourceNode) || isNumericLiteral(textSourceNode) || isJsxNamespacedName(textSourceNode)) {
Expand All @@ -5179,7 +5179,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
`"${escapeNonAsciiString(text)}"`;
}
else {
return getLiteralTextOfNode(textSourceNode, neverAsciiEscape, jsxAttributeEscape);
return getLiteralTextOfNode(textSourceNode, getSourceFileOfNode(textSourceNode), neverAsciiEscape, jsxAttributeEscape);
}
}

Expand All @@ -5188,7 +5188,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
| (printerOptions.terminateUnterminatedLiterals ? GetLiteralTextFlags.TerminateUnterminatedLiterals : 0)
| (printerOptions.target && printerOptions.target >= ScriptTarget.ES2021 ? GetLiteralTextFlags.AllowNumericSeparator : 0);

return getLiteralText(node, currentSourceFile, flags);
return getLiteralText(node, sourceFile, flags);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/// <reference path="fourslash.ts" />

// @strict: true

// @filename: KlassConstructor.ts

//// type GenericConstructor<T> = new (...args: any[]) => T;
//// export type KlassConstructor<Cls extends GenericConstructor<any>> =
//// GenericConstructor<InstanceType<Cls>> & { [k in keyof Cls]: Cls[k] };

// @filename: ElementNode.ts
//// import { KlassConstructor } from "./KlassConstructor";
////
//// export type NodeKey = string;
////
//// export class ElementNode {
//// ["constructor"]!: KlassConstructor<typeof ElementNode>;
//// }

// @filename: CollapsibleContainerNode.ts
//// import { ElementNode, NodeKey } from "./ElementNode";
////
//// export class CollapsibleContainerNode extends ElementNode {
//// __open: boolean;
////
//// /*1*/
//// }

format.setFormatOptions({
insertSpaceAfterConstructor: false,
});

verify.completions({
marker: "1",
preferences: {
includeCompletionsWithClassMemberSnippets: true,
includeCompletionsWithInsertText: true,
},
includes: [{
name: `["constructor"]`,
insertText: `["constructor"]: KlassConstructor<typeof ElementNode>;`,
filterText: `["constructor"]`,
hasAction: true,
source: 'ClassMemberSnippet/'
}],
isNewIdentifierLocation: true,
});

0 comments on commit 3163fe7

Please sign in to comment.