瀏覽代碼

Автодок: список импорта

Arthur Yefimov 2 年之前
父節點
當前提交
19f1069fae

+ 7 - 1
src/Autodoc/Autodoc.Mod

@@ -85,10 +85,14 @@ BEGIN
   Out.String(' by Arthur Yefimov and others.'); Out.Ln;
   Out.String('Usage:'); Out.Ln; Args.Get(0, s);
   Out.String('  '); Out.String(s);
-  Out.String(' { "-o" outputPath | "--lang" code | sourceFile}'); Out.Ln; Out.Ln;
+  Out.String(' { "-o" outputPath | "--lang" code | "-a" | "-k" | sourceFile}');
+  Out.Ln; Out.Ln;
   Out.String('outputPath is a file name if a single source file is given.');
   Out.Ln;
   Out.String('outputPath is a directory if many source files are given.');
+  Out.Ln;
+  Out.String('-a ...... get All objects, not only exported'); Out.Ln;
+  Out.String('-k ...... Keep module aliases');
   Out.Ln; Out.Ln;
   Out.String('Examples:'); Out.Ln;
   Out.String('  '); Out.String(s);
@@ -132,6 +136,8 @@ BEGIN
         IF i < Args.Count THEN INC(i); Args.Get(i, out) END
       ELSIF s = '-a' THEN (* All *)
         P.SetExportedOnly(FALSE)
+      ELSIF s = '-k' THEN (* Keep module aliases *)
+        P.SetKeepAliases(TRUE)
       ELSIF s = '--debug' THEN
         P.SetDebug(TRUE)
       ELSIF (s = '--inline-style') OR (s = '-i') THEN

+ 27 - 9
src/Autodoc/AutodocHtml.Mod

@@ -11,7 +11,7 @@ VAR
   TX: Texts.Text;
   W: Texts.Writer;
   
-  preventSemicol: BOOLEAN;
+  isLastItem: BOOLEAN;
 
   (** Render Settings **)
   showExportMarks: BOOLEAN; (** Value is exactly ~M.exportedOnly *)
@@ -168,6 +168,17 @@ BEGIN
   WriteLn('</section>')
 END PrintComment;
 
+PROCEDURE PrintImport(I: P.Import; indent: INTEGER; inlined: BOOLEAN);
+VAR tmp: BOOLEAN;
+BEGIN tmp := isLastItem; isLastItem := FALSE;
+  Write('<span class="import">');
+  IF I.name # I.alias THEN
+    Write('<span class="alias">'); Write(I.alias); Write('</span> := ')
+  END;
+  Write('<span class="name">'); Write(I.name); Write('</span>');
+  IF ~tmp THEN WriteLn(', ') END
+END PrintImport;
+
 PROCEDURE PrintOrdinalConst(C: P.Const);
 BEGIN
   Write('<tr><td class="name">'); Write(C.name); WriteExport(C);
@@ -198,7 +209,9 @@ BEGIN
     o := L.first;
     WHILE o # NIL DO
       IF ordinalConsts THEN PrintOrdinalConst(o(P.Const))
-      ELSE PrintObject(o, indent, FALSE)
+      ELSE
+        IF o = L.last THEN isLastItem := TRUE END;
+        PrintObject(o, indent, FALSE)
       END;
       o := o.next
     END;
@@ -208,7 +221,7 @@ END PrintList;
 
 PROCEDURE PrintParam(par: P.Param; indent: INTEGER; inlined: BOOLEAN);
 VAR tmp: BOOLEAN;
-BEGIN tmp := preventSemicol; preventSemicol := FALSE;
+BEGIN tmp := isLastItem; isLastItem := FALSE;
   Write('<span class="param">');
   IF par.passed = P.byVar THEN
     Write('<span class="passed by-var">VAR</span>&nbsp;')
@@ -222,7 +235,7 @@ END PrintParam;
 
 PROCEDURE PrintVar(v: P.Var; indent: INTEGER; inlined: BOOLEAN);
 VAR tmp: BOOLEAN;
-BEGIN tmp := preventSemicol; preventSemicol := FALSE;
+BEGIN tmp := isLastItem; isLastItem := FALSE;
   IF inlined THEN
     Write('<span class="var">');
     PrintIndent(indent);
@@ -260,7 +273,7 @@ BEGIN
       x := T.fields.first;
       IF x # NIL THEN WriteLn('<span class="record-fields">') END;
       WHILE x # NIL DO
