private static LookupElementBuilder createOverridingLookupElement(
      boolean implemented,
      final PsiMethod baseMethod,
      PsiClass baseClass,
      PsiSubstitutor substitutor) {

    RowIcon icon =
        new RowIcon(
            baseMethod.getIcon(0),
            implemented ? AllIcons.Gutter.ImplementingMethod : AllIcons.Gutter.OverridingMethod);
    return createGenerateMethodElement(
        baseMethod,
        substitutor,
        icon,
        baseClass.getName(),
        new InsertHandler<LookupElement>() {
          @Override
          public void handleInsert(InsertionContext context, LookupElement item) {
            removeLookupString(context);

            final PsiClass parent =
                PsiTreeUtil.findElementOfClassAtOffset(
                    context.getFile(), context.getStartOffset(), PsiClass.class, false);
            if (parent == null) return;

            List<PsiMethod> prototypes =
                OverrideImplementUtil.overrideOrImplementMethod(parent, baseMethod, false);
            insertGenerationInfos(
                context, OverrideImplementUtil.convert2GenerationInfos(prototypes));
          }
        });
  }
    private void reportMissingOnClickProblem(
        OnClickConverter.MyReference reference,
        PsiClass activity,
        String methodName,
        boolean incorrectSignature) {
      String activityName = activity.getName();

      if (activityName == null) {
        activityName = "";
      }
      final String message =
          incorrectSignature
              ? AndroidBundle.message(
                  "android.inspections.on.click.missing.incorrect.signature",
                  methodName,
                  activityName)
              : AndroidBundle.message(
                  "android.inspections.on.click.missing.problem", methodName, activityName);

      final LocalQuickFix[] fixes =
          StringUtil.isJavaIdentifier(methodName)
              ? new LocalQuickFix[] {new MyQuickFix(methodName, reference.getConverter(), activity)}
              : LocalQuickFix.EMPTY_ARRAY;

      myResult.add(
          myInspectionManager.createProblemDescriptor(
              reference.getElement(),
              reference.getRangeInElement(),
              message,
              ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
              myOnTheFly,
              fixes));
    }
 private static void addDefaultConstructor(
     JavaChangeInfo changeInfo, PsiClass aClass, final UsageInfo[] usages)
     throws IncorrectOperationException {
   if (!(aClass instanceof PsiAnonymousClass)) {
     PsiElementFactory factory = JavaPsiFacade.getElementFactory(aClass.getProject());
     PsiMethod defaultConstructor =
         factory.createMethodFromText(aClass.getName() + "(){}", aClass);
     defaultConstructor =
         (PsiMethod)
             CodeStyleManager.getInstance(aClass.getProject()).reformat(defaultConstructor);
     defaultConstructor = (PsiMethod) aClass.add(defaultConstructor);
     PsiUtil.setModifierProperty(
         defaultConstructor, VisibilityUtil.getVisibilityModifier(aClass.getModifierList()), true);
     addSuperCall(changeInfo, defaultConstructor, null, usages);
   } else {
     final PsiElement parent = aClass.getParent();
     if (parent instanceof PsiNewExpression) {
       final PsiExpressionList argumentList = ((PsiNewExpression) parent).getArgumentList();
       final PsiClass baseClass = changeInfo.getMethod().getContainingClass();
       final PsiSubstitutor substitutor =
           TypeConversionUtil.getSuperClassSubstitutor(baseClass, aClass, PsiSubstitutor.EMPTY);
       fixActualArgumentsList(argumentList, changeInfo, true, substitutor);
     }
   }
 }
 private static boolean isAvailable(PsiField field) {
   PsiClass containingClass = field == null ? null : field.getContainingClass();
   return field != null
       && field.getManager().isInProject(field)
       && !field.hasModifierProperty(PsiModifier.STATIC)
       && containingClass != null
       && !(containingClass instanceof PsiSyntheticClass)
       && containingClass.getName() != null;
 }
  public static boolean isClassEquivalentTo(@NotNull PsiClass aClass, PsiElement another) {
    if (aClass == another) return true;
    if (!(another instanceof PsiClass)) return false;
    String name1 = aClass.getName();
    if (name1 == null) return false;
    if (!another.isValid()) return false;
    String name2 = ((PsiClass) another).getName();
    if (name2 == null) return false;
    if (name1.hashCode() != name2.hashCode()) return false;
    if (!name1.equals(name2)) return false;
    String qName1 = aClass.getQualifiedName();
    String qName2 = ((PsiClass) another).getQualifiedName();
    if (qName1 == null || qName2 == null) {
      //noinspection StringEquality
      if (qName1 != qName2) return false;

      if (aClass instanceof PsiTypeParameter && another instanceof PsiTypeParameter) {
        PsiTypeParameter p1 = (PsiTypeParameter) aClass;
        PsiTypeParameter p2 = (PsiTypeParameter) another;

        return p1.getIndex() == p2.getIndex()
            && aClass.getManager().areElementsEquivalent(p1.getOwner(), p2.getOwner());
      } else {
        return false;
      }
    }
    if (qName1.hashCode() != qName2.hashCode() || !qName1.equals(qName2)) {
      return false;
    }

    if (originalElement(aClass).equals(originalElement((PsiClass) another))) {
      return true;
    }

    final PsiFile file1 = aClass.getContainingFile().getOriginalFile();
    final PsiFile file2 = another.getContainingFile().getOriginalFile();

    // see com.intellij.openapi.vcs.changes.PsiChangeTracker
    // see com.intellij.psi.impl.PsiFileFactoryImpl#createFileFromText(CharSequence,PsiFile)
    final PsiFile original1 = file1.getUserData(PsiFileFactory.ORIGINAL_FILE);
    final PsiFile original2 = file2.getUserData(PsiFileFactory.ORIGINAL_FILE);
    if (original1 == original2 && original1 != null
        || original1 == file2
        || original2 == file1
        || file1 == file2) {
      return compareClassSeqNumber(aClass, (PsiClass) another);
    }

    final FileIndexFacade fileIndex =
        ServiceManager.getService(file1.getProject(), FileIndexFacade.class);
    final VirtualFile vfile1 = file1.getViewProvider().getVirtualFile();
    final VirtualFile vfile2 = file2.getViewProvider().getVirtualFile();
    boolean lib1 = fileIndex.isInLibraryClasses(vfile1);
    boolean lib2 = fileIndex.isInLibraryClasses(vfile2);

    return (fileIndex.isInSource(vfile1) || lib1) && (fileIndex.isInSource(vfile2) || lib2);
  }
