Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarsten Pfeiffer2012-11-26 19:51:17 +0000
committerCurtis Windatt2012-11-26 19:51:17 +0000
commit84b471a2fabf3bc475d09adc7a80cf9c0ed001fe (patch)
treec715bfa2234f9c56eb95e9d31471ce6c3683930b
parent64a8cc628523b1b729a8051c175da12e9c5f7421 (diff)
downloadeclipse.pde.ui-84b471a2fabf3bc475d09adc7a80cf9c0ed001fe.tar.gz
eclipse.pde.ui-84b471a2fabf3bc475d09adc7a80cf9c0ed001fe.tar.xz
eclipse.pde.ui-84b471a2fabf3bc475d09adc7a80cf9c0ed001fe.zip
Bug 381975 - [patch] Improved support for import package/export packagev20121126-195117I20121127-0800
(quickfixes)
-rw-r--r--ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/java/FindClassResolutionsOperation.java199
-rw-r--r--ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/java/QuickFixProcessor.java147
2 files changed, 285 insertions, 61 deletions
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/java/FindClassResolutionsOperation.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/java/FindClassResolutionsOperation.java
index 20f7e2c602..b0008add0d 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/java/FindClassResolutionsOperation.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/java/FindClassResolutionsOperation.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008 IBM Corporation and others.
+ * Copyright (c) 2008, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,12 +10,12 @@
*******************************************************************************/
package org.eclipse.pde.internal.ui.correction.java;
-import org.eclipse.osgi.service.resolver.ExportPackageDescription;
-
import java.util.*;
import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.core.search.*;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.osgi.service.resolver.*;
import org.eclipse.pde.core.plugin.IPluginModelBase;
@@ -27,7 +27,6 @@ import org.eclipse.pde.internal.core.PDECore;
* When it is run, it will pass any ExportPackageDescriptions which provide the package to the AbstractClassResolutionCollector.
* The AbstractClassResolutionCollector is responsible for creating the appropriate resolutions.
*
- * @since 3.4
*/
public class FindClassResolutionsOperation implements IRunnableWithProgress {
@@ -39,7 +38,6 @@ public class FindClassResolutionsOperation implements IRunnableWithProgress {
* This class is meant to be sub-classed for use with FindClassResolutionsOperation. The subclass is responsible for creating
* corresponding proposals with the help of JavaResolutionFactory.
*
- * @since 3.4
* @see JavaResolutionFactory
*/
public static abstract class AbstractClassResolutionCollector {
@@ -50,13 +48,36 @@ public class FindClassResolutionsOperation implements IRunnableWithProgress {
*/
abstract public void addResolutionModification(IProject project, ExportPackageDescription desc);
+ /**
+ * Adds an export package proposal. Subclasses should implement the actual adding to the collection.
+ */
+ public Object addExportPackageResolutionModification(IPackageFragment aPackage) {
+ if (aPackage.exists()) {
+ return JavaResolutionFactory.createExportPackageProposal(aPackage.getResource().getProject(), aPackage, JavaResolutionFactory.TYPE_JAVA_COMPLETION, 100);
+ }
+ return null;
+ }
+
+ /**
+ * Adds a require bundle proposal. Subclasses should implement the actual adding to the collection.
+ */
+ public Object addRequireBundleModification(IProject project, ExportPackageDescription desc, int relevance) {
+ return JavaResolutionFactory.createRequireBundleProposal(project, desc, JavaResolutionFactory.TYPE_JAVA_COMPLETION, relevance);
+ }
+
+ /**
+ * Adds a search repositories proposal. Subclasses should implement the actual adding to the collection.
+ */
+ public Object addSearchRepositoriesModification(String packageName) {
+ return JavaResolutionFactory.createSearchRepositoriesProposal(packageName);
+ }
+
/*
* Optimization for case where users is only interested in Import-Package and therefore can quit after first dependency is found
*/
public boolean isDone() {
return false;
}
-
}
/**
@@ -85,12 +106,22 @@ public class FindClassResolutionsOperation implements IRunnableWithProgress {
typeName = null;
}
- if (packageName != null && !isImportedPackage(packageName)) {
- Set<ExportPackageDescription> validPackages = getValidPackages(packageName);
+ Set<IPackageFragment> packagesToExport = new HashSet<IPackageFragment>();
+ Collection<ExportPackageDescription> validPackages = getValidPackages(typeName, packageName, packagesToExport, monitor);
+ if (validPackages != null) {
+
+ if (validPackages.isEmpty()) {
+ for (Iterator<IPackageFragment> it = packagesToExport.iterator(); it.hasNext();) {
+ IPackageFragment packageFragment = it.next();
+ fCollector.addExportPackageResolutionModification(packageFragment);
+ }
+ return;
+ }
+
Iterator<ExportPackageDescription> validPackagesIter = validPackages.iterator();
Set<ExportPackageDescription> visiblePkgs = null;
-
- while (validPackagesIter.hasNext() && !fCollector.isDone()) {
+ boolean allowMultipleFixes = packageName == null;
+ while (validPackagesIter.hasNext() && (allowMultipleFixes || !fCollector.isDone())) {
// since getting visible packages is not very efficient, only do it once and cache result
if (visiblePkgs == null) {
visiblePkgs = getVisiblePackages();
@@ -103,40 +134,156 @@ public class FindClassResolutionsOperation implements IRunnableWithProgress {
// if currentPackage will resolve class and is valid, pass it to collector
fCollector.addResolutionModification(fProject, currentPackage);
}
+
+ // additionally add require bundle proposals
+ for (validPackagesIter = validPackages.iterator(); validPackagesIter.hasNext();) {
+ ExportPackageDescription currentPackage = validPackagesIter.next();
+ fCollector.addRequireBundleModification(fProject, currentPackage, 16);
+ }
}
}
- private boolean isImportedPackage(String packageName) {
- IPluginModelBase model = PluginRegistry.findModel(fProject.getProject());
+ private Collection<ExportPackageDescription> getValidPackages(String typeName, String packageName, Set<IPackageFragment> packagesToExport, IProgressMonitor monitor) {
+ SubMonitor subMonitor = SubMonitor.convert(monitor, 3);
+
+ Collection<ExportPackageDescription> validPackages = null;
+ ImportPackageSpecification[] importPkgs = null;
+ IPluginModelBase model = PluginRegistry.findModel(fProject);
if (model != null && model.getBundleDescription() != null) {
- ImportPackageSpecification[] importPkgs = model.getBundleDescription().getImportPackages();
- for (int i = 0; i < importPkgs.length; i++) {
- if (importPkgs[i].getName().equals(packageName)) {
- return true;
+ importPkgs = model.getBundleDescription().getImportPackages();
+ }
+ subMonitor.worked(1);
+
+ if (importPkgs != null) {
+ if (packageName != null) {
+ if (!isImportedPackage(packageName, importPkgs)) {
+ validPackages = getValidPackages(packageName);
}
+ subMonitor.worked(1);
+ } else {
+ // find possible types in the global packages
+ validPackages = findValidPackagesContainingSimpleType(typeName, importPkgs, packagesToExport, subMonitor.newChild(1));
}
- return false;
}
- // if no BundleDescription, we return true so we don't create any proposals. This is the safe way out if no BundleDescription is available.
- return true;
+ return validPackages;
}
- private static Set<ExportPackageDescription> getValidPackages(String pkgName) {
+ /**
+ * Finds all exported packages containing the simple type aTypeName. The packages
+ * will be filtered from the given packages which are already imported, and all
+ * system packages.
+ *
+ * If no exported package is left, packagesToExport will be filled with those
+ * packages that would have been returned, if they were exported.
+ * @param aTypeName the simple type to search for
+ * @param importPkgs the packages which are already imported
+ * @param packagesToExport return parameter that will be filled with packages to export
+ * if no valid package to import was found
+ * @param monitor
+ * @return the set of packages to import
+ */
+ private Collection<ExportPackageDescription> findValidPackagesContainingSimpleType(String aTypeName, ImportPackageSpecification[] importPkgs, Set<IPackageFragment> packagesToExport, IProgressMonitor monitor) {
+ SubMonitor subMonitor = SubMonitor.convert(monitor);
+
+ IPluginModelBase[] activeModels = PluginRegistry.getActiveModels();
+ Set<IJavaProject> javaProjects = new HashSet<IJavaProject>(activeModels.length * 2);
+
+ for (int i = 0; i < activeModels.length; i++) {
+ IResource resource = activeModels[i].getUnderlyingResource();
+ if (resource != null && resource.isAccessible()) {
+ IJavaProject javaProject = JavaCore.create(resource.getProject());
+ if (javaProject.exists()) {
+ javaProjects.add(javaProject);
+ }
+ }
+ }
+ final IJavaProject currentJavaProject = JavaCore.create(fProject);
+ javaProjects.remove(currentJavaProject); // no need to search in current project itself
+
+ try {
+ IJavaSearchScope searchScope = SearchEngine.createJavaSearchScope(javaProjects.toArray(new IJavaElement[javaProjects.size()]));
+
+ final Map<String, IPackageFragment> packages = new HashMap<String, IPackageFragment>();
+ SearchRequestor requestor = new SearchRequestor() {
+
+ public void acceptSearchMatch(SearchMatch aMatch) throws CoreException {
+ Object element = aMatch.getElement();
+ if (element instanceof IType) {
+ IType type = (IType) element;
+ if (!currentJavaProject.equals(type.getJavaProject())) {
+ IPackageFragment packageFragment = type.getPackageFragment();
+ if (packageFragment.exists()) {
+ packages.put(packageFragment.getElementName(), packageFragment);
+ }
+ }
+ }
+ }
+ };
+
+ SearchPattern typePattern = SearchPattern.createPattern(aTypeName, IJavaSearchConstants.TYPE, IJavaSearchConstants.DECLARATIONS, SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE);
+ new SearchEngine().search(typePattern, new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}, searchScope, requestor, subMonitor.newChild(1));
+
+ if (!packages.isEmpty()) {
+ // transform to ExportPackageDescriptions
+ Map<String, ExportPackageDescription> exportDescriptions = new HashMap<String, ExportPackageDescription>(packages.size());
+
+ // remove system packages if they happen to be included. Adding a system package won't resolve anything, since package package already comes from JRE
+ ExportPackageDescription[] systemPackages = PDECore.getDefault().getModelManager().getState().getState().getSystemPackages();
+ for (int i = 0; i < systemPackages.length; i++) {
+ packages.remove(systemPackages[i].getName());
+ }
+ // also remove packages that are already imported
+ for (int i = 0; i < importPkgs.length; i++) {
+ packages.remove(importPkgs[i].getName());
+ }
+
+ // finally create the list of ExportPackageDescriptions
+ ExportPackageDescription[] knownPackages = PDECore.getDefault().getModelManager().getState().getState().getExportedPackages();
+ for (int i = 0; i < knownPackages.length; i++) {
+ if (packages.containsKey(knownPackages[i].getName())) {
+ exportDescriptions.put(knownPackages[i].getName(), knownPackages[i]);
+ }
+ }
+ if (exportDescriptions.isEmpty()) {
+ // no packages to import found, maybe there are packages to export
+ packagesToExport.addAll(packages.values());
+ }
+
+ return exportDescriptions.values();
+ }
+
+ return Collections.emptySet();
+ } catch (CoreException ex) {
+ // ignore, return an empty set
+ return Collections.emptySet();
+ }
+ }
+
+ private boolean isImportedPackage(String packageName, ImportPackageSpecification[] importPkgs) {
+ for (int i = 0; i < importPkgs.length; i++) {
+ if (importPkgs[i].getName().equals(packageName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static Collection<ExportPackageDescription> getValidPackages(String pkgName) {
ExportPackageDescription[] knownPackages = PDECore.getDefault().getModelManager().getState().getState().getExportedPackages();
- Set<ExportPackageDescription> validPackages = new HashSet<ExportPackageDescription>();
+ Map<String, ExportPackageDescription> validPackages = new HashMap<String, ExportPackageDescription>();
for (int i = 0; i < knownPackages.length; i++) {
if (knownPackages[i].getName().equals(pkgName)) {
- validPackages.add(knownPackages[i]);
+ validPackages.put(knownPackages[i].getName(), knownPackages[i]);
}
}
// remove system packages if they happen to be included. Adding a system package won't resolve anything, since package package already comes from JRE
if (!validPackages.isEmpty()) {
knownPackages = PDECore.getDefault().getModelManager().getState().getState().getSystemPackages();
for (int i = 0; i < knownPackages.length; i++) {
- validPackages.remove(knownPackages[i]);
+ validPackages.remove(knownPackages[i].getName());
}
}
- return validPackages;
+ return validPackages.values();
}
private Set<ExportPackageDescription> getVisiblePackages() {
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/java/QuickFixProcessor.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/java/QuickFixProcessor.java
index 14b226634c..4319e34eb8 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/java/QuickFixProcessor.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/java/QuickFixProcessor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2011 IBM Corporation and others.
+ * Copyright (c) 2007, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -33,13 +33,21 @@ public class QuickFixProcessor implements IQuickFixProcessor {
*/
public IJavaCompletionProposal[] getCorrections(IInvocationContext context, IProblemLocation[] locations) throws CoreException {
ArrayList<Object> results = new ArrayList<Object>();
+
+ AbstractClassResolutionCollector collector = createCollector(results);
+
for (int i = 0; i < locations.length; i++) {
int id = locations[i].getProblemId();
switch (id) {
case IProblem.ForbiddenReference :
- handleAccessRestrictionProblem(context, locations[i], results);
- case IProblem.ImportNotFound :
- handleImportNotFound(context, locations[i], results);
+ handleAccessRestrictionProblem(context, locations[i], collector);
+ case IProblem.ImportNotFound : // fall through
+ case IProblem.UndefinedName : // fall through
+ case IProblem.UndefinedType : // fall through
+ case IProblem.UnresolvedVariable : // fall through
+ case IProblem.MissingTypeInMethod : // fall through
+ case IProblem.MissingTypeInConstructor :
+ handleImportNotFound(context, locations[i], collector);
}
}
@@ -49,13 +57,23 @@ public class QuickFixProcessor implements IQuickFixProcessor {
/*
* Adds IJavaCompletionProposals for a ForbiddenReference marker
*/
- private void handleAccessRestrictionProblem(IInvocationContext context, IProblemLocation location, Collection<Object> results) {
+ private void handleAccessRestrictionProblem(IInvocationContext context, IProblemLocation location, AbstractClassResolutionCollector collector) {
IBinding referencedElement = null;
ASTNode node = location.getCoveredNode(context.getASTRoot());
if (node instanceof Type) {
referencedElement = ((Type) node).resolveBinding();
} else if (node instanceof Name) {
referencedElement = ((Name) node).resolveBinding();
+ } else if (node instanceof MethodInvocation) {
+ IMethodBinding tempMethod = ((MethodInvocation) node).resolveMethodBinding();
+ if (tempMethod != null) {
+ referencedElement = tempMethod.getDeclaringClass();
+ }
+ } else if (node instanceof FieldAccess) {
+ IVariableBinding tempVariable = ((FieldAccess) node).resolveFieldBinding();
+ if (tempVariable != null) {
+ referencedElement = tempVariable.getDeclaringClass();
+ }
}
if (referencedElement != null) {
// get the project that contains the reference element
@@ -78,19 +96,17 @@ public class QuickFixProcessor implements IQuickFixProcessor {
if (exportPackages[i].getName().equals(referencedPackage.getElementName())) {
packageExported = true;
// check to see if access restriction is caused by Import-Package
- handleAccessRestrictionByImportPackage(context.getCompilationUnit().getJavaProject().getProject(), exportPackages[i], results);
+ handleAccessRestrictionByImportPackage(context.getCompilationUnit().getJavaProject().getProject(), exportPackages[i], collector);
break;
}
}
// if the package is not exported, add the quickfix
if (!packageExported) {
- Object proposal = JavaResolutionFactory.createExportPackageProposal(referencedJavaProject.getProject(), referencedPackage, JavaResolutionFactory.TYPE_JAVA_COMPLETION, 100);
- if (proposal != null)
- results.add(proposal);
+ collector.addExportPackageResolutionModification(referencedPackage);
}
}
} else {
- handleAccessRestrictionByImportPackage(referencedPackage, results);
+ handleAccessRestrictionByImportPackage(referencedPackage, collector);
}
}
}
@@ -99,31 +115,35 @@ public class QuickFixProcessor implements IQuickFixProcessor {
/*
* Adds IJavaCompletionProposals for a Require-Bundle if user is using an Import-Package from the bundle
*/
- private void handleAccessRestrictionByImportPackage(IPackageFragment fragment, Collection<Object> results) {
+ private void handleAccessRestrictionByImportPackage(IPackageFragment fragment, AbstractClassResolutionCollector collector) {
HashSet<String> set = new HashSet<String>();
IProject project = fragment.getJavaProject().getProject();
String pkgName = fragment.getElementName();
IPluginModelBase base = PluginRegistry.findModel(project);
ExportPackageDescription[] descs = base.getBundleDescription().getResolvedImports();
+ ExportPackageDescription foundExportPackage = null;
for (int i = 0; i < descs.length; i++) {
BundleDescription exporter = descs[i].getExporter();
if (set.add(exporter.getSymbolicName())) {
ExportPackageDescription[] exportedPkgs = exporter.getExportPackages();
for (int j = 0; j < exportedPkgs.length; j++) {
if (exportedPkgs[j].getName().equals(pkgName)) {
- Object proposal = JavaResolutionFactory.createRequireBundleProposal(project, exportedPkgs[j], JavaResolutionFactory.TYPE_JAVA_COMPLETION, 16);
- if (proposal != null)
- results.add(proposal);
+ foundExportPackage = exportedPkgs[j]; // any one is fine, so simply remember the last one
+ collector.addRequireBundleModification(project, exportedPkgs[j], 16);
+ break;
}
}
}
}
+ if (foundExportPackage != null) {
+ collector.addResolutionModification(project, foundExportPackage);
+ }
}
/*
* Adds IJavaCompletionProposal for a Require-Bundle if user is using an Import-Package from the (workspace) bundle
*/
- private void handleAccessRestrictionByImportPackage(IProject currentProject, ExportPackageDescription desc, Collection<Object> results) {
+ private void handleAccessRestrictionByImportPackage(IProject currentProject, ExportPackageDescription desc, AbstractClassResolutionCollector collector) {
BundleDescription supplier = desc.getSupplier();
if (supplier != null) {
String supplierId = supplier.getSymbolicName();
@@ -139,9 +159,22 @@ public class QuickFixProcessor implements IQuickFixProcessor {
}
}
if (!supplierImported) {
- Object proposal = JavaResolutionFactory.createRequireBundleProposal(currentProject, desc, JavaResolutionFactory.TYPE_JAVA_COMPLETION, 16);
- if (proposal != null)
- results.add(proposal);
+ // add import-package, if possible
+ boolean proposeImportPackage = true;
+
+ ImportPackageSpecification[] importPackages = bd.getImportPackages();
+ for (int i = 0; i < importPackages.length; i++) {
+ if (desc.getName().equals(importPackages[i].getName())) {
+ // already imported, try require-bundle
+ proposeImportPackage = false;
+ break;
+ }
+ }
+
+ if (proposeImportPackage) {
+ collector.addResolutionModification(currentProject, desc); // relevance should actually be 16...
+ }
+ collector.addRequireBundleModification(currentProject, desc, 16);
}
}
}
@@ -149,7 +182,7 @@ public class QuickFixProcessor implements IQuickFixProcessor {
/*
* Adds IJavaCompletionProposals for a ImportNotFound problem
*/
- private void handleImportNotFound(IInvocationContext context, IProblemLocation problemLocation, final Collection<Object> result) {
+ private void handleImportNotFound(IInvocationContext context, IProblemLocation problemLocation, final AbstractClassResolutionCollector collector) {
CompilationUnit cu = context.getASTRoot();
ASTNode selectedNode = problemLocation.getCoveringNode(cu);
if (selectedNode != null) {
@@ -157,29 +190,33 @@ public class QuickFixProcessor implements IQuickFixProcessor {
String className = null;
String packageName = null;
if (node == null) {
- if (selectedNode instanceof SimpleName) {
- ITypeBinding typeBinding = ((SimpleName) selectedNode).resolveTypeBinding();
- className = typeBinding.getBinaryName();
- packageName = typeBinding.getPackage().getName();
+ if (selectedNode instanceof Name) {
+ ITypeBinding typeBinding = ((Name) selectedNode).resolveTypeBinding();
+ if (typeBinding != null) {
+ className = typeBinding.getBinaryName();
+ packageName = typeBinding.getPackage().getName();
+ }
+ if (className == null && selectedNode instanceof SimpleName) { // fallback if the type cannot be resolved
+ className = ((SimpleName) selectedNode).getIdentifier();
+ }
}
} else if (node instanceof ImportDeclaration) {
- // Find import declaration which is the problem
- className = ((ImportDeclaration) node).getName().getFullyQualifiedName();
-
+ // Find the full package name, strip off the class name or on demand qualifier '.*';
+ packageName = ((ImportDeclaration) node).getName().getFullyQualifiedName();
+ if (!((ImportDeclaration) node).isOnDemand()) {
+ int lastPeriod = packageName.lastIndexOf('.'); // if there is no period assume we are importing a single name package
+ packageName = packageName.substring(0, lastPeriod >= 0 ? lastPeriod : packageName.length());
+ }
// always add the search repositories proposal
- int lastPeriod = className.lastIndexOf('.'); // if there is no period assume we are importing a single name package
- packageName = className.substring(0, lastPeriod >= 0 ? lastPeriod : className.length());
- result.add(JavaResolutionFactory.createSearchRepositoriesProposal(packageName));
+ collector.addSearchRepositoriesModification(packageName);
}
- if (className != null && packageName != null) {
+ if (className != null) {
IProject project = cu.getJavaElement().getJavaProject().getProject();
// only try to find proposals on Plug-in Projects
if (!WorkspaceModelManager.isPluginProject(project))
return;
- // create a collector that will create IJavaCompletionProposals and load them into 'result'
- AbstractClassResolutionCollector collector = createCollector(result);
IRunnableWithProgress findOperation = new FindClassResolutionsOperation(project, className, collector);
try {
findOperation.run(new NullProgressMonitor());
@@ -191,22 +228,57 @@ public class QuickFixProcessor implements IQuickFixProcessor {
}
/*
- * Custom AbstractClassResolutionCollector which will only add one IJavaCompletionProposal for adding an Import-Package entry
+ * Custom AbstractClassResolutionCollector which will only add one IJavaCompletionProposal for adding an Import-Package or Export-Package entry
*/
private AbstractClassResolutionCollector createCollector(final Collection<Object> result) {
return new AbstractClassResolutionCollector() {
+ // the list of package names for which an import package resolution has been created
+ private Set<String> addedImportPackageResolutions = new HashSet<String>();
+
boolean isDone = false;
public void addResolutionModification(IProject project, ExportPackageDescription desc) {
+ // guard against multiple import package resolutions for the same package
+ if (addedImportPackageResolutions.contains(desc.getName())) {
+ return;
+ }
+
Object proposal = JavaResolutionFactory.createImportPackageProposal(project, desc, JavaResolutionFactory.TYPE_JAVA_COMPLETION, 17);
if (proposal != null) {
+ addedImportPackageResolutions.add(desc.getName());
result.add(proposal);
isDone = true;
}
}
- // we want to finish after we add the first Import-Package Change
+ public Object addExportPackageResolutionModification(IPackageFragment aPackage) {
+ Object proposal = super.addExportPackageResolutionModification(aPackage);
+ if (proposal != null) {
+ result.add(proposal);
+ }
+ return proposal;
+ }
+
+ @Override
+ public Object addRequireBundleModification(IProject project, ExportPackageDescription desc, int relevance) {
+ Object proposal = super.addRequireBundleModification(project, desc, relevance);
+ if (proposal != null) {
+ result.add(proposal);
+ }
+ return proposal;
+ }
+
+ @Override
+ public Object addSearchRepositoriesModification(String packageName) {
+ Object proposal = super.addSearchRepositoriesModification(packageName);
+ if (proposal != null) {
+ result.add(proposal);
+ }
+ return proposal;
+ }
+
+ // we want to finish after we add the first Import- or Export-Package Change
public boolean isDone() {
return isDone;
}
@@ -229,7 +301,12 @@ public class QuickFixProcessor implements IQuickFixProcessor {
public boolean hasCorrections(ICompilationUnit unit, int problemId) {
switch (problemId) {
case IProblem.ForbiddenReference :
- case IProblem.ImportNotFound :
+ case IProblem.UndefinedName : // fall through
+ case IProblem.ImportNotFound : // fall through
+ case IProblem.UndefinedType : // fall through
+ case IProblem.UnresolvedVariable : // fall through
+ case IProblem.MissingTypeInMethod : // fall through
+ case IProblem.MissingTypeInConstructor :
IJavaElement parent = unit.getParent();
if (parent != null) {
IJavaProject project = parent.getJavaProject();

Back to the top