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 d6b77bf316..6a15bdf3c5 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, 2019 IBM Corporation and others. + * Copyright (c) 2008, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -41,6 +41,7 @@ import org.eclipse.jdt.core.search.SearchParticipant; import org.eclipse.jdt.core.search.SearchPattern; import org.eclipse.jdt.core.search.SearchRequestor; +import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.osgi.service.resolver.BundleDescription; import org.eclipse.osgi.service.resolver.BundleSpecification; @@ -59,9 +60,9 @@ */ public class FindClassResolutionsOperation implements IRunnableWithProgress { - String fClassName = null; - IProject fProject = null; - AbstractClassResolutionCollector fCollector = null; + private String fClassName = null; + private IProject fProject = null; + private AbstractClassResolutionCollector fCollector = null; private CompilationUnit fCompilationUnit; /** @@ -78,7 +79,9 @@ public static abstract class AbstractClassResolutionCollector { * Import-Package. The proposals can be created with the help of the * JavaResolutionFactory */ - abstract public void addResolutionModification(IProject project, ExportPackageDescription desc); + public void addResolutionModification(IProject project, ExportPackageDescription desc) { + addResolutionModification(project, desc, null, ""); //$NON-NLS-1$ + } /** * This method is meant to be sub-classed. The subclass should decide if @@ -93,11 +96,15 @@ abstract public void addResolutionModification(IProject project, ExportPackageDe * Adds an export package proposal. Subclasses should implement the * actual adding to the collection. */ - public Object addExportPackageResolutionModification(IPackageFragment aPackage) { + public IJavaCompletionProposal addExportPackageResolutionModification(IPackageFragment aPackage) { if (aPackage.exists()) { + // TODO: try (and check null inbetween) + // aPackage.getJavaProject().getProject(); IResource packageResource = aPackage.getResource(); if (packageResource != null) { - return JavaResolutionFactory.createExportPackageProposal(packageResource.getProject(), aPackage, JavaResolutionFactory.TYPE_JAVA_COMPLETION, 100); + IProject project = packageResource.getProject(); + var change = JavaResolutionFactory.createExportPackageChange(project, aPackage); + return JavaResolutionFactory.createJavaCompletionProposal(change, 100); } } return null; @@ -114,13 +121,16 @@ public Object addRequireBundleModification(IProject project, ExportPackageDescri * Adds a require bundle proposal. Subclasses should implement the * actual adding to the collection. */ - public Object addRequireBundleModification(IProject project, ExportPackageDescription desc, int relevance, - CompilationUnit cu, String qualifiedTypeToImport) { - return JavaResolutionFactory.createRequireBundleProposal(project, desc, - JavaResolutionFactory.TYPE_JAVA_COMPLETION, relevance, cu, qualifiedTypeToImport); + public IJavaCompletionProposal addRequireBundleModification(IProject project, ExportPackageDescription desc, + int relevance, CompilationUnit cu, String qualifiedTypeToImport) { + BundleDescription exporter = desc.getExporter(); + if (exporter == null) { + return null; + } + var change = JavaResolutionFactory.createRequireBundleChange(project, exporter, cu, qualifiedTypeToImport); + return JavaResolutionFactory.createJavaCompletionProposal(change, relevance); } - /** * Adds a search repositories proposal. Subclasses should implement the actual adding to the collection. */ diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/java/JavaResolutionFactory.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/java/JavaResolutionFactory.java index ca1c14d35f..28d78eb299 100644 --- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/java/JavaResolutionFactory.java +++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/java/JavaResolutionFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2021 IBM Corporation and others. + * Copyright (c) 2008, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -14,6 +14,7 @@ package org.eclipse.pde.internal.ui.correction.java; import java.text.MessageFormat; +import java.util.Arrays; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; @@ -34,6 +35,7 @@ import org.eclipse.ltk.core.refactoring.Change; import org.eclipse.ltk.core.refactoring.RefactoringStatus; import org.eclipse.ltk.core.refactoring.TextFileChange; +import org.eclipse.osgi.service.resolver.BundleDescription; import org.eclipse.osgi.service.resolver.ExportPackageDescription; import org.eclipse.osgi.util.NLS; import org.eclipse.pde.core.IBaseModel; @@ -78,26 +80,21 @@ public class JavaResolutionFactory { * This class represents a Change which will be applied to a Manifest file. This change is meant to be * used to create an IJavaCompletionProposal or ClasspathFixProposal. */ - private static abstract class AbstractManifestChange extends Change { + static abstract class AbstractManifestChange extends Change { - private final Object fChangeObject; + private final T fChangeObject; private final IProject fProject; private CompilationUnit fCompilationUnit; private String fQualifiedTypeToImport; - private AbstractManifestChange(IProject project, Object obj) { + public AbstractManifestChange(IProject project, T changeObj, CompilationUnit cu, String qualifiedTypeToImport) { fProject = project; - fChangeObject = obj; - } - - public AbstractManifestChange(IProject project, Object changeObj, CompilationUnit cu, - String qualifiedTypeToImport) { - this(project, changeObj); + fChangeObject = changeObj; fCompilationUnit = cu; fQualifiedTypeToImport = qualifiedTypeToImport; } - protected Object getChangeObject() { + protected T getChangeObject() { return fChangeObject; } @@ -178,9 +175,9 @@ public void initializeValidationData(IProgressMonitor pm) { * dependency or add multiple Require-Bundle entries to resolve the dependency * based on description name */ - private static class RequireBundleManifestChange extends AbstractManifestChange { + private static class RequireBundleManifestChange extends AbstractManifestChange { - private RequireBundleManifestChange(IProject project, ExportPackageDescription desc, CompilationUnit cu, + RequireBundleManifestChange(IProject project, BundleDescription desc, CompilationUnit cu, String qualifiedTypeToImport) { super(project, desc, cu, qualifiedTypeToImport); } @@ -193,24 +190,19 @@ protected void modifyModel(IBaseModel model, IProgressMonitor monitor) throws Co if (!(model instanceof IPluginModelBase base)) { return; } - String pluginId = ((ExportPackageDescription) getChangeObject()).getSupplier().getSymbolicName(); + String pluginId = getChangeObject().getSymbolicName(); + IPluginImport[] imports = base.getPluginBase().getImports(); if (!isUndo()) { - IPluginImport[] imports = base.getPluginBase().getImports(); - boolean duplicate = false; - for (IPluginImport iPluginImport : imports) { - if (iPluginImport.getId().equals(pluginId)) { - duplicate = true; - break; - } - } + // TODO: is this actually possible? + boolean duplicate = Arrays.stream(imports).map(IPluginImport::getId).anyMatch(pluginId::equals); if (duplicate) { return; } IPluginImport impt = base.getPluginFactory().createImport(); impt.setId(pluginId); + impt.setVersion(pluginId); base.getPluginBase().add(impt); } else { - IPluginImport[] imports = base.getPluginBase().getImports(); for (IPluginImport pluginImport : imports) { if (pluginImport.getId().equals(pluginId)) { base.getPluginBase().remove(pluginImport); @@ -223,8 +215,8 @@ protected void modifyModel(IBaseModel model, IProgressMonitor monitor) throws Co insertImport(getCompilationUnit(), getQualifiedTypeToImport(), pm); if (!isUndo()) { - return new RequireBundleManifestChange(getProject(), (ExportPackageDescription) getChangeObject(), - getCompilationUnit(), getQualifiedTypeToImport()) { + return new RequireBundleManifestChange(getProject(), getChangeObject(), getCompilationUnit(), + getQualifiedTypeToImport()) { @Override public boolean isUndo() { return true; @@ -248,13 +240,9 @@ public String getDescription() { @Override public String getName() { if (!isUndo()) { - if(getChangeObject() instanceof String) { - return MessageFormat.format(PDEUIMessages.UnresolvedImportFixProcessor_0, - (getChangeObject().toString())); - } - return MessageFormat.format(PDEUIMessages.UnresolvedImportFixProcessor_0, ((ExportPackageDescription) getChangeObject()).getExporter().getName()); + return MessageFormat.format(PDEUIMessages.UnresolvedImportFixProcessor_0, getChangeObject().getName()); } - return MessageFormat.format(PDEUIMessages.UnresolvedImportFixProcessor_1, ((ExportPackageDescription) getChangeObject()).getExporter().getName()); + return MessageFormat.format(PDEUIMessages.UnresolvedImportFixProcessor_1, getChangeObject().getName()); } @Override @@ -267,19 +255,14 @@ public Object getModifiedElement() { } return super.getModifiedElement(); } - } /* * A Change which will add an Import-Package entry to resolve the given dependency */ - private static class ImportPackageManifestChange extends AbstractManifestChange { + private static class ImportPackageManifestChange extends AbstractManifestChange { - private ImportPackageManifestChange(IProject project, ExportPackageDescription desc) { - super(project, desc); - } - - private ImportPackageManifestChange(IProject project, ExportPackageDescription desc, CompilationUnit cu, + ImportPackageManifestChange(IProject project, ExportPackageDescription desc, CompilationUnit cu, String qualifiedTypeToImport) { super(project, desc, cu, qualifiedTypeToImport); } @@ -293,7 +276,7 @@ protected void modifyModel(IBaseModel model, IProgressMonitor monitor) throws Co return; } IBundle bundle = base.getBundleModel().getBundle(); - ExportPackageDescription desc = (ExportPackageDescription) getChangeObject(); + ExportPackageDescription desc = getChangeObject(); String pkgId = desc.getName(); IManifestHeader header = bundle.getManifestHeader(Constants.IMPORT_PACKAGE); if (header == null) { @@ -316,7 +299,8 @@ protected void modifyModel(IBaseModel model, IProgressMonitor monitor) throws Co insertImport(getCompilationUnit(), getQualifiedTypeToImport(), pm); if (!isUndo()) { - return new ImportPackageManifestChange(getProject(), (ExportPackageDescription) getChangeObject()) { + return new ImportPackageManifestChange(getProject(), getChangeObject(), getCompilationUnit(), + getQualifiedTypeToImport()) { @Override public boolean isUndo() { return true; @@ -339,9 +323,9 @@ public Image getImage() { @Override public String getName() { if (!isUndo()) { - return MessageFormat.format(PDEUIMessages.UnresolvedImportFixProcessor_3, ((ExportPackageDescription) getChangeObject()).getName()); + return MessageFormat.format(PDEUIMessages.UnresolvedImportFixProcessor_3, getChangeObject().getName()); } - return MessageFormat.format(PDEUIMessages.UnresolvedImportFixProcessor_4, ((ExportPackageDescription) getChangeObject()).getName()); + return MessageFormat.format(PDEUIMessages.UnresolvedImportFixProcessor_4, getChangeObject().getName()); } @Override @@ -355,10 +339,10 @@ public Object getModifiedElement() { } - private static class ExportPackageChange extends AbstractManifestChange { + private static class ExportPackageChange extends AbstractManifestChange { - public ExportPackageChange(IProject project, IPackageFragment fragment) { - super(project, fragment); + ExportPackageChange(IProject project, IPackageFragment fragment) { + super(project, fragment, null, null); } @Override @@ -366,26 +350,30 @@ public Change perform(IProgressMonitor pm) throws CoreException { ModelModification mod = new ModelModification(getProject()) { @Override protected void modifyModel(IBaseModel model, IProgressMonitor monitor) throws CoreException { - if (model instanceof IBundlePluginModelBase) { - IBundle bundle = ((IBundlePluginModelBase) model).getBundleModel().getBundle(); + if (model instanceof IBundlePluginModelBase base) { + IBundle bundle = base.getBundleModel().getBundle(); - ExportPackageHeader header = (ExportPackageHeader) bundle.getManifestHeader(Constants.EXPORT_PACKAGE); + ExportPackageHeader header = (ExportPackageHeader) bundle + .getManifestHeader(Constants.EXPORT_PACKAGE); if (header == null) { bundle.setHeader(Constants.EXPORT_PACKAGE, ""); //$NON-NLS-1$ header = (ExportPackageHeader) bundle.getManifestHeader(Constants.EXPORT_PACKAGE); } - header.addPackage(new ExportPackageObject(header, (IPackageFragment) getChangeObject(), Constants.VERSION_ATTRIBUTE)); + header.addPackage( + new ExportPackageObject(header, getChangeObject(), Constants.VERSION_ATTRIBUTE)); } } }; PDEModelUtility.modifyModel(mod, new NullProgressMonitor()); - // No plans to use as ClasspathFixProposal, therefore we don't have to worry about an undo + // No plans to use as ClasspathFixProposal, therefore we don't have + // to worry about an undo return null; } @Override public String getName() { - return NLS.bind(PDEUIMessages.ForbiddenAccessProposal_quickfixMessage, new String[] {((IPackageFragment) getChangeObject()).getElementName(), getProject().getName()}); + return NLS.bind(PDEUIMessages.ForbiddenAccessProposal_quickfixMessage, + new String[] { getChangeObject().getElementName(), getProject().getName() }); } @Override @@ -404,7 +392,8 @@ public Object getModifiedElement() { @Override public String getDescription() { - // No plans to use as ClasspathFixProposal, therefore we don't have to implement a description + // No plans to use as ClasspathFixProposal, therefore we don't have + // to implement a description return null; } } @@ -419,10 +408,6 @@ public String getDescription() { * @param desc * an ExportPackageDescription from the bundle that is to be * added as a Require-Bundle dependency - * @param type - * the type of the proposal to be returned - * @param relevance - * the relevance of the new proposal * @param qualifiedTypeToImport * the qualified type name of the type that requires this * proposal. If this argument and cu are supplied the proposal @@ -431,16 +416,10 @@ public String getDescription() { * @param cu * the AST root of the java source file in which this fix was * invoked - * @see JavaResolutionFactory#TYPE_JAVA_COMPLETION - * @see JavaResolutionFactory#TYPE_CLASSPATH_FIX */ - public static final Object createRequireBundleProposal(IProject project, ExportPackageDescription desc, int type, - int relevance, CompilationUnit cu, String qualifiedTypeToImport) { - if (desc.getSupplier() == null) { - return null; - } - AbstractManifestChange change = new RequireBundleManifestChange(project, desc, cu, qualifiedTypeToImport); - return createWrapper(change, type, relevance); + public static AbstractManifestChange createRequireBundleChange(IProject project, + BundleDescription desc, CompilationUnit cu, String qualifiedTypeToImport) { + return new RequireBundleManifestChange(project, desc, cu, qualifiedTypeToImport); } /** @@ -453,10 +432,6 @@ public static final Object createRequireBundleProposal(IProject project, ExportP * @param desc * an ExportPackageDescription which represents the package to be * added - * @param type - * the type of the proposal to be returned - * @param relevance - * the relevance of the new proposal * @param qualifiedTypeToImport * the qualified type name of the type that requires this * proposal. If this argument and cu are supplied the proposal @@ -465,13 +440,10 @@ public static final Object createRequireBundleProposal(IProject project, ExportP * @param cu * the AST root of the java source file in which this fix was * invoked - * @see JavaResolutionFactory#TYPE_JAVA_COMPLETION - * @see JavaResolutionFactory#TYPE_CLASSPATH_FIX */ - public static final Object createImportPackageProposal(IProject project, ExportPackageDescription desc, int type, - int relevance, CompilationUnit cu, String qualifiedTypeToImport) { - AbstractManifestChange change = new ImportPackageManifestChange(project, desc, cu, qualifiedTypeToImport); - return createWrapper(change, type, relevance); + public static AbstractManifestChange createImportPackageChange(IProject project, + ExportPackageDescription desc, CompilationUnit cu, String qualifiedTypeToImport) { + return new ImportPackageManifestChange(project, desc, cu, qualifiedTypeToImport); } public static final IJavaCompletionProposal createSearchRepositoriesProposal(String packageName) { @@ -483,22 +455,10 @@ public static final IJavaCompletionProposal createSearchRepositoriesProposal(Str * pkg. The object will be of the type specified by the type argument. * @param project the project to be updated * @param pkg an IPackageFragment which represents the package to be added - * @param type the type of the proposal to be returned - * @param relevance the relevance of the new proposal - * @see JavaResolutionFactory#TYPE_JAVA_COMPLETION - * @see JavaResolutionFactory#TYPE_CLASSPATH_FIX */ - public static final Object createExportPackageProposal(IProject project, IPackageFragment pkg, int type, int relevance) { - AbstractManifestChange change = new ExportPackageChange(project, pkg); - return createWrapper(change, type, relevance); - } - - private static final Object createWrapper(AbstractManifestChange change, int type, int relevance) { - return switch (type) { - case TYPE_JAVA_COMPLETION -> createJavaCompletionProposal(change, relevance); - case TYPE_CLASSPATH_FIX -> createClasspathFixProposal(change, relevance); - default -> null; - }; + public static AbstractManifestChange createExportPackageChange(IProject project, + IPackageFragment pkg) { + return new ExportPackageChange(project, pkg); } // Methods to wrap a AbstractMethodChange into a consumable format @@ -509,7 +469,8 @@ private static final Object createWrapper(AbstractManifestChange change, int typ * @since 3.4 * @see AbstractManifestChange */ - public final static ClasspathFixProposal createClasspathFixProposal(final AbstractManifestChange change, final int relevance) { + public final static ClasspathFixProposal createClasspathFixProposal(AbstractManifestChange change, + int relevance) { return new ClasspathFixProposal() { @Override @@ -547,7 +508,8 @@ public int getRelevance() { * @since 3.4 * @see AbstractManifestChange */ - public final static IJavaCompletionProposal createJavaCompletionProposal(final AbstractManifestChange change, final int relevance) { + public final static IJavaCompletionProposal createJavaCompletionProposal(AbstractManifestChange change, + int relevance) { return new IJavaCompletionProposal() { @Override 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 b9f555c5d5..f9338f1656 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, 2024 IBM Corporation and others. + * Copyright (c) 2007, 2025 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -14,10 +14,10 @@ *******************************************************************************/ package org.eclipse.pde.internal.ui.correction.java; -import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; @@ -46,7 +46,6 @@ import org.eclipse.jdt.ui.text.java.IJavaCompletionProposal; import org.eclipse.jdt.ui.text.java.IProblemLocation; import org.eclipse.jdt.ui.text.java.IQuickFixProcessor; -import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.osgi.service.resolver.BundleDescription; import org.eclipse.osgi.service.resolver.BundleSpecification; import org.eclipse.osgi.service.resolver.ExportPackageDescription; @@ -68,22 +67,15 @@ public class QuickFixProcessor implements IQuickFixProcessor { @Override - public IJavaCompletionProposal[] getCorrections(IInvocationContext context, IProblemLocation[] locations) throws CoreException { - ArrayList results = new ArrayList<>(); - + public IJavaCompletionProposal[] getCorrections(IInvocationContext context, IProblemLocation[] locations) + throws CoreException { + List results = new ArrayList<>(); AbstractClassResolutionCollector collector = createCollector(results, context); - for (IProblemLocation location : locations) { - int id = location.getProblemId(); - switch (id) { - case IProblem.ForbiddenReference : + switch (location.getProblemId()) { + case IProblem.ForbiddenReference: handleAccessRestrictionProblem(context, location, 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 : + case IProblem.ImportNotFound, IProblem.UndefinedName, IProblem.UndefinedType, IProblem.UnresolvedVariable, IProblem.MissingTypeInMethod, IProblem.MissingTypeInConstructor: handleImportNotFound(context, location, collector); } @@ -97,17 +89,17 @@ public IJavaCompletionProposal[] getCorrections(IInvocationContext context, IPro 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 (node instanceof Type type) { + referencedElement = type.resolveBinding(); + } else if (node instanceof Name name) { + referencedElement = name.resolveBinding(); + } else if (node instanceof MethodInvocation methodInvocation) { + IMethodBinding tempMethod = methodInvocation.resolveMethodBinding(); if (tempMethod != null) { referencedElement = tempMethod.getDeclaringClass(); } - } else if (node instanceof FieldAccess) { - IVariableBinding tempVariable = ((FieldAccess) node).resolveFieldBinding(); + } else if (node instanceof FieldAccess fieldAccess) { + IVariableBinding tempVariable = fieldAccess.resolveFieldBinding(); if (tempVariable != null) { referencedElement = tempVariable.getDeclaringClass(); } @@ -154,7 +146,7 @@ private void handleAccessRestrictionProblem(IInvocationContext context, IProblem * Adds IJavaCompletionProposals for a Require-Bundle if user is using an Import-Package from the bundle */ private void handleAccessRestrictionByImportPackage(IPackageFragment fragment, AbstractClassResolutionCollector collector) { - HashSet set = new HashSet<>(); + Set set = new HashSet<>(); IProject project = fragment.getJavaProject().getProject(); String pkgName = fragment.getElementName(); IPluginModelBase base = PluginRegistry.findModel(project); @@ -227,19 +219,20 @@ private void handleImportNotFound(IInvocationContext context, IProblemLocation p ASTNode node = getParent(selectedNode); String className = null; if (node == null) { - if (selectedNode instanceof Name) { - ITypeBinding typeBinding = ((Name) selectedNode).resolveTypeBinding(); + if (selectedNode instanceof Name name) { + ITypeBinding typeBinding = name.resolveTypeBinding(); if (typeBinding != null) { className = typeBinding.getBinaryName(); } - if (className == null && selectedNode instanceof SimpleName) { // fallback if the type cannot be resolved - className = ((SimpleName) selectedNode).getIdentifier(); + if (className == null && selectedNode instanceof SimpleName simpleName) { + // fallback if the type cannot be resolved + className = simpleName.getIdentifier(); } } - } else if (node instanceof ImportDeclaration) { + } else if (node instanceof ImportDeclaration importDeclaration) { // Find the full package name, strip off the class name or on demand qualifier '.*'; - String packageName = ((ImportDeclaration) node).getName().getFullyQualifiedName(); - if (!((ImportDeclaration) node).isOnDemand()) { + String packageName = importDeclaration.getName().getFullyQualifiedName(); + if (!importDeclaration.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()); } @@ -253,13 +246,7 @@ private void handleImportNotFound(IInvocationContext context, IProblemLocation p if (!WorkspaceModelManager.isPluginProject(project)) { return; } - - IRunnableWithProgress findOperation = new FindClassResolutionsOperation(project, cu, className, - collector); - try { - findOperation.run(new NullProgressMonitor()); - } catch (InvocationTargetException | InterruptedException e) { - } + new FindClassResolutionsOperation(project, cu, className, collector).run(new NullProgressMonitor()); } } } @@ -267,8 +254,7 @@ private void handleImportNotFound(IInvocationContext context, IProblemLocation p /* * Custom AbstractClassResolutionCollector which will only add one IJavaCompletionProposal for adding an Import-Package or Export-Package entry */ - private AbstractClassResolutionCollector createCollector(final Collection result, - IInvocationContext context) { + private AbstractClassResolutionCollector createCollector(Collection result, IInvocationContext context) { return new AbstractClassResolutionCollector() { // the list of package names for which an import package resolution has been created @@ -276,35 +262,26 @@ private AbstractClassResolutionCollector createCollector(final Collection fList = new ArrayList<>(); - - @Override - public void addResolutionModification(IProject project, ExportPackageDescription desc) { - addResolutionModification(project, desc, null, ""); //$NON-NLS-1$ - } + private final List proposals = new ArrayList<>(); @Override public void addResolutionModification(IProject project, ExportPackageDescription desc, CompilationUnit cu, - String qualifiedTypeToImport) { - if (desc.getSupplier() == null) { + String typeToImport) { + BundleDescription exporter = desc.getExporter(); + if (exporter == null) { return; } - Object proposal = JavaResolutionFactory.createRequireBundleProposal(project, desc, - JavaResolutionFactory.TYPE_CLASSPATH_FIX, 16, cu, qualifiedTypeToImport); - if (proposal != null) { - fList.add(proposal); - } + // TODO: propose import package too! But what's the difference to + // the other kind? + var change = JavaResolutionFactory.createRequireBundleChange(project, exporter, cu, typeToImport); + ClasspathFixProposal proposal = JavaResolutionFactory.createClasspathFixProposal(change, 16); + proposals.add(proposal); } - - /* - * Returns all the ClasspathFixProposals which were found - */ - public ClasspathFixProposal[] getProposals() { - return fList.toArray(new ClasspathFixProposal[fList.size()]); - } - - } @Override @@ -80,12 +67,9 @@ public ClasspathFixProposal[] getFixImportProposals(IJavaProject project, String return new ClasspathFixProposal[0]; } ClasspathFixCollector collector = new ClasspathFixCollector(); - IRunnableWithProgress findOperation = new FindClassResolutionsOperation(project.getProject(), name, collector); - try { - findOperation.run(new NullProgressMonitor()); - } catch (InvocationTargetException | InterruptedException e) { - } - return collector.getProposals(); + var findOperation = new FindClassResolutionsOperation(project.getProject(), name, collector); + findOperation.run(new NullProgressMonitor()); + return collector.proposals.toArray(ClasspathFixProposal[]::new); } }