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; } }