예제 #6
0
 static boolean isKotlinNamespaceClass(PsiClass psiClass) {
   if (JvmAbi.PACKAGE_CLASS.equals(psiClass.getName()) && !isKotlinClass(psiClass)) {
     for (PsiMethod method : psiClass.getMethods()) {
       if (hasAnnotation(method, JET_METHOD)) {
         return true;
       }
     }
   }
   return false;
 }
예제 #7
0
  public static PsiMethod generateSetterPrototype(
      PsiField field, final PsiClass containingClass, boolean returnSelf) {
    Project project = field.getProject();
    JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
    PsiElementFactory factory = JavaPsiFacade.getInstance(field.getProject()).getElementFactory();

    String name = field.getName();
    boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
    VariableKind kind = codeStyleManager.getVariableKind(field);
    String propertyName = codeStyleManager.variableNameToPropertyName(name, kind);
    String setName = suggestSetterName(project, field);
    try {
      PsiMethod setMethod =
          factory.createMethod(
              setName, returnSelf ? factory.createType(containingClass) : PsiType.VOID);
      String parameterName =
          codeStyleManager.propertyNameToVariableName(propertyName, VariableKind.PARAMETER);
      PsiParameter param = factory.createParameter(parameterName, field.getType());

      annotateWithNullableStuff(field, factory, param);

      setMethod.getParameterList().add(param);
      PsiUtil.setModifierProperty(setMethod, PsiModifier.PUBLIC, true);
      PsiUtil.setModifierProperty(setMethod, PsiModifier.STATIC, isStatic);

      @NonNls StringBuffer buffer = new StringBuffer();
      buffer.append("{\n");
      if (name.equals(parameterName)) {
        if (!isStatic) {
          buffer.append("this.");
        } else {
          String className = containingClass.getName();
          if (className != null) {
            buffer.append(className);
            buffer.append(".");
          }
        }
      }
      buffer.append(name);
      buffer.append("=");
      buffer.append(parameterName);
      buffer.append(";\n");
      if (returnSelf) {
        buffer.append("return this;\n");
      }
      buffer.append("}");
      PsiCodeBlock body = factory.createCodeBlockFromText(buffer.toString(), null);
      setMethod.getBody().replace(body);
      setMethod = (PsiMethod) CodeStyleManager.getInstance(project).reformat(setMethod);
      return setMethod;
    } catch (IncorrectOperationException e) {
      LOG.error(e);
      return null;
    }
  }
 @Nullable
 private static PsiClass findByName(PsiClass[] classes, String name) {
   if (name != null) {
     for (PsiClass aClass : classes) {
       if (name.equals(aClass.getName())) {
         return aClass;
       }
     }
   }
   return null;
 }
 @NotNull
 @Override
 public String getName() {
   return "Create '"
       + myMethodName
       + "("
       + myConverter.getShortParameterName()
       + ")' in '"
       + myClass.getName()
       + "'";
 }
예제 #10
0
 private static boolean containsConflictingClassName(String fqName, PsiJavaFile file) {
   final int lastDotIndex = fqName.lastIndexOf((int) '.');
   final String shortName = fqName.substring(lastDotIndex + 1);
   final PsiClass[] classes = file.getClasses();
   for (PsiClass aClass : classes) {
     if (shortName.equals(aClass.getName())) {
       return true;
     }
   }
   return false;
 }
