View | Details | Raw Unified | Return to bug 233643 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/pde/api/tools/internal/ProjectApiDescription.java (-2 / +76 lines)
Lines 11-16 Link Here
11
package org.eclipse.pde.api.tools.internal;
11
package org.eclipse.pde.api.tools.internal;
12
12
13
import java.util.ArrayList;
13
import java.util.ArrayList;
14
import java.util.Collections;
14
import java.util.HashMap;
15
import java.util.HashMap;
15
import java.util.HashSet;
16
import java.util.HashSet;
16
import java.util.Iterator;
17
import java.util.Iterator;
Lines 223-229 Link Here
223
						long stamp = resource.getModificationStamp();
224
						long stamp = resource.getModificationStamp();
224
						if (stamp != fTimeStamp) {
225
						if (stamp != fTimeStamp) {
225
							modified();
226
							modified();
227
							Set prevMementos = collectChildrenMementos();
226
							children.clear();
228
							children.clear();
229
							int previousRestrictions = restrictions;
227
							restrictions = RestrictionModifiers.NO_RESTRICTIONS;
230
							restrictions = RestrictionModifiers.NO_RESTRICTIONS;
228
							fTimeStamp = resource.getModificationStamp();
231
							fTimeStamp = resource.getModificationStamp();
229
							try {
232
							try {
Lines 232-237 Link Here
232
							} catch (CoreException e) {
235
							} catch (CoreException e) {
233
								ApiPlugin.log(e.getStatus());
236
								ApiPlugin.log(e.getStatus());
234
							}
237
							}
238
							descriptionChanged = previousRestrictions != restrictions;
239
							// check if any children restrictions changed
240
							if (!descriptionChanged) {
241
								Set currMementos = collectChildrenMementos();
242
								descriptionChanged = !currMementos.equals(prevMementos);
243
							}
235
						}
244
						}
236
					} else {
245
					} else {
237
						// element has been removed
246
						// element has been removed
Lines 248-253 Link Here
248
			return this;
257
			return this;
249
		}
258
		}
250
		
259
		
260
		/**
261
		 * Returns a set of restriction mementos for all the children of this type node.
262
		 * 
263
		 * @return restriction mementos for all the children of this type node
264
		 */
265
		private Set collectChildrenMementos() {
266
			if (children.size() == 0) {
267
				return Collections.EMPTY_SET;
268
			}
269
			final Set mementos = new HashSet(children.size()*2);
270
			visitChildren(
271
				new ApiDescriptionVisitor() {
272
					public boolean visitElement(IElementDescriptor element, IApiAnnotations description) {
273
						if (description.getRestrictions() != RestrictionModifiers.NO_RESTRICTIONS) {
274
							mementos.add(new RestrictionMemento(element, description.getRestrictions()));
275
						}
276
						return true;
277
					}
278
				},
279
				children);
280
			return mementos;
281
		}
282
		
251
		/* (non-Javadoc)
283
		/* (non-Javadoc)
252
		 * @see org.eclipse.pde.api.tools.internal.ApiDescription.ManifestNode#persistXML(org.w3c.dom.Document, org.w3c.dom.Element, java.lang.String)
284
		 * @see org.eclipse.pde.api.tools.internal.ApiDescription.ManifestNode#persistXML(org.w3c.dom.Document, org.w3c.dom.Element, java.lang.String)
253
		 */
285
		 */
Lines 278-283 Link Here
278
	}
310
	}
279
	
311
	
280
	/**
312
	/**
313
	 * Used to test if a node's restrictions have changed
314
	 */
