private static boolean canBePrivate( PsiMethod method, Collection<PsiReference> references, Collection<? extends PsiElement> deleted, final PsiElement[] allElementsToDelete) { final PsiClass containingClass = method.getContainingClass(); if (containingClass == null) { return false; } PsiManager manager = method.getManager(); final JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject()); final PsiElementFactory factory = facade.getElementFactory(); final PsiModifierList privateModifierList; try { final PsiMethod newMethod = factory.createMethod("x3", PsiType.VOID); privateModifierList = newMethod.getModifierList(); privateModifierList.setModifierProperty(PsiModifier.PRIVATE, true); } catch (IncorrectOperationException e) { LOG.assertTrue(false); return false; } for (PsiReference reference : references) { final PsiElement element = reference.getElement(); if (!isInside(element, allElementsToDelete) && !isInside(element, deleted) && !facade .getResolveHelper() .isAccessible(method, privateModifierList, element, null, null)) { return false; } } return true; }
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { if (!CodeInsightUtilBase.preparePsiElementForWrite(descriptor.getPsiElement())) return; final PsiMethod psiMethod = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiMethod.class); if (psiMethod != null) { final ArrayList<PsiElement> psiParameters = new ArrayList<PsiElement>(); final RefElement refMethod = myManager != null ? myManager.getReference(psiMethod) : null; if (refMethod != null) { for (final RefParameter refParameter : getUnusedParameters((RefMethod) refMethod)) { psiParameters.add(refParameter.getElement()); } } else { final PsiParameter[] parameters = psiMethod.getParameterList().getParameters(); for (PsiParameter parameter : parameters) { if (Comparing.strEqual(parameter.getName(), myHint)) { psiParameters.add(parameter); break; } } } final PsiModificationTracker tracker = psiMethod.getManager().getModificationTracker(); final long startModificationCount = tracker.getModificationCount(); removeUnusedParameterViaChangeSignature(psiMethod, psiParameters); if (refMethod != null && startModificationCount != tracker.getModificationCount()) { myProcessor.ignoreElement(refMethod); } } }
@NotNull private static Set<PsiClassType> filterInProjectExceptions( @Nullable PsiMethod targetMethod, @NotNull List<PsiClassType> unhandledExceptions) { if (targetMethod == null) return Collections.emptySet(); Set<PsiClassType> result = new HashSet<PsiClassType>(); if (targetMethod.getManager().isInProject(targetMethod)) { PsiMethod[] superMethods = targetMethod.findSuperMethods(); for (PsiMethod superMethod : superMethods) { Set<PsiClassType> classTypes = filterInProjectExceptions(superMethod, unhandledExceptions); result.addAll(classTypes); } if (superMethods.length == 0) { result.addAll(unhandledExceptions); } } else { PsiClassType[] referencedTypes = targetMethod.getThrowsList().getReferencedTypes(); for (PsiClassType referencedType : referencedTypes) { PsiClass psiClass = referencedType.resolve(); if (psiClass == null) continue; for (PsiClassType exception : unhandledExceptions) { if (referencedType.isAssignableFrom(exception)) result.add(exception); } } } return result; }
private void findUsagesForMethod(PsiMethod method, List<FixableUsageInfo> usages) { final PsiManager psiManager = method.getManager(); final Project project = psiManager.getProject(); final GlobalSearchScope scope = GlobalSearchScope.allScope(project); final Iterable<PsiReference> calls = ReferencesSearch.search(method, scope); for (PsiReference reference : calls) { final PsiElement referenceElement = reference.getElement(); final PsiElement parent = referenceElement.getParent(); if (parent instanceof PsiMethodCallExpression) { final PsiMethodCallExpression call = (PsiMethodCallExpression) parent; if (isInMovedElement(call)) { continue; } final PsiReferenceExpression methodExpression = call.getMethodExpression(); final PsiExpression qualifier = methodExpression.getQualifierExpression(); if (qualifier == null || qualifier instanceof PsiThisExpression) { usages.add(new ReplaceThisCallWithDelegateCall(call, delegateFieldName)); } delegationRequired = true; } } if (!delegationRequired && MethodInheritanceUtils.hasSiblingMethods(method)) { delegationRequired = true; } if (delegationRequired) { usages.add(new MakeMethodDelegate(method, delegateFieldName)); } else { usages.add(new RemoveMethod(method)); } }
private static PsiSubstitutor calculateSubstitutor( PsiMethod derivedMethod, PsiMethod baseMethod) { PsiSubstitutor substitutor; if (derivedMethod.getManager().areElementsEquivalent(derivedMethod, baseMethod)) { substitutor = PsiSubstitutor.EMPTY; } else { final PsiClass baseClass = baseMethod.getContainingClass(); final PsiClass derivedClass = derivedMethod.getContainingClass(); if (baseClass != null && derivedClass != null && InheritanceUtil.isInheritorOrSelf(derivedClass, baseClass, true)) { final PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor( baseClass, derivedClass, PsiSubstitutor.EMPTY); final MethodSignature superMethodSignature = baseMethod.getSignature(superClassSubstitutor); final MethodSignature methodSignature = derivedMethod.getSignature(PsiSubstitutor.EMPTY); final PsiSubstitutor superMethodSubstitutor = MethodSignatureUtil.getSuperMethodSignatureSubstitutor( methodSignature, superMethodSignature); substitutor = superMethodSubstitutor != null ? superMethodSubstitutor : superClassSubstitutor; } else { substitutor = PsiSubstitutor.EMPTY; } } return substitutor; }
private void findUsagesForStaticMethod(PsiMethod method, List<FixableUsageInfo> usages) { final PsiManager psiManager = method.getManager(); final Project project = psiManager.getProject(); final GlobalSearchScope scope = GlobalSearchScope.allScope(project); final Iterable<PsiReference> calls = ReferencesSearch.search(method, scope); final String fullyQualifiedName = getQualifiedName(); for (PsiReference reference : calls) { final PsiElement referenceElement = reference.getElement(); final PsiElement parent = referenceElement.getParent(); if (parent instanceof PsiMethodCallExpression) { final PsiMethodCallExpression call = (PsiMethodCallExpression) parent; if (!isInMovedElement(call)) { usages.add(new RetargetStaticMethodCall(call, fullyQualifiedName)); } } else if (parent instanceof PsiImportStaticStatement) { final PsiJavaCodeReferenceElement importReference = ((PsiImportStaticStatement) parent).getImportReference(); if (importReference != null) { final PsiElement qualifier = importReference.getQualifier(); if (qualifier instanceof PsiJavaCodeReferenceElement) { usages.add( new ReplaceClassReference( (PsiJavaCodeReferenceElement) qualifier, fullyQualifiedName)); } } } } usages.add(new RemoveMethod(method)); }
@Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { return myMethod != null && myMethod.isValid() && myMethod.getBody() == null && myMethod.getContainingClass() != null && myMethod.getManager().isInProject(myMethod); }
private static PsiClassType[] getPrimaryChangedExceptionInfo(JavaChangeInfo changeInfo) throws IncorrectOperationException { final ThrownExceptionInfo[] newExceptionInfos = changeInfo.getNewExceptions(); PsiClassType[] newExceptions = new PsiClassType[newExceptionInfos.length]; final PsiMethod method = changeInfo.getMethod(); for (int i = 0; i < newExceptions.length; i++) { newExceptions[i] = (PsiClassType) newExceptionInfos[i].createType( method, method.getManager()); // context really does not matter here } return newExceptions; }
@NotNull protected UsageInfo[] findUsages() { final PsiManager manager = myMethod.getManager(); final GlobalSearchScope searchScope = GlobalSearchScope.allScope(manager.getProject()); final List<UsageInfo> usages = new ArrayList<UsageInfo>(); for (PsiReference ref : ReferencesSearch.search(myMethod, searchScope, false)) { final PsiElement element = ref.getElement(); if (element instanceof PsiReferenceExpression) { boolean isInternal = PsiTreeUtil.isAncestor(myMethod, element, true); usages.add(new MethodCallUsageInfo((PsiReferenceExpression) element, isInternal)); } else if (element instanceof PsiDocTagValue) { usages.add(new JavadocUsageInfo(((PsiDocTagValue) element))); } else { throw new UnknownReferenceTypeException(element.getLanguage()); } } if (myTargetClass.isInterface()) { addInheritorUsages(myTargetClass, searchScope, usages); } final PsiCodeBlock body = myMethod.getBody(); if (body != null) { body.accept( new JavaRecursiveElementWalkingVisitor() { @Override public void visitNewExpression(PsiNewExpression expression) { if (MoveInstanceMembersUtil.getClassReferencedByThis(expression) != null) { usages.add(new InternalUsageInfo(expression)); } super.visitNewExpression(expression); } @Override public void visitReferenceExpression(PsiReferenceExpression expression) { if (MoveInstanceMembersUtil.getClassReferencedByThis(expression) != null) { usages.add(new InternalUsageInfo(expression)); } else if (!expression.isQualified()) { final PsiElement resolved = expression.resolve(); if (myTargetVariable.equals(resolved)) { usages.add(new InternalUsageInfo(expression)); } } super.visitReferenceExpression(expression); } }); } return usages.toArray(new UsageInfo[usages.size()]); }
private static void processCallerMethod( JavaChangeInfo changeInfo, PsiMethod caller, PsiMethod baseMethod, boolean toInsertParams, boolean toInsertThrows) throws IncorrectOperationException { LOG.assertTrue(toInsertParams || toInsertThrows); if (toInsertParams) { List<PsiParameter> newParameters = new ArrayList<PsiParameter>(); ContainerUtil.addAll(newParameters, caller.getParameterList().getParameters()); final JavaParameterInfo[] primaryNewParms = changeInfo.getNewParameters(); PsiSubstitutor substitutor = baseMethod == null ? PsiSubstitutor.EMPTY : ChangeSignatureProcessor.calculateSubstitutor(caller, baseMethod); for (JavaParameterInfo info : primaryNewParms) { if (info.getOldIndex() < 0) newParameters.add(createNewParameter(changeInfo, info, substitutor)); } PsiParameter[] arrayed = newParameters.toArray(new PsiParameter[newParameters.size()]); boolean[] toRemoveParm = new boolean[arrayed.length]; Arrays.fill(toRemoveParm, false); resolveParameterVsFieldsConflicts(arrayed, caller, caller.getParameterList(), toRemoveParm); } if (toInsertThrows) { List<PsiJavaCodeReferenceElement> newThrowns = new ArrayList<PsiJavaCodeReferenceElement>(); final PsiReferenceList throwsList = caller.getThrowsList(); ContainerUtil.addAll(newThrowns, throwsList.getReferenceElements()); final ThrownExceptionInfo[] primaryNewExns = changeInfo.getNewExceptions(); for (ThrownExceptionInfo thrownExceptionInfo : primaryNewExns) { if (thrownExceptionInfo.getOldIndex() < 0) { final PsiClassType type = (PsiClassType) thrownExceptionInfo.createType(caller, caller.getManager()); final PsiJavaCodeReferenceElement ref = JavaPsiFacade.getInstance(caller.getProject()) .getElementFactory() .createReferenceElementByType(type); newThrowns.add(ref); } } PsiJavaCodeReferenceElement[] arrayed = newThrowns.toArray(new PsiJavaCodeReferenceElement[newThrowns.size()]); boolean[] toRemoveParm = new boolean[arrayed.length]; Arrays.fill(toRemoveParm, false); ChangeSignatureUtil.synchronizeList( throwsList, Arrays.asList(arrayed), ThrowsList.INSTANCE, toRemoveParm); } }
@Override public boolean isAvailable( @NotNull Project project, @NotNull PsiFile file, @NotNull PsiElement startElement, @NotNull PsiElement endElement) { final PsiMethod myMethod = (PsiMethod) startElement; PsiType myReturnType = myReturnTypePointer.getType(); return myMethod.isValid() && myMethod.getManager().isInProject(myMethod) && myReturnType != null && myReturnType.isValid() && !TypeConversionUtil.isNullType(myReturnType) && myMethod.getReturnType() != null && !Comparing.equal(myReturnType, myMethod.getReturnType()); }
private boolean shouldFixSuper(PsiMethod method) { for (PsiMember element : myMembersAfterMove) { if (element instanceof PsiMethod) { PsiMethod member = (PsiMethod) element; // if there is such member among moved members, super qualifier // should not be removed final PsiManager manager = method.getManager(); if (manager.areElementsEquivalent( member.getContainingClass(), method.getContainingClass()) && MethodSignatureUtil.areSignaturesEqual(member, method)) { return false; } } } final PsiMethod methodFromSuper = myTargetSuperClass.findMethodBySignature(method, false); return methodFromSuper == null; }
@Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { int offset = editor.getCaretModel().getOffset(); final PsiMethod method = findMethod(file, offset); if (method == null || !method.isValid()) return false; setText(getIntentionName(method)); if (!method.getManager().isInProject(method)) return false; PsiClass containingClass = method.getContainingClass(); if (containingClass == null) return false; final boolean isAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT); if (isAbstract || !method.hasModifierProperty(PsiModifier.PRIVATE) && !method.hasModifierProperty(PsiModifier.STATIC)) { if (!isAbstract && !isOnIdentifier(file, offset)) return false; MyElementProcessor processor = new MyElementProcessor(method); if (containingClass.isEnum()) { for (PsiField field : containingClass.getFields()) { if (field instanceof PsiEnumConstant) { final PsiEnumConstantInitializer initializingClass = ((PsiEnumConstant) field).getInitializingClass(); if (initializingClass == null) { processor.myHasMissingImplementations = true; } else { if (!processor.execute(initializingClass)) { break; } } } } } ClassInheritorsSearch.search(containingClass, false) .forEach(new PsiElementProcessorAdapter<PsiClass>(processor)); return isAvailable(processor); } return false; }
private void reportNullableArgumentsPassedToNonAnnotated( DataFlowInstructionVisitor visitor, ProblemsHolder holder, Set<PsiElement> reportedAnchors) { for (PsiElement expr : visitor.getProblems(NullabilityProblem.passingNullableArgumentToNonAnnotatedParameter)) { if (reportedAnchors.contains(expr)) continue; final String text = isNullLiteralExpression(expr) ? "Passing <code>null</code> argument to non annotated parameter" : "Argument <code>#ref</code> #loc might be null but passed to non annotated parameter"; LocalQuickFix[] fixes = createNPEFixes((PsiExpression) expr, (PsiExpression) expr, holder.isOnTheFly()); final PsiElement parent = expr.getParent(); if (parent instanceof PsiExpressionList) { final int idx = ArrayUtilRt.find(((PsiExpressionList) parent).getExpressions(), expr); if (idx > -1) { final PsiElement gParent = parent.getParent(); if (gParent instanceof PsiCallExpression) { final PsiMethod psiMethod = ((PsiCallExpression) gParent).resolveMethod(); if (psiMethod != null && psiMethod.getManager().isInProject(psiMethod) && AnnotationUtil.isAnnotatingApplicable(psiMethod)) { final PsiParameter[] parameters = psiMethod.getParameterList().getParameters(); if (idx < parameters.length) { final AddNullableAnnotationFix addNullableAnnotationFix = new AddNullableAnnotationFix(parameters[idx]); fixes = fixes == null ? new LocalQuickFix[] {addNullableAnnotationFix} : ArrayUtil.append(fixes, addNullableAnnotationFix); holder.registerProblem(expr, text, fixes); reportedAnchors.add(expr); } } } } } } }
private static void fixPrimaryThrowsLists(PsiMethod method, PsiClassType[] newExceptions) throws IncorrectOperationException { PsiElementFactory elementFactory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); PsiJavaCodeReferenceElement[] refs = new PsiJavaCodeReferenceElement[newExceptions.length]; for (int i = 0; i < refs.length; i++) { refs[i] = elementFactory.createReferenceElementByType(newExceptions[i]); } PsiReferenceList throwsList = elementFactory.createReferenceList(refs); PsiReferenceList methodThrowsList = (PsiReferenceList) method.getThrowsList().replace(throwsList); methodThrowsList = (PsiReferenceList) JavaCodeStyleManager.getInstance(method.getProject()) .shortenClassReferences(methodThrowsList); CodeStyleManager.getInstance(method.getManager().getProject()) .reformatRange( method, method.getParameterList().getTextRange().getEndOffset(), methodThrowsList.getTextRange().getEndOffset()); }
private void addMethodConflicts(MultiMap<PsiElement, String> conflicts) { String newMethodName = myChangeInfo.getNewName(); if (!(myChangeInfo instanceof JavaChangeInfo)) { return; } try { PsiMethod prototype; final PsiMethod method = myChangeInfo.getMethod(); if (!StdLanguages.JAVA.equals(method.getLanguage())) return; PsiManager manager = method.getManager(); PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); final CanonicalTypes.Type returnType = myChangeInfo.getNewReturnType(); if (returnType != null) { prototype = factory.createMethod(newMethodName, returnType.getType(method, manager)); } else { prototype = factory.createConstructor(); prototype.setName(newMethodName); } JavaParameterInfo[] parameters = myChangeInfo.getNewParameters(); for (JavaParameterInfo info : parameters) { PsiType parameterType = info.createType(method, manager); if (parameterType == null) { parameterType = JavaPsiFacade.getElementFactory(method.getProject()) .createTypeFromText(CommonClassNames.JAVA_LANG_OBJECT, method); } PsiParameter param = factory.createParameter(info.getName(), parameterType); prototype.getParameterList().add(param); } ConflictsUtil.checkMethodConflicts( method.getContainingClass(), method, prototype, conflicts); } catch (IncorrectOperationException e) { LOG.error(e); } }
public void checkPrimitiveVarargs( @NotNull List<CandidateInfo> conflicts, final int argumentsCount) { if (JavaVersionService.getInstance().isAtLeast(myArgumentsList, JavaSdkVersion.JDK_1_7)) return; CandidateInfo objectVararg = null; for (CandidateInfo conflict : conflicts) { ProgressManager.checkCanceled(); final PsiMethod method = (PsiMethod) conflict.getElement(); final int parametersCount = method.getParameterList().getParametersCount(); if (method.isVarArgs() && parametersCount - 1 == argumentsCount) { final PsiType type = method.getParameterList().getParameters()[parametersCount - 1].getType(); final PsiType componentType = ((PsiArrayType) type).getComponentType(); final PsiClassType classType = PsiType.getJavaLangObject( method.getManager(), GlobalSearchScope.allScope(method.getProject())); if (Comparing.equal(componentType, classType)) { objectVararg = conflict; } } } if (objectVararg != null) { for (CandidateInfo conflict : conflicts) { ProgressManager.checkCanceled(); PsiMethod method = (PsiMethod) conflict.getElement(); if (method != objectVararg && method.isVarArgs()) { final int paramsCount = method.getParameterList().getParametersCount(); final PsiType type = method.getParameterList().getParameters()[paramsCount - 1].getType(); final PsiType componentType = ((PsiArrayType) type).getComponentType(); if (argumentsCount == paramsCount - 1 && componentType instanceof PsiPrimitiveType) { conflicts.remove(objectVararg); break; } } } } }
public static boolean isMethodEquivalentTo(@NotNull PsiMethod method1, PsiElement another) { if (method1 == another) return true; if (!(another instanceof PsiMethod)) return false; PsiMethod method2 = (PsiMethod) another; if (!another.isValid()) return false; if (!method1.getName().equals(method2.getName())) return false; PsiClass aClass1 = method1.getContainingClass(); PsiClass aClass2 = method2.getContainingClass(); PsiManager manager = method1.getManager(); if (!(aClass1 != null && aClass2 != null && manager.areElementsEquivalent(aClass1, aClass2))) return false; PsiParameter[] parameters1 = method1.getParameterList().getParameters(); PsiParameter[] parameters2 = method2.getParameterList().getParameters(); if (parameters1.length != parameters2.length) return false; for (int i = 0; i < parameters1.length; i++) { PsiParameter parameter1 = parameters1[i]; PsiParameter parameter2 = parameters2[i]; PsiType type1 = parameter1.getType(); PsiType type2 = parameter2.getType(); if (!compareParamTypes(manager, type1, type2)) return false; } return true; }
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); } }
private PsiClass buildClass() { if (existingClass != null) { return existingClass; } final ParameterObjectBuilder beanClassBuilder = new ParameterObjectBuilder(); beanClassBuilder.setVisibility(myCreateInnerClass ? PsiModifier.PRIVATE : PsiModifier.PUBLIC); beanClassBuilder.setProject(myProject); beanClassBuilder.setTypeArguments(typeParams); beanClassBuilder.setClassName(className); beanClassBuilder.setPackageName(packageName); for (ParameterChunk parameterChunk : parameters) { final VariableData parameter = parameterChunk.parameter; final boolean setterRequired = paramsNeedingSetters.contains(parameter.variable); beanClassBuilder.addField( (PsiParameter) parameter.variable, parameter.name, parameter.type, setterRequired); } final String classString = beanClassBuilder.buildBeanClass(); try { final PsiFileFactory factory = PsiFileFactory.getInstance(method.getProject()); final PsiJavaFile newFile = (PsiJavaFile) factory.createFileFromText(className + ".java", JavaFileType.INSTANCE, classString); if (myCreateInnerClass) { final PsiClass containingClass = method.getContainingClass(); final PsiClass[] classes = newFile.getClasses(); assert classes.length > 0 : classString; final PsiClass innerClass = (PsiClass) containingClass.add(classes[0]); PsiUtil.setModifierProperty(innerClass, PsiModifier.STATIC, true); return (PsiClass) JavaCodeStyleManager.getInstance(newFile.getProject()) .shortenClassReferences(innerClass); } else { final PsiFile containingFile = method.getContainingFile(); final PsiDirectory containingDirectory = containingFile.getContainingDirectory(); final PsiDirectory directory; if (myMoveDestination != null) { directory = myMoveDestination.getTargetDirectory(containingDirectory); } else { final Module module = ModuleUtil.findModuleForPsiElement(containingFile); directory = PackageUtil.findOrCreateDirectoryForPackage( module, packageName, containingDirectory, true, true); } if (directory != null) { final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(method.getManager().getProject()); final PsiElement shortenedFile = JavaCodeStyleManager.getInstance(newFile.getProject()) .shortenClassReferences(newFile); final PsiElement reformattedFile = codeStyleManager.reformat(shortenedFile); return ((PsiJavaFile) directory.add(reformattedFile)).getClasses()[0]; } } } catch (IncorrectOperationException e) { logger.info(e); } return null; }
private PsiMethod createMethodToAdd() { ChangeContextUtil.encodeContextInfo(myMethod, true); try { final PsiManager manager = myMethod.getManager(); final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); // correct internal references final PsiCodeBlock body = myMethod.getBody(); if (body != null) { final Map<PsiElement, PsiElement> replaceMap = new HashMap<PsiElement, PsiElement>(); body.accept( new JavaRecursiveElementVisitor() { @Override public void visitThisExpression(PsiThisExpression expression) { final PsiClass classReferencedByThis = MoveInstanceMembersUtil.getClassReferencedByThis(expression); if (classReferencedByThis != null && !PsiTreeUtil.isAncestor(myMethod, classReferencedByThis, false)) { final PsiElementFactory factory = JavaPsiFacade.getInstance(myProject).getElementFactory(); String paramName = getParameterNameToCreate(classReferencedByThis); try { final PsiExpression refExpression = factory.createExpressionFromText(paramName, null); replaceMap.put(expression, refExpression); } catch (IncorrectOperationException e) { LOG.error(e); } } } @Override public void visitReferenceExpression(PsiReferenceExpression expression) { try { final PsiExpression qualifier = expression.getQualifierExpression(); final PsiElement resolved = expression.resolve(); if (qualifier instanceof PsiReferenceExpression && ((PsiReferenceExpression) qualifier).isReferenceTo(myTargetVariable)) { if (resolved instanceof PsiField) { for (PsiParameter parameter : myMethod.getParameterList().getParameters()) { if (Comparing.strEqual( parameter.getName(), ((PsiField) resolved).getName())) { qualifier.replace(factory.createExpressionFromText("this", null)); return; } } } // Target is a field, replace target.m -> m qualifier.delete(); return; } if (myTargetVariable.equals(resolved)) { PsiThisExpression thisExpression = RefactoringChangeUtil.createThisExpression( manager, PsiTreeUtil.isAncestor( myMethod, PsiTreeUtil.getParentOfType(expression, PsiClass.class), true) ? myTargetClass : null); replaceMap.put(expression, thisExpression); return; } else if (myMethod.equals(resolved)) { } else { PsiClass classReferencedByThis = MoveInstanceMembersUtil.getClassReferencedByThis(expression); if (classReferencedByThis != null) { final String paramName = getParameterNameToCreate(classReferencedByThis); if (paramName != null) { PsiReferenceExpression newQualifier = (PsiReferenceExpression) factory.createExpressionFromText(paramName, null); expression.setQualifierExpression(newQualifier); return; } } } super.visitReferenceExpression(expression); } catch (IncorrectOperationException e) { LOG.error(e); } } @Override public void visitNewExpression(PsiNewExpression expression) { try { final PsiExpression qualifier = expression.getQualifier(); if (qualifier instanceof PsiReferenceExpression && ((PsiReferenceExpression) qualifier).isReferenceTo(myTargetVariable)) { // Target is a field, replace target.new A() -> new A() qualifier.delete(); } else { final PsiClass classReferencedByThis = MoveInstanceMembersUtil.getClassReferencedByThis(expression); if (classReferencedByThis != null) { if (qualifier != null) qualifier.delete(); final String paramName = getParameterNameToCreate(classReferencedByThis); final PsiExpression newExpression = factory.createExpressionFromText( paramName + "." + expression.getText(), null); replaceMap.put(expression, newExpression); } } super.visitNewExpression(expression); } catch (IncorrectOperationException e) { LOG.error(e); } } @Override public void visitMethodCallExpression(PsiMethodCallExpression expression) { correctMethodCall(expression, true); super.visitMethodCallExpression(expression); } }); for (PsiElement element : replaceMap.keySet()) { final PsiElement replacement = replaceMap.get(element); element.replace(replacement); } } final PsiMethod methodCopy = getPatternMethod(); final List<PsiParameter> newParameters = Arrays.asList(methodCopy.getParameterList().getParameters()); RefactoringUtil.fixJavadocsForParams(methodCopy, new HashSet<PsiParameter>(newParameters)); return methodCopy; } catch (IncorrectOperationException e) { LOG.error(e); return myMethod; } }
private static PsiMethod generateDelegateMethod( PsiMethod method, PsiClass superClass, PsiSubstitutor substitutor, boolean keepParameterAnnotations) { final LightMethodBuilder builder = new LightMethodBuilder( superClass.getManager(), GroovyFileType.GROOVY_LANGUAGE, method.getName()); builder.setContainingClass(superClass); builder.setMethodReturnType(substitutor.substitute(method.getReturnType())); builder.setNavigationElement(method); builder.addModifier(PsiModifier.PUBLIC); final PsiTypeParameter[] typeParameters = method.getTypeParameters(); final PsiClass containingClass = method.getContainingClass(); boolean isRaw = containingClass != null && PsiUtil.isRawSubstitutor(containingClass, substitutor); if (isRaw) { substitutor = JavaPsiFacade.getInstance(method.getProject()) .getElementFactory() .createRawSubstitutor(substitutor, typeParameters); } if (!isRaw) { for (PsiTypeParameter typeParameter : typeParameters) { builder.addTypeParameter(typeParameter); } } final PsiParameter[] originalParameters = method.getParameterList().getParameters(); for (int i = 0; i < originalParameters.length; i++) { PsiParameter originalParameter = originalParameters[i]; PsiType type; if (isRaw) { type = TypeConversionUtil.erasure(substitutor.substitute(originalParameter.getType())); } else { type = substitutor.substitute(originalParameter.getType()); } if (type == null) { type = PsiType.getJavaLangObject(superClass.getManager(), superClass.getResolveScope()); } final LightParameter lightParameter = new LightParameter( StringUtil.notNullize(originalParameter.getName(), "p" + i), type, builder, JavaLanguage.INSTANCE); if (keepParameterAnnotations) { final PsiCompositeModifierList delegatingModifierList = new PsiCompositeModifierList( method.getManager(), Collections.singletonList(originalParameter.getModifierList())); lightParameter.setModifierList(delegatingModifierList); } builder.addParameter(lightParameter); } builder.setBaseIcon(JetgroovyIcons.Groovy.Method); return new DelegatedMethod(builder, method); }
private static void processPrimaryMethod( JavaChangeInfo changeInfo, PsiMethod method, PsiMethod baseMethod, boolean isOriginal) throws IncorrectOperationException { PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); if (changeInfo.isVisibilityChanged()) { PsiModifierList modifierList = method.getModifierList(); final String highestVisibility = isOriginal ? changeInfo.getNewVisibility() : VisibilityUtil.getHighestVisibility( changeInfo.getNewVisibility(), VisibilityUtil.getVisibilityModifier(modifierList)); VisibilityUtil.setVisibility(modifierList, highestVisibility); } if (changeInfo.isNameChanged()) { String newName = baseMethod == null ? changeInfo.getNewName() : RefactoringUtil.suggestNewOverriderName( method.getName(), baseMethod.getName(), changeInfo.getNewName()); if (newName != null && !newName.equals(method.getName())) { final PsiIdentifier nameId = method.getNameIdentifier(); assert nameId != null; nameId.replace( JavaPsiFacade.getInstance(method.getProject()) .getElementFactory() .createIdentifier(newName)); } } final PsiSubstitutor substitutor = baseMethod == null ? PsiSubstitutor.EMPTY : ChangeSignatureProcessor.calculateSubstitutor(method, baseMethod); if (changeInfo.isReturnTypeChanged()) { PsiType newTypeElement = changeInfo .getNewReturnType() .getType(changeInfo.getMethod().getParameterList(), method.getManager()); final PsiType returnType = substitutor.substitute(newTypeElement); // don't modify return type for non-Java overriders (EJB) if (method.getName().equals(changeInfo.getNewName())) { final PsiTypeElement typeElement = method.getReturnTypeElement(); if (typeElement != null) { typeElement.replace(factory.createTypeElement(returnType)); } } } PsiParameterList list = method.getParameterList(); PsiParameter[] parameters = list.getParameters(); final JavaParameterInfo[] parameterInfos = changeInfo.getNewParameters(); final int delta = baseMethod != null ? baseMethod.getParameterList().getParametersCount() - method.getParameterList().getParametersCount() : 0; PsiParameter[] newParms = new PsiParameter[Math.max(parameterInfos.length - delta, 0)]; final String[] oldParameterNames = changeInfo.getOldParameterNames(); final String[] oldParameterTypes = changeInfo.getOldParameterTypes(); for (int i = 0; i < newParms.length; i++) { JavaParameterInfo info = parameterInfos[i]; int index = info.getOldIndex(); if (index >= 0) { PsiParameter parameter = parameters[index]; newParms[i] = parameter; String oldName = oldParameterNames[index]; if (!oldName.equals(info.getName()) && oldName.equals(parameter.getName())) { PsiIdentifier newIdentifier = factory.createIdentifier(info.getName()); parameter.getNameIdentifier().replace(newIdentifier); } String oldType = oldParameterTypes[index]; if (!oldType.equals(info.getTypeText())) { parameter.normalizeDeclaration(); PsiType newType = substitutor.substitute( info.createType(changeInfo.getMethod().getParameterList(), method.getManager())); parameter.getTypeElement().replace(factory.createTypeElement(newType)); } } else { newParms[i] = createNewParameter(changeInfo, info, substitutor); } } resolveParameterVsFieldsConflicts(newParms, method, list, changeInfo.toRemoveParm()); fixJavadocsForChangedMethod(method, changeInfo, newParms.length); if (changeInfo.isExceptionSetOrOrderChanged()) { final PsiClassType[] newExceptions = getPrimaryChangedExceptionInfo(changeInfo); fixPrimaryThrowsLists(method, newExceptions); } }