]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.ui/src/org/simantics/scl/ui/editor2/OpenDeclaration.java
421328c164222346da2c9eb073f222afe841c601
[simantics/platform.git] / bundles / org.simantics.scl.ui / src / org / simantics / scl / ui / editor2 / OpenDeclaration.java
1 package org.simantics.scl.ui.editor2;
2
3
4 import org.eclipse.core.commands.AbstractHandler;
5 import org.eclipse.core.commands.ExecutionEvent;
6 import org.eclipse.core.commands.ExecutionException;
7 import org.eclipse.swt.custom.StyledText;
8 import org.eclipse.swt.widgets.Control;
9 import org.eclipse.ui.IEditorPart;
10 import org.eclipse.ui.PlatformUI;
11 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
12 import org.simantics.scl.compiler.module.InvalidModulePathException;
13 import org.simantics.scl.compiler.module.ModuleUtils;
14 import org.simantics.scl.compiler.source.ModuleSource;
15 import org.simantics.scl.osgi.SCLOsgi;
16 import org.simantics.scl.ui.editor.completion.SCLTextEditorEnvironment;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19
20 public class OpenDeclaration extends AbstractHandler {
21
22     private static final Logger LOGGER = LoggerFactory.getLogger(OpenDeclaration.class);
23
24     private static boolean isIdentifierPart(char c) {
25         return Character.isJavaIdentifierPart(c) || c=='.';
26     }
27     
28     private static String extractIdentifierAt(String text, int caretPos) {
29         int startPos = caretPos;
30         while(startPos > 0 && isIdentifierPart(text.charAt(startPos-1)))
31             --startPos;
32         int endPos = caretPos;
33         while(endPos < text.length() && isIdentifierPart(text.charAt(endPos)))
34             ++endPos;
35         return text.substring(startPos, endPos);
36     }
37     
38     private static final String SYMBOL_CHARS = "!$%&*+/<=>?@\\^|-:~.";
39     
40     private static boolean isSymbolPart(char c) {
41         for(int i=0;i<SYMBOL_CHARS.length();++i)
42             if(SYMBOL_CHARS.charAt(i) == c)
43                 return true;
44         return false;
45     }
46     
47     private static String extractSymbolAt(String text, int caretPos) {
48         int startPos = caretPos;
49         while(startPos > 0 && isSymbolPart(text.charAt(startPos-1)))
50             --startPos;
51         int endPos = caretPos;
52         while(endPos < text.length() && isSymbolPart(text.charAt(endPos)))
53             ++endPos;
54         return text.substring(startPos, endPos);
55     }
56     
57     public static String extractIdentifierOrSymbolAt(String text, int caretPos) {
58         String result = extractIdentifierAt(text, caretPos);
59         if(!result.isEmpty())
60             return result;
61         return extractSymbolAt(text, caretPos);
62     }
63     
64     private static String extractLineAt(String text, int caretPos) {
65         int startPos = caretPos;
66         while(startPos > 0 && !isNewline(text.charAt(startPos-1)))
67             --startPos;
68         int endPos = caretPos;
69         while(endPos < text.length() && !isNewline(text.charAt(endPos)))
70             ++endPos;
71         return text.substring(startPos, endPos);
72     }
73     
74     private static boolean isNewline(char c) {
75         return c=='\n' || c=='\r';
76     }
77
78     @Override
79     public Object execute(ExecutionEvent event) throws ExecutionException {
80         IEditorPart editor = 
81                 PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
82         if(!(editor instanceof SCLModuleEditor2))
83             return null;
84         SCLModuleEditor2 moduleEditor = (SCLModuleEditor2)editor;
85         StyledText styledText = (StyledText)moduleEditor.getAdapter(Control.class);
86         String text = styledText.getText();
87         int caretOffset = styledText.getCaretOffset();
88         
89         // Find the line where the caret is
90         String lineAtCaret = extractLineAt(text, caretOffset);
91         if(lineAtCaret.startsWith("import ") || lineAtCaret.startsWith("include ")) {
92             int p1 = lineAtCaret.indexOf('"', 6);
93             int p2 = lineAtCaret.indexOf('"', p1+1);
94             SCLModuleEditorInput input = (SCLModuleEditorInput)moduleEditor.getEditorInput();
95             try {
96                     String moduleName = ModuleUtils.resolveAbsolutePath(input.getModuleName(), lineAtCaret.substring(p1+1, p2));
97                 ModuleSource source = SCLOsgi.SOURCE_REPOSITORY.getModuleSource(moduleName, null);
98                 if (source != null) {
99                         OpenSCLModule.scheduleOpenModule(moduleName);
100                 }
101             } catch (InvalidModulePathException e) {
102                 LOGGER.error("Could not open declaration {} {}", input.getModuleName(), lineAtCaret, e);
103             }
104         }
105         else {
106             // Try to find an identifier at caret
107             String identifierAtCaret = extractIdentifierOrSymbolAt(text, caretOffset);
108             if(identifierAtCaret.isEmpty())
109                 return null;
110             SCLTextEditorEnvironment editorEnvironment = moduleEditor.getSCLTextEditorEnvironment();
111             editorEnvironment.updateEnvironment(moduleEditor.getDocument());
112             SCLValue value = editorEnvironment.getValue(identifierAtCaret);
113             //System.out.println("identifierAtCaret = " + identifierAtCaret + " [" + Locations.beginOf(value.definitionLocation) + ", " + Locations.endOf(value.definitionLocation) + "]");
114             if(value != null)
115                 OpenSCLDefinition.scheduleOpenDefinition(value.getName().module, value.definitionLocation);
116         }
117         return null;
118     }
119
120 }