[groovy] eagerly compute list component types

.. otherwise the instantiation of ListLiteralType happens inside one InferenceContext instance,
while component types might be computed in another one, leading to incorrect results/messed caching/SOE.

Example: `org.jetbrains.plugins.groovy.lang.resolve.TypeInferenceTest.testRecursionWithLists`.
Changing list literal type to ArrayList will cause two `DFAType`s in the beginning of a while-loop to become unequal,
then they are joined via LUB (`DFAType.create(DFAType, DFAType, PsiManager)`), type of the `[list]` was instantiated
inside a `PartialContext`, then computation of component types happens outside of `PartialContext`,
which causes unnecessary recursion and disabled caching.

GitOrigin-RevId: 83bc7e0a2fac6f48d30ac55f8c96fca5428b6811
This commit is contained in:
Daniil Ovchinnikov
2020-10-13 18:00:05 +00:00
committed by intellij-monorepo-bot
parent e822967584
commit 3ed75ce0a3
2 changed files with 7 additions and 5 deletions
@@ -1,4 +1,4 @@
// Copyright 2000-2019 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.
// Copyright 2000-2020 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.typing
import com.intellij.openapi.util.RecursionManager
@@ -16,9 +16,11 @@ open class ListLiteralType(val expressions: List<GrExpression>, private val cont
override fun isValid(): Boolean = context.isValid
override fun inferComponents(): List<PsiType?> {
return expressions.flatMap {
doGetComponentTypes(it) ?: return emptyList()
override fun inferComponents(): List<PsiType?> = myComponentTypes
private val myComponentTypes: List<PsiType?> = run {
expressions.flatMap {
doGetComponentTypes(it) ?: return@run emptyList()
}
}
@@ -994,7 +994,7 @@ def foo() {
void 'test recursive literal types'() {
RecursionManager.disableMissedCacheAssertions(testRootDisposable)
doExprTest 'def foo() { [foo()] }\nfoo()', "java.util.List<java.util.List>"
doExprTest 'def foo() { [foo()] }\nfoo()', "java.util.List<java.lang.Object>"
doExprTest 'def foo() { [new Object(), foo()] }\nfoo()', "java.util.List<java.lang.Object>"
doExprTest 'def foo() { [someKey1: foo()] }\nfoo()', "java.util.LinkedHashMap<java.lang.String, java.util.LinkedHashMap>"
doExprTest 'def foo() { [someKey0: new Object(), someKey1: foo()] }\nfoo()',