gradle: configurations configured with closure resolved

This commit is contained in:
Vladislav.Soroka
2016-12-01 11:36:26 +03:00
parent 73929181a7
commit 44b583b2ae
@@ -19,6 +19,7 @@ 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.ElementClassHint
import com.intellij.psi.scope.PsiScopeProcessor
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.util.ProcessingContext
@@ -27,12 +28,16 @@ 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.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.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
import org.jetbrains.plugins.groovy.lang.resolve.delegatesTo.getContainingCall
import org.jetbrains.plugins.groovy.lang.resolve.delegatesTo.resolveActualCall
@@ -100,6 +105,33 @@ class GradleConfigurationsContributor : GradleMethodContextContributor {
val variable = GrLightVariable(place.manager, name, GRADLE_API_CONFIGURATION, place)
if (!processor.execute(variable, state)) return false
}
val classHint = processor.getHint(ElementClassHint.KEY)
val shouldProcessMethods = ResolveUtil.shouldProcessMethods(classHint)
if (shouldProcessMethods && place is GrReferenceExpression) {
val resolveScope = place.getResolveScope()
val psiClass = psiManager.findClassWithCache(GRADLE_API_CONFIGURATION_CONTAINER, resolveScope) ?: return true
if (GradleResolverUtil.canBeMethodOf(name, psiClass)) {
return true
}
val call = PsiTreeUtil.getParentOfType(place, GrMethodCall::class.java) ?: return true
val args = call.argumentList
var argsCount = GradleResolverUtil.getGrMethodArumentsCount(args)
argsCount += call.closureArguments.size
argsCount++ // Configuration name is delivered as an argument.
// at runtime, see org.gradle.internal.metaobject.ConfigureDelegate.invokeMethod
val returnClass = psiManager.createTypeByFQClassName(GRADLE_API_CONFIGURATION, resolveScope) ?: return true
val wrappedBase = GrLightMethodBuilder(place.manager, "configure").apply {
returnType = returnClass
containingClass = psiClass
addParameter("configureClosure", GROOVY_LANG_CLOSURE, true)
val method = psiClass.findMethodsByName("create", true).firstOrNull { it.parameterList.parametersCount == argsCount }
if (method != null) navigationElement = method
}
if (!processor.execute(wrappedBase, state)) return false
}
}
return true