mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
IDEA-83744 Always insert '()' when class name is completed after 'new' keyword
This commit is contained in:
@@ -158,9 +158,11 @@ public class AllClassesGetter {
|
||||
}).forEach(new Processor<PsiClass>() {
|
||||
public boolean process(PsiClass psiClass) {
|
||||
assert psiClass != null;
|
||||
if (isSuitable(context, packagePrefix, qnames, psiClass, filterByScope, pkgContext)) {
|
||||
qnames.add(psiClass.getQualifiedName());
|
||||
consumer.consume(psiClass);
|
||||
if (isAcceptableInContext(context, psiClass, filterByScope, pkgContext)) {
|
||||
String qName = psiClass.getQualifiedName();
|
||||
if (qName != null && qName.startsWith(packagePrefix) && qnames.add(qName)) {
|
||||
consumer.consume(psiClass);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -181,9 +183,9 @@ public class AllClassesGetter {
|
||||
return j > 0 ? prefix.substring(0, j) : "";
|
||||
}
|
||||
|
||||
private static boolean isSuitable(@NotNull final PsiElement context, final String packagePrefix, final Set<String> qnames,
|
||||
@NotNull final PsiClass psiClass,
|
||||
final boolean filterByScope, final boolean pkgContext) {
|
||||
public static boolean isAcceptableInContext(@NotNull final PsiElement context,
|
||||
@NotNull final PsiClass psiClass,
|
||||
final boolean filterByScope, final boolean pkgContext) {
|
||||
ProgressManager.checkCanceled();
|
||||
|
||||
if (!context.isValid() || !psiClass.isValid()) return false;
|
||||
@@ -191,9 +193,7 @@ public class AllClassesGetter {
|
||||
if (JavaCompletionUtil.isInExcludedPackage(psiClass, false)) return false;
|
||||
|
||||
final String qualifiedName = psiClass.getQualifiedName();
|
||||
if (qualifiedName == null || !qualifiedName.startsWith(packagePrefix)) return false;
|
||||
|
||||
if (qnames.contains(qualifiedName)) return false;
|
||||
if (qualifiedName == null) return false;
|
||||
|
||||
if (!filterByScope && !(psiClass instanceof PsiCompiledElement)) return true;
|
||||
|
||||
|
||||
@@ -44,9 +44,7 @@ public class InheritorsHolder implements Consumer<LookupElement> {
|
||||
public void consume(LookupElement lookupElement) {
|
||||
final Object object = lookupElement.getObject();
|
||||
if (object instanceof PsiClass) {
|
||||
final PsiClass psiClass = (PsiClass)object;
|
||||
if (JavaCompletionUtil.hasAccessibleInnerClass(psiClass, myPosition)) return;
|
||||
registerClass(psiClass);
|
||||
registerClass((PsiClass)object);
|
||||
}
|
||||
myResult.addElement(AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(lookupElement));
|
||||
}
|
||||
|
||||
+51
-8
@@ -19,12 +19,12 @@ import com.intellij.codeInsight.ExpectedTypeInfo;
|
||||
import com.intellij.codeInsight.ExpectedTypesProvider;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.lang.LangBundle;
|
||||
import com.intellij.lang.StdLanguages;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.patterns.PsiJavaElementPattern;
|
||||
import com.intellij.patterns.PsiJavaPatterns;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.filters.ClassFilter;
|
||||
import com.intellij.psi.filters.ElementFilter;
|
||||
@@ -35,15 +35,18 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.intellij.util.SmartList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.patterns.PsiJavaPatterns.psiElement;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class JavaClassNameCompletionContributor extends CompletionContributor {
|
||||
private static final PsiJavaElementPattern.Capture<PsiElement> AFTER_NEW = psiElement().afterLeaf(PsiKeyword.NEW);
|
||||
public static final PsiJavaElementPattern.Capture<PsiElement> AFTER_NEW = psiElement().afterLeaf(PsiKeyword.NEW);
|
||||
private static final PsiJavaElementPattern.Capture<PsiElement> IN_TYPE_PARAMETER =
|
||||
psiElement().afterLeaf(PsiKeyword.EXTENDS, PsiKeyword.SUPER, "&").withParent(
|
||||
psiElement(PsiReferenceList.class).withParent(PsiTypeParameter.class));
|
||||
@@ -92,7 +95,8 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
|
||||
final boolean inJavaContext = parameters.getPosition() instanceof PsiIdentifier;
|
||||
if (AFTER_NEW.accepts(insertedElement)) {
|
||||
final boolean afterNew = AFTER_NEW.accepts(insertedElement);
|
||||
if (afterNew) {
|
||||
final PsiExpression expr = PsiTreeUtil.getContextOfType(insertedElement, PsiExpression.class, true);
|
||||
for (final ExpectedTypeInfo info : ExpectedTypesProvider.getExpectedTypes(expr, true)) {
|
||||
final PsiType type = info.getType();
|
||||
@@ -104,20 +108,34 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
|
||||
if (!defaultType.equals(type)) {
|
||||
final PsiClass defClass = PsiUtil.resolveClassInType(defaultType);
|
||||
if (defClass != null) {
|
||||
consumer.consume(createClassLookupItem(defClass, inJavaContext));
|
||||
consumer.consume(createClassLookupItem(defClass, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final boolean lookingForAnnotations = PsiJavaPatterns.psiElement().afterLeaf("@").accepts(insertedElement);
|
||||
final boolean lookingForAnnotations = psiElement().afterLeaf("@").accepts(insertedElement);
|
||||
final boolean pkgContext = JavaCompletionUtil.inSomePackage(insertedElement);
|
||||
AllClassesGetter.processJavaClasses(parameters, matcher, filterByScope, new Consumer<PsiClass>() {
|
||||
@Override
|
||||
public void consume(PsiClass psiClass) {
|
||||
if (lookingForAnnotations && !psiClass.isAnnotationType()) return;
|
||||
|
||||
if (filter.isAcceptable(psiClass, insertedElement)) {
|
||||
consumer.consume(createClassLookupItem(psiClass, inJavaContext));
|
||||
if (!inJavaContext) {
|
||||
consumer.consume(AllClassesGetter.createLookupItem(psiClass, AllClassesGetter.TRY_SHORTENING));
|
||||
} else {
|
||||
for (JavaPsiClassReferenceElement element : createClassLookupItems(psiClass, afterNew,
|
||||
JavaClassNameInsertHandler.JAVA_CLASS_INSERT_HANDLER, new Condition<PsiClass>() {
|
||||
@Override
|
||||
public boolean value(PsiClass psiClass) {
|
||||
return filter.isAcceptable(psiClass, insertedElement) &&
|
||||
AllClassesGetter.isAcceptableInContext(insertedElement, psiClass, filterByScope, pkgContext);
|
||||
}
|
||||
})) {
|
||||
consumer.consume(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -128,6 +146,31 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
|
||||
: AllClassesGetter.TRY_SHORTENING);
|
||||
}
|
||||
|
||||
public static List<JavaPsiClassReferenceElement> createClassLookupItems(final PsiClass psiClass,
|
||||
boolean withInners,
|
||||
InsertHandler<JavaPsiClassReferenceElement> insertHandler,
|
||||
Condition<PsiClass> condition) {
|
||||
List<JavaPsiClassReferenceElement> result = new SmartList<JavaPsiClassReferenceElement>();
|
||||
if (condition.value(psiClass)) {
|
||||
result.add(AllClassesGetter.createLookupItem(psiClass, insertHandler));
|
||||
}
|
||||
String name = psiClass.getName();
|
||||
if (withInners && name != null) {
|
||||
for (PsiClass inner : psiClass.getInnerClasses()) {
|
||||
if (inner.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
for (JavaPsiClassReferenceElement lookupInner : createClassLookupItems(inner, withInners, insertHandler, condition)) {
|
||||
String forced = lookupInner.getForcedPresentableName();
|
||||
lookupInner.setForcedPresentableName(name + "." + (forced != null ? forced : inner.getName()));
|
||||
result.add(lookupInner);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String handleEmptyLookup(@NotNull final CompletionParameters parameters, final Editor editor) {
|
||||
if (!(parameters.getOriginalFile() instanceof PsiJavaFile)) return null;
|
||||
@@ -145,6 +188,6 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
|
||||
private static boolean shouldShowSecondSmartCompletionHint(final CompletionParameters parameters) {
|
||||
return parameters.getCompletionType() == CompletionType.CLASS_NAME &&
|
||||
parameters.getInvocationCount() == 1 &&
|
||||
parameters.getOriginalFile().getLanguage() == StdLanguages.JAVA;
|
||||
parameters.getOriginalFile().getLanguage().isKindOf(JavaLanguage.INSTANCE);
|
||||
}
|
||||
}
|
||||
|
||||
+7
-9
@@ -32,9 +32,6 @@ import com.intellij.psi.filters.FilterPositionUtil;
|
||||
import com.intellij.psi.javadoc.PsiDocTag;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.containers.hash.HashSet;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -91,8 +88,9 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE
|
||||
}
|
||||
|
||||
PsiTypeLookupItem.addImportForItem(context, psiClass);
|
||||
context.setTailOffset(context.getOffset(refEnd));
|
||||
|
||||
if (shouldInsertParentheses(psiClass, file.findElementAt(context.getTailOffset() - 1))) {
|
||||
if (shouldInsertParentheses(file.findElementAt(context.getTailOffset() - 1))) {
|
||||
if (ConstructorInsertHandler.insertParentheses(context, item, psiClass, false)) {
|
||||
fillTypeArgs |= psiClass.hasTypeParameters() && PsiUtil.getLanguageLevel(file).isAtLeast(LanguageLevel.JDK_1_5);
|
||||
}
|
||||
@@ -122,7 +120,7 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean shouldInsertParentheses(PsiClass psiClass, PsiElement position) {
|
||||
private static boolean shouldInsertParentheses(PsiElement position) {
|
||||
final PsiJavaCodeReferenceElement ref = PsiTreeUtil.getParentOfType(position, PsiJavaCodeReferenceElement.class);
|
||||
if (ref == null) {
|
||||
return false;
|
||||
@@ -135,13 +133,13 @@ class JavaClassNameInsertHandler implements InsertHandler<JavaPsiClassReferenceE
|
||||
|
||||
final PsiElement prevElement = FilterPositionUtil.searchNonSpaceNonCommentBack(ref);
|
||||
if (prevElement != null && prevElement.getParent() instanceof PsiNewExpression) {
|
||||
|
||||
Set<PsiType> expectedTypes = new HashSet<PsiType>();
|
||||
for (ExpectedTypeInfo info : ExpectedTypesProvider.getExpectedTypes((PsiExpression)prevElement.getParent(), true)) {
|
||||
expectedTypes.add(info.getType());
|
||||
if (info.getType() instanceof PsiArrayType) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return JavaCompletionUtil.isDefinitelyExpected(psiClass, expectedTypes, position);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
+12
-3
@@ -31,6 +31,7 @@ import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
@@ -282,12 +283,14 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
final Set<String> usedWords = new HashSet<String>();
|
||||
final PsiElement position = parameters.getPosition();
|
||||
final boolean checkAccess = parameters.getInvocationCount() <= 1;
|
||||
final boolean isSwitchLabel = SWITCH_LABEL.accepts(position);
|
||||
final boolean isAfterNew = JavaClassNameCompletionContributor.AFTER_NEW.accepts(position);
|
||||
final boolean pkgContext = JavaCompletionUtil.inSomePackage(position);
|
||||
LegacyCompletionContributor.processReferences(parameters, result, new PairConsumer<PsiReference, CompletionResultSet>() {
|
||||
public void consume(final PsiReference reference, final CompletionResultSet result) {
|
||||
if (reference instanceof PsiJavaReference) {
|
||||
final ElementFilter filter = getReferenceFilter(position);
|
||||
if (filter != null) {
|
||||
final boolean isSwitchLabel = SWITCH_LABEL.accepts(position);
|
||||
final PsiFile originalFile = parameters.getOriginalFile();
|
||||
for (LookupElement element : JavaCompletionUtil.processJavaReference(position,
|
||||
(PsiJavaReference)reference,
|
||||
@@ -332,11 +335,17 @@ public class JavaCompletionContributor extends CompletionContributor {
|
||||
result.addElement((LookupElement)completion);
|
||||
}
|
||||
else if (completion instanceof PsiClass) {
|
||||
if (!inheritors.alreadyProcessed((PsiClass)completion)) {
|
||||
JavaPsiClassReferenceElement item = JavaClassNameCompletionContributor.createClassLookupItem((PsiClass)completion, true);
|
||||
for (JavaPsiClassReferenceElement item : JavaClassNameCompletionContributor.createClassLookupItems((PsiClass)completion, isAfterNew,
|
||||
JavaClassNameInsertHandler.JAVA_CLASS_INSERT_HANDLER, new Condition<PsiClass>() {
|
||||
@Override
|
||||
public boolean value(PsiClass psiClass) {
|
||||
return !inheritors.alreadyProcessed(psiClass) && JavaCompletionUtil.isSourceLevelAccessible(position, psiClass, pkgContext);
|
||||
}
|
||||
})) {
|
||||
usedWords.add(item.getLookupString());
|
||||
result.addElement(item);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
LookupElement element = LookupItemUtil.objectToLookupItem(completion);
|
||||
|
||||
@@ -69,10 +69,7 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
|
||||
@@ -450,8 +447,7 @@ public class JavaCompletionUtil {
|
||||
|
||||
final Set<PsiMember> mentioned = new THashSet<PsiMember>();
|
||||
for (CompletionElement completionElement : processor.getResults()) {
|
||||
LookupElement item = createLookupElement(completionElement, javaReference);
|
||||
if (item != null) {
|
||||
for (LookupElement item : createLookupElements(completionElement, javaReference)) {
|
||||
item.putUserData(QUALIFIER_TYPE_ATTR, qualifierType);
|
||||
final Object o = item.getObject();
|
||||
if (o instanceof PsiClass && !isSourceLevelAccessible(element, (PsiClass)o, pkgContext)) {
|
||||
@@ -604,25 +600,33 @@ public class JavaCompletionUtil {
|
||||
}), 1);
|
||||
}
|
||||
|
||||
private static LookupElement createLookupElement(CompletionElement completionElement, PsiJavaReference reference) {
|
||||
private static List<? extends LookupElement> createLookupElements(CompletionElement completionElement, PsiJavaReference reference) {
|
||||
Object completion = completionElement.getElement();
|
||||
assert !(completion instanceof LookupElement);
|
||||
|
||||
if (completion instanceof PsiMethod &&
|
||||
reference instanceof PsiJavaCodeReferenceElement &&
|
||||
((PsiJavaCodeReferenceElement)reference).getParent() instanceof PsiImportStaticStatement) {
|
||||
return JavaLookupElementBuilder.forMethod((PsiMethod)completion, PsiSubstitutor.EMPTY);
|
||||
if (reference instanceof PsiJavaCodeReferenceElement) {
|
||||
if (completion instanceof PsiMethod &&
|
||||
((PsiJavaCodeReferenceElement)reference).getParent() instanceof PsiImportStaticStatement) {
|
||||
return Arrays.asList(JavaLookupElementBuilder.forMethod((PsiMethod)completion, PsiSubstitutor.EMPTY));
|
||||
}
|
||||
|
||||
if (completion instanceof PsiClass) {
|
||||
return JavaClassNameCompletionContributor.createClassLookupItems((PsiClass)completion,
|
||||
JavaClassNameCompletionContributor.AFTER_NEW.accepts(reference),
|
||||
JavaClassNameInsertHandler.JAVA_CLASS_INSERT_HANDLER,
|
||||
Condition.TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
LookupElement _ret = LookupItemUtil.objectToLookupItem(completion);
|
||||
if (_ret == null || !(_ret instanceof LookupItem)) return null;
|
||||
if (_ret == null || !(_ret instanceof LookupItem)) return Collections.emptyList();
|
||||
|
||||
final PsiSubstitutor substitutor = completionElement.getSubstitutor();
|
||||
if (substitutor != null) {
|
||||
((LookupItem<?>)_ret).setAttribute(LookupItem.SUBSTITUTOR, substitutor);
|
||||
}
|
||||
|
||||
return _ret;
|
||||
return Arrays.asList(_ret);
|
||||
}
|
||||
|
||||
public static boolean hasAccessibleConstructor(PsiType type) {
|
||||
@@ -878,19 +882,6 @@ public class JavaCompletionUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasAccessibleInnerClass(@NotNull PsiClass psiClass, @NotNull PsiElement position) {
|
||||
final PsiClass[] inners = psiClass.getInnerClasses();
|
||||
if (inners.length > 0) {
|
||||
PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(position.getProject()).getResolveHelper();
|
||||
for (PsiClass inner : inners) {
|
||||
if (inner.hasModifierProperty(PsiModifier.STATIC) && resolveHelper.isAccessible(inner, position, null)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean inSomePackage(PsiElement context) {
|
||||
PsiFile contextFile = context.getContainingFile();
|
||||
return contextFile instanceof PsiClassOwner && StringUtil.isNotEmpty(((PsiClassOwner)contextFile).getPackageName());
|
||||
@@ -914,19 +905,6 @@ public class JavaCompletionUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isDefinitelyExpected(PsiClass psiClass, Set<PsiType> expectedTypes, PsiElement position) {
|
||||
final PsiClassType classType = JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass);
|
||||
for (PsiType expectedType : expectedTypes) {
|
||||
if (expectedType instanceof PsiArrayType) return false;
|
||||
}
|
||||
for (PsiType type : expectedTypes) {
|
||||
if (type instanceof PsiClassType && ((PsiClassType)type).rawType().isAssignableFrom(classType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return !hasAccessibleInnerClass(psiClass, position);
|
||||
}
|
||||
|
||||
public static boolean promptTypeArgs(InsertionContext context, int offset) {
|
||||
if (offset < 0) {
|
||||
return false;
|
||||
|
||||
+37
@@ -31,6 +31,9 @@ import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
@@ -38,6 +41,7 @@ public class JavaPsiClassReferenceElement extends LookupItem<Object> {
|
||||
public static final ClassConditionKey<JavaPsiClassReferenceElement> CLASS_CONDITION_KEY = ClassConditionKey.create(JavaPsiClassReferenceElement.class);
|
||||
private final Object myClass;
|
||||
private final String myQualifiedName;
|
||||
private String myForcedPresentableName;
|
||||
|
||||
public JavaPsiClassReferenceElement(PsiClass psiClass) {
|
||||
super(psiClass.getName(), psiClass.getName());
|
||||
@@ -48,6 +52,32 @@ public class JavaPsiClassReferenceElement extends LookupItem<Object> {
|
||||
setTailType(TailType.NONE);
|
||||
}
|
||||
|
||||
public String getForcedPresentableName() {
|
||||
return myForcedPresentableName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getLookupString() {
|
||||
if (myForcedPresentableName != null) {
|
||||
return myForcedPresentableName;
|
||||
}
|
||||
return super.getLookupString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAllLookupStrings() {
|
||||
if (myForcedPresentableName != null) {
|
||||
return Collections.singleton(myForcedPresentableName);
|
||||
}
|
||||
|
||||
return super.getAllLookupStrings();
|
||||
}
|
||||
|
||||
public void setForcedPresentableName(String forcedPresentableName) {
|
||||
myForcedPresentableName = forcedPresentableName;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClass getObject() {
|
||||
@@ -126,6 +156,13 @@ public class JavaPsiClassReferenceElement extends LookupItem<Object> {
|
||||
}
|
||||
|
||||
private static String getName(final PsiClass psiClass, final LookupItem<?> item, boolean diamond) {
|
||||
if (item instanceof JavaPsiClassReferenceElement) {
|
||||
String forced = ((JavaPsiClassReferenceElement)item).getForcedPresentableName();
|
||||
if (forced != null) {
|
||||
return forced;
|
||||
}
|
||||
}
|
||||
|
||||
String name = PsiUtilCore.getName(psiClass);
|
||||
|
||||
if (item.getAttribute(LookupItem.FORCE_QUALIFY) != null) {
|
||||
|
||||
Reference in New Issue
Block a user