[groovy] prevent recursion when computing literal type substitutor

This change should fix EA-68501, EA-97181 and IDEA-190205.
This commit is contained in:
Daniil Ovchinnikov
2018-04-16 17:55:19 +03:00
parent 9f9f124de3
commit d98b845a2d
4 changed files with 21 additions and 50 deletions
@@ -1,18 +1,4 @@
/*
* 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.
*/
// 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.psi.impl;
import com.intellij.openapi.util.NotNullLazyValue;
@@ -125,7 +111,8 @@ public abstract class GrLiteralClassType extends PsiClassType {
final PsiType[] params = getParameters();
if (params.length == 0 || params[0] == null) return name;
return name + "<" + StringUtil.join(params, psiType -> psiType.getPresentableText(), ", ") + ">";
Function<PsiType, String> f = psiType -> psiType == this ? getClassName() : psiType.getPresentableText();
return name + "<" + StringUtil.join(params, f, ", ") + ">";
}
@Override
@@ -135,7 +122,7 @@ public abstract class GrLiteralClassType extends PsiClassType {
final PsiType[] params = getParameters();
if (params.length == 0 || params[0] == null) return name;
final Function<PsiType, String> f = psiType -> psiType.getCanonicalText();
final Function<PsiType, String> f = psiType -> psiType == this ? getJavaClassName() : psiType.getCanonicalText();
return name + "<" + StringUtil.join(params, f, ", ") + ">";
}
@@ -1,18 +1,4 @@
/*
* 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.
*/
// 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.psi.impl;
@@ -33,6 +19,8 @@ import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
import java.util.*;
import static com.intellij.openapi.util.RecursionManager.doPreventingRecursion;
/**
* @author peter
*/
@@ -97,7 +85,8 @@ public abstract class GrMapType extends GrLiteralClassType {
@Override
@NotNull
public PsiType[] getParameters() {
return myParameters.getValue();
PsiType[] parameters = doPreventingRecursion(this, false, () -> myParameters.getValue());
return parameters == null ? PsiType.EMPTY_ARRAY : parameters;
}
@Override
@@ -1,22 +1,9 @@
/*
* 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.
*/
// 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.psi.impl;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.openapi.util.VolatileNotNullLazyValue;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
@@ -77,7 +64,8 @@ public abstract class GrTupleType extends GrLiteralClassType {
@Override
@NotNull
public PsiType[] getParameters() {
return myParameters.getValue();
PsiType[] parameters = RecursionManager.doPreventingRecursion(this, false, () -> myParameters.getValue());
return parameters == null ? PsiType.EMPTY_ARRAY : parameters;
}
@Override
@@ -1,4 +1,4 @@
// Copyright 2000-2017 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-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
import com.intellij.psi.PsiIntersectionType
@@ -792,6 +792,13 @@ def foo(List list) {
doExprTest "[foo: 'bar', 2: 'goo']", "java.util.LinkedHashMap<java.io.Serializable, java.lang.String>"
}
void 'test recursive literal types'() {
doExprTest 'def foo() { [foo()] }\nfoo()', "java.util.List<java.util.List>"
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()', "java.util.LinkedHashMap<java.lang.String, java.lang.Object>"
}
void 'test range literal type'() {
doExprTest "1..10", "groovy.lang.IntRange"
doExprTest "'a'..'z'", "groovy.lang.Range<java.lang.String>"