mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-95249 new WebView(contextMenuEnabled: false) in Groovy highlights 'false' as warning
This commit is contained in:
+66
-33
@@ -16,6 +16,7 @@
|
||||
package org.jetbrains.plugins.groovy.lang;
|
||||
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.scope.ElementClassHint;
|
||||
import com.intellij.psi.scope.NameHint;
|
||||
@@ -23,10 +24,8 @@ import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor;
|
||||
import org.jetbrains.plugins.groovy.extensions.GroovyNamedArgumentProvider;
|
||||
import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
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.GrCall;
|
||||
@@ -41,9 +40,10 @@ import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor.*;
|
||||
import static org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor.Priority;
|
||||
import static org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint.ResolveKind.*;
|
||||
|
||||
/**
|
||||
@@ -94,13 +94,52 @@ public class GroovyConstructorNamedArgumentProvider extends GroovyNamedArgumentP
|
||||
public static void processClass(@NotNull GrCall call,
|
||||
PsiClassType type,
|
||||
@Nullable String argumentName,
|
||||
Map<String, NamedArgumentDescriptor> result) {
|
||||
final Map<String, NamedArgumentDescriptor> result) {
|
||||
if (argumentName == null) {
|
||||
ResolveUtil.processAllDeclarations(type, new MyPsiScopeProcessor(result, call), ResolveState.initial(), call);
|
||||
final HashMap<String, Pair<PsiType, PsiElement>> map = new HashMap<String, Pair<PsiType, PsiElement>>();
|
||||
|
||||
MyPsiScopeProcessor processor = new MyPsiScopeProcessor() {
|
||||
@Override
|
||||
protected void addNamedArgument(String propertyName, PsiType type, PsiElement element) {
|
||||
if (result.containsKey(propertyName)) return;
|
||||
|
||||
Pair<PsiType, PsiElement> pair = map.get(propertyName);
|
||||
if (pair != null) {
|
||||
if (!(element instanceof PsiMethod) && !(element instanceof PsiField)) { // methods should override fields otherwise return
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
map.put(propertyName, Pair.create(type, element));
|
||||
}
|
||||
};
|
||||
|
||||
processor.setResolveTargetKinds(ResolverProcessor.RESOLVE_KINDS_METHOD_PROPERTY);
|
||||
|
||||
ResolveUtil.processAllDeclarations(type, processor, ResolveState.initial(), call);
|
||||
|
||||
for (Map.Entry<String, Pair<PsiType, PsiElement>> entry : map.entrySet()) {
|
||||
result.put(entry.getKey(), new NamedArgumentDescriptor.TypeCondition(entry.getValue().first, entry.getValue().getSecond()).setPriority(Priority.AS_LOCAL_VARIABLE));
|
||||
}
|
||||
}
|
||||
else {
|
||||
ResolveUtil.processAllDeclarations(type, new MyPsiScopeProcessor(argumentName, true, result, call), ResolveState.initial(), call);
|
||||
ResolveUtil.processAllDeclarations(type, new MyPsiScopeProcessor(argumentName, false, result, call), ResolveState.initial(), call);
|
||||
MyPsiScopeProcessor processor = new MyPsiScopeProcessor() {
|
||||
@Override
|
||||
protected void addNamedArgument(String propertyName, PsiType type, PsiElement element) {
|
||||
if (result.containsKey(propertyName)) return;
|
||||
result.put(propertyName, new NamedArgumentDescriptor.TypeCondition(type, element).setPriority(Priority.AS_LOCAL_VARIABLE));
|
||||
}
|
||||
};
|
||||
|
||||
processor.setResolveTargetKinds(ResolverProcessor.RESOLVE_KINDS_METHOD);
|
||||
processor.setNameHint(GroovyPropertyUtils.getSetterName(argumentName));
|
||||
|
||||
ResolveUtil.processAllDeclarations(type, processor, ResolveState.initial(), call);
|
||||
|
||||
processor.setResolveTargetKinds(ResolverProcessor.RESOLVE_KINDS_PROPERTY);
|
||||
processor.setNameHint(argumentName);
|
||||
|
||||
ResolveUtil.processAllDeclarations(type, processor, ResolveState.initial(), call);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,29 +165,9 @@ public class GroovyConstructorNamedArgumentProvider extends GroovyNamedArgumentP
|
||||
return false;
|
||||
}
|
||||
|
||||
private static class MyPsiScopeProcessor implements PsiScopeProcessor, NameHint, ClassHint, ElementClassHint {
|
||||
private final String myNameHint;
|
||||
private final Map<String, NamedArgumentDescriptor> myResult;
|
||||
private final EnumSet<ResolveKind> myResolveTargetKinds;
|
||||
|
||||
private MyPsiScopeProcessor(Map<String, NamedArgumentDescriptor> result, GroovyPsiElement context) {
|
||||
myResolveTargetKinds = ResolverProcessor.RESOLVE_KINDS_METHOD_PROPERTY;
|
||||
myNameHint = null;
|
||||
myResult = result;
|
||||
}
|
||||
|
||||
private MyPsiScopeProcessor(@NotNull String propertyName, boolean findSetter, Map<String, NamedArgumentDescriptor> result, GroovyPsiElement context) {
|
||||
if (findSetter) {
|
||||
myResolveTargetKinds = ResolverProcessor.RESOLVE_KINDS_METHOD;
|
||||
myNameHint = GroovyPropertyUtils.getSetterName(propertyName);
|
||||
}
|
||||
else {
|
||||
myResolveTargetKinds = ResolverProcessor.RESOLVE_KINDS_PROPERTY;
|
||||
myNameHint = propertyName;
|
||||
}
|
||||
|
||||
myResult = result;
|
||||
}
|
||||
private static abstract class MyPsiScopeProcessor implements PsiScopeProcessor, NameHint, ClassHint, ElementClassHint {
|
||||
private String myNameHint;
|
||||
private EnumSet<ResolveKind> myResolveTargetKinds;
|
||||
|
||||
@Override
|
||||
public boolean execute(@NotNull PsiElement element, ResolveState state) {
|
||||
@@ -157,6 +176,8 @@ public class GroovyConstructorNamedArgumentProvider extends GroovyNamedArgumentP
|
||||
PsiType type;
|
||||
|
||||
if (element instanceof PsiMethod) {
|
||||
if (!myResolveTargetKinds.contains(METHOD)) return true;
|
||||
|
||||
PsiMethod method = (PsiMethod)element;
|
||||
if (!GroovyPropertyUtils.isSimplePropertySetter(method)) return true;
|
||||
|
||||
@@ -166,25 +187,29 @@ public class GroovyConstructorNamedArgumentProvider extends GroovyNamedArgumentP
|
||||
type = method.getParameterList().getParameters()[0].getType();
|
||||
}
|
||||
else {
|
||||
if (!myResolveTargetKinds.contains(PROPERTY)) return true;
|
||||
|
||||
type = ((PsiField)element).getType();
|
||||
propertyName = ((PsiField)element).getName();
|
||||
}
|
||||
|
||||
if (((PsiModifierListOwner)element).hasModifierProperty(PsiModifier.STATIC)) return true;
|
||||
if (propertyName.equals(METACLASS)) return true;
|
||||
|
||||
if (myResult.containsKey(propertyName) || propertyName.equals(METACLASS)) return true;
|
||||
if (((PsiModifierListOwner)element).hasModifierProperty(PsiModifier.STATIC)) return true;
|
||||
|
||||
PsiSubstitutor substitutor = state.get(PsiSubstitutor.KEY);
|
||||
if (substitutor != null) {
|
||||
type = substitutor.substitute(type);
|
||||
}
|
||||
|
||||
myResult.put(propertyName, new NamedArgumentDescriptor.TypeCondition(type, element).setPriority(Priority.AS_LOCAL_VARIABLE));
|
||||
addNamedArgument(propertyName, type, element);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected abstract void addNamedArgument(String propertyName, PsiType type, PsiElement element);
|
||||
|
||||
@Override
|
||||
public <T> T getHint(@NotNull Key<T> hintKey) {
|
||||
if ((NameHint.KEY == hintKey && myNameHint != null) || ClassHint.KEY == hintKey || ElementClassHint.KEY == hintKey) {
|
||||
@@ -231,5 +256,13 @@ public class GroovyConstructorNamedArgumentProvider extends GroovyNamedArgumentP
|
||||
public String getName(ResolveState state) {
|
||||
return myNameHint;
|
||||
}
|
||||
|
||||
public void setNameHint(String nameHint) {
|
||||
myNameHint = nameHint;
|
||||
}
|
||||
|
||||
public void setResolveTargetKinds(EnumSet<ResolveKind> resolveTargetKinds) {
|
||||
myResolveTargetKinds = resolveTargetKinds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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
|
||||
|
||||
import com.intellij.psi.CommonClassNames
|
||||
import com.intellij.psi.PsiType
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil
|
||||
|
||||
/**
|
||||
* @author Sergey Evdokimov
|
||||
*/
|
||||
class GroovyNamedArgumentTest extends LightCodeInsightFixtureTestCase {
|
||||
|
||||
public void testNamedArgumentsFromJavaClass() {
|
||||
myFixture.addClass("""
|
||||
class JavaClass {
|
||||
public int intField;
|
||||
private String stringField;
|
||||
|
||||
public static String staticField;
|
||||
|
||||
private int boolProperty;
|
||||
|
||||
public void setBoolProperty(boolean b) {
|
||||
boolProperty = b ? 1 : 0;
|
||||
}
|
||||
|
||||
public void getBoolProperty() {
|
||||
return boolProperty == 1;
|
||||
}
|
||||
}
|
||||
""")
|
||||
|
||||
myFixture.configureByText("a.groovy", "new JavaClass(<caret>)")
|
||||
|
||||
def caretOffset = myFixture.getCaretOffset()
|
||||
|
||||
def lookUps = myFixture.completeBasic()
|
||||
|
||||
assert lookUps != null
|
||||
|
||||
def context = PsiTreeUtil.getParentOfType(myFixture.file.findElementAt(caretOffset), GroovyPsiElement)
|
||||
|
||||
def allLookupStrings = new HashSet()
|
||||
|
||||
for (def e : lookUps) {
|
||||
if (e.object instanceof NamedArgumentDescriptor) {
|
||||
NamedArgumentDescriptor na = e.object
|
||||
|
||||
allLookupStrings << e.lookupString
|
||||
|
||||
if (e.lookupString == "intField") {
|
||||
assert na.checkType(PsiType.INT, context)
|
||||
assert na.checkType(PsiType.LONG, context)
|
||||
assert na.checkType(TypesUtil.createType(CommonClassNames.JAVA_LANG_INTEGER, context), context)
|
||||
|
||||
assert !na.checkType(PsiType.BOOLEAN, (GroovyPsiElement)context)
|
||||
assert !na.checkType(TypesUtil.createType(CommonClassNames.JAVA_LANG_STRING, context), context)
|
||||
}
|
||||
else if (e.lookupString == "boolProperty") {
|
||||
assert na.checkType(PsiType.BOOLEAN, context)
|
||||
assert na.checkType(TypesUtil.createType(CommonClassNames.JAVA_LANG_BOOLEAN, context), context)
|
||||
|
||||
// todo unkoment this
|
||||
//assert na.checkType(TypesUtil.createType(CommonClassNames.JAVA_LANG_STRING, context), context)
|
||||
//assert na.checkType(PsiType.INT, context)
|
||||
//assert na.checkType(TypesUtil.createType(CommonClassNames.JAVA_LANG_OBJECT, context), (GroovyPsiElement)context)
|
||||
}
|
||||
else if (e.lookupString == "stringField") {
|
||||
assert na.checkType(PsiType.INT, (GroovyPsiElement)context)
|
||||
assert na.checkType(PsiType.BOOLEAN, (GroovyPsiElement)context)
|
||||
assert na.checkType(TypesUtil.createType(CommonClassNames.JAVA_LANG_STRING, context), (GroovyPsiElement)context)
|
||||
assert na.checkType(TypesUtil.createType(CommonClassNames.JAVA_LANG_OBJECT, context), (GroovyPsiElement)context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert allLookupStrings == new HashSet(['intField', 'boolProperty', 'stringField'])
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user