mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-17 01:55:50 -06:00
PR Feedback and defer makeUniqueName/getGeneratedNameForNode to printer.
This commit is contained in:
parent
75b2181e17
commit
cd2cf7d3c6
@ -185,24 +185,38 @@ namespace ts {
|
||||
|
||||
// Identifiers
|
||||
|
||||
export function createIdentifier(text: string): Identifier {
|
||||
const node = <Identifier>createNode(SyntaxKind.Identifier);
|
||||
export function createIdentifier(text: string, location?: TextRange): Identifier {
|
||||
const node = <Identifier>createNode(SyntaxKind.Identifier, location);
|
||||
node.text = text;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createTempVariable(): Identifier {
|
||||
const name = <Identifier>createNode(SyntaxKind.Identifier);
|
||||
name.text = undefined;
|
||||
name.tempKind = TempVariableKind.Auto;
|
||||
export function createTempVariable(location?: TextRange): Identifier {
|
||||
const name = <Identifier>createNode(SyntaxKind.Identifier, location);
|
||||
name.autoGenerateKind = GeneratedIdentifierKind.Auto;
|
||||
getNodeId(name);
|
||||
return name;
|
||||
}
|
||||
|
||||
export function createLoopVariable(): Identifier {
|
||||
const name = <Identifier>createNode(SyntaxKind.Identifier);
|
||||
name.text = undefined;
|
||||
name.tempKind = TempVariableKind.Loop;
|
||||
export function createLoopVariable(location?: TextRange): Identifier {
|
||||
const name = <Identifier>createNode(SyntaxKind.Identifier, location);
|
||||
name.autoGenerateKind = GeneratedIdentifierKind.Loop;
|
||||
getNodeId(name);
|
||||
return name;
|
||||
}
|
||||
|
||||
export function createUniqueName(text: string, location?: TextRange): Identifier {
|
||||
const name = <Identifier>createNode(SyntaxKind.Identifier, location);
|
||||
name.text = text;
|
||||
name.autoGenerateKind = GeneratedIdentifierKind.Unique;
|
||||
getNodeId(name);
|
||||
return name;
|
||||
}
|
||||
|
||||
export function createGeneratedNameForNode(node: Node, location?: TextRange): Identifier {
|
||||
const name = <Identifier>createNode(SyntaxKind.Identifier, location);
|
||||
name.autoGenerateKind = GeneratedIdentifierKind.Node;
|
||||
name.original = node;
|
||||
getNodeId(name);
|
||||
return name;
|
||||
}
|
||||
|
||||
@ -121,7 +121,6 @@ const _super = (function (geti, seti) {
|
||||
const writer = createTextWriter(newLine);
|
||||
const {
|
||||
write,
|
||||
writeTextOfNode,
|
||||
writeLine,
|
||||
increaseIndent,
|
||||
decreaseIndent
|
||||
@ -154,11 +153,12 @@ const _super = (function (geti, seti) {
|
||||
let identifierSubstitution: (node: Identifier) => Identifier;
|
||||
let onBeforeEmitNode: (node: Node) => void;
|
||||
let onAfterEmitNode: (node: Node) => void;
|
||||
let isUniqueName: (name: string) => boolean;
|
||||
let temporaryVariables: string[] = [];
|
||||
let nodeToGeneratedName: string[];
|
||||
let generatedNameSet: Map<string>;
|
||||
let tempFlags: TempFlags;
|
||||
let currentSourceFile: SourceFile;
|
||||
let currentText: string;
|
||||
let currentFileIdentifiers: Map<string>;
|
||||
let extendsEmitted: boolean;
|
||||
let decorateEmitted: boolean;
|
||||
let paramEmitted: boolean;
|
||||
@ -169,6 +169,8 @@ const _super = (function (geti, seti) {
|
||||
|
||||
function doPrint(jsFilePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) {
|
||||
sourceMap.initialize(jsFilePath, sourceMapFilePath, sourceFiles, isBundledEmit);
|
||||
nodeToGeneratedName = [];
|
||||
generatedNameSet = {};
|
||||
isOwnFileEmit = !isBundledEmit;
|
||||
|
||||
// Emit helpers from all the files
|
||||
@ -213,8 +215,6 @@ const _super = (function (geti, seti) {
|
||||
identifierSubstitution = undefined;
|
||||
onBeforeEmitNode = undefined;
|
||||
onAfterEmitNode = undefined;
|
||||
isUniqueName = undefined;
|
||||
temporaryVariables = undefined;
|
||||
tempFlags = TempFlags.Auto;
|
||||
currentSourceFile = undefined;
|
||||
currentText = undefined;
|
||||
@ -236,13 +236,13 @@ const _super = (function (geti, seti) {
|
||||
identifierSubstitution = context.identifierSubstitution;
|
||||
onBeforeEmitNode = context.onBeforeEmitNode;
|
||||
onAfterEmitNode = context.onAfterEmitNode;
|
||||
isUniqueName = context.isUniqueName;
|
||||
return printSourceFile;
|
||||
}
|
||||
|
||||
function printSourceFile(node: SourceFile) {
|
||||
currentSourceFile = node;
|
||||
currentText = node.text;
|
||||
currentFileIdentifiers = node.identifiers;
|
||||
sourceMap.setSourceFile(node);
|
||||
comments.setSourceFile(node);
|
||||
emitWorker(node);
|
||||
@ -659,22 +659,11 @@ const _super = (function (geti, seti) {
|
||||
//
|
||||
|
||||
function emitIdentifier(node: Identifier) {
|
||||
if (node.text === undefined) {
|
||||
// Emit a temporary variable name for this node.
|
||||
const nodeId = getOriginalNodeId(node);
|
||||
const text = temporaryVariables[nodeId] || (temporaryVariables[nodeId] = makeTempVariableName(tempKindToFlags(node.tempKind)));
|
||||
write(text);
|
||||
}
|
||||
else if (nodeIsSynthesized(node) || !node.parent) {
|
||||
if (getNodeEmitFlags(node) & NodeEmitFlags.UMDDefine) {
|
||||
writeLines(umdHelper);
|
||||
}
|
||||
else {
|
||||
write(node.text);
|
||||
}
|
||||
if (getNodeEmitFlags(node) && NodeEmitFlags.UMDDefine) {
|
||||
writeLines(umdHelper);
|
||||
}
|
||||
else {
|
||||
writeTextOfNode(currentText, node);
|
||||
write(getTextOfNode(node, /*includeTrivia*/ false));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1720,7 +1709,6 @@ const _super = (function (geti, seti) {
|
||||
emitExpression(node.expression);
|
||||
write(":");
|
||||
|
||||
debugger;
|
||||
emitCaseOrDefaultClauseStatements(node, node.statements);
|
||||
}
|
||||
|
||||
@ -1763,14 +1751,14 @@ const _super = (function (geti, seti) {
|
||||
function emitPropertyAssignment(node: PropertyAssignment) {
|
||||
emit(node.name);
|
||||
write(": ");
|
||||
// // This is to ensure that we emit comment in the following case:
|
||||
// // For example:
|
||||
// // obj = {
|
||||
// // id: /*comment1*/ ()=>void
|
||||
// // }
|
||||
// // "comment1" is not considered to be leading comment for node.initializer
|
||||
// // but rather a trailing comment on the previous node.
|
||||
// emitTrailingCommentsOfPosition(node.initializer.pos);
|
||||
// This is to ensure that we emit comment in the following case:
|
||||
// For example:
|
||||
// obj = {
|
||||
// id: /*comment1*/ ()=>void
|
||||
// }
|
||||
// "comment1" is not considered to be leading comment for node.initializer
|
||||
// but rather a trailing comment on the previous node.
|
||||
emitLeadingComments(node.initializer, getTrailingComments(collapseTextRange(node.initializer, TextRangeCollapse.CollapseToStart)));
|
||||
emitExpression(node.initializer);
|
||||
}
|
||||
|
||||
@ -1951,11 +1939,8 @@ const _super = (function (geti, seti) {
|
||||
}
|
||||
|
||||
function emitModifiers(node: Node, modifiers: ModifiersArray) {
|
||||
const startingPos = writer.getTextPos();
|
||||
emitList(node, modifiers, ListFormat.SingleLine);
|
||||
|
||||
const endingPos = writer.getTextPos();
|
||||
if (startingPos !== endingPos) {
|
||||
if (modifiers && modifiers.length) {
|
||||
emitList(node, modifiers, ListFormat.SingleLine);
|
||||
write(" ");
|
||||
}
|
||||
}
|
||||
@ -2345,7 +2330,15 @@ const _super = (function (geti, seti) {
|
||||
}
|
||||
|
||||
function getTextOfNode(node: Node, includeTrivia?: boolean) {
|
||||
if (nodeIsSynthesized(node) && (isLiteralExpression(node) || isIdentifier(node))) {
|
||||
if (isIdentifier(node)) {
|
||||
if (node.autoGenerateKind) {
|
||||
return getGeneratedIdentifier(node);
|
||||
}
|
||||
else if (nodeIsSynthesized(node) || !node.parent) {
|
||||
return node.text;
|
||||
}
|
||||
}
|
||||
else if (isLiteralExpression(node) && (nodeIsSynthesized(node) || !node.parent)) {
|
||||
return node.text;
|
||||
}
|
||||
|
||||
@ -2368,10 +2361,22 @@ const _super = (function (geti, seti) {
|
||||
&& rangeEndIsOnSameLineAsRangeStart(block, block);
|
||||
}
|
||||
|
||||
function tempKindToFlags(kind: TempVariableKind) {
|
||||
return kind === TempVariableKind.Loop
|
||||
? TempFlags._i
|
||||
: TempFlags.Auto;
|
||||
function isUniqueName(name: string): boolean {
|
||||
return !resolver.hasGlobalName(name) &&
|
||||
!hasProperty(currentFileIdentifiers, name) &&
|
||||
!hasProperty(generatedNameSet, name);
|
||||
}
|
||||
|
||||
function isUniqueLocalName(name: string, container: Node): boolean {
|
||||
for (let node = container; isNodeDescendentOf(node, container); node = node.nextContainer) {
|
||||
if (node.locals && hasProperty(node.locals, name)) {
|
||||
// We conservatively include alias symbols to cover cases where they're emitted as locals
|
||||
if (node.locals[name].flags & (SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2401,6 +2406,85 @@ const _super = (function (geti, seti) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate a name that is unique within the current file and doesn't conflict with any names
|
||||
// in global scope. The name is formed by adding an '_n' suffix to the specified base name,
|
||||
// where n is a positive integer. Note that names generated by makeTempVariableName and
|
||||
// makeUniqueName are guaranteed to never conflict.
|
||||
function makeUniqueName(baseName: string): string {
|
||||
// Find the first unique 'name_n', where n is a positive number
|
||||
if (baseName.charCodeAt(baseName.length - 1) !== CharacterCodes._) {
|
||||
baseName += "_";
|
||||
}
|
||||
let i = 1;
|
||||
while (true) {
|
||||
const generatedName = baseName + i;
|
||||
if (isUniqueName(generatedName)) {
|
||||
return generatedNameSet[generatedName] = generatedName;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
function generateNameForModuleOrEnum(node: ModuleDeclaration | EnumDeclaration) {
|
||||
const name = node.name.text;
|
||||
// Use module/enum name itself if it is unique, otherwise make a unique variation
|
||||
return isUniqueLocalName(name, node) ? name : makeUniqueName(name);
|
||||
}
|
||||
|
||||
function generateNameForImportOrExportDeclaration(node: ImportDeclaration | ExportDeclaration) {
|
||||
const expr = getExternalModuleName(node);
|
||||
const baseName = expr.kind === SyntaxKind.StringLiteral ?
|
||||
escapeIdentifier(makeIdentifierFromModuleName((<LiteralExpression>expr).text)) : "module";
|
||||
return makeUniqueName(baseName);
|
||||
}
|
||||
|
||||
function generateNameForExportDefault() {
|
||||
return makeUniqueName("default");
|
||||
}
|
||||
|
||||
function generateNameForClassExpression() {
|
||||
return makeUniqueName("class");
|
||||
}
|
||||
|
||||
function generateNameForNode(node: Node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return makeUniqueName((<Identifier>node).text);
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
return generateNameForModuleOrEnum(<ModuleDeclaration | EnumDeclaration>node);
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
return generateNameForImportOrExportDeclaration(<ImportDeclaration | ExportDeclaration>node);
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return generateNameForExportDefault();
|
||||
case SyntaxKind.ClassExpression:
|
||||
return generateNameForClassExpression();
|
||||
default:
|
||||
return makeTempVariableName(TempFlags.Auto);
|
||||
}
|
||||
}
|
||||
|
||||
function generateIdentifier(node: Identifier) {
|
||||
switch (node.autoGenerateKind) {
|
||||
case GeneratedIdentifierKind.Auto:
|
||||
return makeTempVariableName(TempFlags.Auto);
|
||||
case GeneratedIdentifierKind.Loop:
|
||||
return makeTempVariableName(TempFlags._i);
|
||||
case GeneratedIdentifierKind.Unique:
|
||||
return makeUniqueName(node.text);
|
||||
case GeneratedIdentifierKind.Node:
|
||||
return generateNameForNode(getOriginalNode(node));
|
||||
}
|
||||
}
|
||||
|
||||
function getGeneratedIdentifier(node: Identifier) {
|
||||
const id = getOriginalNodeId(node);
|
||||
return nodeToGeneratedName[id] || (nodeToGeneratedName[id] = unescapeIdentifier(generateIdentifier(node)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -22,8 +22,6 @@ namespace ts {
|
||||
* @param transforms An array of Transformers.
|
||||
*/
|
||||
export function transformFiles(resolver: EmitResolver, host: EmitHost, sourceFiles: SourceFile[], transformers: Transformer[]) {
|
||||
const nodeToGeneratedName: Identifier[] = [];
|
||||
const generatedNameSet: Map<string> = {};
|
||||
const nodeEmitFlags: NodeEmitFlags[] = [];
|
||||
const lexicalEnvironmentVariableDeclarationsStack: VariableDeclaration[][] = [];
|
||||
const lexicalEnvironmentFunctionDeclarationsStack: FunctionDeclaration[][] = [];
|
||||
@ -40,10 +38,6 @@ namespace ts {
|
||||
getEmitResolver: () => resolver,
|
||||
getNodeEmitFlags,
|
||||
setNodeEmitFlags,
|
||||
isUniqueName,
|
||||
getGeneratedNameForNode,
|
||||
nodeHasGeneratedName,
|
||||
makeUniqueName,
|
||||
hoistVariableDeclaration,
|
||||
hoistFunctionDeclaration,
|
||||
startLexicalEnvironment,
|
||||
@ -119,118 +113,6 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a name that is unique within the current file and doesn't conflict with any names
|
||||
* in global scope. The name is formed by adding an '_n' suffix to the specified base name,
|
||||
* where n is a positive integer. Note that names generated by makeTempVariableName and
|
||||
* makeUniqueName are guaranteed to never conflict.
|
||||
*/
|
||||
function makeUniqueName(baseName: string): Identifier {
|
||||
// Find the first unique 'name_n', where n is a positive number
|
||||
if (baseName.charCodeAt(baseName.length - 1) !== CharacterCodes._) {
|
||||
baseName += "_";
|
||||
}
|
||||
|
||||
let i = 1;
|
||||
while (true) {
|
||||
const generatedName = baseName + i;
|
||||
if (isUniqueName(generatedName)) {
|
||||
return createIdentifier(generatedNameSet[generatedName] = generatedName);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the generated name for a node.
|
||||
*/
|
||||
function getGeneratedNameForNode(node: Node) {
|
||||
const id = getNodeId(node);
|
||||
return nodeToGeneratedName[id] || (nodeToGeneratedName[id] = generateNameForNode(node));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether a node has a generated name.
|
||||
*/
|
||||
function nodeHasGeneratedName(node: Node) {
|
||||
const id = getNodeId(node);
|
||||
return nodeToGeneratedName[id] !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the provided name is unique.
|
||||
*/
|
||||
function isUniqueName(name: string): boolean {
|
||||
return !resolver.hasGlobalName(name)
|
||||
&& !hasProperty(currentSourceFile.identifiers, name)
|
||||
&& !hasProperty(generatedNameSet, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the provided name is unique within a container.
|
||||
*/
|
||||
function isUniqueLocalName(name: string, container: Node): boolean {
|
||||
container = getOriginalNode(container);
|
||||
for (let node = container; isNodeDescendentOf(node, container); node = node.nextContainer) {
|
||||
if (node.locals && hasProperty(node.locals, name)) {
|
||||
// We conservatively include alias symbols to cover cases where they're emitted as locals
|
||||
if (node.locals[name].flags & (SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a name for a node.
|
||||
*/
|
||||
function generateNameForNode(node: Node): Identifier {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return makeUniqueName((<Identifier>node).text);
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
return generateNameForModuleOrEnum(<ModuleDeclaration | EnumDeclaration>node);
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
return generateNameForImportOrExportDeclaration(<ImportDeclaration | ExportDeclaration>node);
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
Debug.assert((node.flags & NodeFlags.Default) !== 0, "Can only generate a name for a default export.");
|
||||
return generateNameForExportDefault();
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return generateNameForExportDefault();
|
||||
case SyntaxKind.ClassExpression:
|
||||
return generateNameForClassExpression();
|
||||
default:
|
||||
return createTempVariable();
|
||||
}
|
||||
}
|
||||
|
||||
function generateNameForModuleOrEnum(node: ModuleDeclaration | EnumDeclaration) {
|
||||
const name = node.name;
|
||||
// Use module/enum name itself if it is unique, otherwise make a unique variation
|
||||
return isUniqueLocalName(name.text, node) ? name : makeUniqueName(name.text);
|
||||
}
|
||||
|
||||
function generateNameForImportOrExportDeclaration(node: ImportDeclaration | ExportDeclaration) {
|
||||
const expr = getExternalModuleName(node);
|
||||
const baseName = expr.kind === SyntaxKind.StringLiteral
|
||||
? escapeIdentifier(makeIdentifierFromModuleName((<LiteralExpression>expr).text))
|
||||
: "module";
|
||||
return makeUniqueName(baseName);
|
||||
}
|
||||
|
||||
function generateNameForExportDefault() {
|
||||
return makeUniqueName("default");
|
||||
}
|
||||
|
||||
function generateNameForClassExpression() {
|
||||
return makeUniqueName("class");
|
||||
}
|
||||
|
||||
/**
|
||||
* Records a hoisted variable declaration for the provided name within a lexical environment.
|
||||
*/
|
||||
|
||||
@ -497,16 +497,19 @@ namespace ts {
|
||||
// @kind(SyntaxKind.StaticKeyword)
|
||||
export interface Modifier extends Node { }
|
||||
|
||||
export const enum TempVariableKind {
|
||||
Auto, // Automatically generated identifier
|
||||
Loop, // Automatically generated identifier with a preference for '_i'
|
||||
export const enum GeneratedIdentifierKind {
|
||||
None, // Not automatically generated.
|
||||
Auto, // Automatically generated identifier.
|
||||
Loop, // Automatically generated identifier with a preference for '_i'.
|
||||
Unique, // Unique name based on the 'text' property.
|
||||
Node, // Unique name based on the node in the 'original' property.
|
||||
}
|
||||
|
||||
// @kind(SyntaxKind.Identifier)
|
||||
export interface Identifier extends PrimaryExpression {
|
||||
text: string; // Text of identifier (with escapes converted to characters)
|
||||
tempKind?: TempVariableKind; // Specifies whether to auto-generate the text for an identifier.
|
||||
originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later
|
||||
autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier.
|
||||
}
|
||||
|
||||
// @kind(SyntaxKind.QualifiedName)
|
||||
@ -2805,7 +2808,7 @@ namespace ts {
|
||||
SingleLine = 1 << 6, // The contents of this node should be emit on a single line.
|
||||
AdviseOnEmitNode = 1 << 7, // The node printer should invoke the onBeforeEmitNode and onAfterEmitNode callbacks when printing this node.
|
||||
IsNotEmittedNode = 1 << 8, // Is a node that is not emitted but whose comments should be preserved if possible.
|
||||
EmitCommentsOfNotEmittedParent = 1 << 8, // Emits comments of missing parent nodes.
|
||||
EmitCommentsOfNotEmittedParent = 1 << 9, // Emits comments of missing parent nodes.
|
||||
}
|
||||
|
||||
/** Additional context provided to `visitEachChild` */
|
||||
@ -2825,10 +2828,6 @@ namespace ts {
|
||||
setNodeEmitFlags<T extends Node>(node: T, flags: NodeEmitFlags): T;
|
||||
hoistFunctionDeclaration(node: FunctionDeclaration): void;
|
||||
hoistVariableDeclaration(node: Identifier): void;
|
||||
isUniqueName(name: string): boolean;
|
||||
getGeneratedNameForNode(node: Node): Identifier;
|
||||
nodeHasGeneratedName(node: Node): boolean;
|
||||
makeUniqueName(baseName: string): Identifier;
|
||||
|
||||
/**
|
||||
* Hook used by transformers to substitute non-expression identifiers
|
||||
|
||||
@ -2297,11 +2297,11 @@ namespace ts {
|
||||
writer.write(" ");
|
||||
}
|
||||
|
||||
let emitInterveningSeperator = false;
|
||||
let emitInterveningSeparator = false;
|
||||
for (const comment of comments) {
|
||||
if (emitInterveningSeperator) {
|
||||
if (emitInterveningSeparator) {
|
||||
writer.write(" ");
|
||||
emitInterveningSeperator = false;
|
||||
emitInterveningSeparator = false;
|
||||
}
|
||||
|
||||
writeComment(text, lineMap, writer, comment, newLine);
|
||||
@ -2309,11 +2309,11 @@ namespace ts {
|
||||
writer.writeLine();
|
||||
}
|
||||
else {
|
||||
emitInterveningSeperator = true;
|
||||
emitInterveningSeparator = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (emitInterveningSeperator && trailingSeparator) {
|
||||
if (emitInterveningSeparator && trailingSeparator) {
|
||||
writer.write(" ");
|
||||
}
|
||||
}
|
||||
@ -2723,7 +2723,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
return collapse === TextRangeCollapse.CollapseToStart
|
||||
? { pos: range.pos, end: range.end }
|
||||
? { pos: range.pos, end: range.pos }
|
||||
: { pos: range.end, end: range.end };
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user