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
 @Override
 public void doApply(
     @NotNull Editor editor,
     @NotNull PySmartEnterProcessor processor,
     @NotNull PyWithStatement withStatement)
     throws IncorrectOperationException {
   final PsiElement colonToken = PyUtil.getFirstChildOfType(withStatement, PyTokenTypes.COLON);
   final PsiElement withToken =
       PyUtil.getFirstChildOfType(withStatement, PyTokenTypes.WITH_KEYWORD);
   final Document document = editor.getDocument();
   if (colonToken == null && withToken != null) {
     int insertAt = withToken.getTextRange().getEndOffset();
     String textToInsert = ":";
     final PyWithItem lastItem = ArrayUtil.getLastElement(withStatement.getWithItems());
     if (lastItem == null || lastItem.getExpression() == null) {
       textToInsert = " :";
       processor.registerUnresolvedError(insertAt + 1);
     } else {
       final PyExpression expression = lastItem.getExpression();
       insertAt = expression.getTextRange().getEndOffset();
       final PsiElement asToken = PyUtil.getFirstChildOfType(lastItem, PyTokenTypes.AS_KEYWORD);
       if (asToken != null) {
         insertAt = asToken.getTextRange().getEndOffset();
         final PyExpression target = lastItem.getTarget();
         if (target != null) {
           insertAt = target.getTextRange().getEndOffset();
         } else {
           textToInsert = " :";
           processor.registerUnresolvedError(insertAt + 1);
         }
       }
     }
     document.insertString(insertAt, textToInsert);
   }
 }
  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);
    }
  }
 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()));
             }
           }
         }
       }
     }
   }
 }
    @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());
          }
        }
      }
    }
  @NotNull
  private static List<RatedResolveResult> resolveInDirectory(
      @NotNull final String referencedName,
      @Nullable final PsiFile containingFile,
      final PsiDirectory dir,
      boolean isFileOnly,
      boolean checkForPackage) {
    final PsiDirectory subdir = dir.findSubdirectory(referencedName);
    if (subdir != null && (!checkForPackage || PyUtil.isPackage(subdir, containingFile))) {
      return ResolveResultList.to(subdir);
    }

    final PsiFile module = findPyFileInDir(dir, referencedName);
    if (module != null) {
      return ResolveResultList.to(module);
    }

    if (!isFileOnly) {
      // not a subdir, not a file; could be a name in parent/__init__.py
      final PsiFile initPy = dir.findFile(PyNames.INIT_DOT_PY);
      if (initPy == containingFile) {
        return Collections.emptyList(); // don't dive into the file we're in
      }
      if (initPy instanceof PyFile) {
        return ((PyFile) initPy).multiResolveName(referencedName);
      }
    }
    return Collections.emptyList();
  }
 @NotNull
 private static List<RatedResolveResult> resolveInPackageDirectory(
     @Nullable PsiElement parent,
     @NotNull String referencedName,
     @Nullable PsiFile containingFile,
     boolean fileOnly,
     boolean checkForPackage) {
   final PsiElement parentDir = PyUtil.turnInitIntoDir(parent);
   if (parentDir instanceof PsiDirectory) {
     final List<RatedResolveResult> resolved =
         resolveInDirectory(
             referencedName, containingFile, (PsiDirectory) parentDir, fileOnly, checkForPackage);
     if (!resolved.isEmpty()) {
       for (RatedResolveResult result : resolved) {
         if (result.getRate() > RatedResolveResult.RATE_LOW) {
           return resolved;
         }
       }
     }
     if (parent instanceof PsiFile) {
       final PsiElement foreign = resolveForeignImports((PsiFile) parent, referencedName);
       if (foreign != null) {
         final ResolveResultList results = new ResolveResultList();
         results.addAll(resolved);
         results.poke(foreign, RatedResolveResult.RATE_NORMAL);
         return results;
       }
     }
     return resolved;
   }
   return Collections.emptyList();
 }
  @NotNull
  private static List<RatedResolveResult> resolveInPackageModule(
      @NotNull PyFile parent,
      @NotNull String referencedName,
      @Nullable PsiFile containingFile,
      boolean fileOnly,
      boolean checkForPackage) {
    final List<RatedResolveResult> moduleMembers = resolveModuleMember(parent, referencedName);
    final List<RatedResolveResult> resolvedInModule = Lists.newArrayList();
    final List<RatedResolveResult> results = Lists.newArrayList();
    for (RatedResolveResult member : moduleMembers) {
      final PsiElement moduleMember = member.getElement();
      if (!fileOnly || PyUtil.instanceOf(moduleMember, PsiFile.class, PsiDirectory.class)) {
        results.add(member);
        if (moduleMember != null && !preferResolveInDirectoryOverModule(moduleMember)) {
          resolvedInModule.add(member);
        }
      }
    }
    if (!resolvedInModule.isEmpty()) {
      return resolvedInModule;
    }

    final List<RatedResolveResult> resolvedInDirectory =
        resolveInPackageDirectory(
            parent, referencedName, containingFile, fileOnly, checkForPackage);
    if (!resolvedInDirectory.isEmpty()) {
      return resolvedInDirectory;
    }

    return results;
  }
 @Override
 protected void moveOffsetAfter(boolean success) {
   if (success && (myPanel != null && myPanel.getInitPlace() != InitPlace.SAME_METHOD)
       || myOperation.getInplaceInitPlace() != InitPlace.SAME_METHOD) {
     final AccessToken accessToken =
         ApplicationManager.getApplication().acquireWriteActionLock(getClass());
     try {
       final PyAssignmentStatement initializer =
           PsiTreeUtil.getParentOfType(myTarget, PyAssignmentStatement.class);
       assert initializer != null;
       final Function<String, PyStatement> callback =
           FunctionUtil.<String, PyStatement>constant(initializer);
       final PyClass pyClass = PyUtil.getContainingClassOrSelf(initializer);
       InitPlace initPlace =
           myPanel != null ? myPanel.getInitPlace() : myOperation.getInplaceInitPlace();
       if (initPlace == InitPlace.CONSTRUCTOR) {
         AddFieldQuickFix.addFieldToInit(myProject, pyClass, "", callback);
       } else if (initPlace == InitPlace.SET_UP) {
         addFieldToSetUp(pyClass, callback);
       }
       if (myOperation.getOccurrences().size() > 0) {
         initializer.delete();
       } else {
         final PyExpression copy =
             PyElementGenerator.getInstance(myProject)
                 .createExpressionFromText(
                     LanguageLevel.forElement(myTarget), myTarget.getText());
         initializer.replace(copy);
       }
       initializer.delete();
     } finally {
       accessToken.finish();
     }
   }
 }
