Skip to content

Commit 3f9f336

Browse files
stephan-herrmannvik-chand
authored andcommitted
Bug 526011 - PDE should provide an abstraction above
annotation-configuration in .classpath * introduce new manifest header Eclipse-ExportExternalAnnotations * if set to true, resolved entries in Required-Plugins will define their annotationPath equal to the plugin location This suffices to help JDT/Core to use these annotations for null analysis, if .eea files are shipped with the plug-in jar. We even have content assist for the new header :) Change-Id: I84643bc57d3da9f5a8f50d61da4ea82f8cd9cac9 Signed-off-by: Stephan Herrmann <stephan.herrmann@berlin.de> Reviewed-on: https://git.eclipse.org/r/c/pde/eclipse.pde.ui/+/175466 Tested-by: Vikas Chandra <Vikas.Chandra@in.ibm.com> Reviewed-by: Vikas Chandra <Vikas.Chandra@in.ibm.com>
1 parent cc28671 commit 3f9f336

11 files changed

Lines changed: 80 additions & 14 deletions

File tree

ui/org.eclipse.pde.core/.settings/.api_filters

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
22
<component id="org.eclipse.pde.core" version="2">
3+
<resource path="META-INF/MANIFEST.MF">
4+
<filter comment="experimental addition of a manifest option" id="924844039">
5+
<message_arguments>
6+
<message_argument value="3.15.200"/>
7+
<message_argument value="3.15.100"/>
8+
</message_arguments>
9+
</filter>
10+
</resource>
311
<resource path="src/org/eclipse/pde/internal/core/project/BundleProjectService.java" type="org.eclipse.pde.internal.core.project.BundleProjectService">
412
<filter comment="Platform Team allows use of bundle importers for PDE import from source repository" id="640712815">
513
<message_arguments>

