diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 854d09761cd..372c606aaf8 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3724,7 +3724,7 @@ "code": 95003 }, - "Extract to {0}": { + "Extract to {0} in {1}": { "category": "Message", "code": 95004 }, diff --git a/src/harness/unittests/extractConstants.ts b/src/harness/unittests/extractConstants.ts index e2c64afb526..179affd86c9 100644 --- a/src/harness/unittests/extractConstants.ts +++ b/src/harness/unittests/extractConstants.ts @@ -40,7 +40,7 @@ namespace ts { } }`); - testExtractConstant("extractConstant_ClassInsertionPosition", + testExtractConstant("extractConstant_ClassInsertionPosition1", `class C { a = 1; b = 2; @@ -51,6 +51,28 @@ namespace ts { } }`); + testExtractConstant("extractConstant_ClassInsertionPosition2", + `class C { + a = 1; + M1() { } + b = 2; + M2() { } + M3() { + let x = [#|1|]; + } +}`); + + testExtractConstant("extractConstant_ClassInsertionPosition3", + `class C { + M1() { } + a = 1; + b = 2; + M2() { } + M3() { + let x = [#|1|]; + } +}`); + testExtractConstant("extractConstant_Parameters", `function F() { let w = 1; @@ -62,26 +84,126 @@ namespace ts { let x = [#|t + 1|]; }`); -// TODO (acasey): handle repeated substitution +// TODO (18857): handle repeated substitution // testExtractConstant("extractConstant_RepeatedSubstitution", // `namespace X { // export const j = 10; // export const y = [#|j * j|]; // }`); - testExtractConstantFailed("extractConstant_BlockScopes_Dependencies", - `for (let i = 0; i < 10; i++) { + testExtractConstant("extractConstant_VariableList_const", + `const a = 1, b = [#|a + 1|];`); + + // NOTE: this test isn't normative - it just documents our sub-optimal behavior. + testExtractConstant("extractConstant_VariableList_let", + `let a = 1, b = [#|a + 1|];`); + + // NOTE: this test isn't normative - it just documents our sub-optimal behavior. + testExtractConstant("extractConstant_VariableList_MultipleLines", + `const /*About A*/a = 1, + /*About B*/b = [#|a + 1|];`); + + testExtractConstant("extractConstant_BlockScopeMismatch", ` +for (let i = 0; i < 10; i++) { for (let j = 0; j < 10; j++) { - let x = [#|i + 1|]; + const x = [#|i + 1|]; } -}`); +} + `); + + testExtractConstant("extractConstant_StatementInsertionPosition1", ` +const i = 0; +for (let j = 0; j < 10; j++) { + const x = [#|i + 1|]; +} + `); + + testExtractConstant("extractConstant_StatementInsertionPosition2", ` +const i = 0; +function F() { + for (let j = 0; j < 10; j++) { + const x = [#|i + 1|]; + } +} + `); + + testExtractConstant("extractConstant_StatementInsertionPosition3", ` +for (let j = 0; j < 10; j++) { + const x = [#|2 + 1|]; +} + `); + + testExtractConstant("extractConstant_StatementInsertionPosition4", ` +function F() { + for (let j = 0; j < 10; j++) { + const x = [#|2 + 1|]; + } +} + `); + + testExtractConstant("extractConstant_StatementInsertionPosition5", ` +function F0() { + function F1() { + function F2(x = [#|2 + 1|]) { + } + } +} + `); + + testExtractConstant("extractConstant_StatementInsertionPosition6", ` +class C { + x = [#|2 + 1|]; +} + `); + + testExtractConstant("extractConstant_StatementInsertionPosition7", ` +const i = 0; +class C { + M() { + for (let j = 0; j < 10; j++) { + x = [#|i + 1|]; + } + } +} + `); + + testExtractConstant("extractConstant_TripleSlash", ` +/// + +const x = [#|2 + 1|]; + `); + + testExtractConstant("extractConstant_PinnedComment", ` +/*! Copyright */ + +const x = [#|2 + 1|]; + `); + + testExtractConstant("extractConstant_Directive", ` +"strict"; + +const x = [#|2 + 1|]; + `); + + testExtractConstant("extractConstant_MultipleHeaders", ` +/*! Copyright */ + +/// + +"strict"; + +const x = [#|2 + 1|]; + `); + + testExtractConstant("extractConstant_PinnedCommentAndDocComment", ` +/*! Copyright */ + +/* About x */ +const x = [#|2 + 1|]; + `); }); function testExtractConstant(caption: string, text: string) { testExtractSymbol(caption, text, "extractConstant", Diagnostics.Extract_constant); } - - function testExtractConstantFailed(caption: string, text: string) { - testExtractSymbolFailed(caption, text, Diagnostics.Extract_constant); - } } diff --git a/src/harness/unittests/extractFunctions.ts b/src/harness/unittests/extractFunctions.ts index 27c21ce3fb6..291324e08f3 100644 --- a/src/harness/unittests/extractFunctions.ts +++ b/src/harness/unittests/extractFunctions.ts @@ -355,7 +355,7 @@ function parsePrimaryExpression(): any { [#|function G() { }|] }`); -// TODO (acasey): handle repeated substitution +// TODO (18857): handle repeated substitution // testExtractFunction("extractFunction_RepeatedSubstitution", // `namespace X { // export const j = 10; diff --git a/src/harness/unittests/extractTestHelpers.ts b/src/harness/unittests/extractTestHelpers.ts index ea1cccd32ea..0d739919e1f 100644 --- a/src/harness/unittests/extractTestHelpers.ts +++ b/src/harness/unittests/extractTestHelpers.ts @@ -113,7 +113,7 @@ namespace ts { if (hasSyntacticDiagnostics(program)) { // Don't bother generating JS baselines for inputs that aren't valid JS. - assert.equal(Extension.Js, extension); + assert.equal(Extension.Js, extension, "Syntactic diagnostics found in non-JS file"); return; } diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 96f4b7ad4b5..f516bc15de3 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -407,28 +407,6 @@ namespace ts.codefix { moduleSpecifierWithoutQuotes ); - function getSourceFileImportLocation(node: SourceFile) { - // For a source file, it is possible there are detached comments we should not skip - const text = node.text; - let ranges = getLeadingCommentRanges(text, 0); - if (!ranges) return 0; - let position = 0; - // However we should still skip a pinned comment at the top - if (ranges.length && ranges[0].kind === SyntaxKind.MultiLineCommentTrivia && isPinnedComment(text, ranges[0])) { - position = ranges[0].end + 1; - ranges = ranges.slice(1); - } - // As well as any triple slash references - for (const range of ranges) { - if (range.kind === SyntaxKind.SingleLineCommentTrivia && isRecognizedTripleSlashComment(node.text, range.pos, range.end)) { - position = range.end + 1; - continue; - } - break; - } - return position; - } - function getSingleQuoteStyleFromExistingImports() { const firstModuleSpecifier = forEach(sourceFile.statements, node => { if (isImportDeclaration(node) || isExportDeclaration(node)) { diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index b88a013f52b..df9da034da6 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -43,7 +43,7 @@ namespace ts.refactor.extractSymbol { // Don't issue refactorings with duplicated names. // Scopes come back in "innermost first" order, so extractions will // preferentially go into nearer scopes - const description = formatStringFromArgs(Diagnostics.Extract_to_0.message, [extraction.functionDescription]); + const description = formatStringFromArgs(Diagnostics.Extract_to_0_in_1.message, [extraction.functionDescription, extraction.functionScopeDescription]); if (!usedFunctionNames.has(description)) { usedFunctionNames.set(description, true); functionActions.push({ @@ -58,7 +58,7 @@ namespace ts.refactor.extractSymbol { // Don't issue refactorings with duplicated names. // Scopes come back in "innermost first" order, so extractions will // preferentially go into nearer scopes - const description = formatStringFromArgs(Diagnostics.Extract_to_0.message, [extraction.constantDescription]); + const description = formatStringFromArgs(Diagnostics.Extract_to_0_in_1.message, [extraction.constantDescription, extraction.constantScopeDescription]); if (!usedConstantNames.has(description)) { usedConstantNames.set(description, true); constantActions.push({ @@ -523,8 +523,10 @@ namespace ts.refactor.extractSymbol { interface PossibleExtraction { readonly functionDescription: string; + readonly functionScopeDescription: string; readonly functionErrors: ReadonlyArray; readonly constantDescription: string; + readonly constantScopeDescription: string; readonly constantErrors: ReadonlyArray; } /** @@ -535,12 +537,23 @@ namespace ts.refactor.extractSymbol { function getPossibleExtractions(targetRange: TargetRange, context: RefactorContext): ReadonlyArray | undefined { const { scopes, readsAndWrites: { functionErrorsPerScope, constantErrorsPerScope } } = getPossibleExtractionsWorker(targetRange, context); // Need the inner type annotation to avoid https://github.com/Microsoft/TypeScript/issues/7547 - const extractions = scopes.map((scope, i): PossibleExtraction => ({ - functionDescription: getDescriptionForFunctionInScope(scope), - functionErrors: functionErrorsPerScope[i], - constantDescription: getDescriptionForConstantInScope(scope), - constantErrors: constantErrorsPerScope[i], - })); + const extractions = scopes.map((scope, i): PossibleExtraction => { + const scopeDescription = isFunctionLikeDeclaration(scope) + ? getDescriptionForFunctionLikeDeclaration(scope) + : isClassLike(scope) + ? getDescriptionForClassLikeDeclaration(scope) + : getDescriptionForModuleLikeDeclaration(scope); + return { + functionDescription: getDescriptionForFunctionInScope(scope), + functionErrors: functionErrorsPerScope[i], + functionScopeDescription: scopeDescription, + constantDescription: getDescriptionForConstantInScope(scope), + constantErrors: constantErrorsPerScope[i], + constantScopeDescription: (i === 0 && !isClassLike(scope)) + ? "enclosing scope" // Like "global scope" and "module scope", this is not localized. + : scopeDescription, + }; + }); return extractions; } @@ -569,17 +582,15 @@ namespace ts.refactor.extractSymbol { function getDescriptionForFunctionInScope(scope: Scope): string { return isFunctionLikeDeclaration(scope) - ? `inner function in ${getDescriptionForFunctionLikeDeclaration(scope)}` + ? "inner function" : isClassLike(scope) - ? `method in ${getDescriptionForClassLikeDeclaration(scope)}` - : `function in ${getDescriptionForModuleLikeDeclaration(scope)}`; + ? "method" + : "function"; } function getDescriptionForConstantInScope(scope: Scope): string { - return isFunctionLikeDeclaration(scope) - ? `constant in ${getDescriptionForFunctionLikeDeclaration(scope)}` - : isClassLike(scope) - ? `readonly field in ${getDescriptionForClassLikeDeclaration(scope)}` - : `constant in ${getDescriptionForModuleLikeDeclaration(scope)}`; + return isClassLike(scope) + ? "readonly field" + : "constant"; } function getDescriptionForFunctionLikeDeclaration(scope: FunctionLikeDeclaration): string { switch (scope.kind) { @@ -869,33 +880,61 @@ namespace ts.refactor.extractSymbol { createIdentifier(localNameText)); // Declare - const minInsertionPos = node.end; - const nodeToInsertBefore = getNodeToInsertConstantBefore(minInsertionPos, scope); + const maxInsertionPos = node.pos; + const nodeToInsertBefore = getNodeToInsertPropertyBefore(maxInsertionPos, scope); changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newVariable, { suffix: context.newLineCharacter + context.newLineCharacter }); // Consume changeTracker.replaceNodeWithNodes(context.file, node, [localReference], { nodeSeparator: context.newLineCharacter }); } else { - const newVariable = createVariableStatement( - /*modifiers*/ undefined, - createVariableDeclarationList( - [createVariableDeclaration(localNameText, variableType, initializer)], - NodeFlags.Const)); + const newVariableDeclaration = createVariableDeclaration(localNameText, variableType, initializer); - // If the parent is an expression statement, replace the statement with the declaration - if (node.parent.kind === SyntaxKind.ExpressionStatement) { - changeTracker.replaceNodeWithNodes(context.file, node.parent, [newVariable], { nodeSeparator: context.newLineCharacter }); - } - else { + // If the node is part of an initializer in a list of variable declarations, insert a new + // variable declaration into the list (in case it depends on earlier ones). + // CONSIDER: If the declaration list isn't const, we might want to split it into multiple + // lists so that the newly extracted one can be const. + const oldVariableDeclaration = getContainingVariableDeclarationIfInList(node, scope); + if (oldVariableDeclaration) { // Declare - const minInsertionPos = node.end; - const nodeToInsertBefore = getNodeToInsertConstantBefore(minInsertionPos, scope); - changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newVariable, { suffix: context.newLineCharacter + context.newLineCharacter }); + // CONSIDER: could detect that each is on a separate line + changeTracker.insertNodeAt(context.file, oldVariableDeclaration.getStart(), newVariableDeclaration, { suffix: ", " }); // Consume const localReference = createIdentifier(localNameText); - changeTracker.replaceNodeWithNodes(context.file, node, [localReference], { nodeSeparator: context.newLineCharacter }); + changeTracker.replaceRange(context.file, { pos: node.getStart(), end: node.end }, localReference); + } + else if (node.parent.kind === SyntaxKind.ExpressionStatement) { + // If the parent is an expression statement, replace the statement with the declaration. + const newVariableStatement = createVariableStatement( + /*modifiers*/ undefined, + createVariableDeclarationList([newVariableDeclaration], NodeFlags.Const)); + changeTracker.replaceNodeWithNodes(context.file, node.parent, [newVariableStatement], { nodeSeparator: context.newLineCharacter }); + } + else { + const newVariableStatement = createVariableStatement( + /*modifiers*/ undefined, + createVariableDeclarationList([newVariableDeclaration], NodeFlags.Const)); + + // Declare + const nodeToInsertBefore = getNodeToInsertConstantBefore(node, scope); + if (nodeToInsertBefore.pos === 0) { + // If we're at the beginning of the file, we need to take care not to insert before header comments + // (e.g. copyright, triple-slash references). Fortunately, this problem has already been solved + // for imports. + const insertionPos = getSourceFileImportLocation(file); + changeTracker.insertNodeAt(context.file, insertionPos, newVariableStatement, { + prefix: insertionPos === 0 ? undefined : context.newLineCharacter, + suffix: isLineBreak(file.text.charCodeAt(insertionPos)) ? context.newLineCharacter : context.newLineCharacter + context.newLineCharacter + }); + } + else { + changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newVariableStatement, { suffix: context.newLineCharacter + context.newLineCharacter }); + } + + // Consume + const localReference = createIdentifier(localNameText); + changeTracker.replaceRange(context.file, { pos: node.getStart(), end: node.end }, localReference); } } @@ -906,6 +945,22 @@ namespace ts.refactor.extractSymbol { return { renameFilename, renameLocation, edits }; } + function getContainingVariableDeclarationIfInList(node: Node, scope: Scope) { + let prevNode = undefined; + while (node !== undefined && node !== scope) { + if (isVariableDeclaration(node) && + node.initializer === prevNode && + isVariableDeclarationList(node.parent) && + node.parent.declarations.length > 1) { + + return node; + } + + prevNode = node; + node = node.parent; + } + } + /** * @return The index of the (only) reference to the extracted symbol. We want the cursor * to be on the reference, rather than the declaration, because it's closer to where the @@ -1088,26 +1143,61 @@ namespace ts.refactor.extractSymbol { child.pos >= minPos && isFunctionLikeDeclaration(child) && !isConstructorDeclaration(child)); } - // TODO (acasey): need to dig into nested statements - // TODO (acasey): don't insert before pinned comments, directives, or triple-slash references - function getNodeToInsertConstantBefore(maxPos: number, scope: Scope): Node { - const children = getStatementsOrClassElements(scope); - Debug.assert(children.length > 0); // There must be at least one child, since we extracted from one. + function getNodeToInsertPropertyBefore(maxPos: number, scope: ClassLikeDeclaration): Node { + const members = scope.members; + Debug.assert(members.length > 0); // There must be at least one child, since we extracted from one. - const isClassLikeScope = isClassLike(scope); - let prevChild: Statement | ClassElement | undefined = undefined; - for (const child of children) { - if (child.pos >= maxPos) { - break; + let prevMember: ClassElement | undefined = undefined; + let allProperties = true; + for (const member of members) { + if (member.pos > maxPos) { + return prevMember || members[0]; } - prevChild = child; - if (isClassLikeScope && !isPropertyDeclaration(child)) { - break; + if (allProperties && !isPropertyDeclaration(member)) { + // If it is non-vacuously true that all preceding members are properties, + // insert before the current member (i.e. at the end of the list of properties). + if (prevMember !== undefined) { + return member; + } + + allProperties = false; + } + prevMember = member; + } + + Debug.assert(prevMember !== undefined); // If the loop didn't return, then it did set prevMember. + return prevMember; + } + + function getNodeToInsertConstantBefore(node: Node, scope: Scope): Node { + Debug.assert(!isClassLike(scope)); + + let prevScope: Scope | undefined = undefined; + for (let curr = node; curr !== scope; curr = curr.parent) { + if (isScope(curr)) { + prevScope = curr; } } - Debug.assert(prevChild !== undefined); - return prevChild; + for (let curr = (prevScope || node).parent; ; curr = curr.parent) { + if (isBlockLike(curr)) { + let prevStatement = undefined; + for (const statement of curr.statements) { + if (statement.pos > node.pos) { + break; + } + prevStatement = statement; + } + // There must be at least one statement since we started in one. + Debug.assert(prevStatement !== undefined); + return prevStatement; + } + + if (curr === scope) { + Debug.fail("Didn't encounter a block-like before encountering scope"); + break; + } + } } function getPropertyAssignmentsForWrites(writes: ReadonlyArray): ShorthandPropertyAssignment[] { @@ -1249,7 +1339,10 @@ namespace ts.refactor.extractSymbol { for (let i = 0; i < scopes.length; i++) { if (!isReadonlyArray(targetRange.range)) { const scopeUsages = usagesPerScope[i]; - if (scopeUsages.usages.size > 0 || scopeUsages.typeParameterUsages.size > 0) { + // Special case: in the innermost scope, all usages are available. + // (The computed value reflects the value at the top-level of the scope, but the + // local will actually be declared at the same level as the extracted expression). + if (i > 0 && (scopeUsages.usages.size > 0 || scopeUsages.typeParameterUsages.size > 0)) { constantErrorsPerScope[i].push(createDiagnosticForNode(targetRange.range, Messages.CannotAccessVariablesFromNestedScopes)); } } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index f367c48ac6f..ee74a8680eb 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1332,4 +1332,26 @@ namespace ts { export function getOpenBraceOfClassLike(declaration: ClassLikeDeclaration, sourceFile: SourceFile) { return getTokenAtPosition(sourceFile, declaration.members.pos - 1, /*includeJsDocComment*/ false); } + + export function getSourceFileImportLocation(node: SourceFile) { + // For a source file, it is possible there are detached comments we should not skip + const text = node.text; + let ranges = getLeadingCommentRanges(text, 0); + if (!ranges) return 0; + let position = 0; + // However we should still skip a pinned comment at the top + if (ranges.length && ranges[0].kind === SyntaxKind.MultiLineCommentTrivia && isPinnedComment(text, ranges[0])) { + position = ranges[0].end + 1; + ranges = ranges.slice(1); + } + // As well as any triple slash references + for (const range of ranges) { + if (range.kind === SyntaxKind.SingleLineCommentTrivia && isRecognizedTripleSlashComment(node.text, range.pos, range.end)) { + position = range.end + 1; + continue; + } + break; + } + return position; + } } diff --git a/tests/baselines/reference/extractConstant/extractConstant_BlockScopeMismatch.js b/tests/baselines/reference/extractConstant/extractConstant_BlockScopeMismatch.js new file mode 100644 index 00000000000..65871513e18 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_BlockScopeMismatch.js @@ -0,0 +1,18 @@ +// ==ORIGINAL== + +for (let i = 0; i < 10; i++) { + for (let j = 0; j < 10; j++) { + const x = i + 1; + } +} + +// ==SCOPE::Extract to constant in enclosing scope== + +for (let i = 0; i < 10; i++) { + for (let j = 0; j < 10; j++) { + const newLocal = i + 1; + + const x = /*RENAME*/newLocal; + } +} + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_BlockScopeMismatch.ts b/tests/baselines/reference/extractConstant/extractConstant_BlockScopeMismatch.ts new file mode 100644 index 00000000000..65871513e18 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_BlockScopeMismatch.ts @@ -0,0 +1,18 @@ +// ==ORIGINAL== + +for (let i = 0; i < 10; i++) { + for (let j = 0; j < 10; j++) { + const x = i + 1; + } +} + +// ==SCOPE::Extract to constant in enclosing scope== + +for (let i = 0; i < 10; i++) { + for (let j = 0; j < 10; j++) { + const newLocal = i + 1; + + const x = /*RENAME*/newLocal; + } +} + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_BlockScopes_NoDependencies.js b/tests/baselines/reference/extractConstant/extractConstant_BlockScopes_NoDependencies.js index 25609a3a801..4446502920a 100644 --- a/tests/baselines/reference/extractConstant/extractConstant_BlockScopes_NoDependencies.js +++ b/tests/baselines/reference/extractConstant/extractConstant_BlockScopes_NoDependencies.js @@ -4,11 +4,11 @@ for (let i = 0; i < 10; i++) { let x = 1; } } -// ==SCOPE::Extract to constant in global scope== -const newLocal = 1; - +// ==SCOPE::Extract to constant in enclosing scope== for (let i = 0; i < 10; i++) { for (let j = 0; j < 10; j++) { + const newLocal = 1; + let x = /*RENAME*/newLocal; } } \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_BlockScopes_NoDependencies.ts b/tests/baselines/reference/extractConstant/extractConstant_BlockScopes_NoDependencies.ts index 25609a3a801..4446502920a 100644 --- a/tests/baselines/reference/extractConstant/extractConstant_BlockScopes_NoDependencies.ts +++ b/tests/baselines/reference/extractConstant/extractConstant_BlockScopes_NoDependencies.ts @@ -4,11 +4,11 @@ for (let i = 0; i < 10; i++) { let x = 1; } } -// ==SCOPE::Extract to constant in global scope== -const newLocal = 1; - +// ==SCOPE::Extract to constant in enclosing scope== for (let i = 0; i < 10; i++) { for (let j = 0; j < 10; j++) { + const newLocal = 1; + let x = /*RENAME*/newLocal; } } \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition.js b/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition1.js similarity index 89% rename from tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition.js rename to tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition1.js index 4e7bcc0521a..6fa63a655f5 100644 --- a/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition.js +++ b/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition1.js @@ -8,7 +8,7 @@ class C { let x = 1; } } -// ==SCOPE::Extract to constant in method 'M3== +// ==SCOPE::Extract to constant in enclosing scope== class C { a = 1; b = 2; diff --git a/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition.ts b/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition1.ts similarity index 92% rename from tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition.ts rename to tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition1.ts index e024fda34bc..15c5d22a34b 100644 --- a/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition.ts +++ b/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition1.ts @@ -8,7 +8,7 @@ class C { let x = 1; } } -// ==SCOPE::Extract to constant in method 'M3== +// ==SCOPE::Extract to constant in enclosing scope== class C { a = 1; b = 2; diff --git a/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition2.js b/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition2.js new file mode 100644 index 00000000000..3273cfbeaa0 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition2.js @@ -0,0 +1,34 @@ +// ==ORIGINAL== +class C { + a = 1; + M1() { } + b = 2; + M2() { } + M3() { + let x = 1; + } +} +// ==SCOPE::Extract to constant in enclosing scope== +class C { + a = 1; + M1() { } + b = 2; + M2() { } + M3() { + const newLocal = 1; + + let x = /*RENAME*/newLocal; + } +} +// ==SCOPE::Extract to constant in global scope== +const newLocal = 1; + +class C { + a = 1; + M1() { } + b = 2; + M2() { } + M3() { + let x = /*RENAME*/newLocal; + } +} \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition2.ts b/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition2.ts new file mode 100644 index 00000000000..777173b0dcd --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition2.ts @@ -0,0 +1,46 @@ +// ==ORIGINAL== +class C { + a = 1; + M1() { } + b = 2; + M2() { } + M3() { + let x = 1; + } +} +// ==SCOPE::Extract to constant in enclosing scope== +class C { + a = 1; + M1() { } + b = 2; + M2() { } + M3() { + const newLocal = 1; + + let x = /*RENAME*/newLocal; + } +} +// ==SCOPE::Extract to readonly field in class 'C'== +class C { + a = 1; + private readonly newProperty = 1; + + M1() { } + b = 2; + M2() { } + M3() { + let x = this./*RENAME*/newProperty; + } +} +// ==SCOPE::Extract to constant in global scope== +const newLocal = 1; + +class C { + a = 1; + M1() { } + b = 2; + M2() { } + M3() { + let x = /*RENAME*/newLocal; + } +} \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition3.js b/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition3.js new file mode 100644 index 00000000000..b990075166e --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition3.js @@ -0,0 +1,34 @@ +// ==ORIGINAL== +class C { + M1() { } + a = 1; + b = 2; + M2() { } + M3() { + let x = 1; + } +} +// ==SCOPE::Extract to constant in enclosing scope== +class C { + M1() { } + a = 1; + b = 2; + M2() { } + M3() { + const newLocal = 1; + + let x = /*RENAME*/newLocal; + } +} +// ==SCOPE::Extract to constant in global scope== +const newLocal = 1; + +class C { + M1() { } + a = 1; + b = 2; + M2() { } + M3() { + let x = /*RENAME*/newLocal; + } +} \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition3.ts b/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition3.ts new file mode 100644 index 00000000000..516a24b8b20 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_ClassInsertionPosition3.ts @@ -0,0 +1,46 @@ +// ==ORIGINAL== +class C { + M1() { } + a = 1; + b = 2; + M2() { } + M3() { + let x = 1; + } +} +// ==SCOPE::Extract to constant in enclosing scope== +class C { + M1() { } + a = 1; + b = 2; + M2() { } + M3() { + const newLocal = 1; + + let x = /*RENAME*/newLocal; + } +} +// ==SCOPE::Extract to readonly field in class 'C'== +class C { + M1() { } + a = 1; + b = 2; + M2() { } + private readonly newProperty = 1; + + M3() { + let x = this./*RENAME*/newProperty; + } +} +// ==SCOPE::Extract to constant in global scope== +const newLocal = 1; + +class C { + M1() { } + a = 1; + b = 2; + M2() { } + M3() { + let x = /*RENAME*/newLocal; + } +} \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_Directive.js b/tests/baselines/reference/extractConstant/extractConstant_Directive.js new file mode 100644 index 00000000000..85b9ff76200 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_Directive.js @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +"strict"; + +const x = 2 + 1; + +// ==SCOPE::Extract to constant in enclosing scope== + +"strict"; + +const newLocal = 2 + 1; + +const x = /*RENAME*/newLocal; + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_Directive.ts b/tests/baselines/reference/extractConstant/extractConstant_Directive.ts new file mode 100644 index 00000000000..85b9ff76200 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_Directive.ts @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +"strict"; + +const x = 2 + 1; + +// ==SCOPE::Extract to constant in enclosing scope== + +"strict"; + +const newLocal = 2 + 1; + +const x = /*RENAME*/newLocal; + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatement.js b/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatement.js index 6bf35cd17e1..c3ccdde3b4f 100644 --- a/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatement.js +++ b/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatement.js @@ -1,4 +1,4 @@ // ==ORIGINAL== "hello"; -// ==SCOPE::Extract to constant in global scope== +// ==SCOPE::Extract to constant in enclosing scope== const /*RENAME*/newLocal = "hello"; \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatement.ts b/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatement.ts index 6bf35cd17e1..c3ccdde3b4f 100644 --- a/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatement.ts +++ b/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatement.ts @@ -1,4 +1,4 @@ // ==ORIGINAL== "hello"; -// ==SCOPE::Extract to constant in global scope== +// ==SCOPE::Extract to constant in enclosing scope== const /*RENAME*/newLocal = "hello"; \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatementExpression.js b/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatementExpression.js index 6bf35cd17e1..c3ccdde3b4f 100644 --- a/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatementExpression.js +++ b/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatementExpression.js @@ -1,4 +1,4 @@ // ==ORIGINAL== "hello"; -// ==SCOPE::Extract to constant in global scope== +// ==SCOPE::Extract to constant in enclosing scope== const /*RENAME*/newLocal = "hello"; \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatementExpression.ts b/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatementExpression.ts index 6bf35cd17e1..c3ccdde3b4f 100644 --- a/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatementExpression.ts +++ b/tests/baselines/reference/extractConstant/extractConstant_ExpressionStatementExpression.ts @@ -1,4 +1,4 @@ // ==ORIGINAL== "hello"; -// ==SCOPE::Extract to constant in global scope== +// ==SCOPE::Extract to constant in enclosing scope== const /*RENAME*/newLocal = "hello"; \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_Function.js b/tests/baselines/reference/extractConstant/extractConstant_Function.js index 67c8255c4b4..cff41806566 100644 --- a/tests/baselines/reference/extractConstant/extractConstant_Function.js +++ b/tests/baselines/reference/extractConstant/extractConstant_Function.js @@ -2,7 +2,7 @@ function F() { let x = 1; } -// ==SCOPE::Extract to constant in function 'F'== +// ==SCOPE::Extract to constant in enclosing scope== function F() { const newLocal = 1; diff --git a/tests/baselines/reference/extractConstant/extractConstant_Function.ts b/tests/baselines/reference/extractConstant/extractConstant_Function.ts index 67c8255c4b4..cff41806566 100644 --- a/tests/baselines/reference/extractConstant/extractConstant_Function.ts +++ b/tests/baselines/reference/extractConstant/extractConstant_Function.ts @@ -2,7 +2,7 @@ function F() { let x = 1; } -// ==SCOPE::Extract to constant in function 'F'== +// ==SCOPE::Extract to constant in enclosing scope== function F() { const newLocal = 1; diff --git a/tests/baselines/reference/extractConstant/extractConstant_Method.js b/tests/baselines/reference/extractConstant/extractConstant_Method.js index bd7c7f86359..32b74d00576 100644 --- a/tests/baselines/reference/extractConstant/extractConstant_Method.js +++ b/tests/baselines/reference/extractConstant/extractConstant_Method.js @@ -4,7 +4,7 @@ class C { let x = 1; } } -// ==SCOPE::Extract to constant in method 'M== +// ==SCOPE::Extract to constant in enclosing scope== class C { M() { const newLocal = 1; diff --git a/tests/baselines/reference/extractConstant/extractConstant_Method.ts b/tests/baselines/reference/extractConstant/extractConstant_Method.ts index 1ae4c8b1cb5..5514b702597 100644 --- a/tests/baselines/reference/extractConstant/extractConstant_Method.ts +++ b/tests/baselines/reference/extractConstant/extractConstant_Method.ts @@ -4,7 +4,7 @@ class C { let x = 1; } } -// ==SCOPE::Extract to constant in method 'M== +// ==SCOPE::Extract to constant in enclosing scope== class C { M() { const newLocal = 1; diff --git a/tests/baselines/reference/extractConstant/extractConstant_MultipleHeaders.js b/tests/baselines/reference/extractConstant/extractConstant_MultipleHeaders.js new file mode 100644 index 00000000000..2ccf5932d38 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_MultipleHeaders.js @@ -0,0 +1,22 @@ +// ==ORIGINAL== + +/*! Copyright */ + +/// + +"strict"; + +const x = 2 + 1; + +// ==SCOPE::Extract to constant in enclosing scope== + +/*! Copyright */ + +/// + +"strict"; + +const newLocal = 2 + 1; + +const x = /*RENAME*/newLocal; + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_MultipleHeaders.ts b/tests/baselines/reference/extractConstant/extractConstant_MultipleHeaders.ts new file mode 100644 index 00000000000..2ccf5932d38 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_MultipleHeaders.ts @@ -0,0 +1,22 @@ +// ==ORIGINAL== + +/*! Copyright */ + +/// + +"strict"; + +const x = 2 + 1; + +// ==SCOPE::Extract to constant in enclosing scope== + +/*! Copyright */ + +/// + +"strict"; + +const newLocal = 2 + 1; + +const x = /*RENAME*/newLocal; + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_Namespace.ts b/tests/baselines/reference/extractConstant/extractConstant_Namespace.ts index 8f25847165f..81a543d29c4 100644 --- a/tests/baselines/reference/extractConstant/extractConstant_Namespace.ts +++ b/tests/baselines/reference/extractConstant/extractConstant_Namespace.ts @@ -2,7 +2,7 @@ namespace N { let x = 1; } -// ==SCOPE::Extract to constant in namespace 'N'== +// ==SCOPE::Extract to constant in enclosing scope== namespace N { const newLocal = 1; diff --git a/tests/baselines/reference/extractConstant/extractConstant_Parameters.js b/tests/baselines/reference/extractConstant/extractConstant_Parameters.js index e6c9c474fbc..b90f78d96af 100644 --- a/tests/baselines/reference/extractConstant/extractConstant_Parameters.js +++ b/tests/baselines/reference/extractConstant/extractConstant_Parameters.js @@ -3,7 +3,7 @@ function F() { let w = 1; let x = w + 1; } -// ==SCOPE::Extract to constant in function 'F'== +// ==SCOPE::Extract to constant in enclosing scope== function F() { let w = 1; const newLocal = w + 1; diff --git a/tests/baselines/reference/extractConstant/extractConstant_Parameters.ts b/tests/baselines/reference/extractConstant/extractConstant_Parameters.ts index e6c9c474fbc..b90f78d96af 100644 --- a/tests/baselines/reference/extractConstant/extractConstant_Parameters.ts +++ b/tests/baselines/reference/extractConstant/extractConstant_Parameters.ts @@ -3,7 +3,7 @@ function F() { let w = 1; let x = w + 1; } -// ==SCOPE::Extract to constant in function 'F'== +// ==SCOPE::Extract to constant in enclosing scope== function F() { let w = 1; const newLocal = w + 1; diff --git a/tests/baselines/reference/extractConstant/extractConstant_PinnedComment.js b/tests/baselines/reference/extractConstant/extractConstant_PinnedComment.js new file mode 100644 index 00000000000..cc897b5c6b9 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_PinnedComment.js @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +/*! Copyright */ + +const x = 2 + 1; + +// ==SCOPE::Extract to constant in enclosing scope== + +/*! Copyright */ + +const newLocal = 2 + 1; + +const x = /*RENAME*/newLocal; + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_PinnedComment.ts b/tests/baselines/reference/extractConstant/extractConstant_PinnedComment.ts new file mode 100644 index 00000000000..cc897b5c6b9 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_PinnedComment.ts @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +/*! Copyright */ + +const x = 2 + 1; + +// ==SCOPE::Extract to constant in enclosing scope== + +/*! Copyright */ + +const newLocal = 2 + 1; + +const x = /*RENAME*/newLocal; + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_PinnedCommentAndDocComment.js b/tests/baselines/reference/extractConstant/extractConstant_PinnedCommentAndDocComment.js new file mode 100644 index 00000000000..9ee07c7cd6a --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_PinnedCommentAndDocComment.js @@ -0,0 +1,16 @@ +// ==ORIGINAL== + +/*! Copyright */ + +/* About x */ +const x = 2 + 1; + +// ==SCOPE::Extract to constant in enclosing scope== + +/*! Copyright */ + +const newLocal = 2 + 1; + +/* About x */ +const x = /*RENAME*/newLocal; + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_PinnedCommentAndDocComment.ts b/tests/baselines/reference/extractConstant/extractConstant_PinnedCommentAndDocComment.ts new file mode 100644 index 00000000000..9ee07c7cd6a --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_PinnedCommentAndDocComment.ts @@ -0,0 +1,16 @@ +// ==ORIGINAL== + +/*! Copyright */ + +/* About x */ +const x = 2 + 1; + +// ==SCOPE::Extract to constant in enclosing scope== + +/*! Copyright */ + +const newLocal = 2 + 1; + +/* About x */ +const x = /*RENAME*/newLocal; + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition1.js b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition1.js new file mode 100644 index 00000000000..2197dd13e3a --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition1.js @@ -0,0 +1,16 @@ +// ==ORIGINAL== + +const i = 0; +for (let j = 0; j < 10; j++) { + const x = i + 1; +} + +// ==SCOPE::Extract to constant in enclosing scope== + +const i = 0; +for (let j = 0; j < 10; j++) { + const newLocal = i + 1; + + const x = /*RENAME*/newLocal; +} + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition1.ts b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition1.ts new file mode 100644 index 00000000000..2197dd13e3a --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition1.ts @@ -0,0 +1,16 @@ +// ==ORIGINAL== + +const i = 0; +for (let j = 0; j < 10; j++) { + const x = i + 1; +} + +// ==SCOPE::Extract to constant in enclosing scope== + +const i = 0; +for (let j = 0; j < 10; j++) { + const newLocal = i + 1; + + const x = /*RENAME*/newLocal; +} + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition2.js b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition2.js new file mode 100644 index 00000000000..900798c19ab --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition2.js @@ -0,0 +1,31 @@ +// ==ORIGINAL== + +const i = 0; +function F() { + for (let j = 0; j < 10; j++) { + const x = i + 1; + } +} + +// ==SCOPE::Extract to constant in enclosing scope== + +const i = 0; +function F() { + for (let j = 0; j < 10; j++) { + const newLocal = i + 1; + + const x = /*RENAME*/newLocal; + } +} + +// ==SCOPE::Extract to constant in global scope== + +const i = 0; +const newLocal = i + 1; + +function F() { + for (let j = 0; j < 10; j++) { + const x = /*RENAME*/newLocal; + } +} + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition2.ts b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition2.ts new file mode 100644 index 00000000000..900798c19ab --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition2.ts @@ -0,0 +1,31 @@ +// ==ORIGINAL== + +const i = 0; +function F() { + for (let j = 0; j < 10; j++) { + const x = i + 1; + } +} + +// ==SCOPE::Extract to constant in enclosing scope== + +const i = 0; +function F() { + for (let j = 0; j < 10; j++) { + const newLocal = i + 1; + + const x = /*RENAME*/newLocal; + } +} + +// ==SCOPE::Extract to constant in global scope== + +const i = 0; +const newLocal = i + 1; + +function F() { + for (let j = 0; j < 10; j++) { + const x = /*RENAME*/newLocal; + } +} + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition3.js b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition3.js new file mode 100644 index 00000000000..3f2f7089ef3 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition3.js @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +for (let j = 0; j < 10; j++) { + const x = 2 + 1; +} + +// ==SCOPE::Extract to constant in enclosing scope== + +for (let j = 0; j < 10; j++) { + const newLocal = 2 + 1; + + const x = /*RENAME*/newLocal; +} + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition3.ts b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition3.ts new file mode 100644 index 00000000000..3f2f7089ef3 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition3.ts @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +for (let j = 0; j < 10; j++) { + const x = 2 + 1; +} + +// ==SCOPE::Extract to constant in enclosing scope== + +for (let j = 0; j < 10; j++) { + const newLocal = 2 + 1; + + const x = /*RENAME*/newLocal; +} + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition4.js b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition4.js new file mode 100644 index 00000000000..4c7c2a50217 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition4.js @@ -0,0 +1,27 @@ +// ==ORIGINAL== + +function F() { + for (let j = 0; j < 10; j++) { + const x = 2 + 1; + } +} + +// ==SCOPE::Extract to constant in enclosing scope== + +function F() { + for (let j = 0; j < 10; j++) { + const newLocal = 2 + 1; + + const x = /*RENAME*/newLocal; + } +} + +// ==SCOPE::Extract to constant in global scope== +const newLocal = 2 + 1; + +function F() { + for (let j = 0; j < 10; j++) { + const x = /*RENAME*/newLocal; + } +} + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition4.ts b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition4.ts new file mode 100644 index 00000000000..4c7c2a50217 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition4.ts @@ -0,0 +1,27 @@ +// ==ORIGINAL== + +function F() { + for (let j = 0; j < 10; j++) { + const x = 2 + 1; + } +} + +// ==SCOPE::Extract to constant in enclosing scope== + +function F() { + for (let j = 0; j < 10; j++) { + const newLocal = 2 + 1; + + const x = /*RENAME*/newLocal; + } +} + +// ==SCOPE::Extract to constant in global scope== +const newLocal = 2 + 1; + +function F() { + for (let j = 0; j < 10; j++) { + const x = /*RENAME*/newLocal; + } +} + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition5.js b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition5.js new file mode 100644 index 00000000000..4b9647fa445 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition5.js @@ -0,0 +1,41 @@ +// ==ORIGINAL== + +function F0() { + function F1() { + function F2(x = 2 + 1) { + } + } +} + +// ==SCOPE::Extract to constant in enclosing scope== + +function F0() { + function F1() { + const newLocal = 2 + 1; + + function F2(x = /*RENAME*/newLocal) { + } + } +} + +// ==SCOPE::Extract to constant in function 'F0'== + +function F0() { + const newLocal = 2 + 1; + + function F1() { + function F2(x = /*RENAME*/newLocal) { + } + } +} + +// ==SCOPE::Extract to constant in global scope== +const newLocal = 2 + 1; + +function F0() { + function F1() { + function F2(x = /*RENAME*/newLocal) { + } + } +} + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition5.ts b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition5.ts new file mode 100644 index 00000000000..4b9647fa445 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition5.ts @@ -0,0 +1,41 @@ +// ==ORIGINAL== + +function F0() { + function F1() { + function F2(x = 2 + 1) { + } + } +} + +// ==SCOPE::Extract to constant in enclosing scope== + +function F0() { + function F1() { + const newLocal = 2 + 1; + + function F2(x = /*RENAME*/newLocal) { + } + } +} + +// ==SCOPE::Extract to constant in function 'F0'== + +function F0() { + const newLocal = 2 + 1; + + function F1() { + function F2(x = /*RENAME*/newLocal) { + } + } +} + +// ==SCOPE::Extract to constant in global scope== +const newLocal = 2 + 1; + +function F0() { + function F1() { + function F2(x = /*RENAME*/newLocal) { + } + } +} + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition6.js b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition6.js new file mode 100644 index 00000000000..0c81cb756a1 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition6.js @@ -0,0 +1,13 @@ +// ==ORIGINAL== + +class C { + x = 2 + 1; +} + +// ==SCOPE::Extract to constant in global scope== +const newLocal = 2 + 1; + +class C { + x = /*RENAME*/newLocal; +} + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition6.ts b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition6.ts new file mode 100644 index 00000000000..44a3456fc23 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition6.ts @@ -0,0 +1,21 @@ +// ==ORIGINAL== + +class C { + x = 2 + 1; +} + +// ==SCOPE::Extract to readonly field in class 'C'== + +class C { + private readonly newProperty = 2 + 1; + + x = this./*RENAME*/newProperty; +} + +// ==SCOPE::Extract to constant in global scope== +const newLocal = 2 + 1; + +class C { + x = /*RENAME*/newLocal; +} + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition7.js b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition7.js new file mode 100644 index 00000000000..f23db0c4aa9 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition7.js @@ -0,0 +1,37 @@ +// ==ORIGINAL== + +const i = 0; +class C { + M() { + for (let j = 0; j < 10; j++) { + x = i + 1; + } + } +} + +// ==SCOPE::Extract to constant in enclosing scope== + +const i = 0; +class C { + M() { + for (let j = 0; j < 10; j++) { + const newLocal = i + 1; + + x = /*RENAME*/newLocal; + } + } +} + +// ==SCOPE::Extract to constant in global scope== + +const i = 0; +const newLocal = i + 1; + +class C { + M() { + for (let j = 0; j < 10; j++) { + x = /*RENAME*/newLocal; + } + } +} + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition7.ts b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition7.ts new file mode 100644 index 00000000000..6867685d6db --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_StatementInsertionPosition7.ts @@ -0,0 +1,50 @@ +// ==ORIGINAL== + +const i = 0; +class C { + M() { + for (let j = 0; j < 10; j++) { + x = i + 1; + } + } +} + +// ==SCOPE::Extract to constant in enclosing scope== + +const i = 0; +class C { + M() { + for (let j = 0; j < 10; j++) { + const newLocal: any = i + 1; + + x = /*RENAME*/newLocal; + } + } +} + +// ==SCOPE::Extract to readonly field in class 'C'== + +const i = 0; +class C { + private readonly newProperty: any = i + 1; + + M() { + for (let j = 0; j < 10; j++) { + x = this./*RENAME*/newProperty; + } + } +} + +// ==SCOPE::Extract to constant in global scope== + +const i = 0; +const newLocal: any = i + 1; + +class C { + M() { + for (let j = 0; j < 10; j++) { + x = /*RENAME*/newLocal; + } + } +} + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_TopLevel.js b/tests/baselines/reference/extractConstant/extractConstant_TopLevel.js index fb0447583ff..fc83d32123e 100644 --- a/tests/baselines/reference/extractConstant/extractConstant_TopLevel.js +++ b/tests/baselines/reference/extractConstant/extractConstant_TopLevel.js @@ -1,6 +1,6 @@ // ==ORIGINAL== let x = 1; -// ==SCOPE::Extract to constant in global scope== +// ==SCOPE::Extract to constant in enclosing scope== const newLocal = 1; let x = /*RENAME*/newLocal; \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_TopLevel.ts b/tests/baselines/reference/extractConstant/extractConstant_TopLevel.ts index fb0447583ff..fc83d32123e 100644 --- a/tests/baselines/reference/extractConstant/extractConstant_TopLevel.ts +++ b/tests/baselines/reference/extractConstant/extractConstant_TopLevel.ts @@ -1,6 +1,6 @@ // ==ORIGINAL== let x = 1; -// ==SCOPE::Extract to constant in global scope== +// ==SCOPE::Extract to constant in enclosing scope== const newLocal = 1; let x = /*RENAME*/newLocal; \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_TripleSlash.js b/tests/baselines/reference/extractConstant/extractConstant_TripleSlash.js new file mode 100644 index 00000000000..e5f87e5d8b8 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_TripleSlash.js @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +/// + +const x = 2 + 1; + +// ==SCOPE::Extract to constant in enclosing scope== + +/// + +const newLocal = 2 + 1; + +const x = /*RENAME*/newLocal; + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_TripleSlash.ts b/tests/baselines/reference/extractConstant/extractConstant_TripleSlash.ts new file mode 100644 index 00000000000..e5f87e5d8b8 --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_TripleSlash.ts @@ -0,0 +1,14 @@ +// ==ORIGINAL== + +/// + +const x = 2 + 1; + +// ==SCOPE::Extract to constant in enclosing scope== + +/// + +const newLocal = 2 + 1; + +const x = /*RENAME*/newLocal; + \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_TypeParameters.ts b/tests/baselines/reference/extractConstant/extractConstant_TypeParameters.ts index a323e988176..f9367ab787c 100644 --- a/tests/baselines/reference/extractConstant/extractConstant_TypeParameters.ts +++ b/tests/baselines/reference/extractConstant/extractConstant_TypeParameters.ts @@ -2,7 +2,7 @@ function F(t: T) { let x = t + 1; } -// ==SCOPE::Extract to constant in function 'F'== +// ==SCOPE::Extract to constant in enclosing scope== function F(t: T) { const newLocal = t + 1; diff --git a/tests/baselines/reference/extractConstant/extractConstant_VariableList_MultipleLines.js b/tests/baselines/reference/extractConstant/extractConstant_VariableList_MultipleLines.js new file mode 100644 index 00000000000..18bb4afc28f --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_VariableList_MultipleLines.js @@ -0,0 +1,6 @@ +// ==ORIGINAL== +const /*About A*/a = 1, + /*About B*/b = a + 1; +// ==SCOPE::Extract to constant in enclosing scope== +const /*About A*/a = 1, + /*About B*/newLocal = a + 1, b = /*RENAME*/newLocal; \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_VariableList_MultipleLines.ts b/tests/baselines/reference/extractConstant/extractConstant_VariableList_MultipleLines.ts new file mode 100644 index 00000000000..18bb4afc28f --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_VariableList_MultipleLines.ts @@ -0,0 +1,6 @@ +// ==ORIGINAL== +const /*About A*/a = 1, + /*About B*/b = a + 1; +// ==SCOPE::Extract to constant in enclosing scope== +const /*About A*/a = 1, + /*About B*/newLocal = a + 1, b = /*RENAME*/newLocal; \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_VariableList_const.js b/tests/baselines/reference/extractConstant/extractConstant_VariableList_const.js new file mode 100644 index 00000000000..161e5a6a02f --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_VariableList_const.js @@ -0,0 +1,4 @@ +// ==ORIGINAL== +const a = 1, b = a + 1; +// ==SCOPE::Extract to constant in enclosing scope== +const a = 1, newLocal = a + 1, b = /*RENAME*/newLocal; \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_VariableList_const.ts b/tests/baselines/reference/extractConstant/extractConstant_VariableList_const.ts new file mode 100644 index 00000000000..161e5a6a02f --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_VariableList_const.ts @@ -0,0 +1,4 @@ +// ==ORIGINAL== +const a = 1, b = a + 1; +// ==SCOPE::Extract to constant in enclosing scope== +const a = 1, newLocal = a + 1, b = /*RENAME*/newLocal; \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_VariableList_let.js b/tests/baselines/reference/extractConstant/extractConstant_VariableList_let.js new file mode 100644 index 00000000000..bc05b13ba7e --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_VariableList_let.js @@ -0,0 +1,4 @@ +// ==ORIGINAL== +let a = 1, b = a + 1; +// ==SCOPE::Extract to constant in enclosing scope== +let a = 1, newLocal = a + 1, b = /*RENAME*/newLocal; \ No newline at end of file diff --git a/tests/baselines/reference/extractConstant/extractConstant_VariableList_let.ts b/tests/baselines/reference/extractConstant/extractConstant_VariableList_let.ts new file mode 100644 index 00000000000..bc05b13ba7e --- /dev/null +++ b/tests/baselines/reference/extractConstant/extractConstant_VariableList_let.ts @@ -0,0 +1,4 @@ +// ==ORIGINAL== +let a = 1, b = a + 1; +// ==SCOPE::Extract to constant in enclosing scope== +let a = 1, newLocal = a + 1, b = /*RENAME*/newLocal; \ No newline at end of file