@zzzen/pyright-internal 1.2.0-dev.20230813 → 1.2.0-dev.20230820

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.
Files changed (78) hide show
  1. package/dist/analyzer/binder.js +8 -2
  2. package/dist/analyzer/binder.js.map +1 -1
  3. package/dist/analyzer/checker.d.ts +1 -0
  4. package/dist/analyzer/checker.js +77 -6
  5. package/dist/analyzer/checker.js.map +1 -1
  6. package/dist/analyzer/dataClasses.js +242 -236
  7. package/dist/analyzer/dataClasses.js.map +1 -1
  8. package/dist/analyzer/enums.js +12 -0
  9. package/dist/analyzer/enums.js.map +1 -1
  10. package/dist/analyzer/importResolver.js +3 -1
  11. package/dist/analyzer/importResolver.js.map +1 -1
  12. package/dist/analyzer/namedTuples.js +6 -0
  13. package/dist/analyzer/namedTuples.js.map +1 -1
  14. package/dist/analyzer/operations.d.ts +1 -1
  15. package/dist/analyzer/operations.js +2 -2
  16. package/dist/analyzer/operations.js.map +1 -1
  17. package/dist/analyzer/parameterUtils.d.ts +2 -1
  18. package/dist/analyzer/parameterUtils.js +15 -0
  19. package/dist/analyzer/parameterUtils.js.map +1 -1
  20. package/dist/analyzer/protocols.js +14 -0
  21. package/dist/analyzer/protocols.js.map +1 -1
  22. package/dist/analyzer/service.js +2 -2
  23. package/dist/analyzer/service.js.map +1 -1
  24. package/dist/analyzer/typeEvaluator.js +194 -108
  25. package/dist/analyzer/typeEvaluator.js.map +1 -1
  26. package/dist/analyzer/typeEvaluatorTypes.d.ts +1 -1
  27. package/dist/analyzer/typeEvaluatorTypes.js +2 -2
  28. package/dist/analyzer/typeEvaluatorTypes.js.map +1 -1
  29. package/dist/analyzer/typeGuards.js +3 -0
  30. package/dist/analyzer/typeGuards.js.map +1 -1
  31. package/dist/analyzer/typePrinter.js +3 -0
  32. package/dist/analyzer/typePrinter.js.map +1 -1
  33. package/dist/analyzer/typeUtils.d.ts +1 -0
  34. package/dist/analyzer/typeUtils.js +20 -2
  35. package/dist/analyzer/typeUtils.js.map +1 -1
  36. package/dist/analyzer/types.js +1 -0
  37. package/dist/analyzer/types.js.map +1 -1
  38. package/dist/common/serviceProvider.d.ts +4 -3
  39. package/dist/languageServerBase.d.ts +2 -2
  40. package/dist/languageServerBase.js +4 -2
  41. package/dist/languageServerBase.js.map +1 -1
  42. package/dist/localization/localize.d.ts +22 -4
  43. package/dist/localization/localize.js +7 -2
  44. package/dist/localization/localize.js.map +1 -1
  45. package/dist/localization/package.nls.cs.json +3 -2
  46. package/dist/localization/package.nls.de.json +3 -2
  47. package/dist/localization/package.nls.en-us.json +16 -11
  48. package/dist/localization/package.nls.es.json +3 -2
  49. package/dist/localization/package.nls.fr.json +3 -2
  50. package/dist/localization/package.nls.it.json +3 -2
  51. package/dist/localization/package.nls.ja.json +3 -2
  52. package/dist/localization/package.nls.ko.json +3 -2
  53. package/dist/localization/package.nls.pl.json +3 -2
  54. package/dist/localization/package.nls.pt-br.json +3 -2
  55. package/dist/localization/package.nls.qps-ploc.json +3 -2
  56. package/dist/localization/package.nls.ru.json +3 -2
  57. package/dist/localization/package.nls.tr.json +3 -2
  58. package/dist/localization/package.nls.zh-cn.json +3 -2
  59. package/dist/localization/package.nls.zh-tw.json +2 -1
  60. package/dist/parser/parser.d.ts +1 -0
  61. package/dist/parser/parser.js +78 -18
  62. package/dist/parser/parser.js.map +1 -1
  63. package/dist/server.js +1 -1
  64. package/dist/server.js.map +1 -1
  65. package/dist/tests/harness/fourslash/testState.d.ts +1 -1
  66. package/dist/tests/harness/fourslash/testState.js +2 -2
  67. package/dist/tests/harness/fourslash/testState.js.map +1 -1
  68. package/dist/tests/typeEvaluator1.test.js +4 -4
  69. package/dist/tests/typeEvaluator1.test.js.map +1 -1
  70. package/dist/tests/typeEvaluator2.test.js +9 -1
  71. package/dist/tests/typeEvaluator2.test.js.map +1 -1
  72. package/dist/tests/typeEvaluator3.test.js +7 -3
  73. package/dist/tests/typeEvaluator3.test.js.map +1 -1
  74. package/dist/tests/typeEvaluator4.test.js +9 -1
  75. package/dist/tests/typeEvaluator4.test.js.map +1 -1
  76. package/dist/tests/typeEvaluator5.test.js +9 -1
  77. package/dist/tests/typeEvaluator5.test.js.map +1 -1
  78. package/package.json +1 -1