315
	class RestrictionMemento {
316
		private IElementDescriptor fTheElement;
317
		private int fTheRestrictions;
318
		/**
319
		 * Constructs a new node memento for the given element and restrictions.
320
		 * 
321
		 * @param element
322
		 * @param restrictions
323
		 */
324
		public RestrictionMemento(IElementDescriptor element, int restrictions) {
325
			fTheElement = element;
326
			fTheRestrictions = restrictions;
327
		}
328
		/* (non-Javadoc)
329
		 * @see java.lang.Object#equals(java.lang.Object)
330
		 */
331
		public boolean equals(Object obj) {
332
			if (obj instanceof RestrictionMemento) {
333
				RestrictionMemento memento = (RestrictionMemento) obj;
334
				return memento.fTheElement.equals(fTheElement) && memento.fTheRestrictions == fTheRestrictions;
335
			}
336
			return false;
337
		}
338
		/* (non-Javadoc)
339
		 * @see java.lang.Object#hashCode()
340
		 */
341
		public int hashCode() {
342
			return fTheElement.hashCode() + fTheRestrictions;
343
		}
344
	}
345
	
346
	/**
281
	 * Constructs a new API description for the given Java project.
347
	 * Constructs a new API description for the given Java project.
282
	 * 
348
	 * 
283
	 * @param component
349
	 * @param component
Lines 365-372 Link Here
365
	 * @see org.eclipse.pde.api.tools.internal.ApiDescription#isInsertOnResolve(org.eclipse.pde.api.tools.internal.provisional.descriptors.IElementDescriptor)
431
	 * @see org.eclipse.pde.api.tools.internal.ApiDescription#isInsertOnResolve(org.eclipse.pde.api.tools.internal.provisional.descriptors.IElementDescriptor)
366
	 */
432
	 */
367
	protected boolean isInsertOnResolve(IElementDescriptor elementDescriptor) {
433
	protected boolean isInsertOnResolve(IElementDescriptor elementDescriptor) {
368
		return elementDescriptor.getElementType() != IElementDescriptor.T_METHOD ||
434
		switch (elementDescriptor.getElementType()) {
369
				elementDescriptor.getElementType() != IElementDescriptor.T_FIELD;
435
			case IElementDescriptor.T_METHOD:
436
			case IElementDescriptor.T_FIELD:
437
				return false;
438
			case IElementDescriptor.T_REFERENCE_TYPE:
439
				// no need to insert member types
440
				return ((IReferenceTypeDescriptor) elementDescriptor).getEnclosingType() == null;
441
			default:
442
				return true;
443
		}
370
	}
444
	}
371
	
445
	
372
	/* (non-Javadoc)
446
	/* (non-Javadoc)
(-)src/org/eclipse/pde/api/tools/internal/ApiDescription.java (-2 / +3 lines)
Lines 74-79 Link Here
74
	class ManifestNode implements Comparable {
74
	class ManifestNode implements Comparable {
75
		protected IElementDescriptor element = null;
75
		protected IElementDescriptor element = null;
76
		protected int visibility, restrictions;
76
		protected int visibility, restrictions;
77
		protected boolean descriptionChanged = false;
77
		protected ManifestNode parent = null;
78
		protected ManifestNode parent = null;
78
		protected HashMap children = new HashMap(1);
79
		protected HashMap children = new HashMap(1);
79
		
80
		
Lines 270-276 Link Here
270
				tmp = null;
271
				tmp = null;
271
			}
272
			}
272
		}
273
		}
273
		IApiAnnotations desc = new ApiAnnotations(vis, node.restrictions);
274
		IApiAnnotations desc = new ApiAnnotations(vis, node.restrictions, node.descriptionChanged);
274
		boolean visitChildren = visitor.visitElement(node.element, desc);
275
		boolean visitChildren = visitor.visitElement(node.element, desc);
275
		if (visitChildren && !node.children.isEmpty()) {
276
		if (visitChildren && !node.children.isEmpty()) {
276
			visitChildren(visitor, node.children);
277
			visitChildren(visitor, node.children);
Lines 345-351 Link Here
345
		if (node.element.equals(element)) {
346
		if (node.element.equals(element)) {
346
			res = node.restrictions;
347
			res = node.restrictions;
347
		}
348
		}
348
		return new ApiAnnotations(vis, res);
349
		return new ApiAnnotations(vis, res, node.descriptionChanged);
349
	}
350
	}
350
	
351
	
351
	/**
352
	/**
(-)src/org/eclipse/pde/api/tools/internal/ApiAnnotations.java (-1 / +10 lines)
Lines 22-27 Link Here
22
public class ApiAnnotations implements IApiAnnotations {
22
public class ApiAnnotations implements IApiAnnotations {
23
23
24
	private int fVisibility, fRestrictions;
24
	private int fVisibility, fRestrictions;
25
	private boolean fHasChanged = false;
25
	
26
	
26
	/**
27
	/**
27
	 * Constructs API annotations.
28
	 * Constructs API annotations.
Lines 29-37 Link Here
29
	 * @param visibility the visibility of an element. See {@linkplain VisibilityModifiers} for visibility constants
30
	 * @param visibility the visibility of an element. See {@linkplain VisibilityModifiers} for visibility constants
30
	 * @param restrictions the restrictions for an element. See {@linkplain RestrictionModifiers} for restriction kind constants
31
	 * @param restrictions the restrictions for an element. See {@linkplain RestrictionModifiers} for restriction kind constants
31
	 */
