3 public class LanguageClientJavascript : LanguageClient {
5 Gee.HashMap<string,string> file_contents;
7 public LanguageClientJavascript(Project.Project project)
9 // extend versions will proably call initialize to start and connect to server.
11 this.file_contents = new Gee.HashMap<string,string>();
12 GLib.debug(" START JAVASCRIPT LANG SERVER");
15 public override void initialize_server() {
16 GLib.debug("initialize javascript server");
20 public override void document_open (JsRender.JsRender file)
22 this.file_contents.set(file.path, file.toSourceCode());
23 Javascript.singleton().validate(file.toSourceCode(), file );
24 BuilderApplication.updateCompileResults();
27 public override async void document_save (JsRender.JsRender file)
30 this.file_contents.set(file.path, file.toSourceCode());
31 GLib.debug("set file %s : %d chars", file.path, this.file_contents.get(file.path).length);
32 Javascript.singleton().validate(file.toSourceCode(), file );
33 BuilderApplication.updateCompileResults();
35 public override async void document_change_force (JsRender.JsRender file, string contents ) {
36 this.file_contents.set(file.path, contents);
37 GLib.debug("set file %s : %d chars", file.path, this.file_contents.get(file.path).length);
38 Javascript.singleton().validate(contents, file );
39 BuilderApplication.updateCompileResults();
41 public override void document_change (JsRender.JsRender file )
43 this.document_change_force.begin( file, file.toSourceCode(), (obj, res) => {
44 this.document_change_force.end(res);
47 public override void document_close (JsRender.JsRender file) {}
48 public override void exit () throws GLib.Error { }
49 public override async void shutdown () throws GLib.Error { }
50 public override async Lsp.CompletionList? completion(JsRender.JsRender file, int line, int offset , int triggerType = 1) throws GLib.Error
53 var ret = new Lsp.CompletionList();
54 if (this.file_contents.get(file.path) == null) {
55 GLib.debug("got file %s : MISSING ", file.path);
58 //GLib.debug("got file %s : %s ", file.path, this.file_contents.get(file.path));
60 var ar = this.file_contents.get(file.path).split("\n");
61 var ln = line >= ar.length || line < 1 ? "" : ar[line-1];
62 if (offset-1 >= ln.length) {
63 GLib.debug("request for complete on line %d @ pos %d > line length %d", line, offset, (int) ln.length);
66 GLib.debug("got Line %d:%d '%s' ", line, offset, ln);
69 for (var i = offset - 1; i > 0; i--) {
70 GLib.debug("check char %d '%c'", i, ln[i]);
71 if (ln[i].isalpha() || ln[i] == '.' || ln[i] == '_') { // any other allowed chars?
79 var complete_string = ln.substring(start, offset - start);
80 GLib.debug("complete string = %s", complete_string);
88 // this. (based on the node type)
89 // this.xxx // Node and any determination.
91 // keywords... // text does not contains "."
93 if (!complete_string.contains(".")) {
94 // string does not have a '.'
95 // offer up this / Roo / javascript keywords... / look for var string = .. in the code..
96 for(var i = 0; i < JsRender.Lang.match_strings.size ; i++) {
97 var str = JsRender.Lang.match_strings.get(i);
98 var sci = new Lsp.CompletionItem.keyword(str, str, "keywords : %s".printf(str));
105 if (complete_string != "Roo" && "Roo".has_prefix(complete_string) ) {
106 // should we ignore exact matches... ???
107 var sci = new Lsp.CompletionItem.keyword("Roo", "Roo", "Roo - A Roo class" );
112 if (complete_string != "_this" && "_this".has_prefix( complete_string) ) {
113 // should we ignore exact matches... ???
115 var sci = new Lsp.CompletionItem.keyword("_this", "_this", "Reference to the global pointer to the files main class instance");
122 // got at least one ".".
123 var parts = complete_string.split(".");
125 var cur_instance = false;
126 if (parts[0] == "_this") {
127 if (file.tree == null) {
129 GLib.debug("file has no tree");
130 return ret; // no idea..
132 curtype = file.tree.fqn();
134 // work out from the node, what the type is...
135 // fetch node from element.
137 //curtype = node.fqn();
142 if (parts[0] == "this") {
143 // work out from the node, what the type is...
144 // fetch node from element.
145 var node = file.lineToNode(line -1); // hopefuly
147 GLib.debug("could nt find scope for 'this'");
148 return ret; // no idea..
150 curtype = node.fqn();
153 if (parts[0] == "Roo") {
155 cur_instance = false;
158 var prevbits = parts[0] + ".";
159 for(var i =1; i < parts.length; i++) {
160 GLib.debug("matching %d/%d\n", i, parts.length);
162 var is_last = i == parts.length -1;
163 // look up all the properties of the type...
164 var cls = this.project.palete.getClass(curtype);
166 GLib.debug("could not get class of curtype '%s'\n", curtype);
172 // only exact matches from here on...
174 if (cls.props.has_key(parts[i])) {
175 var prop = cls.props.get(parts[i]);
176 if (prop.type.index_of(".",0) > -1) {
177 // type is another roo object..
179 prevbits += parts[i] + ".";
187 // check methods?? - we do not export that at present..
188 return ret; //no idea...
192 //look for child classes.
193 var citer = this.project.palete.classes.map_iterator();
195 while (citer.next()) {
196 var scls = citer.get_key();
197 var look = prevbits + parts[i];
198 if (scls.index_of(look,0) != 0) {
201 // got a starting match..
203 cur_instance = false;
210 prevbits += parts[i] + ".";
213 // got to the last element..
214 GLib.debug("Got last element\n");
215 if (curtype == "") { // should not happen.. we would have returned already..
218 GLib.debug("Got last element type %s\n",curtype);
220 GLib.debug("matching instance");
221 // it's a static reference..
222 var citer = this.project.palete.classes.map_iterator();
223 while (citer.next()) {
224 var scls = citer.get_key();
225 var look = prevbits + parts[i];
226 if (parts[i].length > 0 && scls.index_of(look,0) != 0) {
229 var sci = new Lsp.CompletionItem.keyword(scls,scls, "doc??" );
236 GLib.debug("matching property");
240 var citer = cls.methods.map_iterator();
241 while (citer.next()) {
242 var prop = citer.get_value();
243 // does the name start with ...
244 if (parts[i].length > 0 && prop.name.index_of(parts[i],0) != 0) {
247 // got a matching property...
250 var sci = new Lsp.CompletionItem.keyword( prop.name + "(", prop.name + "(" , prop.doctxt );
257 // get the properties / methods and subclasses.. of cls..
258 // we have cls.. - see if the string matches any of the properties..
259 citer = cls.props.map_iterator();
260 while (citer.next()) {
261 var prop = citer.get_value();
262 // does the name start with ...
263 //if (parts[i].length > 0 && prop.name.index_of(parts[i],0) != 0) {
267 var sci = new Lsp.CompletionItem.keyword( prop.name, prop.name , prop.doctxt );
290 public override async Gee.ArrayList<Lsp.DocumentSymbol> syntax (JsRender.JsRender file) throws GLib.Error {
291 var ret = new Gee.ArrayList<Lsp.DocumentSymbol>();