use of org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType in project intellij-community by JetBrains.
the class ConvertClosureToMethodIntention method processIntention.
@Override
protected void processIntention(@NotNull PsiElement element, @NotNull Project project, Editor editor) throws IncorrectOperationException {
final GrField field;
if (element.getParent() instanceof GrField) {
field = (GrField) element.getParent();
} else {
final PsiReference ref = element.getReference();
LOG.assertTrue(ref != null);
PsiElement resolved = ref.resolve();
if (resolved instanceof GrAccessorMethod) {
resolved = ((GrAccessorMethod) resolved).getProperty();
}
LOG.assertTrue(resolved instanceof GrField);
field = (GrField) resolved;
}
final HashSet<PsiReference> usages = new HashSet<>();
usages.addAll(ReferencesSearch.search(field).findAll());
final GrAccessorMethod[] getters = field.getGetters();
for (GrAccessorMethod getter : getters) {
usages.addAll(MethodReferencesSearch.search(getter).findAll());
}
final GrAccessorMethod setter = field.getSetter();
if (setter != null) {
usages.addAll(MethodReferencesSearch.search(setter).findAll());
}
final String fieldName = field.getName();
LOG.assertTrue(fieldName != null);
final Collection<PsiElement> fieldUsages = new HashSet<>();
MultiMap<PsiElement, String> conflicts = new MultiMap<>();
for (PsiReference usage : usages) {
final PsiElement psiElement = usage.getElement();
if (PsiUtil.isMethodUsage(psiElement))
continue;
if (!GroovyLanguage.INSTANCE.equals(psiElement.getLanguage())) {
conflicts.putValue(psiElement, GroovyIntentionsBundle.message("closure.is.accessed.outside.of.groovy", fieldName));
} else {
if (psiElement instanceof GrReferenceExpression) {
fieldUsages.add(psiElement);
if (PsiUtil.isAccessedForWriting((GrExpression) psiElement)) {
conflicts.putValue(psiElement, GroovyIntentionsBundle.message("write.access.to.closure.variable", fieldName));
}
} else if (psiElement instanceof GrArgumentLabel) {
conflicts.putValue(psiElement, GroovyIntentionsBundle.message("field.is.used.in.argument.label", fieldName));
}
}
}
final PsiClass containingClass = field.getContainingClass();
final GrExpression initializer = field.getInitializerGroovy();
LOG.assertTrue(initializer != null);
final PsiType type = initializer.getType();
LOG.assertTrue(type instanceof GrClosureType);
final GrSignature signature = ((GrClosureType) type).getSignature();
final List<MethodSignature> signatures = GrClosureSignatureUtil.generateAllMethodSignaturesBySignature(fieldName, signature);
for (MethodSignature s : signatures) {
final PsiMethod method = MethodSignatureUtil.findMethodBySignature(containingClass, s, true);
if (method != null) {
conflicts.putValue(method, GroovyIntentionsBundle.message("method.with.signature.already.exists", GroovyPresentationUtil.getSignaturePresentation(s)));
}
}
if (!conflicts.isEmpty()) {
final ConflictsDialog conflictsDialog = new ConflictsDialog(project, conflicts, () -> execute(field, fieldUsages));
conflictsDialog.show();
if (conflictsDialog.getExitCode() != DialogWrapper.OK_EXIT_CODE)
return;
}
execute(field, fieldUsages);
}
use of org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType in project intellij-community by JetBrains.
the class GroovyTypeCheckVisitor method checkMethodApplicability.
private <T extends GroovyPsiElement> boolean checkMethodApplicability(@NotNull final GroovyResolveResult methodResolveResult, boolean checkUnknownArgs, @NotNull final CallInfo<T> info) {
final PsiElement element = methodResolveResult.getElement();
if (!(element instanceof PsiMethod))
return true;
if (element instanceof GrBuilderMethod)
return true;
final PsiMethod method = (PsiMethod) element;
if ("call".equals(method.getName()) && info.getInvokedExpression() instanceof GrReferenceExpression) {
final GrExpression qualifierExpression = ((GrReferenceExpression) info.getInvokedExpression()).getQualifierExpression();
if (qualifierExpression != null) {
final PsiType type = qualifierExpression.getType();
if (type instanceof GrClosureType) {
GrClosureSignatureUtil.ApplicabilityResult result = PsiUtil.isApplicableConcrete(info.getArgumentTypes(), (GrClosureType) type, info.getInvokedExpression());
switch(result) {
case inapplicable:
highlightInapplicableMethodUsage(methodResolveResult, info, method);
return false;
case //q(1,2)
canBeApplicable:
if (checkUnknownArgs) {
highlightUnknownArgs(info);
}
return !checkUnknownArgs;
default:
return true;
}
}
}
}
if (method instanceof GrGdkMethod && info.getInvokedExpression() instanceof GrReferenceExpression) {
final GrReferenceExpression invoked = (GrReferenceExpression) info.getInvokedExpression();
final GrExpression qualifier = PsiImplUtil.getRuntimeQualifier(invoked);
if (qualifier == null && method.getName().equals("call")) {
GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(invoked.getProject());
final GrReferenceExpression callRef = factory.createReferenceExpressionFromText("qualifier.call", invoked);
callRef.setQualifier(invoked);
return checkMethodApplicability(methodResolveResult, checkUnknownArgs, new DelegatingCallInfo<T>(info) {
@Nullable
@Override
public GrExpression getInvokedExpression() {
return callRef;
}
@NotNull
@Override
public GroovyResolveResult advancedResolve() {
return methodResolveResult;
}
@NotNull
@Override
public GroovyResolveResult[] multiResolve() {
return new GroovyResolveResult[] { methodResolveResult };
}
@Nullable
@Override
public PsiType getQualifierInstanceType() {
return info.getInvokedExpression().getType();
}
});
}
final PsiMethod staticMethod = ((GrGdkMethod) method).getStaticMethod();
PsiType qualifierType = info.getQualifierInstanceType();
if (method.hasModifierProperty(PsiModifier.STATIC)) {
qualifierType = ResolveUtil.unwrapClassType(qualifierType);
}
//check methods processed by @Category(ClassWhichProcessMethod) annotation
if (qualifierType != null && !GdkMethodUtil.isCategoryMethod(staticMethod, qualifierType, qualifier, methodResolveResult.getSubstitutor()) && !checkCategoryQualifier(invoked, qualifier, staticMethod, methodResolveResult.getSubstitutor())) {
registerError(info.getHighlightElementForCategoryQualifier(), ProblemHighlightType.GENERIC_ERROR, GroovyInspectionBundle.message("category.method.0.cannot.be.applied.to.1", method.getName(), qualifierType.getCanonicalText()));
return false;
}
}
if (info.getArgumentTypes() == null)
return true;
GrClosureSignatureUtil.ApplicabilityResult applicable = PsiUtil.isApplicableConcrete(info.getArgumentTypes(), method, methodResolveResult.getSubstitutor(), info.getCall(), false);
switch(applicable) {
case inapplicable:
highlightInapplicableMethodUsage(methodResolveResult, info, method);
return false;
case canBeApplicable:
if (checkUnknownArgs) {
highlightUnknownArgs(info);
}
return !checkUnknownArgs;
default:
return true;
}
}
use of org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType in project intellij-community by JetBrains.
the class GrClosureSignatureUtil method createSignature.
@Nullable
public static GrClosureSignature createSignature(GrCall call) {
if (call instanceof GrMethodCall) {
final GrExpression invokedExpression = ((GrMethodCall) call).getInvokedExpression();
final PsiType type = invokedExpression.getType();
if (type instanceof GrClosureType) {
final GrSignature signature = ((GrClosureType) type).getSignature();
final Trinity<GrClosureSignature, ArgInfo<PsiType>[], ApplicabilityResult> trinity = getApplicableSignature(signature, PsiUtil.getArgumentTypes(invokedExpression, true), call);
if (trinity != null) {
return trinity.first;
}
return null;
}
}
final GroovyResolveResult resolveResult = call.advancedResolve();
final PsiElement element = resolveResult.getElement();
if (element instanceof PsiMethod) {
return createSignature((PsiMethod) element, resolveResult.getSubstitutor());
}
return null;
}
use of org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType in project intellij-community by JetBrains.
the class DefaultCallExpressionTypeCalculator method getClosureMethodsReturnType.
@Nullable
private static PsiType getClosureMethodsReturnType(GrMethodCall callExpression, GrReferenceExpression refExpr, PsiMethod resolved) {
PsiClass clazz = resolved.getContainingClass();
if (clazz == null || !GroovyCommonClassNames.GROOVY_LANG_CLOSURE.equals(clazz.getQualifiedName()))
return null;
if (!CLOSURE_METHODS.contains(resolved.getName()))
return null;
GrExpression qualifier = refExpr.getQualifierExpression();
if (qualifier == null)
return null;
PsiType qType = qualifier.getType();
if (!(qType instanceof GrClosureType))
return null;
if ("call".equals(resolved.getName())) {
return GrClosureSignatureUtil.getReturnType(((GrClosureType) qType).getSignature(), callExpression);
} else if ("curry".equals(resolved.getName()) || "trampoline".equals(resolved.getName())) {
return ((GrClosureType) qType).curry(PsiUtil.getArgumentTypes(refExpr, false), 0, callExpression);
} else if ("memoize".equals(resolved.getName())) {
return qType;
} else if ("rcurry".equals(resolved.getName())) {
return ((GrClosureType) qType).curry(PsiUtil.getArgumentTypes(refExpr, false), -1, callExpression);
} else if ("ncurry".equals(resolved.getName())) {
final GrArgumentList argList = callExpression.getArgumentList();
final GrExpression[] arguments = argList.getExpressionArguments();
if (arguments.length > 0) {
final GrExpression first = arguments[0];
if (first instanceof GrLiteral) {
final Object value = ((GrLiteral) first).getValue();
if (value instanceof Integer) {
final PsiType[] argTypes = PsiUtil.getArgumentTypes(refExpr, false);
if (argTypes != null) {
return ((GrClosureType) qType).curry(ArrayUtil.remove(argTypes, 0), (Integer) value, callExpression);
}
}
}
}
return qType;
}
return null;
}
use of org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType in project intellij-community by JetBrains.
the class ClosureToSamConverter method isConvertible.
@Override
public Boolean isConvertible(@NotNull PsiType ltype, @NotNull PsiType rtype, @NotNull final GroovyPsiElement context) {
if (rtype instanceof GrClosureType && ltype instanceof PsiClassType && isSamConversionAllowed(context) && !TypesUtil.isClassType(ltype, GroovyCommonClassNames.GROOVY_LANG_CLOSURE)) {
MethodSignature signature = findSAMSignature(ltype);
if (signature != null) {
final PsiType[] samParameterTypes = signature.getParameterTypes();
GrSignature closureSignature = ((GrClosureType) rtype).getSignature();
boolean raw = ((PsiClassType) ltype).isRaw();
if (raw)
return true;
if (GrClosureSignatureUtil.isSignatureApplicable(closureSignature, samParameterTypes, context)) {
return true;
}
}
}
return null;
}
Aggregations