TFModuleTrees.Mod 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757
  1. MODULE TFModuleTrees; (** AUTHOR "tf"; PURPOSE "parse tree with links to text"; *)
  2. IMPORT
  3. WMStandardComponents, WMGraphics, WMProperties, WMComponents,
  4. Strings, KernelLog, WMTrees, PETTrees,
  5. BimboScanner, TFAOParser, TS := TFTypeSys, ST := TFScopeTools,
  6. Kernel, WMPopups, WMTextView, WMEditors, TextUtilities, Texts, WMDialogs,
  7. Diagnostics, Streams, Raster, WMRectangles,
  8. WMStringGrids, WMGrids, WMWindowManager, WMMessages;
  9. CONST
  10. ProcOther = 0;
  11. ProcCommand = 1;
  12. ImageCommandProc = "ModuleTreesIcons.tar://arrow-red.png";
  13. DoAutoRefresh = FALSE;
  14. TYPE
  15. Reference = POINTER TO RECORD
  16. next : Reference;
  17. fp, tp, np : LONGINT;
  18. no : TS.NamedObject;
  19. END;
  20. RefArray = POINTER TO ARRAY OF Reference;
  21. Comment = POINTER TO RECORD
  22. next : Comment;
  23. fp, tp : LONGINT;
  24. h : WMTextView.Highlight;
  25. END;
  26. CurrentHighlights = POINTER TO RECORD
  27. next : CurrentHighlights;
  28. h : WMTextView.Highlight;
  29. END;
  30. TextInfo = OBJECT(PETTrees.TreeNode)
  31. VAR
  32. next : TextInfo;
  33. fp, tp : LONGINT;
  34. name : Strings.String;
  35. def : TS.NamedObject;
  36. END TextInfo;
  37. SelectWindow* = OBJECT (WMComponents.FormWindow)
  38. VAR edit : WMEditors.Editor;
  39. list : WMStringGrids.StringGrid;
  40. spacings : WMGrids.Spacings;
  41. curEditStr : ARRAY 64 OF CHAR;
  42. table : TS.ObjectList;
  43. scope: TS.Scope;
  44. firstLevel : BOOLEAN;
  45. destinationText : Texts.Text;
  46. startPos, cursorPos : LONGINT;
  47. PROCEDURE CreateForm(): WMComponents.VisualComponent;
  48. VAR
  49. panel : WMStandardComponents.Panel;
  50. ep, sb, sr, gb, gr, d : WMStandardComponents.Panel;
  51. BEGIN
  52. NEW(panel); panel.bounds.SetExtents(200, 160); panel.fillColor.Set(0); panel.takesFocus.Set(TRUE);
  53. (* right shadow *)
  54. NEW(sr); sr.bounds.SetWidth(4); sr.alignment.Set(WMComponents.AlignRight); sr.fillColor.Set(0);
  55. panel.AddContent(sr);
  56. NEW(d); d.bounds.SetHeight(4); d.alignment.Set(WMComponents.AlignTop); d.fillColor.Set(0);
  57. sr.AddContent(d);
  58. NEW(gr); gr.alignment.Set(WMComponents.AlignClient); gr.fillColor.Set(080H);
  59. sr.AddContent(gr);
  60. (* bottom shadow *)
  61. NEW(sb); sb.bounds.SetHeight(4); sb.alignment.Set(WMComponents.AlignBottom); sb.fillColor.Set(0);
  62. panel.AddContent(sb);
  63. NEW(d); d.bounds.SetWidth(4); d.alignment.Set(WMComponents.AlignLeft); d.fillColor.Set(0);
  64. sb.AddContent(d);
  65. NEW(gb); gb.alignment.Set(WMComponents.AlignClient); gb.fillColor.Set(080H);
  66. sb.AddContent(gb);
  67. (* edit panel *)
  68. NEW(ep); ep.alignment.Set(WMComponents.AlignClient); ep.fillColor.Set(LONGINT(0DDDD00EEH));
  69. panel.AddContent(ep);
  70. NEW(edit); edit.bounds.SetHeight(20); edit.alignment.Set(WMComponents.AlignTop); edit.tv.showBorder.Set(TRUE);
  71. edit.tv.defaultTextBgColor.Set(0);
  72. edit.tv.borders.Set(WMRectangles.MakeRect(3, 3, 2, 2));
  73. edit.allowIME := FALSE;
  74. edit.multiLine.Set(FALSE);
  75. edit.tv.textAlignV.Set(WMGraphics.AlignCenter);
  76. ep.AddContent(edit);
  77. NEW(list); list.alignment.Set(WMComponents.AlignClient);
  78. NEW(spacings, 2); spacings[0] := 60; spacings[1] := 140;
  79. list.SetExtKeyEventHandler(ListKeyPressed);
  80. list.Acquire;
  81. list.defaultRowHeight.Set(25);
  82. list.cellDist.Set(0);
  83. list.clCell.Set(LONGINT(0FFFFFFA0H));
  84. (*list.SetColSpacings(spacings);
  85. list.SetFont(WMGraphics.GetFont("Single", 20, {})); *)
  86. list.Release;
  87. ep.AddContent(list);
  88. RETURN panel
  89. END CreateForm;
  90. PROCEDURE &New*(text: Texts.Text; startPos, cursorPos, x, y :LONGINT; CONST prefix : ARRAY OF CHAR; scope : TS.Scope; first: BOOLEAN);
  91. VAR vc : WMComponents.VisualComponent;
  92. BEGIN
  93. vc := CreateForm();
  94. edit.onEnter.Add(Ok);
  95. edit.tv.SetExtKeyEventHandler(EditKeyPressed);
  96. SELF.table := table;
  97. SELF.firstLevel := first;
  98. SELF.scope := scope;
  99. SELF.destinationText := text;
  100. SELF.startPos := startPos;
  101. SELF.cursorPos := cursorPos;
  102. Init(vc.bounds.GetWidth(), vc.bounds.GetHeight(), TRUE);
  103. SetContent(vc);
  104. manager := WMWindowManager.GetDefaultManager();
  105. manager.Add(x, y, SELF, {});
  106. manager.SetFocus(SELF);
  107. edit.text.onTextChanged.Add(TextChanged);
  108. edit.SetAsString(prefix);
  109. edit.SetFocus;
  110. END New;
  111. PROCEDURE ListKeyPressed(ucs : LONGINT; flags : SET; VAR keySym : LONGINT; VAR handled : BOOLEAN);
  112. BEGIN
  113. IF keySym = 0FF0DH THEN handled := TRUE; Ok(SELF, NIL); (*edit.SetFocus*)
  114. ELSIF keySym = 0FF1BH THEN ScheduleHide
  115. END;
  116. END ListKeyPressed;
  117. PROCEDURE EditKeyPressed(ucs : LONGINT; flags : SET; VAR keySym : LONGINT; VAR handled : BOOLEAN);
  118. BEGIN
  119. handled := TRUE;
  120. (* IF keySym = 0FF08H THEN
  121. IF curEditStr = "" THEN ScheduleHide
  122. ELSE edit.KeyPressed(ucs, flags, keySym, handled)
  123. END
  124. ELS*)
  125. IF keySym = 0FF0DH THEN handled := TRUE; Ok(SELF, NIL)
  126. ELSIF keySym = 0FF54H (*CursorDown*) THEN list.SetFocus
  127. ELSIF keySym = 0FF1BH (*ESC *)THEN ScheduleHide
  128. ELSE
  129. (*handled := FALSE; *)
  130. edit.KeyPressed(ucs, flags, keySym, handled)
  131. END;
  132. END EditKeyPressed;
  133. PROCEDURE ScheduleHide;
  134. VAR msg : WMMessages.Message;
  135. BEGIN
  136. msg.msgType := WMMessages.MsgExt;
  137. msg.ext := SELF;
  138. IF ~sequencer.Add(msg) THEN KernelLog.String("IME Editor out of sync") END;
  139. END ScheduleHide;
  140. PROCEDURE WriteSelected;
  141. VAR ac, ar, bc, br : LONGINT;
  142. p : ANY;
  143. index, i : LONGINT;
  144. str, newStr : ARRAY 1024 OF CHAR;
  145. signature : TS.ProcedureSignature;
  146. singleSuggestion : TS.NamedObject;
  147. BEGIN
  148. list.Acquire;
  149. list.model.Acquire;
  150. list.GetSelection(ac, ar, bc, br);
  151. p := list.model.GetCellData(0, ar);
  152. list.model.Release;
  153. list.Release;
  154. IF (p # NIL) & (p IS TS.NamedObject) THEN
  155. singleSuggestion := p(TS.NamedObject);
  156. index := 0;
  157. destinationText.AcquireWrite;
  158. TextUtilities.SubTextToStrAt(destinationText, startPos, cursorPos - startPos, index, str);
  159. IF Strings.StartsWith2(str, singleSuggestion.name^) THEN
  160. destinationText.Delete(startPos, cursorPos - startPos);
  161. GetInsertString(singleSuggestion, newStr);
  162. TextUtilities.StrToText(destinationText, startPos, newStr);
  163. END;
  164. destinationText.ReleaseWrite;
  165. END
  166. END WriteSelected;
  167. PROCEDURE ClearSelection;
  168. BEGIN
  169. list.Acquire;
  170. list.model.Acquire;
  171. list.model.SetNofRows(0);
  172. list.model.Release;
  173. list.Release;
  174. END ClearSelection;
  175. PROCEDURE Ok*(sender, data:ANY);
  176. BEGIN
  177. WriteSelected;
  178. ScheduleHide
  179. END Ok;
  180. PROCEDURE TextChanged*(sender, data:ANY);
  181. VAR nof, i : LONGINT;
  182. suggestionStr : ARRAY 1024 OF CHAR;
  183. BEGIN
  184. (* avoid recursion *)
  185. edit.text.onTextChanged.Remove(TextChanged);
  186. (* find the character candidates *)
  187. edit.GetAsString(curEditStr);
  188. NEW(table);
  189. FindSuggestions(scope, firstLevel,curEditStr, table);
  190. list.Acquire;
  191. list.model.Acquire;
  192. list.SetTopPosition(0, 0, TRUE);
  193. list.SetSelection(0, 0, 0, 0);
  194. list.model.SetNofRows(table.nofObjs);
  195. list.model.SetNofCols(1);
  196. FOR i := 0 TO table.nofObjs -1 DO
  197. GetInsertString(table.objs[i], suggestionStr);
  198. list.model.SetCellText(0, i, Strings.NewString(suggestionStr));
  199. list.model.SetCellData(0, i, table.objs[i]);
  200. END;
  201. list.model.Release;
  202. list.Release;
  203. edit.text.onTextChanged.Add(TextChanged)
  204. END TextChanged;
  205. PROCEDURE FocusLost*;
  206. BEGIN
  207. FocusLost^;
  208. ScheduleHide
  209. END FocusLost;
  210. PROCEDURE Hide;
  211. BEGIN
  212. manager := WMWindowManager.GetDefaultManager();
  213. manager.Remove(SELF);
  214. END Hide;
  215. PROCEDURE Handle*(VAR x: WMMessages.Message);
  216. BEGIN
  217. IF (x.msgType = WMMessages.MsgExt) THEN
  218. IF (x.ext = SELF) THEN Hide
  219. END
  220. ELSE Handle^(x)
  221. END
  222. END Handle;
  223. END SelectWindow;
  224. ModuleTree* = OBJECT (PETTrees.Tree)
  225. VAR
  226. nextUseBtn, renameBtn, publicBtn: WMStandardComponents.Button;
  227. updateTimer : WMStandardComponents.Timer;
  228. useHighlights : CurrentHighlights;
  229. currentNode : TextInfo;
  230. definitions : TextInfo;
  231. currentUse : Reference;
  232. actualParameter : Reference;
  233. modified : BOOLEAN;
  234. module : TS.Module;
  235. posKeeper : TextUtilities.TextPositionKeeper;
  236. comments : Comment;
  237. references : Reference;
  238. errorHighlights, tempHighlights: CurrentHighlights;
  239. singleSuggestion : TS.NamedObject;
  240. suggestionStart : LONGINT;
  241. cursorScope : TS.Scope;
  242. cursorIsFirstLevelScope : BOOLEAN;
  243. PROCEDURE & Init*;
  244. BEGIN
  245. Init^;
  246. treeView.SetExtContextMenuHandler(ContextMenu);
  247. NEW(renameBtn); renameBtn.alignment.Set(WMComponents.AlignLeft);
  248. renameBtn.caption.SetAOC("Rename");
  249. renameBtn.onClick.Add(RenameHandler);
  250. toolbar.AddContent(renameBtn);
  251. NEW(nextUseBtn); nextUseBtn.alignment.Set(WMComponents.AlignLeft);
  252. nextUseBtn.caption.SetAOC("Next Use");
  253. nextUseBtn.onClick.Add(NextUseHandler);
  254. toolbar.AddContent(nextUseBtn);
  255. NEW(publicBtn); publicBtn.alignment.Set(WMComponents.AlignLeft);
  256. publicBtn.caption.SetAOC("public");
  257. publicBtn.isToggle.Set(TRUE);
  258. publicBtn.onClick.Add(PublicBtnHandler);
  259. toolbar.AddContent(publicBtn);
  260. treeView.onStartDrag.Add(OnStartDrag);
  261. NEW(updateTimer);
  262. updateTimer.onTimer.Add(RefreshHandler);
  263. updateTimer.interval.Set(100);
  264. END Init;
  265. PROCEDURE OnStartDrag(sender, data : ANY);
  266. VAR w, h: LONGINT; img: WMGraphics.Image; canvas: WMGraphics.BufferCanvas;
  267. BEGIN
  268. NEW(img);
  269. treeView.MeasureNode(treeView.draggedNode, w, h);
  270. Raster.Create(img, w, h, Raster.BGRA8888);
  271. NEW(canvas, img);
  272. canvas.SetColor(LONGINT(0FF00FFFFH));
  273. canvas.Fill(WMRectangles.MakeRect(0, 0, w, h), LONGINT(0FF00FFFFH), WMGraphics.ModeCopy);
  274. KernelLog.String("w= "); KernelLog.Int(w, 0); KernelLog.String("h= "); KernelLog.Int(h, 0); KernelLog.Ln;
  275. canvas.DrawString(5, h - 10, "huga");
  276. IF StartDrag(treeView.draggedNode, img, 0, 0, NIL, NIL) THEN
  277. KernelLog.String("drag started"); KernelLog.Ln;
  278. END;
  279. END OnStartDrag;
  280. PROCEDURE SetEditor*(e: WMEditors.Editor);
  281. BEGIN
  282. IF e = editor THEN RETURN END;
  283. IF (highlight # NIL) & (editor # NIL) THEN
  284. editor.tv.onCtrlClicked.Remove(Follow);
  285. editor.text.onTextChanged.Remove(TextChanged);
  286. editor.macros.Remove(HandleMacro);
  287. END;
  288. SetEditor^(e);
  289. editor.text.onTextChanged.Add(TextChanged);
  290. editor.macros.Add(HandleMacro);
  291. editor.tv.onCtrlClicked.Add(Follow);
  292. NEW(posKeeper, editor.text);
  293. END SetEditor;
  294. PROCEDURE BrowseToDefinition*(sender, data : ANY);
  295. VAR pos : SIZE;
  296. no : TS.NamedObject;
  297. scope : TS.Scope;
  298. ident : ARRAY 64 OF CHAR;
  299. definition : ARRAY 256 OF CHAR;
  300. PROCEDURE GetTypeScope(type : TS.Type) : TS.Scope;
  301. BEGIN
  302. CASE type.kind OF
  303. |TS.TObject : RETURN type.object.scope
  304. |TS.TArray : RETURN GetTypeScope(type.array.base)
  305. |TS.TPointer : RETURN GetTypeScope(type.pointer.type)
  306. |TS.TRecord : RETURN type.record.scope
  307. ELSE
  308. END;
  309. RETURN NIL
  310. END GetTypeScope;
  311. BEGIN
  312. IF ~IsCallFromSequencer() THEN
  313. sequencer.ScheduleEvent(SELF.BrowseToDefinition, sender, data);
  314. RETURN
  315. END;
  316. COPY(data(PETTrees.ExternalDefinitionInfo).definition, definition);
  317. pos := Strings.Pos(".", definition);
  318. IF pos > 0 THEN
  319. Strings.Copy(definition, 0, pos, ident);
  320. Strings.Delete(definition, 0, pos + 1)
  321. END;
  322. IF module.name^ = ident THEN
  323. IF module.scope = NIL THEN
  324. KernelLog.String("The module has no scope."); KernelLog.Ln;
  325. END
  326. END;
  327. scope := module.scope;
  328. WHILE (definition # "") & (scope # NIL) DO
  329. pos := Strings.Pos(".", definition);
  330. IF pos > 0 THEN
  331. Strings.Copy(definition, 0, pos, ident);
  332. Strings.Delete(definition, 0, pos + 1)
  333. ELSE COPY(definition, ident); definition := ""
  334. END;
  335. no := scope.Find(ident, FALSE);
  336. IF no # NIL THEN scope := no.scope END;
  337. IF no IS TS.TypeDecl THEN scope := GetTypeScope(no(TS.TypeDecl).type) END;
  338. END;
  339. IF no # NIL THEN
  340. IF SelectNodeByNamedObject(no, TRUE) THEN END;
  341. ELSE
  342. KernelLog.String("Definition not found"); KernelLog.Ln;
  343. END
  344. END BrowseToDefinition;
  345. PROCEDURE Complete*(sender, data : ANY);
  346. VAR pos, index, i : LONGINT;
  347. str : ARRAY 64 OF CHAR;
  348. newStr : ARRAY 1024 OF CHAR;
  349. signature : TS.ProcedureSignature;
  350. x, y : LONGINT;
  351. selector : SelectWindow;
  352. BEGIN
  353. IF ~IsCallFromSequencer() THEN
  354. sequencer.ScheduleEvent(SELF.Complete, sender, data);
  355. RETURN
  356. END;
  357. tree.Acquire;
  358. editor.text.AcquireWrite;
  359. IF modified THEN
  360. Refresh(tree.GetRoot());
  361. END;
  362. pos := editor.tv.cursor.GetPosition();
  363. IF (singleSuggestion # NIL) & (pos - suggestionStart > 0) THEN
  364. index := 0;
  365. TextUtilities.SubTextToStrAt(editor.text, suggestionStart, pos - suggestionStart, index, str);
  366. IF Strings.StartsWith2(str, singleSuggestion.name^) THEN
  367. editor.text.Delete(suggestionStart, pos - suggestionStart);
  368. GetInsertString(singleSuggestion, newStr);
  369. TextUtilities.StrToText(editor.text, suggestionStart, newStr);
  370. END
  371. ELSE
  372. index := 0;
  373. TextUtilities.SubTextToStrAt(editor.text, suggestionStart, pos - suggestionStart, index, str);
  374. IF editor.tv.FindScreenPos(pos, x, y) THEN
  375. editor.tv.ToWMCoordinates(x, y, x, y);
  376. NEW(selector, editor.text, suggestionStart, pos, x, y, str, cursorScope, cursorIsFirstLevelScope)
  377. END;
  378. END;
  379. FINALLY
  380. editor.text.ReleaseWrite;
  381. tree.Release;
  382. END Complete;
  383. PROCEDURE ContextMenu(sender : ANY; x, y: LONGINT);
  384. VAR wmx, wmy : LONGINT;
  385. popup: WMPopups.Popup;
  386. BEGIN
  387. NEW(popup);
  388. IF ~modified THEN
  389. popup.AddParButton("Rename", RenameHandler, NIL);
  390. popup.AddParButton("SelectRange", SelectRangeHandler, NIL);
  391. END;
  392. IF currentNode # NIL THEN
  393. IF HasActualParameters(currentNode.def) THEN
  394. popup.AddParButton("Delete actual parameters", DelActualParameterHandler, NIL);
  395. END;
  396. END;
  397. treeView.Acquire; treeView.ToWMCoordinates(x, y, wmx, wmy); treeView.Release;
  398. popup.Popup(wmx, wmy)
  399. END ContextMenu;
  400. (* Caller must hold text and tree lock *)
  401. PROCEDURE Refresh(rootNode: WMTrees.TreeNode);
  402. VAR
  403. p : TFAOParser.Parser;
  404. scanner: BimboScanner.Scanner;
  405. done : BOOLEAN;
  406. cr : Reference; count, i : LONGINT; refs : RefArray;
  407. t0, t1: LONGINT; res: WORD;
  408. child: WMTrees.TreeNode;
  409. PROCEDURE QuickSort(references: RefArray; lo, hi: LONGINT);
  410. VAR i, j: LONGINT; x, t: Reference;
  411. BEGIN
  412. i := lo; j := hi;
  413. x := references[(lo+hi) DIV 2];
  414. WHILE (i <= j) DO
  415. WHILE (posKeeper.GetPos(references[i].fp) < posKeeper.GetPos(x.fp)) DO INC(i) END;
  416. WHILE (posKeeper.GetPos(x.fp) < posKeeper.GetPos(references[j].fp)) DO DEC(j) END;
  417. IF (i <= j) THEN
  418. t := references[i]; references[i] := references[j]; references[j] := t;
  419. INC(i); DEC(j)
  420. END
  421. END;
  422. IF (lo < j) THEN QuickSort(references, lo, j) END;
  423. IF (i < hi) THEN QuickSort(references, i, hi) END
  424. END QuickSort;
  425. BEGIN
  426. child := tree.GetChildren(rootNode);
  427. WHILE child # NIL DO
  428. tree.RemoveNode(child);
  429. child := tree.GetChildren(rootNode)
  430. END;
  431. done := FALSE;
  432. IF DoAutoRefresh THEN
  433. updateTimer.Stop(SELF, NIL);
  434. END;
  435. t0 := Kernel.GetTicks();
  436. currentNode := NIL;
  437. scanner := BimboScanner.InitWithText(editor.text, 0);
  438. NEW(p); p.Parse(scanner); module := p.m;
  439. (* TODO: check for parse errors *)
  440. IF module # NIL THEN
  441. ClearHighlights;
  442. ClearErrorHighlights;
  443. posKeeper.Clear;
  444. tree.SetNodeState(rootNode, {WMTrees.NodeAlwaysExpanded});
  445. tree.SetNodeCaption(rootNode, module.name);
  446. tree.SetNodeData(rootNode, GetTextInfo(module.name^, module.pos.a, module.pos.b, 0FFH, {WMGraphics.FontBold}, module));
  447. definitions := NIL; references := NIL; singleSuggestion := NIL; actualParameter := NIL;
  448. IF module.altPos.valid THEN
  449. NEW(references); references.no := module;
  450. references.fp := posKeeper.AddPos(module.altPos.a);
  451. references.tp := posKeeper.AddPos(module.altPos.b);
  452. END;
  453. TraverseScope(rootNode, module.scope);
  454. comments := NIL;
  455. SearchUses(module.scope, references);
  456. (* This seems to lose a reference.
  457. IF references # NIL THEN
  458. (* copy references into an array for easy sortation *)
  459. cr := references; count := 0; WHILE cr # NIL DO INC(count); cr := cr.next END;
  460. NEW(refs, count); cr := references; i:= 0; WHILE cr # NIL DO refs[i] := cr; INC(i); cr := cr.next END;
  461. QuickSort(refs, 0, LEN(refs^) -1);
  462. (* recreate the linear list for reuse *)
  463. references := refs[0]; cr := references;
  464. FOR i := 1 TO count - 1 DO cr.next := refs[i]; cr := cr.next; END;
  465. refs[count - 1].next := NIL;
  466. (* KernelLog.String("reference count= "); KernelLog.Int(count, 0); KernelLog.Ln; *)
  467. END; *)
  468. modified := FALSE;
  469. END;
  470. t1 := Kernel.GetTicks();
  471. KernelLog.Int((t1-t0), 0); KernelLog.String("ms"); KernelLog.Ln;
  472. done := TRUE;
  473. (* Need to catch errors to release locks and let the editing continue*)
  474. FINALLY
  475. IF ~done THEN
  476. TextUtilities.Store(editor.text, "crashtext.txt", "UTF-8", res)
  477. END
  478. END Refresh;
  479. PROCEDURE AddNodes*(parent : PETTrees.TreeNode; diagnostics : Diagnostics.Diagnostics; log : Streams.Writer);
  480. BEGIN
  481. AddNodes^(parent, diagnostics, log);
  482. Refresh(parent)
  483. END AddNodes;
  484. PROCEDURE HighlightReferences(no : TS.NamedObject);
  485. VAR
  486. cur : CurrentHighlights;
  487. cr : Reference;
  488. BEGIN
  489. ClearHighlights();
  490. cr := references;
  491. WHILE cr # NIL DO
  492. IF cr.no = no THEN
  493. NEW(cur); cur.next := useHighlights; useHighlights := cur;
  494. cur.h := editor.tv.CreateHighlight();
  495. cur.h.SetColor(07FFF3380H);
  496. cur.h.SetFromTo(posKeeper.GetPos(cr.fp),posKeeper.GetPos(cr.tp));
  497. END;
  498. cr := cr.next
  499. END;
  500. END HighlightReferences;
  501. PROCEDURE SelectReferences(d : TextInfo; gotoDef : BOOLEAN);
  502. BEGIN
  503. editor.DisableUpdate;
  504. currentNode := d;
  505. currentUse := NIL;
  506. HighlightReferences(d.def);
  507. IF gotoDef THEN
  508. editor.tv.cursor.SetPosition(posKeeper.GetPos(currentNode.fp));
  509. editor.tv.cursor.SetVisible(TRUE);
  510. END;
  511. highlight.SetFromTo(posKeeper.GetPos(currentNode.fp), posKeeper.GetPos(currentNode.tp));
  512. editor.EnableUpdate;
  513. editor.Invalidate()
  514. END SelectReferences;
  515. PROCEDURE SelectActualParameters(def : TS.NamedObject);
  516. VAR
  517. cur : CurrentHighlights;
  518. cr : Reference; tp : LONGINT;
  519. BEGIN
  520. editor.DisableUpdate;
  521. cr := actualParameter;
  522. WHILE cr # NIL DO
  523. IF cr.no = def THEN
  524. NEW(cur); cur.next := useHighlights; useHighlights := cur;
  525. cur.h := editor.tv.CreateHighlight();
  526. cur.h.SetColor(000FF3380H);
  527. IF cr.np # -1 THEN tp := posKeeper.GetPos(cr.np) ELSE tp := posKeeper.GetPos(cr.tp) END;
  528. cur.h.SetFromTo(posKeeper.GetPos(cr.fp), tp);
  529. END;
  530. cr := cr.next
  531. END;
  532. editor.EnableUpdate;
  533. editor.Invalidate()
  534. END SelectActualParameters;
  535. PROCEDURE HasActualParameters(def : TS.NamedObject) : BOOLEAN;
  536. VAR
  537. cr : Reference;
  538. BEGIN
  539. cr := actualParameter;
  540. WHILE cr # NIL DO
  541. IF cr.no = def THEN RETURN TRUE END;
  542. cr := cr.next
  543. END;
  544. RETURN FALSE
  545. END HasActualParameters;
  546. PROCEDURE ClickNode*(sender, data : ANY);
  547. VAR
  548. d: ANY;
  549. text : Texts.Text;
  550. BEGIN
  551. currentNode := NIL;
  552. IF (data # NIL) & (data IS WMTrees.TreeNode) THEN
  553. tree.Acquire;
  554. d := tree.GetNodeData(data(WMTrees.TreeNode));
  555. tree.Release;
  556. IF (d # NIL) & (d IS TextInfo) THEN
  557. IF d(TextInfo).def # NIL THEN
  558. KernelLog.String("def.name= "); KernelLog.String(d(TextInfo).def.name^); KernelLog.Ln;
  559. ST.ID(d(TextInfo).def);
  560. ELSE KernelLog.String("def.name=NIL"); KernelLog.Ln
  561. END;
  562. text := editor.text;
  563. text.AcquireRead;
  564. SelectReferences(d(TextInfo), TRUE);
  565. SelectActualParameters(d(TextInfo).def);
  566. text.ReleaseRead;
  567. editor.SetFocus()
  568. END
  569. END
  570. END ClickNode;
  571. PROCEDURE ClearHighlights;
  572. VAR cc : Comment;
  573. cur : CurrentHighlights;
  574. BEGIN
  575. editor.DisableUpdate;
  576. (* remove comment highlights *)
  577. cc := comments;
  578. WHILE cc # NIL DO
  579. IF cc.h # NIL THEN editor.tv.RemoveHighlight(cc.h) END;
  580. cc := cc.next
  581. END;
  582. (* remove use highlight *)
  583. cur := useHighlights;
  584. WHILE cur # NIL DO
  585. editor.tv.RemoveHighlight(cur.h);
  586. cur := cur.next
  587. END;
  588. useHighlights := NIL;
  589. editor.EnableUpdate;
  590. editor.Invalidate()
  591. END ClearHighlights;
  592. PROCEDURE ClearErrorHighlights;
  593. VAR cur : CurrentHighlights;
  594. BEGIN
  595. editor.DisableUpdate;
  596. cur := errorHighlights;
  597. WHILE cur # NIL DO
  598. editor.tv.RemoveHighlight(cur.h);
  599. cur := cur.next
  600. END;
  601. errorHighlights := NIL;
  602. cur := tempHighlights;
  603. WHILE cur # NIL DO
  604. editor.tv.RemoveHighlight(cur.h);
  605. cur := cur.next
  606. END;
  607. tempHighlights := NIL;
  608. singleSuggestion := NIL;
  609. editor.EnableUpdate;
  610. editor.Invalidate()
  611. END ClearErrorHighlights;
  612. PROCEDURE PublicBtnHandler(sender, data: ANY);
  613. VAR
  614. node : WMTrees.TreeNode;
  615. d : ANY;
  616. no : TS.NamedObject;
  617. public : BOOLEAN;
  618. BEGIN
  619. tree.Acquire;
  620. public := publicBtn.GetPressed();
  621. node := tree.GetRoot();
  622. WHILE node # NIL DO
  623. node := GetNextNode(node, FALSE);
  624. d := tree.GetNodeData(node);
  625. IF (d # NIL) & (d IS TextInfo) THEN
  626. IF (d(TextInfo).def # NIL) & (d(TextInfo).def IS TS.NamedObject) THEN
  627. no := d(TextInfo).def(TS.NamedObject);
  628. IF public & (no.exportState = {}) THEN
  629. tree.InclNodeState(node, WMTrees.NodeHidden)
  630. ELSE
  631. tree.ExclNodeState(node, WMTrees.NodeHidden)
  632. END
  633. END
  634. END
  635. END;
  636. tree.Release;
  637. END PublicBtnHandler;
  638. PROCEDURE RenameHandler(sender, data: ANY);
  639. VAR name, curname : ARRAY 64 OF CHAR;
  640. instances, replacements : LONGINT;
  641. cur : Reference;
  642. PROCEDURE Replace(a, b : LONGINT; CONST old, new : ARRAY OF CHAR) : BOOLEAN;
  643. VAR oldname : ARRAY 64 OF CHAR;
  644. BEGIN
  645. TextUtilities.SubTextToStr(editor.text, a, b - a, oldname);
  646. IF oldname = old THEN
  647. editor.text.Delete(a, b - a);
  648. TextUtilities.StrToText(editor.text, a, new);
  649. RETURN TRUE
  650. ELSE
  651. KernelLog.String(curname); KernelLog.String(" expected "); KernelLog.String(oldname); KernelLog.String(" found. Not replaced"); KernelLog.Ln;
  652. RETURN FALSE
  653. END
  654. END Replace;
  655. BEGIN
  656. IF currentNode = NIL THEN RETURN END;
  657. tree.Acquire;
  658. (*editor.text.debug := TRUE; *)
  659. editor.text.AcquireWrite;
  660. (* IF modified THEN
  661. Refresh(tree.GetRoot());
  662. END; *)
  663. (* TODO: find the current node again *)
  664. IF ~modified THEN
  665. WMDialogs.Information("Not up to date", "Refresh first")
  666. ELSE
  667. instances := 0; replacements := 0;
  668. COPY(currentNode.def.name^, curname);
  669. COPY(curname, name);
  670. IF WMDialogs.QueryString("Rename the identifier (No warning for collisions !)", name) = 0 THEN
  671. IF name # curname THEN
  672. IF Replace(posKeeper.GetPos(currentNode.fp),posKeeper.GetPos( currentNode.tp), curname, name) THEN
  673. INC(replacements);
  674. cur := references;
  675. WHILE cur # NIL DO
  676. IF cur.no = currentNode.def THEN
  677. INC(instances);
  678. IF Replace(posKeeper.GetPos(cur.fp), posKeeper.GetPos(cur.tp), curname, name) THEN INC(replacements) END
  679. END;
  680. cur := cur.next
  681. END
  682. END
  683. END
  684. END;
  685. KernelLog.String("instances= "); KernelLog.Int(instances, 0); KernelLog.String("replacements= "); KernelLog.Int(replacements, 0); KernelLog.Ln;
  686. END;
  687. editor.text.ReleaseWrite;
  688. (* editor.text.debug := FALSE; *)
  689. tree.Release;
  690. RefreshHandler(sender, data)
  691. END RenameHandler;
  692. PROCEDURE SelectRangeHandler(sender, data: ANY);
  693. VAR
  694. a, b, ch : LONGINT;
  695. r : Texts.TextReader;
  696. BEGIN
  697. IF currentNode = NIL THEN RETURN END;
  698. IF currentNode.def = NIL THEN RETURN END;
  699. IF ~currentNode.def.pos.valid OR ~currentNode.def.altPos.valid THEN
  700. KernelLog.String("Positions not valid"); KernelLog.Ln;
  701. RETURN
  702. END;
  703. tree.Acquire;
  704. editor.text.AcquireWrite;
  705. a := currentNode.def.pos.a;
  706. b := currentNode.def.altPos.b + 1;
  707. IF currentNode.def.preComment # NIL THEN
  708. a := currentNode.def.preComment.first.pos.a
  709. END;
  710. NEW(r, editor.text); r.SetDirection(-1); r.SetPosition(a);
  711. REPEAT
  712. r.ReadCh(ch);
  713. DEC(a)
  714. UNTIL (r.eot) OR (ch = Texts.NewLineChar);
  715. IF ~r.eot THEN r.ReadCh(ch); IF ch = Texts.NewLineChar THEN DEC(a) END END;
  716. NEW(r, editor.text); r.SetDirection(1); r.SetPosition(b);
  717. REPEAT
  718. r.ReadCh(ch);
  719. INC(b)
  720. UNTIL (r.eot) OR (ch = Texts.NewLineChar);
  721. editor.tv.selection.SetFromTo(a, b);
  722. editor.text.ReleaseWrite;
  723. tree.Release;
  724. RefreshHandler(sender, data)
  725. END SelectRangeHandler;
  726. PROCEDURE DelActualParameterHandler(sender, data: ANY);
  727. VAR
  728. a, b, instances : LONGINT;
  729. cur : Reference;
  730. BEGIN
  731. IF currentNode = NIL THEN RETURN END;
  732. tree.Acquire;
  733. editor.text.AcquireWrite;
  734. instances := 0;
  735. a := posKeeper.GetPos(currentNode.fp);
  736. b := posKeeper.GetPos(currentNode.tp);
  737. editor.text.Delete(a, b - a);
  738. cur := actualParameter;
  739. WHILE cur # NIL DO
  740. IF cur.no = currentNode.def THEN
  741. IF cur.np # -1 THEN b := posKeeper.GetPos(cur.np) ELSE b := posKeeper.GetPos(cur.tp) END;
  742. a := posKeeper.GetPos(cur.fp);
  743. editor.text.Delete(a, b - a);
  744. INC(instances);
  745. END;
  746. cur := cur.next
  747. END;
  748. KernelLog.String("instances= "); KernelLog.Int(instances, 0); KernelLog.Ln;
  749. editor.text.ReleaseWrite;
  750. tree.Release;
  751. RefreshHandler(sender, data)
  752. END DelActualParameterHandler;
  753. PROCEDURE NextUseHandler(sender, data : ANY);
  754. VAR
  755. text : Texts.Text;
  756. BEGIN
  757. IF currentNode # NIL THEN
  758. IF currentUse = NIL THEN currentUse := references END;
  759. REPEAT currentUse := currentUse.next UNTIL (currentUse = NIL) OR (currentUse.no = currentNode.def);
  760. IF currentUse # NIL THEN
  761. text := editor.text;
  762. text.AcquireRead;
  763. editor.tv.cursor.SetPosition(posKeeper.GetPos(currentUse.fp));
  764. editor.tv.cursor.SetVisible(TRUE);
  765. text.ReleaseRead;
  766. editor.SetFocus()
  767. END
  768. END
  769. END NextUseHandler;
  770. PROCEDURE GetTextInfo(CONST name: ARRAY OF CHAR; fp, tp: LONGINT; color: LONGINT; style: SET; def : TS.NamedObject): TextInfo;
  771. VAR newInfo: TextInfo; font: WMGraphics.Font;
  772. BEGIN
  773. NEW(newInfo); newInfo.next := definitions; definitions := newInfo;
  774. newInfo.name := Strings.NewString(name);
  775. newInfo.color := color;
  776. IF style = {} THEN
  777. font := treeFontOberon10Plain
  778. ELSIF style = {WMGraphics.FontBold} THEN
  779. font := treeFontOberon10Bold
  780. ELSIF style = {WMGraphics.FontItalic} THEN
  781. font := treeFontOberon10Italic
  782. ELSE
  783. (* unknown style *)
  784. font := treeFontOberon10Plain
  785. END;
  786. newInfo.def := def;
  787. newInfo.font := font;
  788. newInfo.fp := posKeeper.AddPos(fp);
  789. NEW(newInfo.pos, editor.text);
  790. newInfo.pos.SetPosition(fp);
  791. newInfo.tp := posKeeper.AddPos(tp);
  792. RETURN newInfo
  793. END GetTextInfo;
  794. PROCEDURE NewNode(parent: WMTrees.TreeNode; caption: Strings.String; ti : TextInfo): WMTrees.TreeNode;
  795. VAR newNode: WMTrees.TreeNode;
  796. BEGIN
  797. IF parent # NIL THEN
  798. NEW(newNode);
  799. tree.SetNodeCaption(newNode, caption);
  800. tree.SetNodeData(newNode, ti);
  801. tree.AddChildNode(parent, newNode)
  802. END;
  803. RETURN newNode
  804. END NewNode;
  805. PROCEDURE TraverseTypeScope(curNode : WMTrees.TreeNode;t : TS.Type);
  806. BEGIN
  807. IF (t = NIL) THEN
  808. KernelLog.String("Illegal type def"); KernelLog.Ln;
  809. RETURN;
  810. END;
  811. CASE t.kind OF
  812. |TS.TAlias : (*DumpDesignator(t.qualident) *)
  813. |TS.TObject :
  814. IF t.object # NIL THEN
  815. TraverseScope(curNode, t.object.scope);
  816. END;
  817. |TS.TArray : TraverseTypeScope(curNode, t.array.base);
  818. |TS.TPointer : TraverseTypeScope(curNode, t.pointer.type)
  819. |TS.TRecord : TraverseScope(curNode, t.record.scope)
  820. (* |TS.TProcedure : DumpProcedure(t.procedure) *)
  821. ELSE
  822. END
  823. END TraverseTypeScope;
  824. PROCEDURE TraverseProcDecl(curNode : WMTrees.TreeNode; p : TS.ProcDecl);
  825. VAR params, node : WMTrees.TreeNode;
  826. cur : TS.NamedObject;
  827. i : LONGINT;
  828. ti : TextInfo;
  829. BEGIN
  830. IF (p.signature # NIL) & (p.signature.params # NIL) THEN
  831. params := NewNode(curNode, Strings.NewString("Parameter"), NIL);
  832. FOR i := 0 TO p.signature.params.nofObjs - 1 DO
  833. cur := p.signature.params.objs[i];
  834. ti := GetTextInfo("", cur.pos.a, cur.pos.b, 0AAFFH, {}, cur);
  835. node := NewNode(params, cur.name, ti);
  836. END
  837. END;
  838. IF p.scope # NIL THEN
  839. (* locals := NewNode(curNode, Strings.NewString("Locals"), NIL); *)
  840. TraverseScope(curNode, p.scope)
  841. END
  842. END TraverseProcDecl;
  843. PROCEDURE MakeReference(no : TS.NamedObject; from, to : LONGINT);
  844. VAR nr : Reference;
  845. BEGIN
  846. NEW(nr); nr.next := references; references := nr;
  847. nr.no := no; nr.fp := posKeeper.AddPos(from); nr.tp := posKeeper.AddPos(to)
  848. END MakeReference;
  849. PROCEDURE UnknownIdentifierError(scope: TS.Scope; first : BOOLEAN; ident : TS.Ident);
  850. VAR s : ARRAY 1024 OF CHAR;
  851. cur : CurrentHighlights;
  852. color : LONGINT;
  853. suggestions : TS.ObjectList;
  854. nofSuggestions : LONGINT;
  855. BEGIN
  856. color := LONGINT(0FF000080H);
  857. TS.s.GetString(ident.name, s);
  858. (* KernelLog.String("*** Unknown identifier :"); KernelLog.String(s); KernelLog.Ln; *)
  859. IF editor.tv.cursor.GetPosition() = ident.pos.b THEN
  860. suggestionStart := ident.pos.a;
  861. cursorScope := scope;
  862. cursorIsFirstLevelScope := first;
  863. color := LONGINT(0FF800080H);
  864. NEW(suggestions);
  865. FindSuggestions(scope, first, s, suggestions);
  866. IF suggestions.nofObjs > 0 THEN color := LONGINT(000008080H) END;
  867. IF suggestions.nofObjs = 1 THEN singleSuggestion := suggestions.objs[0] END;
  868. END;
  869. NEW(cur); cur.next := errorHighlights; errorHighlights := cur;
  870. cur.h := editor.tv.CreateHighlight();
  871. cur.h.SetColor(color);
  872. cur.h.SetFromTo(ident.pos.a, ident.pos.b);
  873. END UnknownIdentifierError;
  874. (* Add scope declarations to the tree *)
  875. PROCEDURE TraverseScope(curNode : WMTrees.TreeNode; scope : TS.Scope);
  876. VAR i : LONGINT;
  877. last, cur : TS.NamedObject;
  878. node : WMTrees.TreeNode;
  879. ti : TextInfo;
  880. imports, consts, vars : WMTrees.TreeNode;
  881. type : TS.Type;
  882. procType : LONGINT;
  883. image : WMGraphics.Image;
  884. d : ANY;
  885. PROCEDURE Insert(parent : WMTrees.TreeNode; color : LONGINT; style : SET);
  886. BEGIN
  887. ti := GetTextInfo("", cur.pos.a, cur.pos.b, color, style, cur);
  888. IF cur.altPos.valid THEN MakeReference(cur, cur.altPos.a, cur.altPos.b) END;
  889. node := NewNode(parent, cur.name, ti);
  890. END Insert;
  891. BEGIN
  892. IF scope = NIL THEN RETURN END;
  893. FOR i := 0 TO scope.elements.nofObjs - 1 DO
  894. cur := scope.elements.objs[i];
  895. IF cur IS TS.Const THEN
  896. IF consts = NIL THEN
  897. NEW(consts);
  898. tree.SetNodeCaption(consts, Strings.NewString("CONST"));
  899. tree.AddChildNode(curNode, consts)
  900. END;
  901. Insert(consts, 0FFFFH, {WMGraphics.FontBold});
  902. ELSIF cur IS TS.TypeDecl THEN
  903. (* In case of an object type, the name is defined by the type name, the
  904. name at the end of the OBJECT block is a non functional use. Copy
  905. the alternative position value *)
  906. IF (cur(TS.TypeDecl).type.kind = TS.TObject) THEN
  907. cur(TS.TypeDecl).altPos := cur(TS.TypeDecl).type.object.altPos
  908. END;
  909. Insert(curNode, 0FFFFH, {WMGraphics.FontItalic});
  910. IF (cur(TS.TypeDecl).type.kind = TS.TObject) & (cur(TS.TypeDecl).type.object.scope.superQualident # NIL) THEN
  911. AddPostfixToCaption(node, Strings.NewString(" ("));
  912. AddPostfixToCaption(node, ST.QualidentToString(scope, cur(TS.TypeDecl).type.object.scope.superQualident));
  913. AddPostfixToCaption(node, Strings.NewString(")"));
  914. ELSIF (cur(TS.TypeDecl).type.kind = TS.TPointer) THEN
  915. IF (cur(TS.TypeDecl).type.pointer.type.kind = TS.TRecord) &
  916. (cur(TS.TypeDecl).type.pointer.type.record.scope.superQualident # NIL) THEN
  917. AddPostfixToCaption(node, Strings.NewString(" ("));
  918. AddPostfixToCaption(node, ST.QualidentToString(scope, cur(TS.TypeDecl).type.pointer.type.record.scope.superQualident));
  919. AddPostfixToCaption(node, Strings.NewString(")"));
  920. END
  921. END;
  922. TraverseTypeScope(node, cur(TS.TypeDecl).type);
  923. ELSIF cur IS TS.Var THEN
  924. IF vars = NIL THEN
  925. NEW(vars);
  926. tree.SetNodeCaption(vars, Strings.NewString("VAR"));
  927. tree.AddChildNode(curNode, vars)
  928. END;
  929. Insert(vars, 07C0000FFH, {});
  930. IF type # cur(TS.Var).type THEN TraverseTypeScope(node, cur(TS.Var).type) END; type := cur(TS.Var).type
  931. ELSIF cur IS TS.ProcDecl THEN
  932. Insert(curNode, 0FFH, {WMGraphics.FontBold});
  933. IF scope = module.scope THEN
  934. procType := GetProcedureType(cur(TS.ProcDecl));
  935. IF (procType = ProcCommand) THEN
  936. tree.Acquire;
  937. d := tree.GetNodeData(node);
  938. (* IF (d # NIL) & (d IS TextInfo) THEN INCL(d(TextInfo).flags, CanExecute) END; *)
  939. image := WMGraphics.LoadImage(ImageCommandProc, TRUE);
  940. tree.SetNodeImage(node, image);
  941. tree.Release;
  942. END;
  943. END;
  944. TraverseProcDecl(node, cur(TS.ProcDecl))
  945. ELSIF cur IS TS.Import THEN
  946. IF imports = NIL THEN
  947. NEW(imports);
  948. tree.SetNodeCaption(imports, Strings.NewString("IMPORTS"));
  949. tree.AddChildNode(curNode, imports)
  950. END;
  951. Insert(imports, 0FFH, {});
  952. END;
  953. last := cur;
  954. END
  955. END TraverseScope;
  956. PROCEDURE GetNextNode(this : WMTrees.TreeNode; ignoreChildren : BOOLEAN) : WMTrees.TreeNode;
  957. VAR state : SET;
  958. BEGIN
  959. state := tree.GetNodeState(this);
  960. IF ~ignoreChildren & (tree.GetChildren(this) # NIL) THEN RETURN tree.GetChildren(this);
  961. ELSIF tree.GetNextSibling(this) # NIL THEN RETURN tree.GetNextSibling(this);
  962. ELSIF tree.GetParent(this) # NIL THEN RETURN GetNextNode(tree.GetParent(this), TRUE)
  963. ELSE RETURN NIL
  964. END;
  965. END GetNextNode;
  966. PROCEDURE SelectNodeByNamedObject(no : TS.NamedObject; gotoDef: BOOLEAN) : BOOLEAN;
  967. VAR node : WMTrees.TreeNode;
  968. d : ANY;
  969. BEGIN
  970. tree.Acquire;
  971. node := tree.GetRoot();
  972. WHILE node # NIL DO
  973. node := GetNextNode(node, FALSE);
  974. d := tree.GetNodeData(node);
  975. IF (d # NIL) & (d IS TextInfo) THEN
  976. IF d(TextInfo).def = no THEN
  977. treeView.SelectNode(node);
  978. tree.ExpandToRoot(node);
  979. SelectReferences(d(TextInfo), gotoDef);
  980. tree.Release;
  981. RETURN TRUE;
  982. END
  983. END
  984. END;
  985. tree.Release;
  986. RETURN FALSE
  987. END SelectNodeByNamedObject;
  988. PROCEDURE FindScopeByPos(pos : LONGINT);
  989. VAR cur : TextInfo;
  990. cand, scope : TS.NamedObject;
  991. candDist, dist : LONGINT;
  992. BEGIN
  993. cur := definitions;
  994. scope := NIL;
  995. WHILE cur # NIL DO
  996. cand := cur.def;
  997. IF (cand IS TS.ProcDecl) OR
  998. (cand IS TS.TypeDecl) & (cand(TS.TypeDecl).type.kind = TS.TObject) THEN
  999. KernelLog.String("#");
  1000. IF cand.pos.valid & cand.altPos.valid THEN
  1001. dist := cand.altPos.b - cand.pos.a;
  1002. IF (pos >= cand.pos.a) & (pos <= cand.altPos.b) &
  1003. ((scope = NIL) OR (dist < candDist)) THEN
  1004. candDist := dist;
  1005. scope := cand;
  1006. editor.tv.selection.SetFromTo(cand.pos.a, cand.altPos.b);
  1007. END
  1008. END
  1009. END;
  1010. KernelLog.String(" "); KernelLog.String(cand.name^); KernelLog.Ln;
  1011. cur := cur.next
  1012. END;
  1013. IF scope = NIL THEN scope := module END;
  1014. KernelLog.String(" --> "); KernelLog.String(scope.name^); KernelLog.Ln;
  1015. END FindScopeByPos;
  1016. PROCEDURE FindIdentByPos(pos : LONGINT);
  1017. VAR cur : Reference; ct : TextInfo; c : LONGINT;
  1018. msg : PETTrees.ExternalDefinitionInfo;
  1019. filename, definition : ARRAY 256 OF CHAR;
  1020. m : TS.Module;
  1021. BEGIN
  1022. (* Search uses *)
  1023. cur := references; c := 0;
  1024. WHILE cur # NIL DO
  1025. INC(c);
  1026. IF (pos >= posKeeper.GetPos(cur.fp)) & (pos <= posKeeper.GetPos(cur.tp)) THEN
  1027. IF ~SelectNodeByNamedObject(cur.no, TRUE) THEN
  1028. (* Ask PET to load and show in different tab *)
  1029. ST.ID(cur.no);
  1030. ST.GetSourceReference(cur.no, filename, definition);
  1031. KernelLog.String("filename= "); KernelLog.String(filename); KernelLog.Ln;
  1032. NEW(msg, filename, definition);
  1033. onGoToDefinition.Call(msg);
  1034. END;
  1035. RETURN
  1036. ELSE cur := cur.next
  1037. END
  1038. END;
  1039. KernelLog.String("references searched c= "); KernelLog.Int(c, 0); KernelLog.Ln;
  1040. (* not found search for definitions*)
  1041. ct := definitions; c := 0;
  1042. WHILE ct # NIL DO
  1043. c := 0;
  1044. IF (pos >= posKeeper.GetPos(ct.fp)) & (pos <= posKeeper.GetPos(ct.tp)) THEN
  1045. IF (ct.def # NIL) & (ct.def IS TS.Import) THEN
  1046. m := TS.ns.GetModule(ct.def(TS.Import).import^);
  1047. IF m = NIL THEN
  1048. m := TS.ReadSymbolFile(ct.def(TS.Import).import^)
  1049. END;
  1050. IF (m # NIL) & (m.filename # NIL) THEN
  1051. COPY(m.filename^, filename);
  1052. definition := "";
  1053. KernelLog.String("filename= "); KernelLog.String(filename); KernelLog.Ln;
  1054. NEW(msg, filename, definition);
  1055. onGoToDefinition.Call(msg);
  1056. END
  1057. ELSIF ~ SelectNodeByNamedObject(ct.def, TRUE) THEN
  1058. KernelLog.String("Definition not found in tree : "); KernelLog.Ln;
  1059. ST.ID(ct.def);
  1060. END;
  1061. RETURN
  1062. ELSE ct := ct.next
  1063. END
  1064. END;
  1065. KernelLog.String("definitions searched c= "); KernelLog.Int(c, 0); KernelLog.Ln;
  1066. KernelLog.String("Not found"); KernelLog.String(" pos= "); KernelLog.Int(pos, 0); KernelLog.Ln;
  1067. END FindIdentByPos;
  1068. PROCEDURE HandleMacro*(sender, data: ANY);
  1069. VAR md : WMEditors.MacroData; text : Texts.Text; cursor : WMTextView.PositionMarker;
  1070. BEGIN
  1071. IF (data # NIL) & (data IS WMEditors.MacroData) THEN
  1072. md := data(WMEditors.MacroData);
  1073. IF md.keySym = 0FFC9H THEN
  1074. text := md.text; cursor := md.cursor;
  1075. md.handled := TRUE;
  1076. FindIdentByPos(cursor.GetPosition())
  1077. ELSIF md.keySym = 0FFC2H THEN
  1078. RefreshHandler(sender, data);
  1079. md.handled := TRUE
  1080. END;
  1081. END
  1082. END HandleMacro;
  1083. PROCEDURE Follow(sender, data : ANY);
  1084. BEGIN
  1085. FindIdentByPos(editor.tv.cursor.GetPosition())
  1086. END Follow;
  1087. PROCEDURE AddComments(c : TS.Comments);
  1088. VAR cur : TS.Comment;
  1089. nc : Comment;
  1090. BEGIN
  1091. IF c = NIL THEN RETURN END;
  1092. cur := c.first;
  1093. WHILE cur # NIL DO
  1094. NEW(nc); nc.next := comments; comments := nc;
  1095. nc.fp := posKeeper.AddPos(cur.pos.a);
  1096. nc.tp := posKeeper.AddPos(cur.pos.b);
  1097. cur := cur.next
  1098. END
  1099. END AddComments;
  1100. PROCEDURE SearchUses*(d : TS.Scope; VAR ref : Reference);
  1101. VAR i : LONGINT;
  1102. last, cur : TS.NamedObject;
  1103. nr : Reference;
  1104. lastVarType : TS.Type;
  1105. PROCEDURE CheckExpressionList(e : TS.ExpressionList; sig : TS.ProcedureSignature; scope : TS.Scope);
  1106. VAR i, a, b : LONGINT; nr, f : Reference;
  1107. BEGIN
  1108. i := 0;
  1109. f := NIL;
  1110. WHILE e # NIL DO
  1111. CheckExpression(e.expression, scope);
  1112. IF (sig # NIL) & (sig.params # NIL) THEN
  1113. IF i < sig.params.nofObjs THEN
  1114. a := -1; b := -1; GetExpressionRange(e.expression, a, b);
  1115. IF (a >= 0) & (b > a) THEN
  1116. NEW(nr); nr.next := actualParameter; actualParameter := nr; nr.np := -1;
  1117. nr.no := sig.params.objs[i];
  1118. nr.fp := posKeeper.AddPos(a);
  1119. nr.tp := posKeeper.AddPos(b);
  1120. IF f # NIL THEN f.np := nr.fp END; f := nr;
  1121. END
  1122. ELSE
  1123. GetExpressionRange(e.expression, a, b);
  1124. KernelLog.String("pos = "); KernelLog.Int(a, 0); KernelLog.String(" more parameter than expected ")
  1125. END
  1126. END;
  1127. INC(i);
  1128. e := e.next
  1129. END
  1130. END CheckExpressionList;
  1131. PROCEDURE GetDesignatorRange(d : TS.Designator; VAR a, b : LONGINT);
  1132. BEGIN
  1133. IF d IS TS.Ident THEN
  1134. IF (a = -1) OR (d(TS.Ident).pos.a < a) THEN a := d(TS.Ident).pos.a END;
  1135. IF d(TS.Ident).pos.b > b THEN b := d(TS.Ident).pos.b END;
  1136. ELSIF d IS TS.Index THEN
  1137. ELSIF d IS TS.ActualParameters THEN
  1138. END;
  1139. IF (d.next # NIL) THEN
  1140. GetDesignatorRange(d.next, a, b)
  1141. END
  1142. END GetDesignatorRange;
  1143. PROCEDURE GetExpressionRange(e : TS.Expression; VAR a, b : LONGINT);
  1144. VAR ta, tb : LONGINT;
  1145. BEGIN
  1146. ta := -1; tb := -1; IF e = NIL THEN RETURN END;
  1147. IF e.kind = TS.ExpressionPrimitive THEN
  1148. ELSIF e.kind = TS.ExpressionUnary THEN
  1149. GetExpressionRange(e.a, ta, tb);
  1150. IF a = -1 THEN a := ta END;
  1151. IF (ta # -1) & (ta < a) THEN a := ta END;IF (tb > b) THEN b := tb END;
  1152. ELSIF e.kind = TS.ExpressionBinary THEN
  1153. GetExpressionRange(e.a, ta, tb);
  1154. IF a = -1 THEN a := ta END;
  1155. IF (ta # -1) & (ta < a) THEN a := ta END;IF (tb > b) THEN b := tb END;
  1156. ta := -1; tb := -1;
  1157. GetExpressionRange(e.b, ta, tb);
  1158. IF a = -1 THEN a := ta END;
  1159. IF (ta # -1) & (ta < a) THEN a := ta END;IF (tb > b) THEN b := tb END;
  1160. ELSIF e.kind = TS.ExpressionDesignator THEN
  1161. GetDesignatorRange(e.designator, a, b)
  1162. END
  1163. END GetExpressionRange;
  1164. PROCEDURE CheckExpression(e : TS.Expression; scope : TS.Scope);
  1165. VAR t : TS.Type;
  1166. sr : TS.SetRange;
  1167. BEGIN
  1168. IF e = NIL THEN KernelLog.String("Expression is NIL"); RETURN END;
  1169. IF e.kind = TS.ExpressionPrimitive THEN
  1170. IF e.basicType = TS.BasicSet THEN
  1171. sr := e.setValue.setRanges;
  1172. WHILE sr # NIL DO
  1173. IF sr.a # NIL THEN CheckExpression(sr.a, scope) END;
  1174. IF sr.b # NIL THEN CheckExpression(sr.b, scope) END;
  1175. sr := sr.next
  1176. END;
  1177. END;
  1178. ELSIF e.kind = TS.ExpressionUnary THEN
  1179. CheckExpression(e.a, scope);
  1180. ELSIF e.kind = TS.ExpressionBinary THEN
  1181. CheckExpression(e.a, scope);
  1182. IF e.op # TS.OpIs THEN CheckExpression(e.b, scope)
  1183. ELSE
  1184. t := ST.FindType(e.b.designator, scope);
  1185. CheckDesignator(e.b.designator, scope);
  1186. IF t = NIL THEN KernelLog.String("pos = "); KernelLog.Int(e.b.designator(TS.Ident).pos.a, 0); KernelLog.String(" Type not found ") END;
  1187. END
  1188. ELSIF e.kind = TS.ExpressionDesignator THEN
  1189. CheckDesignator(e.designator, scope)
  1190. END;
  1191. END CheckExpression;
  1192. PROCEDURE CheckSuperClass(o : TS.Class; scope : TS.Scope);
  1193. VAR st : TS.Type;
  1194. BEGIN
  1195. IF (o.scope.super = NIL) & (o.scope.super # NIL) THEN
  1196. (* KernelLog.String("Searching for super type :"); ST.ShowDesignator(o.super); KernelLog.Ln; *)
  1197. st := ST.DealiaseType(ST.FindType(o.scope.superQualident, scope));
  1198. IF st # NIL THEN
  1199. IF st.kind = TS.TObject THEN
  1200. o.scope.super := st.object.scope;
  1201. ELSE KernelLog.String("super type is not an class"); KernelLog.Ln;
  1202. END
  1203. (* ELSE KernelLog.String("No information about super type "); KernelLog.Ln; *)
  1204. END
  1205. END
  1206. END CheckSuperClass;
  1207. PROCEDURE CheckDesignator(d : TS.Designator; scope : TS.Scope);
  1208. VAR no: TS.NamedObject;
  1209. curScope : TS.Scope;
  1210. type, temptype : TS.Type;
  1211. first : BOOLEAN;
  1212. s : ARRAY 64 OF CHAR;
  1213. m : TS.Module;
  1214. te : TS.ExpressionList;
  1215. lastpos : LONGINT;
  1216. PROCEDURE SetReference(id : TS.Ident; no : TS.NamedObject);
  1217. BEGIN
  1218. NEW(nr); nr.next := ref; ref := nr;
  1219. nr.no := no;
  1220. nr.fp := posKeeper.AddPos(id.pos.a);
  1221. nr.tp := posKeeper.AddPos(id.pos.b);
  1222. END SetReference;
  1223. BEGIN
  1224. first := TRUE;
  1225. curScope := scope;
  1226. WHILE d # NIL DO
  1227. IF d IS TS.Ident THEN
  1228. lastpos := d(TS.Ident).pos.a;
  1229. TS.s.GetString(d(TS.Ident).name, s);
  1230. IF first & (s = "SELF") THEN
  1231. curScope := scope.parent;
  1232. (* look for object or module represented by SELF*)
  1233. WHILE (curScope.parent # NIL) & (curScope.owner # NIL) &
  1234. ~((curScope.owner IS TS.Class) OR (curScope.owner IS TS.Module)) DO
  1235. curScope := curScope.parent
  1236. END;
  1237. IF curScope = NIL THEN
  1238. KernelLog.String("SELF could not be resolved"); KernelLog.Ln;
  1239. END;
  1240. ELSIF first & (s = "SYSTEM") THEN
  1241. d := d.next;
  1242. IF d # NIL THEN
  1243. IF d IS TS.Ident THEN
  1244. TS.s.GetString(d(TS.Ident).name, s);
  1245. IF s = "VAL" THEN
  1246. d := d.next;
  1247. IF d # NIL THEN
  1248. IF d IS TS.ActualParameters THEN
  1249. te := d(TS.ActualParameters).expressionList;
  1250. IF te # NIL THEN
  1251. IF te.expression.kind = TS.ExpressionDesignator THEN
  1252. temptype := ST.FindType(te.expression.designator, scope);
  1253. IF temptype = NIL THEN KernelLog.String("pos = "); KernelLog.Int(te.expression.designator(TS.Ident).pos.a, 0); KernelLog.String(" Type not found ") END;
  1254. END;
  1255. te := te.next;
  1256. CheckExpression(te.expression, scope);
  1257. ELSE
  1258. KernelLog.String("type arameter expeced"); KernelLog.Ln;
  1259. END
  1260. ELSE
  1261. KernelLog.String("parameters expeced"); KernelLog.Ln;
  1262. END
  1263. ELSE
  1264. KernelLog.String("Pos= "); KernelLog.Int(d(TS.Ident).pos.a, 0); KernelLog.String(s); KernelLog.String("Ident expeced"); KernelLog.Ln;
  1265. END
  1266. END
  1267. ELSE
  1268. KernelLog.String(s); KernelLog.String("Ident expeced"); KernelLog.Ln;
  1269. END
  1270. ELSE
  1271. KernelLog.String("Pos= "); KernelLog.Int(d(TS.Ident).pos.a, 0); KernelLog.String(s); KernelLog.String("incomplete SYSTEM call"); KernelLog.Ln;
  1272. END
  1273. ELSE
  1274. IF curScope # NIL THEN
  1275. no := curScope.Find(s, first);
  1276. IF (no = NIL) THEN
  1277. UnknownIdentifierError(curScope, first, d(TS.Ident));
  1278. RETURN;
  1279. END;
  1280. (* check if it is a super call or reference *)
  1281. IF (no IS TS.ProcDecl) & (d.next # NIL) & (d.next IS TS.Dereference) THEN
  1282. no.scope.parent.FixSuperScope;
  1283. IF no.scope.parent.super # NIL THEN
  1284. no := no.scope.parent.super.Find(s, FALSE)
  1285. ELSE KernelLog.String(" super is NIL"); KernelLog.String(s); KernelLog.Ln;
  1286. END
  1287. END;
  1288. SetReference(d(TS.Ident), no);
  1289. IF no IS TS.Var THEN
  1290. type := ST.DealiaseType(no(TS.Var).type);
  1291. IF type # NIL THEN
  1292. IF type.kind = TS.TRecord THEN curScope := type.record.scope
  1293. ELSIF type.kind = TS.TObject THEN curScope := type.object.scope END
  1294. END
  1295. ELSIF no IS TS.ProcDecl THEN
  1296. IF no(TS.ProcDecl).signature # NIL THEN
  1297. type := ST.DealiaseType(no(TS.ProcDecl).signature.return);
  1298. IF type # NIL THEN
  1299. IF type.kind = TS.TRecord THEN curScope := type.record.scope
  1300. ELSIF type.kind = TS.TObject THEN curScope := type.object.scope END
  1301. END
  1302. END;
  1303. ELSIF no IS TS.Import THEN
  1304. m := TS.GetModule(no(TS.Import));
  1305. IF m # NIL THEN
  1306. curScope := m.scope;
  1307. (* ELSE
  1308. KernelLog.String("No symbol information for : "); KernelLog.String(no(TS.Import).import^); KernelLog.Ln *)
  1309. END
  1310. ELSIF no IS TS.Const THEN
  1311. IF d.next # NIL THEN
  1312. END
  1313. (* ELSE
  1314. KernelLog.String(" Pos= "); KernelLog.Int(d(TS.Ident).pos.a, 0); KernelLog.String(" : ");
  1315. KernelLog.String("variable, const or procedure expected but "); ST.ID(no); KernelLog.Ln; *)
  1316. END
  1317. ELSE
  1318. KernelLog.String("no scope"); KernelLog.Ln;
  1319. END
  1320. END
  1321. ELSIF d IS TS.Dereference THEN IF d.next # NIL THEN d := d.next END;
  1322. ELSIF d IS TS.Index THEN
  1323. (* automatic dealiasing if index access *)
  1324. IF (type # NIL) & (type.kind = TS.TPointer) THEN
  1325. type := ST.DealiaseType(type.pointer.type) END;
  1326. IF (type = NIL) OR ( type.kind # TS.TArray) THEN
  1327. IF type # NIL THEN ST.ShowType(type) END;
  1328. KernelLog.String("Type is not an array pos= "); KernelLog.Int(lastpos, 0); KernelLog.Ln
  1329. ELSE
  1330. type := ST.DealiaseType(type.array.base);
  1331. IF type # NIL THEN
  1332. IF type.kind = TS.TRecord THEN curScope := type.record.scope
  1333. ELSIF type.kind = TS.TObject THEN curScope := type.object.scope END
  1334. END
  1335. END;
  1336. CheckExpressionList(d(TS.Index).expressionList, NIL, scope);
  1337. ELSIF d IS TS.ActualParameters THEN
  1338. (* no is the item before "(" *)
  1339. IF no # NIL THEN
  1340. IF no IS TS.ProcDecl THEN
  1341. CheckExpressionList(d(TS.ActualParameters).expressionList, no(TS.ProcDecl).signature, scope)
  1342. ELSIF (no IS TS.Var) THEN
  1343. type := ST.DealiaseType(no(TS.Var).type);
  1344. IF (type # NIL) & (type.kind = TS.TProcedure) THEN
  1345. (* delegate *)
  1346. IF type.procedure = NIL THEN
  1347. KernelLog.String("no(TS.Var).type.procedure"); KernelLog.Ln;
  1348. ELSIF type.procedure.signature = NIL THEN
  1349. KernelLog.String("no(TS.Var).type.procedure.signature"); KernelLog.Ln;
  1350. ELSE
  1351. CheckExpressionList(d(TS.ActualParameters).expressionList, type.procedure.signature, scope)
  1352. END;
  1353. ELSE
  1354. (* type guard *)
  1355. IF d(TS.ActualParameters).expressionList # NIL THEN
  1356. IF d(TS.ActualParameters).expressionList.next # NIL THEN
  1357. KernelLog.String("lastpos= "); KernelLog.Int(lastpos, 0);
  1358. KernelLog.String(" Can only guard for one type at once."); KernelLog.Ln
  1359. ELSE
  1360. IF d(TS.ActualParameters).expressionList.expression.kind = TS.ExpressionDesignator THEN
  1361. type := ST.DealiaseType(ST.FindType(d(TS.ActualParameters).expressionList.expression.designator, scope));
  1362. IF type # NIL THEN
  1363. IF type.kind = TS.TRecord THEN curScope := type.record.scope
  1364. ELSIF type.kind = TS.TObject THEN curScope := type.object.scope END
  1365. END;
  1366. CheckDesignator(d(TS.ActualParameters).expressionList.expression.designator, scope);
  1367. ELSE
  1368. KernelLog.String("Type expected"); KernelLog.Ln
  1369. END
  1370. END
  1371. END
  1372. END
  1373. ELSE (* huh ? *)
  1374. HALT(12345);
  1375. END
  1376. ELSE
  1377. (* not found... fallback *)
  1378. CheckExpressionList(d(TS.ActualParameters).expressionList, NIL, scope)
  1379. (* probably because of a not found
  1380. KernelLog.String("lastpos= "); KernelLog.Int(lastpos, 0);
  1381. KernelLog.String(" No proc"); KernelLog.Ln *)
  1382. END
  1383. END;
  1384. first := FALSE;
  1385. (* Auto dereferencing *)
  1386. IF type # NIL THEN
  1387. IF type.kind = TS.TPointer THEN type := ST.DealiaseType(type.pointer.type) END;
  1388. IF type # NIL THEN
  1389. IF type.kind = TS.TRecord THEN curScope := type.record.scope
  1390. ELSIF type.kind = TS.TObject THEN curScope := type.object.scope END
  1391. END
  1392. END;
  1393. d := d.next
  1394. END
  1395. END CheckDesignator;
  1396. PROCEDURE CheckCases(case : TS.Case; scope : TS.Scope);
  1397. VAR cr : TS.CaseRange;
  1398. BEGIN
  1399. WHILE case # NIL DO
  1400. cr := case.caseRanges;
  1401. WHILE cr # NIL DO
  1402. CheckExpression(cr.a, scope);
  1403. IF cr.b # NIL THEN CheckExpression(cr.b, scope) END;
  1404. cr := cr.next
  1405. END;
  1406. IF case.statements # NIL THEN SearchStatements(case.statements, scope) END;
  1407. case := case.next
  1408. END
  1409. END CheckCases;
  1410. PROCEDURE SearchStatements(s : TS.Statement; scope : TS.Scope);
  1411. VAR ts : TS.Statement; t : TS.Type;
  1412. BEGIN
  1413. WHILE s # NIL DO
  1414. AddComments(s.preComment); AddComments(s.postComment);
  1415. IF s IS TS.Assignment THEN
  1416. CheckDesignator(s(TS.Assignment).designator, scope);
  1417. CheckExpression(s(TS.Assignment).expression, scope);
  1418. ELSIF s IS TS.ProcedureCall THEN
  1419. CheckDesignator(s(TS.ProcedureCall).designator, scope)
  1420. ELSIF s IS TS.StatementBlock THEN
  1421. SearchStatements(s(TS.StatementBlock).statements, scope);
  1422. ELSIF s IS TS.IFStatement THEN
  1423. CheckExpression(s(TS.IFStatement).expression, scope);
  1424. SearchStatements(s(TS.IFStatement).then, scope);
  1425. ts := s(TS.IFStatement).else;
  1426. IF ts # NIL THEN
  1427. SearchStatements(ts, scope);
  1428. END;
  1429. ELSIF s IS TS.WHILEStatement THEN
  1430. CheckExpression(s(TS.WHILEStatement).expression, scope);
  1431. SearchStatements(s(TS.WHILEStatement).statements, scope);
  1432. ELSIF s IS TS.REPEATStatement THEN
  1433. SearchStatements(s(TS.REPEATStatement).statements, scope);
  1434. CheckExpression(s(TS.REPEATStatement).expression, scope);
  1435. ELSIF s IS TS.LOOPStatement THEN
  1436. SearchStatements(s(TS.LOOPStatement).statements, scope);
  1437. ELSIF s IS TS.FORStatement THEN
  1438. CheckDesignator(s(TS.FORStatement).variable, scope);
  1439. CheckExpression(s(TS.FORStatement).fromExpression, scope);
  1440. CheckExpression(s(TS.FORStatement).toExpression, scope);
  1441. IF s(TS.FORStatement).byExpression # NIL THEN
  1442. CheckExpression(s(TS.FORStatement).byExpression, scope);
  1443. END;
  1444. SearchStatements(s(TS.FORStatement).statements, scope);
  1445. ELSIF s IS TS.RETURNStatement THEN
  1446. IF s(TS.RETURNStatement).expression # NIL THEN CheckExpression(s(TS.RETURNStatement).expression, scope) END;
  1447. ELSIF s IS TS.AWAITStatement THEN
  1448. CheckExpression(s(TS.AWAITStatement).expression, scope);
  1449. ELSIF s IS TS.WITHStatement THEN
  1450. CheckDesignator(s(TS.WITHStatement).variable, scope);
  1451. t := ST.FindType(s(TS.WITHStatement).type, scope);
  1452. IF t = NIL THEN KernelLog.String("pos = "); KernelLog.Int(s(TS.WITHStatement).type(TS.Ident).pos.a, 0); KernelLog.String(" Type not found "); KernelLog.Ln; END;
  1453. SearchStatements(s(TS.WITHStatement).statements, scope);
  1454. ELSIF s IS TS.CASEStatement THEN
  1455. CheckExpression(s(TS.CASEStatement).expression, scope);
  1456. CheckCases(s(TS.CASEStatement).cases, scope);
  1457. IF s(TS.CASEStatement).else # NIL THEN
  1458. SearchStatements(s(TS.CASEStatement).else, scope)
  1459. END;
  1460. END;
  1461. s := s.next
  1462. END
  1463. END SearchStatements;
  1464. PROCEDURE CheckSignature(sig : TS.ProcedureSignature);
  1465. VAR i : LONGINT; cur : TS.NamedObject; t : TS.Type;
  1466. BEGIN
  1467. IF sig = NIL THEN RETURN END;
  1468. IF sig.return # NIL THEN CheckType(sig.return) END;
  1469. IF sig.params # NIL THEN
  1470. t := NIL;
  1471. FOR i := 0 TO sig.params.nofObjs - 1 DO
  1472. cur := sig.params.objs[i];
  1473. IF cur IS TS.Var THEN IF t # cur(TS.Var).type THEN CheckType(cur(TS.Var).type) END; t := cur(TS.Var).type
  1474. ELSE KernelLog.String("non- variable as a parameter"); KernelLog.Ln
  1475. END
  1476. END
  1477. END
  1478. END CheckSignature;
  1479. PROCEDURE CheckProcedure(p : TS.ProcDecl);
  1480. BEGIN
  1481. CheckSignature(p.signature);
  1482. SearchUses(p.scope, ref);
  1483. END CheckProcedure;
  1484. PROCEDURE CheckType(t : TS.Type);
  1485. BEGIN
  1486. IF t = NIL THEN
  1487. (* TODO: what ? *)
  1488. RETURN
  1489. END;
  1490. CASE t.kind OF
  1491. |TS.TAlias : CheckDesignator(t.qualident, t.container)
  1492. |TS.TObject : CheckDesignator(t.object.scope.superQualident, t.container); CheckSuperClass(t.object, t.container); SearchUses(t.object.scope, ref)
  1493. |TS.TArray : IF t.array.expression # NIL THEN CheckExpression(t.array.expression, t.container) END;
  1494. CheckType(t.array.base)
  1495. |TS.TPointer : CheckType(t.pointer.type)
  1496. |TS.TRecord : CheckDesignator(t.record.scope.superQualident, t.container); SearchUses(t.record.scope, ref)
  1497. |TS.TProcedure : (* CheckDeclarations(t.procedure.scope)*)
  1498. ELSE
  1499. KernelLog.String("t.kind= "); KernelLog.Int(t.kind, 0); KernelLog.Ln
  1500. END
  1501. END CheckType;
  1502. BEGIN
  1503. IF d = NIL THEN RETURN END;
  1504. IF d.ownerBody # NIL THEN SearchStatements(d.ownerBody, d) END;
  1505. FOR i := 0 TO d.elements.nofObjs - 1 DO
  1506. cur := d.elements.objs[i];
  1507. AddComments(cur.preComment); AddComments(cur.postComment);
  1508. IF cur IS TS.Const THEN CheckExpression(cur(TS.Const).expression, d)
  1509. ELSIF cur IS TS.TypeDecl THEN
  1510. IF (cur(TS.TypeDecl).type.kind= TS.TObject) & (cur(TS.TypeDecl).type.object = NIL) THEN
  1511. KernelLog.String("cur.name^= "); KernelLog.String(cur.name^); KernelLog.String(" will now lead to halt "); KernelLog.Ln;
  1512. END;
  1513. CheckType(cur(TS.TypeDecl).type)
  1514. ELSIF cur IS TS.Var THEN
  1515. IF (cur(TS.Var).type.kind= TS.TObject) & (cur(TS.Var).type.object = NIL) THEN
  1516. KernelLog.String("cur.name^= "); KernelLog.String(cur.name^); KernelLog.String(" will now lead to halt "); KernelLog.Ln;
  1517. END;
  1518. IF lastVarType # cur(TS.Var).type THEN CheckType(cur(TS.Var).type) END; lastVarType := cur(TS.Var).type;
  1519. ELSIF cur IS TS.ProcDecl THEN CheckProcedure(cur(TS.ProcDecl))
  1520. END;
  1521. last := cur
  1522. END
  1523. END SearchUses;
  1524. PROCEDURE TextChanged(sender, data : ANY);
  1525. BEGIN
  1526. modified := TRUE;
  1527. IF DoAutoRefresh THEN
  1528. updateTimer.Stop(SELF, NIL);
  1529. updateTimer.Start(SELF, NIL)
  1530. END
  1531. END TextChanged;
  1532. PROCEDURE Finalize*;
  1533. BEGIN
  1534. Finalize^;
  1535. IF (editor # NIL) & (editor.text # NIL) THEN
  1536. editor.text.onTextChanged.Remove(TextChanged)
  1537. END
  1538. END Finalize;
  1539. END ModuleTree;
  1540. VAR
  1541. PrototypeShowTypeHierarchy, PrototypeShowImportedModules : WMProperties.BooleanProperty;
  1542. treeFontOberon10Plain, treeFontOberon10Bold, treeFontOberon10Italic: WMGraphics.Font;
  1543. PMTonBrowseExternal : Strings.String;
  1544. PROCEDURE GetInsertString(ident : TS.NamedObject; VAR newStr : ARRAY OF CHAR);
  1545. VAR signature : TS.ProcedureSignature;
  1546. i : LONGINT;
  1547. BEGIN
  1548. COPY(ident.name^, newStr);
  1549. IF ident IS TS.ProcDecl THEN
  1550. signature := ident(TS.ProcDecl).signature;
  1551. IF signature # NIL THEN
  1552. IF signature.params.nofObjs > 0 THEN Strings.Append(newStr, "(") END;
  1553. FOR i := 0 TO signature.params.nofObjs - 1 DO
  1554. Strings.Append(newStr, signature.params.objs[i].name^);
  1555. IF i < signature.params.nofObjs - 1 THEN
  1556. Strings.Append(newStr, ", ")
  1557. END
  1558. END;
  1559. IF signature.params.nofObjs > 0 THEN Strings.Append(newStr, ")") END
  1560. END;
  1561. END;
  1562. END GetInsertString;
  1563. PROCEDURE FindSuggestions(scope : TS.Scope; first: BOOLEAN; prefix : ARRAY OF CHAR; suggestions : TS.ObjectList);
  1564. VAR ol : TS.ObjectList;
  1565. i: LONGINT;
  1566. BEGIN
  1567. IF scope = NIL THEN RETURN END;
  1568. NEW(ol);
  1569. scope.FindCandidates(prefix, first, TRUE, ol);
  1570. i := 0; WHILE i < ol.nofObjs DO
  1571. IF Strings.StartsWith2(prefix, ol.objs[i].name^) THEN
  1572. suggestions.Add(ol.objs[i]);
  1573. END;
  1574. INC(i)
  1575. END;
  1576. END FindSuggestions;
  1577. (** returns the type of the procedure *)
  1578. PROCEDURE GetProcedureType(proc : TS.ProcDecl) : LONGINT;
  1579. VAR type : LONGINT;
  1580. BEGIN
  1581. type := ProcOther;
  1582. IF (proc.signature = NIL) OR (proc.signature.params = NIL) & (proc.signature.return = NIL) THEN
  1583. type := ProcCommand;
  1584. END;
  1585. RETURN type;
  1586. END GetProcedureType;
  1587. PROCEDURE GenModuleTree*() : PETTrees.Tree;
  1588. VAR tree : ModuleTree;
  1589. BEGIN
  1590. NEW(tree); RETURN tree;
  1591. END GenModuleTree;
  1592. BEGIN
  1593. PMTonBrowseExternal := Strings.NewString("Browse into another file");
  1594. PMTonBrowseExternal := Strings.NewString("fired to browse to a definition in another file");
  1595. treeFontOberon10Plain := WMGraphics.GetFont("Oberon", 10, {});
  1596. treeFontOberon10Bold := WMGraphics.GetFont("Oberon", 10, {WMGraphics.FontBold});
  1597. treeFontOberon10Italic := WMGraphics.GetFont("Oberon", 10, {WMGraphics.FontItalic});
  1598. NEW(PrototypeShowTypeHierarchy, NIL, Strings.NewString("ShowTypeHierarchy"), Strings.NewString("Show type hierarchy?"));
  1599. PrototypeShowTypeHierarchy.Set(FALSE);
  1600. NEW(PrototypeShowImportedModules, NIL, Strings.NewString("ShowImportedModules"), Strings.NewString("Show imported modules details?"));
  1601. PrototypeShowImportedModules.Set(FALSE);
  1602. END TFModuleTrees.
  1603. Tar.Create ModuleTreesIcons.tar
  1604. activity.png
  1605. arrow-red.png
  1606. arrow-yellow.png
  1607. arrow-green.png
  1608. arrow-blue.png
  1609. ~