private void fixReferencesToStatic(GroovyPsiElement classMember, Set<PsiMember> movedMembers) throws IncorrectOperationException { final StaticReferencesCollector collector = new StaticReferencesCollector(movedMembers); classMember.accept(collector); ArrayList<GrReferenceElement> refs = collector.getReferences(); ArrayList<PsiElement> members = collector.getReferees(); ArrayList<PsiClass> classes = collector.getRefereeClasses(); GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject); for (int i = 0; i < refs.size(); i++) { GrReferenceElement ref = refs.get(i); PsiElement namedElement = members.get(i); PsiClass aClass = classes.get(i); if (namedElement instanceof PsiNamedElement) { GrReferenceExpression newRef = (GrReferenceExpression) factory.createExpressionFromText( "a." + ((PsiNamedElement) namedElement).getName(), null); GrExpression qualifier = newRef.getQualifierExpression(); assert qualifier != null; qualifier = (GrExpression) qualifier.replace( factory.createReferenceExpressionFromText(aClass.getQualifiedName())); qualifier.putCopyableUserData(PRESERVE_QUALIFIER, ref.isQualified()); PsiElement replaced = ref.replace(newRef); JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(replaced); } } }
private static void genForPart( StringBuilder builder, GroovyPsiElement part, final Generator visitor) { part.accept(visitor); for (String statement : visitor.getContext().myStatements) { builder.append(statement).append(", "); } builder.append(visitor.getBuilder()); }
@Override public void visitParenthesizedExpression(GrParenthesizedExpression expression) { final PsiElement parent = expression.getParent(); if (parent instanceof GroovyPsiElement) { ((GroovyPsiElement) parent).accept(this); } else { parent.accept(new GroovyPsiElementVisitor(this)); } }
@Override public void processDynamicElements( final @NotNull PsiType qualifierType, final PsiScopeProcessor processor, final GroovyPsiElement place, final ResolveState state) { if (!GroovyPsiManager.isInheritorCached(qualifierType, CommonClassNames.JAVA_UTIL_COLLECTION)) return; final PsiType collectionType = PsiUtil.extractIterableTypeParameter(qualifierType, true); if (collectionType == null) return; final PsiScopeProcessor fieldSearcher = new FieldSearcher( processor, JavaPsiFacade.getInstance(place.getProject()) .findClass(CommonClassNames.JAVA_UTIL_COLLECTION, place.getResolveScope())); ResolveUtil.processAllDeclarations(collectionType, fieldSearcher, state, place); }
@Override public void processDynamicElements( @NotNull PsiType qualifierType, PsiClass aClass, PsiScopeProcessor processor, GroovyPsiElement place, ResolveState state) { ClassHint classHint = processor.getHint(ClassHint.KEY); if (classHint != null && !classHint.shouldProcess(ClassHint.ResolveKind.PROPERTY)) return; String nameHint = ResolveUtil.getNameHint(processor); Map<String, PsiClass> supers = TypesUtil.getSuperClassesWithCache(aClass); PsiElement grCall = place.getParent(); if (grCall instanceof GrMethodCall) { PsiElement grClosure = grCall.getParent(); if (grClosure instanceof GrClosableBlock) { PsiElement contentField = grClosure.getParent(); if (contentField instanceof GrField) { GrField f = (GrField) contentField; if ("content".equals(f.getName()) && f.hasModifierProperty(PsiModifier.STATIC) && f.getContainingClass() == aClass) { Map<String, PsiField> elements = GebUtil.getContentElements(aClass); for (PsiField field : elements.values()) { if (field.getNavigationElement() == place) { return; // Don't resolve variable definition. } } } } } } for (PsiClass psiClass : supers.values()) { Map<String, PsiField> contentFields = GebUtil.getContentElements(psiClass); if (nameHint == null) { for (Map.Entry<String, PsiField> entry : contentFields.entrySet()) { if (!processor.execute(entry.getValue(), state)) return; } } else { PsiField field = contentFields.get(nameHint); if (field != null) { processor.execute(field, state); return; } } } }
public static void detectAccessibilityConflicts( @Nullable GroovyPsiElement elementToProcess, final UsageInfo[] usages, MultiMap<PsiElement, String> conflicts, boolean replaceFieldsWithGetters, Project project) { if (elementToProcess == null) return; final ReferencedElementsCollector collector = new ReferencedElementsCollector(); elementToProcess.accept(collector); final List<PsiElement> result = collector.getResult(); if (result.isEmpty()) return; for (final UsageInfo usageInfo : usages) { if (!(usageInfo instanceof ExternalUsageInfo) || !IntroduceParameterUtil.isMethodUsage(usageInfo)) continue; final PsiElement place = usageInfo.getElement(); for (PsiElement element : result) { if (element instanceof PsiField && replaceFieldsWithGetters) { // check getter access instead final PsiClass psiClass = ((PsiField) element).getContainingClass(); LOG.assertTrue(psiClass != null); final PsiMethod method = GroovyPropertyUtils.findGetterForField((PsiField) element); if (method != null) { element = method; } } if (element instanceof PsiMember && !JavaPsiFacade.getInstance(project) .getResolveHelper() .isAccessible((PsiMember) element, place, null)) { String message = RefactoringBundle.message( "0.is.not.accessible.from.1.value.for.introduced.parameter.in.that.method.call.will.be.incorrect", RefactoringUIUtil.getDescription(element, true), RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(place), true)); conflicts.putValue(element, message); } } } }
private void buildFlowForClosure(final GrClosableBlock closure) { for (GrParameter parameter : closure.getAllParameters()) { if (myPolicy.isVariableInitialized(parameter)) { addNode(new ReadWriteVariableInstruction(parameter.getName(), parameter, WRITE)); } } addNode(new ReadWriteVariableInstruction("owner", closure.getLBrace(), WRITE)); PsiElement child = closure.getFirstChild(); while (child != null) { if (child instanceof GroovyPsiElement) { ((GroovyPsiElement) child).accept(this); } child = child.getNextSibling(); } final GrStatement[] statements = closure.getStatements(); if (statements.length > 0) { handlePossibleReturn(statements[statements.length - 1]); } }
public Instruction[] buildControlFlow(GroovyPsiElement scope) { myInstructions = new ArrayList<InstructionImpl>(); myProcessingStack = new ArrayDeque<InstructionImpl>(); myCaughtExceptionInfos = new ArrayDeque<ExceptionInfo>(); myConditions = new ArrayDeque<ConditionInstruction>(); myFinallyCount = 0; myPending = new ArrayList<Pair<InstructionImpl, GroovyPsiElement>>(); myInstructionNumber = 0; myScope = scope; startNode(null); if (scope instanceof GrClosableBlock) { buildFlowForClosure((GrClosableBlock) scope); } else { scope.accept(this); } final InstructionImpl end = startNode(null); checkPending(end); // collect return edges return assertValidPsi(myInstructions.toArray(new Instruction[myInstructions.size()])); }
public static MultiMap<PsiElement, String> checkConflicts( final MemberInfoBase<? extends GrMember>[] infos, @NotNull final PsiClass subclass, @Nullable PsiClass superClass, @NotNull final PsiPackage targetPackage, @NotNull PsiDirectory targetDirectory, final InterfaceContainmentVerifier interfaceContainmentVerifier, boolean movedMembers2Super) { final PsiElement targetRepresentativeElement; final boolean isInterfaceTarget; if (superClass != null) { isInterfaceTarget = superClass.isInterface(); targetRepresentativeElement = superClass; } else { isInterfaceTarget = false; targetRepresentativeElement = targetDirectory; } final Set<GrMember> movedMembers = ContainerUtil.newHashSet(); final Set<GrMethod> abstractMethods = ContainerUtil.newHashSet(); for (MemberInfoBase<? extends GrMember> info : infos) { GrMember member = info.getMember(); if (member instanceof GrMethod) { if (!info.isToAbstract() && !isInterfaceTarget) { movedMembers.add(member); } else { abstractMethods.add((GrMethod) member); } } else { movedMembers.add(member); } } final Set<PsiMethod> allAbstractMethods = new HashSet<PsiMethod>(abstractMethods); if (superClass != null) { for (PsiMethod method : subclass.getMethods()) { if (!movedMembers.contains(method) && !method.hasModifierProperty(PsiModifier.PRIVATE)) { if (method.findSuperMethods(superClass).length > 0) { allAbstractMethods.add(method); } } } } final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>(); GrRefactoringConflictsUtil.analyzeAccessibilityConflicts( movedMembers, superClass, conflicts, VisibilityUtil.ESCALATE_VISIBILITY, targetRepresentativeElement, allAbstractMethods); if (superClass != null) { if (movedMembers2Super) { checkSuperclassMembers(superClass, infos, conflicts); if (isInterfaceTarget) { checkInterfaceTarget(infos, conflicts); } } else { final String qualifiedName = superClass.getQualifiedName(); assert qualifiedName != null; if (superClass.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) { if (!Comparing.strEqual( StringUtil.getPackageName(qualifiedName), targetPackage.getQualifiedName())) { conflicts.putValue( superClass, RefactoringUIUtil.getDescription(superClass, true) + " won't be accessible from " + RefactoringUIUtil.getDescription(targetPackage, true)); } } } } // check if moved methods use other members in the classes between Subclass and Superclass List<PsiElement> checkModuleConflictsList = new ArrayList<PsiElement>(); for (PsiMember member : movedMembers) { if (member instanceof PsiMethod || member instanceof PsiClass && !(member instanceof PsiCompiledElement)) { GrClassMemberReferenceVisitor visitor = movedMembers2Super ? new ConflictingUsagesOfSubClassMembers( member, movedMembers, abstractMethods, subclass, superClass, superClass != null ? null : targetPackage, conflicts, interfaceContainmentVerifier) : new ConflictingUsagesOfSuperClassMembers( member, subclass, targetPackage, movedMembers, conflicts); ((GroovyPsiElement) member).accept(visitor); } checkModuleConflictsList.add(member); } for (final PsiMethod method : abstractMethods) { ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getParameterList()); ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getReturnTypeElement()); ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getTypeParameterList()); } GrRefactoringConflictsUtil.analyzeModuleConflicts( subclass.getProject(), checkModuleConflictsList, new UsageInfo[0], targetRepresentativeElement, conflicts); final String fqName = subclass.getQualifiedName(); final String packageName; if (fqName != null) { packageName = StringUtil.getPackageName(fqName); } else { final PsiFile psiFile = PsiTreeUtil.getParentOfType(subclass, PsiFile.class); if (psiFile instanceof PsiClassOwner) { packageName = ((PsiClassOwner) psiFile).getPackageName(); } else { packageName = null; } } final boolean toDifferentPackage = !Comparing.strEqual(targetPackage.getQualifiedName(), packageName); for (final GrMethod abstractMethod : abstractMethods) { abstractMethod.accept( new GrClassMemberReferenceVisitor(subclass) { @Override protected void visitClassMemberReferenceElement( GrMember classMember, GrReferenceElement classMemberReference) { if (classMember != null && willBeMoved(classMember, movedMembers)) { boolean isAccessible = false; if (classMember.hasModifierProperty(PsiModifier.PRIVATE)) { isAccessible = true; } else if (classMember.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && toDifferentPackage) { isAccessible = true; } if (isAccessible) { String message = RefactoringUIUtil.getDescription(abstractMethod, false) + " uses " + RefactoringUIUtil.getDescription(classMember, true) + " which won't be accessible from the subclass."; message = CommonRefactoringUtil.capitalize(message); conflicts.putValue(classMember, message); } } } }); if (abstractMethod.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && toDifferentPackage) { if (!isInterfaceTarget) { String message = "Can't make " + RefactoringUIUtil.getDescription(abstractMethod, false) + " abstract as it won't be accessible from the subclass."; message = CommonRefactoringUtil.capitalize(message); conflicts.putValue(abstractMethod, message); } } } return conflicts; }
public void moveMembersToBase() throws IncorrectOperationException { final HashSet<PsiMember> movedMembers = ContainerUtil.newHashSet(); myMembersAfterMove = ContainerUtil.newHashSet(); // build aux sets for (GrMemberInfo info : myMembersToMove) { movedMembers.add(info.getMember()); } // correct private member visibility for (GrMemberInfo info : myMembersToMove) { if (info.getMember() instanceof PsiClass && info.getOverrides() != null) continue; setCorrectVisibility(movedMembers, info); GroovyChangeContextUtil.encodeContextInfo(info.getMember()); info.getMember().accept(new QualifiedThisSuperSearcher()); fixReferencesToStatic(info.getMember(), movedMembers); } final PsiSubstitutor substitutor = upDownSuperClassSubstitutor(); // do actual move for (GrMemberInfo info : myMembersToMove) { if (info.getMember() instanceof PsiMethod) { doMoveMethod(substitutor, info); } else if (info.getMember() instanceof GrField) { doMoveField(substitutor, info); } else if (info.getMember() instanceof PsiClass) { doMoveClass(substitutor, info); } } ExplicitSuperDeleter explicitSuperDeleter = new ExplicitSuperDeleter(); for (PsiMember member : myMembersAfterMove) { ((GrMember) member).accept(explicitSuperDeleter); } explicitSuperDeleter.fixSupers(); final QualifiedThisSuperAdjuster qualifiedThisSuperAdjuster = new QualifiedThisSuperAdjuster(); for (PsiMember member : myMembersAfterMove) { ((GrMember) member).accept(qualifiedThisSuperAdjuster); } for (PsiMember member : myMembersAfterMove) { GroovyChangeContextUtil.decodeContextInfo(member, null, null); } final JavaRefactoringListenerManagerImpl listenerManager = (JavaRefactoringListenerManagerImpl) JavaRefactoringListenerManager.getInstance(myProject); for (final PsiMember movedMember : myMembersAfterMove) { ((GroovyPsiElement) movedMember) .accept( new GroovyRecursiveElementVisitor() { @Override public void visitReferenceExpression(GrReferenceExpression referenceExpression) { if (processRef(referenceExpression)) return; super.visitReferenceExpression(referenceExpression); } @Override public void visitCodeReferenceElement(GrCodeReferenceElement refElement) { if (processRef(refElement)) return; super.visitCodeReferenceElement(refElement); } private boolean processRef( @NotNull GrReferenceElement<? extends GroovyPsiElement> refElement) { final PsiElement qualifier = refElement.getQualifier(); if (qualifier != null) { final Boolean preserveQualifier = qualifier.getCopyableUserData(PRESERVE_QUALIFIER); if (preserveQualifier != null && !preserveQualifier) { refElement.setQualifier(null); return true; } } return false; } }); listenerManager.fireMemberMoved(mySourceClass, movedMember); } }
private void acceptNullable(@Nullable GroovyPsiElement element) { if (element != null) { element.accept(this); } }
private void error(String descr) { PsiFile file = myScope.getContainingFile(); String fileText = file != null ? file.getText() : null; LogMessageEx.error(LOG, descr, myScope.getText(), "\n------------------\n", fileText); }