ui/org.eclipse.pde.core/src/org/eclipse/pde/core/plugin/IPluginBase.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,4 +179,16 @@ public interface IPluginBase extends IExtensions, IIdentifiable {
179179
*/
180180
void setSchemaVersion(String schemaVersion) throws CoreException;
181181

182+
/**
183+
* Returns whether this plugin exports its external annotations (.eea files)
184+
* to be considered by clients performing annotation based null analysis.
185+
* This is read from the manifest header
186+
* {@code Eclipse-ExportExternalAnnotations}.
187+
*
188+
* @since 3.15
189+
*/
190+
default boolean exportsExternalAnnotations() {
191+
return false;
192+
}
193+
182194
}

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ICoreConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ public interface ICoreConstants {
285285
String ECLIPSE_SOURCE_REFERENCES = "Eclipse-SourceReferences"; //$NON-NLS-1$
286286
String SERVICE_COMPONENT = "Service-Component"; //$NON-NLS-1$
287287
String AUTOMATIC_MODULE_NAME = "Automatic-Module-Name"; //$NON-NLS-1$
288+
String ECLIPSE_EXPORT_EXTERNAL_ANNOTATIONS = "Eclipse-ExportExternalAnnotations"; //$NON-NLS-1$
288289

289290
// Equinox-specific system properties
290291
String OSGI_SYSTEM_BUNDLE = "osgi.system.bundle"; //$NON-NLS-1$

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDEAuxiliaryState.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ static class PluginInfo {
9595
String project;
9696
String localization;
9797
String bundleSourceEntry;
98+
boolean exportsExternalAnnotations;
9899
}
99100

100101
/**
@@ -188,6 +189,11 @@ public String getBundleSourceEntry(long bundleID) {
188189
return info == null ? null : info.bundleSourceEntry;
189190
}
190191

192+
public boolean exportsExternalAnnotations(long bundleID) {
193+
PluginInfo info = fPluginInfos.get(Long.toString(bundleID));
194+
return info == null ? false : info.exportsExternalAnnotations;
195+
}
196+
191197
/**
192198
* Builds an xml document storing the auxiliary plugin info.
193199
* @param dir directory location to create the file
@@ -375,6 +381,8 @@ protected void addAuxiliaryData(BundleDescription desc, Map<String, String> mani
375381
info.localization = manifest.get(Constants.BUNDLE_LOCALIZATION);
376382
info.hasBundleStructure = hasBundleStructure;
377383
info.bundleSourceEntry = manifest.get(ICoreConstants.ECLIPSE_SOURCE_BUNDLE);
384+
info.exportsExternalAnnotations = "true" //$NON-NLS-1$
385+
.equals(manifest.get(ICoreConstants.ECLIPSE_EXPORT_EXTERNAL_ANNOTATIONS));
378386
fPluginInfos.put(Long.toString(desc.getBundleId()), info);
379387
}
380388

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDEClasspathContainer.java

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.io.File;
1717
import java.util.ArrayList;
1818
import java.util.HashMap;
19+
import java.util.List;
1920
import org.eclipse.core.resources.IProject;
2021
import org.eclipse.core.runtime.CoreException;
2122
import org.eclipse.core.runtime.IPath;
@@ -24,6 +25,7 @@
2425
import org.eclipse.jdt.core.IClasspathAttribute;
2526
import org.eclipse.jdt.core.IClasspathEntry;
2627
import org.eclipse.jdt.core.JavaCore;
28+
import org.eclipse.jdt.core.JavaModelException;
2729
import org.eclipse.osgi.service.resolver.BundleDescription;
2830
import org.eclipse.pde.core.plugin.IPluginLibrary;
2931
import org.eclipse.pde.core.plugin.IPluginModelBase;
@@ -54,21 +56,28 @@ public String toString() {
5456

5557
private static final IAccessRule EXCLUDE_ALL_RULE = JavaCore.newAccessRule(new Path("**/*"), IAccessRule.K_NON_ACCESSIBLE | IAccessRule.IGNORE_IF_BETTER); //$NON-NLS-1$
5658

57-
protected void addProjectEntry(IProject project, Rule[] rules, ArrayList<IClasspathEntry> entries) throws CoreException {
59+
protected void addProjectEntry(IProject project, Rule[] rules, boolean exportsExternalAnnotations,
60+
ArrayList<IClasspathEntry> entries) throws CoreException {
5861
if (project.hasNature(JavaCore.NATURE_ID)) {
59-
IClasspathEntry entry = null;
60-
if (rules != null) {
61-
IAccessRule[] accessRules = getAccessRules(rules);
62-
entry = JavaCore.newProjectEntry(project.getFullPath(), accessRules, true, new IClasspathAttribute[0], false);
63-
} else {
64-
entry = JavaCore.newProjectEntry(project.getFullPath());
65-
}
62+
IAccessRule[] accessRules = rules != null ? getAccessRules(rules) : null;
63+
IClasspathAttribute[] extraAttribs = getClasspathAttributesForProject(project, exportsExternalAnnotations);
64+
IClasspathEntry entry = JavaCore.newProjectEntry(project.getFullPath(), accessRules, true, extraAttribs, false);
6665
if (!entries.contains(entry)) {
6766
entries.add(entry);
6867
}
6968
}
7069
}
7170

71+
private IClasspathAttribute[] getClasspathAttributesForProject(IProject project, boolean exportsExternalAnnotations)
72+
throws JavaModelException {
73+
if (exportsExternalAnnotations) {
74+
String annotationPath = JavaCore.create(project).getOutputLocation().toString();
75+
return new IClasspathAttribute[] {
76+
JavaCore.newClasspathAttribute(IClasspathAttribute.EXTERNAL_ANNOTATION_PATH, annotationPath) };
77+
}
78+
return new IClasspathAttribute[0];
79+
}
80+
7281
public static IClasspathEntry[] getExternalEntries(IPluginModelBase model) {
7382
ArrayList<IClasspathEntry> entries = new ArrayList<>();
7483
addExternalPlugin(model, new Rule[0], entries);
@@ -153,12 +162,20 @@ private static synchronized IAccessRule getAccessibleRule(IPath path) {
153162
}
154163

155164
private static IClasspathAttribute[] getClasspathAttributes(IPluginModelBase model) {
165+
List<IClasspathAttribute> attributes = new ArrayList<>();
156166
JavadocLocationManager manager = PDECore.getDefault().getJavadocLocationManager();
157167
String location = manager.getJavadocLocation(model);
158-
if (location == null) {
159-
return new IClasspathAttribute[0];
168+
if (location != null) {
169+
attributes
170+
.add(JavaCore.newClasspathAttribute(IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, location));
171+
}
172+
if (model.getPluginBase().exportsExternalAnnotations()) {
173+
String installLocation = model.getInstallLocation();
174+
attributes.add(
175+
JavaCore.newClasspathAttribute(IClasspathAttribute.EXTERNAL_ANNOTATION_PATH,
176+
installLocation));
160177
}
161-
return new IClasspathAttribute[] {JavaCore.newClasspathAttribute(IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, location)};
178+
return attributes.toArray(IClasspathAttribute[]::new);
162179
}
163180

164181
private static synchronized IAccessRule getDiscouragedRule(IPath path) {

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDEState.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,4 +306,8 @@ public String getBundleSourceEntry(long bundleID) {
306306
return fAuxiliaryState.getBundleSourceEntry(bundleID);
307307
}
308308

309+
public boolean exportsExternalAnnotations(long bundleID) {
310+
return fAuxiliaryState.exportsExternalAnnotations(bundleID);
311+
}
312+
309313
}

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/RequiredPluginsClasspathContainer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ private boolean addPlugin(BundleDescription desc, boolean useInclusions, Map<Bun
347347
}
348348

349349
if (resource != null) {
350-
addProjectEntry(resource.getProject(), rules, entries);
350+
addProjectEntry(resource.getProject(), rules, model.getPluginBase().exportsExternalAnnotations(), entries);
351351
} else {
352352
addExternalPlugin(model, rules, entries);
353353
}

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspacePluginModelManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ public class WorkspacePluginModelManager extends WorkspaceModelManager<IPluginMo
8484
Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT, //
8585
IPDEBuildConstants.ECLIPSE_PLATFORM_FILTER, //
8686
ICoreConstants.ECLIPSE_SYSTEM_BUNDLE, //
87-
ICoreConstants.ECLIPSE_SOURCE_BUNDLE)));
87+
ICoreConstants.ECLIPSE_SOURCE_BUNDLE, //
88+
ICoreConstants.ECLIPSE_EXPORT_EXTERNAL_ANNOTATIONS)));
8889

