diff --git a/plugins/gradle/src/META-INF/gradle-maven-integration.xml b/plugins/gradle/src/META-INF/gradle-maven-integration.xml
index 2cd12be2fd38..ca045a5fa847 100644
--- a/plugins/gradle/src/META-INF/gradle-maven-integration.xml
+++ b/plugins/gradle/src/META-INF/gradle-maven-integration.xml
@@ -21,7 +21,7 @@
-
+
+
diff --git a/plugins/gradle/src/META-INF/plugin.xml b/plugins/gradle/src/META-INF/plugin.xml
index 93266441ebdc..c6c51716bb61 100644
--- a/plugins/gradle/src/META-INF/plugin.xml
+++ b/plugins/gradle/src/META-INF/plugin.xml
@@ -58,19 +58,16 @@
-
-
+
+
-
-
-
-
+
@@ -153,6 +150,8 @@
implementationClass="org.jetbrains.plugins.gradle.documentation.GradleDocumentationProvider"/>
+
-
+
@@ -170,10 +169,7 @@
-
-
-
-
+
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleArtifactsContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleArtifactsContributor.java
deleted file mode 100644
index 9c8eca1dac2f..000000000000
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleArtifactsContributor.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2000-2016 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.scope.PsiScopeProcessor;
-import com.intellij.psi.util.PsiTreeUtil;
-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.GroovyPsiManager;
-import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceExpressionImpl;
-import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
-import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightParameter;
-
-import java.util.List;
-
-/**
- * @author Vladislav.Soroka
- * @since 8/30/13
- */
-public class GradleArtifactsContributor implements GradleMethodContextContributor {
-
- @Override
- public void process(@NotNull List methodCallInfo,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull PsiElement place) {
- if (methodCallInfo.isEmpty() || methodCallInfo.size() < 2 || !"artifacts".equals(methodCallInfo.get(1))) {
- return;
- }
- final String text = place.getText();
- if (!methodCallInfo.contains(text) && place instanceof GrReferenceExpressionImpl) {
- GradleResolverUtil.addImplicitVariable(processor, state, (GrReferenceExpressionImpl)place, Object.class.getName());
- return;
- }
-
- GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
- GradleResolverUtil.processDeclarations(psiManager, processor, state, place, GradleCommonClassNames.GRADLE_API_ARTIFACT_HANDLER);
- PsiClass contributorClass = psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_ARTIFACT_HANDLER, place.getResolveScope());
- if (contributorClass != null) {
- // assuming that the method call is addition of an artifact to the given configuration.
- processAtrifactAddition(methodCallInfo.get(0), contributorClass, processor, state, place);
- }
- }
-
- private static void processAtrifactAddition(@NotNull String gradleConfigurationName,
- @NotNull PsiClass artifactHandlerClass,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull PsiElement place) {
- GrLightMethodBuilder builder = new GrLightMethodBuilder(place.getManager(), gradleConfigurationName);
- PsiClassType type = PsiType.getJavaLangObject(place.getManager(), place.getResolveScope());
- builder.addParameter(new GrLightParameter("artifactInfo", type, builder));
- processor.execute(builder, state);
-
- GrMethodCall call = PsiTreeUtil.getParentOfType(place, GrMethodCall.class);
- if (call == null) {
- return;
- }
- GrArgumentList args = call.getArgumentList();
-
- int argsCount = GradleResolverUtil.getGrMethodArumentsCount(args);
- argsCount++; // Configuration name is delivered as an argument.
-
- for (PsiMethod method : artifactHandlerClass.findMethodsByName("add", false)) {
- if (method.getParameterList().getParametersCount() == argsCount) {
- builder.setNavigationElement(method);
- }
- }
- }
-}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleArtifactsContributor.kt b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleArtifactsContributor.kt
new file mode 100644
index 000000000000..a2dabe81ec5c
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleArtifactsContributor.kt
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2000-2016 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.patterns.PsiJavaPatterns.psiElement
+import com.intellij.psi.CommonClassNames.JAVA_LANG_OBJECT
+import com.intellij.psi.PsiClass
+import com.intellij.psi.PsiElement
+import com.intellij.psi.PsiType
+import com.intellij.psi.ResolveState
+import com.intellij.psi.scope.PsiScopeProcessor
+import com.intellij.psi.util.PsiTreeUtil
+import groovy.lang.Closure
+import org.jetbrains.plugins.gradle.service.resolve.GradleCommonClassNames.GRADLE_API_ARTIFACT_HANDLER
+import org.jetbrains.plugins.gradle.service.resolve.GradleCommonClassNames.GRADLE_API_PROJECT
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression
+import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager
+import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil
+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.patterns.groovyClosure
+import org.jetbrains.plugins.groovy.lang.psi.patterns.psiMethod
+import org.jetbrains.plugins.groovy.lang.resolve.delegatesTo.DelegatesToInfo
+
+/**
+ * @author Vladislav.Soroka
+ * *
+ * @since 8/30/13
+ */
+class GradleArtifactsContributor : GradleMethodContextContributor {
+
+ companion object {
+ val artifactsClosure = groovyClosure().inMethod(psiMethod(GRADLE_API_PROJECT, "artifacts"))
+ }
+
+ override fun process(methodCallInfo: List,
+ processor: PsiScopeProcessor,
+ state: ResolveState,
+ place: PsiElement): Boolean {
+ val psiManager = GroovyPsiManager.getInstance(place.project)
+ val methodName = if (methodCallInfo.isNotEmpty()) methodCallInfo[0] else null
+ if (methodName != null && place is GrReferenceExpression && psiElement().inside(artifactsClosure).accepts(place)) {
+ val text = place.text
+ if (!methodCallInfo.contains(text) && place is GrReferenceExpression) {
+ GradleResolverUtil.addImplicitVariable(processor, state, place, JAVA_LANG_OBJECT)
+ return false
+ }
+
+ if (!GradleResolverUtil.processDeclarations(psiManager, processor, state, place, GRADLE_API_ARTIFACT_HANDLER)) return false
+ val contributorClass = psiManager.findClassWithCache(GRADLE_API_ARTIFACT_HANDLER, place.resolveScope)
+ if (contributorClass != null) {
+ // assuming that the method call is addition of an artifact to the given configuration.
+ if (!processArtifactAddition(methodCallInfo[0], contributorClass, processor, state, place)) return false
+ }
+ }
+ return true
+ }
+
+ override fun getDelegatesToInfo(closure: GrClosableBlock): DelegatesToInfo? {
+ if (artifactsClosure.accepts(closure)) {
+ return DelegatesToInfo(TypesUtil.createType(GRADLE_API_ARTIFACT_HANDLER, closure), Closure.DELEGATE_FIRST)
+ }
+ return null
+ }
+
+ private fun processArtifactAddition(gradleConfigurationName: String,
+ artifactHandlerClass: PsiClass,
+ processor: PsiScopeProcessor,
+ state: ResolveState,
+ place: PsiElement): Boolean {
+ val call = PsiTreeUtil.getParentOfType(place, GrMethodCall::class.java) ?: return true
+ val builder = GrLightMethodBuilder(place.manager, gradleConfigurationName)
+ val type = PsiType.getJavaLangObject(place.manager, place.resolveScope)
+ builder.addParameter(GrLightParameter("artifactInfo", type, builder))
+ val args = call.argumentList
+
+ var argsCount = GradleResolverUtil.getGrMethodArumentsCount(args)
+ argsCount++ // Configuration name is delivered as an argument.
+
+ for (method in artifactHandlerClass.findMethodsByName("add", false)) {
+ if (method.parameterList.parametersCount == argsCount) {
+ builder.navigationElement = method
+ }
+ }
+
+ return processor.execute(builder, state)
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleBuildScriptContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleBuildScriptContributor.java
deleted file mode 100644
index 735c92eac24c..000000000000
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleBuildScriptContributor.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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;
-
-/**
- * @author Vladislav.Soroka
- * @since 8/30/13
- */
-public class GradleBuildScriptContributor extends GradleSimpleContributor {
- public GradleBuildScriptContributor() {
- super("buildscript", GradleCommonClassNames.GRADLE_API_SCRIPT_HANDLER);
- }
-}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleBuildScriptContributor.kt b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleBuildScriptContributor.kt
new file mode 100644
index 000000000000..3c211c8937b4
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleBuildScriptContributor.kt
@@ -0,0 +1,41 @@
+/*
+ * 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 groovy.lang.Closure
+import org.jetbrains.plugins.gradle.service.resolve.GradleCommonClassNames.*
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock
+import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil
+import org.jetbrains.plugins.groovy.lang.psi.patterns.groovyClosure
+import org.jetbrains.plugins.groovy.lang.psi.patterns.psiMethod
+import org.jetbrains.plugins.groovy.lang.resolve.delegatesTo.DelegatesToInfo
+
+/**
+ * @author Vladislav.Soroka
+ * @since 8/30/13
+ */
+class GradleBuildScriptContributor : GradleMethodContextContributor {
+ companion object {
+ val buildscriptClosure = groovyClosure().inMethod(psiMethod(GRADLE_API_PROJECT, "buildscript"))
+ }
+
+ override fun getDelegatesToInfo(closure: GrClosableBlock): DelegatesToInfo? {
+ if (buildscriptClosure.accepts(closure)) {
+ return DelegatesToInfo(TypesUtil.createType(GRADLE_API_SCRIPT_HANDLER, closure), Closure.DELEGATE_FIRST)
+ }
+ return null
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleCommonClassNames.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleCommonClassNames.java
index 0162e5451d51..55eed83302ca 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleCommonClassNames.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleCommonClassNames.java
@@ -24,11 +24,18 @@ import org.jetbrains.annotations.NonNls;
public final class GradleCommonClassNames {
@NonNls public static final String GRADLE_API_SCRIPT = "org.gradle.api.Script";
@NonNls public static final String GRADLE_API_PROJECT = "org.gradle.api.Project";
+ @NonNls public static final String GRADLE_API_BASE_PLUGIN_CONVENTION = "org.gradle.api.plugins.BasePluginConvention";
+ @NonNls public static final String GRADLE_API_JAVA_PLUGIN_CONVENTION = "org.gradle.api.plugins.JavaPluginConvention";
+ @NonNls public static final String GRADLE_API_APPLICATION_PLUGIN_CONVENTION = "org.gradle.api.plugins.ApplicationPluginConvention";
+ @NonNls public static final String GRADLE_API_WAR_CONVENTION = "org.gradle.api.plugins.WarPluginConvention";
@NonNls public static final String GRADLE_API_CONFIGURATION_CONTAINER = "org.gradle.api.artifacts.ConfigurationContainer";
+ @NonNls public static final String GRADLE_API_DEPENDENCY_SUBSTITUTIONS = "org.gradle.api.artifacts.DependencySubstitutions";
+ @NonNls public static final String GRADLE_API_RESOLUTION_STRATEGY = "org.gradle.api.artifacts.ResolutionStrategy";
@NonNls public static final String GRADLE_API_CONFIGURATION = "org.gradle.api.artifacts.Configuration";
@NonNls public static final String GRADLE_API_ARTIFACT_HANDLER = "org.gradle.api.artifacts.dsl.ArtifactHandler";
@NonNls public static final String GRADLE_API_DEPENDENCY_HANDLER = "org.gradle.api.artifacts.dsl.DependencyHandler";
@NonNls public static final String GRADLE_API_ARTIFACTS_EXTERNAL_MODULE_DEPENDENCY = "org.gradle.api.artifacts.ExternalModuleDependency";
+ @NonNls public static final String GRADLE_API_ARTIFACTS_CLIENT_MODULE_DEPENDENCY = "org.gradle.api.artifacts.ClientModule";
@NonNls public static final String GRADLE_API_ARTIFACTS_MODULE_DEPENDENCY = "org.gradle.api.artifacts.ModuleDependency";
@NonNls public static final String GRADLE_API_ARTIFACTS_DEPENDENCY_ARTIFACT = "org.gradle.api.artifacts.DependencyArtifact";
@NonNls public static final String GRADLE_API_REPOSITORY_HANDLER = "org.gradle.api.artifacts.dsl.RepositoryHandler";
@@ -59,6 +66,7 @@ public final class GradleCommonClassNames {
@NonNls public static final String GRADLE_BUILDSETUP_TASKS_SETUP_BUILD = "org.gradle.buildsetup.tasks.SetupBuild";
@NonNls public static final String GRADLE_API_TASK_CONTAINER = "org.gradle.api.tasks.TaskContainer";
@NonNls public static final String GRADLE_API_JAVA_ARCHIVES_MANIFEST = "org.gradle.api.java.archives.Manifest";
+ @NonNls public static final String GRADLE_API_DOMAIN_OBJECT_COLLECTION = "org.gradle.api.DomainObjectCollection";
@NonNls public static final String GRADLE_API_NAMED_DOMAIN_OBJECT_COLLECTION = "org.gradle.api.NamedDomainObjectCollection";
@NonNls public static final String GRADLE_API_ARTIFACTS_REPOSITORIES_MAVEN_ARTIFACT_REPOSITORY = "org.gradle.api.artifacts.repositories.MavenArtifactRepository";
@NonNls public static final String GRADLE_API_ARTIFACTS_MAVEN_MAVEN_DEPLOYER = "org.gradle.api.artifacts.maven.MavenDeployer";
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleConfigurationsContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleConfigurationsContributor.java
deleted file mode 100644
index 9cbe87c6ae72..000000000000
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleConfigurationsContributor.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.PsiElement;
-import com.intellij.psi.ResolveState;
-import com.intellij.psi.scope.PsiScopeProcessor;
-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 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 methodCallInfo,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull PsiElement place) {
- if (methodCallInfo.isEmpty()) {
- return;
- }
- final String methodCall = methodCallInfo.get(0);
-
- String contributorClass = null;
- if (methodCallInfo.size() == 1) {
- if (methodCall.startsWith(CONFIGURATIONS + '.')) {
- contributorClass = GradleCommonClassNames.GRADLE_API_CONFIGURATION;
- }
- else if (CONFIGURATIONS.equals(methodCall)) {
- contributorClass = GradleCommonClassNames.GRADLE_API_CONFIGURATION_CONTAINER;
- if (place instanceof GrReferenceExpressionImpl) {
- GradleResolverUtil
- .addImplicitVariable(processor, state, (GrReferenceExpressionImpl)place, GradleCommonClassNames.GRADLE_API_CONFIGURATION);
- return;
- }
- }
- }
- else if (methodCallInfo.size() == 2) {
- if (CONFIGURATIONS.equals(methodCallInfo.get(1))) {
- contributorClass = GradleCommonClassNames.GRADLE_API_CONFIGURATION_CONTAINER;
- if (place instanceof GrReferenceExpressionImpl) {
- GradleResolverUtil
- .addImplicitVariable(processor, state, (GrReferenceExpressionImpl)place, GradleCommonClassNames.GRADLE_API_CONFIGURATION);
- return;
- }
- }
- }
- if (contributorClass != null) {
- GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
- GradleResolverUtil.processDeclarations(psiManager, processor, state, place, contributorClass);
- }
- }
-}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleConfigurationsContributor.kt b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleConfigurationsContributor.kt
new file mode 100644
index 000000000000..79fa41a9522e
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleConfigurationsContributor.kt
@@ -0,0 +1,107 @@
+/*
+ * 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.patterns.ElementPattern
+import com.intellij.patterns.PsiJavaPatterns.psiElement
+import com.intellij.psi.PsiElement
+import com.intellij.psi.ResolveState
+import com.intellij.psi.scope.PsiScopeProcessor
+import com.intellij.psi.util.PsiTreeUtil
+import com.intellij.util.ProcessingContext
+import groovy.lang.Closure
+import org.jetbrains.plugins.gradle.service.resolve.GradleCommonClassNames.*
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression
+import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager
+import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil
+import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightVariable
+import org.jetbrains.plugins.groovy.lang.psi.patterns.groovyClosure
+import org.jetbrains.plugins.groovy.lang.psi.patterns.psiMethod
+import org.jetbrains.plugins.groovy.lang.resolve.delegatesTo.DelegatesToInfo
+import org.jetbrains.plugins.groovy.lang.resolve.delegatesTo.getContainingCall
+import org.jetbrains.plugins.groovy.lang.resolve.delegatesTo.resolveActualCall
+
+/**
+ * @author Vladislav.Soroka
+ * *
+ * @since 8/29/13
+ */
+class GradleConfigurationsContributor : GradleMethodContextContributor {
+
+ companion object {
+ val configurationsClosure = groovyClosure().inMethod(psiMethod(GRADLE_API_PROJECT, "configurations"))
+ val configurationReference = object : ElementPattern {
+ override fun getCondition() = null
+ override fun accepts(o: Any?) = false
+ override fun accepts(o: Any?, context: ProcessingContext): Boolean {
+ return o is GrExpression && o.type?.equalsToText(GRADLE_API_CONFIGURATION) ?: false
+ }
+ }
+ val configurationClosure = groovyClosure().inMethod(psiMethod(GRADLE_API_DOMAIN_OBJECT_COLLECTION, "all"))
+ val dependencySubstitutionClosure = groovyClosure().inMethod(psiMethod(GRADLE_API_RESOLUTION_STRATEGY, "dependencySubstitution"))
+ }
+
+ override fun getDelegatesToInfo(closure: GrClosableBlock): DelegatesToInfo? {
+ if (configurationsClosure.accepts(closure)) {
+ return DelegatesToInfo(TypesUtil.createType(GRADLE_API_CONFIGURATION_CONTAINER, closure), Closure.DELEGATE_FIRST)
+ }
+
+ // // resolve configuration ref closure:
+ // configurations.myConfiguration {
+ // extendsFrom(configurations.testCompile)
+ // }
+ if (psiElement().withParent(psiElement().withFirstChild(configurationReference)).accepts(closure)) {
+ return DelegatesToInfo(TypesUtil.createType(GRADLE_API_CONFIGURATION, closure), Closure.DELEGATE_FIRST)
+ }
+
+ if (dependencySubstitutionClosure.accepts(closure)) {
+ return DelegatesToInfo(TypesUtil.createType(GRADLE_API_DEPENDENCY_SUBSTITUTIONS, closure), Closure.DELEGATE_FIRST)
+ }
+ return null
+ }
+
+
+ override fun process(methodCallInfo: List, processor: PsiScopeProcessor, state: ResolveState, place: PsiElement): Boolean {
+ val psiManager = GroovyPsiManager.getInstance(place.project)
+ val psiElement = psiElement()
+
+ if (psiElement.inside(configurationClosure).accepts(place)) {
+ val closure = PsiTreeUtil.getParentOfType(place, GrClosableBlock::class.java) ?: return true
+ val call = getContainingCall(closure) ?: return true
+ val result = resolveActualCall(call)
+ for (psiType in result.substitutor.substitutionMap.values) {
+ if (psiType.equalsToText(GRADLE_API_CONFIGURATION)) {
+ if (!GradleResolverUtil.processDeclarations(psiManager, processor, state, place, GRADLE_API_CONFIGURATION)) return false
+ return false
+ }
+ }
+ }
+
+ if (psiElement.inside(configurationsClosure).accepts(place)) {
+ val name = place.text
+ if (place.parent is GrReferenceExpression || place.parent is GrArgumentList ||
+ psiElement.withTreeParent(configurationsClosure).accepts(place)) {
+ val variable = GrLightVariable(place.manager, name, GRADLE_API_CONFIGURATION, place)
+ if (!processor.execute(variable, state)) return false
+ }
+ }
+
+ return true
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleConfigurationsNonCodeMembersContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleConfigurationsNonCodeMembersContributor.java
deleted file mode 100644
index 50e448a0b5ce..000000000000
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleConfigurationsNonCodeMembersContributor.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2000-2014 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 org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-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;
-
-import static org.jetbrains.plugins.gradle.service.resolve.GradleCommonClassNames.GRADLE_API_CONFIGURATION;
-import static org.jetbrains.plugins.gradle.service.resolve.GradleCommonClassNames.GRADLE_API_CONFIGURATION_CONTAINER;
-import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.GROOVY_LANG_CLOSURE;
-
-/**
- * @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,
- @Nullable PsiClass aClass,
- @NotNull PsiScopeProcessor processor,
- @NotNull PsiElement place,
- @NotNull ResolveState state) {
- if (aClass == null) {
- return;
- }
-
- if (!GRADLE_API_CONFIGURATION_CONTAINER.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
- if(place instanceof GrReferenceExpressionImpl) {
- GrReferenceExpressionImpl expression = (GrReferenceExpressionImpl)place;
- String expr = expression.getCanonicalText();
- GrImplicitVariableImpl myPsi = new GrImplicitVariableImpl(place.getManager(), expr, GRADLE_API_CONFIGURATION, place);
- processor.execute(myPsi, state);
- setNavigation(myPsi, dependencyHandlerClass, METHOD_GET_BY_NAME, 1);
- }
- return;
- }
- GrArgumentList args = call.getArgumentList();
- 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(GROOVY_LANG_CLOSURE)) {
- element.setNavigationElement(method);
- }
- }
- }
-}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDelegatesToProvider.kt b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDelegatesToProvider.kt
new file mode 100644
index 000000000000..276b42ec6ec5
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDelegatesToProvider.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2016 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.openapi.util.io.FileUtilRt
+import org.jetbrains.plugins.gradle.util.GradleConstants
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock
+import org.jetbrains.plugins.groovy.lang.resolve.delegatesTo.DelegatesToInfo
+import org.jetbrains.plugins.groovy.lang.resolve.delegatesTo.GrDelegatesToProvider
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/8/2016
+ */
+class GradleDelegatesToProvider() : GrDelegatesToProvider {
+
+ override fun getDelegatesToInfo(closure: GrClosableBlock): DelegatesToInfo? {
+ val file = closure.containingFile
+ if (file == null || !FileUtilRt.extensionEquals(file.getName(), GradleConstants.EXTENSION)) return null
+
+ for (contributor in GradleMethodContextContributor.EP_NAME.extensions) {
+ val delegatesToInfo = contributor.getDelegatesToInfo(closure)
+ if (delegatesToInfo != null) return delegatesToInfo
+ }
+ return null
+ }
+}
\ No newline at end of file
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDependenciesContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDependenciesContributor.java
deleted file mode 100644
index e3070d5cb8d6..000000000000
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDependenciesContributor.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.openapi.util.text.StringUtil;
-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.ContainerUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
-
-import java.util.List;
-
-/**
- * @author Denis Zhdanov
- * @since 8/14/13 12:58 PM
- */
-public class GradleDependenciesContributor implements GradleMethodContextContributor {
-
- @Override
- public void process(@NotNull List methodCallInfo,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull PsiElement place) {
- if (methodCallInfo.isEmpty()) return;
-
- String methodCall = ContainerUtil.getLastItem(methodCallInfo);
- if (methodCall == null) return;
-
- if (!StringUtil.equals(methodCall, "dependencies")) return;
-
- final GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
- if (methodCallInfo.size() == 2) {
- GradleResolverUtil.processDeclarations(
- psiManager, processor, state, place, GradleCommonClassNames.GRADLE_API_ARTIFACTS_EXTERNAL_MODULE_DEPENDENCY);
- // Assuming that the method call is addition of new dependency into configuration.
- PsiClass contributorClass =
- psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_DEPENDENCY_HANDLER, place.getResolveScope());
- if (contributorClass == null) return;
- GradleResolverUtil.processMethod(methodCallInfo.get(0), contributorClass, processor, state, place, "add");
- }
- else if (methodCallInfo.size() == 3) {
- GradleResolverUtil.processDeclarations(psiManager, processor, state, place,
- GradleCommonClassNames.GRADLE_API_DEPENDENCY_HANDLER,
- GradleCommonClassNames.GRADLE_API_ARTIFACTS_EXTERNAL_MODULE_DEPENDENCY,
- GradleCommonClassNames.GRADLE_API_ARTIFACTS_DEPENDENCY_ARTIFACT,
- GradleCommonClassNames.GRADLE_API_PROJECT);
- }
- else if (methodCallInfo.size() == 4) {
- // Assuming that the method call is addition of new dependency into configuration.
- PsiClass contributorClass =
- psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_DEPENDENCY_HANDLER, place.getResolveScope());
- if (contributorClass == null) return;
- GradleResolverUtil.processMethod(methodCallInfo.get(0), contributorClass, processor, state, place, "add");
- }
- }
-}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDependenciesContributor.kt b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDependenciesContributor.kt
new file mode 100644
index 000000000000..43829f88d98e
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDependenciesContributor.kt
@@ -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.openapi.util.Key
+import com.intellij.patterns.PsiJavaPatterns.psiElement
+import com.intellij.patterns.StandardPatterns.or
+import com.intellij.psi.*
+import com.intellij.psi.scope.BaseScopeProcessor
+import com.intellij.psi.scope.ElementClassHint
+import com.intellij.psi.scope.PsiScopeProcessor
+import groovy.lang.Closure
+import org.jetbrains.plugins.gradle.service.resolve.GradleCommonClassNames.*
+import org.jetbrains.plugins.gradle.service.resolve.GradleResolverUtil.canBeMethodOf
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression
+import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager
+import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil
+import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder
+import org.jetbrains.plugins.groovy.lang.psi.patterns.groovyClosure
+import org.jetbrains.plugins.groovy.lang.psi.patterns.psiMethod
+import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil
+import org.jetbrains.plugins.groovy.lang.resolve.delegatesTo.DelegatesToInfo
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/10/2016
+ */
+class GradleDependenciesContributor : GradleMethodContextContributor {
+ companion object {
+ val dependenciesClosure = groovyClosure().inMethod(or(psiMethod(GRADLE_API_PROJECT, "dependencies"),
+ psiMethod(GRADLE_API_SCRIPT_HANDLER, "dependencies")))
+ val dependencyConfigurationClosure = groovyClosure().inMethod(psiMethod(GRADLE_API_DEPENDENCY_HANDLER, "add"))
+ }
+
+ override fun getDelegatesToInfo(closure: GrClosableBlock): DelegatesToInfo? {
+ if (dependencyConfigurationClosure.accepts(closure)) {
+ return DelegatesToInfo(TypesUtil.createType(GRADLE_API_ARTIFACTS_MODULE_DEPENDENCY, closure), Closure.DELEGATE_FIRST)
+ }
+ if (dependenciesClosure.accepts(closure)) {
+ return DelegatesToInfo(TypesUtil.createType(GRADLE_API_DEPENDENCY_HANDLER, closure), Closure.DELEGATE_FIRST)
+ }
+ return null
+ }
+
+ override fun process(methodCallInfo: List, processor: PsiScopeProcessor, state: ResolveState, place: PsiElement): Boolean {
+ val psiManager = GroovyPsiManager.getInstance(place.project)
+ val methodName = if (methodCallInfo.isNotEmpty()) methodCallInfo[0] else return true
+
+ val classHint = processor.getHint(ElementClassHint.KEY)
+ val shouldProcessMethods = ResolveUtil.shouldProcessMethods(classHint)
+ if (shouldProcessMethods && place is GrReferenceExpression && psiElement().inside(dependenciesClosure).accepts(place)) {
+ if (methodCallInfo.size == 2) {
+ val psiClass = psiManager.findClassWithCache(GRADLE_API_DEPENDENCY_HANDLER, place.getResolveScope()) ?: return true
+ if (canBeMethodOf(methodName, psiClass)) {
+ return true
+ }
+ val componentProcessor = AddDependencyNotationProcessor(processor, place, psiClass)
+ if (!psiClass.processDeclarations(componentProcessor, state, null, place)) return false
+ }
+ }
+ if (psiElement().inside(dependencyConfigurationClosure).accepts(place)) {
+ if (GradleResolverUtil.processDeclarations(psiManager, processor, state, place,
+ GRADLE_API_ARTIFACTS_MODULE_DEPENDENCY,
+ GRADLE_API_ARTIFACTS_CLIENT_MODULE_DEPENDENCY)) return false
+ }
+ return true
+ }
+
+ class AddDependencyNotationProcessor(val delegate: PsiScopeProcessor, val place: PsiElement, val psiClass: PsiClass) : BaseScopeProcessor() {
+ override fun execute(method: PsiElement, state: ResolveState): Boolean {
+ method as? PsiMethod ?: return true
+
+ val wrappedBase = GrLightMethodBuilder(place.manager, "add").apply {
+ navigationElement = method
+ containingClass = psiClass
+ }
+ wrappedBase.addParameter("configurationName", CommonClassNames.JAVA_LANG_OBJECT)
+ wrappedBase.addParameter("dependencyNotation", CommonClassNames.JAVA_LANG_OBJECT, true)
+ if (!delegate.execute(wrappedBase, state)) return false
+ return true
+ }
+
+ override fun getHint(hintKey: Key) = if (hintKey == com.intellij.psi.scope.ElementClassHint.KEY) {
+ @Suppress("UNCHECKED_CAST")
+ ElementClassHint { it == com.intellij.psi.scope.ElementClassHint.DeclarationKind.METHOD } as T
+ }
+ else {
+ null
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDistributionsContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDistributionsContributor.java
deleted file mode 100644
index 6f49696a2cd2..000000000000
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDistributionsContributor.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright 2000-2015 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.openapi.util.text.StringUtil;
-import com.intellij.psi.PsiClass;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.ResolveState;
-import com.intellij.psi.scope.PsiScopeProcessor;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.containers.ContainerUtil;
-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.GrLightMethodBuilder;
-
-import java.util.List;
-
-import static org.jetbrains.plugins.gradle.service.resolve.GradleCommonClassNames.*;
-
-/**
- * @author Vladislav.Soroka
- * @since 8/30/13
- */
-public class GradleDistributionsContributor implements GradleMethodContextContributor {
-
- static final String DISTRIBUTIONS = "distributions";
- private static final String CONTENTS_METHOD = "contents";
-
- @Override
- public void process(@NotNull List methodCallInfo,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull PsiElement place) {
- if (methodCallInfo.isEmpty()) {
- return;
- }
- String methodCall = ContainerUtil.getLastItem(methodCallInfo);
- if (methodCall == null) {
- return;
- }
-
- if (methodCallInfo.size() > 1 && DISTRIBUTIONS.equals(place.getText()) && place instanceof GrReferenceExpressionImpl) {
- GradleResolverUtil.addImplicitVariable(processor, state, (GrReferenceExpressionImpl)place, GRADLE_API_DISTRIBUTION_CONTAINER);
- }
-
- if (methodCallInfo.size() > 1 && methodCall.equals("project")) {
- methodCallInfo.remove(methodCallInfo.size() - 1);
- methodCall = ContainerUtil.getLastItem(methodCallInfo);
- }
-
- if (methodCall == null || !StringUtil.startsWith(methodCall, DISTRIBUTIONS)) {
- return;
- }
-
- String closureMethod = null;
- String configureClosureClazz = null;
- String contributorClass = null;
- boolean isRootRelated = StringUtil.startsWith(methodCall, DISTRIBUTIONS + '.');
-
- if (methodCallInfo.size() == 1) {
- configureClosureClazz = GRADLE_API_DISTRIBUTION_CONTAINER;
- if (place instanceof GrReferenceExpressionImpl) {
- String varClazz =
- StringUtil.startsWith(methodCall, DISTRIBUTIONS + '.') ? GRADLE_API_DISTRIBUTION_CONTAINER : GRADLE_API_DISTRIBUTION;
- GradleResolverUtil.addImplicitVariable(processor, state, (GrReferenceExpressionImpl)place, varClazz);
- }
- else {
- contributorClass = GRADLE_API_DISTRIBUTION_CONTAINER;
- }
- closureMethod = "configure";
- }
- else if (methodCallInfo.size() == 2) {
- configureClosureClazz = GRADLE_API_DISTRIBUTION;
- contributorClass = GRADLE_API_DISTRIBUTION;
- closureMethod = "create";
- }
- else if (methodCallInfo.size() == 3 && CONTENTS_METHOD.equals(place.getText())) {
- GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
- PsiClass psiClass = psiManager.findClassWithCache(GRADLE_API_DISTRIBUTION, place.getResolveScope());
-
- GrLightMethodBuilder methodWithClosure =
- GradleResolverUtil.createMethodWithClosure(CONTENTS_METHOD, GRADLE_API_FILE_COPY_SPEC, null, place, psiManager);
- if (methodWithClosure != null) {
- if (psiClass != null) {
- PsiMethod psiMethod = ArrayUtil.getFirstElement(psiClass.findMethodsByName(CONTENTS_METHOD, false));
- if (psiMethod != null) {
- methodWithClosure.setNavigationElement(psiMethod);
- }
- }
- processor.execute(methodWithClosure, state);
- }
- }
- else if (methodCallInfo.size() == 4 && CONTENTS_METHOD.equals(methodCallInfo.get(1))) {
- GradleResolverUtil.processDeclarations(methodCallInfo.get(0), GroovyPsiManager.getInstance(place.getProject()),
- processor, state, place, GRADLE_API_FILE_COPY_SPEC);
- }
-
- if (configureClosureClazz != null && !isRootRelated) {
- final GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
- GrLightMethodBuilder methodWithClosure =
- GradleResolverUtil.createMethodWithClosure(closureMethod, configureClosureClazz, null, place, psiManager);
- if (methodWithClosure != null) {
- processor.execute(methodWithClosure, state);
- }
- }
-
- if (contributorClass != null) {
- GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
- GradleResolverUtil.processDeclarations(psiManager, processor, state, place, contributorClass);
- }
- }
-}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDistributionsContributor.kt b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDistributionsContributor.kt
new file mode 100644
index 000000000000..35261283cfad
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleDistributionsContributor.kt
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2000-2015 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.patterns.PsiJavaPatterns
+import com.intellij.psi.PsiElement
+import com.intellij.psi.ResolveState
+import com.intellij.psi.scope.ElementClassHint
+import com.intellij.psi.scope.NameHint
+import com.intellij.psi.scope.PsiScopeProcessor
+import groovy.lang.Closure
+import org.jetbrains.plugins.gradle.service.resolve.GradleCommonClassNames.*
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression
+import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager
+import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil
+import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder
+import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightVariable
+import org.jetbrains.plugins.groovy.lang.psi.patterns.groovyClosure
+import org.jetbrains.plugins.groovy.lang.psi.patterns.psiMethod
+import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.GROOVY_LANG_CLOSURE
+import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil
+import org.jetbrains.plugins.groovy.lang.resolve.delegatesTo.DelegatesToInfo
+
+/**
+ * @author Vladislav.Soroka
+ * *
+ * @since 8/30/13
+ */
+class GradleDistributionsContributor : GradleMethodContextContributor {
+
+ companion object {
+ val DISTRIBUTIONS_METHOD = "distributions"
+ val distributionsClosure = groovyClosure().inMethod(psiMethod(GRADLE_API_PROJECT, DISTRIBUTIONS_METHOD))
+ val distributionClosure = groovyClosure().withAncestor(2, distributionsClosure)
+ val contentsClosure = groovyClosure().inMethod(psiMethod(GRADLE_API_DISTRIBUTION, "contents"))
+ }
+
+ override fun getDelegatesToInfo(closure: GrClosableBlock): DelegatesToInfo? {
+ if (distributionsClosure.accepts(closure)) {
+ return DelegatesToInfo(TypesUtil.createType(GRADLE_API_DISTRIBUTION_CONTAINER, closure), Closure.DELEGATE_FIRST)
+ }
+ if (distributionClosure.accepts(closure)) {
+ return DelegatesToInfo(TypesUtil.createType(GRADLE_API_DISTRIBUTION, closure), Closure.DELEGATE_FIRST)
+ }
+ if (contentsClosure.accepts(closure)) {
+ return DelegatesToInfo(TypesUtil.createType(GRADLE_API_FILE_COPY_SPEC, closure), Closure.DELEGATE_FIRST)
+ }
+ return null
+ }
+
+ override fun process(methodCallInfo: MutableList,
+ processor: PsiScopeProcessor,
+ state: ResolveState,
+ place: PsiElement): Boolean {
+ val classHint = processor.getHint(ElementClassHint.KEY)
+ val shouldProcessMethods = ResolveUtil.shouldProcessMethods(classHint)
+ if (shouldProcessMethods && processor.getHint(NameHint.KEY)?.getName(state) == DISTRIBUTIONS_METHOD) {
+ val psiManager = GroovyPsiManager.getInstance(place.project)
+ val projectClass = psiManager.findClassWithCache(GRADLE_API_PROJECT, place.resolveScope) ?: return true
+ val distContainerClass = psiManager.createTypeByFQClassName(GRADLE_API_DISTRIBUTION_CONTAINER, place.resolveScope) ?: return true
+ val methodBuilder = GrLightMethodBuilder(place.manager, DISTRIBUTIONS_METHOD).apply {
+ containingClass = projectClass
+ returnType = distContainerClass
+ }
+ methodBuilder.addParameter("configuration", GROOVY_LANG_CLOSURE, true)
+ if (!processor.execute(methodBuilder, state)) return false
+ }
+
+ val psiElement = PsiJavaPatterns.psiElement()
+ if (psiElement.inside(distributionsClosure).accepts(place)) {
+ val name = place.text
+ if (place.parent is GrMethodCallExpression) {
+ val psiManager = GroovyPsiManager.getInstance(place.project)
+ val methodBuilder = GradleResolverUtil.createMethodWithClosure(
+ name, GRADLE_API_DISTRIBUTION, null, place, psiManager)
+ if (methodBuilder != null) {
+ if (!processor.execute(methodBuilder, state)) return false
+ }
+ }
+ if (place.parent is GrReferenceExpression || psiElement.withTreeParent(distributionsClosure).accepts(place)) {
+ val variable = GrLightVariable(place.manager, name, GRADLE_API_DISTRIBUTION, place)
+ if (!processor.execute(variable, state)) return false
+ }
+ }
+
+ return true
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleIdeaPluginScriptContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleIdeaPluginScriptContributor.java
deleted file mode 100644
index f853386987a0..000000000000
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleIdeaPluginScriptContributor.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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;
-
-
-/**
- * @author Vladislav.Soroka
- * @since 11/18/13
- */
-public class GradleIdeaPluginScriptContributor extends GradleSimpleContributor {
- public GradleIdeaPluginScriptContributor() {
- super("idea", "org.gradle.plugins.ide.idea.model.IdeaModel");
- }
-}
\ No newline at end of file
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleIdeaPluginScriptContributor.kt b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleIdeaPluginScriptContributor.kt
new file mode 100644
index 000000000000..5c74025c43b0
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleIdeaPluginScriptContributor.kt
@@ -0,0 +1,100 @@
+/*
+ * 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.patterns.PsiJavaPatterns.psiElement
+import com.intellij.psi.PsiElement
+import com.intellij.psi.ResolveState
+import com.intellij.psi.scope.PsiScopeProcessor
+import groovy.lang.Closure
+import org.jetbrains.plugins.gradle.service.resolve.GradleCommonClassNames.GRADLE_API_PROJECT
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock
+import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager
+import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil
+import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder
+import org.jetbrains.plugins.groovy.lang.psi.patterns.groovyClosure
+import org.jetbrains.plugins.groovy.lang.psi.patterns.psiMethod
+import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames.GROOVY_LANG_CLOSURE
+import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil
+import org.jetbrains.plugins.groovy.lang.resolve.delegatesTo.DelegatesToInfo
+
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/18/13
+ */
+class GradleIdeaPluginScriptContributor : GradleMethodContextContributor {
+
+ companion object {
+ val IDEA_METHOD = "idea"
+ val IDEA_MODEL_FQN = "org.gradle.plugins.ide.idea.model.IdeaModel"
+ val IDEA_PROJECT_FQN = "org.gradle.plugins.ide.idea.model.IdeaProject"
+ val IDEA_MODULE_FQN = "org.gradle.plugins.ide.idea.model.IdeaModule"
+ val IDEA_MODULE_IML_FQN = "org.gradle.plugins.ide.idea.model.IdeaModuleIml"
+ val IDE_XML_MERGER_FQN = "org.gradle.plugins.ide.api.XmlFileContentMerger"
+ val IDE_FILE_MERGER_FQN = "org.gradle.plugins.ide.api.FileContentMerger"
+ val IDEA_XML_MODULE_FQN = "org.gradle.plugins.ide.idea.model.Module"
+ val IDEA_XML_PROJECT_FQN = "org.gradle.plugins.ide.idea.model.Project"
+ val ideaClosure = groovyClosure().inMethod(psiMethod(GRADLE_API_PROJECT, IDEA_METHOD))
+ val ideaProjectClosure = groovyClosure().inMethod(psiMethod(IDEA_MODEL_FQN, "project"))
+ val ideaIprClosure = groovyClosure().inMethod(psiMethod(IDEA_PROJECT_FQN, "ipr"))
+ val ideaModuleClosure = groovyClosure().inMethod(psiMethod(IDEA_MODEL_FQN, "module"))
+ val ideaImlClosure = groovyClosure().inMethod(psiMethod(IDEA_MODULE_FQN, "iml"))
+ val ideaBeforeMergedClosure = groovyClosure().inMethod(psiMethod(IDE_FILE_MERGER_FQN, "beforeMerged"))
+ val ideaWhenMergedClosure = groovyClosure().inMethod(psiMethod(IDE_FILE_MERGER_FQN, "whenMerged"))
+ }
+
+ override fun getDelegatesToInfo(closure: GrClosableBlock): DelegatesToInfo? {
+ if (ideaClosure.accepts(closure)) {
+ return DelegatesToInfo(TypesUtil.createType(IDEA_MODEL_FQN, closure), Closure.DELEGATE_FIRST)
+ }
+ if (ideaImlClosure.accepts(closure)) {
+ return DelegatesToInfo(TypesUtil.createType(IDEA_MODULE_IML_FQN, closure), Closure.DELEGATE_FIRST)
+ }
+ return null
+ }
+
+ override fun process(methodCallInfo: List, processor: PsiScopeProcessor, state: ResolveState, place: PsiElement): Boolean {
+ val classHint = processor.getHint(com.intellij.psi.scope.ElementClassHint.KEY)
+ val shouldProcessMethods = ResolveUtil.shouldProcessMethods(classHint)
+ if (shouldProcessMethods && processor.getHint(
+ com.intellij.psi.scope.NameHint.KEY)?.getName(state) == IDEA_METHOD) {
+ val psiManager = GroovyPsiManager.getInstance(place.project)
+ val projectClass = psiManager.findClassWithCache(GRADLE_API_PROJECT, place.resolveScope) ?: return true
+ val returnClass = psiManager.createTypeByFQClassName(IDEA_MODEL_FQN, place.resolveScope) ?: return true
+ val methodBuilder = GrLightMethodBuilder(place.manager, IDEA_METHOD).apply {
+ containingClass = projectClass
+ returnType = returnClass
+ }
+ methodBuilder.addParameter("configuration", GROOVY_LANG_CLOSURE, true)
+ if (!processor.execute(methodBuilder, state)) return false
+ }
+
+ val psiManager = GroovyPsiManager.getInstance(place.project)
+ if (psiElement().inside(ideaModuleClosure).accepts(place)) {
+ if (GradleResolverUtil.processDeclarations(psiManager, processor, state, place, IDEA_MODULE_FQN)) return false
+ }
+
+ if (psiElement().inside(ideaProjectClosure).accepts(place)) {
+ if (psiElement().inside(ideaIprClosure).accepts(place)) {
+ if (GradleResolverUtil.processDeclarations(psiManager, processor, state, place, IDE_XML_MERGER_FQN)) return false
+ }
+ if (GradleResolverUtil.processDeclarations(psiManager, processor, state, place, IDEA_PROJECT_FQN)) return false
+ }
+
+ return true
+ }
+}
\ No newline at end of file
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleImplicitContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleImplicitContributor.java
index 24fb16278359..e33cb63319fc 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleImplicitContributor.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleImplicitContributor.java
@@ -78,17 +78,48 @@ public class GradleImplicitContributor implements GradleMethodContextContributor
);
@Override
- public void process(@NotNull List methodCallInfo,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull PsiElement place) {
+ public boolean process(@NotNull List methodCallInfo,
+ @NotNull PsiScopeProcessor processor,
+ @NotNull ResolveState state,
+ @NotNull PsiElement place) {
+
+ //Module module = ProjectFileIndex.SERVICE.getInstance(place.getProject()).getModuleForFile(place.getContainingFile().getVirtualFile());
+ //String rootProjectPath = ExternalSystemApiUtil.getExternalRootProjectPath(module);
+ //if (rootProjectPath != null) {
+ // ExternalProject externalProject = ExternalProjectDataCache.getInstance(place.getProject())
+ // .getRootExternalProject(GradleConstants.SYSTEM_ID, new File(rootProjectPath));
+ // if (externalProject != null) {
+ // Map properties = externalProject.getProperties();
+ //
+ // if (true || ResolveUtil.shouldProcessProperties(processor.getHint(ElementClassHint.KEY))) {
+ // String placeText = place.getText();
+ // ExternalProperty externalProperty = properties.get(placeText);
+ // if (externalProperty != null) {
+ // String type = externalProperty.getType() == null ? CommonClassNames.JAVA_LANG_OBJECT : externalProperty.getType();
+ // //String name = processor.getHint(NameHint.KEY).getName(state);
+ // LightVariableBuilder variable =
+ // new LightVariableBuilder(place.getManager(), placeText, TypesUtil.createType(type, place),
+ // GroovyLanguage.INSTANCE);
+ // if (!processor.execute(variable, state)) return;
+ // //if (((String)name).let {it == null || it == "hostname" }) {
+ // //val variable = LightVariableBuilder>(
+ // // place.manager, "hostname", TypesUtil.createType(JAVA_LANG_STRING, place), GroovyLanguage)
+ // //if (!processor.execute(variable, state)) return
+ // //}
+ // }
+ // }
+ // }
+ //}
+ if (true) return true;
+
+
if (methodCallInfo.isEmpty()) {
checkForAvailableTasks(0, place.getText(), processor, state, place);
- return;
+ return true;
}
final String methodCall = getLastItem(methodCallInfo);
- if (methodCall == null) return;
+ if (methodCall == null) return true;
if (!methodCall.equals("task")) {
if (methodCallInfo.size() == 1) {
@@ -125,6 +156,7 @@ public class GradleImplicitContributor implements GradleMethodContextContributor
}
}
}
+ return true;
}
public static void processImplicitDeclarations(@NotNull PsiScopeProcessor processor,
@@ -185,7 +217,7 @@ public class GradleImplicitContributor implements GradleMethodContextContributor
PsiClass contributorClass =
psiManager.findClassWithCache(fqName, place.getResolveScope());
if (contributorClass == null) return;
- GradleResolverUtil.processMethod(taskName, contributorClass, processor, state, place);
+ //GradleResolverUtil.processMethod(taskName, contributorClass, processor, state, place);
}
}
else {
@@ -203,8 +235,8 @@ public class GradleImplicitContributor implements GradleMethodContextContributor
if (canBeMethodOf(GroovyPropertyUtils.getGetterNameNonBoolean(taskName), gradleApiProjectClass)) return;
final String className = BUILT_IN_TASKS.get(taskName);
if (className != null) {
- GradleResolverUtil.processDeclarations(
- methodCallInfo.size() > 0 ? methodCallInfo.get(0) : null, psiManager, processor, state, place, className);
+ //GradleResolverUtil.processDeclarations(
+ // methodCallInfo.size() > 0 ? methodCallInfo.get(0) : null, psiManager, processor, state, place, className);
}
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleJavaContributor.kt b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleJavaContributor.kt
new file mode 100644
index 000000000000..f5c782cf1319
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleJavaContributor.kt
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2000-2016 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.patterns.ElementPattern
+import com.intellij.patterns.PsiJavaPatterns.psiElement
+import com.intellij.patterns.StandardPatterns.or
+import com.intellij.psi.PsiElement
+import com.intellij.psi.ResolveState
+import com.intellij.psi.scope.PsiScopeProcessor
+import com.intellij.util.ProcessingContext
+import groovy.lang.Closure
+import org.jetbrains.plugins.gradle.service.resolve.GradleCommonClassNames.*
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression
+import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager
+import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil
+import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightVariable
+import org.jetbrains.plugins.groovy.lang.psi.patterns.groovyClosure
+import org.jetbrains.plugins.groovy.lang.psi.patterns.psiMethod
+import org.jetbrains.plugins.groovy.lang.resolve.delegatesTo.DelegatesToInfo
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/10/2016
+ */
+class GradleJavaContributor : GradleMethodContextContributor {
+ companion object {
+ val sourceSetsClosure = groovyClosure().inMethod(psiMethod(GRADLE_API_JAVA_PLUGIN_CONVENTION, "sourceSets"))
+ val sourceSetClosure = groovyClosure().withAncestor(2, sourceSetsClosure)
+ val sourceSetReference = object : ElementPattern {
+ override fun getCondition() = null
+ override fun accepts(o: Any?) = false
+ override fun accepts(o: Any?, context: ProcessingContext): Boolean {
+ return o is GrExpression && o.type?.equalsToText(GRADLE_API_SOURCE_SET) ?: false
+ }
+ }
+
+ val sourceDirectorySetClosure = psiElement().andOr(
+ groovyClosure().withAncestor(2, sourceSetClosure),
+ groovyClosure().inMethod(or(psiMethod(GRADLE_API_SOURCE_SET, "java"),
+ psiMethod(GRADLE_API_SOURCE_SET, "resources"))))
+ }
+
+ override fun getDelegatesToInfo(closure: GrClosableBlock): DelegatesToInfo? {
+ if (sourceSetsClosure.accepts(closure)) {
+ return DelegatesToInfo(TypesUtil.createType(GRADLE_API_SOURCE_SET_CONTAINER, closure), Closure.DELEGATE_FIRST)
+ }
+ if (sourceSetClosure.accepts(closure)) {
+ return DelegatesToInfo(TypesUtil.createType(GRADLE_API_SOURCE_SET, closure), Closure.DELEGATE_FIRST)
+ }
+ if (sourceDirectorySetClosure.accepts(closure)) {
+ return DelegatesToInfo(TypesUtil.createType(GRADLE_API_SOURCE_DIRECTORY_SET, closure), Closure.DELEGATE_FIRST)
+ }
+ if (psiElement().withParent(
+ psiElement().withFirstChild(sourceSetReference)).accepts(closure)) {
+ return DelegatesToInfo(TypesUtil.createType(GRADLE_API_SOURCE_SET, closure), Closure.DELEGATE_FIRST)
+ }
+ return null
+ }
+
+ override fun process(methodCallInfo: List, processor: PsiScopeProcessor, state: ResolveState, place: PsiElement): Boolean {
+ val psiManager = GroovyPsiManager.getInstance(place.project)
+ if (!GradleResolverUtil.processDeclarations(psiManager, processor, state, place,
+ GRADLE_API_BASE_PLUGIN_CONVENTION,
+ GRADLE_API_JAVA_PLUGIN_CONVENTION,
+ GRADLE_API_APPLICATION_PLUGIN_CONVENTION,
+ GRADLE_API_WAR_CONVENTION)) {
+ return false
+ }
+
+ val psiElement = psiElement()
+ if (psiElement.inside(sourceSetsClosure).accepts(place)) {
+ val name = place.text
+ if (place.parent is GrMethodCallExpression) {
+ val methodBuilder = GradleResolverUtil.createMethodWithClosure(
+ name, GRADLE_API_SOURCE_SET, null, place, psiManager)
+ if (methodBuilder != null) {
+ if (!processor.execute(methodBuilder, state)) return false
+ }
+ }
+ if (place.parent is GrReferenceExpression || psiElement.withTreeParent(sourceSetsClosure).accepts(place)) {
+ val variable = GrLightVariable(place.manager, name, GRADLE_API_SOURCE_SET, place)
+ if (!processor.execute(variable, state)) return false
+ }
+ }
+
+ return true
+ }
+}
\ No newline at end of file
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleMavenArtifactRepositoryContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleMavenArtifactRepositoryContributor.java
deleted file mode 100644
index 8ab490d898c2..000000000000
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleMavenArtifactRepositoryContributor.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.ResolveState;
-import com.intellij.psi.scope.PsiScopeProcessor;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
-
-import java.util.List;
-
-/**
- * @{GradleMavenArtifactRepositoryContributor} provides gradle MavenArtifactRepository DSL resolving contributor.
- *
- * e.g.
- * repositories {
- * maven {
- * url "http://snapshots.repository.codehaus.org/"
- * }
- * }
- *
- * @author Vladislav.Soroka
- * @since 10/21/13
- */
-public class GradleMavenArtifactRepositoryContributor implements GradleMethodContextContributor {
-
- @Override
- public void process(@NotNull List methodCallInfo,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull PsiElement place) {
- if (methodCallInfo.isEmpty() || methodCallInfo.size() < 3 ||
- !"repositories".equals(methodCallInfo.get(2)) || !"maven".equals(methodCallInfo.get(1))) {
- return;
- }
- GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
- GradleResolverUtil.processDeclarations(
- psiManager, processor, state, place,
- GradleCommonClassNames.GRADLE_API_ARTIFACTS_REPOSITORIES_MAVEN_ARTIFACT_REPOSITORY);
- PsiClass contributorClass = psiManager.findClassWithCache(
- GradleCommonClassNames.GRADLE_API_ARTIFACTS_REPOSITORIES_MAVEN_ARTIFACT_REPOSITORY, place.getResolveScope());
- if (contributorClass == null) return;
- GradleResolverUtil.processMethod(methodCallInfo.get(0), contributorClass, processor, state, place);
- }
-}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleMavenArtifactRepositoryContributor.kt b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleMavenArtifactRepositoryContributor.kt
new file mode 100644
index 000000000000..7e2962142d1d
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleMavenArtifactRepositoryContributor.kt
@@ -0,0 +1,76 @@
+/*
+ * 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.patterns.PsiJavaPatterns.psiElement
+import com.intellij.patterns.StandardPatterns.or
+import com.intellij.psi.PsiElement
+import com.intellij.psi.ResolveState
+import com.intellij.psi.scope.PsiScopeProcessor
+import groovy.lang.Closure
+import org.jetbrains.plugins.gradle.service.resolve.GradleCommonClassNames.*
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock
+import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager
+import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil
+import org.jetbrains.plugins.groovy.lang.psi.patterns.groovyClosure
+import org.jetbrains.plugins.groovy.lang.psi.patterns.psiMethod
+import org.jetbrains.plugins.groovy.lang.resolve.delegatesTo.DelegatesToInfo
+
+/**
+ * Provides gradle MavenArtifactRepository DSL resolving contributor.
+ *
+ * e.g.
+ * repositories {
+ * maven {
+ * url "http://snapshots.repository.codehaus.org/"
+ * }
+ * }
+ *
+ * @author Vladislav.Soroka
+ * @since 10/21/13
+ */
+class GradleMavenArtifactRepositoryContributor : GradleMethodContextContributor {
+ companion object {
+ val repositoriesClosure = groovyClosure().inMethod(or(psiMethod(GRADLE_API_PROJECT, "repositories"),
+ psiMethod(GRADLE_API_SCRIPT_HANDLER, "repositories")))
+ val repositoryClosure = psiElement().andOr(
+ groovyClosure().withAncestor(2, repositoriesClosure),
+ groovyClosure().inMethod(psiMethod(GRADLE_API_REPOSITORY_HANDLER, "maven")))
+ }
+
+ override fun process(methodCallInfo: List,
+ processor: PsiScopeProcessor,
+ state: ResolveState,
+ place: PsiElement): Boolean {
+
+ val psiManager = GroovyPsiManager.getInstance(place.project)
+ if (methodCallInfo.isNotEmpty() && psiElement().inside(repositoryClosure).accepts(place)) {
+ if (!GradleResolverUtil.processDeclarations(
+ psiManager, processor, state, place, GRADLE_API_ARTIFACTS_REPOSITORIES_MAVEN_ARTIFACT_REPOSITORY)) return false
+ }
+ return true
+ }
+
+ override fun getDelegatesToInfo(closure: GrClosableBlock): DelegatesToInfo? {
+ if (repositoriesClosure.accepts(closure)) {
+ return DelegatesToInfo(TypesUtil.createType(GRADLE_API_REPOSITORY_HANDLER, closure), Closure.DELEGATE_FIRST)
+ }
+// if (repositoryClosure.accepts(closure)) {
+// return DelegatesToInfo(TypesUtil.createType(GRADLE_API_ARTIFACTS_REPOSITORIES_MAVEN_ARTIFACT_REPOSITORY, closure), DELEGATE_FIRST)
+// }
+ return null
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleMavenDeployerContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleMavenDeployerContributor.java
deleted file mode 100644
index 682786542249..000000000000
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleMavenDeployerContributor.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.ResolveState;
-import com.intellij.psi.scope.PsiScopeProcessor;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
-
-import java.util.List;
-
-/**
- * @{GradleMavenArtifactRepositoryContributor} provides gradle MavenArtifactRepository DSL resolving contributor.
- *
- * e.g.
- * repositories {
- * maven {
- * url "http://snapshots.repository.codehaus.org/"
- * }
- * }
- *
- * @author Vladislav.Soroka
- * @since 10/21/13
- */
-public class GradleMavenDeployerContributor implements GradleMethodContextContributor {
-
- @Override
- public void process(@NotNull List methodCallInfo,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull PsiElement place) {
- if (methodCallInfo.isEmpty() || methodCallInfo.size() < 3 ||
- !"repositories".equals(methodCallInfo.get(2)) || !"mavenDeployer".equals(methodCallInfo.get(1))) {
- return;
- }
- GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
- GradleResolverUtil.processDeclarations(
- psiManager, processor, state, place,
- GradleCommonClassNames.GRADLE_API_ARTIFACTS_MAVEN_MAVEN_DEPLOYER);
- PsiClass contributorClass = psiManager.findClassWithCache(
- GradleCommonClassNames.GRADLE_API_ARTIFACTS_MAVEN_MAVEN_DEPLOYER, place.getResolveScope());
- if (contributorClass == null) return;
- GradleResolverUtil.processMethod(methodCallInfo.get(0), contributorClass, processor, state, place);
- }
-}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleMethodContextContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleMethodContextContributor.java
index d08616276435..508e3fba117b 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleMethodContextContributor.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleMethodContextContributor.java
@@ -20,7 +20,10 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.ResolveState;
import com.intellij.psi.scope.PsiScopeProcessor;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor;
+import org.jetbrains.plugins.groovy.lang.resolve.delegatesTo.DelegatesToInfo;
import java.util.List;
@@ -56,9 +59,17 @@ public interface GradleMethodContextContributor {
* @param processor the processor receiving the declarations.
* @param state current resolve state
* @param place the original element from which the tree up walk was initiated.
+ * @return true if the processing should continue or false if it should be stopped.
*/
- void process(@NotNull List methodCallInfo,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull PsiElement place);
+ default boolean process(@NotNull List methodCallInfo,
+ @NotNull PsiScopeProcessor processor,
+ @NotNull ResolveState state,
+ @NotNull PsiElement place) {
+ return true;
+ }
+
+ @Nullable
+ default DelegatesToInfo getDelegatesToInfo(@NotNull GrClosableBlock closure) {
+ return null;
+ }
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleProjectContributor.kt b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleProjectContributor.kt
new file mode 100644
index 000000000000..16a1e1835df2
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleProjectContributor.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2016 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.PsiElement
+import com.intellij.psi.ResolveState
+import com.intellij.psi.scope.PsiScopeProcessor
+import org.jetbrains.plugins.gradle.service.resolve.GradleCommonClassNames.GRADLE_API_PROJECT
+import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/10/2016
+ */
+class GradleProjectContributor : GradleMethodContextContributor {
+ override fun process(methodCallInfo: List, processor: PsiScopeProcessor, state: ResolveState, place: PsiElement): Boolean {
+ val psiManager = GroovyPsiManager.getInstance(place.project)
+ return GradleResolverUtil.processDeclarations(psiManager, processor, state, place, GRADLE_API_PROJECT)
+ }
+}
\ No newline at end of file
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java
index a2286d4e6ea6..ff5a5b4bdea5 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleResolverUtil.java
@@ -18,7 +18,6 @@ package org.jetbrains.plugins.gradle.service.resolve;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.psi.*;
import com.intellij.psi.scope.PsiScopeProcessor;
-import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.util.GradleLog;
@@ -29,14 +28,12 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgument
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.api.statements.expressions.GrMethodCall;
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.GrLightField;
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 org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
import java.util.Arrays;
@@ -122,87 +119,19 @@ public class GradleResolverUtil {
return methodWithClosure;
}
- public static void processMethod(@NotNull String methodName,
- @NotNull PsiClass handlerClass,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull PsiElement place) {
- processMethod(methodName, handlerClass, processor, state, place, null);
- }
-
- public static void processMethod(@NotNull String methodName,
- @NotNull PsiClass handlerClass,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull PsiElement place,
- @Nullable String defaultMethodName) {
- GrLightMethodBuilder builder = new GrLightMethodBuilder(place.getManager(), methodName);
- PsiElementFactory factory = JavaPsiFacade.getElementFactory(place.getManager().getProject());
- PsiType type = new PsiArrayType(factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, place.getResolveScope()));
- builder.addParameter(new GrLightParameter("param", type, builder));
- PsiClassType retType = factory.createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, place.getResolveScope());
- builder.setReturnType(retType);
- processor.execute(builder, state);
-
- GrMethodCall call = PsiTreeUtil.getParentOfType(place, GrMethodCall.class);
- if (call == null) {
- return;
- }
- GrArgumentList args = call.getArgumentList();
-
- int argsCount = getGrMethodArumentsCount(args);
- argsCount++; // Configuration name is delivered as an argument.
-
- // handle setter's shortcut facilities
- final String setter = GroovyPropertyUtils.getSetterName(methodName);
- for (PsiMethod method : handlerClass.findMethodsByName(setter, false)) {
- if (method.getParameterList().getParametersCount() == 1) {
- builder.setNavigationElement(method);
- return;
- }
- }
-
- for (PsiMethod method : handlerClass.findMethodsByName(methodName, false)) {
- if (method.getParameterList().getParametersCount() == argsCount) {
- builder.setNavigationElement(method);
- return;
- }
- }
-
- if (defaultMethodName != null) {
- for (PsiMethod method : handlerClass.findMethodsByName(defaultMethodName, false)) {
- if (method.getParameterList().getParametersCount() == argsCount) {
- builder.setNavigationElement(method);
- return;
- }
- }
- }
- }
-
- public static void processDeclarations(@NotNull GroovyPsiManager psiManager,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull PsiElement place,
- @NotNull String... fqNames) {
- processDeclarations(null, psiManager, processor, state, place, fqNames);
- }
-
- public static void processDeclarations(@Nullable String methodName,
- @NotNull GroovyPsiManager psiManager,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull PsiElement place,
- @NotNull String... fqNames) {
+ public static boolean processDeclarations(@NotNull GroovyPsiManager psiManager,
+ @NotNull PsiScopeProcessor processor,
+ @NotNull ResolveState state,
+ @NotNull PsiElement place,
+ @NotNull String... fqNames) {
for (String fqName : fqNames) {
if(fqName == null) continue;
PsiClass psiClass = psiManager.findClassWithCache(fqName, place.getResolveScope());
if (psiClass != null) {
- psiClass.processDeclarations(processor, state, null, place);
- if (methodName != null) {
- processMethod(methodName, psiClass, processor, state, place);
- }
+ if (!UtilKt.processDeclarations(psiClass, processor, state, place)) return false;
}
}
+ return true;
}
@Nullable
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleRootContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleRootContributor.java
deleted file mode 100644
index 7b4fe8c95e54..000000000000
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleRootContributor.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.openapi.util.text.StringUtil;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.ResolveState;
-import com.intellij.psi.scope.PsiScopeProcessor;
-import com.intellij.util.containers.ContainerUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
-
-import java.util.List;
-import java.util.Set;
-
-import static org.jetbrains.plugins.gradle.service.resolve.GradleDistributionsContributor.DISTRIBUTIONS;
-import static org.jetbrains.plugins.gradle.service.resolve.GradleSourceSetsContributor.SOURCE_SETS;
-
-/**
- * @author Denis Zhdanov
- * @since 8/14/13 1:03 PM
- */
-public class GradleRootContributor implements GradleMethodContextContributor {
-
- private final GradleSourceSetsContributor mySourceSetsContributor;
- private final GradleDistributionsContributor myDistributionsContributor;
-
- public GradleRootContributor(GradleSourceSetsContributor sourceSetsContributor, GradleDistributionsContributor contributor) {
- mySourceSetsContributor = sourceSetsContributor;
- myDistributionsContributor = contributor;
- }
-
- private final static Set BUILD_SCRIPT_BLOCKS = ContainerUtil.newHashSet(
- "subprojects",
- "allprojects",
- "beforeEvaluate",
- "afterEvaluate",
- SOURCE_SETS,
- DISTRIBUTIONS
- );
-
- @Override
- public void process(@NotNull List methodCallInfo,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull PsiElement place) {
- if (methodCallInfo.size() > 2) {
- return;
- }
-
- if (methodCallInfo.size() == 2 && !BUILD_SCRIPT_BLOCKS.contains(methodCallInfo.get(1))) {
- return;
- }
- if (methodCallInfo.size() > 0) {
- String method = ContainerUtil.getLastItem(methodCallInfo);
- if (method != null && StringUtil.startsWith(method, SOURCE_SETS)) {
- mySourceSetsContributor.process(methodCallInfo, processor, state, place);
- return;
- }
- if (method != null && StringUtil.startsWith(method, DISTRIBUTIONS)) {
- myDistributionsContributor.process(methodCallInfo, processor, state, place);
- return;
- }
- }
-
- GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
- GradleResolverUtil.processDeclarations(methodCallInfo.size() > 0 ? methodCallInfo.get(0) : null,
- psiManager, processor, state, place,
- GradleCommonClassNames.GRADLE_API_PROJECT);
- }
-}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleScriptContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleScriptContributor.java
index 2b2747d7d08f..185c287d61e1 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleScriptContributor.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleScriptContributor.java
@@ -66,9 +66,6 @@ public class GradleScriptContributor extends NonCodeMembersContributor {
current != null;
current = PsiTreeUtil.getParentOfType(current, GrMethodCall.class)) {
GrExpression expression = current.getInvokedExpression();
- if (expression == null) {
- continue;
- }
String text = expression.getText();
if (text != null) {
methodInfo.add(text);
@@ -81,7 +78,7 @@ public class GradleScriptContributor extends NonCodeMembersContributor {
}
for (GradleMethodContextContributor contributor : GradleMethodContextContributor.EP_NAME.getExtensions()) {
- contributor.process(methodInfo, processor, state, place);
+ if (!contributor.process(methodInfo, processor, state, place)) return;
}
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleSimpleContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleSimpleContributor.java
deleted file mode 100644
index 4a3163f69e2a..000000000000
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleSimpleContributor.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.ResolveState;
-import com.intellij.psi.scope.PsiScopeProcessor;
-import com.intellij.util.containers.ContainerUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
-
-import java.util.List;
-
-/**
- * @author Vladislav.Soroka
- * @since 8/30/13
- */
-public abstract class GradleSimpleContributor implements GradleMethodContextContributor {
-
- private final String blockName;
- private final String fqName;
- private final List myMixIns;
-
- protected GradleSimpleContributor(@NotNull String blockName, @NotNull String fqName, String... mixIns) {
- this.blockName = blockName;
- this.fqName = fqName;
- myMixIns = ContainerUtil.newArrayList(mixIns);
- }
-
- @Override
- public void process(@NotNull List methodCallInfo,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull PsiElement place) {
- if (methodCallInfo.isEmpty() || methodCallInfo.size() < 2 || !blockName.equals(methodCallInfo.get(1))) {
- return;
- }
- GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
- GradleResolverUtil.processDeclarations(psiManager, processor, state, place, fqName);
- for(final String mixin : myMixIns) {
- PsiClass contributorClass =
- psiManager.findClassWithCache(mixin, place.getResolveScope());
- if (contributorClass == null) continue;
- GradleResolverUtil.processMethod(methodCallInfo.get(0), contributorClass, processor, state, place);
- }
- }
-}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleSourceSetsContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleSourceSetsContributor.java
deleted file mode 100644
index f5a1a7ae79db..000000000000
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleSourceSetsContributor.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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.openapi.util.text.StringUtil;
-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.ContainerUtil;
-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.GrLightMethodBuilder;
-
-import java.util.List;
-
-/**
- * @author Vladislav.Soroka
- * @since 8/29/13
- */
-public class GradleSourceSetsContributor implements GradleMethodContextContributor {
- static final String SOURCE_SETS = "sourceSets";
- private static final String CONFIGURE_CLOSURE_METHOD = "configure";
- private static final int SOURCE_SET_CONTAINER_LEVEL = 1;
- private static final int SOURCE_SET_LEVEL = 2;
- private static final int SOURCE_DIRECTORY_LEVEL = 3;
- private static final int SOURCE_DIRECTORY_CLOSURE_LEVEL = 4;
-
- @Override
- public void process(@NotNull List methodCallInfo,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull PsiElement place) {
- if (methodCallInfo.isEmpty()) {
- return;
- }
- String methodCall = ContainerUtil.getLastItem(methodCallInfo);
- if (methodCall == null) {
- return;
- }
-
- if (methodCallInfo.size() > 1 && SOURCE_SETS.equals(place.getText()) && place instanceof GrReferenceExpressionImpl) {
- GradleResolverUtil
- .addImplicitVariable(processor, state, (GrReferenceExpressionImpl)place, GradleCommonClassNames.GRADLE_API_SOURCE_SET_CONTAINER);
- }
-
- if (methodCallInfo.size() > 1 && methodCall.equals("project")) {
- methodCallInfo.remove(methodCallInfo.size() - 1);
- methodCall = ContainerUtil.getLastItem(methodCallInfo);
- }
-
- if (methodCall == null || methodCallInfo.size() > SOURCE_DIRECTORY_CLOSURE_LEVEL || !StringUtil.startsWith(methodCall, SOURCE_SETS)) {
- return;
- }
-
- String configureClosureClazz = null;
- String contributorClass = null;
-
- boolean isRootRelated = StringUtil.startsWith(methodCall, SOURCE_SETS + '.');
-
- if (methodCallInfo.size() == SOURCE_SET_CONTAINER_LEVEL) {
- configureClosureClazz = GradleCommonClassNames.GRADLE_API_SOURCE_SET_CONTAINER;
- if (place instanceof GrReferenceExpressionImpl) {
- String varClazz = StringUtil.startsWith(methodCall, SOURCE_SETS + '.')
- ? GradleCommonClassNames.GRADLE_API_SOURCE_SET_CONTAINER
- : GradleCommonClassNames.GRADLE_API_SOURCE_SET;
- GradleResolverUtil.addImplicitVariable(processor, state, (GrReferenceExpressionImpl)place, varClazz);
- }
- else {
- contributorClass = GradleCommonClassNames.GRADLE_API_SOURCE_SET_CONTAINER;
- }
- }
- else if (methodCallInfo.size() == SOURCE_SET_LEVEL) {
- configureClosureClazz = GradleCommonClassNames.GRADLE_API_SOURCE_SET;
- contributorClass = GradleCommonClassNames.GRADLE_API_SOURCE_SET;
- }
- else if (methodCallInfo.size() == SOURCE_DIRECTORY_LEVEL) {
- GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
- PsiClass psiClass = psiManager.findClassWithCache(GradleCommonClassNames.GRADLE_API_SOURCE_SET, place.getResolveScope());
- configureClosureClazz =
- GradleResolverUtil.canBeMethodOf(place.getText(), psiClass) ? null : GradleCommonClassNames.GRADLE_API_SOURCE_DIRECTORY_SET;
- contributorClass = GradleCommonClassNames.GRADLE_API_SOURCE_DIRECTORY_SET;
- }
- else if (methodCallInfo.size() == SOURCE_DIRECTORY_CLOSURE_LEVEL) {
- contributorClass = GradleCommonClassNames.GRADLE_API_SOURCE_DIRECTORY_SET;
- }
-
- if (configureClosureClazz != null && !isRootRelated) {
- final GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
- GrLightMethodBuilder methodWithClosure =
- GradleResolverUtil
- .createMethodWithClosure(CONFIGURE_CLOSURE_METHOD, configureClosureClazz, null, place, psiManager);
- if (methodWithClosure != null) {
- processor.execute(methodWithClosure, state);
- }
- }
- //else {
- // GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
- // GradleResolverUtil.processDeclarations(psiManager, processor, state, place, GradleCommonClassNames.GRADLE_API_PROJECT);
- //}
- if (contributorClass != null) {
- GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
- GradleResolverUtil.processDeclarations(psiManager, processor, state, place, contributorClass);
- }
- }
-}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleTaskContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleTaskContributor.java
index 77e734a8b09f..2121b4a55b4c 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleTaskContributor.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/GradleTaskContributor.java
@@ -42,11 +42,11 @@ import java.util.List;
public class GradleTaskContributor implements GradleMethodContextContributor {
@Override
- public void process(@NotNull List methodCallInfo,
- @NotNull PsiScopeProcessor processor,
- @NotNull ResolveState state,
- @NotNull PsiElement place) {
- if (methodCallInfo.isEmpty()) return;
+ public boolean process(@NotNull List methodCallInfo,
+ @NotNull PsiScopeProcessor processor,
+ @NotNull ResolveState state,
+ @NotNull PsiElement place) {
+ if (methodCallInfo.isEmpty()) return true;
if (methodCallInfo.size() == 1) {
if(GradleResolverUtil.isLShiftElement(place.getParent())) {
@@ -59,28 +59,19 @@ public class GradleTaskContributor implements GradleMethodContextContributor {
processTaskAddition(methodCallInfo.get(0), GradleCommonClassNames.GRADLE_API_TASK_CONTAINER, processor, state, place);
}
else {
- processTaskTypeParameter(methodCallInfo.get(0), processor, state, place);
+ processTaskTypeParameter(processor, state, place);
}
GradleImplicitContributor.processImplicitDeclarations(processor, state, place);
}
else if (methodCallInfo.size() >= 3) {
- processTaskTypeParameter(methodCallInfo.get(0), processor, state, place);
-
+ processTaskTypeParameter(processor, state, place);
GradleImplicitContributor.processImplicitDeclarations(processor, state, place);
-
- if (place.getText().equals(GradleSourceSetsContributor.SOURCE_SETS) &&
- StringUtil.startsWith(methodCallInfo.get(0), GradleSourceSetsContributor.SOURCE_SETS + '.')) {
- GradleResolverUtil.addImplicitVariable(processor, state, place, GradleCommonClassNames.GRADLE_API_SOURCE_SET_CONTAINER);
- }
- if (place.getText().equals(GradleDistributionsContributor.DISTRIBUTIONS) &&
- StringUtil.startsWith(methodCallInfo.get(0), GradleDistributionsContributor.DISTRIBUTIONS + '.')) {
- GradleResolverUtil.addImplicitVariable(processor, state, place, GradleCommonClassNames.GRADLE_API_DISTRIBUTION_CONTAINER);
- }
}
+ return true;
}
- private static void processTaskTypeParameter(@NotNull String methodCall, @NotNull PsiScopeProcessor processor,
+ private static void processTaskTypeParameter(@NotNull PsiScopeProcessor processor,
@NotNull ResolveState state,
@NotNull PsiElement place) {
final int taskTypeParameterLevel = 3;
@@ -102,7 +93,7 @@ public class GradleTaskContributor implements GradleMethodContextContributor {
PsiImmediateClassType immediateClassType = (PsiImmediateClassType)psiType;
for (PsiType type : immediateClassType.getParameters()) {
GroovyPsiManager psiManager = GroovyPsiManager.getInstance(place.getProject());
- GradleResolverUtil.processDeclarations(methodCall, psiManager, processor, state, place, TypesUtil.getQualifiedName(type));
+ GradleResolverUtil.processDeclarations(psiManager, processor, state, place, TypesUtil.getQualifiedName(type));
}
}
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/dsl/GradleCompletionWeigher.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/dsl/GradleCompletionWeigher.java
new file mode 100644
index 000000000000..84d827236f4d
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/dsl/GradleCompletionWeigher.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2000-2016 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.dsl;
+
+import com.intellij.codeInsight.completion.CompletionLocation;
+import com.intellij.codeInsight.completion.CompletionWeigher;
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.openapi.util.io.FileUtilRt;
+import com.intellij.psi.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.gradle.util.GradleConstants;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/7/2016
+ */
+public class GradleCompletionWeigher extends CompletionWeigher {
+
+ @Override
+ public Comparable weigh(@NotNull LookupElement element, @NotNull CompletionLocation location) {
+ PsiFile containingFile = location.getCompletionParameters().getPosition().getContainingFile();
+ if (!(containingFile instanceof GroovyFileBase)) {
+ return null;
+ }
+
+ if (!FileUtilRt.extensionEquals(containingFile.getName(), GradleConstants.EXTENSION)) {
+ return null;
+ }
+
+ Object o = element.getObject();
+ if (o instanceof ResolveResult) {
+ PsiElement psiElement = ((ResolveResult)o).getElement();
+ PsiFile psiFile = null;
+ if (psiElement != null) {
+ psiFile = psiElement.getContainingFile();
+ }
+ if (psiFile == null && psiElement instanceof PsiMember) {
+ PsiClass psiClass = ((PsiMember)psiElement).getContainingClass();
+ psiFile = psiClass != null ? psiClass.getContainingFile() : null;
+ }
+ if (psiFile instanceof PsiJavaFile) {
+ if (((PsiJavaFile)psiFile).getPackageName().startsWith("org.gradle")) {
+ return 1;
+ }
+ }
+ }
+ return -1;
+ }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/util.kt b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/util.kt
new file mode 100644
index 000000000000..ea6c0e897c4b
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/resolve/util.kt
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2000-2016 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.openapi.util.Key
+import com.intellij.psi.PsiClass
+import com.intellij.psi.PsiElement
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.ResolveState
+import com.intellij.psi.scope.BaseScopeProcessor
+import com.intellij.psi.scope.ElementClassHint
+import com.intellij.psi.scope.NameHint.KEY
+import com.intellij.psi.scope.PsiScopeProcessor
+
+/**
+ * @author Vladislav.Soroka
+ * @since 11/11/2016
+ */
+
+fun processDeclarations(handlerClass: PsiClass,
+ processor: PsiScopeProcessor,
+ state: ResolveState,
+ place: PsiElement): Boolean {
+ val name = processor.getHint(KEY)?.getName(state)
+ val componentClass = handlerClass
+ val componentProcessor = ComponentProcessor(processor, place, name)
+ if (name == null) {
+ if (!componentClass.processDeclarations(componentProcessor, state, null, place)) return false
+ }
+ else {
+ for (method in componentClass.findMethodsByName(name, true)) {
+ if (!componentProcessor.execute(method, state)) return false
+ }
+ for (prefix in arrayOf("add", "set")) {
+ for (method in componentClass.findMethodsByName(prefix + name.capitalize(), true)) {
+ if (!componentProcessor.execute(method, state)) return false
+ }
+ }
+ }
+ return true
+}
+
+class ComponentProcessor(val delegate: PsiScopeProcessor, val place: PsiElement, val name: String?) : BaseScopeProcessor() {
+
+ override fun execute(method: PsiElement, state: ResolveState): Boolean {
+ method as? PsiMethod ?: return true
+ return delegate.execute(method, state)
+ }
+
+ override fun getHint(hintKey: Key): T? = if (hintKey == com.intellij.psi.scope.ElementClassHint.KEY) {
+ @Suppress("UNCHECKED_CAST")
+ ElementClassHint { it == com.intellij.psi.scope.ElementClassHint.DeclarationKind.METHOD } as T
+ }
+ else {
+ null
+ }
+}
\ No newline at end of file