package com.redhat.ceylon.eclipse.code.open;
import static com.redhat.ceylon.eclipse.code.editor.Navigation.gotoDeclaration;
import static com.redhat.ceylon.eclipse.code.editor.Navigation.resolveNative;
import static com.redhat.ceylon.eclipse.util.EditorUtil.getCurrentEditor;
import static com.redhat.ceylon.eclipse.util.EditorUtil.getSelection;
import static com.redhat.ceylon.eclipse.util.Nodes.findNode;
import static com.redhat.ceylon.eclipse.util.Nodes.getReferencedModel;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.ui.IEditorPart;
import com.redhat.ceylon.common.Backends;
import com.redhat.ceylon.compiler.typechecker.tree.Node;
import com.redhat.ceylon.compiler.typechecker.tree.Tree;
import com.redhat.ceylon.eclipse.code.editor.CeylonEditor;
import com.redhat.ceylon.eclipse.code.parse.CeylonParseController;
import com.redhat.ceylon.model.typechecker.model.Declaration;
import com.redhat.ceylon.model.typechecker.model.Referenceable;
import com.redhat.ceylon.model.typechecker.model.TypedDeclaration;
public class OpenSelectedDeclarationHandler extends AbstractHandler {
private Node getSelectedNode(
ITextSelection textSel, CeylonEditor editor) {
CeylonParseController controller =
editor.getParseController();
if (controller==null) {
return null;
}
else {
Tree.CompilationUnit rootNode =
controller.getLastCompilationUnit();
if (rootNode == null) {
return null;
}
else {
return findNode(rootNode,
controller.getTokens(),
textSel.getOffset(),
textSel.getOffset() +
textSel.getLength());
}
}
}
public boolean isEnabled() {
IEditorPart editor = getCurrentEditor();
if (super.isEnabled()
&& editor instanceof CeylonEditor) {
CeylonEditor ce = (CeylonEditor) editor;
Node selectedNode =
getSelectedNode(getSelection(ce), ce);
return getReferencedModel(selectedNode)!=null;
}
else {
return false;
}
}
@Override
public Object execute(ExecutionEvent event)
throws ExecutionException {
IEditorPart editor = getCurrentEditor();
if (editor instanceof CeylonEditor) {
CeylonEditor ce = (CeylonEditor) editor;
Node selectedNode =
getSelectedNode(getSelection(ce), ce);
Referenceable referenceable =
getReferencedModel(selectedNode);
if (referenceable instanceof Declaration) {
Declaration dec =
(Declaration)
referenceable;
//look for the "original" declaration,
//ignoring narrowing synthetic declarations
if (dec instanceof TypedDeclaration) {
Declaration od = dec;
while (od!=null) {
referenceable = dec = od;
TypedDeclaration td =
(TypedDeclaration) od;
od = td.getOriginalDeclaration();
}
}
if (dec.isNative()) {
//for native declarations, go to the
//header
referenceable =
resolveNative(dec,
Backends.HEADER);
}
}
if (referenceable!=null) {
gotoDeclaration(referenceable);
}
}
return null;
}
}