package com.redhat.ceylon.eclipse.code.resolve;
import static com.redhat.ceylon.eclipse.code.editor.Navigation.gotoDeclaration;
import static com.redhat.ceylon.eclipse.util.EditorUtil.getCurrentEditor;
import static com.redhat.ceylon.eclipse.util.EditorUtil.getFile;
import static com.redhat.ceylon.eclipse.util.JavaSearch.toCeylonDeclaration;
import static java.lang.Character.isJavaIdentifierPart;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.jdt.core.ICodeAssist;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.ui.javaeditor.IClassFileEditorInput;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.hyperlink.AbstractHyperlinkDetector;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.part.FileEditorInput;
import com.redhat.ceylon.eclipse.util.JavaSearch;
import com.redhat.ceylon.model.typechecker.model.Declaration;
public class JavaToCeylonHyperlinkDetector extends AbstractHyperlinkDetector {
private static final class JavaToCeylonLink implements IHyperlink {
private final IRegion region;
private final IDocument doc;
private final Declaration ceylonDeclaration;
private JavaToCeylonLink(IRegion region, IDocument doc,
Declaration ceylonDeclaration) {
this.region = region;
this.doc = doc;
this.ceylonDeclaration = ceylonDeclaration;
}
@Override
public void open() {
gotoDeclaration(ceylonDeclaration);
}
@Override
public String getTypeLabel() {
return null;
}
@Override
public String getHyperlinkText() {
return "Open Ceylon Declaration";
}
@Override
public IRegion getHyperlinkRegion() {
int offset = region.getOffset();
int length = region.getLength();
try {
while (isJavaIdentifierPart(
doc.getChar(offset-1))) {
offset--;
}
while (isJavaIdentifierPart(
doc.getChar(offset+length))) {
length++;
}
}
catch (BadLocationException e) {
e.printStackTrace();
}
return new Region(offset, length);
}
}
@Override
public IHyperlink[] detectHyperlinks(ITextViewer textViewer,
final IRegion region, boolean canShowMultipleHyperlinks) {
try {
final IDocument doc = textViewer.getDocument();
IEditorInput editorInput =
getCurrentEditor().getEditorInput();
ICodeAssist ca = null;
if (editorInput instanceof FileEditorInput) {
IFile file = getFile(editorInput);
ca = (ICodeAssist) JavaCore.create(file);
}
else if (editorInput instanceof IClassFileEditorInput) {
IClassFileEditorInput cfei =
(IClassFileEditorInput) editorInput;
ca = cfei.getClassFile();
}
if (ca==null) return null;
IJavaElement[] selection =
ca.codeSelect(region.getOffset(),
region.getLength());
for (IJavaElement javaElement: selection) {
if (JavaSearch.isCeylonDeclaration(javaElement) &&
!(javaElement instanceof IPackageFragment)) {
IProject project =
javaElement.getJavaProject()
.getProject();
Declaration declaration =
toCeylonDeclaration(project,
javaElement);
if (declaration != null) {
return new IHyperlink[] {
new JavaToCeylonLink(region,
doc, declaration)
};
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
}