diff --git a/src/services/smartSelection.ts b/src/services/smartSelection.ts index c2aa95a0eaff8..bacaf86f29894 100644 --- a/src/services/smartSelection.ts +++ b/src/services/smartSelection.ts @@ -24,6 +24,11 @@ namespace ts.SmartSelectionRange { } if (positionShouldSnapToNode(sourceFile, pos, node)) { + if (isFunctionBody(node) + && isFunctionLikeDeclaration(parentNode) && !positionsAreOnSameLine(node.getStart(sourceFile), node.getEnd(), sourceFile)) { + pushSelectionRange(node.getStart(sourceFile), node.getEnd()); + } + // 1. Blocks are effectively redundant with SyntaxLists. // 2. TemplateSpans, along with the SyntaxLists containing them, are a somewhat unintuitive grouping // of things that should be considered independently. diff --git a/src/testRunner/unittests/tsserver/smartSelection.ts b/src/testRunner/unittests/tsserver/smartSelection.ts index 3c903d7da675f..4cdbbb89fc3e6 100644 --- a/src/testRunner/unittests/tsserver/smartSelection.ts +++ b/src/testRunner/unittests/tsserver/smartSelection.ts @@ -44,23 +44,28 @@ class Foo { parent: { textSpan: { // SyntaxList + whitespace (body of method) start: { line: 3, offset: 16 }, - end: { line: 8, offset: 5 } }, + end: { line: 8, offset: 5 } + }, parent: { - textSpan: { // MethodDeclaration - start: { line: 3, offset: 5 }, + textSpan: { // {} + start: { line: 3, offset: 15 }, end: { line: 8, offset: 6 } }, parent: { - textSpan: { // SyntaxList + whitespace (body of class) - start: { line: 2, offset: 12 }, - end: { line: 9, offset: 1 } }, + textSpan: { // MethodDeclaration + start: { line: 3, offset: 5 }, + end: { line: 8, offset: 6 } }, parent: { - textSpan: { // ClassDeclaration - start: { line: 2, offset: 1 }, - end: { line: 9, offset: 2 } }, + textSpan: { // SyntaxList + whitespace (body of class) + start: { line: 2, offset: 12 }, + end: { line: 9, offset: 1 } }, parent: { - textSpan: { // SourceFile (all text) - start: { line: 1, offset: 1 }, - end: { line: 9, offset: 2 }, } } } } } } } } }]); + textSpan: { // ClassDeclaration + start: { line: 2, offset: 1 }, + end: { line: 9, offset: 2 } }, + parent: { + textSpan: { // SourceFile (all text) + start: { line: 1, offset: 1 }, + end: { line: 9, offset: 2 } } } } } } } } } } }]); }); }); } diff --git a/tests/baselines/reference/smartSelection_emptyRanges.baseline b/tests/baselines/reference/smartSelection_emptyRanges.baseline index efcb6e66ee920..e2d9bfae3f6e3 100644 --- a/tests/baselines/reference/smartSelection_emptyRanges.baseline +++ b/tests/baselines/reference/smartSelection_emptyRanges.baseline @@ -62,6 +62,13 @@ class HomePage { •• + { + if (this.props.username) { + return ''; + } + } + + componentDidMount() { if (this.props.username) { return ''; @@ -119,6 +126,13 @@ class HomePage { •• + { + if (this.props.username) { + return ''; + } + } + + componentDidMount() { if (this.props.username) { return ''; diff --git a/tests/baselines/reference/smartSelection_function1.baseline b/tests/baselines/reference/smartSelection_function1.baseline new file mode 100644 index 0000000000000..908d7e1b510d2 --- /dev/null +++ b/tests/baselines/reference/smartSelection_function1.baseline @@ -0,0 +1,16 @@ +const f1 = () => { + /**/ +}; + + + { + +} + + () => { + +} + +const f1 = () => { + +}; \ No newline at end of file diff --git a/tests/baselines/reference/smartSelection_function2.baseline b/tests/baselines/reference/smartSelection_function2.baseline new file mode 100644 index 0000000000000..3d92a4c358232 --- /dev/null +++ b/tests/baselines/reference/smartSelection_function2.baseline @@ -0,0 +1,12 @@ +function f2() { + /**/ +} + + + { + +} + +function f2() { + +} \ No newline at end of file diff --git a/tests/baselines/reference/smartSelection_function3.baseline b/tests/baselines/reference/smartSelection_function3.baseline new file mode 100644 index 0000000000000..230106f98fade --- /dev/null +++ b/tests/baselines/reference/smartSelection_function3.baseline @@ -0,0 +1,16 @@ +const f3 = function () { + /**/ +} + + + { + +} + + function () { + +} + +const f3 = function () { + +} \ No newline at end of file diff --git a/tests/baselines/reference/smartSelection_simple1.baseline b/tests/baselines/reference/smartSelection_simple1.baseline index f28c607c524ba..16cc30487d8af 100644 --- a/tests/baselines/reference/smartSelection_simple1.baseline +++ b/tests/baselines/reference/smartSelection_simple1.baseline @@ -27,6 +27,14 @@ class Foo { •• + { + if (a === b) { + return true; + } + return false; + } + + bar(a, b) { if (a === b) { return true; @@ -89,6 +97,14 @@ class Foo { •• + { + if (a === b) { + return true; + } + return false; + } + + bar(a, b) { if (a === b) { return true; diff --git a/tests/cases/fourslash/smartSelection_function1.ts b/tests/cases/fourslash/smartSelection_function1.ts new file mode 100644 index 0000000000000..7edd0a7e473b6 --- /dev/null +++ b/tests/cases/fourslash/smartSelection_function1.ts @@ -0,0 +1,7 @@ +/// + +////const f1 = () => { +//// /**/ +////}; + +verify.baselineSmartSelection(); diff --git a/tests/cases/fourslash/smartSelection_function2.ts b/tests/cases/fourslash/smartSelection_function2.ts new file mode 100644 index 0000000000000..3e1576cd96254 --- /dev/null +++ b/tests/cases/fourslash/smartSelection_function2.ts @@ -0,0 +1,7 @@ +/// + +////function f2() { +//// /**/ +////} + +verify.baselineSmartSelection(); diff --git a/tests/cases/fourslash/smartSelection_function3.ts b/tests/cases/fourslash/smartSelection_function3.ts new file mode 100644 index 0000000000000..a0a94c54145ec --- /dev/null +++ b/tests/cases/fourslash/smartSelection_function3.ts @@ -0,0 +1,7 @@ +/// + +////const f3 = function () { +//// /**/ +////} + +verify.baselineSmartSelection();