Skip to content

Commit a0e1871

Browse files
authored
Check for forbidden classes when adding static import favorites (#2923)
* Check for forbidden classes when adding static import favorite quick-fix - modify UnresolvedElementsBaseSubProcessor.addStaticImportFavoriteProposals() to check if the favorite class is forbidden in the class path - for #2893
1 parent 7c9a92e commit a0e1871

2 files changed

Lines changed: 140 additions & 0 deletions

File tree

org.eclipse.jdt.core.manipulation/common/org/eclipse/jdt/internal/ui/text/correction/UnresolvedElementsBaseSubProcessor.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
import org.eclipse.core.runtime.CoreException;
3434
import org.eclipse.core.runtime.FileLocator;
35+
import org.eclipse.core.runtime.IPath;
3536
import org.eclipse.core.runtime.IProgressMonitor;
3637
import org.eclipse.core.runtime.IStatus;
3738
import org.eclipse.core.runtime.NullProgressMonitor;
@@ -45,6 +46,8 @@
4546
import org.eclipse.ltk.core.refactoring.resource.DeleteResourceChange;
4647
import org.eclipse.ltk.core.refactoring.resource.ResourceChange;
4748

49+
import org.eclipse.jdt.core.IAccessRule;
50+
import org.eclipse.jdt.core.IClasspathEntry;
4851
import org.eclipse.jdt.core.ICompilationUnit;
4952
import org.eclipse.jdt.core.IJavaElement;
5053
import org.eclipse.jdt.core.IJavaProject;
@@ -56,6 +59,7 @@
5659
import org.eclipse.jdt.core.JavaCore;
5760
import org.eclipse.jdt.core.JavaModelException;
5861
import org.eclipse.jdt.core.Signature;
62+
import org.eclipse.jdt.core.compiler.CharOperation;
5963
import org.eclipse.jdt.core.compiler.IProblem;
6064
import org.eclipse.jdt.core.dom.AST;
6165
import org.eclipse.jdt.core.dom.ASTMatcher;
@@ -1526,6 +1530,10 @@ private void addStaticImportFavoriteProposals(IInvocationContext context, Simple
15261530
String qualifiedTypeName= Signature.getQualifier(Signature.getTypeErasure(curr));
15271531
String elementLabel= BasicElementLabels.getJavaElementName(JavaModelUtil.concatenateName(Signature.getSimpleName(qualifiedTypeName), name));
15281532

1533+
if (isForbidden(root, qualifiedTypeName)) {
1534+
continue;
1535+
}
1536+
15291537
String res= importRewrite.addStaticImport(qualifiedTypeName, name, isMethod, new ContextSensitiveImportRewriteContext(root, node.getStartPosition(), importRewrite));
15301538
int dot= res.lastIndexOf('.');
15311539
if (dot != -1) {
@@ -1546,6 +1554,30 @@ private void addStaticImportFavoriteProposals(IInvocationContext context, Simple
15461554
}
15471555
}
15481556

1557+
private boolean isForbidden(CompilationUnit root, String qualifiedTypeName) throws JavaModelException {
1558+
String qualifiedPathName= qualifiedTypeName.replace('.', '/');
1559+
IJavaElement type= root.getJavaElement().getJavaProject().findElement(IPath.fromPortableString(qualifiedPathName).removeLastSegments(1));
1560+
while (type != null) {
1561+
IClasspathEntry entry= root.getJavaElement().getJavaProject().getClasspathEntryFor(type.getPath());
1562+
if (entry != null) {
1563+
for (IAccessRule rule : entry.getAccessRules()) {
1564+
if (CharOperation.pathMatch(rule.getPattern().toString().toCharArray(), qualifiedPathName.toCharArray(),
1565+
true/*case sensitive*/, '/')) {
1566+
switch (rule.getKind()) {
1567+
case IAccessRule.K_NON_ACCESSIBLE:
1568+
case IAccessRule.K_DISCOURAGED:
1569+
return true;
1570+
default:
1571+
break;
1572+
}
1573+
}
1574+
}
1575+
}
1576+
type= type.getParent();
1577+
}
1578+
return false;
1579+
}
1580+
15491581
// 1400
15501582
private void addNewMethodProposals(ICompilationUnit cu, CompilationUnit astRoot, Expression sender, List<Expression> arguments, boolean isSuperInvocation, ASTNode invocationNode, String methodName, Collection<T> proposals) throws JavaModelException {
15511583
ITypeBinding nodeParentType= Bindings.getBindingOfParentType(invocationNode);

org.eclipse.jdt.ui.tests/ui/org/eclipse/jdt/ui/tests/quickfix/UnresolvedVariablesQuickFixTest.java

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,13 @@
2929
import org.eclipse.jdt.testplugin.JavaProjectHelper;
3030
import org.eclipse.jdt.testplugin.TestOptions;
3131

32+
import org.eclipse.core.runtime.Path;
33+
3234
import org.eclipse.jface.preference.IPreferenceStore;
3335

36+
import org.eclipse.jdt.core.IAccessRule;
37+
import org.eclipse.jdt.core.IClasspathAttribute;
38+
import org.eclipse.jdt.core.IClasspathEntry;
3439
import org.eclipse.jdt.core.ICompilationUnit;
3540
import org.eclipse.jdt.core.IJavaProject;
3641
import org.eclipse.jdt.core.IPackageFragment;
@@ -57,6 +62,10 @@ public class UnresolvedVariablesQuickFixTest extends QuickFixTest {
5762
public ProjectTestSetup projectSetup = new ProjectTestSetup();
5863

5964
private IJavaProject fJProject1;
65+
IJavaProject p1= null;
66+
IJavaProject referencing1= null;
67+
IJavaProject referencing2= null;
68+
6069
private IPackageFragmentRoot fSourceFolder;
6170

6271
@Before
@@ -1547,6 +1556,105 @@ private float foo() {
15471556
}
15481557
}
15491558

1559+
@Test
1560+
public void testStaticImportFavorite_Issue2893() throws Exception { //https://github.com/eclipse-jdt/eclipse.jdt.ui/issues/2893
1561+
IPreferenceStore preferenceStore= PreferenceConstants.getPreferenceStore();
1562+
preferenceStore.setValue(PreferenceConstants.CODEASSIST_FAVORITE_STATIC_MEMBERS, "test.Assertions.*");
1563+
try {
1564+
p1= JavaProjectHelper.createJavaProject("p1", "bin");
1565+
referencing1= JavaProjectHelper.createJavaProject("p2", "bin");
1566+
referencing2= JavaProjectHelper.createJavaProject("p3", "bin");
1567+
1568+
JavaProjectHelper.addRTJar(p1);
1569+
IPackageFragmentRoot p1SourceFolder= JavaProjectHelper.addSourceContainer(p1, "src");
1570+
IPackageFragment pack= p1SourceFolder.createPackageFragment("test", false, null);
1571+
1572+
String str= """
1573+
package test;
1574+
1575+
public class Assertions {
1576+
public static boolean assertEquals(Object obj1, Object obj2) throws Exception {
1577+
if (Object.equals(obj1, obj2)) {
1578+
throw new Exception();
1579+
}
1580+
}
1581+
}
1582+
""";
1583+
pack.createCompilationUnit("Assertions.java", str, false, null);
1584+
1585+
JavaProjectHelper.addRTJar(referencing1);
1586+
JavaProjectHelper.addRequiredProject(referencing1, p1);
1587+
IPackageFragmentRoot ref1SourceFolder= JavaProjectHelper.addSourceContainer(referencing1, "src");
1588+
IPackageFragment pack1= ref1SourceFolder.createPackageFragment("test1", false, null);
1589+
String str1= """
1590+
package test1;
1591+
1592+
public class E {
1593+
public boolean foo(Object obj1, Object obj2) throws Exception {
1594+
assertEquals(obj1, obj2);
1595+
}
1596+
}
1597+
""";
1598+
ICompilationUnit cu1= pack1.createCompilationUnit("E.java", str1, false, null);
1599+
1600+
JavaProjectHelper.addRTJar(referencing2);
1601+
IPackageFragmentRoot ref2SourceFolder= JavaProjectHelper.addSourceContainer(referencing2, "src");
1602+
IPackageFragment pack2= ref2SourceFolder.createPackageFragment("test2", false, null);
1603+
String str2= """
1604+
package test2;
1605+
1606+
public class E2 {
1607+
public boolean foo2(Object obj1, Object obj2) throws Exception {
1608+
assertEquals(obj1, obj2);
1609+
}
1610+
}
1611+
""";
1612+
ICompilationUnit cu2= pack2.createCompilationUnit("E2.java", str2, false, null);
1613+
1614+
1615+
1616+
IAccessRule[] accessRules2= new IAccessRule[] {
1617+
JavaCore.newAccessRule(new Path("**/*"), IAccessRule.K_NON_ACCESSIBLE)
1618+
};
1619+
IClasspathAttribute[] extraAttributes2= new IClasspathAttribute[] {
1620+
JavaCore.newClasspathAttribute("myTestAttribute", "val")
1621+
};
1622+
IClasspathEntry cpe2= JavaCore.newProjectEntry(p1.getProject().getFullPath(), accessRules2, true, extraAttributes2, false);
1623+
JavaProjectHelper.addToClasspath(referencing2, cpe2);
1624+
1625+
CompilationUnit astRoot2= getASTRoot(cu2);
1626+
ArrayList<IJavaCompletionProposal> proposals= collectCorrections(cu2, astRoot2, 1);
1627+
assertProposalDoesNotExist(proposals, "Add static import for 'Assertions.assertEquals'");
1628+
CompilationUnit astRoot1= getASTRoot(cu1);
1629+
ArrayList<IJavaCompletionProposal> proposals1= collectCorrections(cu1, astRoot1, 1);
1630+
String expected= """
1631+
package test1;
1632+
1633+
import static test.Assertions.assertEquals;
1634+
1635+
public class E {
1636+
public boolean foo(Object obj1, Object obj2) throws Exception {
1637+
assertEquals(obj1, obj2);
1638+
}
1639+
}
1640+
""";
1641+
assertExpectedExistInProposals(proposals1, new String[] { expected });
1642+
} finally {
1643+
preferenceStore.setValue(PreferenceConstants.CODEASSIST_FAVORITE_STATIC_MEMBERS, "");
1644+
if (referencing1 != null && referencing1.exists())
1645+
JavaProjectHelper.removeSourceContainer(referencing1, "src");
1646+
if (referencing2 != null && referencing2.exists())
1647+
JavaProjectHelper.removeSourceContainer(referencing2, "src");
1648+
1649+
if (p1 != null && p1.exists())
1650+
JavaProjectHelper.delete(p1);
1651+
if (referencing1 != null && referencing1.exists())
1652+
JavaProjectHelper.delete(referencing1);
1653+
if (referencing2 != null && referencing2.exists())
1654+
JavaProjectHelper.delete(referencing2);
1655+
}
1656+
}
1657+
15501658
@Test
15511659
public void testLongVarRef() throws Exception {
15521660
IPackageFragment pack1= fSourceFolder.createPackageFragment("test1", false, null);

0 commit comments

Comments
 (0)