public void invoke(@NotNull Project project, Editor editor, PsiFile file)
      throws IncorrectOperationException {
    Set<String> classes = new LinkedHashSet<String>();
    Set<String> interfaces = new LinkedHashSet<String>();
    Set<String> unknownClasses = new LinkedHashSet<String>();
    Set<String> unknownInterfaces = new LinkedHashSet<String>();

    if (myExtendsClause != null) {
      collectRefs(
          myExtendsClause.getReferenceElementsGroovy(),
          classes,
          interfaces,
          myClass.isInterface() ? unknownInterfaces : unknownClasses);
      myExtendsClause.delete();
    }

    if (myImplementsClause != null) {
      collectRefs(
          myImplementsClause.getReferenceElementsGroovy(), classes, interfaces, unknownInterfaces);
      myImplementsClause.delete();
    }

    if (myClass.isInterface()) {
      interfaces.addAll(classes);
      unknownInterfaces.addAll(unknownClasses);
      addNewClause(interfaces, unknownInterfaces, project, true);
    } else {
      addNewClause(classes, unknownClasses, project, true);
      addNewClause(interfaces, unknownInterfaces, project, false);
    }
  }
Ejemplo n.º 2
0
 private void getVariantsFromQualifierType(
     @NotNull PsiType qualifierType, @NotNull Project project) {
   final ResolveState state = ResolveState.initial();
   if (qualifierType instanceof PsiClassType) {
     PsiClassType.ClassResolveResult result = ((PsiClassType) qualifierType).resolveGenerics();
     PsiClass qualifierClass = result.getElement();
     if (qualifierClass != null) {
       qualifierClass.processDeclarations(
           myProcessor, state.put(PsiSubstitutor.KEY, result.getSubstitutor()), null, myRefExpr);
     }
   } else if (qualifierType instanceof PsiArrayType) {
     final GrTypeDefinition arrayClass =
         GroovyPsiManager.getInstance(project)
             .getArrayClass(((PsiArrayType) qualifierType).getComponentType());
     if (arrayClass != null) {
       if (!arrayClass.processDeclarations(myProcessor, state, null, myRefExpr)) return;
     }
   } else if (qualifierType instanceof PsiIntersectionType) {
     for (PsiType conjunct : ((PsiIntersectionType) qualifierType).getConjuncts()) {
       getVariantsFromQualifierType(conjunct, project);
     }
     return;
   }
   ResolveUtil.processNonCodeMembers(qualifierType, myProcessor, myRefExpr, state);
 }
  private void addNewClause(
      Collection<String> elements,
      Collection<String> additional,
      Project project,
      boolean isExtends)
      throws IncorrectOperationException {
    if (elements.isEmpty() && additional.isEmpty()) return;

    StringBuilder classText = new StringBuilder();
    classText.append("class A ");
    classText.append(isExtends ? "extends " : "implements ");

    for (String str : elements) {
      classText.append(str);
      classText.append(", ");
    }

    for (String str : additional) {
      classText.append(str);
      classText.append(", ");
    }

    classText.delete(classText.length() - 2, classText.length());

    classText.append(" {}");

    final GrTypeDefinition definition =
        GroovyPsiElementFactory.getInstance(project).createTypeDefinition(classText.toString());
    GroovyPsiElement clause =
        isExtends ? definition.getExtendsClause() : definition.getImplementsClause();
    assert clause != null;

    PsiElement addedClause = myClass.addBefore(clause, myClass.getBody());
    JavaCodeStyleManager.getInstance(project).shortenClassReferences(addedClause);
  }
  @NotNull
  public static PsiClassType[] getExtendsListTypes(GrTypeDefinition grType) {
    final PsiClassType[] extendsTypes = getReferenceListTypes(grType.getExtendsClause());
    if (grType.isInterface()) {
      return extendsTypes;
    }

    for (PsiClassType type : extendsTypes) {
      final PsiClass superClass = type.resolve();
      if (superClass instanceof GrTypeDefinition && !superClass.isInterface()
          || superClass != null
              && GroovyCommonClassNames.GROOVY_OBJECT_SUPPORT.equals(
                  superClass.getQualifiedName())) {
        return extendsTypes;
      }
    }

    PsiClass grObSupport =
        GroovyPsiManager.getInstance(grType.getProject())
            .findClassWithCache(
                GroovyCommonClassNames.GROOVY_OBJECT_SUPPORT, grType.getResolveScope());
    if (grObSupport != null) {
      final PsiClassType type =
          JavaPsiFacade.getInstance(grType.getProject())
              .getElementFactory()
              .createType(grObSupport);
      return ArrayUtil.append(extendsTypes, type, PsiClassType.ARRAY_FACTORY);
    }
    return extendsTypes;
  }
 @Nullable
 public static PsiClass getBaseClass(GrTypeDefinition grType) {
   if (grType.isEnum()) {
     return JavaPsiFacade.getInstance(grType.getProject())
         .findClass(CommonClassNames.JAVA_LANG_ENUM, grType.getResolveScope());
   } else {
     return JavaPsiFacade.getInstance(grType.getProject())
         .findClass(CommonClassNames.JAVA_LANG_OBJECT, grType.getResolveScope());
   }
 }
  @NotNull
  public static PsiClassType[] getSuperTypes(GrTypeDefinition grType) {
    PsiClassType[] extendsList = grType.getExtendsListTypes();
    if (extendsList.length == 0) {
      extendsList = new PsiClassType[] {createBaseClassType(grType)};
    }

    return ArrayUtil.mergeArrays(
        extendsList, grType.getImplementsListTypes(), PsiClassType.ARRAY_FACTORY);
  }
  @Nullable
  public static PsiClass createSubclassGroovy(
      final GrTypeDefinition psiClass, final PsiDirectory targetDirectory, final String className) {
    final Project project = psiClass.getProject();
    final Ref<GrTypeDefinition> targetClass = new Ref<GrTypeDefinition>();

    new WriteCommandAction(project, getTitle(psiClass), getTitle(psiClass)) {
      @Override
      protected void run(Result result) throws Throwable {
        IdeDocumentHistory.getInstance(project).includeCurrentPlaceAsChangePlace();

        final GrTypeParameterList oldTypeParameterList = psiClass.getTypeParameterList();

        try {
          targetClass.set(
              CreateClassActionBase.createClassByType(
                  targetDirectory,
                  className,
                  PsiManager.getInstance(project),
                  psiClass,
                  NewGroovyClassAction.GROOVY_CLASS));
        } catch (final IncorrectOperationException e) {
          ApplicationManager.getApplication()
              .invokeLater(
                  new Runnable() {
                    @Override
                    public void run() {
                      Messages.showErrorDialog(
                          project,
                          CodeInsightBundle.message(
                                  "intention.error.cannot.create.class.message", className)
                              + "\n"
                              + e.getLocalizedMessage(),
                          CodeInsightBundle.message("intention.error.cannot.create.class.title"));
                    }
                  });
          return;
        }
        startTemplate(oldTypeParameterList, project, psiClass, targetClass.get(), false);
        GrReferenceAdjuster.shortenReferences(targetClass.get());
      }
    }.execute();
    if (targetClass.get() == null) return null;
    if (!ApplicationManager.getApplication().isUnitTestMode() && !psiClass.hasTypeParameters()) {

      final Editor editor =
          CodeInsightUtil.positionCursor(
              project, targetClass.get().getContainingFile(), targetClass.get().getLBrace());
      if (editor == null) return targetClass.get();
      chooseAndImplement(psiClass, project, targetClass.get(), editor);
    }
    return targetClass.get();
  }
  public static void collectMethodsFromBody(
      @NotNull GrTypeDefinition definition, List<PsiMethod> result) {
    for (GrMethod method : definition.getCodeMethods()) {
      addExpandingReflectedMethods(result, method);
    }

    for (GrField field : definition.getFields()) {
      if (!field.isProperty()) continue;
      ContainerUtil.addAll(result, field.getGetters());
      ContainerUtil.addIfNotNull(result, field.getSetter());
    }
  }
