Skip to content

Commit 6970f5a

Browse files
committed
Filter visibility on search match (do not open type to get modifiers)
1 parent 517b392 commit 6970f5a

File tree

1 file changed

+57
-78
lines changed

1 file changed

+57
-78
lines changed

org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/codeassist/DOMCompletionEngine.java

Lines changed: 57 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@
9696
import org.eclipse.jdt.core.dom.IfStatement;
9797
import org.eclipse.jdt.core.dom.ImportDeclaration;
9898
import org.eclipse.jdt.core.dom.InfixExpression;
99-
import org.eclipse.jdt.core.dom.InfixExpression.Operator;
10099
import org.eclipse.jdt.core.dom.Initializer;
101100
import org.eclipse.jdt.core.dom.InstanceofExpression;
102101
import org.eclipse.jdt.core.dom.Javadoc;
@@ -108,7 +107,6 @@
108107
import org.eclipse.jdt.core.dom.MethodInvocation;
109108
import org.eclipse.jdt.core.dom.MethodRef;
110109
import org.eclipse.jdt.core.dom.Modifier;
111-
import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
112110
import org.eclipse.jdt.core.dom.ModuleDeclaration;
113111
import org.eclipse.jdt.core.dom.Name;
114112
import org.eclipse.jdt.core.dom.NodeFinder;
@@ -149,6 +147,8 @@
149147
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
150148
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
151149
import org.eclipse.jdt.core.dom.WhileStatement;
150+
import org.eclipse.jdt.core.dom.InfixExpression.Operator;
151+
import org.eclipse.jdt.core.dom.Modifier.ModifierKeyword;
152152
import org.eclipse.jdt.core.formatter.DefaultCodeFormatterConstants;
153153
import org.eclipse.jdt.core.search.IJavaSearchConstants;
154154
import org.eclipse.jdt.core.search.IJavaSearchScope;
@@ -812,24 +812,19 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
812812
suggestTypeKeywords(true);
813813
suggestModifierKeywords(bodyDeclaration.getModifiers());
814814
if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
815-
findTypes(this.prefix, IJavaSearchConstants.TYPE, null)
815+
findTypes(this.prefix, null)
816816
// don't care about annotations
817817
.filter(type -> {
818818
try {
819819
return !type.isAnnotation();
820820
} catch (JavaModelException e) {
821821
return true;
822822
}
823-
})
824-
.filter(type -> {
825-
return defaultCompletionBindings.all().map(typeBinding -> typeBinding.getJavaElement()).noneMatch(elt -> type.equals(elt));
826-
})
827-
.filter(type -> this.pattern.matchesName(this.prefix.toCharArray(),
828-
type.getElementName().toCharArray()))
829-
.filter(type -> {
830-
return filterBasedOnExtendsOrImplementsInfo(type, this.extendsOrImplementsInfo);
831-
})
832-
.map(this::toProposal).forEach(this.requestor::accept);
823+
}).filter(type -> defaultCompletionBindings.all().map(typeBinding -> typeBinding.getJavaElement()).noneMatch(elt -> type.equals(elt)))
824+
.filter(type -> this.pattern.matchesName(this.prefix.toCharArray(), type.getElementName().toCharArray()))
825+
.filter(type -> filterBasedOnExtendsOrImplementsInfo(type, this.extendsOrImplementsInfo))
826+
.map(this::toProposal)
827+
.forEach(this.requestor::accept);
833828
}
834829
if (!this.requestor.isIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION) && !typeDeclBinding.isAnnotation()) {
835830
int cursorStart = this.offset - this.prefix.length() - 1;
@@ -1395,7 +1390,7 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
13951390
if (packageDecl != null) {
13961391
packageName = packageDecl.getName().toString();
13971392
}
1398-
this.findTypes(this.prefix, IJavaSearchConstants.TYPE, packageName)
1393+
this.findTypes(this.prefix, packageName)
13991394
.filter(type -> {
14001395
try {
14011396
return !type.isAnnotation();
@@ -1537,7 +1532,7 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
15371532
packageName = ""; //$NON-NLS-1$
15381533
}
15391534
}
1540-
List<IType> potentialTypes = findTypes(classToComplete, IJavaSearchConstants.TYPE, packageName).toList();
1535+
List<IType> potentialTypes = findTypes(classToComplete, packageName).toList();
15411536
List<IType> sourceTypes = potentialTypes.stream().filter(type -> type instanceof SourceType).toList();
15421537
if (!potentialTypes.isEmpty()) {
15431538
IType typeToComplete;
@@ -1586,7 +1581,7 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
15861581
.filter(type -> (this.qualifiedPrefix.equals(this.prefix) || this.qualifiedPrefix.equals(finalizedCurrentPackage)) && this.pattern.matchesName(this.prefix.toCharArray(), type.getName().toCharArray()))
15871582
.map(this::toProposal).forEach(this.requestor::accept);
15881583

1589-
findTypes(completeAfter, IJavaSearchConstants.TYPE, completeAfter.equals(this.qualifiedPrefix) ? null : this.qualifiedPrefix)
1584+
findTypes(completeAfter, completeAfter.equals(this.qualifiedPrefix) ? null : this.qualifiedPrefix)
15901585
.filter(type -> {
15911586
return localTypeBindings.all().map(typeBinding -> typeBinding.getJavaElement()).noneMatch(elt -> type.equals(elt));
15921587
})
@@ -1713,7 +1708,7 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
17131708
packageName = ""; //$NON-NLS-1$
17141709
}
17151710
}
1716-
List<IType> potentialTypes = findTypes(classToComplete, IJavaSearchConstants.TYPE, packageName).toList();
1711+
List<IType> potentialTypes = findTypes(classToComplete, packageName).toList();
17171712
List<IType> sourceTypes = potentialTypes.stream().filter(type -> type instanceof SourceType).toList();
17181713
if (!potentialTypes.isEmpty()) {
17191714
IType typeToComplete;
@@ -1865,10 +1860,9 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
18651860
String currentPackage = this.unit.getPackage() == null ? "" : this.unit.getPackage().getName().toString();
18661861
AbstractTypeDeclaration typeDecl = DOMCompletionUtil.findParentTypeDeclaration(context);
18671862
ITypeBinding currentTypeBinding = typeDecl == null ? null : typeDecl.resolveBinding();
1868-
findTypes(completeAfter, IJavaSearchConstants.TYPE, null)
1863+
findTypes(completeAfter, null)
18691864
.filter(type -> this.pattern.matchesName(this.prefix.toCharArray(),
18701865
type.getElementName().toCharArray()))
1871-
.filter(type -> filterTypeBasedOnAccess(type, currentPackage, currentTypeBinding))
18721866
.filter(type -> {
18731867
for (var scrapedBinding : catchExceptionBindings.all().toList()) {
18741868
if (scrapedBinding instanceof ITypeBinding scrapedTypeBinding) {
@@ -2068,10 +2062,8 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
20682062
: IJavaSearchConstants.TYPE;
20692063
if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
20702064
final Set<String> alreadySuggestedFqn = ConcurrentHashMap.newKeySet();
2071-
findTypes(completeAfter, typeMatchRule, null)
2072-
.filter(type -> this.pattern.matchesName(this.prefix.toCharArray(),
2073-
type.getElementName().toCharArray()))
2074-
.filter(type -> filterTypeBasedOnAccess(type, currentPackage, currentTypeBinding))
2065+
findTypes(completeAfter, -1, typeMatchRule, null)
2066+
.filter(type -> this.pattern.matchesName(this.prefix.toCharArray(), type.getElementName().toCharArray()))
20752067
.filter(type -> {
20762068
for (var scrapedBinding : defaultCompletionBindings.all().toList()) {
20772069
if (scrapedBinding instanceof ITypeBinding scrapedTypeBinding) {
@@ -2081,18 +2073,15 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
20812073
}
20822074
}
20832075
return true;
2084-
})
2085-
.filter(type -> {
2086-
return filterBasedOnExtendsOrImplementsInfo(type, this.extendsOrImplementsInfo);
2087-
})
2076+
}).filter(type -> filterBasedOnExtendsOrImplementsInfo(type, this.extendsOrImplementsInfo))
20882077
.filter(type -> {
20892078
if (alreadySuggestedFqn.contains(type.getFullyQualifiedName())) {
20902079
return false;
20912080
}
20922081
alreadySuggestedFqn.add(type.getFullyQualifiedName());
20932082
return true;
2094-
})
2095-
.map(this::toProposal).forEach(this.requestor::accept);
2083+
}).map(this::toProposal)
2084+
.forEach(this.requestor::accept);
20962085
}
20972086
}
20982087
checkCancelled();
@@ -2698,42 +2687,6 @@ private void suggestSuperConstructors() {
26982687
}
26992688
}
27002689

