diff --git a/src/harness/unittests/extractFunctions.ts b/src/harness/unittests/extractFunctions.ts index ecc4112c3a722..5e9214fb35e0c 100644 --- a/src/harness/unittests/extractFunctions.ts +++ b/src/harness/unittests/extractFunctions.ts @@ -552,6 +552,11 @@ export default class { M() { [#|1 + 1|]; } +}`); + + testExtractFunction("extractFunction_NoDeclarations", ` +function F() { +[#|arguments.length|]; // arguments has no declaration }`); }); diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 68001262a3f0b..bf410ab27a9cd 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -1689,7 +1689,8 @@ namespace ts.refactor.extractSymbol { return symbolId; } // find first declaration in this file - const declInFile = find(symbol.getDeclarations(), d => d.getSourceFile() === sourceFile); + const decls = symbol.getDeclarations(); + const declInFile = decls && find(decls, d => d.getSourceFile() === sourceFile); if (!declInFile) { return undefined; } @@ -1782,7 +1783,8 @@ namespace ts.refactor.extractSymbol { if (!symbol) { return undefined; } - if (symbol.getDeclarations().some(d => d.parent === scopeDecl)) { + const decls = symbol.getDeclarations(); + if (decls && decls.some(d => d.parent === scopeDecl)) { return createIdentifier(symbol.name); } const prefix = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.parent, scopeDecl, isTypeNode); diff --git a/tests/baselines/reference/extractFunction/extractFunction_NoDeclarations.js b/tests/baselines/reference/extractFunction/extractFunction_NoDeclarations.js new file mode 100644 index 0000000000000..b4129d1225e27 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_NoDeclarations.js @@ -0,0 +1,24 @@ +// ==ORIGINAL== + +function F() { +/*[#|*/arguments.length/*|]*/; // arguments has no declaration +} +// ==SCOPE::Extract to inner function in function 'F'== + +function F() { + /*RENAME*/newFunction(); // arguments has no declaration + + + function newFunction() { + arguments.length; + } +} +// ==SCOPE::Extract to function in global scope== + +function F() { + /*RENAME*/newFunction(); // arguments has no declaration +} + +function newFunction() { + arguments.length; +} diff --git a/tests/baselines/reference/extractFunction/extractFunction_NoDeclarations.ts b/tests/baselines/reference/extractFunction/extractFunction_NoDeclarations.ts new file mode 100644 index 0000000000000..b4129d1225e27 --- /dev/null +++ b/tests/baselines/reference/extractFunction/extractFunction_NoDeclarations.ts @@ -0,0 +1,24 @@ +// ==ORIGINAL== + +function F() { +/*[#|*/arguments.length/*|]*/; // arguments has no declaration +} +// ==SCOPE::Extract to inner function in function 'F'== + +function F() { + /*RENAME*/newFunction(); // arguments has no declaration + + + function newFunction() { + arguments.length; + } +} +// ==SCOPE::Extract to function in global scope== + +function F() { + /*RENAME*/newFunction(); // arguments has no declaration +} + +function newFunction() { + arguments.length; +}