32
	 */
32
	public ApiAnnotations(int visibility, int restrictions) {
33
	public ApiAnnotations(int visibility, int restrictions, boolean hasChanged) {
33
		fVisibility = visibility;
34
		fVisibility = visibility;
34
		fRestrictions = restrictions;
35
		fRestrictions = restrictions;
36
		fHasChanged = hasChanged;
35
	}
37
	}
36
	
38
	
37
	/* (non-Javadoc)
39
	/* (non-Javadoc)
Lines 118-122 Link Here
118
	public int hashCode() {
120
	public int hashCode() {
119
		return fRestrictions + fVisibility;
121
		return fRestrictions + fVisibility;
120
	}
122
	}
123
124
	/* (non-Javadoc)
125
	 * @see org.eclipse.pde.api.tools.internal.provisional.IApiAnnotations#hasChanged()
126
	 */
127
	public boolean hasChanged() {
128
		return fHasChanged;
129
	}
121
	
130
	
122
}
131
}
(-)src/org/eclipse/pde/api/tools/internal/provisional/IApiAnnotations.java (+7 lines)
Lines 33-36 Link Here
33
	 */
33
	 */
34
	public int getRestrictions();
34
	public int getRestrictions();
35
	
35
	
36
	/**
37
	 * Returns whether this description has changed 
38
	 * 
39
	 * @return
40
	 */
41
	public boolean hasChanged();
42
	
36
}
43
}
(-)src/org/eclipse/pde/api/tools/internal/builder/ApiAnalysisBuilder.java (-52 / +57 lines)
Lines 64-70 Link Here
64
import org.eclipse.pde.api.tools.internal.IApiCoreConstants;
64
import org.eclipse.pde.api.tools.internal.IApiCoreConstants;
65
import org.eclipse.pde.api.tools.internal.problems.ApiProblemFactory;
65
import org.eclipse.pde.api.tools.internal.problems.ApiProblemFactory;
66
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
66
import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
67
import org.eclipse.pde.api.tools.internal.provisional.Factory;
68
import org.eclipse.pde.api.tools.internal.provisional.IApiAnnotations;
67
import org.eclipse.pde.api.tools.internal.provisional.IApiComponent;
69
import org.eclipse.pde.api.tools.internal.provisional.IApiComponent;
70
import org.eclipse.pde.api.tools.internal.provisional.IApiDescription;
68
import org.eclipse.pde.api.tools.internal.provisional.IApiMarkerConstants;
71
import org.eclipse.pde.api.tools.internal.provisional.IApiMarkerConstants;
69
import org.eclipse.pde.api.tools.internal.provisional.IApiProfile;
72
import org.eclipse.pde.api.tools.internal.provisional.IApiProfile;
70
import org.eclipse.pde.api.tools.internal.provisional.builder.IApiAnalyzer;
73
import org.eclipse.pde.api.tools.internal.provisional.builder.IApiAnalyzer;
Lines 165-170 Link Here
165
	private IProject fCurrentProject = null;
168
	private IProject fCurrentProject = null;
166
	
169
	