2701-
/**
2702-
* Returns true if the given type can be accessed from the given context
2703-
*
2704-
* @param type the type that you're trying to access
2705-
* @param currentPackage the package that you're in
2706-
* @param currentTypeBinding the binding of the type that you're currently in, can be null
2707-
* @return true if the given type can be accessed from the given context
2708-
*/
2709-
private boolean filterTypeBasedOnAccess(IType type, String currentPackage, ITypeBinding currentTypeBinding) {
2710-
String typePackage = type.getAncestor(IJavaElement.PACKAGE_FRAGMENT).getElementName();
2711-
// can only access classes in the default package from the default package
2712-
if (!currentPackage.isEmpty() && typePackage.isEmpty()) {
2713-
return false;
2714-
}
2715-
try {
2716-
int flags = type.getFlags();
2717-
if ((flags & (Flags.AccPublic | Flags.AccPrivate | Flags.AccProtected)) == 0) {
2718-
return currentPackage.equals(typePackage);
2719-
}
2720-
if ((flags & Flags.AccPublic) != 0) {
2721-
return true;
2722-
}
2723-
if ((flags & Flags.AccProtected) != 0) {
2724-
// if `protected` is used correctly means `type` is an inner class
2725-
if (currentTypeBinding == null || type.getDeclaringType() == null) {
2726-
return false;
2727-
}
2728-
return DOMCompletionUtil.findInSupers(currentTypeBinding, type.getDeclaringType().getKey());
2729-
}
2730-
// private inner class
2731-
return false;
2732-
} catch (JavaModelException e) {
2733-
return true;
2734-
}
2735-
}
2736-
27372690
private boolean isParameterInNonParameterizedType(ASTNode context) {
27382691
if (context instanceof ParameterizedType) {
27392692
return true;
@@ -2925,13 +2878,13 @@ private void scrapeAccessibleBindings(Bindings scope) {
29252878
favouriteReference = favouriteReference.substring(0, favouriteReference.length() - 2);
29262879
String packageName = favouriteReference.indexOf('.') < 0 ? "" : favouriteReference.substring(0, favouriteReference.lastIndexOf('.')); //$NON-NLS-1$
29272880
String typeName = favouriteReference.indexOf('.') < 0 ? favouriteReference : favouriteReference.substring(favouriteReference.lastIndexOf('.') + 1);
2928-
findTypes(typeName, SearchPattern.R_EXACT_MATCH, packageName).filter(type -> type.getElementName().equals(typeName)).forEach(keysToResolve::add);
2881+
findTypes(typeName, SearchPattern.R_EXACT_MATCH, IJavaSearchConstants.TYPE, packageName).filter(type -> type.getElementName().equals(typeName)).forEach(keysToResolve::add);
29292882
} else if (favouriteReference.lastIndexOf('.') >= 0) {
29302883
String memberName = favouriteReference.substring(favouriteReference.lastIndexOf('.') + 1);
29312884
String typeFqn = favouriteReference.substring(0, favouriteReference.lastIndexOf('.'));
29322885
String packageName = typeFqn.indexOf('.') < 0 ? "" : typeFqn.substring(0, typeFqn.lastIndexOf('.')); //$NON-NLS-1$
29332886
String typeName = typeFqn.indexOf('.') < 0 ? typeFqn : typeFqn.substring(typeFqn.lastIndexOf('.') + 1);
2934-
findTypes(typeName, SearchPattern.R_EXACT_MATCH, packageName).filter(type -> type.getElementName().equals(typeName)).findFirst().ifPresent(type -> {
2887+
findTypes(typeName, SearchPattern.R_EXACT_MATCH, IJavaSearchConstants.TYPE, packageName).filter(type -> type.getElementName().equals(typeName)).findFirst().ifPresent(type -> {
29352888
try {
29362889
for (IMethod method : type.getMethods()) {
29372890
if (method.exists() && (method.getFlags() & Flags.AccStatic) != 0 && memberName.equals(method.getElementName())) {
@@ -3220,12 +3173,10 @@ private void suggestPackages(ASTNode context) {
32203173
private void suggestTypesInPackage(String packageName) {
32213174
if (!this.requestor.isIgnored(CompletionProposal.TYPE_REF)) {
32223175
List<IType> foundTypes = findTypes(this.prefix, packageName).toList();
3223-
String currentPackage = this.unit.getPackage() == null ? "" : this.unit.getPackage().getName().toString();
32243176
AbstractTypeDeclaration typeDecl = DOMCompletionUtil.findParentTypeDeclaration(this.toComplete);
3225-
ITypeBinding currentTypeBinding = typeDecl == null ? null : typeDecl.resolveBinding();
32263177
for (IType foundType : foundTypes) {
32273178
if (this.pattern.matchesName(this.prefix.toCharArray(), foundType.getElementName().toCharArray())) {
3228-
if (filterBasedOnExtendsOrImplementsInfo(foundType, this.extendsOrImplementsInfo) && filterTypeBasedOnAccess(foundType, currentPackage, currentTypeBinding)) {
3179+
if (filterBasedOnExtendsOrImplementsInfo(foundType, this.extendsOrImplementsInfo)) {
32293180
this.requestor.accept(this.toProposal(foundType));
32303181
}
32313182
}
@@ -3379,7 +3330,7 @@ private static boolean extendsOrImplementsGivenType(TypeDeclaration typeDecl, IT
33793330
}
33803331

33813332
private void completeMarkerAnnotation(String completeAfter) {
3382-
findTypes(completeAfter, IJavaSearchConstants.ANNOTATION_TYPE, null)
3333+
findTypes(completeAfter, -1, IJavaSearchConstants.ANNOTATION_TYPE, null)
33833334
.filter(type -> this.pattern.matchesName(this.prefix.toCharArray(),
33843335
type.getElementName().toCharArray()))
33853336
.map(this::toProposal).forEach(this.requestor::accept);
@@ -3566,10 +3517,10 @@ private void findOverridableMethods0(ITypeBinding currentType, ITypeBinding type
35663517
}
35673518

35683519
private Stream<IType> findTypes(String namePrefix, String packageName) {
3569-
return findTypes(namePrefix, IJavaSearchConstants.TYPE, packageName);
3520+
return findTypes(namePrefix, -1, IJavaSearchConstants.TYPE, packageName);
35703521
}
35713522

3572-
private Stream<IType> findTypes(String namePrefix, int typeMatchRule, String packageName) {
3523+
private Stream<IType> findTypes(String namePrefix, int typeMatchRule, int searchFor, String packageName) {
35733524
if (namePrefix == null) {
35743525
namePrefix = ""; //$NON-NLS-1$
35753526
}
@@ -3578,18 +3529,38 @@ private Stream<IType> findTypes(String namePrefix, int typeMatchRule, String pac
35783529
TypeNameMatchRequestor typeRequestor = new TypeNameMatchRequestor() {
35793530
@Override
35803531
public void acceptTypeNameMatch(org.eclipse.jdt.core.search.TypeNameMatch match) {
3581-
types.add(match.getType());
3532+
if (isVisible(match)) {
3533+
types.add(match.getType());
3534+
}
3535+
}
3536+
private boolean isVisible(TypeNameMatch match) {
3537+
if (match.getPackageName().isEmpty() && !currentTypeBinding().getPackage().getName().isEmpty()) {
3538+
// can only access classes in the default package from the default package
3539+
return false;
3540+
}
3541+
if (Flags.isPublic(match.getModifiers())) {
3542+
return true;
3543+
}
3544+
if (Flags.isPrivate(match.getModifiers())) {
3545+
return modelUnit.equals(match.getType().getTypeRoot());
3546+
}
3547+
if (Flags.isProtected(match.getModifiers())) {
3548+
IType nestingType = match.getType().getDeclaringType();
3549+
return nestingType != null && DOMCompletionUtil.findInSupers(currentTypeBinding(), nestingType.getKey());
3550+
}
3551+
return match.getPackageName().equals(modelUnit.getAncestor(IJavaElement.PACKAGE_FRAGMENT).getElementName());
35823552
}
35833553
};
35843554
try {
35853555
new SearchEngine(this.modelUnit instanceof ICompilationUnit modelCU ? modelCU.getOwner() : this.workingCopyOwner).searchAllTypeNames(
35863556
packageName == null ? null : packageName.toCharArray(), SearchPattern.R_EXACT_MATCH,
35873557
namePrefix.toCharArray(),
3588-
SearchPattern.R_PREFIX_MATCH
3558+
typeMatchRule >= 0 ? typeMatchRule :
3559+
SearchPattern.R_PREFIX_MATCH
35893560
| (this.assistOptions.substringMatch ? SearchPattern.R_SUBSTRING_MATCH : 0)
35903561
| (this.assistOptions.subwordMatch ? SearchPattern.R_SUBWORD_MATCH : 0)
35913562
| (this.assistOptions.camelCaseMatch ? SearchPattern.R_CAMELCASE_MATCH : 0),
3592-
typeMatchRule, searchScope, typeRequestor, IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, null);
3563+
searchFor, searchScope, typeRequestor, IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, null);
35933564
// TODO also resolve potential sub-packages
35943565
} catch (JavaModelException ex) {
35953566
ILog.get().error(ex.getMessage(), ex);
@@ -4201,12 +4172,11 @@ private CompletionProposal toProposal(IType type) {
42014172
inSamePackage = type.getPackageFragment().getElementName().isEmpty();
42024173
}
42034174
boolean inCatchClause = DOMCompletionUtil.findParent(this.toComplete, new int[] { ASTNode.CATCH_CLAUSE }) != null;
4204-
boolean subclassesException = DOMCompletionUtil.findInSupers(type, "Ljava/lang/Exception;", this.workingCopyOwner, this.typeHierarchyCache);
42054175
int relevance = RelevanceConstants.R_DEFAULT
42064176
+ RelevanceConstants.R_RESOLVED
42074177
+ RelevanceUtils.computeRelevanceForInteresting(type, expectedTypes)
42084178
+ RelevanceConstants.R_NON_RESTRICTED
4209-
+ (inCatchClause && subclassesException ? RelevanceConstants.R_EXCEPTION : 0)
4179+
+ (inCatchClause && DOMCompletionUtil.findInSupers(type, "Ljava/lang/Exception;", this.workingCopyOwner, this.typeHierarchyCache) ? RelevanceConstants.R_EXCEPTION : 0)
42104180
+ RelevanceUtils.computeRelevanceForInheritance(this.qualifyingType, type)
42114181
+ RelevanceUtils.computeRelevanceForQualification(!type.getFullyQualifiedName().startsWith("java.") && !nodeInImports && !fromCurrentCU && !inSamePackage && !typeIsImported, this.prefix, this.qualifiedPrefix)
42124182
+ (type.getFullyQualifiedName().startsWith("java.") ? RelevanceConstants.R_JAVA_LIBRARY : 0)
@@ -5195,4 +5165,13 @@ private ITypeBinding getDeclaringClass(IBinding binding) {
51955165
binding instanceof IVariableBinding variableBinding && variableBinding.isField() ? variableBinding.getDeclaringClass() :
51965166
null;
51975167
}
5168+
5169+
private ITypeBinding _currentTypeBinding;
5170+
private ITypeBinding currentTypeBinding() {
5171+
if (_currentTypeBinding == null) {
5172+
_currentTypeBinding = DOMCompletionUtil.findParentTypeDeclaration(this.toComplete).resolveBinding();
5173+
}
5174+
return _currentTypeBinding;
5175+
}
5176+
51985177
}

0 commit comments

Comments
 (0)