예제 #10
0
 @Nullable
 private PyType getImplicitlyResolvedType(
     @NotNull List<Token<PyElementType>> tokens,
     @NotNull TypeEvalContext context,
     @NotNull Map<TextRange, PyType> types,
     @NotNull Map<PyType, TextRange> fullRanges,
     TextRange firstRange) {
   PyType type = null;
   QualifiedName qName = null;
   while (!tokens.isEmpty()) {
     final Token<PyElementType> token = tokens.get(0);
     final String name = token.getText().toString();
     qName = qName != null ? qName.append(name) : QualifiedName.fromComponents(name);
     PsiElement module =
         new QualifiedNameResolverImpl(qName).fromElement(myAnchor).firstResult();
     if (module == null) {
       break;
     }
     if (module instanceof PsiDirectory) {
       module = PyUtil.getPackageElement((PsiDirectory) module, myAnchor);
     }
     if (module instanceof PyTypedElement) {
       final PyType moduleType = context.getType((PyTypedElement) module);
       if (moduleType != null) {
         type = moduleType;
         types.put(token.getRange(), type);
         fullRanges.put(
             type,
             TextRange.create(firstRange.getStartOffset(), token.getRange().getEndOffset()));
       }
     }
     tokens.remove(0);
   }
   return type;
 }
예제 #11
0
 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
 protected PyAssignmentStatement createDeclaration(
     Project project, String assignmentText, PsiElement anchor) {
   final PyFunction container = PsiTreeUtil.getParentOfType(anchor, PyFunction.class);
   String selfName = PyUtil.getFirstParameterName(container);
   final LanguageLevel langLevel = LanguageLevel.forElement(anchor);
   return PyElementGenerator.getInstance(project)
       .createFromText(langLevel, PyAssignmentStatement.class, selfName + "." + assignmentText);
 }
