@zzzen/pyright-internal 1.2.0-dev.20230305 → 1.2.0-dev.20230312
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyzer/binder.js +23 -3
- package/dist/analyzer/binder.js.map +1 -1
- package/dist/analyzer/checker.js +3 -3
- package/dist/analyzer/checker.js.map +1 -1
- package/dist/analyzer/commentUtils.js +11 -1
- package/dist/analyzer/commentUtils.js.map +1 -1
- package/dist/analyzer/constructorTransform.d.ts +1 -0
- package/dist/analyzer/constructorTransform.js +19 -2
- package/dist/analyzer/constructorTransform.js.map +1 -1
- package/dist/analyzer/packageTypeVerifier.js +40 -40
- package/dist/analyzer/packageTypeVerifier.js.map +1 -1
- package/dist/analyzer/patternMatching.js +13 -11
- package/dist/analyzer/patternMatching.js.map +1 -1
- package/dist/analyzer/program.js +5 -4
- package/dist/analyzer/program.js.map +1 -1
- package/dist/analyzer/sourceFile.js +12 -1
- package/dist/analyzer/sourceFile.js.map +1 -1
- package/dist/analyzer/typeEvaluator.js +156 -42
- package/dist/analyzer/typeEvaluator.js.map +1 -1
- package/dist/analyzer/typeEvaluatorTypes.d.ts +1 -0
- package/dist/analyzer/typePrinter.js +63 -55
- package/dist/analyzer/typePrinter.js.map +1 -1
- package/dist/analyzer/typeUtils.d.ts +1 -0
- package/dist/analyzer/typeUtils.js +9 -3
- package/dist/analyzer/typeUtils.js.map +1 -1
- package/dist/analyzer/typedDicts.d.ts +2 -1
- package/dist/analyzer/typedDicts.js +57 -40
- package/dist/analyzer/typedDicts.js.map +1 -1
- package/dist/analyzer/types.d.ts +1 -0
- package/dist/analyzer/types.js +8 -0
- package/dist/analyzer/types.js.map +1 -1
- package/dist/commands/dumpFileDebugInfoCommand.js +78 -0
- package/dist/commands/dumpFileDebugInfoCommand.js.map +1 -1
- package/dist/common/extensibility.js +25 -1
- package/dist/common/extensibility.js.map +1 -1
- package/dist/languageServerBase.js +3 -1
- package/dist/languageServerBase.js.map +1 -1
- package/dist/languageService/completionProvider.d.ts +4 -2
- package/dist/languageService/completionProvider.js +206 -151
- package/dist/languageService/completionProvider.js.map +1 -1
- package/dist/languageService/renameModuleProvider.d.ts +1 -1
- package/dist/languageService/renameModuleProvider.js +8 -1
- package/dist/languageService/renameModuleProvider.js.map +1 -1
- package/dist/languageService/tooltipUtils.js +2 -1
- package/dist/languageService/tooltipUtils.js.map +1 -1
- package/dist/localization/localize.d.ts +3 -0
- package/dist/localization/localize.js +1 -0
- package/dist/localization/localize.js.map +1 -1
- package/dist/localization/package.nls.en-us.json +1 -0
- package/dist/parser/parser.js +22 -7
- package/dist/parser/parser.js.map +1 -1
- package/dist/parser/tokenizer.js +1 -1
- package/dist/tests/completions.test.js +445 -0
- package/dist/tests/completions.test.js.map +1 -1
- package/dist/tests/fourslash/completions.dictionary.keys.expression.fourslash.js +13 -3
- package/dist/tests/fourslash/completions.dictionary.keys.expression.fourslash.js.map +1 -1
- package/dist/tests/fourslash/completions.dictionary.keys.stringLiterals.fourslash.js +7 -2
- package/dist/tests/fourslash/completions.dictionary.keys.stringLiterals.fourslash.js.map +1 -1
- package/dist/tests/hoverProvider.test.js +1 -1
- package/dist/tests/hoverProvider.test.js.map +1 -1
- package/dist/tests/moveSymbol.misc.test.js +27 -0
- package/dist/tests/moveSymbol.misc.test.js.map +1 -1
- package/dist/tests/typeEvaluator1.test.js +4 -0
- package/dist/tests/typeEvaluator1.test.js.map +1 -1
- package/dist/tests/typeEvaluator2.test.js +4 -0
- package/dist/tests/typeEvaluator2.test.js.map +1 -1
- package/dist/tests/typeEvaluator4.test.js +4 -0
- package/dist/tests/typeEvaluator4.test.js.map +1 -1
- package/package.json +1 -1
@@ -250,7 +250,7 @@ class CompletionProvider {
|
|
250
250
|
while (true) {
|
251
251
|
(0, cancellationUtils_1.throwIfCancellationRequested)(this._cancellationToken);
|
252
252
|
if (curNode.nodeType === 49 /* String */) {
|
253
|
-
return this._getLiteralCompletions(curNode, priorWord, priorText, postText);
|
253
|
+
return this._getLiteralCompletions(curNode, offset, priorWord, priorText, postText);
|
254
254
|
}
|
255
255
|
if (curNode.nodeType === 48 /* StringList */ || curNode.nodeType === 27 /* FormatString */) {
|
256
256
|
return undefined;
|
@@ -259,14 +259,15 @@ class CompletionProvider {
|
|
259
259
|
return this._getImportModuleCompletions(curNode);
|
260
260
|
}
|
261
261
|
if (curNode.nodeType === 0 /* Error */) {
|
262
|
-
return this._getExpressionErrorCompletions(curNode, priorWord, priorText, postText);
|
262
|
+
return this._getExpressionErrorCompletions(curNode, offset, priorWord, priorText, postText);
|
263
263
|
}
|
264
264
|
if (curNode.nodeType === 35 /* MemberAccess */) {
|
265
265
|
return this._getMemberAccessCompletions(curNode.leftExpression, priorWord);
|
266
266
|
}
|
267
267
|
if (curNode.nodeType === 15 /* Dictionary */) {
|
268
268
|
const completionMap = new CompletionMap();
|
269
|
-
if (this.
|
269
|
+
if (this._tryAddTypedDictKeysFromDictionary(curNode,
|
270
|
+
/* stringNode */ undefined, priorWord, priorText, postText, completionMap)) {
|
270
271
|
return { completionMap };
|
271
272
|
}
|
272
273
|
}
|
@@ -276,8 +277,8 @@ class CompletionProvider {
|
|
276
277
|
const dictionaryNode = dictionaryEntry.parent;
|
277
278
|
if (dictionaryNode.trailingCommaToken && dictionaryNode.trailingCommaToken.start < offset) {
|
278
279
|
const completionMap = new CompletionMap();
|
279
|
-
if (this.
|
280
|
-
/* stringNode */ undefined, priorText, postText, completionMap)) {
|
280
|
+
if (this._tryAddTypedDictKeysFromDictionary(dictionaryNode,
|
281
|
+
/* stringNode */ undefined, priorWord, priorText, postText, completionMap)) {
|
281
282
|
return { completionMap };
|
282
283
|
}
|
283
284
|
}
|
@@ -542,7 +543,7 @@ class CompletionProvider {
|
|
542
543
|
return tokens.getItemAt(tokenIndex + 1);
|
543
544
|
}
|
544
545
|
}
|
545
|
-
_getExpressionErrorCompletions(node, priorWord, priorText, postText) {
|
546
|
+
_getExpressionErrorCompletions(node, offset, priorWord, priorText, postText) {
|
546
547
|
var _a;
|
547
548
|
// Is the error due to a missing member access name? If so,
|
548
549
|
// we can evaluate the left side of the member access expression
|
@@ -605,8 +606,9 @@ class CompletionProvider {
|
|
605
606
|
case 4 /* MissingDecoratorCallName */: {
|
606
607
|
return this._getExpressionCompletions(node, priorWord, priorText, postText);
|
607
608
|
}
|
609
|
+
case 11 /* MissingPattern */:
|
608
610
|
case 3 /* MissingIndexOrSlice */: {
|
609
|
-
let completionResults = this._getLiteralCompletions(node, priorWord, priorText, postText);
|
611
|
+
let completionResults = this._getLiteralCompletions(node, offset, priorWord, priorText, postText);
|
610
612
|
if (!completionResults) {
|
611
613
|
completionResults = this._getExpressionCompletions(node, priorWord, priorText, postText);
|
612
614
|
}
|
@@ -1108,7 +1110,7 @@ class CompletionProvider {
|
|
1108
1110
|
return this._getExpressionCompletions(parseNode, priorWord, priorText, postText);
|
1109
1111
|
}
|
1110
1112
|
_getExpressionCompletions(parseNode, priorWord, priorText, postText) {
|
1111
|
-
var _a, _b
|
1113
|
+
var _a, _b;
|
1112
1114
|
const isIndexArgument = this._isIndexArgument(parseNode);
|
1113
1115
|
// If the user typed a "." as part of a number, don't present
|
1114
1116
|
// any completion options.
|
@@ -1152,39 +1154,7 @@ class CompletionProvider {
|
|
1152
1154
|
this._addAutoImportCompletions(priorWord, similarityLimit, this._options.lazyEdit, completionResults);
|
1153
1155
|
}
|
1154
1156
|
// Add literal values if appropriate.
|
1155
|
-
|
1156
|
-
if (parseNode.category === 3 /* MissingIndexOrSlice */ &&
|
1157
|
-
((_c = parseNode.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 24 /* Index */) {
|
1158
|
-
this._tryAddTypedDictStringLiteral(parseNode.parent,
|
1159
|
-
/* priorText */ undefined,
|
1160
|
-
/* postText */ undefined, completionMap);
|
1161
|
-
}
|
1162
|
-
else if (parseNode.category === 2 /* MissingExpression */) {
|
1163
|
-
if (parseNode.parent && parseNode.parent.nodeType === 3 /* Assignment */) {
|
1164
|
-
const declaredTypeOfTarget = (_d = this._evaluator.getExpectedType(parseNode)) === null || _d === void 0 ? void 0 : _d.type;
|
1165
|
-
if (declaredTypeOfTarget) {
|
1166
|
-
this._addLiteralValuesForTargetType(declaredTypeOfTarget, priorText, priorWord, postText, completionMap);
|
1167
|
-
}
|
1168
|
-
}
|
1169
|
-
}
|
1170
|
-
}
|
1171
|
-
if (isIndexArgument) {
|
1172
|
-
// Completion for dict key (ex, dict_variable[<here>])
|
1173
|
-
const indexNode = parseNode.parent.parent;
|
1174
|
-
this._getIndexerKeys(indexNode, parseNode).forEach((key) => {
|
1175
|
-
if (completionMap.has(key)) {
|
1176
|
-
// Don't add key if it already exists in the completion.
|
1177
|
-
// ex) key = "dictKey"
|
1178
|
-
// dict[key] = 1
|
1179
|
-
// print(dict[<key will come from symbol table provider>]))
|
1180
|
-
return;
|
1181
|
-
}
|
1182
|
-
this._addNameToCompletions(key, vscode_languageserver_1.CompletionItemKind.Constant, priorWord, completionMap, {
|
1183
|
-
sortText: this._makeSortText(SortCategory.LiteralValue, key),
|
1184
|
-
itemDetail: exports.dictionaryKeyDetail,
|
1185
|
-
});
|
1186
|
-
});
|
1187
|
-
}
|
1157
|
+
this._tryAddLiterals(parseNode, priorWord, priorText, postText, completionMap);
|
1188
1158
|
return completionResults;
|
1189
1159
|
}
|
1190
1160
|
_isIndexArgument(node) {
|
@@ -1213,11 +1183,11 @@ class CompletionProvider {
|
|
1213
1183
|
this._addNamedParameters(signatureInfo, priorWord, completionMap);
|
1214
1184
|
}
|
1215
1185
|
// Add literals that apply to this parameter.
|
1216
|
-
this._addLiteralValuesForArgument(signatureInfo,
|
1186
|
+
this._addLiteralValuesForArgument(signatureInfo, priorWord, priorText, postText, completionMap);
|
1217
1187
|
}
|
1218
1188
|
}
|
1219
1189
|
}
|
1220
|
-
_addLiteralValuesForArgument(signatureInfo,
|
1190
|
+
_addLiteralValuesForArgument(signatureInfo, priorWord, priorText, postText, completionMap) {
|
1221
1191
|
signatureInfo.signatures.forEach((signature) => {
|
1222
1192
|
if (!signature.activeParam) {
|
1223
1193
|
return undefined;
|
@@ -1228,12 +1198,12 @@ class CompletionProvider {
|
|
1228
1198
|
return undefined;
|
1229
1199
|
}
|
1230
1200
|
const paramType = type.details.parameters[paramIndex].type;
|
1231
|
-
this._addLiteralValuesForTargetType(paramType,
|
1201
|
+
this._addLiteralValuesForTargetType(paramType, priorWord, priorText, postText, completionMap);
|
1232
1202
|
return undefined;
|
1233
1203
|
});
|
1234
1204
|
}
|
1235
|
-
_addLiteralValuesForTargetType(type,
|
1236
|
-
const quoteValue = this._getQuoteInfo(priorText);
|
1205
|
+
_addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap) {
|
1206
|
+
const quoteValue = this._getQuoteInfo(priorWord, priorText);
|
1237
1207
|
this._getSubTypesWithLiteralValues(type).forEach((v) => {
|
1238
1208
|
if (types_1.ClassType.isBuiltIn(v, 'str')) {
|
1239
1209
|
const value = (0, typePrinter_1.printLiteralValue)(v, quoteValue.quoteCharacter);
|
@@ -1243,7 +1213,7 @@ class CompletionProvider {
|
|
1243
1213
|
});
|
1244
1214
|
}
|
1245
1215
|
else {
|
1246
|
-
this._addStringLiteralToCompletions(value.substr(1, value.length - 2), quoteValue
|
1216
|
+
this._addStringLiteralToCompletions(value.substr(1, value.length - 2), quoteValue, postText, completionMap);
|
1247
1217
|
}
|
1248
1218
|
}
|
1249
1219
|
});
|
@@ -1399,96 +1369,178 @@ class CompletionProvider {
|
|
1399
1369
|
}
|
1400
1370
|
return [...keys];
|
1401
1371
|
}
|
1402
|
-
_getLiteralCompletions(parseNode, priorWord, priorText, postText) {
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1372
|
+
_getLiteralCompletions(parseNode, offset, priorWord, priorText, postText) {
|
1373
|
+
if (this._options.triggerCharacter === '"' || this._options.triggerCharacter === "'") {
|
1374
|
+
if (parseNode.start !== offset - 1) {
|
1375
|
+
// If completion is triggered by typing " or ', it must be the one that starts a string
|
1376
|
+
// literal. In another word, it can't be something inside of another string or comment
|
1377
|
+
return undefined;
|
1378
|
+
}
|
1407
1379
|
}
|
1408
1380
|
const completionMap = new CompletionMap();
|
1381
|
+
if (!this._tryAddLiterals(parseNode, priorWord, priorText, postText, completionMap)) {
|
1382
|
+
return undefined;
|
1383
|
+
}
|
1384
|
+
return { completionMap };
|
1385
|
+
}
|
1386
|
+
_tryAddLiterals(parseNode, priorWord, priorText, postText, completionMap) {
|
1387
|
+
var _a, _b, _c, _d, _e, _f;
|
1388
|
+
const parentAndChild = getParentSkippingStringList(parseNode);
|
1389
|
+
if (!parentAndChild) {
|
1390
|
+
return false;
|
1391
|
+
}
|
1409
1392
|
// See if the type evaluator can determine the expected type for this node.
|
1410
|
-
|
1411
|
-
|
1393
|
+
// ex) a: Literal["str"] = /* here */
|
1394
|
+
const nodeForExpectedType = parentAndChild.parent.nodeType === 3 /* Assignment */
|
1395
|
+
? parentAndChild.parent.rightExpression === parentAndChild.child
|
1396
|
+
? parentAndChild.child
|
1397
|
+
: undefined
|
1398
|
+
: (0, parseNodes_1.isExpressionNode)(parentAndChild.child)
|
1399
|
+
? parentAndChild.child
|
1400
|
+
: undefined;
|
1401
|
+
if (nodeForExpectedType) {
|
1402
|
+
const expectedTypeResult = this._evaluator.getExpectedType(nodeForExpectedType);
|
1412
1403
|
if (expectedTypeResult && (0, typeUtils_1.isLiteralTypeOrUnion)(expectedTypeResult.type)) {
|
1413
|
-
this._addLiteralValuesForTargetType(expectedTypeResult.type,
|
1414
|
-
return
|
1415
|
-
}
|
1416
|
-
if (parseNode.nodeType === 49 /* String */ && ((_a = parseNode.parent) === null || _a === void 0 ? void 0 : _a.parent)) {
|
1417
|
-
const stringParent = parseNode.parent.parent;
|
1418
|
-
// If the dictionary is not yet filled in, it will appear as though it's
|
1419
|
-
// a set initially.
|
1420
|
-
let dictOrSet;
|
1421
|
-
if (stringParent.nodeType === 17 /* DictionaryKeyEntry */ &&
|
1422
|
-
stringParent.keyExpression === parseNode.parent &&
|
1423
|
-
((_b = stringParent.parent) === null || _b === void 0 ? void 0 : _b.nodeType) === 15 /* Dictionary */) {
|
1424
|
-
dictOrSet = stringParent.parent;
|
1425
|
-
}
|
1426
|
-
else if ((stringParent === null || stringParent === void 0 ? void 0 : stringParent.nodeType) === 45 /* Set */) {
|
1427
|
-
dictOrSet = stringParent;
|
1428
|
-
}
|
1429
|
-
if (dictOrSet) {
|
1430
|
-
if (this._addTypedDictKeys(dictOrSet, parseNode, priorText, postText, completionMap)) {
|
1431
|
-
return { completionMap };
|
1432
|
-
}
|
1433
|
-
}
|
1404
|
+
this._addLiteralValuesForTargetType(expectedTypeResult.type, priorWord, priorText, postText, completionMap);
|
1405
|
+
return true;
|
1434
1406
|
}
|
1435
1407
|
}
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1408
|
+
// ex) a: TypedDictType = { "/* here */" } or a: TypedDictType = { A/* here */ }
|
1409
|
+
const nodeForKey = parentAndChild.parent;
|
1410
|
+
if (nodeForKey) {
|
1411
|
+
// If the dictionary is not yet filled in, it will appear as though it's
|
1412
|
+
// a set initially.
|
1413
|
+
let dictOrSet;
|
1414
|
+
if (nodeForKey.nodeType === 17 /* DictionaryKeyEntry */ &&
|
1415
|
+
nodeForKey.keyExpression === parentAndChild.child &&
|
1416
|
+
((_a = nodeForKey.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 15 /* Dictionary */) {
|
1417
|
+
dictOrSet = nodeForKey.parent;
|
1439
1418
|
}
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1419
|
+
else if ((nodeForKey === null || nodeForKey === void 0 ? void 0 : nodeForKey.nodeType) === 45 /* Set */) {
|
1420
|
+
dictOrSet = nodeForKey;
|
1421
|
+
}
|
1422
|
+
if (dictOrSet) {
|
1423
|
+
if (this._tryAddTypedDictKeysFromDictionary(dictOrSet, parseNode.nodeType === 49 /* String */ ? parseNode : undefined, priorWord, priorText, postText, completionMap)) {
|
1424
|
+
return true;
|
1425
|
+
}
|
1443
1426
|
}
|
1444
1427
|
}
|
1445
|
-
|
1428
|
+
// a: DictType = { .... }
|
1429
|
+
// a[/* here */] or a['/* here */'] or a[variable/*here*/]
|
1430
|
+
const argument = parentAndChild.parent;
|
1431
|
+
if (argument.nodeType === 1 /* Argument */ && ((_b = argument.parent) === null || _b === void 0 ? void 0 : _b.nodeType) === 24 /* Index */) {
|
1446
1432
|
const priorTextInString = parseNode.nodeType === 49 /* String */ ? priorText : '';
|
1447
|
-
if (
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
if
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
this._addNameToCompletions(key, vscode_languageserver_1.CompletionItemKind.Constant, priorWord, completionMap, {
|
1461
|
-
sortText: this._makeSortText(SortCategory.LiteralValue, key),
|
1462
|
-
itemDetail: exports.dictionaryKeyDetail,
|
1463
|
-
});
|
1464
|
-
}
|
1433
|
+
if (this._tryAddTypedDictKeysFromIndexer(argument.parent, priorWord, priorTextInString, postText, completionMap)) {
|
1434
|
+
return true;
|
1435
|
+
}
|
1436
|
+
const quoteInfo = this._getQuoteInfo(priorWord, priorTextInString);
|
1437
|
+
const keys = this._getIndexerKeys(argument.parent, parseNode);
|
1438
|
+
let keyFound = false;
|
1439
|
+
for (const key of keys) {
|
1440
|
+
if (completionMap.has(key)) {
|
1441
|
+
// Don't add key if it already exists in the completion.
|
1442
|
+
// ex) key = "dictKey"
|
1443
|
+
// dict[key] = 1
|
1444
|
+
// print(dict[<key will come from symbol table provider>]))
|
1445
|
+
continue;
|
1465
1446
|
}
|
1466
|
-
|
1467
|
-
|
1447
|
+
const stringLiteral = /^["|'].*["|']$/.test(key);
|
1448
|
+
if (parseNode.nodeType === 49 /* String */ && !stringLiteral) {
|
1449
|
+
continue;
|
1450
|
+
}
|
1451
|
+
keyFound = true;
|
1452
|
+
if (stringLiteral) {
|
1453
|
+
const keyWithoutQuote = key.substr(1, key.length - 2);
|
1454
|
+
this._addStringLiteralToCompletions(keyWithoutQuote, quoteInfo, postText, completionMap, exports.dictionaryKeyDetail);
|
1468
1455
|
}
|
1456
|
+
else {
|
1457
|
+
this._addNameToCompletions(key, vscode_languageserver_1.CompletionItemKind.Constant, priorWord, completionMap, {
|
1458
|
+
sortText: this._makeSortText(SortCategory.LiteralValue, key),
|
1459
|
+
itemDetail: exports.dictionaryKeyDetail,
|
1460
|
+
});
|
1461
|
+
}
|
1462
|
+
}
|
1463
|
+
if (keyFound) {
|
1464
|
+
return true;
|
1469
1465
|
}
|
1470
1466
|
}
|
1471
|
-
|
1472
|
-
|
1467
|
+
// if c == "/* here */"
|
1468
|
+
const comparison = parentAndChild.parent;
|
1469
|
+
const supportedOperators = [2 /* Assign */, 12 /* Equals */, 28 /* NotEquals */];
|
1470
|
+
if (comparison.nodeType === 7 /* BinaryOperation */ && supportedOperators.includes(comparison.operator)) {
|
1471
|
+
const type = this._evaluator.getType(comparison.leftExpression);
|
1472
|
+
if (type && (0, typeUtils_1.isLiteralTypeOrUnion)(type)) {
|
1473
|
+
this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
|
1474
|
+
return true;
|
1475
|
+
}
|
1476
|
+
}
|
1477
|
+
// if c := "/* here */"
|
1478
|
+
const assignmentExpression = parentAndChild.parent;
|
1479
|
+
if (assignmentExpression.nodeType === 4 /* AssignmentExpression */ &&
|
1480
|
+
assignmentExpression.rightExpression === parentAndChild.child) {
|
1481
|
+
const type = this._evaluator.getType(assignmentExpression.name);
|
1482
|
+
if (type && (0, typeUtils_1.isLiteralTypeOrUnion)(type)) {
|
1483
|
+
this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
|
1484
|
+
return true;
|
1485
|
+
}
|
1486
|
+
}
|
1487
|
+
// For now, we only support simple cases. no complex pattern matching.
|
1488
|
+
// match c:
|
1489
|
+
// case /* here */
|
1490
|
+
const caseNode = parentAndChild.parent;
|
1491
|
+
if (caseNode.nodeType === 64 /* Case */ &&
|
1492
|
+
caseNode.pattern.nodeType === 0 /* Error */ &&
|
1493
|
+
caseNode.pattern.category === 11 /* MissingPattern */ &&
|
1494
|
+
caseNode.suite === parentAndChild.child &&
|
1495
|
+
((_c = caseNode.parent) === null || _c === void 0 ? void 0 : _c.nodeType) === 63 /* Match */) {
|
1496
|
+
const type = this._evaluator.getType(caseNode.parent.subjectExpression);
|
1497
|
+
if (type && (0, typeUtils_1.isLiteralTypeOrUnion)(type)) {
|
1498
|
+
this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
|
1499
|
+
return true;
|
1500
|
+
}
|
1501
|
+
}
|
1502
|
+
// match c:
|
1503
|
+
// case "/* here */"
|
1504
|
+
// case Sym/*here*/
|
1505
|
+
const patternLiteral = parentAndChild.parent;
|
1506
|
+
if ((patternLiteral.nodeType === 67 /* PatternLiteral */ ||
|
1507
|
+
patternLiteral.nodeType === 69 /* PatternCapture */) &&
|
1508
|
+
((_d = patternLiteral.parent) === null || _d === void 0 ? void 0 : _d.nodeType) === 66 /* PatternAs */ &&
|
1509
|
+
((_e = patternLiteral.parent.parent) === null || _e === void 0 ? void 0 : _e.nodeType) === 64 /* Case */ &&
|
1510
|
+
((_f = patternLiteral.parent.parent.parent) === null || _f === void 0 ? void 0 : _f.nodeType) === 63 /* Match */) {
|
1511
|
+
const type = this._evaluator.getType(patternLiteral.parent.parent.parent.subjectExpression);
|
1512
|
+
if (type && (0, typeUtils_1.isLiteralTypeOrUnion)(type)) {
|
1513
|
+
this._addLiteralValuesForTargetType(type, priorWord, priorText, postText, completionMap);
|
1514
|
+
return true;
|
1515
|
+
}
|
1516
|
+
}
|
1517
|
+
if (parseNode.nodeType === 49 /* String */) {
|
1473
1518
|
const offset = (0, positionUtils_1.convertPositionToOffset)(this._position, this._parseResults.tokenizerOutput.lines);
|
1474
|
-
const atArgument =
|
1519
|
+
const atArgument = parseNode.parent.start < offset && offset < textRange_2.TextRange.getEnd(parseNode);
|
1475
1520
|
this._addCallArgumentCompletions(parseNode, priorWord, priorText, postText, atArgument, completionMap);
|
1521
|
+
return true;
|
1476
1522
|
}
|
1477
|
-
return
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1523
|
+
return false;
|
1524
|
+
function getParentSkippingStringList(node) {
|
1525
|
+
var _a;
|
1526
|
+
if (!node.parent) {
|
1527
|
+
return undefined;
|
1528
|
+
}
|
1529
|
+
if (node.nodeType !== 49 /* String */) {
|
1530
|
+
return { parent: node.parent, child: node };
|
1531
|
+
}
|
1532
|
+
if (!node.parent.parent) {
|
1533
|
+
return undefined;
|
1534
|
+
}
|
1535
|
+
if (((_a = node.parent) === null || _a === void 0 ? void 0 : _a.nodeType) !== 48 /* StringList */ || node.parent.strings.length > 1) {
|
1536
|
+
return undefined;
|
1537
|
+
}
|
1538
|
+
return { parent: node.parent.parent, child: node.parent };
|
1489
1539
|
}
|
1540
|
+
}
|
1541
|
+
_tryAddTypedDictKeys(type, existingKeys, priorWord, priorText, postText, completionMap) {
|
1490
1542
|
let typedDicts = [];
|
1491
|
-
(0, typeUtils_1.doForEachSubtype)(
|
1543
|
+
(0, typeUtils_1.doForEachSubtype)(type, (subtype) => {
|
1492
1544
|
if ((0, types_1.isClassInstance)(subtype) && types_1.ClassType.isTypedDictClass(subtype)) {
|
1493
1545
|
typedDicts.push(subtype);
|
1494
1546
|
}
|
@@ -1496,10 +1548,9 @@ class CompletionProvider {
|
|
1496
1548
|
if (typedDicts.length === 0) {
|
1497
1549
|
return false;
|
1498
1550
|
}
|
1499
|
-
|
1500
|
-
|
1501
|
-
const
|
1502
|
-
const excludes = new Set(keys);
|
1551
|
+
typedDicts = this._tryNarrowTypedDicts(typedDicts, existingKeys);
|
1552
|
+
const quoteInfo = this._getQuoteInfo(priorWord, priorText);
|
1553
|
+
const excludes = new Set(existingKeys);
|
1503
1554
|
typedDicts.forEach((typedDict) => {
|
1504
1555
|
(0, typedDicts_1.getTypedDictMembersForClass)(this._evaluator, typedDict, /* allowNarrowed */ true).forEach((_, key) => {
|
1505
1556
|
// Unions of TypedDicts may define the same key.
|
@@ -1507,13 +1558,25 @@ class CompletionProvider {
|
|
1507
1558
|
return;
|
1508
1559
|
}
|
1509
1560
|
excludes.add(key);
|
1510
|
-
this._addStringLiteralToCompletions(key,
|
1511
|
-
? quoteValue.quoteCharacter
|
1512
|
-
: this._parseResults.tokenizerOutput.predominantSingleQuoteCharacter, completionMap);
|
1561
|
+
this._addStringLiteralToCompletions(key, quoteInfo, postText, completionMap);
|
1513
1562
|
});
|
1514
1563
|
});
|
1515
1564
|
return true;
|
1516
1565
|
}
|
1566
|
+
_tryAddTypedDictKeysFromDictionary(dictionaryNode, stringNode, priorWord, priorText, postText, completionMap) {
|
1567
|
+
var _a;
|
1568
|
+
const expectedTypeResult = this._evaluator.getExpectedType(dictionaryNode);
|
1569
|
+
if (!expectedTypeResult) {
|
1570
|
+
return false;
|
1571
|
+
}
|
1572
|
+
// If the expected type result is associated with a node above the
|
1573
|
+
// dictionaryNode in the parse tree, there are no typed dict keys to add.
|
1574
|
+
if (ParseTreeUtils.getNodeDepth(expectedTypeResult.node) < ParseTreeUtils.getNodeDepth(dictionaryNode)) {
|
1575
|
+
return false;
|
1576
|
+
}
|
1577
|
+
const keys = this._getDictExpressionStringKeys(dictionaryNode, stringNode ? new Set([(_a = stringNode.parent) === null || _a === void 0 ? void 0 : _a.id]) : undefined);
|
1578
|
+
return this._tryAddTypedDictKeys(expectedTypeResult.type, keys, priorWord, priorText, postText, completionMap);
|
1579
|
+
}
|
1517
1580
|
_tryNarrowTypedDicts(types, keys) {
|
1518
1581
|
const newTypes = types.flatMap((type) => {
|
1519
1582
|
const entries = (0, typedDicts_1.getTypedDictMembersForClass)(this._evaluator, type, /* allowNarrowed */ true);
|
@@ -1532,14 +1595,15 @@ class CompletionProvider {
|
|
1532
1595
|
}
|
1533
1596
|
// Find out quotation and string prefix to use for string literals
|
1534
1597
|
// completion under current context.
|
1535
|
-
_getQuoteInfo(priorText) {
|
1598
|
+
_getQuoteInfo(priorWord, priorText) {
|
1599
|
+
let filterText = priorWord;
|
1536
1600
|
let stringValue = undefined;
|
1537
1601
|
let quoteCharacter = this._parseResults.tokenizerOutput.predominantSingleQuoteCharacter;
|
1538
1602
|
// If completion is not inside of the existing string literal
|
1539
1603
|
// ex) typedDict[ |<= here
|
1540
1604
|
// use default quotation char without any string prefix.
|
1541
1605
|
if (!this._insideStringLiteral) {
|
1542
|
-
return { stringValue, quoteCharacter };
|
1606
|
+
return { priorWord, priorText, filterText, stringValue, quoteCharacter };
|
1543
1607
|
}
|
1544
1608
|
const singleQuote = "'";
|
1545
1609
|
const doubleQuote = '"';
|
@@ -1569,9 +1633,12 @@ class CompletionProvider {
|
|
1569
1633
|
if (this._insideStringLiteral.flags & 64 /* Format */) {
|
1570
1634
|
quoteCharacter = this._insideStringLiteral.flags & 1 /* SingleQuote */ ? doubleQuote : singleQuote;
|
1571
1635
|
}
|
1572
|
-
|
1636
|
+
if (stringValue) {
|
1637
|
+
filterText = stringValue;
|
1638
|
+
}
|
1639
|
+
return { priorWord, priorText, filterText, stringValue, quoteCharacter };
|
1573
1640
|
}
|
1574
|
-
|
1641
|
+
_tryAddTypedDictKeysFromIndexer(indexNode, priorWord, priorText, postText, completionMap) {
|
1575
1642
|
if (!indexNode) {
|
1576
1643
|
return false;
|
1577
1644
|
}
|
@@ -1579,26 +1646,11 @@ class CompletionProvider {
|
|
1579
1646
|
if (!baseType) {
|
1580
1647
|
return false;
|
1581
1648
|
}
|
1582
|
-
|
1583
|
-
(0, typeUtils_1.doForEachSubtype)(baseType, (subtype) => {
|
1584
|
-
if (!(0, types_1.isClassInstance)(subtype)) {
|
1585
|
-
return;
|
1586
|
-
}
|
1587
|
-
if (!types_1.ClassType.isTypedDictClass(subtype)) {
|
1588
|
-
return;
|
1589
|
-
}
|
1590
|
-
const entries = (0, typedDicts_1.getTypedDictMembersForClass)(this._evaluator, subtype, /* allowNarrowed */ true);
|
1591
|
-
const quoteValue = this._getQuoteInfo(priorText);
|
1592
|
-
entries.forEach((_, key) => {
|
1593
|
-
this._addStringLiteralToCompletions(key, quoteValue.stringValue, postText, quoteValue.quoteCharacter, completionMap);
|
1594
|
-
});
|
1595
|
-
foundTypedDict = true;
|
1596
|
-
});
|
1597
|
-
return foundTypedDict;
|
1649
|
+
return this._tryAddTypedDictKeys(baseType, [], priorWord, priorText, postText, completionMap);
|
1598
1650
|
}
|
1599
|
-
_addStringLiteralToCompletions(value,
|
1600
|
-
if (StringUtils.isPatternInSymbol(
|
1601
|
-
const valueWithQuotes = `${quoteCharacter}${value}${quoteCharacter}`;
|
1651
|
+
_addStringLiteralToCompletions(value, quoteInfo, postText, completionMap, detail) {
|
1652
|
+
if (StringUtils.isPatternInSymbol(quoteInfo.filterText || '', value)) {
|
1653
|
+
const valueWithQuotes = `${quoteInfo.quoteCharacter}${value}${quoteInfo.quoteCharacter}`;
|
1602
1654
|
if (completionMap.has(valueWithQuotes)) {
|
1603
1655
|
return;
|
1604
1656
|
}
|
@@ -1606,14 +1658,17 @@ class CompletionProvider {
|
|
1606
1658
|
completionItem.kind = vscode_languageserver_1.CompletionItemKind.Constant;
|
1607
1659
|
completionItem.sortText = this._makeSortText(SortCategory.LiteralValue, valueWithQuotes);
|
1608
1660
|
let rangeStartCol = this._position.character;
|
1609
|
-
if (
|
1610
|
-
rangeStartCol -=
|
1661
|
+
if (quoteInfo.stringValue !== undefined) {
|
1662
|
+
rangeStartCol -= quoteInfo.stringValue.length + 1;
|
1663
|
+
}
|
1664
|
+
else if (quoteInfo.priorWord) {
|
1665
|
+
rangeStartCol -= quoteInfo.priorWord.length;
|
1611
1666
|
}
|
1612
1667
|
// If the text after the insertion point is the closing quote,
|
1613
1668
|
// replace it.
|
1614
1669
|
let rangeEndCol = this._position.character;
|
1615
1670
|
if (postText !== undefined) {
|
1616
|
-
if (postText.startsWith(quoteCharacter)) {
|
1671
|
+
if (postText.startsWith(quoteInfo.quoteCharacter)) {
|
1617
1672
|
rangeEndCol++;
|
1618
1673
|
}
|
1619
1674
|
}
|