@Override protected void updateTitle(@Nullable final PsiVariable variable, final String value) { final PsiElement declarationScope = variable != null ? ((PsiParameter) variable).getDeclarationScope() : null; if (declarationScope instanceof PsiMethod) { final PsiMethod psiMethod = (PsiMethod) declarationScope; final StringBuilder buf = new StringBuilder(); buf.append(psiMethod.getName()).append(" ("); boolean frst = true; final List<TextRange> ranges2Remove = new ArrayList<>(); TextRange addedRange = null; for (PsiParameter parameter : psiMethod.getParameterList().getParameters()) { if (frst) { frst = false; } else { buf.append(", "); } int startOffset = buf.length(); if (myMustBeFinal || myPanel.isGenerateFinal()) { buf.append("final "); } buf.append(parameter.getType().getPresentableText()) .append(" ") .append(variable == parameter ? value : parameter.getName()); int endOffset = buf.length(); if (variable == parameter) { addedRange = new TextRange(startOffset, endOffset); } else if (myPanel.isParamToRemove(parameter)) { ranges2Remove.add(new TextRange(startOffset, endOffset)); } } buf.append(")"); setPreviewText(buf.toString()); final MarkupModel markupModel = DocumentMarkupModel.forDocument(getPreviewEditor().getDocument(), myProject, true); markupModel.removeAllHighlighters(); for (TextRange textRange : ranges2Remove) { markupModel.addRangeHighlighter( textRange.getStartOffset(), textRange.getEndOffset(), 0, getTestAttributesForRemoval(), HighlighterTargetArea.EXACT_RANGE); } markupModel.addRangeHighlighter( addedRange.getStartOffset(), addedRange.getEndOffset(), 0, getTextAttributesForAdd(), HighlighterTargetArea.EXACT_RANGE); revalidate(); } }
private static boolean parametersAreEquivalent( @NotNull PsiParameter parameter1, @NotNull PsiParameter parameter2) { final PsiType type1 = parameter1.getType(); final PsiType type2 = parameter2.getType(); if (!typesAreEquivalent(type1, type2)) { return false; } final String name1 = parameter1.getName(); final String name2 = parameter2.getName(); return name1.equals(name2); }
@SuppressWarnings({"HardCodedStringLiteral"}) private static JVMName getJVMSignature( @Nullable PsiMethod method, boolean constructor, @Nullable PsiClass declaringClass) { JVMNameBuffer signature = new JVMNameBuffer(); signature.append("("); if (constructor) { if (declaringClass != null) { final PsiClass outerClass = declaringClass.getContainingClass(); if (outerClass != null) { // declaring class is an inner class if (!declaringClass.hasModifierProperty(PsiModifier.STATIC)) { appendJvmClassQualifiedName(signature, getJVMQualifiedName(outerClass)); } } } } if (method != null) { for (PsiParameter psiParameter : method.getParameterList().getParameters()) { appendJVMSignature(signature, psiParameter.getType()); } } signature.append(")"); if (!constructor && method != null) { appendJVMSignature(signature, method.getReturnType()); } else { signature.append(new JVMRawText("V")); } return signature.toName(); }
/** signature should be changed for methods with type parameters */ private void prepareMethodsChangeSignature( final PsiClass currentClass, final PsiElement memberToChangeSignature, final PsiType memberType) { if (memberToChangeSignature instanceof PsiMethod) { final PsiMethod method = MethodSignatureUtil.findMethodBySuperMethod( currentClass, (PsiMethod) memberToChangeSignature, true); if (method != null && method.getContainingClass() == currentClass) { myLabeler.addRoot(new TypeMigrationUsageInfo(method), memberType, method, false); } } else if (memberToChangeSignature instanceof PsiParameter && ((PsiParameter) memberToChangeSignature).getDeclarationScope() instanceof PsiMethod) { final PsiMethod superMethod = (PsiMethod) ((PsiParameter) memberToChangeSignature).getDeclarationScope(); final int parameterIndex = superMethod.getParameterList().getParameterIndex((PsiParameter) memberToChangeSignature); final PsiMethod method = MethodSignatureUtil.findMethodBySuperMethod(currentClass, superMethod, true); if (method != null && method.getContainingClass() == currentClass) { final PsiParameter parameter = method.getParameterList().getParameters()[parameterIndex]; if (!parameter.getType().equals(memberType)) { myLabeler.addRoot(new TypeMigrationUsageInfo(parameter), memberType, parameter, false); } } } }
private void processListenerProperties(@NotNull PsiMethod method) { if (!method.getName().startsWith("add") || method.getParameterList().getParametersCount() != 1) return; final PsiParameter parameter = method.getParameterList().getParameters()[0]; final PsiType type = parameter.getType(); if (!(type instanceof PsiClassType)) return; final PsiClassType classType = (PsiClassType) type; final PsiClass listenerClass = classType.resolve(); if (listenerClass == null) return; final PsiMethod[] listenerMethods = listenerClass.getMethods(); if (!InheritanceUtil.isInheritorOrSelf(listenerClass, myEventListener, true)) return; for (PsiMethod listenerMethod : listenerMethods) { final String name = listenerMethod.getName(); if (myPropertyNames.add(name)) { LookupElementBuilder builder = LookupElementBuilder.create( generatePropertyResolveResult(name, listenerMethod, null, null), name) .withIcon(JetgroovyIcons.Groovy.Property); myConsumer.consume(builder); } } }
@NotNull public List<String> createConversions(@NotNull PsiCallExpression expression) { PsiExpressionList argumentList = expression.getArgumentList(); PsiExpression[] arguments = argumentList != null ? argumentList.getExpressions() : new PsiExpression[] {}; List<String> conversions = new LinkedList<String>(); //noinspection UnusedDeclaration for (PsiExpression a : arguments) { conversions.add(""); } PsiMethod resolve = expression.resolveMethod(); if (resolve != null) { List<PsiType> expectedTypes = new LinkedList<PsiType>(); List<PsiType> actualTypes = new LinkedList<PsiType>(); for (PsiParameter p : resolve.getParameterList().getParameters()) expectedTypes.add(p.getType()); for (PsiExpression e : arguments) actualTypes.add(e.getType()); if (conversions.size() == actualTypes.size() && actualTypes.size() == expectedTypes.size()) { for (int i = 0; i < actualTypes.size(); i++) conversions.set(i, createConversionForExpression(arguments[i], expectedTypes.get(i))); } } return conversions; }
@NotNull public Parameter parameterToParameter(@NotNull PsiParameter parameter) { return new Parameter( new IdentifierImpl(parameter.getName()), typeToType( parameter.getType(), ConverterUtil.isAnnotatedAsNotNull(parameter.getModifierList()))); }
private static void removeUnusedParameterViaChangeSignature( final PsiMethod psiMethod, final Collection<PsiElement> parametersToDelete) { ArrayList<ParameterInfoImpl> newParameters = new ArrayList<ParameterInfoImpl>(); PsiParameter[] oldParameters = psiMethod.getParameterList().getParameters(); for (int i = 0; i < oldParameters.length; i++) { PsiParameter oldParameter = oldParameters[i]; if (!parametersToDelete.contains(oldParameter)) { newParameters.add( new ParameterInfoImpl(i, oldParameter.getName(), oldParameter.getType())); } } ParameterInfoImpl[] parameterInfos = newParameters.toArray(new ParameterInfoImpl[newParameters.size()]); ChangeSignatureProcessor csp = new ChangeSignatureProcessor( psiMethod.getProject(), psiMethod, false, null, psiMethod.getName(), psiMethod.getReturnType(), parameterInfos); csp.run(); }
@Override public void visitNewExpression(PsiNewExpression expression) { super.visitNewExpression(expression); final PsiJavaCodeReferenceElement classReference = expression.getClassReference(); if (classReference == null) { return; } final String name = classReference.getReferenceName(); if (!"BigDecimal".equals(name)) { return; } final PsiMethod constructor = expression.resolveConstructor(); if (constructor == null) { return; } final PsiParameterList parameterList = constructor.getParameterList(); final int length = parameterList.getParametersCount(); if (length != 1 && length != 2) { return; } final PsiParameter[] parameters = parameterList.getParameters(); final PsiParameter firstParameter = parameters[0]; final PsiType type = firstParameter.getType(); if (type != PsiType.DOUBLE) { return; } registerNewExpressionError(expression); }
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 boolean hasOnlyClosureParams(PsiMethod method) { final PsiParameter[] params = method.getParameterList().getParameters(); for (PsiParameter param : params) { final PsiType type = param.getType(); if (!TypesUtil.isClassType(type, GroovyCommonClassNames.GROOVY_LANG_CLOSURE)) { return false; } } return params.length > 0; }
@Override public void visitThrowStatement(PsiThrowStatement statement) { super.visitThrowStatement(statement); final PsiCatchSection catchSection = PsiTreeUtil.getParentOfType(statement, PsiCatchSection.class, true, PsiClass.class); if (catchSection == null) { return; } final PsiParameter parameter = catchSection.getParameter(); if (parameter == null) { return; } @NonNls final String parameterName = parameter.getName(); if (PsiUtil.isIgnoredName(parameterName)) { return; } final PsiExpression exception = statement.getException(); if (exception == null) { return; } if (ignoreCantWrap) { final PsiType thrownType = exception.getType(); if (thrownType instanceof PsiClassType) { final PsiClassType classType = (PsiClassType) thrownType; final PsiClass exceptionClass = classType.resolve(); if (exceptionClass != null) { final PsiMethod[] constructors = exceptionClass.getConstructors(); final PsiClassType throwableType = TypeUtils.getType(CommonClassNames.JAVA_LANG_THROWABLE, statement); boolean canWrap = false; outer: for (PsiMethod constructor : constructors) { final PsiParameterList parameterList = constructor.getParameterList(); final PsiParameter[] parameters = parameterList.getParameters(); for (PsiParameter constructorParameter : parameters) { final PsiType type = constructorParameter.getType(); if (throwableType.equals(type)) { canWrap = true; break outer; } } } if (!canWrap) { return; } } } } final ReferenceFinder visitor = new ReferenceFinder(parameter); exception.accept(visitor); if (visitor.usesParameter()) { return; } registerStatementError(statement); }
private static boolean forEachStatementsAreEquivalent( @NotNull PsiForeachStatement statement1, @NotNull PsiForeachStatement statement2) { final PsiExpression value1 = statement1.getIteratedValue(); final PsiExpression value2 = statement2.getIteratedValue(); if (!expressionsAreEquivalent(value1, value2)) { return false; } final PsiParameter parameter1 = statement1.getIterationParameter(); final PsiParameter parameter2 = statement1.getIterationParameter(); final String name1 = parameter1.getName(); final String name2 = parameter2.getName(); if (!name1.equals(name2)) { return false; } final PsiType type1 = parameter1.getType(); if (!type1.equals(parameter2.getType())) { return false; } final PsiStatement body1 = statement1.getBody(); final PsiStatement body2 = statement2.getBody(); return statementsAreEquivalent(body1, body2); }
@Nullable private PsiType extractLastParameterType(GroovyResolveResult candidate) { PsiElement element = candidate.getElement(); if (element instanceof PsiMethod) { PsiParameter[] parameters = ((PsiMethod) element).getParameterList().getParameters(); if (parameters.length > 1) { PsiParameter last = parameters[parameters.length - 1]; return TypesUtil.substituteBoxAndNormalizeType( last.getType(), candidate.getSubstitutor(), candidate.getSpreadState(), this); } } return null; }
@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()); }
static boolean isArgumentInVarargPosition( PsiExpression[] expressions, int ei, PsiParameter varargParam, PsiSubstitutor substitutor) { if (varargParam == null) return false; final PsiExpression expression = expressions[ei]; if (expression == null || TypeConversionUtil.areTypesAssignmentCompatible( substitutor.substitute(((PsiEllipsisType) varargParam.getType()).getComponentType()), expression)) { final int lastExprIdx = expressions.length - 1; if (ei == lastExprIdx) return true; return expressions[lastExprIdx].getType() != PsiType.NULL; } return false; }
@NotNull private ParameterList createFunctionParameters(@NotNull PsiMethod method) { List<Parameter> result = new LinkedList<Parameter>(); for (PsiParameter parameter : method.getParameterList().getParameters()) { result.add( new Parameter( new IdentifierImpl(parameter.getName()), typeToType( parameter.getType(), ConverterUtil.isAnnotatedAsNotNull(parameter.getModifierList())), ConverterUtil.isReadOnly(parameter, method.getBody()))); } return new ParameterList(result); }
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; }
@Test public void shouldNotVerifyThatFieldIsSetInConstructorIfConstructorHasDifferentParameterName() { // given prepareBehaviourForReturningParameter(); given(parameter.getType()).willReturn(psiType); given(psiField.getType()).willReturn(psiType); given(parameter.getName()).willReturn(name); given(psiField.getName()).willReturn("differentName"); // when boolean result = psiFieldVerifier.isSetInConstructor(psiField, psiClass); // then assertThat(result, is(false)); }
private static void appendMethodParameters( StringBuffer buf, PsiMethod method, boolean showNames) { PsiParameter[] params = method.getParameterList().getParameters(); buf.append('('); for (int i = 0; i < params.length; i++) { if (i != 0) buf.append(", "); PsiParameter param = params[i]; buf.append(param.getType().getPresentableText()); if (showNames) { buf.append(' '); buf.append(param.getName()); } } buf.append(')'); }
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 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 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 void removeParameter(final PsiMethod method, final PsiParameter parameter) { final PsiParameter[] parameters = method.getParameterList().getParameters(); final List<ParameterInfoImpl> psiParameters = new ArrayList<ParameterInfoImpl>(); int paramIdx = 0; final String paramName = parameter.getName(); for (PsiParameter param : parameters) { if (!Comparing.strEqual(paramName, param.getName())) { psiParameters.add(new ParameterInfoImpl(paramIdx, param.getName(), param.getType())); } paramIdx++; } new ChangeSignatureProcessor( method.getProject(), method, false, null, method.getName(), method.getReturnType(), psiParameters.toArray(new ParameterInfoImpl[psiParameters.size()])) .run(); }
private boolean hasOnlyMain(PsiClass aClass) { final PsiMethod[] methods = aClass.getMethods(); if (methods.length == 0) { return false; } for (PsiMethod method : methods) { if (method.isConstructor()) { continue; } if (!method.hasModifierProperty(PsiModifier.STATIC)) { return false; } if (method.hasModifierProperty(PsiModifier.PRIVATE)) { continue; } if (!method.hasModifierProperty(PsiModifier.PUBLIC)) { return false; } final String name = method.getName(); if (!name.equals(HardcodedMethodConstants.MAIN)) { return false; } final PsiType returnType = method.getReturnType(); if (!PsiType.VOID.equals(returnType)) { return false; } final PsiParameterList parameterList = method.getParameterList(); if (parameterList.getParametersCount() != 1) { return false; } final PsiParameter[] parameters = parameterList.getParameters(); final PsiParameter parameter = parameters[0]; final PsiType type = parameter.getType(); if (!type.equalsToText("java.lang.String[]")) { return false; } } return true; }
private static boolean isClassHasConstructorWithMap(PsiClass aClass) { PsiMethod[] constructors = aClass.getConstructors(); if (constructors.length == 0) return true; for (PsiMethod constructor : constructors) { PsiParameterList parameterList = constructor.getParameterList(); PsiParameter[] parameters = parameterList.getParameters(); if (parameters.length == 0) return true; final PsiParameter first = parameters[0]; if (InheritanceUtil.isInheritor(first.getType(), CommonClassNames.JAVA_UTIL_MAP)) return true; if (first instanceof GrParameter && ((GrParameter) first).getTypeGroovy() == null) return true; // if constructor has only optional parameters it can be used as default constructor with map // args if (!PsiUtil.isConstructorHasRequiredParameters(constructor)) return true; } return false; }
@Override public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) { if (!LambdaUtil.isFunctionalType(myT)) { return false; } final PsiType groundTargetType = FunctionalInterfaceParameterizationUtil.getGroundTargetType(myT); final PsiClassType.ClassResolveResult classResolveResult = PsiUtil.resolveGenericsClassInType(groundTargetType); final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(classResolveResult); if (interfaceMethod == null) { return false; } final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, classResolveResult); final PsiParameter[] targetParameters = interfaceMethod.getParameterList().getParameters(); final PsiType interfaceMethodReturnType = interfaceMethod.getReturnType(); final PsiType returnType = substitutor.substitute(interfaceMethodReturnType); final PsiType[] typeParameters = myExpression.getTypeParameters(); final PsiMethodReferenceUtil.QualifierResolveResult qualifierResolveResult = PsiMethodReferenceUtil.getQualifierResolveResult(myExpression); if (!myExpression.isExact()) { for (PsiParameter parameter : targetParameters) { if (!session.isProperType(substitutor.substitute(parameter.getType()))) { return false; } } } else { final PsiMember applicableMember = myExpression.getPotentiallyApplicableMember(); LOG.assertTrue(applicableMember != null); final PsiClass applicableMemberContainingClass = applicableMember.getContainingClass(); final PsiClass containingClass = qualifierResolveResult.getContainingClass(); PsiSubstitutor psiSubstitutor = qualifierResolveResult.getSubstitutor(); psiSubstitutor = applicableMemberContainingClass == null || containingClass == null || myExpression.isConstructor() ? psiSubstitutor : TypeConversionUtil.getSuperClassSubstitutor( applicableMemberContainingClass, containingClass, psiSubstitutor); PsiType applicableMethodReturnType = applicableMember instanceof PsiMethod ? ((PsiMethod) applicableMember).getReturnType() : null; int idx = 0; for (PsiTypeParameter param : ((PsiTypeParameterListOwner) applicableMember).getTypeParameters()) { if (idx < typeParameters.length) { psiSubstitutor = psiSubstitutor.put(param, typeParameters[idx++]); } } final PsiParameter[] parameters = applicableMember instanceof PsiMethod ? ((PsiMethod) applicableMember).getParameterList().getParameters() : PsiParameter.EMPTY_ARRAY; if (targetParameters.length == parameters.length + 1) { specialCase(session, constraints, substitutor, targetParameters, true); for (int i = 1; i < targetParameters.length; i++) { constraints.add( new TypeCompatibilityConstraint( session.substituteWithInferenceVariables( psiSubstitutor.substitute(parameters[i - 1].getType())), substitutor.substitute(targetParameters[i].getType()))); } } else if (targetParameters.length == parameters.length) { for (int i = 0; i < targetParameters.length; i++) { constraints.add( new TypeCompatibilityConstraint( session.substituteWithInferenceVariables( psiSubstitutor.substitute(parameters[i].getType())), substitutor.substitute(targetParameters[i].getType()))); } } else { return false; } if (returnType != PsiType.VOID && returnType != null) { if (applicableMethodReturnType == PsiType.VOID) { return false; } if (applicableMethodReturnType != null) { constraints.add( new TypeCompatibilityConstraint( returnType, session.substituteWithInferenceVariables( psiSubstitutor.substitute(applicableMethodReturnType)))); } else if (applicableMember instanceof PsiClass || applicableMember instanceof PsiMethod && ((PsiMethod) applicableMember).isConstructor()) { final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(applicableMember.getProject()); if (containingClass != null) { final PsiType classType = session.substituteWithInferenceVariables( elementFactory.createType(containingClass, psiSubstitutor)); constraints.add(new TypeCompatibilityConstraint(returnType, classType)); } } } return true; } final Map<PsiElement, PsiType> map = LambdaUtil.getFunctionalTypeMap(); final PsiType added = map.put(myExpression, session.startWithFreshVars(groundTargetType)); final JavaResolveResult resolve; try { resolve = myExpression.advancedResolve(true); } finally { if (added == null) { map.remove(myExpression); } } final PsiElement element = resolve.getElement(); if (element == null) { return false; } if (PsiType.VOID.equals(returnType) || returnType == null) { return true; } if (element instanceof PsiMethod) { final PsiMethod method = (PsiMethod) element; final PsiType referencedMethodReturnType; final PsiClass containingClass = method.getContainingClass(); LOG.assertTrue(containingClass != null, method); PsiClass qContainingClass = qualifierResolveResult.getContainingClass(); PsiSubstitutor psiSubstitutor = qualifierResolveResult.getSubstitutor(); if (qContainingClass != null) { if (PsiUtil.isRawSubstitutor(qContainingClass, psiSubstitutor)) { psiSubstitutor = PsiSubstitutor.EMPTY; } if (qContainingClass.isInheritor(containingClass, true)) { psiSubstitutor = TypeConversionUtil.getClassSubstitutor( containingClass, qContainingClass, PsiSubstitutor.EMPTY); LOG.assertTrue(psiSubstitutor != null); } } if (method.isConstructor()) { referencedMethodReturnType = JavaPsiFacade.getElementFactory(method.getProject()) .createType(containingClass, PsiSubstitutor.EMPTY); } else { referencedMethodReturnType = method.getReturnType(); } LOG.assertTrue(referencedMethodReturnType != null, method); if (!PsiTreeUtil.isContextAncestor(containingClass, myExpression, false) || PsiUtil.getEnclosingStaticElement(myExpression, containingClass) != null) { session.initBounds(myExpression, containingClass.getTypeParameters()); } session.initBounds(myExpression, method.getTypeParameters()); // if i) the method reference elides NonWildTypeArguments, // ii) the compile-time declaration is a generic method, and // iii) the return type of the compile-time declaration mentions at least one of the method's // type parameters; if (typeParameters.length == 0 && method.getTypeParameters().length > 0) { final PsiClass interfaceClass = classResolveResult.getElement(); LOG.assertTrue(interfaceClass != null); if (PsiPolyExpressionUtil.mentionsTypeParameters( referencedMethodReturnType, ContainerUtil.newHashSet(method.getTypeParameters()))) { // the constraint reduces to the bound set B3 which would be used to determine the method // reference's invocation type // when targeting the return type of the function type, as defined in 18.5.2. session.collectApplicabilityConstraints( myExpression, ((MethodCandidateInfo) resolve), groundTargetType); session.registerReturnTypeConstraints(referencedMethodReturnType, returnType); return true; } } if (PsiType.VOID.equals(referencedMethodReturnType)) { return false; } int idx = 0; for (PsiTypeParameter param : method.getTypeParameters()) { if (idx < typeParameters.length) { psiSubstitutor = psiSubstitutor.put(param, typeParameters[idx++]); } } final PsiParameter[] parameters = method.getParameterList().getParameters(); if (targetParameters.length == parameters.length + 1 && !method.isVarArgs() && PsiPolyExpressionUtil.mentionsTypeParameters( referencedMethodReturnType, ContainerUtil.newHashSet( containingClass.getTypeParameters()))) { // todo specification bug? specialCase(session, constraints, substitutor, targetParameters, false); } constraints.add( new TypeCompatibilityConstraint( returnType, session.substituteWithInferenceVariables( psiSubstitutor.substitute(referencedMethodReturnType)))); } return true; }
public static PsiMethod generateConstructorPrototype( PsiClass aClass, PsiMethod baseConstructor, boolean copyJavaDoc, PsiField[] fields) throws IncorrectOperationException { PsiManager manager = aClass.getManager(); JVMElementFactory factory = JVMElementFactories.requireFactory(aClass.getLanguage(), aClass.getProject()); CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject()); PsiMethod constructor = factory.createConstructor(aClass.getName(), aClass); String modifier = PsiUtil.getMaximumModifierForMember(aClass, false); if (modifier != null) { PsiUtil.setModifierProperty(constructor, modifier, true); } if (baseConstructor != null) { PsiJavaCodeReferenceElement[] throwRefs = baseConstructor.getThrowsList().getReferenceElements(); for (PsiJavaCodeReferenceElement ref : throwRefs) { constructor.getThrowsList().add(ref); } if (copyJavaDoc) { final PsiDocComment docComment = ((PsiMethod) baseConstructor.getNavigationElement()).getDocComment(); if (docComment != null) { constructor.addAfter(docComment, null); } } } boolean isNotEnum = false; if (baseConstructor != null) { PsiClass superClass = aClass.getSuperClass(); LOG.assertTrue(superClass != null); if (!CommonClassNames.JAVA_LANG_ENUM.equals(superClass.getQualifiedName())) { isNotEnum = true; if (baseConstructor instanceof PsiCompiledElement) { // to get some parameter names PsiClass dummyClass = JVMElementFactories.requireFactory( baseConstructor.getLanguage(), baseConstructor.getProject()) .createClass("Dummy"); baseConstructor = (PsiMethod) dummyClass.add(baseConstructor); } PsiParameter[] params = baseConstructor.getParameterList().getParameters(); for (PsiParameter param : params) { PsiParameter newParam = factory.createParameter(param.getName(), param.getType(), aClass); GenerateMembersUtil.copyOrReplaceModifierList(param, newParam); constructor.getParameterList().add(newParam); } } } JavaCodeStyleManager javaStyle = JavaCodeStyleManager.getInstance(aClass.getProject()); final PsiMethod dummyConstructor = factory.createConstructor(aClass.getName()); dummyConstructor.getParameterList().replace(constructor.getParameterList().copy()); List<PsiParameter> fieldParams = new ArrayList<PsiParameter>(); for (PsiField field : fields) { String fieldName = field.getName(); String name = javaStyle.variableNameToPropertyName(fieldName, VariableKind.FIELD); String parmName = javaStyle.propertyNameToVariableName(name, VariableKind.PARAMETER); parmName = javaStyle.suggestUniqueVariableName(parmName, dummyConstructor, true); PsiParameter parm = factory.createParameter(parmName, field.getType(), aClass); final NullableNotNullManager nullableManager = NullableNotNullManager.getInstance(field.getProject()); final String notNull = nullableManager.getNotNull(field); if (notNull != null) { parm.getModifierList() .addAfter(factory.createAnnotationFromText("@" + notNull, field), null); } constructor.getParameterList().add(parm); dummyConstructor.getParameterList().add(parm.copy()); fieldParams.add(parm); } ConstructorBodyGenerator generator = ConstructorBodyGenerator.INSTANCE.forLanguage(aClass.getLanguage()); if (generator != null) { @NonNls StringBuilder buffer = new StringBuilder(); generator.start(buffer, constructor.getName(), PsiParameter.EMPTY_ARRAY); if (isNotEnum) { generator.generateSuperCallIfNeeded( buffer, baseConstructor.getParameterList().getParameters()); } generator.generateFieldInitialization( buffer, fields, fieldParams.toArray(new PsiParameter[fieldParams.size()])); generator.finish(buffer); PsiMethod stub = factory.createMethodFromText(buffer.toString(), aClass); constructor.getBody().replace(stub.getBody()); } constructor = (PsiMethod) codeStyleManager.reformat(constructor); return constructor; }
private void findUsagesForMethod( PsiMethod overridingMethod, List<FixableUsageInfo> usages, boolean changeSignature) { final PsiCodeBlock body = overridingMethod.getBody(); final String baseParameterName = StringUtil.decapitalize(className); final String fixedParamName = body != null ? JavaCodeStyleManager.getInstance(myProject) .suggestUniqueVariableName(baseParameterName, body.getLBrace(), true) : JavaCodeStyleManager.getInstance(myProject) .propertyNameToVariableName(baseParameterName, VariableKind.PARAMETER); usages.add( new MergeMethodArguments( overridingMethod, className, packageName, fixedParamName, paramsToMerge, typeParams, keepMethodAsDelegate, myCreateInnerClass ? method.getContainingClass() : null, changeSignature)); final ParamUsageVisitor visitor = new ParamUsageVisitor(overridingMethod, paramsToMerge); overridingMethod.accept(visitor); final Set<PsiReferenceExpression> values = visitor.getParameterUsages(); for (PsiReferenceExpression paramUsage : values) { final PsiParameter parameter = (PsiParameter) paramUsage.resolve(); assert parameter != null; final PsiMethod containingMethod = (PsiMethod) parameter.getDeclarationScope(); final int index = containingMethod.getParameterList().getParameterIndex(parameter); final PsiParameter replacedParameter = method.getParameterList().getParameters()[index]; final ParameterChunk parameterChunk = ParameterChunk.getChunkByParameter(parameter, parameters); @NonNls String getter = parameterChunk != null ? parameterChunk.getter : null; final String paramName = parameterChunk != null ? parameterChunk.parameter.name : replacedParameter.getName(); final PsiType paramType = parameterChunk != null ? parameterChunk.parameter.type : replacedParameter.getType(); if (getter == null) { getter = GenerateMembersUtil.suggestGetterName(paramName, paramType, myProject); paramsNeedingGetters.add(replacedParameter); } @NonNls String setter = parameterChunk != null ? parameterChunk.setter : null; if (setter == null) { setter = GenerateMembersUtil.suggestSetterName(paramName, paramType, myProject); } if (RefactoringUtil.isPlusPlusOrMinusMinus(paramUsage.getParent())) { usages.add( new ReplaceParameterIncrementDecrement(paramUsage, fixedParamName, setter, getter)); if (parameterChunk == null || parameterChunk.setter == null) { paramsNeedingSetters.add(replacedParameter); } } else if (RefactoringUtil.isAssignmentLHS(paramUsage)) { usages.add( new ReplaceParameterAssignmentWithCall(paramUsage, fixedParamName, setter, getter)); if (parameterChunk == null || parameterChunk.setter == null) { paramsNeedingSetters.add(replacedParameter); } } else { usages.add(new ReplaceParameterReferenceWithCall(paramUsage, fixedParamName, getter)); } } }