mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-16 07:13:45 -05:00
@@ -2612,6 +2612,16 @@ namespace ts {
|
||||
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.
|
||||
*/
|
||||
|
||||
@@ -223,6 +223,14 @@ const f = () => {
|
||||
testExtractConstant("extractConstant_ArrowFunction_Expression",
|
||||
`const f = () => [#|2 + 1|];`);
|
||||
|
||||
testExtractConstant("extractConstant_PreserveTrivia", `
|
||||
// a
|
||||
var q = /*b*/ //c
|
||||
/*d*/ [#|1 /*e*/ //f
|
||||
/*g*/ + /*h*/ //i
|
||||
/*j*/ 2|] /*k*/ //l
|
||||
/*m*/; /*n*/ //o`);
|
||||
|
||||
testExtractConstantFailed("extractConstant_Void", `
|
||||
function f(): void { }
|
||||
[#|f();|]`);
|
||||
|
||||
@@ -532,6 +532,14 @@ function f() {
|
||||
[#|let x;|]
|
||||
return { x };
|
||||
}`);
|
||||
|
||||
testExtractFunction("extractFunction_PreserveTrivia", `
|
||||
// a
|
||||
var q = /*b*/ //c
|
||||
/*d*/ [#|1 /*e*/ //f
|
||||
/*g*/ + /*h*/ //i
|
||||
/*j*/ 2|] /*k*/ //l
|
||||
/*m*/; /*n*/ //o`);
|
||||
});
|
||||
|
||||
function testExtractFunction(caption: string, text: string) {
|
||||
|
||||
@@ -740,6 +740,8 @@ namespace ts.refactor.extractSymbol {
|
||||
}
|
||||
|
||||
const { body, returnValueProperty } = transformFunctionBody(node, exposedVariableDeclarations, writes, substitutions, !!(range.facts & RangeFacts.HasReturn));
|
||||
suppressLeadingAndTrailingTrivia(body);
|
||||
|
||||
let newFunction: MethodDeclaration | FunctionDeclaration;
|
||||
|
||||
if (isClassLike(scope)) {
|
||||
@@ -926,15 +928,10 @@ namespace ts.refactor.extractSymbol {
|
||||
}
|
||||
}
|
||||
|
||||
if (isReadonlyArray(range.range)) {
|
||||
changeTracker.replaceNodesWithNodes(context.file, range.range, newNodes, {
|
||||
nodeSeparator: context.newLineCharacter,
|
||||
suffix: context.newLineCharacter // insert newline only when replacing statements
|
||||
});
|
||||
}
|
||||
else {
|
||||
changeTracker.replaceNodeWithNodes(context.file, range.range, newNodes, { nodeSeparator: context.newLineCharacter });
|
||||
}
|
||||
const replacementRange = isReadonlyArray(range.range)
|
||||
? { pos: first(range.range).getStart(), end: last(range.range).end }
|
||||
: { pos: range.range.getStart(), end: range.range.end };
|
||||
changeTracker.replaceRangeWithNodes(context.file, replacementRange, newNodes, { nodeSeparator: context.newLineCharacter });
|
||||
|
||||
const edits = changeTracker.getChanges();
|
||||
const renameRange = isReadonlyArray(range.range) ? first(range.range) : range.range;
|
||||
@@ -982,6 +979,7 @@ namespace ts.refactor.extractSymbol {
|
||||
: checker.typeToTypeNode(checker.getContextualType(node), scope, NodeBuilderFlags.NoTruncation);
|
||||
|
||||
const initializer = transformConstantInitializer(node, substitutions);
|
||||
suppressLeadingAndTrailingTrivia(initializer);
|
||||
|
||||
const changeTracker = textChanges.ChangeTracker.fromContext(context);
|
||||
|
||||
@@ -1014,7 +1012,7 @@ namespace ts.refactor.extractSymbol {
|
||||
changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newVariable, { suffix: context.newLineCharacter + context.newLineCharacter });
|
||||
|
||||
// Consume
|
||||
changeTracker.replaceNodeWithNodes(context.file, node, [localReference], { nodeSeparator: context.newLineCharacter });
|
||||
changeTracker.replaceRange(context.file, { pos: node.getStart(), end: node.end }, localReference);
|
||||
}
|
||||
else {
|
||||
const newVariableDeclaration = createVariableDeclaration(localNameText, variableType, initializer);
|
||||
|
||||
@@ -1369,4 +1369,39 @@ namespace ts {
|
||||
|
||||
return visited;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets EmitFlags to suppress leading and trailing trivia on the node.
|
||||
*/
|
||||
/* @internal */
|
||||
export function suppressLeadingAndTrailingTrivia(node: Node) {
|
||||
Debug.assert(node !== undefined);
|
||||
|
||||
suppressLeading(node);
|
||||
suppressTrailing(node);
|
||||
|
||||
function suppressLeading(node: Node) {
|
||||
addEmitFlags(node, EmitFlags.NoLeadingComments);
|
||||
|
||||
const firstChild = forEachChild(node, child => child);
|
||||
firstChild && suppressLeading(firstChild);
|
||||
}
|
||||
|
||||
function suppressTrailing(node: Node) {
|
||||
addEmitFlags(node, EmitFlags.NoTrailingComments);
|
||||
|
||||
let lastChild: Node = undefined;
|
||||
forEachChild(
|
||||
node,
|
||||
child => (lastChild = child, undefined),
|
||||
children => {
|
||||
// As an optimization, jump straight to the end of the list.
|
||||
if (children.length) {
|
||||
lastChild = last(children);
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
lastChild && suppressTrailing(lastChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user