-        IF x = T.fields.last THEN preventSemicol := TRUE END;
+        IF x = T.fields.last THEN isLastItem := TRUE END;
         PrintObject(x, indent + 1, TRUE);
         x := x.next
       END;
@@ -272,7 +285,7 @@ BEGIN
       x := T.fields.first;
       IF (x # NIL) OR (T.base # NIL) THEN Write(' (');
         WHILE x # NIL DO
-          IF x = T.fields.last THEN preventSemicol := TRUE END;
+          IF x = T.fields.last THEN isLastItem := TRUE END;
           PrintObject(x, indent, TRUE);
           x := x.next
         END;
@@ -306,7 +319,7 @@ BEGIN
   x := p.params.first;
   IF (x # NIL) OR (p.returnType # NIL) THEN Write('(');
     WHILE x # NIL DO
-      IF x = p.params.last THEN preventSemicol := TRUE END;
+      IF x = p.params.last THEN isLastItem := TRUE END;
       PrintObject(x, indent, TRUE);
       x := x.next
     END;
@@ -370,6 +383,10 @@ BEGIN
   showExportMarks := ~M.exportedOnly;
   Header(M.name);
   PrintComment(M, FALSE);
+  IF M.imports.first # NIL THEN
+    Lang.Get('import', s); BigTitle(s);
+    PrintList(M.imports, 0, FALSE)
+  END;
   Lang.Get('constants', s); BigTitle(s);
   PrintList(M.consts, 0, FALSE);
   Lang.Get('types', s); BigTitle(s);
@@ -385,9 +402,10 @@ PROCEDURE PrintObject0(o: P.Object; indent: INTEGER; inlined: BOOLEAN);
 BEGIN
   IF o = NIL THEN WriteLn('NIL')
   ELSIF o IS P.Module THEN PrintModule(o(P.Module), indent, inlined)
-  ELSIF o IS P.Var THEN PrintVar(o(P.Var), indent, inlined)
+  ELSIF o IS P.Import THEN PrintImport(o(P.Import), indent, inlined)
   ELSIF o IS P.Const THEN PrintConst(o(P.Const), indent, inlined)
   ELSIF o IS P.Type THEN PrintType(o(P.Type), indent, inlined)
+  ELSIF o IS P.Var THEN PrintVar(o(P.Var), indent, inlined)
   ELSIF o IS P.Procedure THEN PrintProcedure(o(P.Procedure), indent, inlined)
   ELSIF o IS P.Param THEN PrintParam(o(P.Param), indent, inlined)
   ELSIF o IS P.List THEN PrintList(o(P.List), indent, inlined)
@@ -408,7 +426,7 @@ END SetLang;
 PROCEDURE Save*(module: P.Module; fname: ARRAY OF CHAR): BOOLEAN;
 BEGIN
   LoadLang; NEW(TX); Texts.Open(TX, ''); Texts.OpenWriter(W);
-  preventSemicol := FALSE;
+  isLastItem := FALSE;
   PrintObject(module, 0, FALSE);
   Texts.Append(TX, W.buf); Texts.Close(TX, fname)
 RETURN TRUE END Save;

+ 77 - 27
src/Autodoc/AutodocParser.Mod

@@ -90,7 +90,9 @@ TYPE
   END;
   
   Import* = POINTER TO ImportDesc;
-  ImportDesc* = RECORD(ObjectDesc) END;
+  ImportDesc* = RECORD(ObjectDesc)
+    alias*: Str
+  END;
 
   Const* = POINTER TO ConstDesc;
   ConstDesc* = RECORD(ObjectDesc)
@@ -134,6 +136,7 @@ TYPE
   END;
 
 VAR
+  curModule: Module; (** Currently generated module data structure *)
   curFname: Str; (** Set by SetFname and used in Mark for error output *)
   R: Files.Rider; (** Rider of the currently parsed module *)
   c: CHAR; (** One step ahead character read from rider R *)
@@ -141,6 +144,7 @@ VAR
   lastError: INTEGER; (** Position in R of last error, or -1 *)
   constExprBeginPos: INTEGER; (** After '=' or 'ARRAY', see ParseConstExpr *)
   constExprBeginC: CHAR; (** Value of c the moment constExprBeginPos is set *)
+  objectIsExported: BOOLEAN; (** The parsed variable/field/param is exported *)
 
   sym: INTEGER; (** One step ahead (syntactic) symbol read *)
 
@@ -163,6 +167,7 @@ VAR
   (** Parsing Parameters **)
   
   exportedOnly: BOOLEAN; (** If TRUE, only exported objects are added *)
+  keepAliases: BOOLEAN; (** If FALSE, change alias to real module names *)
   
   (** Debug **)
   debug*: BOOLEAN;
@@ -173,6 +178,10 @@ PROCEDURE SetExportedOnly*(yes: BOOLEAN);
 BEGIN exportedOnly := yes
 END SetExportedOnly;
 
+PROCEDURE SetKeepAliases*(yes: BOOLEAN);
+BEGIN keepAliases := yes
+END SetKeepAliases;
+
 (** Debug **)
 
 PROCEDURE Debug*(s: ARRAY OF CHAR);
@@ -191,6 +200,7 @@ PROCEDURE SetFname*(fname: ARRAY OF CHAR);
 BEGIN curFname := fname
 END SetFname;
 
+(** Show error s *)
 PROCEDURE Mark(s: ARRAY OF CHAR);
 VAR pos: INTEGER;
 BEGIN
@@ -203,6 +213,13 @@ BEGIN
   lastError := pos
 END Mark;
 
+(** Show error consisting of a + b + c *)
+PROCEDURE Mark3(a, b, c: ARRAY OF CHAR);
+VAR s: ARRAY 1024 OF CHAR;
+BEGIN s := a; Strings.Append(b, s); Strings.Append(c, s); Mark(s)
+END Mark3;
+
+(** Put textual representation of sym in s *)
 PROCEDURE SymToStr(sym: INTEGER; VAR s: ARRAY OF CHAR);
 BEGIN
   IF    sym = null      THEN s := 'nothing'
@@ -252,15 +269,16 @@ BEGIN
   END
 END SymToStr;
 
+(** Show error that something is expected, but something else found. *)
 PROCEDURE MarkExp(name: ARRAY OF CHAR);
 VAR s, word: ARRAY 256 OF CHAR;
 BEGIN
   s := name; Strings.Append(' expected, but ', s);
   SymToStr(sym, word); Strings.Append(word, s);
-  Strings.Append(' found', s);
-  Mark(s)
+  Strings.Append(' found', s); Mark(s)
 END MarkExp;
 
+(** Show error that a module or a procedure was not closed *)
 PROCEDURE MarkEnd(title, name: ARRAY OF CHAR);
 VAR s, word: ARRAY 256 OF CHAR;
 BEGIN
@@ -270,10 +288,12 @@ END MarkEnd;
 
 (** Handle Comments **)
 
+(** Remove all comments from doc *)
 PROCEDURE ClearComments;
 BEGIN doc[0] := 0X; docLen := 0; docLine := -1
 END ClearComments;
 
+(** If doc is not empty, remove the first comment (until the 1st tab or 0X) *)
 PROCEDURE RemoveLastComment;
 BEGIN
   WHILE (docLen # 0) & (doc[docLen] # tab) DO DEC(docLen) END;
@@ -282,6 +302,7 @@ END RemoveLastComment;
 
 (** Comments **)
 
+(** Append a comment to the end of doc (tab is separator) *)
 PROCEDURE AppendComment(VAR comment: ARRAY OF CHAR);
 VAR L, i, j: INTEGER;
 BEGIN
@@ -296,6 +317,7 @@ BEGIN
   END
 END AppendComment;
 
+(** Get text of the last comment *)
 PROCEDURE GetLastComment(VAR comment: ARRAY OF CHAR);
 VAR L, i, j: INTEGER;
 BEGIN
@@ -306,6 +328,7 @@ BEGIN
   END
 END GetLastComment;
 
+(** Join all comments and attach them to o *)
 PROCEDURE SaveAllComments(o: Object);
 VAR i: INTEGER;
 BEGIN
@@ -338,6 +361,7 @@ END SaveComment;
 
 (** Scanner **)
 
+(** Text Driver *)
 PROCEDURE Read;
 BEGIN
   IF c = 0AX THEN INC(line); col := 0 END;
@@ -405,6 +429,7 @@ BEGIN
   END
 END ReadNumber;
 
+(** Attach a character to the end of comment in global varaible doc *)
 PROCEDURE WriteDoc(c: CHAR);
 BEGIN
   IF writingDoc & (docLen < LEN(doc) - 1) &
@@ -415,6 +440,7 @@ BEGIN
   END
 END WriteDoc;
 
+(** Recursive procedure to read (potentially nested) comments *)
 PROCEDURE ReadComment(toplevel: BOOLEAN);
 VAR closed, tmp: BOOLEAN;
   x: CHAR;
@@ -781,7 +807,7 @@ END Print;
 (** Object **)
 
 PROCEDURE InitObject(o: Object);
-BEGIN o.name[0] := 0X; o.comment[0] := 0X; o.next := NIL
+BEGIN o.name[0] := 0X; o.comment[0] := 0X; o.next := NIL; o.exported := FALSE
 END InitObject;
 
 (** Sets exported field of object to TRUE or FALSE
@@ -790,7 +816,8 @@ PROCEDURE CheckExportMark(o: Object);
 BEGIN
   IF (sym = times) OR (sym = minus) THEN GetSym; o.exported := TRUE
   ELSE o.exported := FALSE
-  END
+  END;
+  objectIsExported := o.exported
 END CheckExportMark;
 
 (** Skips compiler directives such as [notag]
@@ -805,10 +832,21 @@ BEGIN
   END
 END CheckDirective;
 
-(** Registers the given module name as imported module in global variable M. *)
-PROCEDURE AddImportedModule(name: ARRAY OF CHAR);
+(** Finds import with the given alias in curModule. If parameter exported
+    is TRUE, marks the import object as exported. Depending on keepAliases,
+    on may replace value of VAR-parameter name from with the real name of
+    the imported module. *)
+PROCEDURE CheckImportedModule(VAR name: ARRAY OF CHAR; exported: BOOLEAN);
+VAR x: Object;
 BEGIN
-END AddImportedModule;
+  x := curModule.imports.first;
+  WHILE (x # NIL) & (x(Import).alias # name) DO x := x.next END;
+  IF x # NIL THEN
+    IF exported THEN x.exported := TRUE END;
+    IF ~keepAliases THEN Strings.Copy(x.name, name) END
+  ELSE Mark3('Module "', name, '" not imported.')
+  END
+END CheckImportedModule;
 
 (** Type **)
 
@@ -1000,17 +1038,14 @@ BEGIN curTitle := '-';
       Debug(id);
       UpdateCurGroup(M.types);
       T := NewType(namedType); SaveAllComments(T);
-      AddToList(M.types.last(List), T);
-      Debug('ParseTypeDecl before CheckExportMark');
       Strings.Copy(id, T.name); GetSym; CheckExportMark(T);
-      Debug('ParseTypeDecl after CheckExportMark');
       IF sym = equals THEN GetSym ELSE MarkExp('=') END;
-      Debug('ParseTypeDecl before ParseType');
       T.base := ParseType(T); line2 := line;
-      Debug('ParseTypeDecl after ParseType');
       IF sym = semicol THEN GetSym ELSE MarkExp(';') END;
-      SaveComment(T, line2);
-      Debug('ParseTypeDecl end of WHILE iteration')
+      IF ~exportedOnly OR T.exported THEN
+        AddToList(M.types.last(List), T)
+      END;
+      SaveComment(T, line2)
     END
   END
 END ParseTypeDecl;
@@ -1020,11 +1055,10 @@ VAR T: Type;
 BEGIN
   IF sym = ident THEN
     T := NewType(namedType);
-    Strings.Copy(id, T.name);
-    GetSym;
+    Strings.Copy(id, T.name); GetSym;
     IF sym = period THEN GetSym;
       IF sym = ident THEN
-        AddImportedModule(T.name);
+        CheckImportedModule(T.name, objectIsExported);
         Strings.Append('.', T.name); Strings.Append(id, T.name); GetSym
       ELSE MarkExp('identifier')
       END
@@ -1208,23 +1242,35 @@ VAR I: Import;
 BEGIN
   IF sym = ident THEN
     I := NewImport(); GetSym;
+    Strings.Copy(I.name, I.alias);
     IF sym = becomes THEN GetSym;
-      Strings.Copy(I.name, I.alias);
-      Strings.Copy(id, I.name);
-      GetSym
-    END
-  END (*!TODO*)
+      Strings.Copy(id, I.name); GetSym
+    END;
+    AddToList(M.imports, I)
+  END
 END ParseImport;
 
 PROCEDURE ParseImportList(M: Module);
 BEGIN
   IF sym = import THEN
     GetSym; ParseImport(M);
-    WHILE sym = comma DO GetSym; ParseImport(M) END
+    WHILE sym = comma DO GetSym; ParseImport(M) END;
     IF sym = semicol THEN GetSym ELSE MarkExp(';') END
   END
 END ParseImportList;
 
+PROCEDURE CleanImportList(M: Module);
+VAR x, next: Object;
+BEGIN
+  x := M.imports.first;
+  WHILE x # NIL DO next := x.next;
+    IF ~x.exported THEN RemoveFromList(M.imports, x)
+    ELSIF ~keepAliases THEN Strings.Copy(x.name, x(Import).alias)
+    END;
+    x := next
+  END
+END CleanImportList;
+
 PROCEDURE FindMin(G: Group; ordinal: BOOLEAN): Object;
 VAR x: Object;
 BEGIN
@@ -1290,10 +1336,12 @@ END SortModule;
 
 PROCEDURE ParseModule*(VAR r: Files.Rider; VAR err: ARRAY OF CHAR): Module;
 VAR M: Module;
-BEGIN NEW(M); InitObject(M); M.foreign := FALSE;
-  M.exportedOnly := exportedOnly; M.consts := NewList();
+BEGIN NEW(M); InitObject(M); curModule := M;
+  M.foreign := FALSE; M.exportedOnly := exportedOnly;
+  M.imports := NewList(); M.consts := NewList();
   M.types := NewList(); M.vars := NewList(); M.procedures := NewList();
   R := r; c := 0X; line := 1; col := 0; lastError := -1;
+  objectIsExported := FALSE;
   Read; ClearComments; curTitle := '-'; GetSym;
   Debug('Begin ParseModule');
   IF sym = module THEN GetSym;
@@ -1322,6 +1370,7 @@ BEGIN NEW(M); InitObject(M); M.foreign := FALSE;
     END
   ELSE MarkExp('MODULE')
   END;
+  IF exportedOnly THEN CleanImportList(M) END;
   Debug('Begin SortModule');
   IF lastError = -1 THEN SortModule(M)
   ELSE M := NIL; err := 'Error' (*!FIXME*)
@@ -1334,5 +1383,6 @@ BEGIN
   ParseType := ParseType0;
   ParseParamType := ParseParamType0;
 
-  curFname[0] := 0X; debug := FALSE; exportedOnly := TRUE
+  curFname[0] := 0X; debug := FALSE;
+  exportedOnly := TRUE; keepAliases := FALSE
 END AutodocParser.

+ 1 - 0
src/Autodoc/Data/Langs/en.dat

@@ -1,6 +1,7 @@
 0 "Error message example"
 
 generatedMsg "Generated automatically by Free Oberon Autodoc"
+import "Imports"
 constants "Constants"
 types "Types"
 variables "Variables"

+ 1 - 0
src/Autodoc/Data/Langs/ru.dat

@@ -1,6 +1,7 @@
 0 "Пример сообщения об ошибке"
 
 generatedMsg "Сгенерировано автоматически при помощи системы Фри Оберон Автодок"
+import "Импортирует"
 constants "Постоянные"
 types "Типы"
 variables "Переменные"

+ 5 - 3
src/Autodoc/Test/Apples.Mod

@@ -22,7 +22,7 @@
     call Init and other procedures on it *)
 MODULE Apples;
 (** Это тестовый модуль. *)
-IMPORT Out, Fruits;
+IMPORT Out, F := Files, SYSTEM, Fruits;
 
 CONST
   str4* = "В двойных кавычках.";
@@ -64,6 +64,8 @@ CONST
 
 TYPE
 
+  FL = F.File;
+
   LetterA = CHAR;
   LetterB = CHAR;
 
@@ -77,7 +79,7 @@ TYPE
   END;
 
   (** - **)
-  LetterC = CHAR;
+  LetterC* = CHAR;
   LetterD = CHAR;
 
   (** ВСЯКОЕ **)
@@ -101,7 +103,7 @@ VAR
   shown: BOOLEAN;
   lastAdded*: INTEGER; (** How many seeds were added the last time, or -1 *)
   (** ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ ЗАПИСНЫХ ТИПОВ **)
-  R: RECORD
+  R*: RECORD(F.Rider)
     t, x: INTEGER; (** Время в секундах и мс *)
     z, y: Array    (** Z-буфер, показатель светимости  *)
   END;