Skip to content

Commit f111e31

Browse files
snjezargrunber
authored andcommitted
Null Analysis does not work for Eclipse/invisible project
Signed-off-by: Snjezana Peco <snjezana.peco@redhat.com>
1 parent bf2c986 commit f111e31

8 files changed

Lines changed: 98 additions & 14 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ target/
44
bin/
55
**/lib/
66
!org.eclipse.jdt.ls.tests/projects/singlefile/simple/lib/
7+
!org.eclipse.jdt.ls.tests/projects/eclipse/testnullable2/lib/
78
!org.eclipse.jdt.ls.tests/projects/maven/salut5/node_modules/
89
!org.eclipse.jdt.ls.tests/fakejdk2/17a/bin
910
!org.eclipse.jdt.ls.tests/fakejdk2/17a/lib

org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/Preferences.java

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2277,23 +2277,11 @@ private String getAnnotationType(IJavaProject javaProject, List<String> annotati
22772277
}
22782278
}
22792279
}
2280+
return findTypeInProject(javaProject, annotationType, classpathStorage);
22802281
} else {
22812282
// for unknown types, try to find type in the project
22822283
try {
2283-
IType type = javaProject.findType(annotationType);
2284-
if (type != null) {
2285-
IJavaElement fragmentRoot = type.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
2286-
IClasspathEntry classpathEntry = javaProject.getClasspathEntryFor(fragmentRoot.getPath());
2287-
if (classpathEntry == null || !classpathEntry.isTest()) {
2288-
String classpath = fragmentRoot.getPath().toOSString();
2289-
if (classpathStorage.containsKey(annotationType)) {
2290-
classpathStorage.get(annotationType).add(classpath);
2291-
} else {
2292-
classpathStorage.put(annotationType, new ArrayList<>(Arrays.asList(classpath)));
2293-
}
2294-
return annotationType;
2295-
}
2296-
}
2284+
return findTypeInProject(javaProject, annotationType, classpathStorage);
22972285
} catch (JavaModelException e) {
22982286
continue;
22992287
}
@@ -2306,6 +2294,24 @@ private String getAnnotationType(IJavaProject javaProject, List<String> annotati
23062294
return null;
23072295
}
23082296

2297+
private String findTypeInProject(IJavaProject javaProject, String annotationType, Map<String, List<String>> classpathStorage) throws JavaModelException {
2298+
IType type = javaProject.findType(annotationType);
2299+
if (type != null) {
2300+
IJavaElement fragmentRoot = type.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
2301+
IClasspathEntry classpathEntry = javaProject.getClasspathEntryFor(fragmentRoot.getPath());
2302+
if (classpathEntry == null || !classpathEntry.isTest()) {
2303+
String classpath = fragmentRoot.getPath().toOSString();
2304+
if (classpathStorage.containsKey(annotationType)) {
2305+
classpathStorage.get(annotationType).add(classpath);
2306+
} else {
2307+
classpathStorage.put(annotationType, new ArrayList<>(Arrays.asList(classpath)));
2308+
}
2309+
return annotationType;
2310+
}
2311+
}
2312+
return null;
2313+
}
2314+
23092315
/**
23102316
* generates the null analysis options of the given nonnull type and nullable type
23112317
* @param nonnullType the given nonnull type
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<classpath>
3+
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
4+
<classpathentry kind="src" path="src"/>
5+
<classpathentry kind="lib" path="lib/jsr305-3.0.2.jar"/>
6+
<classpathentry kind="lib" path="lib/org.eclipse.jdt.annotation-2.2.600.jar"/>
7+
<classpathentry kind="output" path="bin"/>
8+
</classpath>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<projectDescription>
3+
<name>testnullable2</name>
4+
<comment></comment>
5+
<projects>
6+
</projects>
7+
<buildSpec>
8+
<buildCommand>
9+
<name>org.eclipse.jdt.core.javabuilder</name>
10+
<arguments>
11+
</arguments>
12+
</buildCommand>
13+
</buildSpec>
14+
<natures>
15+
<nature>org.eclipse.jdt.core.javanature</nature>
16+
</natures>
17+
</projectDescription>
Binary file not shown.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package org.sample;
2+
import javax.annotation.Nonnull;
3+
public class Main {
4+
public static void main(String[] args) {
5+
Test.foo(null);
6+
}
7+
}
8+
class Test {
9+
static void foo(@Nonnull Test a) { }
10+
}

org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/managers/EclipseProjectImporterTest.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import static org.eclipse.jdt.ls.core.internal.WorkspaceHelper.getProject;
1616
import static org.junit.Assert.assertEquals;
1717
import static org.junit.Assert.assertFalse;
18+
import static org.junit.Assert.assertNotNull;
1819
import static org.junit.Assert.assertNull;
1920
import static org.junit.Assert.assertSame;
2021
import static org.junit.Assert.assertTrue;
@@ -24,26 +25,35 @@
2425
import java.io.File;
2526
import java.util.ArrayList;
2627
import java.util.Collection;
28+
import java.util.Collections;
2729
import java.util.List;
2830
import java.util.Map;
2931
import java.util.function.Function;
3032

33+
import org.eclipse.core.resources.IFile;
34+
import org.eclipse.core.resources.IMarker;
3135
import org.eclipse.core.resources.IProject;
36+
import org.eclipse.core.resources.IResource;
3237
import org.eclipse.core.resources.IWorkspace;
3338
import org.eclipse.core.resources.IWorkspaceRoot;
3439
import org.eclipse.core.runtime.IPath;
40+
import org.eclipse.core.runtime.NullProgressMonitor;
41+
import org.eclipse.jdt.core.IJavaProject;
3542
import org.eclipse.jdt.core.JavaCore;
3643
import org.eclipse.jdt.ls.core.internal.JavaClientConnection;
3744
import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
3845
import org.eclipse.jdt.ls.core.internal.ProjectUtils;
3946
import org.eclipse.jdt.ls.core.internal.ResourceUtils;
47+
import org.eclipse.jdt.ls.core.internal.handlers.BuildWorkspaceHandler;
4048
import org.eclipse.jdt.ls.core.internal.preferences.ClientPreferences;
49+
import org.eclipse.jdt.ls.core.internal.preferences.Preferences.FeatureStatus;
4150
import org.eclipse.lsp4j.FileSystemWatcher;
4251
import org.eclipse.lsp4j.RelativePattern;
4352
import org.junit.After;
4453
import org.junit.Before;
4554
import org.junit.Test;
4655

56+
import com.google.common.collect.ImmutableList;
4757

4858
public class EclipseProjectImporterTest extends AbstractProjectsManagerBasedTest {
4959

@@ -240,6 +250,38 @@ public void importJavaProjectWithRootSource() throws Exception {
240250
assertTrue("Unexpected source glob pattern: " + srcGlobPattern, srcGlobPattern.endsWith("projectwithrootsource/**"));
241251
}
242252

253+
@Test
254+
public void testNullAnalysis() throws Exception {
255+
this.preferenceManager.getPreferences().setNonnullTypes(ImmutableList.of("javax.annotation.Nonnull", "org.eclipse.jdt.annotation.NonNull"));
256+
this.preferenceManager.getPreferences().setNullableTypes(ImmutableList.of("org.eclipse.jdt.annotation.Nullable", "javax.annotation.Nonnull"));
257+
this.preferenceManager.getPreferences().setNullAnalysisMode(FeatureStatus.automatic);
258+
try {
259+
String name = "testnullable2";
260+
importProjects("eclipse/" + name);
261+
IProject project = getProject(name);
262+
assertIsJavaProject(project);
263+
if (this.preferenceManager.getPreferences().updateAnnotationNullAnalysisOptions()) {
264+
BuildWorkspaceHandler buildWorkspaceHandler = new BuildWorkspaceHandler(JavaLanguageServerPlugin.getProjectsManager());
265+
buildWorkspaceHandler.buildWorkspace(true, new NullProgressMonitor());
266+
}
267+
IMarker[] markers = project.findMarkers(null, true, IResource.DEPTH_INFINITE);
268+
assertEquals(2, markers.length);
269+
IMarker marker = getWarningMarker(project, "Null type mismatch: required '@Nonnull Test' but the provided value is null");
270+
assertNotNull(marker);
271+
assertTrue(marker.getResource() instanceof IFile);
272+
assertEquals("Main.java", ((IFile) marker.getResource()).getFullPath().lastSegment());
273+
IJavaProject javaProject = JavaCore.create(project);
274+
Map<String, String> options = javaProject.getOptions(true);
275+
assertEquals(JavaCore.ENABLED, options.get(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS));
276+
assertNoErrors(project);
277+
} finally {
278+
this.preferenceManager.getPreferences().setNonnullTypes(Collections.emptyList());
279+
this.preferenceManager.getPreferences().setNullableTypes(Collections.emptyList());
280+
this.preferenceManager.getPreferences().setNullAnalysisMode(FeatureStatus.disabled);
281+
this.preferenceManager.getPreferences().updateAnnotationNullAnalysisOptions();
282+
}
283+
}
284+
243285
@After
244286
public void after() {
245287
importer = null;

0 commit comments

Comments
 (0)