public void doInvoke(@NotNull Project project, Editor editor, PsiFile file)
      throws IncorrectOperationException {
    final PsiElement element =
        PyUtil.findNonWhitespaceAtOffset(file, editor.getCaretModel().getOffset());
    PyFunction problemFunction = PsiTreeUtil.getParentOfType(element, PyFunction.class);
    if (problemFunction == null) return;
    final PyClass containingClass = problemFunction.getContainingClass();
    if (containingClass == null) return;
    final List<UsageInfo> usages = PyRefactoringUtil.findUsages(problemFunction, false);
    final PyDecoratorList decoratorList = problemFunction.getDecoratorList();
    if (decoratorList != null) {
      final PyDecorator decorator = decoratorList.findDecorator(PyNames.STATICMETHOD);
      if (decorator != null) decorator.delete();
    }

    final PsiElement copy = problemFunction.copy();
    problemFunction.delete();
    file.addAfter(copy, containingClass);

    for (UsageInfo usage : usages) {
      final PsiElement usageElement = usage.getElement();
      if (usageElement instanceof PyReferenceExpression) {
        PyUtil.removeQualifier((PyReferenceExpression) usageElement);
      }
    }
  }
コード例 #2
0
 protected boolean isValidIntroduceContext(PsiElement element) {
   PyDecorator decorator = PsiTreeUtil.getParentOfType(element, PyDecorator.class);
   if (decorator != null && PsiTreeUtil.isAncestor(decorator.getCallee(), element, false)) {
     return false;
   }
   return PsiTreeUtil.getParentOfType(element, PyParameterList.class) == null;
 }
コード例 #3
0
 @Override
 public void visitPyDecoratorList(final PyDecoratorList node) {
   PyDecorator[] decorators = node.getDecorators();
   for (PyDecorator deco : decorators) {
     if (deco.hasArgumentList()) continue;
     final PyCallExpression.PyMarkedCallee markedCallee =
         deco.resolveCallee(resolveWithoutImplicits());
     if (markedCallee != null && !markedCallee.isImplicitlyResolved()) {
       final Callable callable = markedCallee.getCallable();
       int firstParamOffset = markedCallee.getImplicitOffset();
       final List<PyParameter> params = PyUtil.getParameters(callable, myTypeEvalContext);
       final PyNamedParameter allegedFirstParam =
           params.size() < firstParamOffset
               ? null
               : params.get(firstParamOffset - 1).getAsNamed();
       if (allegedFirstParam == null || allegedFirstParam.isKeywordContainer()) {
         // no parameters left to pass function implicitly, or wrong param type
         registerProblem(
             deco,
             PyBundle.message(
                 "INSP.func.$0.lacks.first.arg",
                 callable.getName())); // TODO: better names for anon lambdas
       } else { // possible unfilled params
         for (int i = firstParamOffset; i < params.size(); i += 1) {
           final PyParameter parameter = params.get(i);
           if (parameter instanceof PySingleStarParameter) continue;
           final PyNamedParameter par = parameter.getAsNamed();
           // param tuples, non-starred or non-default won't do
           if (par == null
               || (!par.isKeywordContainer()
                   && !par.isPositionalContainer()
                   && !par.hasDefaultValue())) {
             String parameterName = par != null ? par.getName() : "(...)";
             registerProblem(
                 deco, PyBundle.message("INSP.parameter.$0.unfilled", parameterName));
           }
         }
       }
     }
     // else: this case is handled by arglist visitor
   }
 }
コード例 #4
0
 /**
  * When a function is decorated many decorators, finds the deepest builtin decorator:
  *
  * <pre>
  * &#x40;foo
  * &#x40;classmethod <b># &lt;-- that's it</b>
  * &#x40;bar
  * def moo(cls):
  * &nbsp;&nbsp;pass
  * </pre>
  *
  * @return name of the built-in decorator, or null (even if there are non-built-in decorators).
  */
 @Nullable
 private String getClassOrStaticMethodDecorator() {
   PyDecoratorList decolist = getDecoratorList();
   if (decolist != null) {
     PyDecorator[] decos = decolist.getDecorators();
     if (decos.length > 0) {
       for (int i = decos.length - 1; i >= 0; i -= 1) {
         PyDecorator deco = decos[i];
         String deconame = deco.getName();
         if (PyNames.CLASSMETHOD.equals(deconame) || PyNames.STATICMETHOD.equals(deconame)) {
           return deconame;
         }
         for (PyKnownDecoratorProvider provider :
             PyUtil.KnownDecoratorProviderHolder.KNOWN_DECORATOR_PROVIDERS) {
           String name = provider.toKnownDecorator(deconame);
           if (name != null) {
             return name;
           }
         }
       }
     }
   }
   return null;
 }
コード例 #5
0
 @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;
 }