コード例 #1
0
  @Nullable
  @Override
  public PyType getReturnType(
      @NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
    final PyType type = getGenericReturnType(context, callSite);

    if (callSite == null) {
      return type;
    }
    final PyTypeChecker.AnalyzeCallResults results =
        PyTypeChecker.analyzeCallSite(callSite, context);

    if (PyTypeChecker.hasGenerics(type, context)) {
      if (results != null) {
        final Map<PyGenericType, PyType> substitutions =
            PyTypeChecker.unifyGenericCall(
                this, results.getReceiver(), results.getArguments(), context);
        if (substitutions != null) {
          return PyTypeChecker.substitute(type, substitutions, context);
        }
      }
      return null;
    }
    if (results != null && isDynamicallyEvaluated(results.getArguments().values(), context)) {
      return PyUnionType.createWeakType(type);
    } else {
      return type;
    }
  }
コード例 #2
0
 @Override
 public PyType getReferenceType(
     @NotNull PsiElement referenceTarget, TypeEvalContext context, @Nullable PsiElement anchor) {
   if (referenceTarget instanceof PyTargetExpression) {
     final PyTargetExpression target = (PyTargetExpression) referenceTarget;
     if (context.maySwitchToAST(target)) {
       // XXX: Requires switching from stub to AST
       final PyAnnotation annotation = target.getAnnotation();
       if (annotation != null) {
         final PyExpression value = annotation.getValue();
         if (value != null) {
           return getType(value, new Context(context));
         }
         return null;
       }
     }
     final String comment = target.getTypeCommentAnnotation();
     if (comment != null) {
       final PyType type = getStringBasedType(comment, referenceTarget, new Context(context));
       if (type instanceof PyTupleType) {
         final PyTupleExpression tupleExpr =
             PsiTreeUtil.getParentOfType(target, PyTupleExpression.class);
         if (tupleExpr != null) {
           return PyTypeChecker.getTargetTypeFromTupleAssignment(
               target, tupleExpr, (PyTupleType) type);
         }
       }
       return type;
     }
   }
   return null;
 }
コード例 #3
0
 @Nullable
 /** Suits when there is no call site(e.g. implicit __iter__ call in statement for) */
 public PyType getReturnTypeWithoutCallSite(
     @NotNull TypeEvalContext context, @Nullable PyExpression receiver) {
   final PyType type = getGenericReturnType(context, null);
   if (PyTypeChecker.hasGenerics(type, context)) {
     final Map<PyGenericType, PyType> substitutions =
         PyTypeChecker.unifyGenericCall(
             this, receiver, Maps.<PyExpression, PyNamedParameter>newHashMap(), context);
     if (substitutions != null) {
       return PyTypeChecker.substitute(type, substitutions, context);
     }
     return null;
   }
   return type;
 }
    @Override
    public void visitPyAssignmentStatement(PyAssignmentStatement node) {
      final PyExpression value = node.getAssignedValue();
      if (value instanceof PyCallExpression) {
        final PyType type = myTypeEvalContext.getType(value);
        final PyExpression callee = ((PyCallExpression) value).getCallee();

        if (type instanceof PyNoneType && callee != null) {
          final PyTypeChecker.AnalyzeCallResults analyzeCallResults =
              PyTypeChecker.analyzeCall(((PyCallExpression) value), myTypeEvalContext);
          if (analyzeCallResults != null) {
            final PyCallable callable = analyzeCallResults.getCallable();
            if (PySdkUtil.isElementInSkeletons(callable)) {
              return;
            }
            if (callable instanceof PyFunction) {
              final PyFunction function = (PyFunction) callable;
              // Currently we don't infer types returned by decorators
              if (hasInheritors(function) || PyUtil.hasCustomDecorators(function)) {
                return;
              }
            }
            registerProblem(
                node,
                PyBundle.message("INSP.none.function.assignment", callee.getName()),
                new PyRemoveAssignmentQuickFix());
          }
        }
      }
    }