167
	/**
170
	/**
171
	 * Corresponding API component being analyzed
172
	 */
173
	private IApiComponent fCurrentApiComponent = null;
174
	
175
	/**
168
	 * The API analyzer for this builder
176
	 * The API analyzer for this builder
169
	 */
177
	 */
170
	private IApiAnalyzer fAnalyzer = null;
178
	private IApiAnalyzer fAnalyzer = null;
Lines 272-277 Link Here
272
		if (memberIndex > 0) {
280
		if (memberIndex > 0) {
273
			typeName = typeName.substring(0, memberIndex);
281
			typeName = typeName.substring(0, memberIndex);
274
		}
282
		}
283
		if (fCurrentApiComponent != null) {
284
			try {
285
				IApiDescription description = fCurrentApiComponent.getApiDescription();
286
				IApiAnnotations annotations = description.resolveAnnotations(Factory.packageDescriptor(packageName.replace('/', '.')).getType(typeName));
287
				if (annotations != null && !annotations.hasChanged()) {
288
					return;
289
				}
290
			} catch (CoreException e) {
291
				ApiPlugin.log(e.getStatus());
292
			}
293
		}
275
		if (fTypes.add(typeName) && fPackages.add(packageName) && DEBUG) {
294
		if (fTypes.add(typeName) && fPackages.add(packageName) && DEBUG) {
276
			System.out.println("  will look for dependents of " + typeName + " in " + packageName); //$NON-NLS-1$ //$NON-NLS-2$
295
			System.out.println("  will look for dependents of " + typeName + " in " + packageName); //$NON-NLS-1$ //$NON-NLS-2$
277
		}
296
		}
Lines 283-288 Link Here
283
	protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