@@ -86,270 +86,276 @@ function synthesizeDataClassMethods(evaluator, node, classType, skipSynthesizeIn
86
86
  }
87
87
  const localEntryTypeEvaluator = [];
88
88
  let sawKeywordOnlySeparator = false;
89
- classType.details.fields.forEach((symbol) => {
89
+ classType.details.fields.forEach((symbol, name) => {
90
90
  var _a, _b, _c;
91
- if (!symbol.isIgnoredForProtocolMatch()) {
92
- // Only variables (not functions, classes, etc.) are considered.
93
- const classVarDecl = symbol.getTypedDeclarations().find((decl) => {
94
- if (decl.type !== 1 /* Variable */) {
95
- return false;
96
- }
97
- const container = (0, parseTreeUtils_1.getEnclosingClassOrFunction)(decl.node);
98
- if (!container || container.nodeType !== 10 /* Class */) {
99
- return false;
91
+ if (symbol.isIgnoredForProtocolMatch()) {
92
+ return;
93
+ }
94
+ // Apparently, `__hash__` is special-cased in a dataclass. I can't find
95
+ // this in the spec, but the runtime seems to treat is specially.
96
+ if (name === '__hash__') {
97
+ return;
98
+ }
99
+ // Only variables (not functions, classes, etc.) are considered.
100
+ const classVarDecl = symbol.getTypedDeclarations().find((decl) => {
101
+ if (decl.type !== 1 /* Variable */) {
102
+ return false;
103
+ }
104
+ const container = (0, parseTreeUtils_1.getEnclosingClassOrFunction)(decl.node);
105
+ if (!container || container.nodeType !== 10 /* Class */) {
106
+ return false;
107
+ }
108
+ return true;
109
+ });
110
+ if (classVarDecl) {
111
+ let statement = classVarDecl.node;
112
+ while (statement) {
113
+ if (statement.nodeType === 3 /* Assignment */) {
114
+ break;
100
115
  }
101
- return true;
102
- });
103
- if (classVarDecl) {
104
- let statement = classVarDecl.node;
105
- while (statement) {
106
- if (statement.nodeType === 3 /* Assignment */) {
107
- break;
116
+ if (statement.nodeType === 54 /* TypeAnnotation */) {
117
+ if (((_a = statement.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 3 /* Assignment */) {
118
+ statement = statement.parent;
108
119
  }
109
- if (statement.nodeType === 54 /* TypeAnnotation */) {
110
- if (((_a = statement.parent) === null || _a === void 0 ? void 0 : _a.nodeType) === 3 /* Assignment */) {
111
- statement = statement.parent;
112
- }
113
- break;
114
- }
115
- statement = statement.parent;
120
+ break;
116
121
  }
117
- if (!statement) {
118
- return;
122
+ statement = statement.parent;
123
+ }
124
+ if (!statement) {
125
+ return;
126
+ }
127
+ let variableNameNode;
128
+ let aliasName;
129
+ let variableTypeEvaluator;
130
+ let hasDefaultValue = false;
131
+ let isKeywordOnly = types_1.ClassType.isDataClassKeywordOnlyParams(classType) || sawKeywordOnlySeparator;
132
+ let defaultValueExpression;
133
+ let includeInInit = true;
134
+ let converter;
135
+ if (statement.nodeType === 3 /* Assignment */) {
136
+ if (statement.leftExpression.nodeType === 54 /* TypeAnnotation */ &&
137
+ statement.leftExpression.valueExpression.nodeType === 38 /* Name */) {
138
+ variableNameNode = statement.leftExpression.valueExpression;
139
+ const assignmentStatement = statement;
140
+ variableTypeEvaluator = () => evaluator.getTypeOfAnnotation(assignmentStatement.leftExpression.typeAnnotation, {
141
+ isVariableAnnotation: true,
142
+ allowFinal: true,
143
+ allowClassVar: true,
144
+ });
119
145
  }
120
- let variableNameNode;
121
- let aliasName;
122
- let variableTypeEvaluator;
123
- let hasDefaultValue = false;
124
- let isKeywordOnly = types_1.ClassType.isDataClassKeywordOnlyParams(classType) || sawKeywordOnlySeparator;
125
- let defaultValueExpression;
126
- let includeInInit = true;
127
- let converter;
128
- if (statement.nodeType === 3 /* Assignment */) {
129
- if (statement.leftExpression.nodeType === 54 /* TypeAnnotation */ &&
130
- statement.leftExpression.valueExpression.nodeType === 38 /* Name */) {
131
- variableNameNode = statement.leftExpression.valueExpression;
132
- const assignmentStatement = statement;
133
- variableTypeEvaluator = () => evaluator.getTypeOfAnnotation(assignmentStatement.leftExpression.typeAnnotation, {
134
- isVariableAnnotation: true,
135
- allowFinal: true,
136
- allowClassVar: true,
137
- });
138
- }
139
- hasDefaultValue = true;
140
- defaultValueExpression = statement.rightExpression;
141
- // If the RHS of the assignment is assigning a field instance where the
142
- // "init" parameter is set to false, do not include it in the init method.
143
- if (statement.rightExpression.nodeType === 9 /* Call */) {
144
- const callTypeResult = evaluator.getTypeOfExpression(statement.rightExpression.leftExpression, 16777218 /* CallBaseDefaults */);
145
- const callType = callTypeResult.type;
146
- if (isDataclassFieldConstructor(callType, ((_b = classType.details.dataClassBehaviors) === null || _b === void 0 ? void 0 : _b.fieldDescriptorNames) || [])) {
147
- const initArg = statement.rightExpression.arguments.find((arg) => { var _a; return ((_a = arg.name) === null || _a === void 0 ? void 0 : _a.value) === 'init'; });
148
- if (initArg && initArg.valueExpression) {
149
- const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
150
- const value = (0, staticExpressions_1.evaluateStaticBoolExpression)(initArg.valueExpression, fileInfo.executionEnvironment, fileInfo.definedConstants);
151
- if (value === false) {
152
- includeInInit = false;
153
- }
146
+ hasDefaultValue = true;
147
+ defaultValueExpression = statement.rightExpression;
148
+ // If the RHS of the assignment is assigning a field instance where the
149
+ // "init" parameter is set to false, do not include it in the init method.
150
+ if (statement.rightExpression.nodeType === 9 /* Call */) {
151
+ const callTypeResult = evaluator.getTypeOfExpression(statement.rightExpression.leftExpression, 16777218 /* CallBaseDefaults */);
152
+ const callType = callTypeResult.type;
153
+ if (isDataclassFieldConstructor(callType, ((_b = classType.details.dataClassBehaviors) === null || _b === void 0 ? void 0 : _b.fieldDescriptorNames) || [])) {
154
+ const initArg = statement.rightExpression.arguments.find((arg) => { var _a; return ((_a = arg.name) === null || _a === void 0 ? void 0 : _a.value) === 'init'; });
155
+ if (initArg && initArg.valueExpression) {
156
+ const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
157
+ const value = (0, staticExpressions_1.evaluateStaticBoolExpression)(initArg.valueExpression, fileInfo.executionEnvironment, fileInfo.definedConstants);
158
+ if (value === false) {
159
+ includeInInit = false;
154
160
  }
155
- else {
156
- // See if the field constructor has an `init` parameter with
157
- // a default value.
158
- let callTarget;
159
- if ((0, types_1.isFunction)(callType)) {
160
- callTarget = callType;
161
- }
162
- else if ((0, types_1.isOverloadedFunction)(callType)) {
163
- callTarget = evaluator.getBestOverloadForArguments(statement.rightExpression, { type: callType, isIncomplete: callTypeResult.isIncomplete }, statement.rightExpression.arguments);
164
- }
165
- else if ((0, types_1.isInstantiableClass)(callType)) {
166
- const initCall = evaluator.getBoundMethod(callType, '__init__');
167
- if (initCall) {
168
- if ((0, types_1.isFunction)(initCall)) {
169
- callTarget = initCall;
170
- }
171
- else if ((0, types_1.isOverloadedFunction)(initCall)) {
172
- callTarget = evaluator.getBestOverloadForArguments(statement.rightExpression, { type: initCall }, statement.rightExpression.arguments);
173
- }
161
+ }
162
+ else {
163
+ // See if the field constructor has an `init` parameter with
164
+ // a default value.
165
+ let callTarget;
166
+ if ((0, types_1.isFunction)(callType)) {
167
+ callTarget = callType;
168
+ }
169
+ else if ((0, types_1.isOverloadedFunction)(callType)) {
170
+ callTarget = evaluator.getBestOverloadForArguments(statement.rightExpression, { type: callType, isIncomplete: callTypeResult.isIncomplete }, statement.rightExpression.arguments);
171
+ }
172
+ else if ((0, types_1.isInstantiableClass)(callType)) {
173
+ const initCall = evaluator.getBoundMethod(callType, '__init__');
174
+ if (initCall) {
175
+ if ((0, types_1.isFunction)(initCall)) {
176
+ callTarget = initCall;
174
177
  }
175
- }
176
- if (callTarget) {
177
- const initParam = callTarget.details.parameters.find((p) => p.name === 'init');
178
- if (initParam && initParam.defaultValueExpression && initParam.hasDeclaredType) {
179
- if ((0, types_1.isClass)(initParam.type) &&
180
- types_1.ClassType.isBuiltIn(initParam.type, 'bool') &&
181
- (0, typeUtils_1.isLiteralType)(initParam.type)) {
182
- if (initParam.type.literalValue === false) {
183
- includeInInit = false;
184
- }
185
- }
178
+ else if ((0, types_1.isOverloadedFunction)(initCall)) {
179
+ callTarget = evaluator.getBestOverloadForArguments(statement.rightExpression, { type: initCall }, statement.rightExpression.arguments);
186
180
  }
187
181
  }
188
182
  }
189
- const kwOnlyArg = statement.rightExpression.arguments.find((arg) => { var _a; return ((_a = arg.name) === null || _a === void 0 ? void 0 : _a.value) === 'kw_only'; });
190
- if (kwOnlyArg && kwOnlyArg.valueExpression) {
191
- const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
192
- const value = (0, staticExpressions_1.evaluateStaticBoolExpression)(kwOnlyArg.valueExpression, fileInfo.executionEnvironment, fileInfo.definedConstants);
193
- if (value === false) {
194
- isKeywordOnly = false;
195
- }
196
- else if (value === true) {
197
- isKeywordOnly = true;
183
+ if (callTarget) {
184
+ const initParam = callTarget.details.parameters.find((p) => p.name === 'init');
185
+ if (initParam && initParam.defaultValueExpression && initParam.hasDeclaredType) {
186
+ if ((0, types_1.isClass)(initParam.type) &&
187
+ types_1.ClassType.isBuiltIn(initParam.type, 'bool') &&
188
+ (0, typeUtils_1.isLiteralType)(initParam.type)) {
189
+ if (initParam.type.literalValue === false) {
190
+ includeInInit = false;
191
+ }
192
+ }
198
193
  }
199
194
  }
200
- const defaultArg = statement.rightExpression.arguments.find((arg) => {
201
- var _a, _b, _c;
202
- return ((_a = arg.name) === null || _a === void 0 ? void 0 : _a.value) === 'default' ||
203
- ((_b = arg.name) === null || _b === void 0 ? void 0 : _b.value) === 'default_factory' ||
204
- ((_c = arg.name) === null || _c === void 0 ? void 0 : _c.value) === 'factory';
205
- });
206
- hasDefaultValue = !!defaultArg;
207
- if (defaultArg === null || defaultArg === void 0 ? void 0 : defaultArg.valueExpression) {
208
- defaultValueExpression = defaultArg.valueExpression;
209
- }
210
- const aliasArg = statement.rightExpression.arguments.find((arg) => { var _a; return ((_a = arg.name) === null || _a === void 0 ? void 0 : _a.value) === 'alias'; });
211
- if (aliasArg) {
212
- const valueType = evaluator.getTypeOfExpression(aliasArg.valueExpression).type;
213
- if ((0, types_1.isClassInstance)(valueType) &&
214
- types_1.ClassType.isBuiltIn(valueType, 'str') &&
215
- (0, typeUtils_1.isLiteralType)(valueType)) {
216
- aliasName = valueType.literalValue;
217
- }
195
+ }
196
+ const kwOnlyArg = statement.rightExpression.arguments.find((arg) => { var _a; return ((_a = arg.name) === null || _a === void 0 ? void 0 : _a.value) === 'kw_only'; });
197
+ if (kwOnlyArg && kwOnlyArg.valueExpression) {
198
+ const fileInfo = AnalyzerNodeInfo.getFileInfo(node);
199
+ const value = (0, staticExpressions_1.evaluateStaticBoolExpression)(kwOnlyArg.valueExpression, fileInfo.executionEnvironment, fileInfo.definedConstants);
200
+ if (value === false) {
201
+ isKeywordOnly = false;
218
202
  }
219
- const converterArg = statement.rightExpression.arguments.find((arg) => { var _a; return ((_a = arg.name) === null || _a === void 0 ? void 0 : _a.value) === 'converter'; });
220
- if (converterArg && converterArg.valueExpression) {
221
- converter = converterArg;
203
+ else if (value === true) {
204
+ isKeywordOnly = true;
222
205
  }
223
206
  }
224
- }
225
- }
226
- else if (statement.nodeType === 54 /* TypeAnnotation */) {
227
- if (statement.valueExpression.nodeType === 38 /* Name */) {
228
- variableNameNode = statement.valueExpression;
229
- const annotationStatement = statement;
230
- variableTypeEvaluator = () => evaluator.getTypeOfAnnotation(annotationStatement.typeAnnotation, {
231
- isVariableAnnotation: true,
232
- allowFinal: true,
233
- allowClassVar: true,
207
+ const defaultArg = statement.rightExpression.arguments.find((arg) => {
208
+ var _a, _b, _c;
209
+ return ((_a = arg.name) === null || _a === void 0 ? void 0 : _a.value) === 'default' ||
210
+ ((_b = arg.name) === null || _b === void 0 ? void 0 : _b.value) === 'default_factory' ||
211
+ ((_c = arg.name) === null || _c === void 0 ? void 0 : _c.value) === 'factory';
234
212
  });
235
- // Is this a KW_ONLY separator introduced in Python 3.10?
236
- if (statement.valueExpression.value === '_') {
237
- const annotatedType = variableTypeEvaluator();
238
- if ((0, types_1.isClassInstance)(annotatedType) && types_1.ClassType.isBuiltIn(annotatedType, 'KW_ONLY')) {
239
- sawKeywordOnlySeparator = true;
240
- variableNameNode = undefined;
241
- variableTypeEvaluator = undefined;
213
+ hasDefaultValue = !!defaultArg;
214
+ if (defaultArg === null || defaultArg === void 0 ? void 0 : defaultArg.valueExpression) {
215
+ defaultValueExpression = defaultArg.valueExpression;
216
+ }
217
+ const aliasArg = statement.rightExpression.arguments.find((arg) => { var _a; return ((_a = arg.name) === null || _a === void 0 ? void 0 : _a.value) === 'alias'; });
218
+ if (aliasArg) {
219
+ const valueType = evaluator.getTypeOfExpression(aliasArg.valueExpression).type;
220
+ if ((0, types_1.isClassInstance)(valueType) &&
221
+ types_1.ClassType.isBuiltIn(valueType, 'str') &&
222
+ (0, typeUtils_1.isLiteralType)(valueType)) {
223
+ aliasName = valueType.literalValue;
242
224
  }
243
225
  }
226
+ const converterArg = statement.rightExpression.arguments.find((arg) => { var _a; return ((_a = arg.name) === null || _a === void 0 ? void 0 : _a.value) === 'converter'; });
227
+ if (converterArg && converterArg.valueExpression) {
228
+ converter = converterArg;
229
+ }
244
230
  }
245
231
  }
246
- if (variableNameNode && variableTypeEvaluator) {
247
- const variableName = variableNameNode.value;
248
- // Don't include class vars. PEP 557 indicates that they shouldn't
249
- // be considered data class entries.
250
- const variableSymbol = classType.details.fields.get(variableName);
251
- const isFinal = variableSymbol === null || variableSymbol === void 0 ? void 0 : variableSymbol.getDeclarations().some((decl) => decl.type === 1 /* Variable */ && decl.isFinal);
252
- if ((variableSymbol === null || variableSymbol === void 0 ? void 0 : variableSymbol.isClassVar()) && !isFinal) {
253
- // If an ancestor class declared an instance variable but this dataclass
254
- // declares a ClassVar, delete the older one from the full data class entries.
255
- // We exclude final variables here because a Final type annotation is implicitly
256
- // considered a ClassVar by the binder, but dataclass rules are different.
257
- const index = fullDataClassEntries.findIndex((p) => p.name === variableName);
258
- if (index >= 0) {
259
- fullDataClassEntries.splice(index, 1);
232
+ }
233
+ else if (statement.nodeType === 54 /* TypeAnnotation */) {
234
+ if (statement.valueExpression.nodeType === 38 /* Name */) {
235
+ variableNameNode = statement.valueExpression;
236
+ const annotationStatement = statement;
237
+ variableTypeEvaluator = () => evaluator.getTypeOfAnnotation(annotationStatement.typeAnnotation, {
238
+ isVariableAnnotation: true,
239
+ allowFinal: true,
240
+ allowClassVar: true,
241
+ });
242
+ // Is this a KW_ONLY separator introduced in Python 3.10?
243
+ if (statement.valueExpression.value === '_') {
244
+ const annotatedType = variableTypeEvaluator();
245
+ if ((0, types_1.isClassInstance)(annotatedType) && types_1.ClassType.isBuiltIn(annotatedType, 'KW_ONLY')) {
246
+ sawKeywordOnlySeparator = true;
247
+ variableNameNode = undefined;
248
+ variableTypeEvaluator = undefined;
260
249
  }
261
- const dataClassEntry = {
262
- name: variableName,
263
- classType,
264
- alias: aliasName,
265
- isKeywordOnly: false,
266
- hasDefault: hasDefaultValue,
267
- defaultValueExpression,
268
- includeInInit,
269
- nameNode: variableNameNode,
270
- type: types_1.UnknownType.create(),
271
- isClassVar: true,
272
- converter,
273
- };
274
- localDataClassEntries.push(dataClassEntry);
250
+ }
251
+ }
252
+ }
253
+ if (variableNameNode && variableTypeEvaluator) {
254
+ const variableName = variableNameNode.value;
255
+ // Don't include class vars. PEP 557 indicates that they shouldn't
256
+ // be considered data class entries.
257
+ const variableSymbol = classType.details.fields.get(variableName);
258
+ const isFinal = variableSymbol === null || variableSymbol === void 0 ? void 0 : variableSymbol.getDeclarations().some((decl) => decl.type === 1 /* Variable */ && decl.isFinal);
259
+ if ((variableSymbol === null || variableSymbol === void 0 ? void 0 : variableSymbol.isClassVar()) && !isFinal) {
260
+ // If an ancestor class declared an instance variable but this dataclass
261
+ // declares a ClassVar, delete the older one from the full data class entries.
262
+ // We exclude final variables here because a Final type annotation is implicitly
263
+ // considered a ClassVar by the binder, but dataclass rules are different.
264
+ const index = fullDataClassEntries.findIndex((p) => p.name === variableName);
265
+ if (index >= 0) {
266
+ fullDataClassEntries.splice(index, 1);
267
+ }
268
+ const dataClassEntry = {
269
+ name: variableName,
270
+ classType,
271
+ alias: aliasName,
272
+ isKeywordOnly: false,
273
+ hasDefault: hasDefaultValue,
274
+ defaultValueExpression,
275
+ includeInInit,
276
+ nameNode: variableNameNode,
277
+ type: types_1.UnknownType.create(),
278
+ isClassVar: true,
279
+ converter,
280
+ };
281
+ localDataClassEntries.push(dataClassEntry);
282
+ }
283
+ else {
284
+ // Create a new data class entry, but defer evaluation of the type until
285
+ // we've compiled the full list of data class entries for this class. This
286
+ // allows us to handle circular references in types.
287
+ const dataClassEntry = {
288
+ name: variableName,
289
+ classType,
290
+ alias: aliasName,
291
+ isKeywordOnly,
292
+ hasDefault: hasDefaultValue,
293
+ defaultValueExpression,
294
+ includeInInit,
295
+ nameNode: variableNameNode,
296
+ type: types_1.UnknownType.create(),
297
+ isClassVar: false,
298
+ converter,
299
+ };
300
+ localEntryTypeEvaluator.push({ entry: dataClassEntry, evaluator: variableTypeEvaluator });
301
+ // Add the new entry to the local entry list.
302
+ let insertIndex = localDataClassEntries.findIndex((e) => e.name === variableName);
303
+ if (insertIndex >= 0) {
304
+ localDataClassEntries[insertIndex] = dataClassEntry;
275
305
  }
276
306
  else {
277
- // Create a new data class entry, but defer evaluation of the type until
278
- // we've compiled the full list of data class entries for this class. This
279
- // allows us to handle circular references in types.
280
- const dataClassEntry = {
281
- name: variableName,
282
- classType,
283
- alias: aliasName,
284
- isKeywordOnly,
285
- hasDefault: hasDefaultValue,
286
- defaultValueExpression,
287
- includeInInit,
288
- nameNode: variableNameNode,
289
- type: types_1.UnknownType.create(),
290
- isClassVar: false,
291
- converter,
292
- };
293
- localEntryTypeEvaluator.push({ entry: dataClassEntry, evaluator: variableTypeEvaluator });
294
- // Add the new entry to the local entry list.
295
- let insertIndex = localDataClassEntries.findIndex((e) => e.name === variableName);
296
- if (insertIndex >= 0) {
297
- localDataClassEntries[insertIndex] = dataClassEntry;
298
- }
299
- else {
300
- localDataClassEntries.push(dataClassEntry);
301
- }
302
- // Add the new entry to the full entry list.
303
- insertIndex = fullDataClassEntries.findIndex((p) => p.name === variableName);
304
- if (insertIndex >= 0) {
305
- const oldEntry = fullDataClassEntries[insertIndex];
306
- // While this isn't documented behavior, it appears that the dataclass implementation
307
- // causes overridden variables to "inherit" default values from parent classes.
308
- if (!dataClassEntry.hasDefault && oldEntry.hasDefault && oldEntry.includeInInit) {
309
- dataClassEntry.hasDefault = true;
310
- dataClassEntry.defaultValueExpression = oldEntry.defaultValueExpression;
311
- hasDefaultValue = true;
312
- }
313
- fullDataClassEntries[insertIndex] = dataClassEntry;
314
- }
315
- else {
316
- fullDataClassEntries.push(dataClassEntry);
317
- insertIndex = fullDataClassEntries.length - 1;
307
+ localDataClassEntries.push(dataClassEntry);
308
+ }
309
+ // Add the new entry to the full entry list.
310
+ insertIndex = fullDataClassEntries.findIndex((p) => p.name === variableName);
311
+ if (insertIndex >= 0) {
312
+ const oldEntry = fullDataClassEntries[insertIndex];
313
+ // While this isn't documented behavior, it appears that the dataclass implementation
314
+ // causes overridden variables to "inherit" default values from parent classes.
315
+ if (!dataClassEntry.hasDefault && oldEntry.hasDefault && oldEntry.includeInInit) {
316
+ dataClassEntry.hasDefault = true;
317
+ dataClassEntry.defaultValueExpression = oldEntry.defaultValueExpression;
318
+ hasDefaultValue = true;
318
319
  }
319
- // If we've already seen a entry with a default value defined,
320
- // all subsequent entries must also have default values.
321
- if (!isKeywordOnly && includeInInit && !skipSynthesizeInit && !hasDefaultValue) {
322
- const firstDefaultValueIndex = fullDataClassEntries.findIndex((p) => p.hasDefault && p.includeInInit && !p.isKeywordOnly);
323
- if (firstDefaultValueIndex >= 0 && firstDefaultValueIndex < insertIndex) {
324
- evaluator.addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.dataClassFieldWithDefault(), variableNameNode);
325
- }
320
+ fullDataClassEntries[insertIndex] = dataClassEntry;
321
+ }
322
+ else {
323
+ fullDataClassEntries.push(dataClassEntry);
324
+ insertIndex = fullDataClassEntries.length - 1;
325
+ }
326
+ // If we've already seen a entry with a default value defined,
327
+ // all subsequent entries must also have default values.
328
+ if (!isKeywordOnly && includeInInit && !skipSynthesizeInit && !hasDefaultValue) {
329
+ const firstDefaultValueIndex = fullDataClassEntries.findIndex((p) => p.hasDefault && p.includeInInit && !p.isKeywordOnly);
330
+ if (firstDefaultValueIndex >= 0 && firstDefaultValueIndex < insertIndex) {
331
+ evaluator.addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.dataClassFieldWithDefault(), variableNameNode);
326
332
  }
327
333
  }
328
334
  }
329
335
  }
330
- else {
331
- // The symbol had no declared type, so it is (mostly) ignored by dataclasses.
332
- // However, if it is assigned a field descriptor, it will result in a
333
- // runtime exception.
334
- const declarations = symbol.getDeclarations();
335
- if (declarations.length === 0) {
336
- return;
337
- }
338
- const lastDecl = declarations[declarations.length - 1];
339
- if (lastDecl.type !== 1 /* Variable */) {
340
- return;
341
- }
342
- const statement = lastDecl.node.parent;
343
- if (!statement || statement.nodeType !== 3 /* Assignment */) {
344
- return;
345
- }
346
- // If the RHS of the assignment is assigning a field instance where the
347
- // "init" parameter is set to false, do not include it in the init method.
348
- if (statement.rightExpression.nodeType === 9 /* Call */) {
349
- const callType = evaluator.getTypeOfExpression(statement.rightExpression.leftExpression, 16777218 /* CallBaseDefaults */).type;
350
- if (isDataclassFieldConstructor(callType, ((_c = classType.details.dataClassBehaviors) === null || _c === void 0 ? void 0 : _c.fieldDescriptorNames) || [])) {
351
- evaluator.addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.dataClassFieldWithoutAnnotation(), statement.rightExpression);
352
- }
336
+ }
337
+ else {
338
+ // The symbol had no declared type, so it is (mostly) ignored by dataclasses.
339
+ // However, if it is assigned a field descriptor, it will result in a
340
+ // runtime exception.
341
+ const declarations = symbol.getDeclarations();
342
+ if (declarations.length === 0) {
343
+ return;
344
+ }
345
+ const lastDecl = declarations[declarations.length - 1];
346
+ if (lastDecl.type !== 1 /* Variable */) {
347
+ return;
348
+ }
349
+ const statement = lastDecl.node.parent;
350
+ if (!statement || statement.nodeType !== 3 /* Assignment */) {
351
+ return;
352
+ }
353
+ // If the RHS of the assignment is assigning a field instance where the
354
+ // "init" parameter is set to false, do not include it in the init method.
355
+ if (statement.rightExpression.nodeType === 9 /* Call */) {
356
+ const callType = evaluator.getTypeOfExpression(statement.rightExpression.leftExpression, 16777218 /* CallBaseDefaults */).type;
357
+ if (isDataclassFieldConstructor(callType, ((_c = classType.details.dataClassBehaviors) === null || _c === void 0 ? void 0 : _c.fieldDescriptorNames) || [])) {
358
+ evaluator.addDiagnostic(AnalyzerNodeInfo.getFileInfo(node).diagnosticRuleSet.reportGeneralTypeIssues, diagnosticRules_1.DiagnosticRule.reportGeneralTypeIssues, localize_1.Localizer.Diagnostic.dataClassFieldWithoutAnnotation(), statement.rightExpression);
353
359
  }
354
360
  }
355
361
  }