예제 #11
0
 private static boolean processClasses(
     @NotNull PsiScopeProcessor processor,
     @NotNull ResolveState state,
     @NotNull PsiClass[] classes,
     @NotNull Condition<String> nameCondition) {
   for (PsiClass aClass : classes) {
     String name = aClass.getName();
     if (name != null && nameCondition.value(name) && !processor.execute(aClass, state))
       return false;
   }
   return true;
 }
예제 #12
0
 /**
  * ImportUtils currently checks all inner classes, even those that are contained in inner classes
  * themselves, because it doesn't know the location of the original fully qualified reference. It
  * should really only check if the containing class of the fully qualified reference has any
  * conflicting inner classes.
  */
 private static boolean containsConflictingInnerClass(String fqName, PsiClass aClass) {
   final String shortName = ClassUtil.extractClassName(fqName);
   if (shortName.equals(aClass.getName()) && !fqName.equals(aClass.getQualifiedName())) {
     return true;
   }
   final PsiClass[] classes = aClass.getInnerClasses();
   for (PsiClass innerClass : classes) {
     if (containsConflictingInnerClass(fqName, innerClass)) {
       return true;
     }
   }
   return false;
 }
 private static int getSeqNumber(@NotNull PsiClass aClass) {
   // sequence number of this class among its parent' child classes named the same
   PsiElement parent = aClass.getParent();
   if (parent == null) return -1;
   int seqNo = 0;
   for (PsiElement child : parent.getChildren()) {
     if (child == aClass) return seqNo;
     if (child instanceof PsiClass
         && Comparing.strEqual(aClass.getName(), ((PsiClass) child).getName())) {
       seqNo++;
     }
   }
   return -1;
 }
예제 #14
0
 public static boolean nameCanBeImported(@NotNull String fqName, @NotNull PsiElement context) {
   final PsiClass containingClass = PsiTreeUtil.getParentOfType(context, PsiClass.class);
   if (containingClass != null) {
     if (fqName.equals(containingClass.getQualifiedName())) {
       return true;
     }
     final String shortName = ClassUtil.extractClassName(fqName);
     final PsiClass[] innerClasses = containingClass.getAllInnerClasses();
     for (PsiClass innerClass : innerClasses) {
       if (innerClass.hasModifierProperty(PsiModifier.PRIVATE)) {
         continue;
       }
       if (innerClass.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) {
         if (!ClassUtils.inSamePackage(innerClass, containingClass)) {
           continue;
         }
       }
       final String className = innerClass.getName();
       if (shortName.equals(className)) {
         return false;
       }
     }
     PsiField field = containingClass.findFieldByName(shortName, false);
     if (field != null) {
       return false;
     }
     field = containingClass.findFieldByName(shortName, true);
     if (field != null
         && PsiUtil.isAccessible(containingClass.getProject(), field, containingClass, null)) {
       return false;
     }
   }
   final PsiJavaFile file = PsiTreeUtil.getParentOfType(context, PsiJavaFile.class);
   if (file == null) {
     return false;
   }
   if (hasExactImportConflict(fqName, file)) {
     return false;
   }
   if (hasOnDemandImportConflict(fqName, file, true)) {
     return false;
   }
   if (containsConflictingReference(file, fqName)) {
     return false;
   }
   if (containsConflictingClass(fqName, file)) {
     return false;
   }
   return !containsConflictingClassName(fqName, file);
 }
  private static boolean compareParamTypes(
      @NotNull PsiManager manager, @NotNull PsiType type1, @NotNull PsiType type2) {
    if (type1 instanceof PsiArrayType) {
      return type2 instanceof PsiArrayType
          && compareParamTypes(
              manager,
              ((PsiArrayType) type1).getComponentType(),
              ((PsiArrayType) type2).getComponentType());
    }

    if (!(type1 instanceof PsiClassType) || !(type2 instanceof PsiClassType)) {
      return type1.equals(type2);
    }

    PsiClass class1 = ((PsiClassType) type1).resolve();
    PsiClass class2 = ((PsiClassType) type2).resolve();

    if (class1 instanceof PsiTypeParameter && class2 instanceof PsiTypeParameter) {
      return Comparing.equal(class1.getName(), class2.getName())
          && ((PsiTypeParameter) class1).getIndex() == ((PsiTypeParameter) class2).getIndex();
    }

    return manager.areElementsEquivalent(class1, class2);
  }
 @Nullable
 public static PsiClass findInnerClassByName(
     GrTypeDefinition grType, String name, boolean checkBases) {
   if (!checkBases) {
     for (PsiClass inner : grType.getInnerClasses()) {
       if (name.equals(inner.getName())) return inner;
     }
     return null;
   } else {
     Map<String, CandidateInfo> innerClasses =
         CollectClassMembersUtil.getAllInnerClasses(grType, true);
     final CandidateInfo info = innerClasses.get(name);
     return info == null ? null : (PsiClass) info.getElement();
   }
 }
