2 classvar subListSorter;
3 classvar <>currentPath;
4 classvar <defaultServer;
7 subListSorter = { | a b | a[0].perform('<', b[0]) };
9 Class.initClassTree(Server);
12 if (ScIDE.connected) {
19 this.prConnect(ideName);
26 this.prSend(\classLibraryRecompiled);
27 this.prSend(\requestCurrentPath);
29 defaultServer = Server.default;
31 SimpleController(defaultServer)
32 .put(\serverRunning, { | server, what, extraArg |
33 var addr = server.addr;
34 this.prSend(\defaultServerRunningChanged, [server.serverRunning, addr.hostname, addr.port])
37 this.prSend(\defaultServerRunningChanged, [defaultServer.serverRunning, defaultServer.addr.hostname, defaultServer.addr.port]);
39 this.sendIntrospection; // sending the introspection at the end, as otherwise the communication channel seems to get stuck
42 *request { |id, command, data|
43 this.tryPerform(command, id, data);
50 *open { |path, charPos = 0, selectionLength = 0|
51 this.prSend(\openFile, [path, charPos, selectionLength])
57 Class.allClasses.do { |class|
62 class.superclass !? {class.superclass.name},
65 class.methods.collect { |m| this.serializeMethodDetailed(m) };
67 out = out.add(classData);
69 this.prSend(\introspection, out);
72 *sendAllClasses { |id|
73 this.prSend(id, Class.allClasses.collectAs(_.asString, Array))
76 *sendSymbolTable { |id|
80 result = IdentitySet(16384);
81 Class.allClasses.do { | class |
82 if (class.isMetaClass.not) {
83 result.add(class.name);
85 class.methods.do { | method |
86 result.add(method.name);
90 result = result.collectAs(_.asString, Array)
93 "ScIDE: Built symbol table in % seconds\n".postf(dt.asStringPrec(3));
95 this.prSend(id, result)
98 *completeClass { |id, text|
100 Class.allClasses.do { |class|
101 var name = class.name.asString;
102 if (name.beginsWith(text)) {
107 this.prSend(id, out);
111 *completeClassMethod { |id, text|
112 var class, methods, out;
113 class = text.asSymbol.asClass;
115 methods = IdentityDictionary();
117 while { class.notNil } {
118 class.methods.do { |method|
119 // methods include operators like "+", but those are
120 // actually not valid in the method call syntax
121 if (method.name.asString[0].isAlpha &&
122 methods[method.name].isNil)
124 methods.put(method.name, method);
127 class = class.superclass;
129 out = methods.values.collect { |m| this.serializeMethod(m) };
130 if (out.size > 0) { this.prSend(id, out) };
134 *completeMethod { |id, text|
137 Class.allClasses.do { |class|
138 class.methods.do { |method|
141 if (method.name.asString.beginsWith(text)) {
142 out = out.add( this.serializeMethod(method) );
146 if (out.size > 0) { this.prSend(id, out) };
149 *findMethod { |id, text|
150 var cname, mname, tokens, out;
153 tokens = text.split($.);
154 if (tokens.size > 1) {
160 if (mname.size < 1) { ^this };
162 if (cname.size > 0) {
163 class = cname.asSymbol.asClass;
165 warn("No class named" + cname.asString);
168 method = class.class.findRespondingMethodFor(mname.asSymbol);
170 warn("No such method:" + cname.asString ++ "." ++ mname.asString);
173 this.prSend(id, [this.serializeMethod(method)]);
176 this.allMethodsDo { |method|
177 if (method.name.asString == mname) {
178 out = out.add( this.serializeMethod(method) );
184 warn("No such method:" + mname.asString);
190 *serializeMethod { arg method;
191 var data = [method.ownerClass.name, method.name];
192 if (method.argNames.size > 1) {
194 method.argNames.as(Array),
195 method.prototypeFrame.collect { |val| val !? val.cs }
201 *serializeMethodDetailed { arg method;
204 if (method.argNames.size > 1) {
206 method.argNames.as(Array),
207 method.prototypeFrame.collect { |val|
209 if (val.class === Float) { val.asString } { val.cs }
215 method.ownerClass.name,
217 method.filenameSymbol,
224 *allMethodsDo { arg func;
225 Class.allClasses.do { |class|
226 class.methods.do { |method|
232 *findReferencesToSymbol {|requestId, symbol|
234 var result = SortedList(8, subListSorter);
235 var references = Class.findAllReferences(symbol.asSymbol);
237 if (references.notNil) {
238 methods = IdentitySet.new;
239 references.do { | funcDef |
241 homeContext = if(funcDef.context.isNil) {funcDef} {funcDef.context.homeContext};
242 if (homeContext.isKindOf(Method)) {
243 methods.add(homeContext);
246 methods.do { | method |
248 method.ownerClass.name,
250 method.filenameSymbol.asString,
256 ScIDE.prSend(requestId, [symbol, result.asArray])
264 *prConnect {|ideName|