Skip to content

Commit 25af013

Browse files
committed
Merge remote-tracking branch 'origin/main' into infer-intersected-mapped-types
2 parents 16b6d35 + 243d8de commit 25af013

File tree

7 files changed

+147
-99
lines changed

7 files changed

+147
-99
lines changed

package-lock.json

+88-88
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/harness/fourslashImpl.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -984,15 +984,19 @@ export class TestState {
984984
if (actual.insertText !== expected.insertText) {
985985
this.raiseError(`At entry ${actual.name}: Completion insert text did not match: ${showTextDiff(expected.insertText || "", actual.insertText || "")}`);
986986
}
987+
987988
const convertedReplacementSpan = expected.replacementSpan && ts.createTextSpanFromRange(expected.replacementSpan);
988-
if (convertedReplacementSpan?.length) {
989+
if (convertedReplacementSpan) {
989990
try {
990991
assert.deepEqual(actual.replacementSpan, convertedReplacementSpan);
991992
}
992993
catch {
993994
this.raiseError(`At entry ${actual.name}: Expected completion replacementSpan to be ${stringify(convertedReplacementSpan)}, got ${stringify(actual.replacementSpan)}`);
994995
}
995996
}
997+
else if (ts.hasProperty(expected, "replacementSpan")) { // Expected `replacementSpan` is explicitly set as `undefined`.
998+
assert.equal(actual.replacementSpan, undefined, `At entry ${actual.name}: Expected 'replacementSpan' properties to match`);
999+
}
9961000

9971001
if (expected.kind !== undefined || expected.kindModifiers !== undefined) {
9981002
assert.equal(actual.kind, expected.kind, `At entry ${actual.name}: Expected 'kind' for ${actual.name} to match`);

src/services/completions.ts

+16-4
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,7 @@ function completionInfoFromData(
927927
/*replacementToken*/ undefined,
928928
contextToken,
929929
location,
930+
position,
930931
sourceFile,
931932
host,
932933
program,
@@ -1316,6 +1317,7 @@ function createCompletionEntry(
13161317
replacementToken: Node | undefined,
13171318
contextToken: Node | undefined,
13181319
location: Node,
1320+
position: number,
13191321
sourceFile: SourceFile,
13201322
host: LanguageServiceHost,
13211323
program: Program,
@@ -1406,7 +1408,8 @@ function createCompletionEntry(
14061408
completionKind === CompletionKind.MemberLike &&
14071409
isClassLikeMemberCompletion(symbol, location, sourceFile)) {
14081410
let importAdder;
1409-
({ insertText, isSnippet, importAdder, replacementSpan } = getEntryForMemberCompletion(host, program, options, preferences, name, symbol, location, contextToken, formatContext));
1411+
({ insertText, isSnippet, importAdder, replacementSpan } =
1412+
getEntryForMemberCompletion(host, program, options, preferences, name, symbol, location, position, contextToken, formatContext));
14101413
sortText = SortText.ClassMemberSnippets; // sortText has to be lower priority than the sortText for keywords. See #47852.
14111414
if (importAdder?.hasFixes()) {
14121415
hasAction = true;
@@ -1545,6 +1548,7 @@ function getEntryForMemberCompletion(
15451548
name: string,
15461549
symbol: Symbol,
15471550
location: Node,
1551+
position: number,
15481552
contextToken: Node | undefined,
15491553
formatContext: formatting.FormatContext | undefined,
15501554
): { insertText: string, isSnippet?: true, importAdder?: codefix.ImportAdder, replacementSpan?: TextSpan } {
@@ -1586,7 +1590,7 @@ function getEntryForMemberCompletion(
15861590
let modifiers = ModifierFlags.None;
15871591
// Whether the suggested member should be abstract.
15881592
// e.g. in `abstract class C { abstract | }`, we should offer abstract method signatures at position `|`.
1589-
const { modifiers: presentModifiers, span: modifiersSpan } = getPresentModifiers(contextToken);
1593+
const { modifiers: presentModifiers, span: modifiersSpan } = getPresentModifiers(contextToken, sourceFile, position);
15901594
const isAbstract = !!(presentModifiers & ModifierFlags.Abstract);
15911595
const completionNodes: Node[] = [];
15921596
codefix.addNewNodeForMemberSymbol(
@@ -1650,8 +1654,13 @@ function getEntryForMemberCompletion(
16501654
return { insertText, isSnippet, importAdder, replacementSpan };
16511655
}
16521656

1653-
function getPresentModifiers(contextToken: Node | undefined): { modifiers: ModifierFlags, span?: TextSpan } {
1654-
if (!contextToken) {
1657+
function getPresentModifiers(
1658+
contextToken: Node | undefined,
1659+
sourceFile: SourceFile,
1660+
position: number): { modifiers: ModifierFlags, span?: TextSpan } {
1661+
if (!contextToken ||
1662+
getLineAndCharacterOfPosition(sourceFile, position).line
1663+
> getLineAndCharacterOfPosition(sourceFile, contextToken.getEnd()).line) {
16551664
return { modifiers: ModifierFlags.None };
16561665
}
16571666
let modifiers = ModifierFlags.None;
@@ -2086,6 +2095,7 @@ export function getCompletionEntriesFromSymbols(
20862095
replacementToken: Node | undefined,
20872096
contextToken: Node | undefined,
20882097
location: Node,
2098+
position: number,
20892099
sourceFile: SourceFile,
20902100
host: LanguageServiceHost,
20912101
program: Program,
@@ -2132,6 +2142,7 @@ export function getCompletionEntriesFromSymbols(
21322142
replacementToken,
21332143
contextToken,
21342144
location,
2145+
position,
21352146
sourceFile,
21362147
host,
21372148
program,
@@ -2471,6 +2482,7 @@ function getCompletionEntryCodeActionsAndSourceDisplay(
24712482
name,
24722483
symbol,
24732484
location,
2485+
position,
24742486
contextToken,
24752487
formatContext);
24762488
if (importAdder) {

src/services/stringCompletions.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ export function getStringLiteralCompletions(
198198
if (isInString(sourceFile, position, contextToken)) {
199199
if (!contextToken || !isStringLiteralLike(contextToken)) return undefined;
200200
const entries = getStringLiteralCompletionEntries(sourceFile, contextToken, position, program.getTypeChecker(), options, host, preferences);
201-
return convertStringLiteralCompletions(entries, contextToken, sourceFile, host, program, log, options, preferences);
201+
return convertStringLiteralCompletions(entries, contextToken, sourceFile, host, program, log, options, preferences, position);
202202
}
203203
}
204204

@@ -211,6 +211,7 @@ function convertStringLiteralCompletions(
211211
log: Log,
212212
options: CompilerOptions,
213213
preferences: UserPreferences,
214+
position: number,
214215
): CompletionInfo | undefined {
215216
if (completion === undefined) {
216217
return undefined;
@@ -228,6 +229,7 @@ function convertStringLiteralCompletions(
228229
contextToken,
229230
contextToken,
230231
sourceFile,
232+
position,
231233
sourceFile,
232234
host,
233235
program,

tests/baselines/reference/completionsClassMembers2.baseline

-4
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,6 @@
173173
"kindModifiers": "",
174174
"sortText": "17",
175175
"insertText": "method(): void {\r\n}",
176-
"replacementSpan": {
177-
"start": 71,
178-
"length": 16
179-
},
180176
"displayParts": [
181177
{
182178
"text": "(",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @Filename: a.ts
4+
// @newline: LF
5+
6+
// Issue #52211
7+
8+
//// interface Interface {
9+
//// method(): void;
10+
//// }
11+
////
12+
//// export class Class implements Interface {
13+
//// property = "yadda";
14+
////
15+
//// /**/
16+
//// }
17+
18+
verify.completions({
19+
marker: "",
20+
isNewIdentifierLocation: true,
21+
preferences: {
22+
includeCompletionsWithInsertText: true,
23+
includeCompletionsWithSnippetText: false,
24+
includeCompletionsWithClassMemberSnippets: true,
25+
},
26+
includes: [
27+
{
28+
name: "method",
29+
sortText: completion.SortText.ClassMemberSnippets,
30+
insertText: "method(): void {\n}",
31+
replacementSpan: undefined,
32+
},
33+
],
34+
});

tests/cases/fourslash/importStatementCompletions1.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
//// [|import f/*4*/ =|]
2121

2222
// @Filename: /index5.ts
23-
//// import f/*5*/ from "";
23+
//// [|import f/*5*/ from "";|]
2424

2525
([[0, true], [1, true], [2, false], [3, true], [4, true], [5, true]] as const).forEach(([marker, typeKeywordValid]) => {
2626
verify.completions({

0 commit comments

Comments
 (0)