예제 #17
0
 @Nullable
 private static Object createSubclassLookupValue(
     @NotNull final PsiPackage context, @NotNull final PsiClass clazz) {
   String name = clazz.getQualifiedName();
   if (name == null) return null;
   final String pack = context.getQualifiedName();
   if (pack.length() > 0) {
     if (name.startsWith(pack)) {
       name = name.substring(pack.length() + 1);
     } else {
       return null;
     }
   }
   final LookupItem<PsiClass> lookup =
       LookupElementFactoryImpl.getInstance().createLookupElement(clazz, name);
   lookup.addLookupStrings(clazz.getName());
   return JavaCompletionUtil.setShowFQN(lookup).setTailType(TailType.NONE);
 }
예제 #18
0
 private PsiClass[] getCachedClassInDumbMode(String name) {
   Map<String, PsiClass[]> map = SoftReference.dereference(myClassCache);
   if (map == null) {
     map = new HashMap<String, PsiClass[]>();
     for (PsiClass psiClass : getClasses(new EverythingGlobalScope(getProject()))) {
       String psiClassName = psiClass.getName();
       if (psiClassName != null) {
         PsiClass[] existing = map.get(psiClassName);
         map.put(
             psiClassName,
             existing == null ? new PsiClass[] {psiClass} : ArrayUtil.append(existing, psiClass));
       }
     }
     myClassCache = new SoftReference<Map<String, PsiClass[]>>(map);
   }
   PsiClass[] classes = map.get(name);
   return classes == null ? PsiClass.EMPTY_ARRAY : classes;
 }
 public static Set<String> getAllLookupStrings(@NotNull PsiMember member) {
   Set<String> allLookupStrings = ContainerUtil.newLinkedHashSet();
   String name = member.getName();
   allLookupStrings.add(name);
   PsiClass containingClass = member.getContainingClass();
   while (containingClass != null) {
     final String className = containingClass.getName();
     if (className == null) {
       break;
     }
     name = className + "." + name;
     allLookupStrings.add(name);
     final PsiElement parent = containingClass.getParent();
     if (!(parent instanceof PsiClass)) {
       break;
     }
     containingClass = (PsiClass) parent;
   }
   return allLookupStrings;
 }
