コード例 #1
0
  /**
   * Looks for two standard decorators to a function, or a wrapping assignment that closely follows
   * it.
   *
   * @return a flag describing what was detected.
   */
  @Nullable
  public Modifier getModifier() {
    final String deconame = getClassOrStaticMethodDecorator();
    if (PyNames.CLASSMETHOD.equals(deconame)) {
      return CLASSMETHOD;
    } else if (PyNames.STATICMETHOD.equals(deconame)) {
      return STATICMETHOD;
    }
    // implicit staticmethod __new__
    final PyClass cls = getContainingClass();
    if (cls != null && PyNames.NEW.equals(getName()) && cls.isNewStyleClass(null)) {
      return STATICMETHOD;
    }
    //
    if (getStub() != null) {
      return getWrappersFromStub();
    }
    final String funcName = getName();
    if (funcName != null) {
      PyAssignmentStatement currentAssignment =
          PsiTreeUtil.getNextSiblingOfType(this, PyAssignmentStatement.class);
      while (currentAssignment != null) {
        final String modifier =
            currentAssignment
                .getTargetsToValuesMapping()
                .stream()
                .filter(
                    pair ->
                        pair.getFirst() instanceof PyTargetExpression
                            && funcName.equals(pair.getFirst().getName()))
                .filter(pair -> pair.getSecond() instanceof PyCallExpression)
                .map(
                    pair ->
                        interpretAsModifierWrappingCall((PyCallExpression) pair.getSecond(), this))
                .filter(interpreted -> interpreted != null && interpreted.getSecond() == this)
                .map(interpreted -> interpreted.getFirst())
                .filter(
                    wrapperName ->
                        PyNames.CLASSMETHOD.equals(wrapperName)
                            || PyNames.STATICMETHOD.equals(wrapperName))
                .findAny()
                .orElse(null);

        if (PyNames.CLASSMETHOD.equals(modifier)) {
          return CLASSMETHOD;
        } else if (PyNames.STATICMETHOD.equals(modifier)) {
          return STATICMETHOD;
        }

        currentAssignment =
            PsiTreeUtil.getNextSiblingOfType(currentAssignment, PyAssignmentStatement.class);
      }
    }
    return null;
  }
コード例 #2
0
 /**
  * Looks for two standard decorators to a function, or a wrapping assignment that closely follows
  * it.
  *
  * @return a flag describing what was detected.
  */
 @Nullable
 public Modifier getModifier() {
   String deconame = getClassOrStaticMethodDecorator();
   if (PyNames.CLASSMETHOD.equals(deconame)) {
     return CLASSMETHOD;
   } else if (PyNames.STATICMETHOD.equals(deconame)) {
     return STATICMETHOD;
   }
   // implicit staticmethod __new__
   PyClass cls = getContainingClass();
   if (cls != null && PyNames.NEW.equals(getName()) && cls.isNewStyleClass()) {
     return STATICMETHOD;
   }
   //
   if (getStub() != null) {
     return getWrappersFromStub();
   }
   String func_name = getName();
   if (func_name != null) {
     PyAssignmentStatement assignment =
         PsiTreeUtil.getNextSiblingOfType(this, PyAssignmentStatement.class);
     if (assignment != null) {
       for (Pair<PyExpression, PyExpression> pair : assignment.getTargetsToValuesMapping()) {
         PyExpression value = pair.getSecond();
         if (value instanceof PyCallExpression) {
           PyExpression target = pair.getFirst();
           if (target instanceof PyTargetExpression && func_name.equals(target.getName())) {
             Pair<String, PyFunction> interpreted =
                 interpretAsModifierWrappingCall((PyCallExpression) value, this);
             if (interpreted != null) {
               PyFunction original = interpreted.getSecond();
               if (original == this) {
                 String wrapper_name = interpreted.getFirst();
                 if (PyNames.CLASSMETHOD.equals(wrapper_name)) {
                   return CLASSMETHOD;
                 } else if (PyNames.STATICMETHOD.equals(wrapper_name)) {
                   return STATICMETHOD;
                 }
               }
             }
           }
         }
       }
     }
   }
   return null;
 }
コード例 #3
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;
 }