302
	protected IProject[] build(int kind, Map args, IProgressMonitor monitor) throws CoreException {
284
		fCurrentProject = getProject();
303
		fCurrentProject = getProject();
285
		fAnalyzer = getAnalyzer();
304
		fAnalyzer = getAnalyzer();
305
		fCurrentApiComponent = null;
286
		if (fCurrentProject == null || !fCurrentProject.isAccessible() || !fCurrentProject.hasNature(ApiPlugin.NATURE_ID) ||
306
		if (fCurrentProject == null || !fCurrentProject.isAccessible() || !fCurrentProject.hasNature(ApiPlugin.NATURE_ID) ||
287
				hasBeenBuilt(fCurrentProject)) {
307
				hasBeenBuilt(fCurrentProject)) {
288
			return new IProject[0];
308
			return new IProject[0];
Lines 291-298 Link Here
291
			System.out.println("\nStarting build of " + fCurrentProject.getName() + " @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$ //$NON-NLS-2$
311
			System.out.println("\nStarting build of " + fCurrentProject.getName() + " @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$ //$NON-NLS-2$
292
		}
312
		}
293
		updateMonitor(monitor, 0);
313
		updateMonitor(monitor, 0);
294
		SubMonitor localMonitor = SubMonitor.convert(monitor, BuilderMessages.api_analysis_builder, 2);
314
		SubMonitor localMonitor = SubMonitor.convert(monitor, BuilderMessages.api_analysis_builder, 3);
295
		IProject[] projects = getRequiredProjects(true);
315
		IProject[] projects = getRequiredProjects(true);
316
		localMonitor.subTask(BuilderMessages.building_workspace_profile);
317
		IPluginModelBase currentModel = getCurrentModel();
318
		IApiProfile wsprofile = null;
319
		if (currentModel != null) {
320
			wsprofile = getWorkspaceProfile();
321
			if (wsprofile != null) {
322
				String id = currentModel.getBundleDescription().getSymbolicName();
323
				fCurrentApiComponent = wsprofile.getApiComponent(id);
324
			} else {
325
				if (DEBUG) {
326
					System.err.println("Could not retrieve a workspace profile"); //$NON-NLS-1$
327
				}
328
			}
329
		}
330
		updateMonitor(localMonitor, 1);
296
		try {
331
		try {
297
			switch(kind) {
332
			switch(kind) {
298
				case FULL_BUILD : {
333
				case FULL_BUILD : {
Lines 342-347 Link Here
342
			}
377
			}
343
			updateMonitor(monitor, 0);
378
			updateMonitor(monitor, 0);
344
		} finally {
379
		} finally {
380
			fCurrentApiComponent = null;
345
			fTypes.clear();
381
			fTypes.clear();
346
			fPackages.clear();
382
			fPackages.clear();
347
			fTypesToCheck.clear();
383
			fTypesToCheck.clear();
Lines 356-361 Link Here
356
				saveBuiltState(fCurrentProject, fBuildState);
392
				saveBuiltState(fCurrentProject, fBuildState);
357
				fBuildState = null;
393
				fBuildState = null;
358
			}
394
			}
395
			if (wsprofile != null) {
396
				wsprofile.close();
397
			}
359
		}
398
		}
360
		if (DEBUG) {
399
		if (DEBUG) {
361
			System.out.println("Finished build of " + fCurrentProject.getName() + " @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$ //$NON-NLS-2$
400
			System.out.println("Finished build of " + fCurrentProject.getName() + " @ " + new Date(System.currentTimeMillis())); //$NON-NLS-1$ //$NON-NLS-2$
Lines 368-408 Link Here
368
	 * @param monitor
407
	 * @param monitor
369
	 */
408
	 */
370
	private void buildAll(IProgressMonitor monitor) throws CoreException {
409
	private void buildAll(IProgressMonitor monitor) throws CoreException {
371
		IApiProfile wsprofile = null;
372
		try {
410
		try {
373
			clearLastState();
411
			clearLastState();
374
			fBuildState = new BuildState();
412
			fBuildState = new BuildState();
375
			SubMonitor localMonitor = SubMonitor.convert(monitor, BuilderMessages.api_analysis_on_0, 4);
413
			SubMonitor localMonitor = SubMonitor.convert(monitor, BuilderMessages.api_analysis_on_0, 3);
376
			localMonitor.subTask(NLS.bind(BuilderMessages.ApiAnalysisBuilder_initializing_analyzer, fCurrentProject.getName()));
414
			localMonitor.subTask(NLS.bind(BuilderMessages.ApiAnalysisBuilder_initializing_analyzer, fCurrentProject.getName()));
377
			IApiProfile profile = ApiPlugin.getDefault().getApiProfileManager().getDefaultApiProfile();
415
			IApiProfile profile = ApiPlugin.getDefault().getApiProfileManager().getDefaultApiProfile();
378
			cleanupMarkers(fCurrentProject);
416
			cleanupMarkers(fCurrentProject);
379
			cleanupUnsupportedTagMarkers(fCurrentProject);
417
			cleanupUnsupportedTagMarkers(fCurrentProject);
380
			IPluginModelBase currentModel = getCurrentModel();
418
			// Compatibility checks
381
			if (currentModel != null) {
419
			if(fCurrentApiComponent != null) {
382
				localMonitor.subTask(BuilderMessages.building_workspace_profile);
420
				fAnalyzer.analyzeComponent(fBuildState, null, profile, fCurrentApiComponent, null, null, localMonitor.newChild(1));
383
				wsprofile = getWorkspaceProfile();
421
				updateMonitor(localMonitor, 1);
422
				createMarkers();
384
				updateMonitor(localMonitor, 1);
423
				updateMonitor(localMonitor, 1);
385
				if (wsprofile == null) {
386
					if (DEBUG) {
387
						System.err.println("Could not retrieve a workspace profile"); //$NON-NLS-1$
388
					}
389
					return;
390
				}
391
				String id = currentModel.getBundleDescription().getSymbolicName();
392
				// Compatibility checks
393
				IApiComponent apiComponent = wsprofile.getApiComponent(id);
394
				if(apiComponent != null) {
395
					fAnalyzer.analyzeComponent(fBuildState, null, profile, apiComponent, null, null, localMonitor.newChild(1));
396
					updateMonitor(localMonitor, 1);
397
					createMarkers();
398
					updateMonitor(localMonitor, 1);
399
				}
400
			}
424
			}
401
		}
425
		}
402
		finally {
426
		finally {
403
			if(wsprofile != null) {
404
				wsprofile.close();
405
			}
406
			if(monitor != null) {
427
			if(monitor != null) {
407
				monitor.done();
428
				monitor.done();
408
			}
429
			}
Lines 581-587 Link Here
581
	 * @param monitor
602
	 * @param monitor
582
	 */
603
	 */
583
	private void build(final State state, IProgressMonitor monitor) throws CoreException {
604
	private void build(final State state, IProgressMonitor monitor) throws CoreException {
584
		IApiProfile wsprofile = null;
585
		try {
605
		try {
586
			clearLastState(); // so if the build fails, a full build will be triggered
606
			clearLastState(); // so if the build fails, a full build will be triggered
587
			SubMonitor localMonitor = SubMonitor.convert(monitor, BuilderMessages.api_analysis_on_0, 6);
607
			SubMonitor localMonitor = SubMonitor.convert(monitor, BuilderMessages.api_analysis_on_0, 6);
Lines 590-625 Link Here
590
			collectAffectedSourceFiles(state);
610
			collectAffectedSourceFiles(state);
591
			updateMonitor(localMonitor, 1);
611
			updateMonitor(localMonitor, 1);
592
			if (fTypesToCheck.size() != 0) {
612
			if (fTypesToCheck.size() != 0) {
593
				IPluginModelBase currentModel = getCurrentModel();
613
				if(fCurrentApiComponent == null) {
594
				if (currentModel != null) {
614
					return;
595
					wsprofile = getWorkspaceProfile();
596
					if (wsprofile == null) {
597
						if (DEBUG) {
598
							System.err.println("Could not retrieve a workspace profile"); //$NON-NLS-1$
599
						}
600
						return;
601
					}
602
					String id = currentModel.getBundleDescription().getSymbolicName();
603
					IApiComponent apiComponent = wsprofile.getApiComponent(id);
604
					if(apiComponent == null) {
605
						return;
606
					}
607
					List tnames = new ArrayList(fTypesToCheck.size()),
608
						 cnames = new ArrayList(fChangedTypes.size());
609
					collectAllQualifiedNames(fTypesToCheck, fChangedTypes, tnames, cnames, localMonitor.newChild(1));
610
					updateMonitor(localMonitor, 1);
611
					IApiProfile profile = ApiPlugin.getDefault().getApiProfileManager().getDefaultApiProfile();
612
					fAnalyzer.analyzeComponent(fBuildState, null, profile, apiComponent, (String[])tnames.toArray(new String[tnames.size()]), (String[])cnames.toArray(new String[cnames.size()]), localMonitor.newChild(1));
613
					updateMonitor(localMonitor, 1);
614
					createMarkers();
615
					updateMonitor(localMonitor, 1);
616
				}
615
				}
616
				List tnames = new ArrayList(fTypesToCheck.size()),
617
					 cnames = new ArrayList(fChangedTypes.size());
618
				collectAllQualifiedNames(fTypesToCheck, fChangedTypes, tnames, cnames, localMonitor.newChild(1));
619
				updateMonitor(localMonitor, 1);
620
				IApiProfile profile = ApiPlugin.getDefault().getApiProfileManager().getDefaultApiProfile();
621
				fAnalyzer.analyzeComponent(fBuildState, null, profile, fCurrentApiComponent, (String[])tnames.toArray(new String[tnames.size()]), (String[])cnames.toArray(new String[cnames.size()]), localMonitor.newChild(1));
622
				updateMonitor(localMonitor, 1);
623
				createMarkers();
624
				updateMonitor(localMonitor, 1);
617
			}
625
			}
618
		}
626
		}
619
		finally {
627
		finally {
620
			if(wsprofile != null) {
621
				wsprofile.close();
622
			}
623
			if(monitor != null) {
628
			if(monitor != null) {
624
				monitor.done();
629
				monitor.done();
625
			}
630
			}

Return to bug 233643