PsiExtensionMethod (PsiMethod staticMethod, PsiClass targetClass, PsiMethodCallExpression callExpression) { if (!staticMethod.getName().equals(callExpression.getMethodExpression().getReferenceName())) return null; PsiClass providerClass = Objects.requireNonNull(staticMethod.getContainingClass()); PsiMethodCallExpression staticMethodCall; try { StringBuilder args = new StringBuilder(Objects.requireNonNull(callExpression.getMethodExpression().getQualifierExpression()).getText()); PsiExpression[] expressions = callExpression.getArgumentList().getExpressions(); if (expressions.length > 0) { args.append(", "); } args.append(StringUtil.join(expressions, expression -> expression.getText(), ",")); staticMethodCall = (PsiMethodCallExpression)JavaPsiFacade.getElementFactory(staticMethod.getProject()) .createExpressionFromText(providerClass.getQualifiedName() + "." + staticMethod.getName() + "(" + args + ")", callExpression); } catch (ProcessCanceledException e) { throw e; } catch (Throwable e) { LOG.error(e); return null; } JavaResolveResult result = staticMethodCall.resolveMethodGenerics(); if (!(result instanceof MethodCandidateInfo)) return null; PsiMethod method = ((MethodCandidateInfo)result).getElement(); if (!method.equals(staticMethod) || !((MethodCandidateInfo)result).isApplicable()) return null; PsiSubstitutor substitutor = result.getSubstitutor(); final LombokExtensionMethod lightMethod = new LombokExtensionMethod(staticMethod); lightMethod .addModifiers(PsiModifier.PUBLIC); PsiParameter @NotNull [] parameters = staticMethod.getParameterList().getParameters(); if (targetClass.isInterface()) { lightMethod.addModifier(PsiModifier.DEFAULT); } lightMethod.setMethodReturnType(substitutor.substitute(staticMethod.getReturnType())); for (int i = 1, length = parameters.length; i < length; i++) { PsiParameter parameter = parameters[i]; lightMethod.addParameter(new LombokLightParameter(parameter.getName(), substitutor.substitute(parameter.getType()), lightMethod, JavaLanguage.INSTANCE)); } PsiClassType[] thrownTypes = staticMethod.getThrowsList().getReferencedTypes(); for (PsiClassType thrownType : thrownTypes) { lightMethod.addException((PsiClassType)substitutor.substitute(thrownType)); } PsiTypeParameter[] staticMethodTypeParameters = staticMethod.getTypeParameters(); HashSet<PsiTypeParameter> initialTypeParameters = ContainerUtil.newHashSet(staticMethodTypeParameters); Arrays.stream(staticMethodTypeParameters) .filter(typeParameter -> PsiTypesUtil.mentionsTypeParameters(substitutor.substitute(typeParameter), initialTypeParameters)) .forEach(lightMethod::addTypeParameter); lightMethod.setNavigationElement(staticMethod); lightMethod.setContainingClass(targetClass); return lightMethod; }