예제 #13
0
 @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;
 }
 @Override
 public Icon getIcon(@NotNull PsiElement element, int flags) {
   if (element instanceof PsiDirectory) {
     final PsiDirectory directory = (PsiDirectory) element;
     if (PyUtil.isPackage(directory, null) && !isSpecialDirectory(directory)) {
       return PlatformIcons.PACKAGE_ICON;
     }
   }
   return null;
 }
 private static void highlightIncorrectArguments(
     ProblemsHolder holder, CallArgumentsMapping result, @NotNull TypeEvalContext context) {
   for (Map.Entry<PyExpression, EnumSet<CallArgumentsMapping.ArgFlag>> argEntry :
       result.getArgumentFlags().entrySet()) {
     EnumSet<CallArgumentsMapping.ArgFlag> flags = argEntry.getValue();
     if (!flags.isEmpty()) { // something's wrong
       PyExpression arg = argEntry.getKey();
       if (flags.contains(CallArgumentsMapping.ArgFlag.IS_DUP)) {
         holder.registerProblem(arg, PyBundle.message("INSP.duplicate.argument"));
       }
       if (flags.contains(CallArgumentsMapping.ArgFlag.IS_DUP_KWD)) {
         holder.registerProblem(arg, PyBundle.message("INSP.duplicate.doublestar.arg"));
       }
       if (flags.contains(CallArgumentsMapping.ArgFlag.IS_DUP_TUPLE)) {
         holder.registerProblem(arg, PyBundle.message("INSP.duplicate.star.arg"));
       }
       if (flags.contains(CallArgumentsMapping.ArgFlag.IS_POS_PAST_KWD)) {
         holder.registerProblem(
             arg,
             PyBundle.message("INSP.cannot.appear.past.keyword.arg"),
             ProblemHighlightType.ERROR);
       }
       if (flags.contains(CallArgumentsMapping.ArgFlag.IS_UNMAPPED)) {
         holder.registerProblem(arg, PyBundle.message("INSP.unexpected.arg"));
       }
       if (flags.contains(CallArgumentsMapping.ArgFlag.IS_TOO_LONG)) {
         final PyCallExpression.PyMarkedCallee markedCallee = result.getMarkedCallee();
         String parameterName = null;
         if (markedCallee != null) {
           final List<PyParameter> parameters =
               PyUtil.getParameters(markedCallee.getCallable(), context);
           for (int i = parameters.size() - 1; i >= 0; --i) {
             final PyParameter param = parameters.get(i);
             if (param instanceof PyNamedParameter) {
               final List<PyNamedParameter> unmappedParams = result.getUnmappedParams();
               if (!((PyNamedParameter) param).isPositionalContainer()
                   && !((PyNamedParameter) param).isKeywordContainer()
                   && param.getDefaultValue() == null
                   && !unmappedParams.contains(param)) {
                 parameterName = param.getName();
                 break;
               }
             }
           }
           holder.registerProblem(
               arg,
               parameterName != null
                   ? PyBundle.message(
                       "INSP.multiple.values.resolve.to.positional.$0", parameterName)
                   : PyBundle.message("INSP.more.args.that.pos.params"));
         }
       }
     }
   }
 }
 @Nullable
 @Override
 public List<? extends RatedResolveResult> resolveMember(
     @NotNull String name,
     @Nullable PyExpression location,
     @NotNull AccessDirection direction,
     @NotNull PyResolveContext resolveContext) {
   final PsiElement resolved = myImportedModule.resolve();
   if (resolved != null) {
     final PsiFile containingFile = location != null ? location.getContainingFile() : null;
     List<PsiElement> elements =
         Collections.singletonList(
             ResolveImportUtil.resolveChild(resolved, name, containingFile, false, true));
     final PyImportElement importElement = myImportedModule.getImportElement();
     final PyFile resolvedFile = PyUtil.as(resolved, PyFile.class);
     if (location != null
         && importElement != null
         && PyUtil.inSameFile(location, importElement)
         && ResolveImportUtil.getPointInImport(location) == PointInImport.NONE
         && resolved instanceof PsiFileSystemItem
         && (resolvedFile == null
             || !PyUtil.isPackage(resolvedFile)
             || resolvedFile.getElementNamed(name) == null)) {
       final List<PsiElement> importedSubmodules =
           PyModuleType.collectImportedSubmodules((PsiFileSystemItem) resolved, location);
       if (importedSubmodules != null) {
         final Set<PsiElement> imported = Sets.newHashSet(importedSubmodules);
         elements =
             ContainerUtil.filter(
                 elements,
                 new Condition<PsiElement>() {
                   @Override
                   public boolean value(PsiElement element) {
                     return imported.contains(element);
                   }
                 });
       }
     }
     return ResolveImportUtil.rateResults(elements);
   }
   return null;
 }
 private static boolean isAbstractMethodForClass(
     @NotNull PyFunction method, @NotNull PyClass cls) {
   final String methodName = method.getName();
   if (methodName == null
       || cls.findMethodByName(methodName, false) != null
       || cls.findClassAttribute(methodName, false) != null) {
     return false;
   }
   return PyUtil.isDecoratedAsAbstract(method)
       || PyOverrideImplementUtil.raisesNotImplementedError(method);
 }
 @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;
 }
