From 283f9cd3c49b0122a41f11b82a4908667eb42d90 Mon Sep 17 00:00:00 2001 From: Patrick Ziegler Date: Wed, 15 Jan 2025 20:46:13 +0100 Subject: [PATCH] Restrict system library check to require Java nature The validation of the project classpath introduced with 74d062b38d3003638127127cc5358dd9f79df0f4 always fails, if the project doesn't have a Java nature (and thus usually no .classpath file). This causes issues when e.g. trying to open a source file with the Java editor or simply when trying to use the AST parser outside of a Java project. With this change, the check becomes more conservative and only fails, if both the Java nature exists and no system library is configured. Note that one can avoid this exception by disabling the binding resolution. But given that this requires changes in user code, it is more prudent to only fail in cases where this is the desired behavior. Resolves https://github.com/eclipse-jdt/eclipse.jdt.core/issues/3298 --- .../core/tests/dom/ASTConverterBugsTest.java | 64 +++++++++++++++++++ .../org/eclipse/jdt/core/dom/ASTParser.java | 7 +- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterBugsTest.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterBugsTest.java index df440d9bd3c..863fcf0ee99 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterBugsTest.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterBugsTest.java @@ -21,6 +21,7 @@ import java.util.Map; import java.util.Set; import junit.framework.Test; +import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.ICompilationUnit; @@ -1445,4 +1446,67 @@ public void acceptAST(String sourceFilePath, CompilationUnit cu) { parser.createASTs(paths, null, new String[] {}, new MyFileASTRequestor() {}, null); assertEquals(expectedProblems, actualProblems); } +public void testGH3298() throws Exception { + Hashtable options = JavaCore.getDefaultOptions(); + options.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_9); + options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_9); + options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_9); + + createProject("GH3298"); + IFile javaFile = createFile("GH3298/Test.java", "public class Test{}"); + ICompilationUnit javaElement = JavaCore.createCompilationUnitFrom(javaFile); + + try { + ASTParser parser = ASTParser.newParser(AST.getJLSLatest()); + parser.setSource(javaElement); + parser.setCompilerOptions(options); + parser.setResolveBindings(true); + parser.setKind(ASTParser.K_COMPILATION_UNIT); + assertNotNull(parser.createAST(null)); + + addJavaNature("GH3298"); + parser.setSource(javaElement); + parser.setCompilerOptions(options); + parser.setResolveBindings(true); + parser.setKind(ASTParser.K_COMPILATION_UNIT); + try { + parser.createAST(null); + fail("Expected exception was not thrown"); + } catch (IllegalStateException ise) { + assertEquals("Missing system library", ise.getMessage()); + } + + parser.setSource(javaElement); + parser.setCompilerOptions(options); + parser.setResolveBindings(false); + parser.setKind(ASTParser.K_COMPILATION_UNIT); + assertNotNull(parser.createAST(null)); + } finally { + deleteProject("GH3298"); + } +} +public void testGH3298_2() throws Exception { + Hashtable options = JavaCore.getDefaultOptions(); + options.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_9); + options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_9); + options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_9); + + Hashtable oldOptions = JavaCore.getOptions(); + + try { + JavaCore.setOptions(options); + ASTParser parser = ASTParser.newParser(AST.getJLSLatest()); + parser.setSource("public class Test{}".toCharArray()); + parser.setResolveBindings(true); + parser.setKind(ASTParser.K_COMPILATION_UNIT); + assertNotNull(parser.createAST(null)); + + parser.setSource("public class Test{}".toCharArray()); + parser.setResolveBindings(false); + parser.setKind(ASTParser.K_COMPILATION_UNIT); + assertNotNull(parser.createAST(null)); + } finally { + JavaCore.setOptions(oldOptions); + } +} } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java index 6223e6f1aaa..3252700db18 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java @@ -44,6 +44,7 @@ import org.eclipse.jdt.internal.core.ClassFileWorkingCopy; import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner; import org.eclipse.jdt.internal.core.JavaModelManager; +import org.eclipse.jdt.internal.core.JavaProject; import org.eclipse.jdt.internal.core.PackageFragment; import org.eclipse.jdt.internal.core.dom.ICompilationUnitResolver; import org.eclipse.jdt.internal.core.dom.util.DOMASTUtil; @@ -306,7 +307,7 @@ private void checkForSystemLibrary(List allClasspaths) { } } } - if (!hasSystemLibrary) + if (!hasSystemLibrary && hasJavaNature()) throw new IllegalStateException("Missing system library", exception); //$NON-NLS-1$ } } @@ -1562,4 +1563,8 @@ private void rootNodeToCompilationUnit(AST ast, CompilationUnit compilationUnit, } } } + + private boolean hasJavaNature() { + return this.project != null && JavaProject.hasJavaNature(this.project.getProject()); + } }