[groovy] use Argument instead of PsiType in call references

This commit is contained in:
Daniil Ovchinnikov
2018-11-07 23:23:17 +03:00
parent 91ac62dc38
commit 3effccaf3a
10 changed files with 82 additions and 24 deletions
@@ -17,6 +17,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrExpressionImpl;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyIndexPropertyUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.RValue;
import org.jetbrains.plugins.groovy.lang.resolve.references.GrGetAtReference;
import org.jetbrains.plugins.groovy.lang.resolve.references.GrIndexPropertyReference;
import org.jetbrains.plugins.groovy.lang.resolve.references.GrPutAtReference;
@@ -24,7 +25,7 @@ import org.jetbrains.plugins.groovy.lang.resolve.references.GrPutAtReference;
import static org.jetbrains.plugins.groovy.lang.psi.GroovyElementTypes.T_Q;
import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyIndexPropertyUtil.isClassLiteral;
import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyIndexPropertyUtil.isSimpleArrayAccess;
import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyLValueUtil.isLValue;
import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyLValueUtil.getRValue;
import static org.jetbrains.plugins.groovy.lang.psi.util.GroovyLValueUtil.isRValue;
import static org.jetbrains.plugins.groovy.lang.resolve.ReferencesKt.referenceArray;
@@ -37,9 +38,11 @@ public class GrIndexPropertyImpl extends GrExpressionImpl implements GrIndexProp
() -> isRValue(this) && isIndexAccess() ? new GrGetAtReference(this) : null
);
private final NullableLazyValue<GrIndexPropertyReference> myLValueReference = AtomicNullableLazyValue.createValue(
() -> isLValue(this) && isIndexAccess() ? new GrPutAtReference(this) : null
);
private final NullableLazyValue<GrIndexPropertyReference> myLValueReference = AtomicNullableLazyValue.createValue(() -> {
if (!isIndexAccess()) return null;
RValue rValue = getRValue(this);
return rValue == null?null : new GrPutAtReference(this, rValue.getArgument());
});
private final NotNullLazyValue<GroovyReference[]> myReferences = AtomicNotNullLazyValue.createValue(
() -> referenceArray(getRValueReference(), getLValueReference())
@@ -18,6 +18,8 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.GrImmediateTupleType
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil.getClassReferenceFromExpression
import org.jetbrains.plugins.groovy.lang.resolve.api.Argument
import org.jetbrains.plugins.groovy.lang.resolve.api.LazyTypeArgument
fun GrIndexProperty.isSimpleArrayAccess(): Boolean {
return getSimpleArrayAccessType() != null
@@ -77,6 +79,8 @@ fun GrIndexProperty.getArgumentListType(): PsiType? {
return GrImmediateTupleType(types, JavaPsiFacade.getInstance(project), resolveScope)
}
fun GrIndexProperty.getArgumentListArgument(): Argument = LazyTypeArgument { getArgumentListType() }
fun GrIndexProperty.getArgumentTypes(rhs: Boolean): Array<PsiType>? {
val argumentListType = getArgumentListType() ?: return null
if (rhs) {
@@ -0,0 +1,9 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.lang.resolve.api
import com.intellij.psi.PsiType
class LazyTypeArgument(typeComputable: () -> PsiType?) : Argument {
override val type: PsiType? by lazy(typeComputable)
}
@@ -1,6 +1,4 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.lang.resolve.api
import com.intellij.psi.PsiType
typealias Arguments = List<PsiType?>
typealias Arguments = List<Argument?>
@@ -4,7 +4,6 @@ package org.jetbrains.plugins.groovy.lang.resolve.impl
import com.intellij.psi.PsiType
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.util.PsiUtil.getArgumentTypes
import org.jetbrains.plugins.groovy.lang.resolve.api.Arguments
import org.jetbrains.plugins.groovy.lang.resolve.api.GroovyMethodCallReferenceBase
@@ -22,5 +21,5 @@ class GrImplicitCallReference(element: GrMethodCall) : GroovyMethodCallReference
override val methodName: String get() = "call"
override val arguments: Arguments? get() = getArgumentTypes(element.argumentList)?.toList()
override val arguments: Arguments? get() = element.getArguments()
}
@@ -0,0 +1,48 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.lang.resolve.impl
import com.intellij.psi.PsiElement
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrSpreadArgument
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.impl.GrMapType
import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType
import org.jetbrains.plugins.groovy.lang.resolve.api.*
import java.util.*
fun GrMethodCall.getArguments(): Arguments? {
val argumentList = argumentList
return getArguments(argumentList.namedArguments, argumentList.expressionArguments, closureArguments, this)
}
private fun getArguments(namedArguments: Array<out GrNamedArgument>,
expressionArguments: Array<out GrExpression>,
closureArguments: Array<out GrClosableBlock>,
context: PsiElement): Arguments? {
val result = ArrayList<Argument>()
if (namedArguments.isNotEmpty()) {
result += LazyTypeArgument {
GrMapType.createFromNamedArgs(context, namedArguments)
}
}
for (expression in expressionArguments) {
if (expression is GrSpreadArgument) {
val type = expression.argument.type as? GrTupleType ?: return null
type.componentTypes.mapTo(result) {
JustTypeArgument(it)
}
}
else {
result += ExpressionArgument(expression)
}
}
closureArguments.mapTo(result) {
ExpressionArgument(it)
}
return result
}
@@ -1,18 +1,18 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.plugins.groovy.lang.resolve.impl
import com.intellij.psi.PsiType
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult
import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil
import org.jetbrains.plugins.groovy.lang.resolve.api.Arguments
import org.jetbrains.plugins.groovy.lang.resolve.api.GroovyMethodCallReference
fun GroovyMethodCallReference.resolveImpl(incomplete: Boolean): Collection<GroovyResolveResult> {
val receiver = receiver ?: TypesUtil.getJavaLangObject(element)
val methodName = methodName
fun resolveWithArguments(args: Arguments?): Array<out GroovyResolveResult> {
fun resolveWithArguments(args: List<PsiType?>?): Array<out GroovyResolveResult> {
return if (args == null) {
ResolveUtil.getMethodCandidates(receiver, methodName, element, incomplete)
}
@@ -21,7 +21,7 @@ fun GroovyMethodCallReference.resolveImpl(incomplete: Boolean): Collection<Groov
}
}
val arguments = arguments
val arguments = arguments?.map { it?.type }
val candidates = resolveWithArguments(arguments)
val tupleType = arguments?.singleOrNull() as? GrTupleType
if (tupleType == null || candidates.any { it.isValidResult }) {
@@ -3,9 +3,9 @@ package org.jetbrains.plugins.groovy.lang.resolve.references
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiType
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty
import org.jetbrains.plugins.groovy.lang.psi.util.getArgumentListType
import org.jetbrains.plugins.groovy.lang.psi.util.getArgumentListArgument
import org.jetbrains.plugins.groovy.lang.resolve.api.Argument
import org.jetbrains.plugins.groovy.lang.resolve.api.Arguments
import org.jetbrains.plugins.groovy.lang.resolve.api.GroovyMethodCallReferenceBase
@@ -28,10 +28,10 @@ class GrGetAtReference(element: GrIndexProperty) : GrIndexPropertyReference(elem
override val methodName: String get() = "getAt"
override val arguments: Arguments get() = listOf(element.getArgumentListType())
override val arguments: Arguments get() = listOf(element.getArgumentListArgument())
}
class GrPutAtReference(element: GrIndexProperty) : GrIndexPropertyReference(element) {
class GrPutAtReference(element: GrIndexProperty, private val rValue: Argument?) : GrIndexPropertyReference(element) {
override fun getRangeInElement(): TextRange {
val argumentList = element.argumentList
@@ -40,10 +40,5 @@ class GrPutAtReference(element: GrIndexProperty) : GrIndexPropertyReference(elem
override val methodName: String get() = "putAt"
override val arguments: Arguments
get() {
val listArgument = element.getArgumentListType()
val rValue = (element.parent as? GrAssignmentExpression)?.type
return listOf(listArgument, rValue)
}
override val arguments: Arguments get() = listOf(element.getArgumentListArgument(), rValue)
}
@@ -14,6 +14,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrParent
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.HardcodedGroovyMethodConstants.*
import org.jetbrains.plugins.groovy.lang.resolve.api.Arguments
import org.jetbrains.plugins.groovy.lang.resolve.api.GroovyMethodCallReferenceBase
import org.jetbrains.plugins.groovy.lang.resolve.api.LazyTypeArgument
class GrOperatorReference(
element: GrOperatorExpression
@@ -26,7 +27,7 @@ class GrOperatorReference(
override val methodName: String = binaryOperatorMethodNames[element.operator] ?: error(element.text)
override val arguments: Arguments? get() = listOf(element.rightType)
override val arguments: Arguments? get() = listOf(LazyTypeArgument { element.rightType })
override fun collectDependencies(): MutableCollection<out PsiPolyVariantReference> {
val result = SmartList<PsiPolyVariantReference>()
@@ -7,6 +7,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSafeCa
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.HardcodedGroovyMethodConstants.AS_TYPE
import org.jetbrains.plugins.groovy.lang.resolve.api.Arguments
import org.jetbrains.plugins.groovy.lang.resolve.api.GroovyMethodCallReferenceBase
import org.jetbrains.plugins.groovy.lang.resolve.api.LazyTypeArgument
import org.jetbrains.plugins.groovy.lang.resolve.wrapClassType
class GrSafeCastReference(element: GrSafeCastExpression) : GroovyMethodCallReferenceBase<GrSafeCastExpression>(element) {
@@ -17,5 +18,5 @@ class GrSafeCastReference(element: GrSafeCastExpression) : GroovyMethodCallRefer
override val methodName: String get() = AS_TYPE
override val arguments: Arguments? get() = listOf(wrapClassType(element.castTypeElement?.type, element))
override val arguments: Arguments? get() = listOf(LazyTypeArgument { wrapClassType(element.castTypeElement?.type, element) })
}