Ejemplo n.º 9
0
 private void doMoveField(PsiSubstitutor substitutor, GrMemberInfo info) {
   GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject);
   GrField field = (GrField) info.getMember();
   field.normalizeDeclaration();
   replaceMovedMemberTypeParameters(
       field, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
   // fixReferencesToStatic(field, movedMembers);
   if (myTargetSuperClass.isInterface()) {
     PsiUtil.setModifierProperty(field, PsiModifier.PUBLIC, true);
   }
   final PsiMember movedElement = (PsiMember) myTargetSuperClass.add(field);
   myMembersAfterMove.add(movedElement);
   deleteMemberWithDocComment(field);
 }
 @Nullable
 public static GrTypeDefinition findContainingClass(GrIntroduceContext context) {
   PsiElement place = context.getPlace();
   while (true) {
     final GrTypeDefinition typeDefinition =
         PsiTreeUtil.getParentOfType(place, GrTypeDefinition.class, true, GroovyFileBase.class);
     if (typeDefinition == null) return null;
     if (!typeDefinition.isAnonymous()
         && (typeDefinition.hasModifierProperty(PsiModifier.STATIC)
             || typeDefinition.getContainingClass() == null)) {
       return typeDefinition;
     }
     place = typeDefinition;
   }
 }
 private static boolean checkForDelegate(GrTypeDefinition clazz) {
   for (GrField field : clazz.getFields()) {
     if (PsiImplUtil.getAnnotation(field, GroovyCommonClassNames.GROOVY_LANG_DELEGATE) != null)
       return true;
   }
   return false;
 }
  @NotNull
  public static List<Pair<PsiMethod, PsiSubstitutor>> findMethodsAndTheirSubstitutorsByName(
      GrTypeDefinition grType, String name, boolean checkBases) {
    final ArrayList<Pair<PsiMethod, PsiSubstitutor>> result =
        new ArrayList<Pair<PsiMethod, PsiSubstitutor>>();

    if (!checkBases) {
      final PsiMethod[] methods = grType.findMethodsByName(name, false);
      for (PsiMethod method : methods) {
        result.add(new Pair<PsiMethod, PsiSubstitutor>(method, PsiSubstitutor.EMPTY));
      }
    } else {
      final Map<String, List<CandidateInfo>> map =
          CollectClassMembersUtil.getAllMethods(grType, true);
      final List<CandidateInfo> candidateInfos = map.get(name);
      if (candidateInfos != null) {
        for (CandidateInfo info : candidateInfos) {
          final PsiElement element = info.getElement();
          result.add(
              new Pair<PsiMethod, PsiSubstitutor>((PsiMethod) element, info.getSubstitutor()));
        }
      }
    }

    return result;
  }
 @Nullable
 public static PsiClass getSuperClass(GrTypeDefinition grType) {
   final PsiClassType[] extendsList = grType.getExtendsListTypes();
   if (extendsList.length == 0) return getBaseClass(grType);
   final PsiClass superClass = extendsList[0].resolve();
   return superClass != null ? superClass : getBaseClass(grType);
 }
