private static String compoundLambdaOrMethodReference( PsiParameter parameter, PsiExpression expression, String samQualifiedName, PsiType[] samParamTypes) { String result = ""; final Project project = parameter.getProject(); final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); final PsiClass functionClass = psiFacade.findClass(samQualifiedName, GlobalSearchScope.allScope(project)); for (int i = 0; i < samParamTypes.length; i++) { if (samParamTypes[i] instanceof PsiPrimitiveType) { samParamTypes[i] = ((PsiPrimitiveType) samParamTypes[i]).getBoxedType(expression); } } final PsiClassType functionalInterfaceType = functionClass != null ? psiFacade.getElementFactory().createType(functionClass, samParamTypes) : null; final PsiParameter[] parameters = {parameter}; final String methodReferenceText = LambdaCanBeMethodReferenceInspection.convertToMethodReference( expression, parameters, functionalInterfaceType, null); if (methodReferenceText != null) { LOG.assertTrue(functionalInterfaceType != null); result += "(" + functionalInterfaceType.getCanonicalText() + ")" + methodReferenceText; } else { result += parameter.getName() + " -> " + expression.getText(); } return result; }
@Nullable private static PsiType getFunctionalType( int functionalTypeIdx, @NotNull CandidateInfo candidateInfo) { final PsiMethod psiMethod = (PsiMethod) candidateInfo.getElement(); LOG.assertTrue(true); final PsiParameter[] methodParameters = psiMethod.getParameterList().getParameters(); if (methodParameters.length == 0) return null; final PsiParameter param = functionalTypeIdx < methodParameters.length ? methodParameters[functionalTypeIdx] : methodParameters[methodParameters.length - 1]; return ((MethodCandidateInfo) candidateInfo).getSiteSubstitutor().substitute(param.getType()); }
private static PsiAnnotation[] getHierarchyAnnotations( PsiModifierListOwner listOwner, PsiModifierList modifierList) { final Set<PsiAnnotation> all = new HashSet<PsiAnnotation>() { public boolean add(PsiAnnotation o) { // don't overwrite "higher level" annotations return !contains(o) && super.add(o); } }; if (listOwner instanceof PsiMethod) { ContainerUtil.addAll(all, modifierList.getAnnotations()); SuperMethodsSearch.search((PsiMethod) listOwner, null, true, true) .forEach( new Processor<MethodSignatureBackedByPsiMethod>() { public boolean process(final MethodSignatureBackedByPsiMethod superMethod) { ContainerUtil.addAll( all, superMethod.getMethod().getModifierList().getAnnotations()); return true; } }); return all.toArray(new PsiAnnotation[all.size()]); } if (listOwner instanceof PsiParameter) { PsiParameter parameter = (PsiParameter) listOwner; PsiElement declarationScope = parameter.getDeclarationScope(); PsiParameterList parameterList; if (declarationScope instanceof PsiMethod && parameter.getParent() == (parameterList = ((PsiMethod) declarationScope).getParameterList())) { PsiMethod method = (PsiMethod) declarationScope; final int parameterIndex = parameterList.getParameterIndex(parameter); ContainerUtil.addAll(all, modifierList.getAnnotations()); SuperMethodsSearch.search(method, null, true, true) .forEach( new Processor<MethodSignatureBackedByPsiMethod>() { public boolean process(final MethodSignatureBackedByPsiMethod superMethod) { PsiParameter superParameter = superMethod.getMethod().getParameterList().getParameters()[parameterIndex]; PsiModifierList modifierList = superParameter.getModifierList(); if (modifierList != null) { ContainerUtil.addAll(all, modifierList.getAnnotations()); } return true; } }); return all.toArray(new PsiAnnotation[all.size()]); } } return modifierList.getAnnotations(); }
public static PsiType getLambdaParameterType(PsiParameter param) { final PsiElement paramParent = param.getParent(); if (paramParent instanceof PsiParameterList) { final int parameterIndex = ((PsiParameterList) paramParent).getParameterIndex(param); if (parameterIndex > -1) { final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(param, PsiLambdaExpression.class); if (lambdaExpression != null) { PsiType type = getFunctionalInterfaceType(lambdaExpression, true, parameterIndex); if (type == null) { type = getFunctionalInterfaceType(lambdaExpression, false); } if (type instanceof PsiIntersectionType) { final PsiType[] conjuncts = ((PsiIntersectionType) type).getConjuncts(); for (PsiType conjunct : conjuncts) { final PsiType lambdaParameterFromType = getLambdaParameterFromType(parameterIndex, lambdaExpression, conjunct); if (lambdaParameterFromType != null) return lambdaParameterFromType; } } else { final PsiType lambdaParameterFromType = getLambdaParameterFromType(parameterIndex, lambdaExpression, type); if (lambdaParameterFromType != null) { return lambdaParameterFromType; } } } } } return new PsiLambdaParameterType(param); }
private static PsiType getNormalizedType(PsiParameter parameter) { final PsiType type = parameter.getType(); if (type instanceof PsiEllipsisType) { return ((PsiEllipsisType) type).getComponentType(); } return type; }
private static void fixExceptions(PsiElement ref, PsiClassType[] newExceptions) throws IncorrectOperationException { // methods' throws lists are already modified, may use ExceptionUtil.collectUnhandledExceptions newExceptions = filterCheckedExceptions(newExceptions); PsiElement context = PsiTreeUtil.getParentOfType(ref, PsiTryStatement.class, PsiMethod.class); if (context instanceof PsiTryStatement) { PsiTryStatement tryStatement = (PsiTryStatement) context; PsiCodeBlock tryBlock = tryStatement.getTryBlock(); // Remove unused catches Collection<PsiClassType> classes = ExceptionUtil.collectUnhandledExceptions(tryBlock, tryBlock); PsiParameter[] catchParameters = tryStatement.getCatchBlockParameters(); for (PsiParameter parameter : catchParameters) { final PsiType caughtType = parameter.getType(); if (!(caughtType instanceof PsiClassType)) continue; if (ExceptionUtil.isUncheckedExceptionOrSuperclass((PsiClassType) caughtType)) continue; if (!isCatchParameterRedundant((PsiClassType) caughtType, classes)) continue; parameter.getParent().delete(); // delete catch section } PsiClassType[] exceptionsToAdd = filterUnhandledExceptions(newExceptions, tryBlock); addExceptions(exceptionsToAdd, tryStatement); adjustPossibleEmptyTryStatement(tryStatement); } else { newExceptions = filterUnhandledExceptions(newExceptions, ref); if (newExceptions.length > 0) { // Add new try statement PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(ref.getProject()); PsiTryStatement tryStatement = (PsiTryStatement) elementFactory.createStatementFromText("try {} catch (Exception e) {}", null); PsiStatement anchor = PsiTreeUtil.getParentOfType(ref, PsiStatement.class); LOG.assertTrue(anchor != null); tryStatement.getTryBlock().add(anchor); tryStatement = (PsiTryStatement) anchor.getParent().addAfter(tryStatement, anchor); addExceptions(newExceptions, tryStatement); anchor.delete(); tryStatement.getCatchSections()[0].delete(); // Delete dummy catch section } } }
private static PsiClassType createDefaultConsumerType(Project project, PsiParameter parameter) { final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); final PsiClass consumerClass = psiFacade.findClass("java.util.function.Consumer", GlobalSearchScope.allScope(project)); return consumerClass != null ? psiFacade.getElementFactory().createType(consumerClass, parameter.getType()) : null; }
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(); } }
public static boolean isMethodParameterAnnotatedWith( final PsiMethod method, final int idx, @Nullable Collection<PsiMethod> processed, final String annFqn, @Nullable Map<String, Object> annotationAttributeValues, @Nullable final Set<PsiModifierListOwner> nonNlsTargets) { if (processed != null) { if (processed.contains(method)) return false; } else { processed = new THashSet<PsiMethod>(); } processed.add(method); final PsiParameter[] params = method.getParameterList().getParameters(); PsiParameter param; if (idx >= params.length) { if (params.length == 0) { return false; } PsiParameter lastParam = params[params.length - 1]; if (lastParam.isVarArgs()) { param = lastParam; } else { return false; } } else { param = params[idx]; } final PsiAnnotation annotation = AnnotationUtil.findAnnotation(param, annFqn); if (annotation != null) { return processAnnotationAttributes(annotationAttributeValues, annotation); } if (nonNlsTargets != null) { nonNlsTargets.add(param); } final PsiMethod[] superMethods = method.findSuperMethods(); for (PsiMethod superMethod : superMethods) { if (isMethodParameterAnnotatedWith( superMethod, idx, processed, annFqn, annotationAttributeValues, null)) return true; } return false; }
private static void checkCall( @NotNull PsiCallExpression methodCall, @NotNull ProblemsHolder holder) { PsiMethod method = methodCall.resolveMethod(); if (method == null) return; PsiParameter[] parameters = method.getParameterList().getParameters(); PsiExpression[] arguments = methodCall.getArgumentList().getExpressions(); for (int i = 0; i < parameters.length; i++) { PsiParameter parameter = parameters[i]; AllowedValues values = getAllowedValues(parameter, parameter.getType(), null); if (values == null) continue; if (i >= arguments.length) break; PsiExpression argument = arguments[i]; argument = PsiUtil.deparenthesizeExpression(argument); if (argument == null) continue; checkMagicParameterArgument(parameter, argument, values, holder); } }
private static void checkMagicParameterArgument( @NotNull PsiParameter parameter, PsiExpression argument, @NotNull AllowedValues allowedValues, @NotNull ProblemsHolder holder) { final PsiManager manager = PsiManager.getInstance(holder.getProject()); if (!argument.getTextRange().isEmpty() && !isAllowed(parameter.getDeclarationScope(), argument, allowedValues, manager)) { registerProblem(argument, allowedValues, holder); } }
private static String createMapperFunctionalExpressionText( PsiParameter parameter, PsiExpression expression) { String iteration = ""; if (!isIdentityMapping(parameter, expression)) { iteration += ".map("; iteration += compoundLambdaOrMethodReference( parameter, expression, "java.util.function.Function", new PsiType[] {parameter.getType(), expression.getType()}); iteration += ")"; } return iteration; }
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 static boolean isTrivial(PsiStatement body, PsiParameter parameter) { final PsiIfStatement ifStatement = extractIfStatement(body); // filter if (ifStatement != null) { return false; } // method reference final PsiCallExpression callExpression = LambdaCanBeMethodReferenceInspection.canBeMethodReferenceProblem( body instanceof PsiBlockStatement ? ((PsiBlockStatement) body).getCodeBlock() : body, new PsiParameter[] {parameter}, createDefaultConsumerType(parameter.getProject(), parameter)); if (callExpression == null) { return true; } final PsiMethod method = callExpression.resolveMethod(); return method != null && isThrowsCompatible(method); }
private static String createForEachFunctionalExpressionText( Project project, PsiStatement body, PsiParameter parameter) { final PsiCallExpression callExpression = LambdaCanBeMethodReferenceInspection.extractMethodCallFromBlock(body); if (callExpression != null) { final PsiClassType functionalType = createDefaultConsumerType(project, parameter); final PsiParameter[] parameters = {parameter}; final PsiElement bodyBlock = body instanceof PsiBlockStatement ? ((PsiBlockStatement) body).getCodeBlock() : body; final String methodReferenceText = LambdaCanBeMethodReferenceInspection.convertToMethodReference( bodyBlock, parameters, functionalType, null); if (methodReferenceText != null) { return methodReferenceText; } } return parameter.getName() + " -> " + wrapInBlock(body); }
private static String createFiltersChainText( PsiStatement body, PsiParameter parameter, PsiIfStatement ifStatement) { final List<String> filters = new ArrayList<String>(); while (ifStatement != null && PsiTreeUtil.isAncestor(body, ifStatement, false)) { final PsiExpression condition = ifStatement.getCondition(); if (condition != null) { filters.add( ".filter(" + compoundLambdaOrMethodReference( parameter, condition, "java.util.function.Predicate", new PsiType[] {parameter.getType()}) + ")"); } ifStatement = PsiTreeUtil.getParentOfType(ifStatement, PsiIfStatement.class); } Collections.reverse(filters); return StringUtil.join(filters, ""); }
public static boolean isAcceptable( PsiLambdaExpression lambdaExpression, final PsiType leftType, boolean checkReturnType) { if (leftType instanceof PsiIntersectionType) { for (PsiType conjunctType : ((PsiIntersectionType) leftType).getConjuncts()) { if (isAcceptable(lambdaExpression, conjunctType, checkReturnType)) return true; } return false; } final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(GenericsUtil.eliminateWildcards(leftType)); final PsiClass psiClass = resolveResult.getElement(); if (psiClass instanceof PsiAnonymousClass) { return isAcceptable( lambdaExpression, ((PsiAnonymousClass) psiClass).getBaseClassType(), checkReturnType); } final MethodSignature methodSignature = getFunction(psiClass); if (methodSignature == null) return false; final PsiParameter[] lambdaParameters = lambdaExpression.getParameterList().getParameters(); final PsiType[] parameterTypes = methodSignature.getParameterTypes(); if (lambdaParameters.length != parameterTypes.length) return false; for (int lambdaParamIdx = 0, length = lambdaParameters.length; lambdaParamIdx < length; lambdaParamIdx++) { PsiParameter parameter = lambdaParameters[lambdaParamIdx]; final PsiTypeElement typeElement = parameter.getTypeElement(); if (typeElement != null) { final PsiType lambdaFormalType = typeElement.getType(); final PsiType methodParameterType = parameterTypes[lambdaParamIdx]; if (lambdaFormalType instanceof PsiPrimitiveType) { if (methodParameterType instanceof PsiPrimitiveType) return methodParameterType.equals(lambdaFormalType); return false; } if (!TypeConversionUtil.erasure(lambdaFormalType) .isAssignableFrom( TypeConversionUtil.erasure( GenericsUtil.eliminateWildcards( resolveResult .getSubstitutor() .substitute( methodSignature .getSubstitutor() .substitute(methodParameterType)))))) { return false; } } } if (checkReturnType) { final String uniqueVarName = JavaCodeStyleManager.getInstance(lambdaExpression.getProject()) .suggestUniqueVariableName("l", lambdaExpression, true); String canonicalText = leftType.getCanonicalText(); if (leftType instanceof PsiEllipsisType) { canonicalText = ((PsiEllipsisType) leftType).toArrayType().getCanonicalText(); } final PsiStatement assignmentFromText = JavaPsiFacade.getElementFactory(lambdaExpression.getProject()) .createStatementFromText( canonicalText + " " + uniqueVarName + " = " + lambdaExpression.getText(), lambdaExpression); final PsiLocalVariable localVariable = (PsiLocalVariable) ((PsiDeclarationStatement) assignmentFromText).getDeclaredElements()[0]; LOG.assertTrue(psiClass != null); PsiType methodReturnType = getReturnType(psiClass, methodSignature); if (methodReturnType != null) { methodReturnType = resolveResult .getSubstitutor() .substitute(methodSignature.getSubstitutor().substitute(methodReturnType)); return LambdaHighlightingUtil.checkReturnTypeCompatible( (PsiLambdaExpression) localVariable.getInitializer(), methodReturnType) == null; } } return true; }
private static AllowedValues parseBeanInfo(@NotNull PsiModifierListOwner owner) { PsiMethod method = null; if (owner instanceof PsiParameter) { PsiParameter parameter = (PsiParameter) owner; PsiElement scope = parameter.getDeclarationScope(); if (!(scope instanceof PsiMethod)) return null; PsiElement nav = scope.getNavigationElement(); if (!(nav instanceof PsiMethod)) return null; method = (PsiMethod) nav; if (method.isConstructor()) { // not a property, try the @ConstructorProperties({"prop"}) PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, "java.beans.ConstructorProperties"); if (annotation == null) return null; PsiAnnotationMemberValue value = annotation.findAttributeValue("value"); if (!(value instanceof PsiArrayInitializerMemberValue)) return null; PsiAnnotationMemberValue[] initializers = ((PsiArrayInitializerMemberValue) value).getInitializers(); PsiElement parent = parameter.getParent(); if (!(parent instanceof PsiParameterList)) return null; int index = ((PsiParameterList) parent).getParameterIndex(parameter); if (index >= initializers.length) return null; PsiAnnotationMemberValue initializer = initializers[index]; if (!(initializer instanceof PsiLiteralExpression)) return null; Object val = ((PsiLiteralExpression) initializer).getValue(); if (!(val instanceof String)) return null; PsiMethod setter = PropertyUtil.findPropertySetter( method.getContainingClass(), (String) val, false, false); if (setter == null) return null; // try the @beaninfo of the corresponding setter method = (PsiMethod) setter.getNavigationElement(); } } else if (owner instanceof PsiMethod) { PsiElement nav = owner.getNavigationElement(); if (!(nav instanceof PsiMethod)) return null; method = (PsiMethod) nav; } if (method == null) return null; PsiClass aClass = method.getContainingClass(); if (aClass == null) return null; if (PropertyUtil.isSimplePropertyGetter(method)) { List<PsiMethod> setters = PropertyUtil.getSetters(aClass, PropertyUtil.getPropertyNameByGetter(method)); if (setters.size() != 1) return null; method = setters.get(0); } if (!PropertyUtil.isSimplePropertySetter(method)) return null; PsiDocComment doc = method.getDocComment(); if (doc == null) return null; PsiDocTag beaninfo = doc.findTagByName("beaninfo"); if (beaninfo == null) return null; String data = StringUtil.join( beaninfo.getDataElements(), new Function<PsiElement, String>() { @Override public String fun(PsiElement element) { return element.getText(); } }, "\n"); int enumIndex = StringUtil.indexOfSubstringEnd(data, "enum:"); if (enumIndex == -1) return null; data = data.substring(enumIndex); int colon = data.indexOf(":"); int last = colon == -1 ? data.length() : data.substring(0, colon).lastIndexOf("\n"); data = data.substring(0, last); List<PsiAnnotationMemberValue> values = new ArrayList<PsiAnnotationMemberValue>(); for (String line : StringUtil.splitByLines(data)) { List<String> words = StringUtil.split(line, " ", true, true); if (words.size() != 2) continue; String ref = words.get(1); PsiExpression constRef = JavaPsiFacade.getElementFactory(aClass.getProject()) .createExpressionFromText(ref, aClass); if (!(constRef instanceof PsiReferenceExpression)) continue; PsiReferenceExpression expr = (PsiReferenceExpression) constRef; values.add(expr); } if (values.isEmpty()) return null; PsiAnnotationMemberValue[] array = values.toArray(new PsiAnnotationMemberValue[values.size()]); return new AllowedValues(array, false); }
@Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { final PsiForeachStatement foreachStatement = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiForeachStatement.class); if (foreachStatement != null) { if (!FileModificationService.getInstance().preparePsiElementForWrite(foreachStatement)) return; PsiStatement body = foreachStatement.getBody(); final PsiExpression iteratedValue = foreachStatement.getIteratedValue(); if (body != null && iteratedValue != null) { restoreComments(foreachStatement, body); final PsiParameter parameter = foreachStatement.getIterationParameter(); final PsiIfStatement ifStmt = extractIfStatement(body); StringBuilder buffer = new StringBuilder(getIteratedValueText(iteratedValue)); if (ifStmt != null) { final PsiStatement thenBranch = ifStmt.getThenBranch(); LOG.assertTrue(thenBranch != null); buffer.append(".stream()"); buffer.append(createFiltersChainText(body, parameter, ifStmt)); body = thenBranch; } buffer.append(".").append(getForEachMethodName()).append("("); final String functionalExpressionText = createForEachFunctionalExpressionText(project, body, parameter); final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project); PsiExpressionStatement callStatement = (PsiExpressionStatement) elementFactory.createStatementFromText( buffer.toString() + functionalExpressionText + ");", foreachStatement); callStatement = (PsiExpressionStatement) foreachStatement.replace(callStatement); final PsiExpressionList argumentList = ((PsiCallExpression) callStatement.getExpression()).getArgumentList(); LOG.assertTrue(argumentList != null, callStatement.getText()); final PsiExpression[] expressions = argumentList.getExpressions(); LOG.assertTrue(expressions.length == 1); if (expressions[0] instanceof PsiFunctionalExpression && ((PsiFunctionalExpression) expressions[0]).getFunctionalInterfaceType() == null) { callStatement = (PsiExpressionStatement) callStatement.replace( elementFactory.createStatementFromText( buffer.toString() + "(" + parameter.getText() + ") -> " + wrapInBlock(body) + ");", callStatement)); } simplifyRedundantCast(callStatement); CodeStyleManager.getInstance(project) .reformat( JavaCodeStyleManager.getInstance(project).shortenClassReferences(callStatement)); } } }
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 static boolean isFreeFromTypeInferenceArgs( final PsiParameter[] methodParameters, final PsiLambdaExpression lambdaExpression, final PsiExpression expression, final PsiSubstitutor subst, final PsiType functionalInterfaceType, final PsiTypeParameter typeParam) { if (expression instanceof PsiCallExpression && ((PsiCallExpression) expression).getTypeArguments().length > 0) return true; if (expression instanceof PsiNewExpression) { final PsiJavaCodeReferenceElement classReference = ((PsiNewExpression) expression).getClassOrAnonymousClassReference(); if (classReference != null) { final PsiReferenceParameterList parameterList = classReference.getParameterList(); if (parameterList != null) { final PsiTypeElement[] typeParameterElements = parameterList.getTypeParameterElements(); if (typeParameterElements.length > 0) { if (!(typeParameterElements[0].getType() instanceof PsiDiamondType)) { return true; } } } } } final PsiParameter[] lambdaParams = lambdaExpression.getParameterList().getParameters(); if (lambdaParams.length != methodParameters.length) return false; final boolean[] independent = {true}; final PsiMethod interfaceMethod = getFunctionalInterfaceMethod(functionalInterfaceType); if (interfaceMethod == null) return false; final TypeParamsChecker paramsChecker = new TypeParamsChecker(lambdaExpression); for (PsiParameter parameter : interfaceMethod.getParameterList().getParameters()) { subst.substitute(parameter.getType()).accept(paramsChecker); } paramsChecker.myUsedTypeParams.add(typeParam); expression.accept( new JavaRecursiveElementWalkingVisitor() { @Override public void visitConditionalExpression(PsiConditionalExpression expression) { final PsiExpression thenExpression = expression.getThenExpression(); if (thenExpression != null) { thenExpression.accept(this); } final PsiExpression elseExpression = expression.getElseExpression(); if (elseExpression != null) { elseExpression.accept(this); } } @Override public void visitReferenceExpression(PsiReferenceExpression expression) { super.visitReferenceExpression(expression); int usedParamIdx = -1; for (int i = 0; i < lambdaParams.length; i++) { PsiParameter param = lambdaParams[i]; if (expression.isReferenceTo(param)) { usedParamIdx = i; break; } } if (usedParamIdx > -1 && dependsOnTypeParams( subst.substitute(methodParameters[usedParamIdx].getType()), functionalInterfaceType, lambdaExpression, paramsChecker.myUsedTypeParams.toArray( new PsiTypeParameter[paramsChecker.myUsedTypeParams.size()]))) { independent[0] = false; } } }); return independent[0]; }