blob: 6f487583ee452d8c37acf137f41aa332adcf4062 [file]
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.gradle.service.resolve;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.util.GradleLog;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightParameter;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
import java.util.Arrays;
/**
* @author Vladislav.Soroka
*/
public class GradleResolverUtil {
public static int getGrMethodArumentsCount(@NotNull GrArgumentList args) {
int argsCount = 0;
boolean namedArgProcessed = false;
for (GroovyPsiElement arg : args.getAllArguments()) {
if (arg instanceof GrNamedArgument) {
if (!namedArgProcessed) {
namedArgProcessed = true;
argsCount++;
}
}
else {
argsCount++;
}
}
return argsCount;
}
@Nullable
public static GrLightMethodBuilder createMethodWithClosure(@NotNull String name,
@Nullable String returnType,
@Nullable String closureTypeParameter,
@NotNull PsiElement place) {
PsiClassType closureType;
PsiClass closureClass =
JavaPsiFacade.getInstance(place.getProject()).findClass(GroovyCommonClassNames.GROOVY_LANG_CLOSURE, place.getResolveScope());
if (closureClass == null) return null;
if (closureClass.getTypeParameters().length != 1) {
GradleLog.LOG.debug(String.format("Unexpected type parameters found for closureClass(%s) : (%s)",
closureClass, Arrays.toString(closureClass.getTypeParameters())));
return null;
}
PsiElementFactory factory = JavaPsiFacade.getElementFactory(place.getManager().getProject());
if (closureTypeParameter != null) {
PsiClassType closureClassTypeParameter =
factory.createTypeByFQClassName(closureTypeParameter, place.getResolveScope());
closureType = factory.createType(closureClass, closureClassTypeParameter);
}
else {
PsiClassType closureClassTypeParameter =
factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, place.getResolveScope());
closureType = factory.createType(closureClass, closureClassTypeParameter);
}
GrLightMethodBuilder methodWithClosure = new GrLightMethodBuilder(place.getManager(), name);
GrLightParameter closureParameter = new GrLightParameter("closure", closureType, methodWithClosure);
methodWithClosure.addParameter(closureParameter);
PsiClassType retType = factory.createTypeByFQClassName(
returnType != null ? returnType : CommonClassNames.JAVA_LANG_OBJECT, place.getResolveScope());
methodWithClosure.setReturnType(retType);
methodWithClosure.setContainingClass(retType.resolve());
return methodWithClosure;
}
@Nullable
public static PsiElement findParent(@NotNull PsiElement element, int level) {
PsiElement parent = element;
do {
parent = parent.getParent();
}
while (parent != null && --level > 0);
return parent;
}
@Nullable
public static <T extends PsiElement> T findParent(@NotNull PsiElement element, Class<T> clazz) {
PsiElement parent = element;
do {
parent = parent.getParent();
if (clazz.isInstance(parent)) {
//noinspection unchecked
return (T)parent;
}
}
while (parent != null && !(parent instanceof GroovyFile));
return null;
}
public static boolean canBeMethodOf(@Nullable String methodName, @Nullable PsiClass aClass) {
return methodName != null && aClass != null && aClass.findMethodsByName(methodName, true).length != 0;
}
@Nullable
public static PsiType getTypeOf(@Nullable final GrExpression expression) {
if (expression == null) return null;
return RecursionManager.doPreventingRecursion(expression, true, () -> expression.getNominalType());
}
public static boolean isLShiftElement(@Nullable PsiElement psiElement) {
return (psiElement instanceof GrBinaryExpression &&
GroovyElementTypes.COMPOSITE_LSHIFT_SIGN.equals(((GrBinaryExpression)psiElement).getOperationTokenType()));
}
}