Ejemplo n.º 14
0
  @NotNull
  private Set<String> addAllRestrictedProperties() {
    if (myRefExpr.getQualifier() != null) {
      return Collections.emptySet();
    }

    Set<String> propertyNames = new HashSet<String>();
    for (GrTypeDefinition containingClass =
            PsiTreeUtil.getParentOfType(myRefExpr, GrTypeDefinition.class);
        containingClass != null;
        containingClass = PsiTreeUtil.getParentOfType(containingClass, GrTypeDefinition.class)) {
      for (PsiField field : containingClass.getFields()) {
        propertyNames.add(field.getName());
      }
    }
    return propertyNames;
  }
  private static void getImplementListsInner(
      GrTypeDefinition grType, List<PsiClassType> result, Set<PsiClass> visited) {
    if (!visited.add(grType)) return;

    final PsiClassType[] implementsTypes = getReferenceListTypes(grType.getImplementsClause());
    List<PsiClassType> fromDelegates = getImplementsFromDelegate(grType, visited);
    if (fromDelegates != null) {
      result.addAll(fromDelegates);
    }
    result.addAll(Arrays.asList(implementsTypes));

    if (!grType.isInterface()
        && !ContainerUtil.or(implementsTypes, IS_GROOVY_OBJECT)
        && !ContainerUtil.or(getReferenceListTypes(grType.getExtendsClause()), IS_GROOVY_OBJECT)) {
      result.add(getGroovyObjectType(grType));
    }
  }
 public static PsiClass[] getInterfaces(GrTypeDefinition grType) {
   final PsiClassType[] implementsListTypes = grType.getImplementsListTypes();
   List<PsiClass> result = new ArrayList<PsiClass>(implementsListTypes.length);
   for (PsiClassType type : implementsListTypes) {
     final PsiClass psiClass = type.resolve();
     if (psiClass != null) result.add(psiClass);
   }
   return result.toArray(new PsiClass[result.size()]);
 }
  @Override
  public void collectMethods(
      @NotNull GrTypeDefinition clazz, @NotNull Collection<PsiMethod> collector) {
    if (!hasGeneratedImplementations(clazz)) return;

    final LightMethodBuilder write = new LightMethodBuilder(clazz.getManager(), "writeExternal");
    write.setContainingClass(clazz);
    write.addParameter("out", ObjectOutput.class.getName());
    write.addException(IOException.class.getName());
    write.setOriginInfo("created by @AutoExternalize");
    collector.add(write);

    final LightMethodBuilder read = new LightMethodBuilder(clazz.getManager(), "readExternal");
    read.setContainingClass(clazz);
    read.addParameter("oin", ObjectInput.class.getName());
    read.setOriginInfo("created by @AutoExternalize");
    collector.add(read);
  }
