mirror of
https://github.com/microsoft/pyright.git
synced 2024-10-05 12:27:30 +03:00
Fixed a few bugs in generics processing.
This commit is contained in:
parent
4f270b62d7
commit
9f3b20bfc1
@ -1300,7 +1300,9 @@ export class TypeAnalyzer extends ParseTreeWalker {
|
||||
node.entries.forEach(expr => {
|
||||
this._getTypeOfExpression(expr);
|
||||
});
|
||||
exprType = TypeAnnotation.getBuiltInObject(this._currentScope, 'list');
|
||||
// TODO - infer list type
|
||||
exprType = TypeAnnotation.getBuiltInObject(
|
||||
this._currentScope, 'list', []);
|
||||
} else if (node instanceof SliceExpressionNode) {
|
||||
// TODO - need to implement
|
||||
if (node.startValue) {
|
||||
@ -1312,7 +1314,9 @@ export class TypeAnalyzer extends ParseTreeWalker {
|
||||
if (node.stepValue) {
|
||||
this._getTypeOfExpression(node.stepValue);
|
||||
}
|
||||
exprType = TypeAnnotation.getBuiltInObject(this._currentScope, 'set');
|
||||
// TODO - infer set type
|
||||
exprType = TypeAnnotation.getBuiltInObject(
|
||||
this._currentScope, 'set', []);
|
||||
} else if (node instanceof AwaitExpressionNode) {
|
||||
// TODO - need to implement
|
||||
exprType = this._getTypeOfExpression(node.expression);
|
||||
@ -1323,18 +1327,23 @@ export class TypeAnalyzer extends ParseTreeWalker {
|
||||
let rightType = this._getTypeOfExpression(node.elseExpression);
|
||||
exprType = TypeUtils.combineTypes(leftType, rightType);
|
||||
} else if (node instanceof ListComprehensionNode) {
|
||||
// TODO - need to implement
|
||||
// TODO - infer list type
|
||||
this._getTypeOfExpression(node.baseExpression);
|
||||
exprType = TypeAnnotation.getBuiltInObject(this._currentScope, 'list');
|
||||
exprType = TypeAnnotation.getBuiltInObject(
|
||||
this._currentScope, 'list', []);
|
||||
} else if (node instanceof DictionaryNode) {
|
||||
exprType = TypeAnnotation.getBuiltInObject(this._currentScope, 'dict');
|
||||
// TODO - infer dict type
|
||||
exprType = TypeAnnotation.getBuiltInObject(
|
||||
this._currentScope, 'dict', []);
|
||||
} else if (node instanceof LambdaNode) {
|
||||
exprType = AnalyzerNodeInfo.getExpressionType(node);
|
||||
} else if (node instanceof SetNode) {
|
||||
node.entries.forEach(expr => {
|
||||
this._getTypeOfExpression(expr);
|
||||
});
|
||||
exprType = TypeAnnotation.getBuiltInObject(this._currentScope, 'set');
|
||||
// TODO - infer set type
|
||||
exprType = TypeAnnotation.getBuiltInObject(
|
||||
this._currentScope, 'set', []);
|
||||
} else if (node instanceof AssignmentNode) {
|
||||
this._getTypeOfExpression(node.rightExpression);
|
||||
exprType = this._getTypeOfExpression(node.leftExpression);
|
||||
|
@ -157,16 +157,19 @@ export class TypeAnnotation {
|
||||
initType.setDeclaredReturnType(NoneType.create());
|
||||
initType.addParameter(selfParameter);
|
||||
|
||||
let addGenericGetAttribute = false;
|
||||
|
||||
if (node.arguments.length < 2) {
|
||||
diagSink.addErrorWithTextRange('Expected named tuple entry list as second parameter',
|
||||
node.leftExpression);
|
||||
addGenericGetAttribute = true;
|
||||
} else {
|
||||
const entriesArg = node.arguments[1];
|
||||
if (entriesArg.argumentCategory !== ArgumentCategory.Simple ||
|
||||
!(entriesArg.valueExpression instanceof ListNode)) {
|
||||
diagSink.addErrorWithTextRange(
|
||||
'Expected named tuple entry list as second parameter',
|
||||
entriesArg.valueExpression);
|
||||
// A dynamic expression was used, so we can't evaluate
|
||||
// the named tuple statically.
|
||||
addGenericGetAttribute = true;
|
||||
} else {
|
||||
const entryList = entriesArg.valueExpression;
|
||||
let entryMap: { [name: string]: string } = {};
|
||||
@ -237,7 +240,8 @@ export class TypeAnnotation {
|
||||
classFields.set('__init__', new Symbol(initType, DefaultTypeSourceId));
|
||||
|
||||
let keysItemType = new FunctionType(FunctionTypeFlags.None);
|
||||
keysItemType.setDeclaredReturnType(this.getBuiltInObject(currentScope, 'list'));
|
||||
keysItemType.setDeclaredReturnType(this.getBuiltInObject(currentScope, 'list',
|
||||
[this.getBuiltInObject(currentScope, 'str')]));
|
||||
classFields.set('keys', new Symbol(keysItemType, DefaultTypeSourceId));
|
||||
classFields.set('items', new Symbol(keysItemType, DefaultTypeSourceId));
|
||||
|
||||
@ -246,6 +250,18 @@ export class TypeAnnotation {
|
||||
lenType.addParameter(selfParameter);
|
||||
classFields.set('__len__', new Symbol(lenType, DefaultTypeSourceId));
|
||||
|
||||
if (addGenericGetAttribute) {
|
||||
let getAttribType = new FunctionType(FunctionTypeFlags.InstanceMethod);
|
||||
getAttribType.setDeclaredReturnType(AnyType.create());
|
||||
getAttribType.addParameter(selfParameter);
|
||||
getAttribType.addParameter({
|
||||
category: ParameterCategory.Simple,
|
||||
name: 'name',
|
||||
type: this.getBuiltInObject(currentScope, 'str')
|
||||
});
|
||||
classFields.set('__getattribute__', new Symbol(getAttribType, DefaultTypeSourceId));
|
||||
}
|
||||
|
||||
return classType;
|
||||
}
|
||||
|
||||
@ -265,10 +281,17 @@ export class TypeAnnotation {
|
||||
return UnknownType.create();
|
||||
}
|
||||
|
||||
static getBuiltInObject(currentScope: Scope, className: string): Type {
|
||||
static getBuiltInObject(currentScope: Scope, className: string,
|
||||
typeArguments?: Type[]): Type {
|
||||
|
||||
let nameType = this.getBuiltInType(currentScope, className);
|
||||
if (nameType instanceof ClassType) {
|
||||
return new ObjectType(nameType);
|
||||
let classType = nameType;
|
||||
if (typeArguments) {
|
||||
classType = classType.cloneForSpecialization();
|
||||
classType.setTypeArguments(typeArguments);
|
||||
}
|
||||
return new ObjectType(classType);
|
||||
}
|
||||
|
||||
return nameType;
|
||||
@ -590,8 +613,15 @@ export class TypeAnnotation {
|
||||
}
|
||||
|
||||
if (!type) {
|
||||
type = this._createSpecializedClassType(baseTypeResult.type,
|
||||
typeArgs, diagSink);
|
||||
if (baseTypeResult.type === this.getBuiltInType(currentScope, 'type')) {
|
||||
// The built-in 'type' class isn't defined as a generic class. It needs
|
||||
// to be special-cased here.
|
||||
type = this._createTypeType(node, typeArgs, diagSink);
|
||||
isClassType = true;
|
||||
} else {
|
||||
type = this._createSpecializedClassType(baseTypeResult.type,
|
||||
typeArgs, diagSink);
|
||||
}
|
||||
}
|
||||
} else if (!baseTypeResult.type.isAny()) {
|
||||
diagSink.addErrorWithTextRange(
|
||||
|
Loading…
Reference in New Issue
Block a user