コード例 #5
0
 private static void highlightStarArgumentTypeMismatch(
     PyArgumentList node, ProblemsHolder holder, TypeEvalContext context) {
   for (PyExpression arg : node.getArguments()) {
     if (arg instanceof PyStarArgument) {
       PyExpression content =
           PyUtil.peelArgument(PsiTreeUtil.findChildOfType(arg, PyExpression.class));
       if (content != null) {
         PyType inside_type = context.getType(content);
         if (inside_type != null && !PyTypeChecker.isUnknown(inside_type)) {
           if (((PyStarArgument) arg).isKeyword()) {
             if (!PyABCUtil.isSubtype(inside_type, PyNames.MAPPING)) {
               holder.registerProblem(
                   arg, PyBundle.message("INSP.expected.dict.got.$0", inside_type.getName()));
             }
           } else { // * arg
             if (!PyABCUtil.isSubtype(inside_type, PyNames.ITERABLE)) {
               holder.registerProblem(
                   arg, PyBundle.message("INSP.expected.iter.got.$0", inside_type.getName()));
             }
           }
         }
       }
     }
   }
 }
コード例 #6
0
 @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);
 }
コード例 #7
0
 @Nullable
 private PyType analyzeCallType(
     @Nullable PyType type,
     @Nullable PyExpression receiver,
     @NotNull Map<PyExpression, PyNamedParameter> parameters,
     @NotNull TypeEvalContext context) {
   if (PyTypeChecker.hasGenerics(type, context)) {
     final Map<PyGenericType, PyType> substitutions =
         PyTypeChecker.unifyGenericCall(receiver, parameters, context);
     if (substitutions != null) {
       type = PyTypeChecker.substitute(type, substitutions, context);
     } else {
       type = null;
     }
   }
   if (receiver != null) {
     type = replaceSelf(type, receiver, context);
   }
   if (type != null && isDynamicallyEvaluated(parameters.values(), context)) {
     type = PyUnionType.createWeakType(type);
   }
   return type;
 }
コード例 #8
0
 public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) {
   if (isOperator("and") || isOperator("or")) {
     final PyExpression left = getLeftExpression();
     final PyType leftType = left != null ? context.getType(left) : null;
     final PyExpression right = getRightExpression();
     final PyType rightType = right != null ? context.getType(right) : null;
     if (leftType == null && rightType == null) {
       return null;
     }
     return PyUnionType.union(leftType, rightType);
   }
   final PyTypeChecker.AnalyzeCallResults results = PyTypeChecker.analyzeCall(this, context);
   if (results != null) {
     final PyType type = results.getCallable().getCallType(context, this);
     if (!PyTypeChecker.isUnknown(type) && !(type instanceof PyNoneType)) {
       return type;
     }
   }
   if (PyNames.COMPARISON_OPERATORS.contains(getReferencedName())) {
     return PyBuiltinCache.getInstance(this).getBoolType();
   }
   return null;
 }
コード例 #9
0
  @Nullable
  @Override
  public PyType getCallType(
      @NotNull TypeEvalContext context, @NotNull PyCallSiteExpression callSite) {
    for (PyTypeProvider typeProvider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) {
      final Ref<PyType> typeRef = typeProvider.getCallType(this, callSite, context);
      if (typeRef != null) {
        return derefType(typeRef, typeProvider);
      }
    }

    final PyExpression receiver = PyTypeChecker.getReceiver(callSite, this);
    final Map<PyExpression, PyNamedParameter> mapping =
        PyCallExpressionHelper.mapArguments(callSite, this, context);
    return getCallType(receiver, mapping, context);
  }
コード例 #10
0
 @Nullable
 @Override
 public PyType getCallType(
     @NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
   PyType type = null;
   for (PyTypeProvider typeProvider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) {
     type = typeProvider.getCallType(this, callSite, context);
     if (type != null) {
       type.assertValid(typeProvider.toString());
       break;
     }
   }
   if (type == null) {
     type = context.getReturnType(this);
   }
   final PyTypeChecker.AnalyzeCallResults results =
       PyTypeChecker.analyzeCallSite(callSite, context);
   if (results != null) {
     return analyzeCallType(type, results.getReceiver(), results.getArguments(), context);
   }
   return type;
 }
コード例 #11
0
 @Nullable
 private PyType replaceSelf(
     @Nullable PyType returnType,
     @Nullable PyExpression receiver,
     @NotNull TypeEvalContext context) {
   if (receiver != null) {
     // TODO: Currently we substitute only simple subclass types, but we could handle union and
     // collection types as well
     if (returnType instanceof PyClassType) {
       final PyClassType returnClassType = (PyClassType) returnType;
       if (returnClassType.getPyClass() == getContainingClass()) {
         final PyType receiverType = context.getType(receiver);
         if (receiverType instanceof PyClassType
             && PyTypeChecker.match(returnType, receiverType, context)) {
           return returnClassType.isDefinition()
               ? receiverType
               : ((PyClassType) receiverType).toInstance();
         }
       }
     }
   }
   return returnType;
 }