Ejemplo n.º 18
0
  public void setCorrectVisibility(final HashSet<PsiMember> movedMembers, GrMemberInfo info) {
    PsiModifierListOwner modifierListOwner = info.getMember();
    if (myTargetSuperClass.isInterface()) {
      PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PUBLIC, true);
    } else if (modifierListOwner.hasModifierProperty(PsiModifier.PRIVATE)) {
      if (info.isToAbstract()
          || willBeUsedInSubclass(
              modifierListOwner, movedMembers, myTargetSuperClass, mySourceClass)) {
        PsiUtil.setModifierProperty(modifierListOwner, PsiModifier.PROTECTED, true);
      }

      if (modifierListOwner instanceof GrTypeDefinition) {
        ((GrTypeDefinition) modifierListOwner)
            .accept(
                new GroovyRecursiveElementVisitor() {
                  @Override
                  public void visitMethod(GrMethod method) {
                    check(method);
                  }

                  @Override
                  public void visitField(GrField field) {
                    check(field);
                  }

                  @Override
                  public void visitTypeDefinition(GrTypeDefinition typeDefinition) {
                    check(typeDefinition);
                    super.visitTypeDefinition(typeDefinition);
                  }

                  private void check(PsiMember member) {
                    if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
                      if (willBeUsedInSubclass(
                          member, movedMembers, myTargetSuperClass, mySourceClass)) {
                        PsiUtil.setModifierProperty(member, PsiModifier.PROTECTED, true);
                      }
                    }
                  }
                });
      }
    }
  }
  private static void processClassUsage(GrTypeDefinition psiClass, JavaChangeInfo changeInfo) {
    String name = psiClass.getName();

    GrMethod constructor =
        GroovyPsiElementFactory.getInstance(psiClass.getProject())
            .createConstructorFromText(
                name, ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.EMPTY_STRING_ARRAY, "{}", null);

    GrModifierList list = constructor.getModifierList();
    if (psiClass.hasModifierProperty(PsiModifier.PRIVATE))
      list.setModifierProperty(PsiModifier.PRIVATE, true);
    if (psiClass.hasModifierProperty(PsiModifier.PROTECTED))
      list.setModifierProperty(PsiModifier.PROTECTED, true);
    if (!list.hasExplicitVisibilityModifiers()) {
      list.setModifierProperty(GrModifier.DEF, true);
    }

    constructor = (GrMethod) psiClass.add(constructor);
    processConstructor(constructor, changeInfo);
  }
 private static boolean shouldProcessInstanceMembers(
     @NotNull GrTypeDefinition grType, @Nullable PsiElement lastParent) {
   if (lastParent != null) {
     final GrModifierList modifierList = grType.getModifierList();
     if (modifierList != null
         && modifierList.findAnnotation(GroovyCommonClassNames.GROOVY_LANG_CATEGORY) != null) {
       return false;
     }
   }
   return true;
 }
  @NotNull
  private static List<PsiClass> getInnerClassesForResolve(
      @NotNull final GrTypeDefinition grType,
      @Nullable final PsiElement lastParent,
      @NotNull final PsiElement place) {
    if (lastParent instanceof GrReferenceList
        || PsiTreeUtil.getParentOfType(place, GrReferenceList.class) != null) {
      return Arrays.asList(grType.getInnerClasses());
    }

    List<PsiClass> classes =
        RecursionManager.doPreventingRecursion(
            grType,
            true,
            new Computable<List<PsiClass>>() {
              @Override
              public List<PsiClass> compute() {
                List<PsiClass> result = new ArrayList<PsiClass>();
                for (CandidateInfo info :
                    CollectClassMembersUtil.getAllInnerClasses(grType, false).values()) {
                  final PsiClass inner = (PsiClass) info.getElement();
                  final PsiClass containingClass = inner.getContainingClass();
                  assert containingClass != null;

                  if (lastParent == null
                      || !containingClass.isInterface()
                      || PsiTreeUtil.isAncestor(containingClass, place, false)) {
                    ContainerUtil.addIfNotNull(result, inner);
                  }
                }
                return result;
              }
            });

    if (classes == null) {
      return Arrays.asList(grType.getInnerClasses());
    }

    return classes;
  }
  @NotNull
  public static PsiClass[] getSupers(GrTypeDefinition grType) {
    PsiClassType[] superTypes = grType.getSuperTypes();
    List<PsiClass> result = new ArrayList<PsiClass>();
    for (PsiClassType superType : superTypes) {
      PsiClass superClass = superType.resolve();
      if (superClass != null) {
        result.add(superClass);
      }
    }

    return result.toArray(new PsiClass[result.size()]);
  }
 @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();
   }
 }
  private static Set<ReadWriteVariableInstruction> collectUsedVariableWithoutInitialization(
      GrTypeDefinition typeDefinition) {
    final Set<ReadWriteVariableInstruction> vars = ContainerUtil.newLinkedHashSet();
    typeDefinition.acceptChildren(
        new GroovyRecursiveElementVisitor() {
          private void collectVars(Instruction[] flow) {
            ReadWriteVariableInstruction[] reads =
                ControlFlowBuilderUtil.getReadsWithoutPriorWrites(flow, false);
            Collections.addAll(vars, reads);
          }

          @Override
          public void visitField(GrField field) {
            GrExpression initializer = field.getInitializerGroovy();
            if (initializer != null) {
              Instruction[] flow =
                  new ControlFlowBuilder(field.getProject()).buildControlFlow(initializer);
              collectVars(flow);
            }
          }

          @Override
          public void visitMethod(GrMethod method) {
            GrOpenBlock block = method.getBlock();
            if (block != null) {
              collectVars(block.getControlFlow());
            }
          }

          @Override
          public void visitClassInitializer(GrClassInitializer initializer) {
            GrOpenBlock block = initializer.getBlock();
            collectVars(block.getControlFlow());
          }
        });
    return vars;
  }
  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;
  }
 public static PsiClassType createBaseClassType(GrTypeDefinition grType) {
   if (grType.isEnum()) {
     return TypesUtil.createTypeByFQClassName(CommonClassNames.JAVA_LANG_ENUM, grType);
   }
   return TypesUtil.getJavaLangObject(grType);
 }
  @Override
  public void collectMethods(
      @NotNull GrTypeDefinition typeDefinition, Collection<PsiMethod> collector) {
    if (typeDefinition.getName() == null) return;

    PsiModifierList modifierList = typeDefinition.getModifierList();
    if (modifierList == null) return;

    final PsiAnnotation tupleConstructor =
        modifierList.findAnnotation(GroovyCommonClassNames.GROOVY_TRANSFORM_TUPLE_CONSTRUCTOR);
    final boolean immutable =
        modifierList.findAnnotation(IMMUTABLE) != null
            || modifierList.findAnnotation(GroovyCommonClassNames.GROOVY_TRANSFORM_IMMUTABLE)
                != null;
    final PsiAnnotation canonical =
        modifierList.findAnnotation(GroovyCommonClassNames.GROOVY_TRANSFORM_CANONICAL);
    if (!immutable && canonical == null && tupleConstructor == null) {
      return;
    }

    if (tupleConstructor != null
        && typeDefinition.getCodeConstructors().length > 0
        && !PsiUtil.getAnnoAttributeValue(tupleConstructor, "force", false)) {
      return;
    }

    final GrLightMethodBuilder fieldsConstructor =
        new GrLightMethodBuilder(typeDefinition.getManager(), typeDefinition.getName());
    fieldsConstructor.setConstructor(true).setNavigationElement(typeDefinition);

    Set<String> excludes = new HashSet<String>();
    if (tupleConstructor != null) {
      for (String s : PsiUtil.getAnnoAttributeValue(tupleConstructor, "excludes", "").split(",")) {
        final String name = s.trim();
        if (StringUtil.isNotEmpty(name)) {
          excludes.add(name);
        }
      }
    }

    if (tupleConstructor != null) {
      final boolean superFields =
          PsiUtil.getAnnoAttributeValue(tupleConstructor, "includeSuperFields", false);
      final boolean superProperties =
          PsiUtil.getAnnoAttributeValue(tupleConstructor, "includeSuperProperties", false);
      if (superFields || superProperties) {
        addParametersForSuper(
            typeDefinition,
            fieldsConstructor,
            superFields,
            superProperties,
            new HashSet<PsiClass>(),
            excludes);
      }
    }

    addParameters(
        typeDefinition,
        fieldsConstructor,
        tupleConstructor == null
            || PsiUtil.getAnnoAttributeValue(tupleConstructor, "includeProperties", true),
        tupleConstructor != null
            ? PsiUtil.getAnnoAttributeValue(tupleConstructor, "includeFields", false)
            : canonical == null,
        !immutable,
        excludes);

    collector.add(fieldsConstructor.setContainingClass(typeDefinition));

    collector.add(
        new GrLightMethodBuilder(typeDefinition.getManager(), typeDefinition.getName())
            .addParameter("args", CommonClassNames.JAVA_UTIL_MAP, false)
            .setConstructor(true)
            .setContainingClass(typeDefinition));
  }
  private static void startTemplate(
      GrTypeParameterList oldTypeParameterList,
      final Project project,
      final GrTypeDefinition psiClass,
      final GrTypeDefinition targetClass,
      boolean includeClassName) {
    PsiElementFactory jfactory = JavaPsiFacade.getElementFactory(project);
    final GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(project);
    GrCodeReferenceElement ref = elementFactory.createCodeReferenceElementFromClass(psiClass);
    try {
      if (psiClass.isInterface()) {
        GrImplementsClause clause = targetClass.getImplementsClause();
        if (clause == null) {
          clause =
              (GrImplementsClause)
                  targetClass.addAfter(
                      elementFactory.createImplementsClause(),
                      targetClass.getNameIdentifierGroovy());
        }
        ref = (GrCodeReferenceElement) clause.add(ref);
      } else {
        GrExtendsClause clause = targetClass.getExtendsClause();
        if (clause == null) {
          clause =
              (GrExtendsClause)
                  targetClass.addAfter(
                      elementFactory.createExtendsClause(), targetClass.getNameIdentifierGroovy());
        }
        ref = (GrCodeReferenceElement) clause.add(ref);
      }
      if (psiClass.hasTypeParameters() || includeClassName) {
        final Editor editor =
            CodeInsightUtil.positionCursor(
                project, targetClass.getContainingFile(), targetClass.getLBrace());
        final TemplateBuilderImpl templateBuilder =
            editor == null || ApplicationManager.getApplication().isUnitTestMode()
                ? null
                : (TemplateBuilderImpl)
                    TemplateBuilderFactory.getInstance().createTemplateBuilder(targetClass);

        if (includeClassName && templateBuilder != null) {
          templateBuilder.replaceElement(targetClass.getNameIdentifier(), targetClass.getName());
        }

        if (oldTypeParameterList != null) {
          for (PsiTypeParameter parameter : oldTypeParameterList.getTypeParameters()) {
            final PsiElement param =
                ref.getTypeArgumentList()
                    .add(elementFactory.createTypeElement(jfactory.createType(parameter)));
            if (templateBuilder != null) {
              templateBuilder.replaceElement(param, param.getText());
            }
          }
        }

        final GrTypeParameterList typeParameterList = targetClass.getTypeParameterList();
        assert typeParameterList != null;
        typeParameterList.replace(oldTypeParameterList);

        if (templateBuilder != null) {
          templateBuilder.setEndVariableBefore(ref);
          final Template template = templateBuilder.buildTemplate();
          template.addEndVariable();

          final PsiFile containingFile = targetClass.getContainingFile();

          PsiDocumentManager.getInstance(project)
              .doPostponedOperationsAndUnblockDocument(editor.getDocument());

          final TextRange textRange = targetClass.getTextRange();
          final int startClassOffset = textRange.getStartOffset();
          editor.getDocument().deleteString(textRange.getStartOffset(), textRange.getEndOffset());
          CreateFromUsageBaseFix.startTemplate(
              editor,
              template,
              project,
              new TemplateEditingAdapter() {
                @Override
                public void templateFinished(Template template, boolean brokenOff) {
                  chooseAndImplement(
                      psiClass,
                      project,
                      PsiTreeUtil.getParentOfType(
                          containingFile.findElementAt(startClassOffset), GrTypeDefinition.class),
                      editor);
                }
              },
              getTitle(psiClass));
        }
      }
    } catch (IncorrectOperationException e) {
      LOG.error(e);
    }
  }
 public ChangeExtendsImplementsQuickFix(@NotNull GrTypeDefinition aClass) {
   myClass = aClass;
   myExtendsClause = aClass.getExtendsClause();
   myImplementsClause = aClass.getImplementsClause();
 }
 public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
   return myClass.isValid() && myClass.getManager().isInProject(file);
 }