8990
private final ArrayList<IExtensionDeltaListener> fExtensionListeners = new ArrayList<>();
9091
private ArrayList<ModelChange> fChangedExtensions = null;

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bundle/BundlePlugin.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,9 @@ public boolean hasExtensibleAPI() {
5252
return "true".equals(getValue(ICoreConstants.EXTENSIBLE_API, false)); //$NON-NLS-1$
5353
}
5454

55+
@Override
56+
public boolean exportsExternalAnnotations() {
57+
return "true".equals(getValue(ICoreConstants.ECLIPSE_EXPORT_EXTERNAL_ANNOTATIONS, false)); //$NON-NLS-1$
58+
}
59+
5560
}

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/plugin/PluginBase.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public abstract class PluginBase extends AbstractExtensions implements IPluginBa
5151
private String fVersion;
5252
private boolean fHasBundleStructure;
5353
private String fBundleSourceEntry;
54+
private boolean fExportsExternalAnnotations;
5455

5556
public PluginBase(boolean readOnly) {
5657
super(readOnly);
@@ -123,6 +124,7 @@ void load(BundleDescription bundleDesc, PDEState state) {
123124
fProviderName = state.getProviderName(bundleDesc.getBundleId());
124125
fHasBundleStructure = state.hasBundleStructure(bundleDesc.getBundleId());
125126
fBundleSourceEntry = state.getBundleSourceEntry(bundleDesc.getBundleId());
127+
fExportsExternalAnnotations = state.exportsExternalAnnotations(bundleDesc.getBundleId());
126128
loadRuntime(bundleDesc, state);
127129
loadImports(bundleDesc);
128130
}
@@ -443,4 +445,8 @@ public String getBundleSourceEntry() {
443445
return fBundleSourceEntry;
444446
}
445447

448+
public boolean exportsExternalAnnotations() {
449+
return fExportsExternalAnnotations;
450+
}
451+
446452
}

0 commit comments

Comments
 (0)