mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-50450 Gradle code insight. 'configurations' resolving added
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
|
||||
<resolve.contributor implementation="org.jetbrains.plugins.gradle.service.resolve.GradleRepositoriesContributor"/>
|
||||
<resolve.contributor implementation="org.jetbrains.plugins.gradle.service.resolve.GradleDependenciesContributor"/>
|
||||
<resolve.contributor implementation="org.jetbrains.plugins.gradle.service.resolve.GradleConfigurationsContributor"/>
|
||||
<resolve.contributor implementation="org.jetbrains.plugins.gradle.service.resolve.GradleRootContributor"/>
|
||||
</extensions>
|
||||
|
||||
@@ -72,6 +73,7 @@
|
||||
<groovyFrameworkConfigNotification implementation="org.jetbrains.plugins.gradle.config.GradleGroovyConfigNotification"/>
|
||||
|
||||
<membersContributor implementation="org.jetbrains.plugins.gradle.service.resolve.GradleScriptContributor"/>
|
||||
<membersContributor implementation="org.jetbrains.plugins.gradle.service.resolve.GradleConfigurationsNonCodeMembersContributor"/>
|
||||
<methodDescriptor class="org.gradle.api.Project" name="apply">
|
||||
<namedArgument name="plugin" values="java,groovy,idea,eclipse,scala,antlr,application,ear,jetty,maven,osgi,war,announce,build-announcements,checkstyle,codenarc,eclipse-wtp,findbugs,jdepend,pmd,project-report,signing,sonar"/>
|
||||
</methodDescriptor>
|
||||
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.gradle.service.resolve;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiVariable;
|
||||
import com.intellij.psi.ResolveState;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.artifacts.ConfigurationContainer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceExpressionImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrImplicitVariableImpl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
* @since 8/29/13
|
||||
*/
|
||||
public class GradleConfigurationsContributor implements GradleMethodContextContributor {
|
||||
|
||||
private static final String CONFIGURATIONS = "configurations";
|
||||
|
||||
@Override
|
||||
public void process(@NotNull List<String> methodCallInfo,
|
||||
@NotNull PsiScopeProcessor processor,
|
||||
@NotNull ResolveState state,
|
||||
@NotNull PsiElement place) {
|
||||
if (methodCallInfo.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
final String methodCall = methodCallInfo.get(0);
|
||||
|
||||
PsiClass contributorClass = null;
|
||||
GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
|
||||
if (methodCallInfo.size() == 1) {
|
||||
if (methodCall.startsWith(CONFIGURATIONS + '.')) {
|
||||
contributorClass = psiManager.findClassWithCache(Configuration.class.getName(), place.getResolveScope());
|
||||
}
|
||||
else if (CONFIGURATIONS.equals(methodCall)) {
|
||||
contributorClass = psiManager.findClassWithCache(ConfigurationContainer.class.getName(), place.getResolveScope());
|
||||
if (place instanceof GrReferenceExpressionImpl) {
|
||||
addImplicitConfiguration(processor, state, (GrReferenceExpressionImpl)place);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (methodCallInfo.size() == 2) {
|
||||
if (CONFIGURATIONS.equals(methodCallInfo.get(1))) {
|
||||
contributorClass = psiManager.findClassWithCache(ConfigurationContainer.class.getName(), place.getResolveScope());
|
||||
if (place instanceof GrReferenceExpressionImpl) {
|
||||
addImplicitConfiguration(processor, state, (GrReferenceExpressionImpl)place);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (contributorClass != null) {
|
||||
contributorClass.processDeclarations(processor, state, null, place);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("MethodMayBeStatic")
|
||||
private void addImplicitConfiguration(@NotNull PsiScopeProcessor processor,
|
||||
@NotNull ResolveState state,
|
||||
@NotNull GrReferenceExpressionImpl expression) {
|
||||
String expr = expression.getCanonicalText();
|
||||
PsiVariable myPsi = new GrImplicitVariableImpl(expression.getManager(), expr, Configuration.class.getName(), expression);
|
||||
processor.execute(myPsi, state);
|
||||
}
|
||||
}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.gradle.service.resolve;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.light.LightElement;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import groovy.lang.Closure;
|
||||
import org.gradle.api.artifacts.Configuration;
|
||||
import org.gradle.api.artifacts.ConfigurationContainer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceExpressionImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrImplicitVariableImpl;
|
||||
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.resolve.NonCodeMembersContributor;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
* @since 8/30/13
|
||||
*/
|
||||
public class GradleConfigurationsNonCodeMembersContributor extends NonCodeMembersContributor {
|
||||
|
||||
private static final String METHOD_GET_BY_NAME = "getByName";
|
||||
|
||||
@Override
|
||||
public void processDynamicElements(@NotNull PsiType qualifierType,
|
||||
PsiClass aClass,
|
||||
PsiScopeProcessor processor,
|
||||
PsiElement place,
|
||||
ResolveState state) {
|
||||
if (place == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ConfigurationContainer.class.getName().equals(aClass.getQualifiedName())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Assuming that the method call is equivalent to calling ConfigurationContainer.getByName()
|
||||
processConfigurationAddition(aClass, processor, state, place);
|
||||
}
|
||||
|
||||
@SuppressWarnings("MethodMayBeStatic")
|
||||
private void processConfigurationAddition(@NotNull PsiClass dependencyHandlerClass,
|
||||
@NotNull PsiScopeProcessor processor,
|
||||
@NotNull ResolveState state,
|
||||
@NotNull PsiElement place) {
|
||||
|
||||
GrMethodCall call = PsiTreeUtil.getParentOfType(place, GrMethodCall.class);
|
||||
if (call == null) {
|
||||
// TODO replace with groovy implicit method
|
||||
GrReferenceExpressionImpl expression = (GrReferenceExpressionImpl)place;
|
||||
String expr = expression.getCanonicalText();
|
||||
GrImplicitVariableImpl myPsi = new GrImplicitVariableImpl(place.getManager(), expr, Configuration.class.getName(), place);
|
||||
processor.execute(myPsi, state);
|
||||
setNavigation(myPsi, dependencyHandlerClass, METHOD_GET_BY_NAME, 1);
|
||||
return;
|
||||
}
|
||||
GrArgumentList args = call.getArgumentList();
|
||||
if (args == null) {
|
||||
return;
|
||||
}
|
||||
int argsCount = GradleResolverUtil.getGrMethodArumentsCount(args);
|
||||
|
||||
argsCount++; // Configuration name is delivered as an argument.
|
||||
|
||||
if (argsCount == 1) {
|
||||
GrLightMethodBuilder builder = new GrLightMethodBuilder(place.getManager(), METHOD_GET_BY_NAME);
|
||||
PsiClassType type = PsiType.getJavaLangObject(place.getManager(), place.getResolveScope());
|
||||
builder.addParameter(new GrLightParameter("s", type, builder));
|
||||
processor.execute(builder, state);
|
||||
|
||||
argsCount++; // we need method with extra argument of type Closure.
|
||||
setNavigation(builder, dependencyHandlerClass, METHOD_GET_BY_NAME, argsCount);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("MethodMayBeStatic")
|
||||
private void setNavigation(LightElement element, PsiClass dependencyHandlerClass, String methodName, int parametersCount) {
|
||||
for (PsiMethod method : dependencyHandlerClass.findMethodsByName(methodName, false)) {
|
||||
int methodParameterCount = method.getParameterList().getParametersCount();
|
||||
if (methodParameterCount == parametersCount &&
|
||||
method.getParameterList().getParameters()[methodParameterCount - 1].getType().equalsToText(Closure.class.getName())) {
|
||||
element.setNavigationElement(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-17
@@ -35,7 +35,7 @@ import java.util.List;
|
||||
* @since 8/14/13 12:58 PM
|
||||
*/
|
||||
public class GradleDependenciesContributor implements GradleMethodContextContributor {
|
||||
|
||||
|
||||
@Override
|
||||
public void process(@NotNull List<String> methodCallInfo,
|
||||
@NotNull PsiScopeProcessor processor,
|
||||
@@ -50,7 +50,7 @@ public class GradleDependenciesContributor implements GradleMethodContextContrib
|
||||
if (i != 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Assuming that the method call is addition of new dependency into configuration.
|
||||
GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
|
||||
PsiClass contributorClass = psiManager.findClassWithCache(DependencyHandler.class.getName(), place.getResolveScope());
|
||||
@@ -70,7 +70,7 @@ public class GradleDependenciesContributor implements GradleMethodContextContrib
|
||||
PsiClassType type = PsiType.getJavaLangObject(place.getManager(), place.getResolveScope());
|
||||
builder.addParameter(new GrLightParameter("dependencyInfo", type, builder));
|
||||
processor.execute(builder, state);
|
||||
|
||||
|
||||
GrMethodCall call = PsiTreeUtil.getParentOfType(place, GrMethodCall.class);
|
||||
if (call == null) {
|
||||
return;
|
||||
@@ -79,20 +79,8 @@ public class GradleDependenciesContributor implements GradleMethodContextContrib
|
||||
if (args == null) {
|
||||
return;
|
||||
}
|
||||
int argsCount = 0;
|
||||
boolean namedArgProcessed = false;
|
||||
for (GroovyPsiElement arg : args.getAllArguments()) {
|
||||
if (arg instanceof GrNamedArgument) {
|
||||
if (!namedArgProcessed) {
|
||||
namedArgProcessed = true;
|
||||
argsCount++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
argsCount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int argsCount = GradleResolverUtil.getGrMethodArumentsCount(args);
|
||||
argsCount++; // Configuration name is delivered as an argument.
|
||||
|
||||
for (PsiMethod method : dependencyHandlerClass.findMethodsByName("add", false)) {
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.gradle.service.resolve;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
* @since 8/30/13
|
||||
*/
|
||||
public class GradleResolverUtil {
|
||||
|
||||
public static int getGrMethodArumentsCount(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;
|
||||
}
|
||||
}
|
||||
+13
-2
@@ -19,12 +19,13 @@ import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.ResolveState;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.gradle.api.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
@@ -32,12 +33,22 @@ import java.util.List;
|
||||
*/
|
||||
public class GradleRootContributor implements GradleMethodContextContributor {
|
||||
|
||||
private final static Set<String> PROJECT_ACTIONS = ContainerUtil.newHashSet(
|
||||
"subprojects",
|
||||
"allprojects",
|
||||
"beforeEvaluate",
|
||||
"afterEvaluate");
|
||||
|
||||
@Override
|
||||
public void process(@NotNull List<String> methodCallInfo,
|
||||
@NotNull PsiScopeProcessor processor,
|
||||
@NotNull ResolveState state,
|
||||
@NotNull PsiElement place) {
|
||||
if (methodCallInfo.size() > 1) {
|
||||
if(methodCallInfo.size() > 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (methodCallInfo.size() == 2 && !PROJECT_ACTIONS.contains(methodCallInfo.get(1))) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user