diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrIndexPropertyImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrIndexPropertyImpl.java index 017e5ad857c4..d2a2c988eaf9 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrIndexPropertyImpl.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/path/GrIndexPropertyImpl.java @@ -22,32 +22,24 @@ import com.intellij.openapi.util.AtomicNullableLazyValue; import com.intellij.openapi.util.NotNullLazyValue; import com.intellij.openapi.util.NullableLazyValue; import com.intellij.psi.PsiType; -import com.intellij.util.Function; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; -import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty; import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper; -import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrExpressionImpl; -import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyIndexPropertyUtil; import org.jetbrains.plugins.groovy.lang.psi.util.GroovyLValueUtil; import org.jetbrains.plugins.groovy.lang.resolve.GroovyPolyVariantReference; -import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; - -import static org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil.getClassReferenceFromExpression; +import org.jetbrains.plugins.groovy.lang.typing.GrTypeCalculator; /** * @author ilyas */ public class GrIndexPropertyImpl extends GrExpressionImpl implements GrIndexProperty { - private static final Function TYPE_CALCULATOR = index -> index.inferType(); - private final NullableLazyValue myRValueReference = AtomicNullableLazyValue.createValue( () -> GroovyLValueUtil.isRValue(this) ? new GrIndexPropertyReference(this, true) : null ); @@ -91,30 +83,6 @@ public class GrIndexPropertyImpl extends GrExpressionImpl implements GrIndexProp return myReferences.getValue(); } - // return not null in case of String[], int[], double[][] - @Nullable - private PsiType inferArrayType() { - PsiType arrayTypeBase = getClassReferenceFromExpression(this); - if (arrayTypeBase == null) return null; - return TypesUtil.createJavaLangClassType(arrayTypeBase, getProject(), getResolveScope()); - } - - private PsiType inferType() { - final PsiType arrayType = inferArrayType(); - if (arrayType != null) return arrayType; - - final PsiType arrayAccessType = GroovyIndexPropertyUtil.getSimpleArrayAccessType(this); - if (arrayAccessType != null) return arrayAccessType; - - final GrIndexPropertyReference reference = myRValueReference.getValue(); - if (reference == null) return null; - - final GroovyResolveResult[] results = reference.multiResolve(false); - final GroovyResolveResult candidate = PsiImplUtil.extractUniqueResult(results); - - return ResolveUtil.extractReturnTypeFromCandidate(candidate, this, null); - } - public GrIndexPropertyImpl(@NotNull ASTNode node) { super(node); } @@ -142,7 +110,7 @@ public class GrIndexPropertyImpl extends GrExpressionImpl implements GrIndexProp @Override public PsiType getType() { - return TypeInferenceHelper.getCurrentContext().getExpressionType(this, TYPE_CALCULATOR); + return TypeInferenceHelper.getCurrentContext().getExpressionType(this, GrTypeCalculator::getTypeFromCalculators); } @Nullable diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/indexPropertyUtil.kt b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/indexPropertyUtil.kt index 6e4f2a25ffca..943a10e4db4c 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/indexPropertyUtil.kt +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/psi/util/indexPropertyUtil.kt @@ -31,6 +31,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrI 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 fun GrIndexProperty.isSimpleArrayAccess(): Boolean { return getSimpleArrayAccessType() != null @@ -71,6 +72,11 @@ fun GrIndexProperty.isClassLiteral(): Boolean { } } +fun GrIndexProperty.getArrayClassType(): PsiType? { + val arrayTypeBase = getClassReferenceFromExpression(this) ?: return null + return TypesUtil.createJavaLangClassType(arrayTypeBase, project, resolveScope) +} + /** * If there is one argument (`foo[a]`), then result is a type of `a`. * If there is multiple arguments (`foo[a,b,c]`), then result is a list from Groovy perspective (as in `[a, b, c]` as a literal). diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/typing/DefaultIndexAccessTypeCalculator.kt b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/typing/DefaultIndexAccessTypeCalculator.kt new file mode 100644 index 000000000000..3f686b1aa997 --- /dev/null +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/lang/typing/DefaultIndexAccessTypeCalculator.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2000-2017 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.groovy.lang.typing + +import com.intellij.psi.PsiType +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty +import org.jetbrains.plugins.groovy.lang.psi.util.advancedResolve +import org.jetbrains.plugins.groovy.lang.psi.util.getArrayClassType +import org.jetbrains.plugins.groovy.lang.psi.util.getSimpleArrayAccessType +import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil.extractReturnTypeFromCandidate + +class DefaultIndexAccessTypeCalculator : GrTypeCalculator { + + override fun getType(expression: GrIndexProperty): PsiType? { + return expression.getArrayClassType() ?: + expression.getSimpleArrayAccessType() ?: + extractReturnTypeFromCandidate(expression.advancedResolve(), expression, null) + } +} \ No newline at end of file diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 256dd53eff20..6130169720eb 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -165,6 +165,8 @@ implementationClass="org.jetbrains.plugins.groovy.lang.typing.GrClosureDelegateTypeCalculator"/> +