예제 #20
0
    @Override
    public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
      if (referenceFound) {
        return;
      }
      super.visitReferenceElement(reference);

      if (reference.getQualifier() != null) return;

      final PsiElement element = reference.resolve();
      if (!(element instanceof PsiClass) || element instanceof PsiTypeParameter) {
        return;
      }
      final PsiClass aClass = (PsiClass) element;
      final String testClassName = aClass.getName();
      final String testClassQualifiedName = aClass.getQualifiedName();
      if (testClassQualifiedName == null
          || testClassName == null
          || testClassQualifiedName.equals(fullyQualifiedName)
          || !testClassName.equals(name)) {
        return;
      }
      referenceFound = true;
    }
  @Nullable
  public static PsiElement doCopyClasses(
      final Map<PsiFile, PsiClass[]> fileToClasses,
      @Nullable HashMap<PsiFile, String> map,
      final String copyClassName,
      final PsiDirectory targetDirectory,
      final Project project)
      throws IncorrectOperationException {
    PsiElement newElement = null;
    final Map<PsiClass, PsiElement> oldToNewMap = new HashMap<PsiClass, PsiElement>();
    for (final PsiClass[] psiClasses : fileToClasses.values()) {
      if (psiClasses != null) {
        for (PsiClass aClass : psiClasses) {
          if (aClass instanceof SyntheticElement) {
            continue;
          }
          oldToNewMap.put(aClass, null);
        }
      }
    }
    final List<PsiFile> createdFiles = new ArrayList<PsiFile>(fileToClasses.size());
    int[] choice = fileToClasses.size() > 1 ? new int[] {-1} : null;
    List<PsiFile> files = new ArrayList<PsiFile>();
    for (final Map.Entry<PsiFile, PsiClass[]> entry : fileToClasses.entrySet()) {
      final PsiFile psiFile = entry.getKey();
      final PsiClass[] sources = entry.getValue();
      if (psiFile instanceof PsiClassOwner && sources != null) {
        final PsiFile createdFile =
            copy(
                psiFile,
                targetDirectory,
                copyClassName,
                map == null ? null : map.get(psiFile),
                choice);
        if (createdFile == null) return null;
        for (final PsiClass destination : ((PsiClassOwner) createdFile).getClasses()) {
          if (destination instanceof SyntheticElement) {
            continue;
          }
          PsiClass source = findByName(sources, destination.getName());
          if (source != null) {
            final PsiClass copy = copy(source, copyClassName);
            newElement = destination.replace(copy);
            oldToNewMap.put(source, newElement);
          } else {
            destination.delete();
          }
        }
        createdFiles.add(createdFile);
      } else {
        files.add(psiFile);
      }
    }

    for (PsiFile file : files) {
      try {
        PsiDirectory finalTarget = targetDirectory;
        final String relativePath = map != null ? map.get(file) : null;
        if (relativePath != null && !relativePath.isEmpty()) {
          finalTarget =
              buildRelativeDir(targetDirectory, relativePath).findOrCreateTargetDirectory();
        }
        final PsiFile fileCopy =
            CopyFilesOrDirectoriesHandler.copyToDirectory(
                file, getNewFileName(file, copyClassName), finalTarget, choice);
        if (fileCopy != null) {
          createdFiles.add(fileCopy);
        }
      } catch (IOException e) {
        throw new IncorrectOperationException(e.getMessage());
      }
    }

    final Set<PsiElement> rebindExpressions = new HashSet<PsiElement>();
    for (PsiElement element : oldToNewMap.values()) {
      if (element == null) {
        LOG.error(oldToNewMap.keySet());
        continue;
      }
      decodeRefs(element, oldToNewMap, rebindExpressions);
    }

    final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
    for (PsiFile psiFile : createdFiles) {
      if (psiFile instanceof PsiJavaFile) {
        codeStyleManager.removeRedundantImports((PsiJavaFile) psiFile);
      }
    }
    for (PsiElement expression : rebindExpressions) {
      codeStyleManager.shortenClassReferences(expression);
    }
    new OptimizeImportsProcessor(
            project, createdFiles.toArray(new PsiFile[createdFiles.size()]), null)
        .run();
    return newElement != null ? newElement : createdFiles.size() > 0 ? createdFiles.get(0) : null;
  }
  public static boolean processDeclarations(
      @NotNull GrTypeDefinition grType,
      @NotNull PsiScopeProcessor processor,
      @NotNull ResolveState state,
      @Nullable PsiElement lastParent,
      @NotNull PsiElement place) {
    if (place instanceof GrCodeReferenceElement && lastParent instanceof GrModifierList) {
      final PsiElement possibleAnnotation =
          PsiTreeUtil.skipParentsOfType(place, GrCodeReferenceElement.class);
      if (possibleAnnotation instanceof GrAnnotation
          && possibleAnnotation.getParent() == lastParent) {
        return true; // don't process class members while resolving annotation which annotates
                     // current class
      }
    }

    for (final PsiTypeParameter typeParameter : grType.getTypeParameters()) {
      if (!processElement(processor, typeParameter, state)) return false;
    }

    NameHint nameHint = processor.getHint(NameHint.KEY);
    String name = nameHint == null ? null : nameHint.getName(state);
    ClassHint classHint = processor.getHint(ClassHint.KEY);
    final PsiSubstitutor substitutor = state.get(PsiSubstitutor.KEY);
    final PsiElementFactory factory = JavaPsiFacade.getElementFactory(place.getProject());

    boolean processInstanceMethods =
        (shouldProcessMethods(classHint) || shouldProcessProperties(classHint))
            && shouldProcessInstanceMembers(grType, lastParent);

    LanguageLevel level = PsiUtil.getLanguageLevel(place);
    if (shouldProcessProperties(classHint)) {
      Map<String, CandidateInfo> fieldsMap = CollectClassMembersUtil.getAllFields(grType);
      if (name != null) {
        CandidateInfo fieldInfo = fieldsMap.get(name);
        if (fieldInfo != null) {
          if (!processField(
              grType,
              processor,
              state,
              place,
              processInstanceMethods,
              substitutor,
              factory,
              level,
              fieldInfo)) {
            return false;
          }
        } else if (grType.isTrait() && lastParent != null) {
          PsiField field = findFieldByName(grType, name, false, true);
          if (field != null && field.hasModifierProperty(PsiModifier.PUBLIC)) {
            if (!processField(
                grType,
                processor,
                state,
                place,
                processInstanceMethods,
                substitutor,
                factory,
                level,
                new CandidateInfo(field, PsiSubstitutor.EMPTY))) {
              return false;
            }
          }
        }
      } else {
        for (CandidateInfo info : fieldsMap.values()) {
          if (!processField(
              grType,
              processor,
              state,
              place,
              processInstanceMethods,
              substitutor,
              factory,
              level,
              info)) {
            return false;
          }
        }
        if (grType.isTrait() && lastParent != null) {
          for (PsiField field : CollectClassMembersUtil.getFields(grType, true)) {
            if (field.hasModifierProperty(PsiModifier.PUBLIC)) {
              if (!processField(
                  grType,
                  processor,
                  state,
                  place,
                  processInstanceMethods,
                  substitutor,
                  factory,
                  level,
                  new CandidateInfo(field, PsiSubstitutor.EMPTY))) {
                return false;
              }
            }
          }
        }
      }
    }

    if (shouldProcessMethods(classHint)) {
      Map<String, List<CandidateInfo>> methodsMap =
          CollectClassMembersUtil.getAllMethods(grType, true);
      boolean isPlaceGroovy = place.getLanguage() == GroovyFileType.GROOVY_LANGUAGE;
      if (name == null) {
        for (List<CandidateInfo> list : methodsMap.values()) {
          for (CandidateInfo info : list) {
            if (!processMethod(
                grType,
                processor,
                state,
                place,
                processInstanceMethods,
                substitutor,
                factory,
                level,
                isPlaceGroovy,
                info)) {
              return false;
            }
          }
        }
      } else {
        List<CandidateInfo> byName = methodsMap.get(name);
        if (byName != null) {
          for (CandidateInfo info : byName) {
            if (!processMethod(
                grType,
                processor,
                state,
                place,
                processInstanceMethods,
                substitutor,
                factory,
                level,
                isPlaceGroovy,
                info)) {
              return false;
            }
          }
        }
      }
    }

    final GrTypeDefinitionBody body = grType.getBody();
    if (body != null) {
      if (shouldProcessClasses(classHint)) {
        for (PsiClass innerClass : getInnerClassesForResolve(grType, lastParent, place)) {
          final String innerClassName = innerClass.getName();
          if (nameHint != null && !innerClassName.equals(nameHint.getName(state))) {
            continue;
          }

          if (!processor.execute(innerClass, state)) {
            return false;
          }
        }
      }
    }

    return true;
  }
