public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { if (!TypeEvalStack.mayEvaluate(this)) { return null; } try { final boolean qualified = isQualified(); if (!qualified) { String name = getReferencedName(); if (PyNames.NONE.equals(name)) { return PyNoneType.INSTANCE; } } PyType type = getTypeFromProviders(context); if (type != null) { return type; } if (qualified) { PyType maybe_type = PyUtil.getSpecialAttributeType(this, context); if (maybe_type != null) return maybe_type; Ref<PyType> typeOfProperty = getTypeOfProperty(context); if (typeOfProperty != null) { return typeOfProperty.get(); } } final PsiPolyVariantReference reference = getReference(PyResolveContext.noImplicits().withTypeEvalContext(context)); final List<PsiElement> targets = PyUtil.multiResolveTopPriority(reference); if (targets.isEmpty()) { return getQualifiedReferenceTypeByControlFlow(context); } final List<PyType> members = new ArrayList<PyType>(); for (PsiElement target : targets) { if (target == this || target == null) { continue; } if (!target.isValid()) { LOG.error( "Reference " + this + " resolved to invalid element " + target + " (text=" + target.getText() + ")"); continue; } members.add(getTypeFromTarget(target, context, this)); } return PyUnionType.union(members); } finally { TypeEvalStack.evaluated(this); } }
public PsiElement setName(@NotNull String name) throws IncorrectOperationException { final ASTNode nameElement = PyUtil.createNewName(this, name); final ASTNode nameNode = getNameNode(); if (nameNode != null) { getNode().replaceChild(nameNode, nameElement); } return this; }
@Override public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { for (PyTypeProvider provider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) { final PyType type = provider.getCallableType(this, context); if (type != null) { return type; } } final boolean hasCustomDecorators = PyUtil.hasCustomDecorators(this) && !PyUtil.isDecoratedAsAbstract(this) && getProperty() == null; final PyFunctionType type = new PyFunctionType(this); if (hasCustomDecorators) { return PyUnionType.createWeakType(type); } return type; }
@NotNull @Override public ProtectionLevel getProtectionLevel() { final int underscoreLevels = PyUtil.getInitialUnderscores(getName()); for (final ProtectionLevel level : ProtectionLevel.values()) { if (level.getUnderscoreLevel() == underscoreLevels) { return level; } } return ProtectionLevel.PRIVATE; }
private void buildFromAttributeDoc() { PyClass cls = PsiTreeUtil.getParentOfType(myElement, PyClass.class); assert cls != null; String type = PyUtil.isInstanceAttribute((PyExpression) myElement) ? "Instance attribute " : "Class attribute "; myProlog .addItem(type) .addWith(TagBold, $().addWith(TagCode, $(((PyTargetExpression) myElement).getName()))) .addItem(" of class ") .addWith(PythonDocumentationProvider.LinkMyClass, $().addWith(TagCode, $(cls.getName()))) .addItem(BR); final String docString = ((PyTargetExpression) myElement).getDocStringValue(); if (docString != null) { addFormattedDocString(myElement, docString, myBody, myEpilog); } }
@Nullable @Override public PyType getCallType( @NotNull TypeEvalContext context, @NotNull PyCallSiteExpression callSite) { for (PyTypeProvider typeProvider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) { final PyType type = typeProvider.getCallType(this, callSite, context); if (type != null) { type.assertValid(typeProvider.toString()); return type; } } final PyExpression receiver = PyTypeChecker.getReceiver(callSite, this); final List<PyExpression> arguments = PyTypeChecker.getArguments(callSite, this); final List<PyParameter> parameters = PyUtil.getParameters(this, context); final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context); final List<PyParameter> explicitParameters = PyTypeChecker.filterExplicitParameters(parameters, this, callSite, resolveContext); final Map<PyExpression, PyNamedParameter> mapping = PyCallExpressionHelper.mapArguments(arguments, explicitParameters); return getCallType(receiver, mapping, context); }
private void buildFromParameter( @NotNull final TypeEvalContext context, @Nullable final PsiElement outerElement, @NotNull final PsiElement elementDefinition) { myBody.addItem(combUp("Parameter " + PyUtil.getReadableRepr(elementDefinition, false))); boolean typeFromDocstringAdded = addTypeAndDescriptionFromDocstring((PyNamedParameter) elementDefinition); if (outerElement instanceof PyExpression) { PyType type = context.getType((PyExpression) outerElement); if (type != null) { String typeString = null; if (type instanceof PyDynamicallyEvaluatedType) { if (!typeFromDocstringAdded) { typeString = "\nDynamically inferred type: "; } } else { if (outerElement.getReference() != null) { PsiElement target = outerElement.getReference().resolve(); if (target instanceof PyTargetExpression) { final String targetName = ((PyTargetExpression) target).getName(); if (targetName != null && targetName.equals(((PyNamedParameter) elementDefinition).getName())) { typeString = "\nReassigned value has type: "; } } } } if (typeString == null && !typeFromDocstringAdded) { typeString = "\nInferred type: "; } if (typeString != null) { myBody.addItem(combUp(typeString)); PythonDocumentationProvider.describeTypeWithLinks( myBody, elementDefinition, type, context); } } } }
@Nullable public static PyType getTypeFromTarget( @NotNull final PsiElement target, final TypeEvalContext context, PyReferenceExpression anchor) { if (!(target instanceof PyTargetExpression)) { // PyTargetExpression will ask about its type itself final PyType pyType = getReferenceTypeFromProviders(target, context, anchor); if (pyType != null) { return pyType; } } if (target instanceof PyTargetExpression) { final String name = ((PyTargetExpression) target).getName(); if (PyNames.NONE.equals(name)) { return PyNoneType.INSTANCE; } if (PyNames.TRUE.equals(name) || PyNames.FALSE.equals(name)) { return PyBuiltinCache.getInstance(target).getBoolType(); } } if (target instanceof PyFile) { return new PyModuleType((PyFile) target); } if (target instanceof PyImportedModule) { return new PyImportedModuleType((PyImportedModule) target); } if ((target instanceof PyTargetExpression || target instanceof PyNamedParameter) && anchor != null && context.allowDataFlow(anchor)) { final ScopeOwner scopeOwner = PsiTreeUtil.getStubOrPsiParentOfType(anchor, ScopeOwner.class); if (scopeOwner != null && scopeOwner == PsiTreeUtil.getStubOrPsiParentOfType(target, ScopeOwner.class)) { final String name = ((PyElement) target).getName(); if (name != null) { final PyType type = getTypeByControlFlow(name, context, anchor, scopeOwner); if (type != null) { return type; } } } } if (target instanceof PyFunction) { final PyDecoratorList decoratorList = ((PyFunction) target).getDecoratorList(); if (decoratorList != null) { final PyDecorator propertyDecorator = decoratorList.findDecorator(PyNames.PROPERTY); if (propertyDecorator != null) { return PyBuiltinCache.getInstance(target).getObjectType(PyNames.PROPERTY); } for (PyDecorator decorator : decoratorList.getDecorators()) { final QualifiedName qName = decorator.getQualifiedName(); if (qName != null && (qName.endsWith(PyNames.SETTER) || qName.endsWith(PyNames.DELETER) || qName.endsWith(PyNames.GETTER))) { return PyBuiltinCache.getInstance(target).getObjectType(PyNames.PROPERTY); } } } } if (target instanceof PyTypedElement) { return context.getType((PyTypedElement) target); } if (target instanceof PsiDirectory) { final PsiDirectory dir = (PsiDirectory) target; PsiFile file = dir.findFile(PyNames.INIT_DOT_PY); if (file != null) { return getTypeFromTarget(file, context, anchor); } if (PyUtil.isPackage(dir, anchor)) { final PsiFile containingFile = anchor.getContainingFile(); if (containingFile instanceof PyFile) { final QualifiedName qualifiedName = QualifiedNameFinder.findShortestImportableQName(dir); if (qualifiedName != null) { final PyImportedModule module = new PyImportedModule(null, (PyFile) containingFile, qualifiedName); return new PyImportedModuleType(module); } } } } return null; }
private boolean isAttribute() { return myElement instanceof PyTargetExpression && PyUtil.isAttribute((PyTargetExpression) myElement); }
private boolean buildFromProperty( PsiElement elementDefinition, @Nullable final PsiElement outerElement, @NotNull final TypeEvalContext context) { if (myOriginalElement == null) { return false; } final String elementName = myOriginalElement.getText(); if (!PyNames.isIdentifier(elementName)) { return false; } if (!(outerElement instanceof PyQualifiedExpression)) { return false; } final PyExpression qualifier = ((PyQualifiedExpression) outerElement).getQualifier(); if (qualifier == null) { return false; } final PyType type = context.getType(qualifier); if (!(type instanceof PyClassType)) { return false; } final PyClass cls = ((PyClassType) type).getPyClass(); final Property property = cls.findProperty(elementName, true, null); if (property == null) { return false; } final AccessDirection direction = AccessDirection.of((PyElement) outerElement); final Maybe<PyCallable> accessor = property.getByDirection(direction); myProlog .addItem("property ") .addWith(TagBold, $().addWith(TagCode, $(elementName))) .addItem(" of ") .add(PythonDocumentationProvider.describeClass(cls, TagCode, true, true)); if (accessor.isDefined() && property.getDoc() != null) { myBody.addItem(": ").addItem(property.getDoc()).addItem(BR); } else { final PyCallable getter = property.getGetter().valueOrNull(); if (getter != null && getter != myElement && getter instanceof PyFunction) { // not in getter, getter's doc comment may be useful final PyStringLiteralExpression docstring = ((PyFunction) getter).getDocStringExpression(); if (docstring != null) { myProlog .addItem(BR) .addWith(TagItalic, $("Copied from getter:")) .addItem(BR) .addItem(docstring.getStringValue()); } } myBody.addItem(BR); } myBody.addItem(BR); if (accessor.isDefined() && accessor.value() == null) elementDefinition = null; final String accessorKind = getAccessorKind(direction); if (elementDefinition != null) { myEpilog.addWith(TagSmall, $(BR, BR, accessorKind, " of property")).addItem(BR); } if (!(elementDefinition instanceof PyDocStringOwner)) { myBody .addWith( TagItalic, elementDefinition != null ? $("Declaration: ") : $(accessorKind + " is not defined.")) .addItem(BR); if (elementDefinition != null) { myBody.addItem(combUp(PyUtil.getReadableRepr(elementDefinition, false))); } } return true; }