diff --git a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/JavacUtils.java b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/JavacUtils.java index a76fcfae878..b3270b67e62 100644 --- a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/JavacUtils.java +++ b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/JavacUtils.java @@ -185,6 +185,9 @@ private static void configureOptions(IJavaProject javaProject, Context context, for (Entry processorOption : processorOptions.entrySet()) { options.put("-A" + processorOption.getKey() + "=" + processorOption.getValue(), Boolean.toString(true)); } + if (!options.isSet(Option.A) && ProcessorConfig.isAnnotationProcessingEnabled(javaProject)) { + options.put(Option.A, ""); + } addDebugInfos(compilerOptions, options); } diff --git a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/ProcessorConfig.java b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/ProcessorConfig.java index 2adf3aab712..c4d295a098c 100644 --- a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/ProcessorConfig.java +++ b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/ProcessorConfig.java @@ -40,6 +40,8 @@ public class ProcessorConfig { private static final String APT_STRING_BASE = "org.eclipse.jdt.apt"; //$NON-NLS-1$ 1$ private static final String APT_PROCESSOROPTIONS = APT_STRING_BASE + ".processorOptions"; //$NON-NLS-1$ private static final String APT_NULLVALUE = APT_STRING_BASE + ".NULLVALUE"; //$NON-NLS-1$ + private static final String APT_ENABLED = APT_STRING_BASE + ".aptEnabled"; //$NON-NLS-1$ + private static final String APT_PROCESSANNOTATIONS = "org.eclipse.jdt.core.compiler.processAnnotations"; //$NON-NLS-1$ /** regex to identify substituted token in path variables */ private static final String PATHVAR_TOKEN = "^%[^%/\\\\ ]+%.*"; //$NON-NLS-1$ @@ -63,6 +65,26 @@ public static Map getProcessorOptions(IJavaProject jproj) { return options; } + public static boolean isAnnotationProcessingEnabled(IJavaProject jproj) { + IScopeContext[] contexts; + if (jproj != null && jproj.getProject() != null) { + contexts = new IScopeContext[] { new ProjectScope(jproj.getProject()), InstanceScope.INSTANCE }; + } else { + contexts = new IScopeContext[] { InstanceScope.INSTANCE }; + } + for (IScopeContext context : contexts) { + IEclipsePreferences prefs = context.getNode(JavaCore.PLUGIN_ID); + if ("enabled".equals(prefs.get(APT_PROCESSANNOTATIONS, "disabled"))) { + return true; + } + prefs = context.getNode(APT_PLUGIN_ID); + if (prefs.getBoolean(APT_ENABLED, false)) { + return true; + } + } + return false; + } + private static Map getRawProcessorOptions(IJavaProject jproj) { Map options = new HashMap<>(); diff --git a/org.eclipse.jdt.core.tests.javac/pom.xml b/org.eclipse.jdt.core.tests.javac/pom.xml index 81e4ed1b48e..4e23878d5df 100644 --- a/org.eclipse.jdt.core.tests.javac/pom.xml +++ b/org.eclipse.jdt.core.tests.javac/pom.xml @@ -47,7 +47,7 @@ - --add-modules ALL-SYSTEM -Dcompliance=21 -DCompilationUnit.DOM_BASED_OPERATIONS=true -DCompilationUnit.codeComplete.DOM_BASED_OPERATIONS=true -DSourceIndexer.DOM_BASED_INDEXER=true -DICompilationUnitResolver=org.eclipse.jdt.core.dom.JavacCompilationUnitResolver -DAbstractImageBuilder.compiler=org.eclipse.jdt.internal.javac.JavacCompiler --add-opens jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED --add-opens jdk.javadoc/jdk.javadoc.internal.doclets.formats.html.taglets.snippet=ALL-UNNAMED --add-opens jdk.javadoc/jdk.javadoc.internal.doclets.formats.html.taglets=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.platform=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.resources=ALL-UNNAMED + --add-modules ALL-SYSTEM -Dcompliance=21 -DCompilationUnit.DOM_BASED_OPERATIONS=true -DCompilationUnit.codeComplete.DOM_BASED_OPERATIONS=true -DSourceIndexer.DOM_BASED_INDEXER=true -DICompilationUnitResolver=org.eclipse.jdt.core.dom.JavacCompilationUnitResolver -DAbstractImageBuilder.compiler=org.eclipse.jdt.internal.javac.JavacCompiler -DAbstractImageBuilder.compilerFactory=org.eclipse.jdt.internal.javac.JavacCompilerFactory --add-opens jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED --add-opens jdk.javadoc/jdk.javadoc.internal.doclets.formats.html.taglets.snippet=ALL-UNNAMED --add-opens jdk.javadoc/jdk.javadoc.internal.doclets.formats.html.taglets=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.platform=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.resources=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens jdk.zipfs/jdk.nio.zipfs=ALL-UNNAMED diff --git a/org.eclipse.jdt.core.tests.javac/projects/lomboktest/.classpath b/org.eclipse.jdt.core.tests.javac/projects/lomboktest/.classpath new file mode 100644 index 00000000000..b8d36270676 --- /dev/null +++ b/org.eclipse.jdt.core.tests.javac/projects/lomboktest/.classpath @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/org.eclipse.jdt.core.tests.javac/projects/lomboktest/.gitignore b/org.eclipse.jdt.core.tests.javac/projects/lomboktest/.gitignore new file mode 100644 index 00000000000..f33b9ca6226 --- /dev/null +++ b/org.eclipse.jdt.core.tests.javac/projects/lomboktest/.gitignore @@ -0,0 +1,3 @@ +bin +.apt_generated + diff --git a/org.eclipse.jdt.core.tests.javac/projects/lomboktest/.project b/org.eclipse.jdt.core.tests.javac/projects/lomboktest/.project new file mode 100644 index 00000000000..88a2d90807f --- /dev/null +++ b/org.eclipse.jdt.core.tests.javac/projects/lomboktest/.project @@ -0,0 +1,17 @@ + + + lomboktest + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/org.eclipse.jdt.core.tests.javac/projects/lomboktest/.settings/org.eclipse.core.resources.prefs b/org.eclipse.jdt.core.tests.javac/projects/lomboktest/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 00000000000..99f26c0203a --- /dev/null +++ b/org.eclipse.jdt.core.tests.javac/projects/lomboktest/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/org.eclipse.jdt.core.tests.javac/projects/lomboktest/.settings/org.eclipse.jdt.apt.core.prefs b/org.eclipse.jdt.core.tests.javac/projects/lomboktest/.settings/org.eclipse.jdt.apt.core.prefs new file mode 100644 index 00000000000..fa6bcfb3fdb --- /dev/null +++ b/org.eclipse.jdt.core.tests.javac/projects/lomboktest/.settings/org.eclipse.jdt.apt.core.prefs @@ -0,0 +1,5 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.apt.aptEnabled=true +org.eclipse.jdt.apt.genSrcDir=.apt_generated +org.eclipse.jdt.apt.genTestSrcDir=.apt_generated_tests +org.eclipse.jdt.apt.reconcileEnabled=true diff --git a/org.eclipse.jdt.core.tests.javac/projects/lomboktest/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jdt.core.tests.javac/projects/lomboktest/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000000..f1275b4cc3b --- /dev/null +++ b/org.eclipse.jdt.core.tests.javac/projects/lomboktest/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=23 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=23 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.processAnnotations=enabled +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=23 diff --git a/org.eclipse.jdt.core.tests.javac/projects/lomboktest/lib/lombok-1.18.34.jar b/org.eclipse.jdt.core.tests.javac/projects/lomboktest/lib/lombok-1.18.34.jar new file mode 100644 index 00000000000..ea0ba78ac43 Binary files /dev/null and b/org.eclipse.jdt.core.tests.javac/projects/lomboktest/lib/lombok-1.18.34.jar differ diff --git a/org.eclipse.jdt.core.tests.javac/projects/lomboktest/src/org/sample/Main.java b/org.eclipse.jdt.core.tests.javac/projects/lomboktest/src/org/sample/Main.java new file mode 100644 index 00000000000..ba585c23d5e --- /dev/null +++ b/org.eclipse.jdt.core.tests.javac/projects/lomboktest/src/org/sample/Main.java @@ -0,0 +1,7 @@ +package org.sample; +public class Main { + public void test() { + Person s = new Person(10, "abc"); + System.out.println(s.getAge() + s.getName()); + } +} \ No newline at end of file diff --git a/org.eclipse.jdt.core.tests.javac/projects/lomboktest/src/org/sample/Person.java b/org.eclipse.jdt.core.tests.javac/projects/lomboktest/src/org/sample/Person.java new file mode 100644 index 00000000000..5d0aac1dc7f --- /dev/null +++ b/org.eclipse.jdt.core.tests.javac/projects/lomboktest/src/org/sample/Person.java @@ -0,0 +1,9 @@ +package org.sample; +import lombok.AllArgsConstructor; +import lombok.Data; +@Data +@AllArgsConstructor +class Person { + private Integer age; + private String name; +} \ No newline at end of file diff --git a/org.eclipse.jdt.core.tests.javac/src/org/eclipse/jdt/core/tests/javac/JobHelpers.java b/org.eclipse.jdt.core.tests.javac/src/org/eclipse/jdt/core/tests/javac/JobHelpers.java new file mode 100644 index 00000000000..c49b44b01c0 --- /dev/null +++ b/org.eclipse.jdt.core.tests.javac/src/org/eclipse/jdt/core/tests/javac/JobHelpers.java @@ -0,0 +1,227 @@ +/******************************************************************************* + * Copyright (c) 2008-2010 Sonatype, Inc. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Sonatype, Inc. - initial API and implementation + * + *******************************************************************************/ +package org.eclipse.jdt.core.tests.javac; + +import org.eclipse.core.internal.resources.CharsetDeltaJob; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRunnable; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.resources.WorkspaceJob; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.ILog; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.jobs.IJobManager; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jdt.core.search.IJavaSearchConstants; +import org.eclipse.jdt.core.search.IJavaSearchScope; +import org.eclipse.jdt.core.search.SearchEngine; +import org.eclipse.jdt.core.search.SearchPattern; +import org.eclipse.jdt.core.search.TypeNameRequestor; +import org.eclipse.jdt.internal.core.JavaModelManager; + +/** + * Copied from m2e's org.eclipse.m2e.tests.common/src/org/eclipse/m2e/tests/common/JobHelpers.java + * + */ +@SuppressWarnings("restriction") +public final class JobHelpers { + + private JobHelpers() { + //no instantiation + } + + private static final int POLLING_DELAY = 10; + public static final int MAX_TIME_MILLIS = 300000; + + public static void waitForJobsToComplete() { + try { + waitForJobsToComplete(new NullProgressMonitor()); + } catch(Exception ex) { + throw new IllegalStateException(ex); + } + } + + public static void waitForJobsToComplete(IProgressMonitor monitor) throws InterruptedException, CoreException { + waitForBuildJobs(); + + /* + * First, make sure refresh job gets all resource change events + * + * Resource change events are delivered after WorkspaceJob#runInWorkspace returns + * and during IWorkspace#run. Each change notification is delivered by + * only one thread/job, so we make sure no other workspaceJob is running then + * call IWorkspace#run from this thread. + * + * Unfortunately, this does not catch other jobs and threads that call IWorkspace#run + * so we have to hard-code workarounds + * + * See http://www.eclipse.org/articles/Article-Resource-deltas/resource-deltas.html + */ + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IJobManager jobManager = Job.getJobManager(); + jobManager.suspend(); + try { + Job[] jobs = jobManager.find(null); + for(int i = 0; i < jobs.length; i++ ) { + if(jobs[i] instanceof WorkspaceJob || jobs[i].getClass().getName().endsWith("JREUpdateJob")) { + jobs[i].join(); + } + } + workspace.run(new IWorkspaceRunnable() { + @Override + public void run(IProgressMonitor monitor) { + } + }, workspace.getRoot(), 0, monitor); + + } finally { + jobManager.resume(); + } + + waitForBuildJobs(); + waitForJobs(CharsetDeltaJob.FAMILY_CHARSET_DELTA, null); + } + + public static void waitForWorkspaceJobsToComplete(IProgressMonitor monitor) throws InterruptedException { + IJobManager jobManager = Job.getJobManager(); + jobManager.suspend(); + try { + Job[] jobs = jobManager.find(null); + for(int i = 0; i < jobs.length; i++ ) { + if(jobs[i] instanceof WorkspaceJob || jobs[i].getClass().getName().endsWith("JREUpdateJob")) { + jobs[i].join(); + } + } + } finally { + jobManager.resume(); + } + } + + private static void waitForBuildJobs() { + waitForBuildJobs(MAX_TIME_MILLIS); + } + + public static void waitForBuildJobs(int maxTimeMilis) { + waitForJobs(BuildJobMatcher.INSTANCE, maxTimeMilis); + waitForJobs(BuildJobOffMatcher.INSTANCE, maxTimeMilis); + } + + public static void waitForJobs(IJobMatcher matcher, int maxWaitMillis) { + final long limit = System.currentTimeMillis() + maxWaitMillis; + while(true) { + Job job = getJob(matcher); + if(job == null) { + return; + } + boolean timeout = System.currentTimeMillis() > limit; + if (timeout) { + ILog.get().info("Timeout while waiting for completion of job: " + job); + break; + } + job.wakeUp(); + try { + Thread.sleep(POLLING_DELAY); + } catch(InterruptedException e) { + // ignore and keep waiting + } + } + } + + private static Job getJob(IJobMatcher matcher) { + Job[] jobs = Job.getJobManager().find(null); + for(Job job : jobs) { + if(matcher.matches(job)) { + return job; + } + } + return null; + } + + public static void waitForJobs(String jobFamily, IProgressMonitor monitor) { + try { + Job.getJobManager().join(jobFamily, monitor); + } catch (OperationCanceledException ignorable) { + // No need to pollute logs when query is cancelled + } catch (InterruptedException e) { + ILog.get().error(e.getMessage(), e); + } + } + + public static void waitForBuildOffJobs(int maxTimeMillis) { + waitForJobs(BuildJobOffMatcher.INSTANCE, maxTimeMillis); + } + + public static void waitForAutoBuildJobs(int maxTimeMillis) { + waitForJobs(AutoBuildJobMatcher.INSTANCE, maxTimeMillis); + } + + // copied from ./org.eclipse.jdt.core.tests.performance/src/org/eclipse/jdt/core/tests/performance/FullSourceWorkspaceTests.java + public static void waitUntilIndexesReady() { + // dummy query for waiting until the indexes are ready + SearchEngine engine = new SearchEngine(); + IJavaSearchScope scope = SearchEngine.createWorkspaceScope(); + JavaModelManager.getIndexManager().waitForIndex(true, null); + try { + engine.searchAllTypeNames(null, SearchPattern.R_EXACT_MATCH, "!@$#!@".toCharArray(), SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CASE_SENSITIVE, IJavaSearchConstants.CLASS, scope, new TypeNameRequestor() { + @Override + public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName, char[][] enclosingTypeNames, String path) { + } + }, IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, null); + } catch (CoreException e) { + ILog.get().error(e.getMessage(), e); + } + } + + interface IJobMatcher { + + boolean matches(Job job); + + } + + static class BuildJobMatcher implements IJobMatcher { + + public static final IJobMatcher INSTANCE = new BuildJobMatcher(); + + @Override + public boolean matches(Job job) { + return (job instanceof WorkspaceJob) || job.getClass().getName().matches("(.*\\.AutoBuild.*)") + || job.getClass().getName().endsWith("JREUpdateJob"); + } + + } + + static class BuildJobOffMatcher implements IJobMatcher { + + public static final IJobMatcher INSTANCE = new BuildJobOffMatcher(); + + @Override + public boolean matches(Job job) { + return job.getClass().getName().matches("(.*\\.AutoBuildOff.*)"); + } + + } + + static class AutoBuildJobMatcher implements IJobMatcher { + + public static final IJobMatcher INSTANCE = new AutoBuildJobMatcher(); + + @Override + public boolean matches(Job job) { + return job.getClass().getName().endsWith("AutoBuildJob"); + } + + } + +} \ No newline at end of file diff --git a/org.eclipse.jdt.core.tests.javac/src/org/eclipse/jdt/core/tests/javac/RegressionTests.java b/org.eclipse.jdt.core.tests.javac/src/org/eclipse/jdt/core/tests/javac/RegressionTests.java index 33f4fae6945..11a978de9de 100644 --- a/org.eclipse.jdt.core.tests.javac/src/org/eclipse/jdt/core/tests/javac/RegressionTests.java +++ b/org.eclipse.jdt.core.tests.javac/src/org/eclipse/jdt/core/tests/javac/RegressionTests.java @@ -35,6 +35,7 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.IJavaElement; @@ -47,13 +48,23 @@ import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.internal.core.CompilationUnit; import org.junit.After; +import org.junit.Assume; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; public class RegressionTests { private static IProject project; + @BeforeClass + public static void beforeClass() throws Exception { + IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); + for (IProject p: projects) { + p.delete(false, true, null); + } + } + @Before public void setUp() throws Exception { project = importProject("projects/dummy"); @@ -118,6 +129,7 @@ public void testBuildMultipleOutputDirectories2() throws Exception { IProject proj2 = importProject("projects/multipleOutputDirectories/proj2"); ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.CLEAN_BUILD, null); ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); + waitForBackgroundJobs(); List errors = findMarkers(proj1, IMarker.SEVERITY_ERROR); assertTrue(errors.isEmpty()); errors = findMarkers(proj2, IMarker.SEVERITY_ERROR); @@ -128,16 +140,33 @@ public void testBuildMultipleOutputDirectories2() throws Exception { assertArrayEquals(new IProblem[0], dom.getProblems()); } + // https://github.com/eclipse-jdtls/eclipse-jdt-core-incubator/issues/955 + @Test + public void testlombok() throws Exception { + Assume.assumeTrue("javac is not set, skip it", CompilationUnit.DOM_BASED_OPERATIONS); + IProject proj = importProject("projects/lomboktest"); + ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.CLEAN_BUILD, null); + ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, null); + waitForBackgroundJobs(); + List errors = findMarkers(proj, IMarker.SEVERITY_ERROR); + assertTrue(errors.isEmpty()); + CompilationUnit unit = (CompilationUnit)JavaCore.create(proj).findElement(Path.fromOSString("org/sample/Main.java")); + unit.becomeWorkingCopy(null); + var dom = unit.reconcile(AST.getJLSLatest(), true, unit.getOwner(), null); + assertArrayEquals(new IProblem[0], dom.getProblems()); + } + static IProject importProject(String locationInBundle) throws URISyntaxException, IOException, CoreException { File file = new File(FileLocator.toFileURL(RegressionTests.class.getResource("/" + locationInBundle + "/.project")).toURI()); IPath dotProjectPath = Path.fromOSString(file.getAbsolutePath()); IProjectDescription projectDescription = ResourcesPlugin.getWorkspace() .loadProjectDescription(dotProjectPath); projectDescription.setLocation(dotProjectPath.removeLastSegments(1)); - IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectDescription.getName()); - project.create(projectDescription, null); - project.open(null); - return project; + IProject proj = ResourcesPlugin.getWorkspace().getRoot().getProject(projectDescription.getName()); + proj.create(projectDescription, null); + proj.open(null); + proj.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); + return proj; } // copied from org.eclipse.jdt.ls.core.internal.ResourceUtils.findMarkers(IResource, Integer...) @@ -154,4 +183,10 @@ static List findMarkers(IResource resource, Integer... severities) thro .collect(Collectors.toList()); return markers; } + + protected void waitForBackgroundJobs() throws Exception { + JobHelpers.waitForJobsToComplete(new NullProgressMonitor()); + JobHelpers.waitUntilIndexesReady(); + } + }