예제 #19
0
  @Override
  public LanguageLevel getLanguageLevel() {
    VirtualFile virtualFile = getVirtualFile();

    if (virtualFile == null) {
      virtualFile = getUserData(IndexingDataKeys.VIRTUAL_FILE);
    }
    if (virtualFile == null) {
      virtualFile = getViewProvider().getVirtualFile();
    }
    return PyUtil.getLanguageLevelForVirtualFile(getProject(), virtualFile);
  }
  /**
   * @return if method could be made abstract? (that means "create abstract version if method in
   *     parent class")
   */
  private static boolean couldBeAbstract(@NotNull final PyFunction function) {
    if (PyUtil.isInit(function)) {
      return false; // Who wants to make __init__ abstract?!
    }
    final PyUtil.MethodFlags flags = PyUtil.MethodFlags.of(function);
    assert flags != null : "Function should be called on method!";

    final boolean py3K = LanguageLevel.forElement(function).isPy3K();

    // TODO: use strategy because we already has the same check in #addMetaAbcIfNeeded
    return flags.isInstanceMethod() || py3K; // Any method could be made abstract in py3
  }
 @Nullable
 private static Boolean isOverrides(final PyFunction pyFunction) {
   final PyClass clazz = PyUtil.getContainingClassOrSelf(pyFunction);
   assert clazz != null : "Refactoring called on function, not method: " + pyFunction;
   for (final PyClass parentClass : clazz.getSuperClasses()) {
     final PyFunction parentMethod = parentClass.findMethodByName(pyFunction.getName(), true);
     if (parentMethod != null) {
       return true;
     }
   }
   return null;
 }
 private static boolean inConstructor(@NotNull PsiElement expression) {
   final PsiElement expr = expression instanceof PyClass ? expression : expression.getParent();
   PyClass clazz = PyUtil.getContainingClassOrSelf(expr);
   final ScopeOwner current = ScopeUtil.getScopeOwner(expression);
   if (clazz != null && current != null && current instanceof PyFunction) {
     PyFunction init = clazz.findMethodByName(PyNames.INIT, false, null);
     if (current == init) {
       return true;
     }
   }
   return false;
 }
 @Override
 public void launch() {
   final String defaultFilePath =
       FileUtil.toSystemDependentName(
           myClassUnderRefactoring.getContainingFile().getVirtualFile().getPath());
   final VirtualFile[] roots =
       ProjectRootManager.getInstance(myClassUnderRefactoring.getProject()).getContentRoots();
   final Collection<PyMemberInfo<PyElement>> pyMemberInfos =
       PyUtil.filterOutObject(myStorage.getClassMemberInfos(myClassUnderRefactoring));
   myView.configure(
       new PyExtractSuperclassInitializationInfo(myModel, pyMemberInfos, defaultFilePath, roots));
   myView.initAndShow();
 }
 /**
  * Resolves a module reference in a general case.
  *
  * @param qualifiedName qualified name of the module reference to resolve
  * @param sourceFile where that reference resides; serves as PSI foothold to determine module,
  *     project, etc.
  * @param importIsAbsolute if false, try old python 2.x's "relative first, absolute next"
  *     approach.
  * @param relativeLevel if > 0, step back from sourceFile and resolve from there (even if
  *     importIsAbsolute is false!).
  * @return list of possible candidates
  */
 @NotNull
 public static List<PsiElement> resolveModule(
     @Nullable QualifiedName qualifiedName,
     @Nullable PsiFile sourceFile,
     boolean importIsAbsolute,
     int relativeLevel) {
   if (qualifiedName == null || sourceFile == null) {
     return Collections.emptyList();
   }
   final ResolveModuleParams params =
       new ResolveModuleParams(qualifiedName, sourceFile, importIsAbsolute, relativeLevel);
   return PyUtil.getParameterizedCachedValue(
       sourceFile, params, ResolveImportUtil::calculateResolveModule);
 }
 @NotNull
 private static List<PsiElement> tryResolving(
     @NotNull PyExpression expression, @NotNull TypeEvalContext context) {
   final List<PsiElement> elements = Lists.newArrayList();
   if (expression instanceof PyReferenceExpression) {
     final PyReferenceExpression referenceExpr = (PyReferenceExpression) expression;
     final PyResolveContext resolveContext =
         PyResolveContext.noImplicits().withTypeEvalContext(context);
     final PsiPolyVariantReference reference = referenceExpr.getReference(resolveContext);
     final List<PsiElement> resolved = PyUtil.multiResolveTopPriority(reference);
     for (PsiElement element : resolved) {
       if (element instanceof PyFunction) {
         final PyFunction function = (PyFunction) element;
         if (PyUtil.isInit(function)) {
           final PyClass cls = function.getContainingClass();
           if (cls != null) {
             elements.add(cls);
             continue;
           }
         }
       } else if (element instanceof PyTargetExpression) {
         final PyTargetExpression targetExpr = (PyTargetExpression) element;
         // XXX: Requires switching from stub to AST
         final PyExpression assignedValue = targetExpr.findAssignedValue();
         if (assignedValue != null) {
           elements.add(assignedValue);
           continue;
         }
       }
       if (element != null) {
         elements.add(element);
       }
     }
   }
   return !elements.isEmpty() ? elements : Collections.singletonList(expression);
 }
 @Nullable
 private static PyType getGenericConstructorType(
     @NotNull PyFunction function, @NotNull Context context) {
   if (PyUtil.isInit(function)) {
     final PyClass cls = function.getContainingClass();
     if (cls != null) {
       final List<PyGenericType> genericTypes = collectGenericTypes(cls, context);
       final List<PyType> elementTypes = new ArrayList<>(genericTypes);
       if (!elementTypes.isEmpty()) {
         return new PyCollectionTypeImpl(cls, false, elementTypes);
       }
     }
   }
   return null;
 }
 @Override
 protected boolean checkEnabled(IntroduceOperation operation) {
   if (PyUtil.getContainingClassOrSelf(operation.getElement()) == null) {
     CommonRefactoringUtil.showErrorHint(
         operation.getProject(),
         operation.getEditor(),
         "Cannot introduce field: not in class",
         myDialogTitle,
         getHelpId());
     return false;
   }
   if (dependsOnLocalScopeValues(operation.getElement())) {
     operation.removeAvailableInitPlace(InitPlace.CONSTRUCTOR);
     operation.removeAvailableInitPlace(InitPlace.SET_UP);
   }
   return true;
 }
 public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
   if (!(file instanceof PyFile)) {
     return false;
   }
   final PsiElement element =
       PyUtil.findNonWhitespaceAtOffset(file, editor.getCaretModel().getOffset());
   final PyFunction function = PsiTreeUtil.getParentOfType(element, PyFunction.class);
   if (function == null) return false;
   final PyClass containingClass = function.getContainingClass();
   if (containingClass == null) return false;
   final PyDecoratorList decoratorList = function.getDecoratorList();
   if (decoratorList != null) {
     final PyDecorator staticMethod = decoratorList.findDecorator(PyNames.STATICMETHOD);
     if (staticMethod != null) return true;
   }
   return false;
 }
  @Nullable
  @Override
  public PsiComment getTypeComment() {
    final PsiComment inlineComment = PyUtil.getCommentOnHeaderLine(this);
    if (inlineComment != null
        && PyTypingTypeProvider.getTypeCommentValue(inlineComment.getText()) != null) {
      return inlineComment;
    }

    final PyStatementList statements = getStatementList();
    if (statements.getStatements().length != 0) {
      final PsiComment comment = as(statements.getFirstChild(), PsiComment.class);
      if (comment != null && PyTypingTypeProvider.getTypeCommentValue(comment.getText()) != null) {
        return comment;
      }
    }
    return null;
  }
 @NotNull
 @Override
 public Collection<PsiReference> findReferencesToHighlight(
     @NotNull PsiElement target, @NotNull SearchScope searchScope) {
   if (target instanceof PyImportedModule) {
     target = ((PyImportedModule) target).resolve();
   }
   if (target instanceof PyFile && PyNames.INIT_DOT_PY.equals(((PyFile) target).getName())) {
     List<PsiReference> result = new ArrayList<PsiReference>();
     result.addAll(super.findReferencesToHighlight(target, searchScope));
     PsiElement targetDir = PyUtil.turnInitIntoDir(target);
     if (targetDir != null) {
       result.addAll(ReferencesSearch.search(targetDir, searchScope, false).findAll());
     }
     return result;
   }
   return super.findReferencesToHighlight(target, searchScope);
 }