9999import org .eclipse .jdt .core .dom .NormalAnnotation ;
100100import org .eclipse .jdt .core .dom .NumberLiteral ;
101101import org .eclipse .jdt .core .dom .PackageDeclaration ;
102+ import org .eclipse .jdt .core .dom .ParameterizedType ;
102103import org .eclipse .jdt .core .dom .PrefixExpression ;
103104import org .eclipse .jdt .core .dom .PrimitiveType ;
104105import org .eclipse .jdt .core .dom .QualifiedName ;
@@ -858,7 +859,10 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
858859 }
859860 if (context instanceof QualifiedName qualifiedName ) {
860861 ImportDeclaration importDecl = (ImportDeclaration )DOMCompletionUtil .findParent (context , new int [] { ASTNode .IMPORT_DECLARATION });
861- if (importDecl != null ) {
862+ if (isParameterInNonParameterizedType (context )) {
863+ // do not complete
864+ suggestDefaultCompletions = false ;
865+ } else if (importDecl != null ) {
862866 if (importDecl .getAST ().apiLevel () >= AST .JLS23
863867 && this .javaProject .getOption (JavaCore .COMPILER_PB_ENABLE_PREVIEW_FEATURES , true ).equals (JavaCore .ENABLED )
864868 && importDecl .modifiers ().stream ().anyMatch (node -> node instanceof Modifier modifier && modifier .getKeyword () == ModifierKeyword .MODULE_KEYWORD )) {
@@ -1405,6 +1409,9 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
14051409 }
14061410 }
14071411 }
1412+ if (isParameterInNonParameterizedType (context )) {
1413+ suggestDefaultCompletions = false ;
1414+ }
14081415
14091416 // check for accessible bindings to potentially turn into completions.
14101417 // currently, this is always run, even when not using the default completion,
@@ -1438,14 +1445,24 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
14381445 }
14391446 publishFromScope (defaultCompletionBindings );
14401447 if (!completeAfter .isBlank ()) {
1448+ String currentPackage = this .unit .getPackage () == null ? "" : this .unit .getPackage ().getName ().toString ();
1449+ AbstractTypeDeclaration typeDecl = DOMCompletionUtil .findParentTypeDeclaration (context );
1450+ ITypeBinding currentTypeBinding = typeDecl == null ? null : typeDecl .resolveBinding ();
14411451 final int typeMatchRule = this .toComplete .getParent () instanceof Annotation
14421452 ? IJavaSearchConstants .ANNOTATION_TYPE
14431453 : IJavaSearchConstants .TYPE ;
1444- if (!this .requestor .isIgnored (CompletionProposal .TYPE_REF )
1445- && (completionContext .getExpectedTypesSignatures () != null || extendsOrImplementsInfo != null )) {
1454+ if (!this .requestor .isIgnored (CompletionProposal .TYPE_REF )) {
14461455 findTypes (completeAfter , typeMatchRule , null )
1456+ .filter (type -> filterTypeBasedOnAccess (type , currentPackage , currentTypeBinding ))
14471457 .filter (type -> {
1448- return defaultCompletionBindings .all ().map (typeBinding -> typeBinding .getJavaElement ()).noneMatch (elt -> type .equals (elt ));
1458+ for (var scrapedBinding : defaultCompletionBindings .all ().toList ()) {
1459+ if (scrapedBinding instanceof ITypeBinding scrapedTypeBinding ) {
1460+ if (type .equals (scrapedTypeBinding .getJavaElement ()) || type .getKey ().equals (scrapedTypeBinding .getKey ())) {
1461+ return false ;
1462+ }
1463+ }
1464+ }
1465+ return true ;
14491466 })
14501467 .filter (type -> this .pattern .matchesName (this .prefix .toCharArray (),
14511468 type .getElementName ().toCharArray ()))
@@ -1470,6 +1487,58 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
14701487 }
14711488 }
14721489
1490+ /**
1491+ * Returns true if the given type can be accessed from the given context
1492+ *
1493+ * @param type the type that you're trying to access
1494+ * @param currentPackage the package that you're in
1495+ * @param currentTypeBinding the binding of the type that you're currently in, can be null
1496+ * @return true if the given type can be accessed from the given context
1497+ */
1498+ private boolean filterTypeBasedOnAccess (IType type , String currentPackage , ITypeBinding currentTypeBinding ) {
1499+ String typePackage = type .getAncestor (IJavaElement .PACKAGE_FRAGMENT ).getElementName ();
1500+ // can only access classes in the default package from the default package
1501+ if (!currentPackage .isEmpty () && typePackage .isEmpty ()) {
1502+ return false ;
1503+ }
1504+ try {
1505+ int flags = type .getFlags ();
1506+ if ((flags & (Flags .AccPublic | Flags .AccPrivate | Flags .AccProtected )) == 0 ) {
1507+ return currentPackage .equals (typePackage );
1508+ }
1509+ if ((flags & Flags .AccPublic ) != 0 ) {
1510+ return true ;
1511+ }
1512+ if ((flags & Flags .AccProtected ) != 0 ) {
1513+ // protected means `type` is an inner class
1514+ if (currentTypeBinding == null ) {
1515+ return false ;
1516+ }
1517+ return findInSupers (currentTypeBinding , ((IType )type .getParent ()).getKey ());
1518+ }
1519+ // private inner class
1520+ return false ;
1521+ } catch (JavaModelException e ) {
1522+ return true ;
1523+ }
1524+ }
1525+
1526+ private boolean isParameterInNonParameterizedType (ASTNode context ) {
1527+ if (DOMCompletionUtil .findParent (context , new int [] { ASTNode .PARAMETERIZED_TYPE }) != null ) {
1528+ ASTNode cursor1 = context ;
1529+ ASTNode cursor2 = context .getParent ();
1530+ while (!(cursor2 instanceof ParameterizedType paramType )) {
1531+ cursor1 = cursor2 ;
1532+ cursor2 = cursor2 .getParent ();
1533+ }
1534+ ITypeBinding paramTypeBinding = paramType .resolveBinding ().getTypeDeclaration ();
1535+ if (paramTypeBinding .getTypeParameters ().length <= paramType .typeArguments ().indexOf (cursor1 )) {
1536+ return true ;
1537+ }
1538+ }
1539+ return false ;
1540+ }
1541+
14731542 private void suggestAccessibleConstructorsForType (ITypeBinding typeBinding ) {
14741543 ITypeBinding parentTypeBinding = DOMCompletionUtil .findParentTypeDeclaration (this .toComplete ).resolveBinding ();
14751544 Stream .of (typeBinding .getDeclaredMethods ()) //
@@ -1825,9 +1894,12 @@ private void suggestTypesInPackage(String packageName) {
18251894 if (!this .requestor .isIgnored (CompletionProposal .TYPE_REF )) {
18261895 List <IType > foundTypes = findTypes (this .prefix , packageName ).toList ();
18271896 ExtendsOrImplementsInfo extendsOrImplementsInfo = isInExtendsOrImplements (this .toComplete );
1897+ String currentPackage = this .unit .getPackage () == null ? "" : this .unit .getPackage ().getName ().toString ();
1898+ AbstractTypeDeclaration typeDecl = DOMCompletionUtil .findParentTypeDeclaration (this .toComplete );
1899+ ITypeBinding currentTypeBinding = typeDecl == null ? null : typeDecl .resolveBinding ();
18281900 for (IType foundType : foundTypes ) {
18291901 if (this .pattern .matchesName (this .prefix .toCharArray (), foundType .getElementName ().toCharArray ())) {
1830- if (filterBasedOnExtendsOrImplementsInfo (foundType , extendsOrImplementsInfo )) {
1902+ if (filterBasedOnExtendsOrImplementsInfo (foundType , extendsOrImplementsInfo ) && filterTypeBasedOnAccess ( foundType , currentPackage , currentTypeBinding ) ) {
18311903 this .requestor .accept (this .toProposal (foundType ));
18321904 }
18331905 }
0 commit comments