blob: 25da00d9644b024548aefb97b85e30ba8fae1634 [file] [log] [blame]
/**
* Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
* 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:
* Florian Pirchner - Initial implementation
*
* generated by Xtext 2.11.0
*/
package org.eclipse.osbp.xtext.oxtype.ui.quickfix;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.compiler.IProblem;
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.jface.text.BadLocationException;
import org.eclipse.osbp.xtext.oxtype.imports.IShouldImportProvider;
import org.eclipse.osbp.xtext.oxtype.ui.contentassist.OXTypeReplacingAppendable;
import org.eclipse.osbp.xtext.oxtype.ui.imports.OXTypeOrganizeImportsHandler;
import org.eclipse.xtext.common.types.JvmDeclaredType;
import org.eclipse.xtext.common.types.JvmType;
import org.eclipse.xtext.common.types.TypesPackage;
import org.eclipse.xtext.common.types.access.jdt.IJavaProjectProvider;
import org.eclipse.xtext.common.types.xtext.ui.JdtTypeRelevance;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.IScopeProvider;
import org.eclipse.xtext.ui.editor.model.IXtextDocument;
import org.eclipse.xtext.ui.editor.model.edit.IModification;
import org.eclipse.xtext.ui.editor.model.edit.IModificationContext;
import org.eclipse.xtext.ui.editor.model.edit.ISemanticModification;
import org.eclipse.xtext.ui.editor.quickfix.IssueResolutionAcceptor;
import org.eclipse.xtext.validation.Issue;
import org.eclipse.xtext.xbase.conversion.XbaseQualifiedNameValueConverter;
import org.eclipse.xtext.xbase.typesystem.util.CommonTypeComputationServices;
import org.eclipse.xtext.xbase.ui.quickfix.ILinkingIssueQuickfixProvider;
import com.google.inject.Inject;
/**
* Imports EObjects from the model. And also JvmTypes that are not contained in
* a JvmModel.
*/
@SuppressWarnings("restriction")
public class ImportEClassQuickfixes implements ILinkingIssueQuickfixProvider {
@Inject
private IScopeProvider scopeProvider;
@Inject
private OXTypeReplacingAppendable.Factory appendableFactory;
@Inject
private IJavaProjectProvider projectProvider;
@Inject
private IShouldImportProvider shouldImport;
@Inject
private CommonTypeComputationServices services;
@Inject
private JdtTypeRelevance jdtTypeRelevance;
@Inject
XbaseQualifiedNameValueConverter valueConverter;
@Inject
OXTypeOrganizeImportsHandler organizeImportsHandler;
@Override
public void addQuickfixes(Issue issue, IssueResolutionAcceptor acceptor, IXtextDocument xtextDocument,
XtextResource resource, EObject referenceOwner, EReference unresolvedReference) throws Exception {
EClass referenceType = unresolvedReference.getEReferenceType();
if (TypesPackage.Literals.JVM_TYPE.isSuperTypeOf(referenceType)) {
createOrphanedJvmTypeImports(issue, acceptor, xtextDocument, referenceOwner, unresolvedReference);
} else {
createEObjectImports(issue, acceptor, xtextDocument, referenceOwner, unresolvedReference);
}
createOrganizeImports(issue, acceptor, xtextDocument, referenceOwner, unresolvedReference);
}
/**
* This method is responsible to create quickfixes for {@link JvmType
* Non-JvmTypes}.
*
* @param issue
* @param acceptor
* @param xtextDocument
* @param referenceOwner
* @param unresolvedReference
* @throws BadLocationException
*/
protected void createEObjectImports(Issue issue, IssueResolutionAcceptor acceptor, IXtextDocument xtextDocument,
EObject referenceOwner, EReference unresolvedReference) throws BadLocationException {
String issueString = xtextDocument.get(issue.getOffset(), issue.getLength());
issueString = valueConverter.toValue(issueString, null);
IScope scope = scopeProvider.getScope(referenceOwner, unresolvedReference);
for (IEObjectDescription desc : scope.getAllElements()) {
if (!shouldImport.shouldImport(desc.getEObjectOrProxy(), unresolvedReference, referenceOwner)) {
continue;
}
// if (similarityMatcher.isSimilar(issueString, desc
// .getQualifiedName().getLastSegment())) {
if (issueString.equals(desc.getQualifiedName().getLastSegment())) {
final String fqn = desc.getQualifiedName().toString();
StringBuilder label = new StringBuilder("Import ns '");
label.append(desc.getName());
label.append("' (");
label.append(fqn);
label.append(")");
acceptor.accept(issue, label.toString(), label.toString(), "impc_obj.gif", new ISemanticModification() {
public void apply(EObject element, IModificationContext context) throws Exception {
OXTypeReplacingAppendable appendable = (OXTypeReplacingAppendable) appendableFactory
.create(context.getXtextDocument(), (XtextResource) element.eResource(), 0, 0);
appendable.appendEClassNsImports(fqn);
appendable.insertNewImports();
}
}, 110);
}
}
}
private void createOrganizeImports(Issue issue, IssueResolutionAcceptor acceptor, IXtextDocument xtextDocument,
EObject referenceOwner, EReference unresolvedReference) {
acceptor.accept(issue, "organize imports", "organize all imports", "impc_obj.gif", new IModification() {
@Override
public void apply(IModificationContext context) throws Exception {
organizeImportsHandler.execute(context.getXtextDocument());
}
}, 110);
}
/**
* This method is responsible to create quickfixes for {@link JvmType
* JvmTypes}. These JvmTypes are not contained in a JvmModel.
*
* @param issue
* @param acceptor
* @param xtextDocument
* @param referenceOwner
* @param unresolvedReference
* @throws BadLocationException
* @throws JavaModelException
*/
protected void createOrphanedJvmTypeImports(Issue issue, IssueResolutionAcceptor acceptor,
IXtextDocument xtextDocument, EObject referenceOwner, EReference unresolvedReference)
throws BadLocationException, JavaModelException {
String issueString = xtextDocument.get(issue.getOffset(), issue.getLength());
IJavaSearchScope javaSearchScope = getJavaSearchScope(referenceOwner);
createImportProposals(referenceOwner, issue, issueString, javaSearchScope, acceptor);
}
private IJavaSearchScope getJavaSearchScope(EObject model) {
if (model == null || model.eResource() == null || model.eResource().getResourceSet() == null) {
return null;
} else {
IJavaProject javaProject = projectProvider.getJavaProject(model.eResource().getResourceSet());
IJavaSearchScope searchScope = SearchEngine.createJavaSearchScope(new IJavaElement[] { javaProject });
return searchScope;
}
}
private String getQualifiedTypeName(char[] packageName, char[][] enclosingTypeNames, char[] simpleTypeName) {
StringBuilder fqName = new StringBuilder(packageName.length + simpleTypeName.length + 1);
if (packageName.length != 0) {
fqName.append(packageName);
fqName.append('.');
}
for (char[] enclosingType : enclosingTypeNames) {
fqName.append(enclosingType);
fqName.append('.');
}
fqName.append(simpleTypeName);
String fqNameAsString = fqName.toString();
return fqNameAsString;
}
private void createImportProposals(final EObject context, final Issue issue, String typeName,
IJavaSearchScope searchScope, final IssueResolutionAcceptor acceptor) throws JavaModelException {
org.eclipse.jdt.internal.core.search.BasicSearchEngine searchEngine = new org.eclipse.jdt.internal.core.search.BasicSearchEngine();
searchEngine.searchAllTypeNames(null, SearchPattern.R_EXACT_MATCH, typeName.toCharArray(),
SearchPattern.R_EXACT_MATCH, IJavaSearchConstants.TYPE, searchScope,
new org.eclipse.jdt.internal.core.search.IRestrictedAccessTypeRequestor() {
public void acceptType(int modifiers, char[] packageName, char[] simpleTypeName,
char[][] enclosingTypeNames, String path,
org.eclipse.jdt.internal.compiler.env.AccessRestriction access) {
final String qualifiedTypeName = getQualifiedTypeName(packageName, enclosingTypeNames,
simpleTypeName);
if (access == null
|| (access.getProblemId() != IProblem.ForbiddenReference && !access.ignoreIfBetter())) {
final JvmType importType = services.getTypeReferences().findDeclaredType(qualifiedTypeName,
context);
if (importType instanceof JvmDeclaredType) {
StringBuilder label = new StringBuilder("Import ns '");
label.append(simpleTypeName);
label.append("' (");
label.append(packageName);
if (enclosingTypeNames != null && enclosingTypeNames.length > 0) {
for (char[] enclosingTypeName : enclosingTypeNames) {
label.append(".");
label.append(enclosingTypeName);
}
}
label.append(")");
acceptor.accept(issue, label.toString(), label.toString(), "impc_obj.gif",
new ISemanticModification() {
public void apply(EObject element, IModificationContext context)
throws Exception {
OXTypeReplacingAppendable appendable = (OXTypeReplacingAppendable) appendableFactory
.create(context.getXtextDocument(),
(XtextResource) element.eResource(), 0, 0);
appendable.appendEClassNsImports(importType.getQualifiedName());
appendable.insertNewImports();
}
}, jdtTypeRelevance.getRelevance(qualifiedTypeName, typeName) + 100);
}
}
}
}, IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, new NullProgressMonitor());
}
}