4b13f6f8f7ef4f9f8dfce6a0e11af900ea7a8857
[sdk] / ide / src / debugger / debugFindCtx.ec
1 #ifdef ECERE_STATIC
2 import static "ec"
3 #else
4 import "ec"
5 #endif
6
7 //extern Class thisClass;
8 static Class currentClass;
9
10 static bool InsideIncl(Location loc, int line, int charPos)
11 {
12    //return !loc.start.included && (loc.start.line < line || (loc.start.line == line && loc.start.charPos <= charPos)) &&
13    //       (loc.end.line > line || (loc.end.line == line && loc.end.charPos >= charPos));
14    return !loc.start.included && loc.start.line <= line && loc.end.line >= line;
15 }
16
17 static bool Inside(Location loc, int line, int charPos)
18 {
19    //return !loc.start.included && (loc.start.line < line || (loc.start.line == line && loc.start.charPos < charPos)) &&
20    //       (loc.end.line > line || (loc.end.line == line && loc.end.charPos > charPos));
21    return !loc.start.included && loc.start.line < line &&  loc.end.line > line;
22 }
23
24 static bool InsideEndIncl(Location loc, int line, int charPos)
25 {
26    //return !loc.start.included && (loc.start.line < line || (loc.start.line == line && loc.start.charPos < charPos)) &&
27    //       (loc.end.line > line || (loc.end.line == line && loc.end.charPos >= charPos));
28    return !loc.start.included && loc.start.line < line &&  loc.end.line >= line;
29 }
30
31 static Identifier DebugFindCtxSpecifier(Specifier spec, int line, int charPos)
32 {
33    Identifier idResult;
34    switch(spec.type)
35    {
36       case enumSpecifier:
37       case structSpecifier:
38       case unionSpecifier:
39       {
40          if(spec.definitions)
41          {
42             ClassDef def;
43             for(def = spec.definitions->first; def; def = def.next)
44             {
45                // TODO: Should use DebugFindCtxClassDef here right?
46
47                //if(def.type == ClassDefDeclaration && def.decl && def.decl.type == DeclarationStruct)
48                //   ProcessDeclaration(def.decl);
49                switch(def.type)
50                {
51                   case declarationClassDef:
52                      if(InsideIncl(&def.decl.loc, line, charPos))
53                      {
54                         idResult = DebugFindCtxDeclaration(def.decl, line, charPos);
55                         if(idResult)
56                            return idResult;
57                      }
58                      break;
59                   case defaultPropertiesClassDef:
60                   {
61                      MemberInit init;
62                      for(init = def.defProperties->first; init; init = init.next)
63                      {
64                         if(InsideIncl(&init.realLoc, line, charPos))
65                         {
66                            Class oldThisClass = GetThisClass();
67                            Context oldTopContext = GetTopContext();
68                            SetThisClass(currentClass);
69                            idResult = DebugFindCtxMemberInit(init, line, charPos);
70                            if(idResult)
71                               return idResult;
72                            SetThisClass(oldThisClass);
73                         }
74                      }
75                      break;
76                   }
77                   case functionClassDef:
78                      if(InsideIncl(&def.function.loc, line, charPos))
79                      {
80                         idResult = DebugFindCtxClassFunction(def.function, line, charPos);
81
82                         if(idResult)
83                            return idResult;
84                      }
85                      break;
86                   case propertyClassDef:
87                      if(def.propertyDef)
88                      {
89                         if(InsideIncl(&def.propertyDef.loc, line, charPos))
90                         {
91                            idResult = DebugFindCtxProperty(def.propertyDef, line, charPos);
92                            if(idResult)
93                               return idResult;
94                         }
95                      }
96                      break;
97                   case propertyWatchClassDef:
98                      if(def.propertyWatch && def.propertyWatch.compound && InsideIncl(&def.propertyWatch.compound.loc, line, charPos))
99                      {
100                         Class oldThisClass = GetThisClass();
101                         Context oldTopContext = GetTopContext();
102                         SetThisClass(currentClass);
103                         idResult = DebugFindCtxStatement(def.propertyWatch.compound, line, charPos);
104                         if(idResult) return idResult;
105                         SetThisClass(oldThisClass);
106                      }
107                      break;
108                }
109             }
110          }
111          break;
112       }
113    }
114    return null;
115 }
116
117
118 Identifier DebugFindCtxIdentifier(Identifier id, int line, int charPos)
119 {
120    //if(id.loc.end.line == line && id.loc.end.charPos == charPos)
121    //if(InsideIncl(&id.loc.end.line == line && id.loc.end.charPos == charPos)
122
123    if(id.badID && InsideIncl(&id.badID.loc, line, charPos))
124       return DebugFindCtxIdentifier(id.badID, line, charPos);
125
126    return id;
127    //return null;
128 }
129
130 Identifier DebugFindCtxExpression(Expression exp, int line, int charPos)
131 {
132    Identifier idResult = null;
133
134    switch(exp.type)
135    {
136       case newExp:
137          if(InsideIncl(&exp._new.size.loc, line, charPos))
138          {
139             idResult = DebugFindCtxExpression(exp._new.size, line, charPos);
140             if(idResult) return idResult;
141          }
142          break;
143       case renewExp:
144          if(InsideIncl(&exp._renew.exp.loc, line, charPos))
145          {
146             idResult = DebugFindCtxExpression(exp._renew.exp, line, charPos);
147             if(idResult) return idResult;
148          }
149          if(InsideIncl(&exp._renew.size.loc, line, charPos))
150          {
151             idResult = DebugFindCtxExpression(exp._renew.size, line, charPos);
152             if(idResult) return idResult;
153          }
154          break;
155       case constantExp:
156          return (void *)-2;
157       case identifierExp:
158          idResult = DebugFindCtxIdentifier(exp.identifier, line, charPos);
159          if(idResult) return idResult;
160          //return (void *)-1;
161          break;
162       case instanceExp:
163          if(InsideIncl(&exp.instance.loc, line, charPos))
164          {
165             idResult = DebugFindCtxInstance(exp.instance, line, charPos);
166             if(idResult) return idResult;
167          }
168          break;
169       case stringExp:
170          return (void *)-2;
171          //break;
172       case opExp:
173          if(exp.op.exp1)
174          {
175             if(InsideIncl(&exp.op.exp1.loc, line, charPos))
176             {
177                idResult = DebugFindCtxExpression(exp.op.exp1, line, charPos);
178                if(idResult) return idResult;
179             }
180          }
181          if(exp.op.exp2)
182          {
183             // Why was this done?
184             //if(InsideIncl(&exp.op.exp2.loc, line, charPos))
185             if(InsideEndIncl(&exp.op.exp2.loc, line, charPos))
186             {
187                idResult = DebugFindCtxExpression(exp.op.exp2, line, charPos);
188                if(idResult) return idResult;
189             }
190             //return (void *)-1;
191             return (void *)-2;
192          }
193          break;
194       case bracketsExp:
195       {
196          Expression expression;
197
198          for(expression = exp.list->first; expression; expression = expression.next)
199          {
200             if(InsideIncl(&expression.loc, line, charPos))
201             {
202                idResult = DebugFindCtxExpression(expression, line, charPos);
203                if(idResult) return idResult;
204             }
205          }
206          break;
207       }
208       case indexExp:
209       {
210          Expression expression;
211          if(InsideIncl(&exp.index.exp.loc, line, charPos))
212          {
213             idResult = DebugFindCtxExpression(exp.index.exp, line, charPos);
214             if(idResult) return idResult;
215          }
216
217          for(expression = exp.index.index->first; expression; expression = expression.next)
218          {
219             if(InsideIncl(&expression.loc, line, charPos))
220             {
221                idResult = DebugFindCtxExpression(expression, line, charPos);
222                if(idResult) return idResult;
223             }
224          }
225          break;
226       }
227       case callExp:
228       {
229          int arg;
230          Type type = exp.call.exp.expType;
231
232          if(InsideIncl(&exp.call.exp.loc, line, charPos))
233          {
234             idResult = DebugFindCtxExpression(exp.call.exp, line, charPos);
235             if(idResult) return idResult;
236          }
237
238          if(exp.call.argLoc.start.line > line || (line == exp.call.argLoc.start.line && exp.call.argLoc.start.charPos >= charPos))
239             arg = -1;
240          else
241             arg = 0;
242
243          if(exp.call.arguments)
244          {
245             Expression expression;
246
247             for(expression = exp.call.arguments->first; expression; expression = expression.next)
248             {
249                if(InsideIncl(&expression.loc, line, charPos) || (expression.loc.end.line > line || (line == expression.loc.end.line && expression.loc.end.charPos > charPos)))
250                {
251                   if(InsideIncl(&expression.loc, line, charPos))
252                      idResult = DebugFindCtxExpression(expression, line, charPos);
253
254                   // Break
255                   break;
256                }
257                arg++;
258             }
259
260
261             if(idResult)
262                return idResult;
263          }
264          break;
265       }
266       case memberExp:
267          if(InsideIncl(&exp.member.exp.loc, line, charPos))
268          {
269             idResult = DebugFindCtxExpression(exp.member.exp, line, charPos);
270             if(idResult) return idResult;
271          }
272          if(exp.addedThis)
273             return exp.member.member; //(void *)-1;
274
275          break;
276       case pointerExp:
277          if(InsideIncl(&exp.member.exp.loc, line, charPos))
278          {
279             idResult = DebugFindCtxExpression(exp.member.exp, line, charPos);
280             if(idResult) return idResult;
281          }
282          break;
283       case typeSizeExp:
284          break;
285       case castExp:
286          if(InsideIncl(&exp.cast.exp.loc, line, charPos))
287          {
288             idResult = DebugFindCtxExpression(exp.cast.exp, line, charPos);
289             if(idResult) return idResult;
290          }
291          break;
292       case conditionExp:
293          if(InsideIncl(&exp.cond.cond.loc, line, charPos))
294          {
295             idResult = DebugFindCtxExpression(exp.cond.cond, line, charPos);
296             if(idResult) return idResult;
297          }
298
299          {
300             Expression expression;
301             for(expression = exp.cond.exp->first; expression; expression = expression.next)
302             {
303                if(InsideIncl(&expression.loc, line, charPos))
304                {
305                   idResult = DebugFindCtxExpression(expression, line, charPos);
306                   if(idResult) return idResult;
307                }
308             }
309          }
310          if(InsideIncl(&exp.cond.elseExp.loc, line, charPos))
311          {
312             idResult = DebugFindCtxExpression(exp.cond.elseExp, line, charPos);
313             if(idResult) return idResult;
314          }
315          break;
316       case dummyExp:
317          return (void *)-2;
318    }
319    return (void *)-1;
320 }
321
322 static Identifier DebugFindCtxStatement(Statement stmt, int line, int charPos)
323 {
324    Identifier idResult;
325
326    switch(stmt.type)
327    {
328       case labeledStmt:
329          if(InsideIncl(&stmt.labeled.stmt.loc, line, charPos))
330             return DebugFindCtxStatement(stmt.labeled.stmt, line, charPos);
331          break;
332       case caseStmt:
333          if(stmt.caseStmt.exp)
334          {
335             if(InsideIncl(&stmt.caseStmt.exp.loc, line, charPos))
336                return DebugFindCtxExpression(stmt.caseStmt.exp, line, charPos);
337          }
338
339          if(stmt.caseStmt.stmt)
340          {
341             if(InsideIncl(&stmt.caseStmt.stmt.loc, line, charPos))
342                return DebugFindCtxStatement(stmt.caseStmt.stmt, line, charPos);
343          }
344          break;
345       case badDeclarationStmt:
346       {
347          Declaration decl = stmt.decl;
348          if(InsideIncl(&decl.loc, line, charPos))
349          {
350             idResult = DebugFindCtxDeclaration(decl, line, charPos);
351             if(idResult) return idResult;
352          }
353          break;
354       }
355       case compoundStmt:
356       {
357          if(!stmt.compound.isSwitch)
358             SetCurrentContext(stmt.compound.context);
359          if(stmt.compound.declarations)
360          {
361             Declaration decl;
362             for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
363             {
364                if(InsideIncl(&decl.loc, line, charPos))
365                {
366                   idResult = DebugFindCtxDeclaration(decl, line, charPos);
367                   if(idResult) return idResult;
368                }
369             }
370          }
371          if(stmt.compound.statements)
372          {
373             Statement statement;
374             for(statement = stmt.compound.statements->first; statement; statement = statement.next)
375             {
376                if(InsideIncl(&statement.loc, line, charPos))
377                {
378                   idResult = DebugFindCtxStatement(statement, line, charPos);
379                   if(idResult) return idResult;
380                }
381             }
382          }
383          return (void *)-1;
384          //break;
385       }
386       case expressionStmt:
387       {
388          if(stmt.expressions)
389          {
390             Expression exp;
391             for(exp = stmt.expressions->first; exp; exp = exp.next)
392             {
393                if(InsideIncl(&exp.loc, line, charPos))
394                {
395                   idResult = DebugFindCtxExpression(exp, line, charPos);
396                   if(idResult) return idResult;
397                }
398             }
399          }
400          break;
401       }
402       case ifStmt:
403       {
404          Expression exp;
405          for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
406          {
407             if(InsideIncl(&exp.loc, line, charPos))
408             {
409                idResult = DebugFindCtxExpression(exp, line, charPos);
410                if(idResult) return idResult;
411             }
412          }
413          if(stmt.ifStmt.stmt)
414          {
415             if(InsideIncl(&stmt.ifStmt.stmt.loc, line, charPos))
416             {
417                idResult = DebugFindCtxStatement(stmt.ifStmt.stmt, line, charPos);
418                if(idResult) return idResult;
419             }
420          }
421          if(stmt.ifStmt.elseStmt)
422          {
423             if(InsideIncl(&stmt.ifStmt.elseStmt.loc, line, charPos))
424                return DebugFindCtxStatement(stmt.ifStmt.elseStmt, line, charPos);
425          }
426          break;
427       }
428       case switchStmt:
429       {
430          Expression exp;
431          for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
432          {
433             if(InsideIncl(&exp.loc, line, charPos))
434             {
435                idResult = DebugFindCtxExpression(exp, line, charPos);
436                if(idResult) return idResult;
437             }
438          }
439          if(InsideIncl(&stmt.switchStmt.stmt.loc, line, charPos))
440             return DebugFindCtxStatement(stmt.switchStmt.stmt, line, charPos);
441          break;
442       }
443       case whileStmt:
444       {
445          Expression exp;
446          if(stmt.whileStmt.exp)
447          {
448             for(exp = stmt.whileStmt.exp->first; exp; exp = exp.next)
449             {
450                if(InsideIncl(&exp.loc, line, charPos))
451                {
452                   idResult = DebugFindCtxExpression(exp, line, charPos);
453                   if(idResult) return idResult;
454                }
455             }
456          }
457          if(stmt.whileStmt.stmt && InsideIncl(&stmt.whileStmt.stmt.loc, line, charPos))
458             return DebugFindCtxStatement(stmt.whileStmt.stmt, line, charPos);
459          break;
460       }
461       case doWhileStmt:
462       {
463          if(InsideIncl(&stmt.doWhile.stmt.loc, line, charPos))
464          {
465             idResult = DebugFindCtxStatement(stmt.doWhile.stmt, line, charPos);
466             if(idResult) return idResult;
467          }
468
469          if(stmt.doWhile.exp)
470          {
471             Expression exp;
472             for(exp = stmt.doWhile.exp->first; exp; exp = exp.next)
473             {
474                if(InsideIncl(&exp.loc, line, charPos))
475                {
476                   idResult = DebugFindCtxExpression(exp, line, charPos);
477                   if(idResult) return idResult;
478                }
479             }
480          }
481          break;
482       }
483       case forStmt:
484       {
485          Expression exp;
486
487          if(stmt.forStmt.init && InsideIncl(&stmt.forStmt.init.loc, line, charPos))
488          {
489             idResult = DebugFindCtxStatement(stmt.forStmt.init, line, charPos);
490             if(idResult) return idResult;
491          }
492
493          if(stmt.forStmt.check && InsideIncl(&stmt.forStmt.check.loc, line, charPos))
494          {
495             idResult = DebugFindCtxStatement(stmt.forStmt.check, line, charPos);
496             if(idResult) return idResult;
497          }
498
499          if(stmt.forStmt.increment)
500          {
501             for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
502             {
503                if(InsideIncl(&exp.loc, line, charPos))
504                {
505                   idResult = DebugFindCtxExpression(exp, line, charPos);
506                   if(idResult) return idResult;
507                }
508             }
509          }
510
511          if(stmt.forStmt.stmt)
512             return DebugFindCtxStatement(stmt.forStmt.stmt, line, charPos);
513          break;
514       }
515       case gotoStmt:
516          break;
517       case continueStmt:
518          break;
519       case breakStmt:
520          break;
521       case returnStmt:
522          if(stmt.expressions)
523          {
524             Expression exp;
525
526             for(exp = stmt.expressions->first; exp; exp = exp.next)
527             {
528                if(InsideIncl(&exp.loc, line, charPos))
529                {
530                   idResult = DebugFindCtxExpression(exp, line, charPos);
531                   if(idResult) return idResult;
532                }
533             }
534          }
535          break;
536       case fireWatchersStmt:
537       case stopWatchingStmt:
538       {
539          Identifier _watch;
540          if(stmt._watch.watcher && InsideIncl(&stmt._watch.watcher.loc, line, charPos))
541          {
542             idResult = DebugFindCtxExpression(stmt._watch.watcher, line, charPos);
543             if(idResult) return idResult;
544          }
545          if(stmt._watch.object && InsideIncl(&stmt._watch.object.loc, line, charPos))
546          {
547             idResult = DebugFindCtxExpression(stmt._watch.object, line, charPos);
548             if(idResult) return idResult;
549          }
550          if(stmt._watch.watches)
551          {
552             for(_watch = stmt._watch.watches->first; _watch; _watch = _watch.next)
553             {
554                if(InsideIncl(&_watch.loc, line, charPos))
555                {
556                   idResult = DebugFindCtxIdentifier(_watch, line, charPos);
557                   if(idResult) return idResult;
558                }
559             }
560          }
561          break;
562       }
563       case watchStmt:
564       {
565          PropertyWatch _watch;
566          if(stmt._watch.watcher && InsideIncl(&stmt._watch.watcher.loc, line, charPos))
567          {
568             idResult = DebugFindCtxExpression(stmt._watch.watcher, line, charPos);
569             if(idResult) return idResult;
570          }
571          if(stmt._watch.object && InsideIncl(&stmt._watch.object.loc, line, charPos))
572          {
573             idResult = DebugFindCtxExpression(stmt._watch.object, line, charPos);
574             if(idResult) return idResult;
575          }
576          if(stmt._watch.watches)
577          {
578             for(_watch = stmt._watch.watches->first; _watch; _watch = _watch.next)
579             {
580                if(_watch.compound && InsideIncl(&_watch.compound.loc, line, charPos))
581                {
582                   idResult = DebugFindCtxStatement(_watch.compound, line, charPos);
583                   if(idResult) return idResult;
584                }
585             }
586          }
587          break;
588       }
589    }
590    return null;
591 }
592
593 static Identifier DebugFindCtxInitializer(Initializer initializer, int line, int charPos)
594 {
595    switch(initializer.type)
596    {
597       case listInitializer:
598       {
599          Initializer init;
600          Identifier idResult;
601
602          for(init = initializer.list->first; init; init = init.next)
603          {
604             if(InsideIncl(&init.loc, line, charPos))
605             {
606                idResult = DebugFindCtxInitializer(init, line, charPos);
607                if(idResult) return idResult;
608             }
609          }
610          break;
611       }
612       case expInitializer:
613          if(InsideIncl(&initializer.exp.loc, line, charPos))
614             return DebugFindCtxExpression(initializer.exp, line, charPos);
615
616          {
617             return (void *)-1;
618          }
619          break;
620    }
621    return null;
622 }
623
624 static Identifier DebugFindCtxInitDeclarator(InitDeclarator decl, int line, int charPos)
625 {
626    if(decl.initializer && InsideIncl(&decl.initializer.loc, line, charPos))
627       return DebugFindCtxInitializer(decl.initializer, line, charPos);
628    return null;
629 }
630
631 static Identifier DebugFindCtxDeclaration(Declaration decl, int line, int charPos)
632 {
633    Identifier idResult;
634
635    switch(decl.type)
636    {
637       case structDeclaration:
638       {
639          Specifier spec;
640          if(decl.specifiers)
641          {
642             for(spec = decl.specifiers->first; spec; spec = spec.next)
643             {
644                if(InsideIncl(&spec.loc, line, charPos))
645                {
646                   idResult = DebugFindCtxSpecifier(spec, line, charPos);
647                   if(idResult) return idResult;
648                }
649             }
650          }
651          /*Declarator d;
652          if(decl.declarators && decl.declarators.first)
653          {
654             for(d = decl.declarators.first; d; d = d.next)
655             {
656                if(InsideIncl(&d.loc, line, charPos))
657                {
658                   if(d.type == DeclaratorStruct && d.declarator && d.declarator.type == DeclaratorIdentifier)
659                      return d.declarator.identifier;
660                }
661             }
662          }
663          */
664          break;
665       }
666       case initDeclaration:
667       {
668          // Need to loop through specifiers to look for :: completion
669          if(decl.specifiers)
670          {
671             Specifier s;
672
673             for(s = decl.specifiers->first; s; s = s.next)
674             {
675                if(InsideIncl(&s.loc, line, charPos))
676                {
677                   idResult = DebugFindCtxSpecifier(s, line, charPos);
678                   if(idResult) return idResult;
679                }
680             }
681          }
682
683          if(decl.declarators && decl.declarators->first)
684          {
685             InitDeclarator d;
686             for(d = decl.declarators->first; d; d = d.next)
687             {
688                if(InsideIncl(&d.loc, line, charPos))
689                {
690                   idResult = DebugFindCtxInitDeclarator(d, line, charPos);
691                   if(idResult) return idResult;
692                }
693             }
694          }
695          break;
696       }
697       case instDeclaration:
698          if(InsideIncl(&decl.inst.loc, line, charPos))
699             return DebugFindCtxInstance(decl.inst, line, charPos);
700          break;
701    }
702    return null;
703 }
704
705 static Identifier DebugFindCtxFunction(FunctionDefinition func, int line, int charPos)
706 {
707    if(func.body && InsideIncl(&func.body.loc, line, charPos))
708    {
709       Identifier idResult;
710
711       Identifier id = GetDeclId(func.declarator);
712       Symbol symbol = func.declarator.symbol;
713       Type type = symbol.type;
714       Class oldThisClass = GetThisClass();
715       Context oldTopContext = GetTopContext();
716
717       idResult = DebugFindCtxStatement(func.body, line, charPos);
718       if(idResult)
719          return idResult;
720
721       SetThisClass(oldThisClass);
722       SetTopContext(oldTopContext);
723    }
724    return null;
725 }
726
727 static Identifier DebugFindCtxMemberInit(MemberInit init, int line, int charPos)
728 {
729    Identifier idResult;
730    if(init.initializer && InsideIncl(&init.initializer.loc, line, charPos))
731    {
732       idResult = DebugFindCtxInitializer(init.initializer, line, charPos);
733       if(idResult)
734       {
735          return idResult;
736       }
737    }
738    if(init.identifiers && init.identifiers->first && InsideIncl(&((Identifier)init.identifiers->first).loc, line, charPos))
739    {
740       idResult = DebugFindCtxIdentifier(init.identifiers->first, line, charPos);
741       if(idResult)
742          return (void *)-2; //idResult;
743    }
744    if(init.initializer && InsideIncl(&init.initializer.loc, line, charPos))
745    {
746       if(init.initializer.type == expInitializer)
747       {
748          return (void *)-1;
749       }
750    }
751    return null;
752 }
753
754 static Identifier DebugFindCtxInstance(Instantiation inst, int line, int charPos)
755 {
756    Identifier idResult = null;
757    Class oldThisClass = GetThisClass();
758    Symbol sym = inst._class ? FindClass(inst._class.name) : null;
759    bool insideSomething = false;
760    bool insideBrackets;
761
762    if(sym)
763       SetThisClass(sym.registered);
764
765    insideBrackets = !(inst.insideLoc.start.line > line || (line == inst.insideLoc.start.line && inst.insideLoc.start.charPos > charPos));
766
767    if(inst.members)
768    {
769       MembersInit init;
770       MemberInit memberInit;
771       for(init = inst.members->first; init; init = init.next)
772       {
773          if(init.loc.start.line > line || (line == init.loc.start.line && init.loc.start.charPos > charPos))
774             break;
775
776          if(init.type == dataMembersInit && init.dataMembers && insideBrackets && sym)
777          {
778             for(memberInit = init.dataMembers->first; memberInit; memberInit = memberInit.next)
779             {
780                if(!idResult && InsideIncl(&memberInit.realLoc, line, charPos))
781                   idResult = DebugFindCtxMemberInit(memberInit, line, charPos);
782
783                if(InsideIncl(&memberInit.realLoc, line, charPos) || (memberInit.realLoc.end.line > line || (line == memberInit.realLoc.end.line && memberInit.realLoc.end.charPos > charPos)))
784                {
785                   if(memberInit.identifiers && memberInit.identifiers->first && InsideIncl(&memberInit.loc, line, charPos))
786                      insideBrackets = false;
787                   break;
788                }
789                /*else if((!memberInit.identifiers || !memberInit.identifiers->first) && (memberInit.next || !InsideIncl(&init.loc, line, charPos)))
790                   ;
791                */
792             }
793          }
794
795          if(InsideIncl(&init.loc, line, charPos))
796          {
797             if(InsideIncl(&init.loc, line, charPos))
798                if(init.type == methodMembersInit)
799                   insideSomething = true;
800
801             if(init.type == methodMembersInit && InsideIncl(&init.function.loc, line, charPos))
802             {
803                idResult = DebugFindCtxClassFunction(init.function, line, charPos);
804             }
805
806             if(InsideIncl(&init.loc, line, charPos))
807                break;
808          }
809
810          if((init.loc.end.line > line || (line == init.loc.end.line && init.loc.end.charPos > charPos)))
811             break;
812       }
813    }
814    if(idResult)
815       return idResult;
816    SetThisClass(oldThisClass);
817
818    return (void *)-1;  // ?
819 }
820
821 static Identifier DebugFindCtxClassFunction(ClassFunction func, int line, int charPos)
822 {
823    if(func.body && InsideIncl(&func.body.loc, line, charPos))
824    {
825       Identifier idResult;
826
827       Identifier id = GetDeclId(func.declarator);
828       Symbol symbol = func.declarator ? func.declarator.symbol : null;
829       Type type = symbol ? symbol.type : null;
830       Class oldThisClass = GetThisClass();
831       Context oldTopContext = GetTopContext();
832       SetThisClass((type && type.thisClass) ? type.thisClass.registered : currentClass);
833
834       if(func.body)
835       {
836          idResult = DebugFindCtxStatement(func.body, line, charPos);
837          if(idResult)
838             return idResult;
839       }
840
841       SetThisClass(oldThisClass);
842       SetTopContext(oldTopContext);
843    }
844    else if(!func.body && GetFuncDecl(func.declarator))
845    {
846       if(!GetThisClass())
847          SetThisClass(currentClass);
848       return (void *)-1;
849    }
850    else if(!func.body && GetDeclId(func.declarator))
851    {
852       if(!GetThisClass())
853          SetThisClass(currentClass);
854       return (void *)-1;
855    }
856    return null;
857 }
858
859 static Identifier DebugFindCtxProperty(PropertyDef def, int line, int charPos)
860 {
861    Identifier result;
862    if(def.getStmt && InsideIncl(&def.getStmt.loc, line, charPos))
863    {
864       Class oldThisClass = GetThisClass();
865       Context oldTopContext = GetTopContext();
866       SetThisClass(currentClass);
867       result = DebugFindCtxStatement(def.getStmt, line, charPos);
868       if(result) return result;
869       SetThisClass(oldThisClass);
870    }
871    if(def.setStmt && InsideIncl(&def.setStmt.loc, line, charPos))
872    {
873       Class oldThisClass = GetThisClass();
874       Context oldTopContext = GetTopContext();
875       SetThisClass(currentClass);
876       result = DebugFindCtxStatement(def.setStmt, line, charPos);
877       if(result) return result;
878       SetThisClass(oldThisClass);
879    }
880    return null;
881 }
882
883 static Identifier DebugFindCtxClassDef(ClassDef def, int line, int charPos)
884 {
885    Identifier idResult;
886    switch(def.type)
887    {
888       case declarationClassDef:
889          if(InsideIncl(&def.decl.loc, line, charPos))
890          {
891             idResult = DebugFindCtxDeclaration(def.decl, line, charPos);
892             if(idResult)
893                return idResult;
894          }
895          break;
896       case defaultPropertiesClassDef:
897       {
898          MemberInit init;
899          for(init = def.defProperties->first; init; init = init.next)
900          {
901             if(InsideIncl(&init.realLoc, line, charPos))
902             {
903                Class oldThisClass = GetThisClass();
904                Context oldTopContext = GetTopContext();
905                SetThisClass(currentClass);
906                idResult = DebugFindCtxMemberInit(init, line, charPos);
907                if(idResult)
908                   return idResult;
909                SetThisClass(oldThisClass);
910             }
911          }
912          break;
913       }
914       case functionClassDef:
915          if(InsideIncl(&def.function.loc, line, charPos))
916          {
917             idResult = DebugFindCtxClassFunction(def.function, line, charPos);
918
919             if(idResult)
920                return idResult;
921          }
922          break;
923       case propertyClassDef:
924          if(def.propertyDef)
925          {
926             // TOCHECK: Missing thisClass here too?
927
928             if(InsideIncl(&def.propertyDef.loc, line, charPos))
929             {
930                idResult = DebugFindCtxProperty(def.propertyDef, line, charPos);
931                if(idResult)
932                   return idResult;
933             }
934          }
935          break;
936       case propertyWatchClassDef:
937          if(def.propertyWatch && def.propertyWatch.compound && InsideIncl(&def.propertyWatch.compound.loc, line, charPos))
938          {
939             Class oldThisClass = GetThisClass();
940             Context oldTopContext = GetTopContext();
941             SetThisClass(currentClass);
942
943             idResult = DebugFindCtxStatement(def.propertyWatch.compound, line, charPos);
944             if(idResult)
945                return idResult;
946             SetThisClass(oldThisClass);
947          }
948          break;
949    }
950    return null;
951 }
952
953 static Identifier DebugFindCtxClass(ClassDefinition _class, int line, int charPos)
954 {
955    Identifier idResult;
956    bool insideSomething = false;
957    if(_class.definitions)
958    {
959       ClassDef def;
960       for(def = _class.definitions->first; def; def = def.next)
961       {
962          if(def.type == defaultPropertiesClassDef ? InsideIncl(&def.loc, line, charPos) : InsideIncl(&def.loc, line, charPos) )
963          {
964             if(def.type != defaultPropertiesClassDef)
965                insideSomething = true;
966
967             idResult = DebugFindCtxClassDef(def, line, charPos);
968             if(idResult)
969                return idResult;
970          }
971       }
972    }
973    if(!insideSomething)
974    {
975       return (void *)-1;
976    }
977    return null;
978 }
979
980 Identifier DebugFindCtxTree(OldList ast, int line, int charPos)
981 {
982    Identifier idResult;
983    External external;
984
985    SetThisClass(null);
986    if(ast != null)
987    {
988       for(external = ast.first; external; external = external.next)
989       {
990          switch(external.type)
991          {
992             case functionExternal:
993                if(InsideIncl(&external.loc, line, charPos))
994                {
995                   idResult = DebugFindCtxFunction(external.function, line, charPos);
996                   if(idResult)
997                      return (idResult == (void *)-1 || idResult == (void *)-2) ? null : idResult;
998                }
999                break;
1000             case declarationExternal:
1001                if(InsideIncl(&external.loc, line, charPos))
1002                {
1003                   idResult = DebugFindCtxDeclaration(external.declaration, line, charPos);
1004                   if(idResult)
1005                      return (idResult == (void *)-1 || idResult == (void *)-2) ? null : idResult;
1006                }
1007                break;
1008             case classExternal:
1009                if(InsideIncl(&external._class.loc, line, charPos))
1010                {
1011                   currentClass = external._class.symbol.registered;
1012                   idResult = DebugFindCtxClass(external._class, line, charPos);
1013                   currentClass = null;
1014                   if(idResult)
1015                      return (idResult == (void *)-1 || idResult == (void *)-2) ? null : idResult;
1016                }
1017                break;
1018          }
1019       }
1020    }
1021    return null;
1022 }