예제 #23
0
  @NotNull
  public Class classToClass(@NotNull PsiClass psiClass) {
    Set<String> modifiers = modifiersListToModifiersSet(psiClass.getModifierList());
    List<Field> fields = fieldsToFieldList(psiClass.getFields(), psiClass);
    List<Element> typeParameters = elementsToElementList(psiClass.getTypeParameters());
    List<Type> implementsTypes = typesToNotNullableTypeList(psiClass.getImplementsListTypes());
    List<Type> extendsTypes = typesToNotNullableTypeList(psiClass.getExtendsListTypes());
    IdentifierImpl name = new IdentifierImpl(psiClass.getName());
    List<Expression> baseClassParams = new LinkedList<Expression>();

    List<Member> members = getMembers(psiClass);

    // we try to find super() call and generate class declaration like that: class A(name: String, i
    // : Int) : Base(name)
    SuperVisitor visitor = new SuperVisitor();
    psiClass.accept(visitor);
    Collection<PsiExpressionList> resolvedSuperCallParameters =
        visitor.getResolvedSuperCallParameters();
    if (resolvedSuperCallParameters.size() == 1) {
      baseClassParams.addAll(
          expressionsToExpressionList(
              resolvedSuperCallParameters.toArray(new PsiExpressionList[1])[0].getExpressions()));
    }

    // we create primary constructor from all non final fields and fields without initializers
    if (!psiClass.isEnum()
        && !psiClass.isInterface()
        && psiClass.getConstructors().length > 1
        && getPrimaryConstructorForThisCase(psiClass) == null) {
      List<Field> finalOrWithEmptyInitializer = getFinalOrWithEmptyInitializer(fields);
      Map<String, String> initializers = new HashMap<String, String>();

      for (Member m : members) {
        // and modify secondaries
        if (m.getKind() == INode.Kind.CONSTRUCTOR) {
          Function f = (Function) m;
          if (!((Constructor) f).isPrimary()) {
            for (Field fo : finalOrWithEmptyInitializer) {
              String init = getDefaultInitializer(fo);
              initializers.put(fo.getIdentifier().toKotlin(), init);
            }

            List<Statement> newStatements = new LinkedList<Statement>();

            for (Statement s : f.getBlock().getStatements()) {
              boolean isRemoved = false;

              if (s.getKind() == INode.Kind.ASSIGNMENT_EXPRESSION) {
                AssignmentExpression assignmentExpression = (AssignmentExpression) s;
                if (assignmentExpression.getLeft().getKind() == INode.Kind.CALL_CHAIN) {
                  for (Field fo : finalOrWithEmptyInitializer) {
                    String id = fo.getIdentifier().toKotlin();
                    if (((CallChainExpression) assignmentExpression.getLeft())
                        .getIdentifier()
                        .toKotlin()
                        .endsWith("." + id)) {
                      initializers.put(id, assignmentExpression.getRight().toKotlin());
                      isRemoved = true;
                    }
                  }
                }
              }
              if (!isRemoved) {
                newStatements.add(s);
              }
            }

            newStatements.add(
                0,
                new DummyStringExpression(
                    "val __ = "
                        + createPrimaryConstructorInvocation(
                            name.toKotlin(), finalOrWithEmptyInitializer, initializers)));

            f.setBlock(new Block(newStatements));
          }
        }
      }

      members.add(
          new Constructor(
              Identifier.EMPTY_IDENTIFIER,
              Collections.<String>emptySet(),
              new ClassType(name),
              Collections.<Element>emptyList(),
              new ParameterList(createParametersFromFields(finalOrWithEmptyInitializer)),
              new Block(createInitStatementsFromFields(finalOrWithEmptyInitializer)),
              true));
    }

    if (psiClass.isInterface()) {
      return new Trait(
          this,
          name,
          modifiers,
          typeParameters,
          extendsTypes,
          Collections.<Expression>emptyList(),
          implementsTypes,
          members);
    }
    if (psiClass.isEnum()) {
      return new Enum(
          this,
          name,
          modifiers,
          typeParameters,
          Collections.<Type>emptyList(),
          Collections.<Expression>emptyList(),
          implementsTypes,
          members);
    }
    return new Class(
        this,
        name,
        modifiers,
        typeParameters,
        extendsTypes,
        baseClassParams,
        implementsTypes,
        members);
  }
  private void correctMethodCall(
      final PsiMethodCallExpression expression, final boolean isInternalCall) {
    try {
      final PsiManager manager = myMethod.getManager();
      PsiReferenceExpression methodExpression = expression.getMethodExpression();
      if (!methodExpression.isReferenceTo(myMethod)) return;
      final PsiExpression oldQualifier = methodExpression.getQualifierExpression();
      PsiExpression newQualifier = null;
      final PsiClass classReferencedByThis =
          MoveInstanceMembersUtil.getClassReferencedByThis(methodExpression);
      if (myTargetVariable instanceof PsiParameter) {
        final int index =
            myMethod.getParameterList().getParameterIndex((PsiParameter) myTargetVariable);
        final PsiExpression[] arguments = expression.getArgumentList().getExpressions();
        if (index < arguments.length) {
          newQualifier = (PsiExpression) arguments[index].copy();
          arguments[index].delete();
        }
      } else {
        VisibilityUtil.escalateVisibility((PsiField) myTargetVariable, expression);
        String newQualifierName = myTargetVariable.getName();
        if (myTargetVariable instanceof PsiField && oldQualifier != null) {
          final PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(oldQualifier.getType());
          if (aClass == ((PsiField) myTargetVariable).getContainingClass()) {
            newQualifierName = oldQualifier.getText() + "." + newQualifierName;
          }
        }
        newQualifier =
            JavaPsiFacade.getInstance(manager.getProject())
                .getElementFactory()
                .createExpressionFromText(newQualifierName, null);
      }

      PsiExpression newArgument = null;

      if (classReferencedByThis != null) {
        @NonNls String thisArgumentText = null;
        if (manager.areElementsEquivalent(myMethod.getContainingClass(), classReferencedByThis)) {
          if (myOldClassParameterNames.containsKey(myMethod.getContainingClass())) {
            thisArgumentText = "this";
          }
        } else {
          thisArgumentText = classReferencedByThis.getName() + ".this";
        }

        if (thisArgumentText != null) {
          newArgument =
              JavaPsiFacade.getInstance(manager.getProject())
                  .getElementFactory()
                  .createExpressionFromText(thisArgumentText, null);
        }
      } else {
        if (!isInternalCall && oldQualifier != null) {
          final PsiType type = oldQualifier.getType();
          if (type instanceof PsiClassType) {
            final PsiClass resolved = ((PsiClassType) type).resolve();
            if (resolved != null && getParameterNameToCreate(resolved) != null) {
              newArgument =
                  replaceRefsToTargetVariable(
                      oldQualifier); // replace is needed in case old qualifier is e.g. the same as
                                     // field as target variable
            }
          }
        }
      }

      if (newArgument != null) {
        expression.getArgumentList().add(newArgument);
      }

      if (newQualifier != null) {
        if (newQualifier instanceof PsiThisExpression
            && ((PsiThisExpression) newQualifier).getQualifier() == null) {
          // Remove now redundant 'this' qualifier
          if (oldQualifier != null) oldQualifier.delete();
        } else {
          final PsiReferenceExpression refExpr =
              (PsiReferenceExpression)
                  JavaPsiFacade.getInstance(manager.getProject())
                      .getElementFactory()
                      .createExpressionFromText("q." + myMethod.getName(), null);
          refExpr.getQualifierExpression().replace(newQualifier);
          methodExpression.replace(refExpr);
        }
      }
    } catch (IncorrectOperationException e) {
      LOG.error(e);
    }
  }
  protected void performRefactoring(@NotNull UsageInfo[] usageInfos) {
    final PsiClass psiClass = buildClass();
    if (psiClass == null) return;
    if (delegationRequired) {
      buildDelegate();
    }
    myExtractEnumProcessor.performEnumConstantTypeMigration(usageInfos);
    final Set<PsiMember> members = new HashSet<PsiMember>();
    for (PsiMethod method : methods) {
      final PsiMethod member = psiClass.findMethodBySignature(method, false);
      if (member != null) {
        members.add(member);
      }
    }
    for (PsiField field : fields) {
      final PsiField member = psiClass.findFieldByName(field.getName(), false);
      if (member != null) {
        members.add(member);
        final PsiExpression initializer = member.getInitializer();
        if (initializer != null) {
          final boolean[] moveInitializerToConstructor = new boolean[1];
          initializer.accept(
              new JavaRecursiveElementWalkingVisitor() {
                @Override
                public void visitReferenceExpression(PsiReferenceExpression expression) {
                  super.visitReferenceExpression(expression);
                  final PsiElement resolved = expression.resolve();
                  if (resolved instanceof PsiField && !members.contains(resolved)) {
                    moveInitializerToConstructor[0] = true;
                  }
                }
              });

          if (moveInitializerToConstructor[0]) {
            final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
            PsiMethod[] constructors = psiClass.getConstructors();
            if (constructors.length == 0) {
              final PsiMethod constructor =
                  (PsiMethod) elementFactory.createConstructor().setName(psiClass.getName());
              constructors = new PsiMethod[] {(PsiMethod) psiClass.add(constructor)};
            }
            for (PsiMethod constructor : constructors) {
              MoveInstanceMembersUtil.moveInitializerToConstructor(
                  elementFactory, constructor, member);
            }
          }
        }
      }
    }

    if (myGenerateAccessors) {
      final NecessaryAccessorsVisitor visitor = checkNecessaryGettersSetters4SourceClass();
      for (PsiField field : visitor.getFieldsNeedingGetter()) {
        sourceClass.add(GenerateMembersUtil.generateGetterPrototype(field));
      }

      for (PsiField field : visitor.getFieldsNeedingSetter()) {
        sourceClass.add(GenerateMembersUtil.generateSetterPrototype(field));
      }
    }
    super.performRefactoring(usageInfos);
    if (myNewVisibility == null) return;
    for (PsiMember member : members) {
      VisibilityUtil.fixVisibility(UsageViewUtil.toElements(usageInfos), member, myNewVisibility);
    }
  }
  public static int insertClassReference(
      PsiClass psiClass, PsiFile file, int startOffset, int endOffset) {
    final Project project = file.getProject();
    PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
    documentManager.commitAllDocuments();

    final PsiManager manager = file.getManager();

    final Document document =
        FileDocumentManager.getInstance().getDocument(file.getViewProvider().getVirtualFile());

    final PsiReference reference = file.findReferenceAt(startOffset);
    if (reference != null) {
      final PsiElement resolved = reference.resolve();
      if (resolved instanceof PsiClass) {
        if (((PsiClass) resolved).getQualifiedName() == null
            || manager.areElementsEquivalent(psiClass, resolved)) {
          return endOffset;
        }
      }
    }

    String name = psiClass.getName();
    if (name == null) {
      return endOffset;
    }

    assert document != null;
    document.replaceString(startOffset, endOffset, name);

    int newEndOffset = startOffset + name.length();
    final RangeMarker toDelete = insertTemporary(newEndOffset, document, " ");

    documentManager.commitAllDocuments();

    PsiElement element = file.findElementAt(startOffset);
    if (element instanceof PsiIdentifier) {
      PsiElement parent = element.getParent();
      if (parent instanceof PsiJavaCodeReferenceElement
          && !((PsiJavaCodeReferenceElement) parent).isQualified()
          && !(parent.getParent() instanceof PsiPackageStatement)) {
        PsiJavaCodeReferenceElement ref = (PsiJavaCodeReferenceElement) parent;

        if (psiClass.isValid()
            && !psiClass.getManager().areElementsEquivalent(psiClass, resolveReference(ref))) {
          final boolean staticImport = ref instanceof PsiImportStaticReferenceElement;
          PsiElement newElement;
          try {
            newElement =
                staticImport
                    ? ((PsiImportStaticReferenceElement) ref).bindToTargetClass(psiClass)
                    : ref.bindToElement(psiClass);
          } catch (IncorrectOperationException e) {
            return endOffset; // can happen if fqn contains reserved words, for example
          }

          final RangeMarker rangeMarker = document.createRangeMarker(newElement.getTextRange());
          documentManager.doPostponedOperationsAndUnblockDocument(document);
          documentManager.commitDocument(document);

          newElement =
              CodeInsightUtilCore.findElementInRange(
                  file,
                  rangeMarker.getStartOffset(),
                  rangeMarker.getEndOffset(),
                  PsiJavaCodeReferenceElement.class,
                  JavaLanguage.INSTANCE);
          rangeMarker.dispose();
          if (newElement != null) {
            newEndOffset = newElement.getTextRange().getEndOffset();
            if (!(newElement instanceof PsiReferenceExpression)) {
              PsiReferenceParameterList parameterList =
                  ((PsiJavaCodeReferenceElement) newElement).getParameterList();
              if (parameterList != null) {
                newEndOffset = parameterList.getTextRange().getStartOffset();
              }
            }

            if (!staticImport
                && !psiClass
                    .getManager()
                    .areElementsEquivalent(psiClass, resolveReference((PsiReference) newElement))
                && !PsiUtil.isInnerClass(psiClass)) {
              final String qName = psiClass.getQualifiedName();
              if (qName != null) {
                document.replaceString(
                    newElement.getTextRange().getStartOffset(), newEndOffset, qName);
                newEndOffset = newElement.getTextRange().getStartOffset() + qName.length();
              }
            }
          }
        }
      }
    }

    if (toDelete.isValid()) {
      document.deleteString(toDelete.getStartOffset(), toDelete.getEndOffset());
    }

    return newEndOffset;
  }