@Override public int compare(PsiVariable o1, PsiVariable o2) { if (o1 instanceof PsiParameter && ((PsiParameter) o1).isVarArgs()) return 1; if (o2 instanceof PsiParameter && ((PsiParameter) o2).isVarArgs()) return -1; if (o1 instanceof PsiField && o2 instanceof PsiField) { return o1.getTextOffset() - o2.getTextOffset(); } if (o1 instanceof PsiParameter && o2 instanceof PsiParameter) { return myParameterList.getParameterIndex((PsiParameter) o1) - myParameterList.getParameterIndex((PsiParameter) o2); } if (o1 instanceof PsiField && o2 instanceof PsiParameter) { final PsiField field = FieldFromParameterUtils.getParameterAssignedToField((PsiParameter) o2); if (field == null) return 1; return o1.getTextOffset() - field.getTextOffset(); } if (o1 instanceof PsiParameter && o2 instanceof PsiField) { final PsiField field = FieldFromParameterUtils.getParameterAssignedToField((PsiParameter) o1); if (field == null) return -1; return field.getTextOffset() - o2.getTextOffset(); } return 0; }
private static PsiParameter createNewParameter( JavaChangeInfo changeInfo, JavaParameterInfo newParm, PsiSubstitutor substitutor) throws IncorrectOperationException { final PsiParameterList list = changeInfo.getMethod().getParameterList(); final PsiElementFactory factory = JavaPsiFacade.getInstance(list.getProject()).getElementFactory(); final PsiType type = substitutor.substitute(newParm.createType(list, list.getManager())); return factory.createParameter(newParm.getName(), type); }
private static boolean usesDefaultClone(PsiClass aClass) { final Project project = aClass.getProject(); final PsiManager manager = aClass.getManager(); final GlobalSearchScope scope = GlobalSearchScope.allScope(project); final PsiClass cloneable = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.lang.Cloneable", scope); if (!InheritanceUtil.isInheritorOrSelf(aClass, cloneable, true)) { return false; } final PsiMethod[] methods = aClass.findMethodsByName("clone", false); for (PsiMethod method : methods) { final PsiParameterList parameterList = method.getParameterList(); final PsiParameter[] parameters = parameterList.getParameters(); if (parameters.length == 0) { return false; } } return true; }
public JLabel getPopupEntryText(RearrangerSettings settings) { StringBuffer name = new StringBuffer(80); PsiMethod m = (PsiMethod) myEnd; if (m.getReturnTypeElement() != null && !settings.isShowTypeAfterMethod()) { name.append(m.getReturnTypeElement().getText()); name.append(' '); } name.append(m.getName()); PsiParameterList plist = m.getParameterList(); if (settings.isShowParameterNames() || settings.isShowParameterTypes()) { if (plist != null) { name.append("("); for (int i = 0; i < plist.getParameters().length; i++) { if (i > 0) { name.append(", "); } if (settings.isShowParameterTypes()) { String modifiers = plist.getParameters()[i].getModifierList().getText(); if (modifiers.length() > 0) { name.append(modifiers); name.append(' '); } name.append(plist.getParameters()[i].getTypeElement().getText()); if (settings.isShowParameterNames()) { name.append(' '); } } if (settings.isShowParameterNames()) { name.append(plist.getParameters()[i].getName()); } } name.append(")"); } } if (m.getReturnTypeElement() != null && settings.isShowTypeAfterMethod()) { name.append(": "); name.append(m.getReturnTypeElement().getText()); } return new JLabel(name.toString()); }
private static boolean usesDefaultSerialization(PsiClass aClass) { final Project project = aClass.getProject(); final PsiManager manager = aClass.getManager(); final GlobalSearchScope scope = GlobalSearchScope.allScope(project); final PsiClass serializable = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.io.Serializable", scope); if (!InheritanceUtil.isInheritorOrSelf(aClass, serializable, true)) { return false; } final PsiMethod[] methods = aClass.findMethodsByName("writeObject", false); for (PsiMethod method : methods) { final PsiParameterList parameterList = method.getParameterList(); final PsiParameter[] parameters = parameterList.getParameters(); if (parameters.length == 1) { final PsiType type = parameters[0].getType(); final String text = type.getCanonicalText(); if ("java.io.DataOutputStream".equals(text)) { return false; } } } return true; }
private static void resolveParameterVsFieldsConflicts( final PsiParameter[] newParms, final PsiMethod method, final PsiParameterList list, boolean[] toRemoveParm) throws IncorrectOperationException { List<FieldConflictsResolver> conflictResolvers = new ArrayList<FieldConflictsResolver>(); for (PsiParameter parameter : newParms) { conflictResolvers.add(new FieldConflictsResolver(parameter.getName(), method.getBody())); } ChangeSignatureUtil.synchronizeList( list, Arrays.asList(newParms), ParameterList.INSTANCE, toRemoveParm); JavaCodeStyleManager.getInstance(list.getProject()).shortenClassReferences(list); for (FieldConflictsResolver fieldConflictsResolver : conflictResolvers) { fieldConflictsResolver.fix(); } }
private void tryToMoveInitializers( PsiMethod constructor, HashSet<PsiMethod> subConstructors, LinkedHashSet<PsiField> movedFields) throws IncorrectOperationException { final LinkedHashMap<PsiField, Initializer> fieldsToInitializers = new LinkedHashMap<PsiField, Initializer>(); boolean anyFound = false; for (PsiField field : movedFields) { PsiStatement commonInitializer = null; final ArrayList<PsiElement> fieldInitializersToRemove = new ArrayList<PsiElement>(); for (PsiMethod subConstructor : subConstructors) { commonInitializer = hasCommonInitializer( commonInitializer, subConstructor, field, fieldInitializersToRemove); if (commonInitializer == null) break; } if (commonInitializer != null) { final ParametersAndMovedFieldsUsedCollector visitor = new ParametersAndMovedFieldsUsedCollector(movedFields); commonInitializer.accept(visitor); fieldsToInitializers.put( field, new Initializer( commonInitializer, visitor.getUsedFields(), visitor.getUsedParameters(), fieldInitializersToRemove)); anyFound = true; } } if (!anyFound) return; { final Set<PsiField> initializedFields = fieldsToInitializers.keySet(); Set<PsiField> unmovable = RefactoringUtil.transitiveClosure( new RefactoringUtil.Graph<PsiField>() { public Set<PsiField> getVertices() { return initializedFields; } public Set<PsiField> getTargets(PsiField source) { return fieldsToInitializers.get(source).movedFieldsUsed; } }, new Condition<PsiField>() { public boolean value(PsiField object) { return !initializedFields.contains(object); } }); for (PsiField psiField : unmovable) { fieldsToInitializers.remove(psiField); } } final PsiElementFactory factory = JavaPsiFacade.getElementFactory(myProject); if (constructor == null) { constructor = (PsiMethod) myTargetSuperClass.add(factory.createConstructor()); final String visibilityModifier = VisibilityUtil.getVisibilityModifier(myTargetSuperClass.getModifierList()); PsiUtil.setModifierProperty(constructor, visibilityModifier, true); } ArrayList<PsiField> initializedFields = new ArrayList<PsiField>(fieldsToInitializers.keySet()); Collections.sort( initializedFields, new Comparator<PsiField>() { public int compare(PsiField field1, PsiField field2) { Initializer i1 = fieldsToInitializers.get(field1); Initializer i2 = fieldsToInitializers.get(field2); if (i1.movedFieldsUsed.contains(field2)) return 1; if (i2.movedFieldsUsed.contains(field1)) return -1; return 0; } }); for (final PsiField initializedField : initializedFields) { Initializer initializer = fieldsToInitializers.get(initializedField); // correct constructor parameters and subConstructors super calls final PsiParameterList parameterList = constructor.getParameterList(); for (final PsiParameter parameter : initializer.usedParameters) { parameterList.add(parameter); } for (final PsiMethod subConstructor : subConstructors) { modifySuperCall(subConstructor, initializer.usedParameters); } PsiStatement assignmentStatement = (PsiStatement) constructor.getBody().add(initializer.initializer); PsiManager manager = PsiManager.getInstance(myProject); ChangeContextUtil.decodeContextInfo( assignmentStatement, myTargetSuperClass, RefactoringChangeUtil.createThisExpression(manager, null)); for (PsiElement psiElement : initializer.statementsToRemove) { psiElement.delete(); } } }
private static boolean addParameterToConstructor( final Project project, final PsiFile file, final Editor editor, final PsiMethod constructor, final PsiField[] fields) throws IncorrectOperationException { final PsiParameterList parameterList = constructor.getParameterList(); final PsiParameter[] parameters = parameterList.getParameters(); ParameterInfoImpl[] newParamInfos = new ParameterInfoImpl[parameters.length + fields.length]; final List<PsiVariable> params = new ArrayList<PsiVariable>(Arrays.asList(parameters)); Collections.addAll(params, fields); Collections.sort(params, new FieldParameterComparator(parameterList)); int i = 0; final HashMap<PsiField, String> usedFields = new HashMap<PsiField, String>(); for (PsiVariable param : params) { final PsiType paramType = param.getType(); if (param instanceof PsiParameter) { newParamInfos[i++] = new ParameterInfoImpl( parameterList.getParameterIndex((PsiParameter) param), param.getName(), paramType, param.getName()); } else { final String uniqueParameterName = getUniqueParameterName(parameters, param, usedFields); usedFields.put((PsiField) param, uniqueParameterName); newParamInfos[i++] = new ParameterInfoImpl(-1, uniqueParameterName, paramType, uniqueParameterName); } } final SmartPointerManager manager = SmartPointerManager.getInstance(project); final SmartPsiElementPointer constructorPointer = manager.createSmartPsiElementPointer(constructor); final PsiMethod fromText = JavaPsiFacade.getElementFactory(project) .createMethodFromText(createDummyMethod(constructor, newParamInfos), constructor); final PsiClass containingClass = constructor.getContainingClass(); if (containingClass == null) return false; final int minUsagesNumber = containingClass.findMethodsBySignature(fromText, false).length > 0 ? 0 : 1; final List<ParameterInfoImpl> parameterInfos = ChangeMethodSignatureFromUsageFix.performChange( project, editor, file, constructor, minUsagesNumber, newParamInfos, true, true); final ParameterInfoImpl[] resultParams = parameterInfos != null ? parameterInfos.toArray(new ParameterInfoImpl[parameterInfos.size()]) : newParamInfos; return ApplicationManager.getApplication() .runWriteAction( new Computable<Boolean>() { @Override public Boolean compute() { return doCreate( project, editor, parameters, constructorPointer, resultParams, usedFields); } }); }
public List<PsiParameter> getChildren(PsiParameterList psiParameterList) { return Arrays.asList(psiParameterList.getParameters()); }
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); } }
public void inlineElement( final Project project, final Editor editor, final PsiElement psiElement) { final PsiParameter psiParameter = (PsiParameter) psiElement; final PsiParameterList parameterList = (PsiParameterList) psiParameter.getParent(); if (!(parameterList.getParent() instanceof PsiMethod)) { return; } final int index = parameterList.getParameterIndex(psiParameter); final PsiMethod method = (PsiMethod) parameterList.getParent(); String errorMessage = getCannotInlineMessage(psiParameter, method); if (errorMessage != null) { CommonRefactoringUtil.showErrorHint( project, editor, errorMessage, RefactoringBundle.message("inline.parameter.refactoring"), null); return; } final Ref<PsiExpression> refInitializer = new Ref<PsiExpression>(); final Ref<PsiExpression> refConstantInitializer = new Ref<PsiExpression>(); final Ref<PsiCallExpression> refMethodCall = new Ref<PsiCallExpression>(); final List<PsiReference> occurrences = Collections.synchronizedList(new ArrayList<PsiReference>()); final Collection<PsiFile> containingFiles = Collections.synchronizedSet(new HashSet<PsiFile>()); containingFiles.add(psiParameter.getContainingFile()); boolean result = ReferencesSearch.search(method) .forEach( new Processor<PsiReference>() { public boolean process(final PsiReference psiReference) { PsiElement element = psiReference.getElement(); final PsiElement parent = element.getParent(); if (parent instanceof PsiCallExpression) { final PsiCallExpression methodCall = (PsiCallExpression) parent; occurrences.add(psiReference); containingFiles.add(element.getContainingFile()); final PsiExpression[] expressions = methodCall.getArgumentList().getExpressions(); if (expressions.length <= index) return false; PsiExpression argument = expressions[index]; if (!refInitializer.isNull()) { return argument != null && PsiEquivalenceUtil.areElementsEquivalent( refInitializer.get(), argument) && PsiEquivalenceUtil.areElementsEquivalent( refMethodCall.get(), methodCall); } if (InlineToAnonymousConstructorProcessor.isConstant(argument) || getReferencedFinalField(argument) != null) { if (refConstantInitializer.isNull()) { refConstantInitializer.set(argument); } else if (!isSameConstant(argument, refConstantInitializer.get())) { return false; } } else if (!isRecursiveReferencedParameter(argument, psiParameter)) { if (!refConstantInitializer.isNull()) return false; refInitializer.set(argument); refMethodCall.set(methodCall); } } return true; } }); final int offset = editor.getCaretModel().getOffset(); final PsiElement refExpr = psiElement.getContainingFile().findElementAt(offset); final PsiCodeBlock codeBlock = PsiTreeUtil.getParentOfType(refExpr, PsiCodeBlock.class); if (codeBlock != null) { final PsiElement[] defs = DefUseUtil.getDefs(codeBlock, psiParameter, refExpr); if (defs.length == 1) { final PsiElement def = defs[0]; if (def instanceof PsiReferenceExpression && PsiUtil.isOnAssignmentLeftHand((PsiExpression) def)) { final PsiExpression rExpr = ((PsiAssignmentExpression) def.getParent()).getRExpression(); if (rExpr != null) { final PsiElement[] refs = DefUseUtil.getRefs(codeBlock, psiParameter, refExpr); if (InlineLocalHandler.checkRefsInAugmentedAssignmentOrUnaryModified(refs, def) == null) { new WriteCommandAction(project) { @Override protected void run(Result result) throws Throwable { for (final PsiElement ref : refs) { InlineUtil.inlineVariable( psiParameter, rExpr, (PsiJavaCodeReferenceElement) ref); } def.getParent().delete(); } }.execute(); return; } } } } } if (occurrences.isEmpty()) { CommonRefactoringUtil.showErrorHint( project, editor, "Method has no usages", RefactoringBundle.message("inline.parameter.refactoring"), null); return; } if (!result) { CommonRefactoringUtil.showErrorHint( project, editor, "Cannot find constant initializer for parameter", RefactoringBundle.message("inline.parameter.refactoring"), null); return; } if (!refInitializer.isNull()) { if (ApplicationManager.getApplication().isUnitTestMode()) { final InlineParameterExpressionProcessor processor = new InlineParameterExpressionProcessor( refMethodCall.get(), method, psiParameter, refInitializer.get(), method .getProject() .getUserData(InlineParameterExpressionProcessor.CREATE_LOCAL_FOR_TESTS)); processor.run(); } else { final boolean createLocal = ReferencesSearch.search(psiParameter).findAll().size() > 1; InlineParameterDialog dlg = new InlineParameterDialog( refMethodCall.get(), method, psiParameter, refInitializer.get(), createLocal); dlg.show(); } return; } if (refConstantInitializer.isNull()) { CommonRefactoringUtil.showErrorHint( project, editor, "Cannot find constant initializer for parameter", RefactoringBundle.message("inline.parameter.refactoring"), null); return; } final Ref<Boolean> isNotConstantAccessible = new Ref<Boolean>(); final PsiExpression constantExpression = refConstantInitializer.get(); constantExpression.accept( new JavaRecursiveElementVisitor() { @Override public void visitReferenceExpression(PsiReferenceExpression expression) { super.visitReferenceExpression(expression); final PsiElement resolved = expression.resolve(); if (resolved instanceof PsiMember && !PsiUtil.isAccessible((PsiMember) resolved, method, null)) { isNotConstantAccessible.set(Boolean.TRUE); } } }); if (!isNotConstantAccessible.isNull() && isNotConstantAccessible.get()) { CommonRefactoringUtil.showErrorHint( project, editor, "Constant initializer is not accessible in method body", RefactoringBundle.message("inline.parameter.refactoring"), null); return; } for (PsiReference psiReference : ReferencesSearch.search(psiParameter)) { final PsiElement element = psiReference.getElement(); if (element instanceof PsiExpression && PsiUtil.isAccessedForWriting((PsiExpression) element)) { CommonRefactoringUtil.showErrorHint( project, editor, "Inline parameter which has write usages is not supported", RefactoringBundle.message("inline.parameter.refactoring"), null); return; } } if (!ApplicationManager.getApplication().isUnitTestMode()) { String occurencesString = RefactoringBundle.message("occurences.string", occurrences.size()); String question = RefactoringBundle.message( "inline.parameter.confirmation", psiParameter.getName(), constantExpression.getText()) + " " + occurencesString; RefactoringMessageDialog dialog = new RefactoringMessageDialog( REFACTORING_NAME, question, HelpID.INLINE_VARIABLE, "OptionPane.questionIcon", true, project); dialog.show(); if (!dialog.isOK()) { return; } } final RefactoringEventData data = new RefactoringEventData(); data.addElement(psiElement.copy()); project .getMessageBus() .syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC) .refactoringStarted(REFACTORING_ID, data); SameParameterValueInspection.InlineParameterValueFix.inlineSameParameterValue( method, psiParameter, constantExpression); project .getMessageBus() .syncPublisher(RefactoringEventListener.REFACTORING_EVENT_TOPIC) .refactoringDone(REFACTORING_ID, null); }
private void addTypesByVariable( HashSet<PsiType> typesSet, PsiVariable var, PsiFile scopeFile, HashSet<PsiVariable> checkedVariables, int flags, TextRange rangeToIgnore) { if (!checkedVariables.add(var)) return; // System.out.println("analyzing usages of " + var + " in file " + scopeFile); SearchScope searchScope = new LocalSearchScope(scopeFile); if (BitUtil.isSet(flags, CHECK_USAGE) || BitUtil.isSet(flags, CHECK_DOWN)) { for (PsiReference varRef : ReferencesSearch.search(var, searchScope, false)) { PsiElement ref = varRef.getElement(); if (BitUtil.isSet(flags, CHECK_USAGE)) { PsiType type = guessElementTypeFromReference(myMethodPatternMap, ref, rangeToIgnore); if (type != null && !(type instanceof PsiPrimitiveType)) { typesSet.add(type); } } if (BitUtil.isSet(flags, CHECK_DOWN)) { if (ref.getParent() instanceof PsiExpressionList && ref.getParent().getParent() instanceof PsiMethodCallExpression) { // TODO : new PsiExpressionList list = (PsiExpressionList) ref.getParent(); PsiExpression[] args = list.getExpressions(); int argIndex = -1; for (int j = 0; j < args.length; j++) { PsiExpression arg = args[j]; if (arg.equals(ref)) { argIndex = j; break; } } PsiMethodCallExpression methodCall = (PsiMethodCallExpression) list.getParent(); PsiMethod method = (PsiMethod) methodCall.getMethodExpression().resolve(); if (method != null) { PsiParameter[] parameters = method.getParameterList().getParameters(); if (argIndex < parameters.length) { addTypesByVariable( typesSet, parameters[argIndex], method.getContainingFile(), checkedVariables, flags | CHECK_USAGE, rangeToIgnore); } } } } } } if (BitUtil.isSet(flags, CHECK_UP)) { if (var instanceof PsiParameter && var.getParent() instanceof PsiParameterList && var.getParent().getParent() instanceof PsiMethod) { PsiParameterList list = (PsiParameterList) var.getParent(); PsiParameter[] parameters = list.getParameters(); int argIndex = -1; for (int i = 0; i < parameters.length; i++) { PsiParameter parameter = parameters[i]; if (parameter.equals(var)) { argIndex = i; break; } } PsiMethod method = (PsiMethod) var.getParent().getParent(); // System.out.println("analyzing usages of " + method + " in file " + scopeFile); for (PsiReference methodRef : ReferencesSearch.search(method, searchScope, false)) { PsiElement ref = methodRef.getElement(); if (ref.getParent() instanceof PsiMethodCallExpression) { PsiMethodCallExpression methodCall = (PsiMethodCallExpression) ref.getParent(); PsiExpression[] args = methodCall.getArgumentList().getExpressions(); if (args.length <= argIndex) continue; PsiExpression arg = args[argIndex]; if (arg instanceof PsiReferenceExpression) { PsiElement refElement = ((PsiReferenceExpression) arg).resolve(); if (refElement instanceof PsiVariable) { addTypesByVariable( typesSet, (PsiVariable) refElement, scopeFile, checkedVariables, flags | CHECK_USAGE, rangeToIgnore); } } // TODO : constructor } } } } }