mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-196685 IDEA 2018.2 freezes on specific editing of build.gradle file
This commit is contained in:
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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 com.intellij.openapi.util;
|
||||
|
||||
import com.intellij.openapi.Disposable;
|
||||
@@ -361,8 +347,8 @@ public class RecursionManager {
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public static void assertOnRecursionPrevention(@NotNull Disposable parentDisposable) {
|
||||
ourAssertOnPrevention = true;
|
||||
public static void assertOnRecursionPrevention(@NotNull Disposable parentDisposable, boolean enableAssert) {
|
||||
ourAssertOnPrevention = enableAssert;
|
||||
Disposer.register(parentDisposable, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
@@ -372,4 +358,8 @@ public class RecursionManager {
|
||||
});
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public static void assertOnRecursionPrevention(@NotNull Disposable parentDisposable) {
|
||||
assertOnRecursionPrevention(parentDisposable, true);
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -33,6 +33,8 @@ import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.plugins.groovy.lang.resolve.processors.inference.InferenceKt.buildTopLevelArgumentTypes;
|
||||
|
||||
/**
|
||||
* @author ilyas
|
||||
*/
|
||||
@@ -196,11 +198,9 @@ public class GrNewExpressionImpl extends GrCallExpressionImpl implements GrNewEx
|
||||
}
|
||||
}
|
||||
|
||||
PsiType[] types = PsiUtil.getArgumentTypes(ref, true);
|
||||
PsiType[] types = buildTopLevelArgumentTypes(ref);
|
||||
|
||||
if (types != null) {
|
||||
types = GrInnerClassConstructorUtil.addEnclosingArgIfNeeded(types, this, (PsiClass)classCandidate.getElement());
|
||||
}
|
||||
types = GrInnerClassConstructorUtil.addEnclosingArgIfNeeded(types, this, (PsiClass)classCandidate.getElement());
|
||||
return PsiUtil.getConstructorCandidates(ref, classCandidate, types);
|
||||
}
|
||||
|
||||
|
||||
+5
-15
@@ -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.resolve.delegatesTo;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -23,6 +9,7 @@ import com.intellij.psi.util.TypeConversionUtil;
|
||||
import groovy.lang.Closure;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyMethodResult;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature;
|
||||
@@ -212,6 +199,9 @@ public class DefaultDelegatesToProvider implements GrDelegatesToProvider {
|
||||
PsiElement context = FromStringHintProcessor.createContext((PsiMethod)element);
|
||||
PsiType type = JavaPsiFacade.getElementFactory(context.getProject()).createTypeFromText(typeValue, context);
|
||||
|
||||
if (result instanceof GroovyMethodResult) {
|
||||
return ((GroovyMethodResult)result).getSubstitutor(false).substitute(type);
|
||||
}
|
||||
return result.getSubstitutor().substitute(type);
|
||||
}
|
||||
|
||||
|
||||
+7
-49
@@ -9,26 +9,20 @@ import com.intellij.psi.scope.ElementClassHint;
|
||||
import com.intellij.psi.scope.JavaScopeProcessorEvent;
|
||||
import com.intellij.psi.scope.NameHint;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.SpreadState;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrCallExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrMapType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyMethodResultImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
|
||||
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.psi.impl.synthetic.GrBindingVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.GrResolverProcessor;
|
||||
@@ -38,13 +32,15 @@ import org.jetbrains.plugins.groovy.lang.resolve.processors.inference.GroovyInfe
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.inference.GroovyInferenceSessionBuilder;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.inference.MethodCandidate;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.plugins.groovy.lang.psi.util.PropertyUtilKt.isPropertyName;
|
||||
import static org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil.isAccessible;
|
||||
import static org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil.isStaticsOK;
|
||||
import static org.jetbrains.plugins.groovy.lang.resolve.processors.inference.InferenceKt.getTopLevelTypeCached;
|
||||
import static org.jetbrains.plugins.groovy.lang.resolve.processors.inference.InferenceKt.*;
|
||||
|
||||
public abstract class GroovyResolverProcessor implements PsiScopeProcessor, ElementClassHint, NameHint, DynamicMembersHint {
|
||||
|
||||
@@ -74,7 +70,7 @@ public abstract class GroovyResolverProcessor implements PsiScopeProcessor, Elem
|
||||
|
||||
myTypeArguments = ref.getTypeArguments();
|
||||
if (kinds.contains(GroovyResolveKind.METHOD) || myIsLValue) {
|
||||
myArgumentTypes = NullableLazyValue.createValue(() -> buildArgumentTypes());
|
||||
myArgumentTypes = NullableLazyValue.createValue(() -> buildTopLevelArgumentTypes(myRef));
|
||||
}
|
||||
else {
|
||||
myArgumentTypes = NullableLazyValue.createValue(() -> null);
|
||||
@@ -196,7 +192,7 @@ public abstract class GroovyResolverProcessor implements PsiScopeProcessor, Elem
|
||||
final PsiSubstitutor siteSubstitutor = updateSubst(myRef.getTypeArguments(), method.getTypeParameters(), substitutor);
|
||||
GrExpression qualifierExpression = myRef.getQualifierExpression();
|
||||
Argument qualifierConstraint = buildQualifier(state, qualifierExpression);
|
||||
List<Argument> argumentConstraints = buildArguments();
|
||||
List<Argument> argumentConstraints = buildArguments(myRef);
|
||||
|
||||
if (method instanceof GrGdkMethod) {
|
||||
ArrayList<Argument> arguments = new ArrayList<>();
|
||||
@@ -225,46 +221,8 @@ public abstract class GroovyResolverProcessor implements PsiScopeProcessor, Elem
|
||||
return new Argument(resolvedThis != null ? resolvedThis : type, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<Argument> buildArguments() {
|
||||
PsiElement parent = myRef.getParent();
|
||||
if (parent instanceof GrCall) {
|
||||
List<Argument> result = new ArrayList<>();
|
||||
GrCall call = (GrCall)parent;
|
||||
GrNamedArgument[] namedArgs = call.getNamedArguments();
|
||||
GrExpression[] expressions = call.getExpressionArguments();
|
||||
GrClosableBlock[] closures = call.getClosureArguments();
|
||||
|
||||
if (namedArgs.length > 0) {
|
||||
GrNamedArgument context = namedArgs[0];
|
||||
result.add(new Argument(GrMapType.createFromNamedArgs(context, namedArgs), null));
|
||||
}
|
||||
|
||||
GrExpression[] argExp = ArrayUtil.mergeArrays(expressions, closures);
|
||||
|
||||
List<Argument> constraints = Arrays.stream(argExp).map((exp) -> new Argument(null, exp)).collect(Collectors.toList());
|
||||
result.addAll(constraints);
|
||||
return result;
|
||||
}
|
||||
|
||||
PsiType[] argumentTypes = PsiUtil.getArgumentTypes(myRef, false, null);
|
||||
if (argumentTypes == null) return Collections.emptyList();
|
||||
return Arrays.stream(argumentTypes).map((t) -> new Argument(t, null)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PsiType[] buildArgumentTypes() {
|
||||
return buildArguments().stream().map(it -> {
|
||||
if (it.getExpression() != null) {
|
||||
return getTopLevelTypeCached(it.getExpression());
|
||||
} else {
|
||||
if (it.getType() instanceof GrMapType) {
|
||||
return TypesUtil.createTypeByFQClassName(CommonClassNames.JAVA_UTIL_MAP, myRef);
|
||||
}
|
||||
return it.getType();
|
||||
}
|
||||
}).toArray(PsiType[]::new);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static PsiSubstitutor updateSubst(@NotNull PsiType[] arguments,
|
||||
|
||||
+14
-13
@@ -10,6 +10,7 @@ import com.intellij.psi.util.TypeConversionUtil
|
||||
import com.intellij.util.ArrayUtil
|
||||
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyMethodResult
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrClassInitializer
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable
|
||||
@@ -21,7 +22,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinitionBody
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil
|
||||
|
||||
class GroovyInferenceSessionBuilder(val ref: GrReferenceExpression, val candidate: MethodCandidate) {
|
||||
@@ -111,18 +111,19 @@ class GroovyInferenceSessionBuilder(val ref: GrReferenceExpression, val candidat
|
||||
else if (parent is GrAssignmentExpression && call == parent.rValue) {
|
||||
val lValue = PsiUtil.skipParentheses(parent.lValue, false)
|
||||
return if (lValue is GrExpression && lValue !is GrIndexProperty) lValue.nominalType else null
|
||||
} else if (parent is GrArgumentList && gparent is GrNewExpression) { // TODO: fix with moving constructor resolve to new API
|
||||
val resolveResult = gparent.advancedResolve()
|
||||
val parameters = GrClosureSignatureUtil.mapArgumentsToParameters(
|
||||
resolveResult,
|
||||
gparent,
|
||||
false,
|
||||
true,
|
||||
gparent.namedArguments,
|
||||
gparent.expressionArguments,
|
||||
gparent.closureArguments)
|
||||
return parameters?.get(call)?.second
|
||||
} else if (parent is GrVariable) {
|
||||
}
|
||||
else if (parent is GrArgumentList && gparent is GrNewExpression) { // TODO: fix with moving constructor resolve to new API
|
||||
with(gparent) {
|
||||
val resolveResult = advancedResolve()
|
||||
if (resolveResult is GroovyMethodResult) {
|
||||
val methodCandidate = MethodCandidate(resolveResult.element, resolveResult.getSubstitutor(false), null,
|
||||
buildArguments(referenceElement!!), call)
|
||||
return methodCandidate.argumentMapping[Argument(null, call)]?.second
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
else if (parent is GrVariable) {
|
||||
return parent.declaredType
|
||||
}
|
||||
return null
|
||||
|
||||
+46
-4
@@ -1,25 +1,29 @@
|
||||
// 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.processors.inference
|
||||
|
||||
import com.intellij.psi.CommonClassNames
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiType
|
||||
import com.intellij.util.ArrayUtil
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyMethodResult
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall
|
||||
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.api.statements.typedef.members.GrEnumConstant
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrMapType
|
||||
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.util.GroovyCommonClassNames
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil
|
||||
import java.util.*
|
||||
|
||||
fun getTopLevelType(expression: GrExpression): PsiType? {
|
||||
if (expression is GrMethodCall) {
|
||||
val resolved = expression.advancedResolve()
|
||||
(resolved as? GroovyMethodResult)?.candidate?.let {
|
||||
val session = GroovyInferenceSessionBuilder(expression.invokedExpression as GrReferenceExpression, it)
|
||||
.resolveMode(false)
|
||||
.build()
|
||||
|
||||
val session = GroovyInferenceSessionBuilder(expression.invokedExpression as GrReferenceExpression, it).build()
|
||||
return session.inferSubst().substitute(PsiUtil.getSmartReturnType(it.method))
|
||||
}
|
||||
}
|
||||
@@ -33,4 +37,42 @@ fun getTopLevelType(expression: GrExpression): PsiType? {
|
||||
|
||||
fun getTopLevelTypeCached(expression: GrExpression): PsiType? {
|
||||
return GroovyPsiManager.getInstance(expression.project).getTopLevelType(expression)
|
||||
}
|
||||
|
||||
fun buildArguments(place: PsiElement): List<Argument> {
|
||||
val parent = place as? GrEnumConstant ?: place.parent
|
||||
if (parent is GrCall) {
|
||||
val result = ArrayList<Argument>()
|
||||
val namedArgs = parent.namedArguments
|
||||
val expressions = parent.expressionArguments
|
||||
val closures = parent.closureArguments
|
||||
|
||||
if (namedArgs.isNotEmpty()) {
|
||||
val context = namedArgs[0]
|
||||
result.add(Argument(GrMapType.createFromNamedArgs(context, namedArgs), null))
|
||||
}
|
||||
|
||||
val argExp = ArrayUtil.mergeArrays(expressions, closures)
|
||||
result.addAll(argExp.map { exp -> Argument(null, exp) })
|
||||
return result
|
||||
}
|
||||
|
||||
val argumentTypes = PsiUtil.getArgumentTypes(place, false, null) ?: return emptyList()
|
||||
return argumentTypes.map { t -> Argument(t, null) }
|
||||
}
|
||||
|
||||
|
||||
fun buildTopLevelArgumentTypes(place: PsiElement): Array<PsiType?> {
|
||||
return buildArguments(place).map { (type, expression) ->
|
||||
if (expression != null) {
|
||||
getTopLevelTypeCached(expression)
|
||||
}
|
||||
else {
|
||||
if (type is GrMapType) {
|
||||
TypesUtil.createTypeByFQClassName(CommonClassNames.JAVA_UTIL_MAP, place)
|
||||
} else {
|
||||
type
|
||||
}
|
||||
}
|
||||
}.toTypedArray()
|
||||
}
|
||||
+25
@@ -238,6 +238,31 @@ class SomeClass {
|
||||
measureHighlighting(text, 14_000)
|
||||
}
|
||||
|
||||
void "test constructor call's"() {
|
||||
def text = """
|
||||
class Cl {
|
||||
|
||||
Cl(Map<String, Integer> a, Condition<Cl> con, String s) {
|
||||
}
|
||||
|
||||
interface Condition<T> {}
|
||||
|
||||
static <T> Condition<T> alwaysFalse() {
|
||||
return (Condition<T>)null
|
||||
}
|
||||
|
||||
|
||||
static m() {
|
||||
${'''new Cl(alwaysFalse(), name: 1, m: 2, new Object().toString(), sad: 12)\n'''*100}
|
||||
}
|
||||
}
|
||||
"""
|
||||
IdeaTestUtil.startPerformanceTest(getTestName(false), 750, configureAndHighlight(text))
|
||||
.attempts(20)
|
||||
.usesAllCPUCores()
|
||||
.assertTiming()
|
||||
}
|
||||
|
||||
void "test infer only the variable types that are needed"() {
|
||||
addGdsl '''contribute(currentType(String.name)) {
|
||||
println 'sleeping'
|
||||
|
||||
+34
@@ -2,6 +2,7 @@
|
||||
package org.jetbrains.plugins.groovy.lang.highlighting
|
||||
|
||||
import com.intellij.codeInspection.InspectionProfileEntry
|
||||
import com.intellij.openapi.util.RecursionManager
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import org.jetbrains.annotations.NotNull
|
||||
import org.jetbrains.plugins.groovy.GroovyLightProjectDescriptor
|
||||
@@ -23,6 +24,12 @@ class GrLatestHighlightingTest extends GrHighlightingTestBase {
|
||||
new MissingReturnInspection()]
|
||||
}
|
||||
|
||||
@Override
|
||||
void setUp() throws Exception {
|
||||
super.setUp()
|
||||
RecursionManager.assertOnRecursionPrevention(myFixture.testRootDisposable)
|
||||
}
|
||||
|
||||
void 'test IDEA-184690'() {
|
||||
testHighlighting '''\
|
||||
import groovy.transform.CompileStatic
|
||||
@@ -383,6 +390,7 @@ class GoodCodeRed {
|
||||
}
|
||||
|
||||
void 'test recursive generics'() {
|
||||
RecursionManager.assertOnRecursionPrevention(myFixture.testRootDisposable, false)
|
||||
testHighlighting '''
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@@ -435,6 +443,32 @@ class Cl {
|
||||
'''
|
||||
}
|
||||
|
||||
void 'test constructor parameter'() {
|
||||
testHighlighting '''
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class Cl {
|
||||
|
||||
Cl(Map<String, Integer> a, Condition<Cl> con, String s) {
|
||||
}
|
||||
|
||||
interface Condition<T> {}
|
||||
|
||||
static <T> Condition<T> alwaysFalse() {
|
||||
return (Condition<T>)null
|
||||
}
|
||||
|
||||
|
||||
static m() {
|
||||
new Cl(alwaysFalse(), name: 1, m: 2, new Object().toString(), sad: 12)
|
||||
}
|
||||
}
|
||||
'''
|
||||
}
|
||||
|
||||
|
||||
|
||||
void 'test call without reference'() {
|
||||
testHighlighting '''
|
||||
class E {
|
||||
|
||||
Reference in New Issue
Block a user