@Override public boolean processUsage( ChangeInfo changeInfo, UsageInfo usageInfo, boolean beforeMethodChange, UsageInfo[] usages) { if (!(changeInfo instanceof JavaChangeInfo)) return false; PsiElement element = usageInfo.getElement(); if (element == null) return false; if (!GroovyLanguage.INSTANCE.equals(element.getLanguage())) return false; if (beforeMethodChange) { if (usageInfo instanceof OverriderUsageInfo) { processPrimaryMethodInner( ((JavaChangeInfo) changeInfo), (GrMethod) ((OverriderUsageInfo) usageInfo).getElement(), ((OverriderUsageInfo) usageInfo).getBaseMethod()); } } else { if (usageInfo instanceof GrMethodCallUsageInfo) { processMethodUsage( element, ((JavaChangeInfo) changeInfo), ((GrMethodCallUsageInfo) usageInfo).isToChangeArguments(), ((GrMethodCallUsageInfo) usageInfo).isToCatchExceptions(), ((GrMethodCallUsageInfo) usageInfo).getMapToArguments(), ((GrMethodCallUsageInfo) usageInfo).getSubstitutor()); return true; } else if (usageInfo instanceof DefaultConstructorImplicitUsageInfo) { processConstructor( (GrMethod) ((DefaultConstructorImplicitUsageInfo) usageInfo).getConstructor(), (JavaChangeInfo) changeInfo); return true; } else if (usageInfo instanceof NoConstructorClassUsageInfo) { processClassUsage( (GrTypeDefinition) ((NoConstructorClassUsageInfo) usageInfo).getPsiClass(), ((JavaChangeInfo) changeInfo)); return true; } else if (usageInfo instanceof ChangeSignatureParameterUsageInfo) { String newName = ((ChangeSignatureParameterUsageInfo) usageInfo).newParameterName; ((PsiReference) element).handleElementRename(newName); return true; } else { PsiReference ref = element.getReference(); if (ref != null && changeInfo.getMethod() != null) { ref.bindToElement(changeInfo.getMethod()); return true; } } } return false; }
@Override public boolean setupDefaultValues( ChangeInfo changeInfo, Ref<UsageInfo[]> refUsages, Project project) { if (!(changeInfo instanceof JavaChangeInfo)) return true; for (UsageInfo usageInfo : refUsages.get()) { if (usageInfo instanceof GrMethodCallUsageInfo) { GrMethodCallUsageInfo methodCallUsageInfo = (GrMethodCallUsageInfo) usageInfo; if (methodCallUsageInfo.isToChangeArguments()) { final PsiElement element = methodCallUsageInfo.getElement(); if (element == null) continue; final PsiMethod caller = RefactoringUtil.getEnclosingMethod(element); final boolean needDefaultValue = !((JavaChangeInfo) changeInfo).getMethodsToPropagateParameters().contains(caller); final PsiMethod referencedMethod = methodCallUsageInfo.getReferencedMethod(); if (needDefaultValue && (caller == null || referencedMethod == null || !MethodSignatureUtil.isSuperMethod(referencedMethod, caller))) { final ParameterInfo[] parameters = changeInfo.getNewParameters(); for (ParameterInfo parameter : parameters) { final String defaultValue = parameter.getDefaultValue(); if (defaultValue == null && parameter.getOldIndex() == -1) { ((ParameterInfoImpl) parameter).setDefaultValue(""); if (!ApplicationManager.getApplication().isUnitTestMode()) { final PsiType type = ((ParameterInfoImpl) parameter) .getTypeWrapper() .getType(element, element.getManager()); final DefaultValueChooser chooser = new DefaultValueChooser( project, parameter.getName(), PsiTypesUtil.getDefaultValueOfType(type)); chooser.show(); if (chooser.isOK()) { if (chooser.feelLucky()) { parameter.setUseAnySingleVariable(true); } else { ((ParameterInfoImpl) parameter).setDefaultValue(chooser.getDefaultValue()); } } else { return false; } } } } } } } } return true; }
private static PsiElement generateTryCatch(PsiElement element, PsiClassType[] exceptions) { if (exceptions.length == 0) return element; GrTryCatchStatement tryCatch = (GrTryCatchStatement) GroovyPsiElementFactory.getInstance(element.getProject()) .createStatementFromText("try{} catch (Exception e){}"); final GrStatement statement = PsiTreeUtil.getParentOfType(element, GrStatement.class); assert statement != null; tryCatch.getTryBlock().addStatementBefore(statement, null); tryCatch = (GrTryCatchStatement) statement.replace(tryCatch); tryCatch.getCatchClauses()[0].delete(); fixCatchBlock(tryCatch, exceptions); return tryCatch; }
private PsiMethod[] findSimpleUsagesWithoutParameters( final PsiMethod method, final ArrayList<UsageInfo> result, boolean isToModifyArgs, boolean isToThrowExceptions, boolean isOriginal) { GlobalSearchScope projectScope = GlobalSearchScope.projectScope(method.getProject()); PsiMethod[] overridingMethods = OverridingMethodsSearch.search(method, true).toArray(PsiMethod.EMPTY_ARRAY); for (PsiMethod overridingMethod : overridingMethods) { result.add( new OverriderUsageInfo( overridingMethod, method, isOriginal, isToModifyArgs, isToThrowExceptions)); } boolean needToChangeCalls = !myChangeInfo.isGenerateDelegate() && (myChangeInfo.isNameChanged() || myChangeInfo.isParameterSetOrOrderChanged() || myChangeInfo.isExceptionSetOrOrderChanged() || myChangeInfo.isVisibilityChanged() /*for checking inaccessible*/); if (needToChangeCalls) { int parameterCount = method.getParameterList().getParametersCount(); PsiReference[] refs = MethodReferencesSearch.search(method, projectScope, true) .toArray(PsiReference.EMPTY_ARRAY); for (PsiReference ref : refs) { PsiElement element = ref.getElement(); boolean isToCatchExceptions = isToThrowExceptions && needToCatchExceptions(RefactoringUtil.getEnclosingMethod(element)); if (!isToCatchExceptions) { if (RefactoringUtil.isMethodUsage(element)) { PsiExpressionList list = RefactoringUtil.getArgumentListByMethodReference(element); if (list == null || !method.isVarArgs() && list.getExpressions().length != parameterCount) continue; } } if (RefactoringUtil.isMethodUsage(element)) { result.add(new MethodCallUsageInfo(element, isToModifyArgs, isToCatchExceptions)); } else if (element instanceof PsiDocTagValue) { result.add(new UsageInfo(element)); } else if (element instanceof PsiMethod && ((PsiMethod) element).isConstructor()) { if (JavaLanguage.INSTANCE.equals(element.getLanguage())) { DefaultConstructorImplicitUsageInfo implicitUsageInfo = new DefaultConstructorImplicitUsageInfo( (PsiMethod) element, ((PsiMethod) element).getContainingClass(), method); result.add(implicitUsageInfo); } } else if (element instanceof PsiClass) { LOG.assertTrue(method.isConstructor()); final PsiClass psiClass = (PsiClass) element; if (JavaLanguage.INSTANCE.equals(psiClass.getLanguage())) { if (myChangeInfo instanceof JavaChangeInfo) { if (shouldPropagateToNonPhysicalMethod( method, result, psiClass, ((JavaChangeInfo) myChangeInfo).getMethodsToPropagateParameters())) { continue; } } result.add(new NoConstructorClassUsageInfo(psiClass)); } } else if (ref instanceof PsiCallReference) { result.add(new CallReferenceUsageInfo((PsiCallReference) ref)); } else { result.add(new MoveRenameUsageInfo(element, ref, method)); } } // if (method.isConstructor() && parameterCount == 0) { // RefactoringUtil.visitImplicitConstructorUsages(method.getContainingClass(), // new // DefaultConstructorUsageCollector(result)); // } } else if (myChangeInfo.isParameterTypesChanged()) { PsiReference[] refs = MethodReferencesSearch.search(method, projectScope, true) .toArray(PsiReference.EMPTY_ARRAY); for (PsiReference reference : refs) { final PsiElement element = reference.getElement(); if (element instanceof PsiDocTagValue) { result.add(new UsageInfo(reference)); } else if (element instanceof XmlElement) { result.add(new MoveRenameUsageInfo(reference, method)); } else if (element instanceof PsiMethodReferenceExpression) { result.add(new UsageInfo(reference)); } } } // Conflicts detectLocalsCollisionsInMethod(method, result, isOriginal); for (final PsiMethod overridingMethod : overridingMethods) { detectLocalsCollisionsInMethod(overridingMethod, result, isOriginal); } return overridingMethods; }
private static void processMethodUsage( PsiElement element, JavaChangeInfo changeInfo, boolean toChangeArguments, boolean toCatchExceptions, GrClosureSignatureUtil.ArgInfo<PsiElement>[] map, PsiSubstitutor substitutor) { if (map == null) return; if (changeInfo.isNameChanged()) { if (element instanceof GrReferenceElement) { element = ((GrReferenceElement) element).handleElementRename(changeInfo.getNewName()); } } if (toChangeArguments) { JavaParameterInfo[] parameters = changeInfo.getNewParameters(); GrArgumentList argumentList = PsiUtil.getArgumentsList(element); GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(element.getProject()); if (argumentList == null) { if (element instanceof GrEnumConstant) { argumentList = factory.createArgumentList(); argumentList = (GrArgumentList) element.add(argumentList); } else { return; } } Set<PsiElement> argsToDelete = new HashSet<PsiElement>(map.length * 2); for (GrClosureSignatureUtil.ArgInfo<PsiElement> argInfo : map) { argsToDelete.addAll(argInfo.args); } for (JavaParameterInfo parameter : parameters) { int index = parameter.getOldIndex(); if (index >= 0) { argsToDelete.removeAll(map[index].args); } } for (PsiElement arg : argsToDelete) { arg.delete(); } boolean skipOptionals = false; PsiElement anchor = null; // PsiTreeUtil.getChildOfAnyType(argumentList, GrExpression.class, // GrNamedArgument.class); for (int i = 0; i < parameters.length; i++) { JavaParameterInfo parameter = parameters[i]; int index = parameter.getOldIndex(); if (index >= 0) { GrClosureSignatureUtil.ArgInfo<PsiElement> argInfo = map[index]; List<PsiElement> arguments = argInfo.args; if (argInfo.isMultiArg) { // arguments for Map and varArg if ((i != 0 || !(!arguments.isEmpty() && arguments.iterator().next() instanceof GrNamedArgument)) && (i != parameters.length - 1 || !parameter.isVarargType())) { final PsiType type = parameter.createType( changeInfo.getMethod().getParameterList(), argumentList.getManager()); final GrExpression arg = GroovyRefactoringUtil.generateArgFromMultiArg( substitutor, arguments, type, element.getProject()); for (PsiElement argument : arguments) { argument.delete(); } anchor = argumentList.addAfter(arg, anchor); JavaCodeStyleManager.getInstance(anchor.getProject()).shortenClassReferences(anchor); } } else { // arguments for simple parameters if (arguments.size() == 1) { // arg exists PsiElement arg = arguments.iterator().next(); if (i == parameters.length - 1 && parameter.isVarargType()) { if (arg instanceof GrSafeCastExpression) { PsiElement expr = ((GrSafeCastExpression) arg).getOperand(); if (expr instanceof GrListOrMap && !((GrListOrMap) expr).isMap()) { final PsiElement copy = expr.copy(); PsiElement[] newVarargs = ((GrListOrMap) copy).getInitializers(); for (PsiElement vararg : newVarargs) { anchor = argumentList.addAfter(vararg, anchor); } arg.delete(); continue; } } } PsiElement curArg = getNextOfType(argumentList, anchor, GrExpression.class); if (curArg == arg) { anchor = arg; } else { final PsiElement copy = arg.copy(); anchor = argumentList.addAfter(copy, anchor); arg.delete(); } } else { // arg is skipped. Parameter is optional skipOptionals = true; } } } else { if (skipOptionals && isParameterOptional(parameter)) continue; if (forceOptional(parameter)) { skipOptionals = true; continue; } try { GrExpression value = createDefaultValue(factory, changeInfo, parameter, argumentList); if (i > 0 && (value == null || anchor == null)) { PsiElement comma = Factory.createSingleLeafElement( GroovyTokenTypes.mCOMMA, ",", 0, 1, SharedImplUtil.findCharTableByTree(argumentList.getNode()), argumentList.getManager()) .getPsi(); if (anchor == null) anchor = argumentList.getLeftParen(); anchor = argumentList.addAfter(comma, anchor); } if (value != null) { anchor = argumentList.addAfter(value, anchor); } } catch (IncorrectOperationException e) { LOG.error(e.getMessage()); } } } GrCall call = GroovyRefactoringUtil.getCallExpressionByMethodReference(element); if (argumentList.getText().trim().isEmpty() && (call == null || !PsiImplUtil.hasClosureArguments(call))) { argumentList = argumentList.replaceWithArgumentList(factory.createArgumentList()); } CodeStyleManager.getInstance(argumentList.getProject()).reformat(argumentList); } if (toCatchExceptions) { final ThrownExceptionInfo[] exceptionInfos = changeInfo.getNewExceptions(); PsiClassType[] exceptions = getExceptions(exceptionInfos, element, element.getManager()); fixExceptions(element, exceptions); } }