Răsfoiți Sursa

Автодок: экспортированность

Arthur Yefimov 2 ani în urmă
părinte
comite
c5fa6549b0
4 a modificat fișierele cu 141 adăugiri și 56 ștergeri
  1. 10 7
      src/Autodoc/Autodoc.Mod
  2. 20 6
      src/Autodoc/AutodocHtml.Mod
  3. 101 39
      src/Autodoc/AutodocParser.Mod
  4. 10 4
      src/Autodoc/Data/style.css

+ 10 - 7
src/Autodoc/Autodoc.Mod

@@ -125,17 +125,20 @@ BEGIN
   IF Args.Count = 0 THEN
     Usage
   ELSE
-    out[0] := 0X;
-    i := 1; fnameCount := 0;
+    out[0] := 0X; i := 1; fnameCount := 0;
     WHILE i <= Args.Count DO
       Args.Get(i, s);
-      IF s = '-o' THEN
+      IF s = '-o' THEN (* Output file or dir *)
         IF i < Args.Count THEN INC(i); Args.Get(i, out) END
+      ELSIF s = '-a' THEN (* All *)
+        P.SetExportedOnly(FALSE)
+      ELSIF s = '--debug' THEN
+        P.SetDebug(TRUE)
       ELSIF (s = '--inline-style') OR (s = '-i') THEN
         H.SetInlineStyle(TRUE)
-      ELSIF s = '--lang' THEN
+      ELSIF s = '--lang' THEN (* Output language *)
         IF i < Args.Count THEN INC(i); Args.Get(i, s); H.SetLang(s) END
-      ELSE
+      ELSE (* On of the file names with Oberon modules *)
         IF fnameCount < LEN(fnames) THEN
           Strings.Copy(s, fnames[fnameCount]);
           INC(fnameCount)
@@ -143,10 +146,10 @@ BEGIN
       END;
       INC(i)
     END;
-    IF fnameCount = 1 THEN
+    IF fnameCount = 1 THEN (* Single file given *)
       IF out[0] = 0X THEN FnameToHtml(fnames[0], out) END;
       HandleFile(fnames[0], out)
-    ELSE
+    ELSE (* Multiple file given, treat "-o" parameter as directory *)
       FOR i := 0 TO fnameCount - 1 DO
         HandleFileToDir(fnames[i], out)
       END

+ 20 - 6
src/Autodoc/AutodocHtml.Mod

@@ -13,6 +13,8 @@ VAR
   
   preventSemicol: BOOLEAN;
 
+  (** Render Settings **)
+  showExportMarks: BOOLEAN; (** Value is exactly ~M.exportedOnly *)
   inlineStyle: BOOLEAN;
   lang: ARRAY 6 OF CHAR;
 
@@ -79,6 +81,13 @@ BEGIN string := FALSE; i := 0; x := s[0];
   IF string THEN Write('</i>') END
 END WriteExpr;
 
+PROCEDURE WriteExport(o: P.Object);
+BEGIN
+  IF showExportMarks & (o # NIL) & o.exported THEN
+    Write('<span class="export">*</span>')
+  END
+END WriteExport;
+
 PROCEDURE WriteParagraphs(s: ARRAY OF CHAR; marks: BOOLEAN);
 VAR i: INTEGER;
   c: CHAR;
@@ -161,7 +170,8 @@ END PrintComment;
 
 PROCEDURE PrintOrdinalConst(C: P.Const);
 BEGIN
-  WriteLn3('<tr><td class="name">', C.name, '</td><td class="value">');
+  Write('<tr><td class="name">'); Write(C.name); WriteExport(C);
+  WriteLn('</td><td class="value">');
   WriteExpr(C.value); WriteLn('</td><td class="desc">');
   PrintComment(C, FALSE); WriteLn('</td></tr>')
 END PrintOrdinalConst;
@@ -170,7 +180,8 @@ PROCEDURE PrintConst(C: P.Const; indent: INTEGER; inlined: BOOLEAN);
 BEGIN
   WriteLn ('<article class="object const">');
   WriteLn ('  <div class="def">');
-  WriteLn3('    <span class="name">', C.name, '</span> =');
+  Write   ('    <span class="name">'); Write(C.name);
+  Write   ('</span>'); WriteExport(C); WriteLn(' =');
   Write   ('    <span class="value">'); WriteExpr(C.value); WriteLn('</span>;');
   WriteLn ('  </div>');
   PrintComment(C, FALSE);
@@ -216,7 +227,7 @@ BEGIN tmp := preventSemicol; preventSemicol := FALSE;
     Write('<span class="var">');
     PrintIndent(indent);
     Write('<span class="name">'); Write(v.name);
-    Write('</span>: <span class="type">');
+    Write('</span>'); WriteExport(v); Write(': <span class="type">');
     PrintObject(v.type, indent, TRUE);
     IF ~tmp THEN Write(';') END;
     Write(' &nbsp;</span></span>');
@@ -224,7 +235,8 @@ BEGIN tmp := preventSemicol; preventSemicol := FALSE;
   ELSE
     WriteLn ('<article class="object var">');
     WriteLn ('  <div class="def">');
-    WriteLn3('    <span class="name">', v.name, '</span>:');
+    Write   ('    <span class="name">'); Write(v.name);
+    WriteExport(v); WriteLn('</span>:');
     WriteLn ('    <span class="type">');
     PrintObject(v.type, indent, TRUE); WriteLn('</span>;');
     WriteLn ('  </div>');
@@ -273,7 +285,8 @@ BEGIN
   ELSE
     WriteLn ('<article class="object type">');
     WriteLn ('  <div class="def">');
-    WriteLn3('    <span class="name">', T.name, '</span> =');
+    Write   ('    <span class="name">'); Write(T.name); Write('</span>');
+    WriteExport(T); WriteLn(' =');
     WriteLn ('    <span class="typedef">');
     PrintObject(T.base, indent, TRUE); WriteLn('</span>;');
     WriteLn ('  </div>');
@@ -289,7 +302,7 @@ BEGIN
   WriteLn ('  <div class="def">');
   WriteLn ('    PROCEDURE');
   Write   ('    <span class="name">'); Write(p.name);
-  Write('</span><span class="params">');
+  Write('</span>'); WriteExport(p); Write('<span class="params">');
   x := p.params.first;
   IF (x # NIL) OR (p.returnType # NIL) THEN Write('(');
     WHILE x # NIL DO
@@ -354,6 +367,7 @@ END Footer;
 PROCEDURE PrintModule(M: P.Module; indent: INTEGER; inlined: BOOLEAN);
 VAR s: ARRAY 64 OF CHAR;
 BEGIN
+  showExportMarks := ~M.exportedOnly;
   Header(M.name);
   PrintComment(M, FALSE);
   Lang.Get('constants', s); BigTitle(s);

+ 101 - 39
src/Autodoc/AutodocParser.Mod

@@ -66,9 +66,6 @@ CONST
 
   (** Comment separator **)
   tab = 9X;
-  
-  (** Parser Settings **)
-  debug* = FALSE;
 
 TYPE
   Str* = ARRAY 256 OF CHAR;
@@ -127,6 +124,7 @@ TYPE
   Module* = POINTER TO ModuleDesc;
   ModuleDesc* = RECORD(ObjectDesc)
     foreign*: BOOLEAN; (** TRUE if module has a [foreign] mark *)
+    exportedOnly*: BOOLEAN; (** TRUE if only exported objects are included *)
     consts*: List;
     types*: List;
     vars*: List;
@@ -159,6 +157,19 @@ VAR
   PrintObject: PROCEDURE (o: Object; indent: INTEGER; inlined: BOOLEAN);
   ParseType: PROCEDURE (docObj: Object): Type;
   ParseParamType: PROCEDURE (): Type;
+  
+  (** Parsing Parameters **)
+  
+  exportedOnly: BOOLEAN; (** If TRUE, only exported objects are added *)
+  
+  (** Debug **)
+  debug*: BOOLEAN;
+
+(** Parsing Parameters **)
+
+PROCEDURE SetExportedOnly*(yes: BOOLEAN);
+BEGIN exportedOnly := yes
+END SetExportedOnly;
 
 (** Debug **)
 
@@ -167,6 +178,10 @@ BEGIN
   IF debug THEN Out.String(s); Out.Ln END
 END Debug;
 
+PROCEDURE SetDebug*(yes: BOOLEAN);
+BEGIN debug := yes
+END SetDebug;
+
 (** Error Handling **)
 
 (** Used for error output in Mark *)
@@ -291,11 +306,14 @@ END GetLastComment;
 
 PROCEDURE SaveAllComments(o: Object);
 VAR i: INTEGER;
-BEGIN Strings.Copy(doc, o.comment); ClearComments;
-  i := 0;
-  WHILE o.comment[i] # 0X DO
-    IF o.comment[i] = tab THEN o.comment[i] := 0AX END;
-    INC(i)
+BEGIN
+  IF o # NIL THEN
+    Strings.Copy(doc, o.comment); ClearComments;
+    i := 0;
+    WHILE o.comment[i] # 0X DO
+      IF o.comment[i] = tab THEN o.comment[i] := 0AX END;
+      INC(i)
+    END
   END
 END SaveAllComments;
 
@@ -418,10 +436,10 @@ BEGIN
             tmp := writingDoc;
             ReadComment(FALSE);
             writingDoc := tmp
-          ELSE WriteDoc('(')
+          ELSE WriteDoc('('); Read
           END
-        END;
-        WriteDoc(c); Read
+        ELSE WriteDoc(c); Read
+        END
       END;
       IF c = '*' THEN Read;
         IF c # ')' THEN WriteDoc('*') END
@@ -764,12 +782,27 @@ PROCEDURE InitObject(o: Object);
 BEGIN o.name[0] := 0X; o.comment[0] := 0X; o.next := NIL
 END InitObject;
 
-(** Sets exported field of object and skips the star mark. *)
+(** Sets exported field of object to TRUE or FALSE
+    and skips the star (or minus) mark. *)
 PROCEDURE CheckExportMark(o: Object);
 BEGIN
-  IF sym = times THEN GetSym; o.exported := TRUE ELSE o.exported := FALSE END
+  IF (sym = times) OR (sym = minus) THEN GetSym; o.exported := TRUE
+  ELSE o.exported := FALSE
+  END
 END CheckExportMark;
 
+(** Skips compiler directives such as [notag]
+    after POINTER, ARRAY and RECORD symbols.
+     Does not change o in any way (yet). *)
+PROCEDURE CheckDirective(o: Object);
+BEGIN
+  IF sym = lbrak THEN GetSym;
+    IF (sym = ident) OR (sym = int) THEN GetSym;
+      IF sym = rbrak THEN GetSym END
+    END
+  END
+END CheckDirective;
+
 (** Type **)
 
 PROCEDURE NewType(form: INTEGER): Type;
@@ -861,19 +894,29 @@ VAR first, v: Var;
   x: Object;
   passed, line2: INTEGER;
   T: Type;
-  stop: BOOLEAN;
+  stop, added: BOOLEAN;
 BEGIN L := NewList(); stop := FALSE;
+  Debug('ParseVars begin');
   WHILE ~stop & (sym = ident) DO
+    Debug('ParseVars inside WHILE');
+    Debug(id);
     IF isVarDecl THEN UpdateCurGroup(L) END;
     first := NewVar(); SaveAllComments(first); GetSym; CheckExportMark(first);
-    IF isVarDecl THEN AddToList(L.last(List), first)
-    ELSE AddToList(L, first)
+    IF first.exported OR ~exportedOnly THEN
+      IF isVarDecl THEN AddToList(L.last(List), first)
+      ELSE AddToList(L, first)
+      END;
+      added := TRUE
+    ELSE added := FALSE; first := NIL
     END;
     WHILE sym = comma DO GetSym;
       IF sym = ident THEN v := NewVar(); GetSym; CheckExportMark(v);
-        IF isVarDecl THEN AddToList(L.last(List), v)
-        ELSE AddToList(L, v)
-        END;
+        IF v.exported OR ~exportedOnly THEN
+          IF isVarDecl THEN AddToList(L.last(List), v)
+          ELSE AddToList(L, v)
+          END;
+          IF ~added THEN first := v; added := TRUE END
+        END
       ELSE MarkExp('variable (field) name')
       END
     END;
@@ -887,14 +930,15 @@ BEGIN L := NewList(); stop := FALSE;
       IF sym = semicol THEN GetSym; SaveComment(first, line2)
       ELSE stop := TRUE; SaveAllComments(first)
       END;
-      IF first.comment[0] # 0X THEN x := first.next;
+      IF (first # NIL) & (first.comment[0] # 0X) THEN x := first.next;
         WHILE x # NIL DO
           Strings.Copy(first.comment, x.comment); x := x.next
         END
       END
     ELSE MarkExp(';')
     END
-  END
+  END;
+  Debug('ParseVars end')
 RETURN L END ParseVars;
 
 PROCEDURE CheckOrdinal(C: Const);
@@ -918,7 +962,9 @@ BEGIN curTitle := '-';
       Debug(id);
       UpdateCurGroup(M.consts);
       C := NewConst(); SaveComment(C, -1); GetSym; CheckExportMark(C);
-      AddToList(M.consts.last(List), C);
+      IF C.exported OR ~exportedOnly THEN
+        AddToList(M.consts.last(List), C)
+      END;
       constExprBeginPos := Files.Pos(R); constExprBeginC := c;
       IF sym = equals THEN GetSym ELSE MarkExp('=') END;
       Debug('Begin ParseConstExpr');
@@ -937,14 +983,20 @@ VAR T: Type;
 BEGIN curTitle := '-';
   IF sym = type THEN GetSym;
     WHILE sym = ident DO
+      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)
+      SaveComment(T, line2);
+      Debug('ParseTypeDecl end of WHILE iteration')
     END
   END
 END ParseTypeDecl;
@@ -971,7 +1023,7 @@ VAR T, T1: Type;
   tmp: INTEGER;
 BEGIN ASSERT(sym = array);
   constExprBeginPos := Files.Pos(R); constExprBeginC := c; GetSym;
-  T := NewType(arrayType); T1 := T;
+  T := NewType(arrayType); T1 := T; CheckDirective(T);
   IF (sym # of) THEN
     ParseConstExpr(T.len, isInt, tmp)
   END;
@@ -988,18 +1040,21 @@ PROCEDURE ParseRecordType(docObj: Object): Type;
 VAR T: Type;
   line2: INTEGER;
 BEGIN ASSERT(sym = record); line2 := line; GetSym;
-  T := NewType(recordType);
+  Debug('ParseRecordType begin');
+  T := NewType(recordType); CheckDirective(T);
   IF sym = lparen THEN GetSym; T.base := ParseNamedType();
     IF sym = rparen THEN GetSym ELSE MarkExp(')') END
   END;
   SaveComment(docObj, line2);
   T.fields := ParseVars(FALSE);
-  IF sym = end THEN GetSym ELSE MarkExp('END') END
+  IF sym = end THEN GetSym ELSE MarkExp('END') END;
+  Debug('ParseRecordType end')
 RETURN T END ParseRecordType;
 
 PROCEDURE ParsePointerType(docObj: Object): Type;
 VAR T: Type;
-BEGIN ASSERT(sym = pointer); GetSym; T := NewType(pointerType);
+BEGIN ASSERT(sym = pointer); GetSym;
+  T := NewType(pointerType); CheckDirective(T);
   IF sym = to THEN GetSym ELSE MarkExp('TO') END;
   T.base := ParseType(docObj)
 RETURN T END ParsePointerType;
@@ -1082,13 +1137,14 @@ END ReachEndOf;
 PROCEDURE ParseProcedureDecl(M: Module);
 VAR name: Str;
   P: Procedure;
+  forward: BOOLEAN;
 BEGIN curTitle := '-';
   WHILE sym = procedure DO UpdateCurGroup(M.procedures);
-    GetSym; NEW(P); InitObject(P);
+    GetSym; NEW(P); InitObject(P); forward := FALSE;
     P.params := NewList(); P.exported := FALSE;
-    AddToList(M.procedures.last(List), P);
-    IF (sym = minus) OR (sym = times) OR (sym = arrow) THEN GetSym END;
-    
+    IF (sym = minus) OR (sym = arrow) THEN GetSym; forward := TRUE
+    ELSIF sym = times THEN GetSym
+    END;
     IF sym = ident THEN Strings.Copy(id, P.name); GetSym
     ELSE MarkExp('procedure name')
     END;
@@ -1101,11 +1157,15 @@ BEGIN curTitle := '-';
       IF sym = rparen THEN GetSym ELSE MarkExp(')') END;
       IF sym = colon THEN GetSym; P.returnType := ParseNamedType() END
     END;
+    IF sym = string THEN GetSym END; (* Foreign code *)
     IF sym = semicol THEN GetSym ELSE MarkExp(';') END;
-    ReachEndOf(P.name); SaveComment(P, -1);
-    IF sym = ident THEN GetSym;
-      IF sym = semicol THEN GetSym ELSE MarkExp(';') END
-    ELSE (* sym = eot *) MarkEnd('Procedure', P.name)
+    IF ~forward THEN
+      ReachEndOf(P.name); SaveComment(P, -1);
+      IF sym = ident THEN GetSym;
+        IF sym = semicol THEN GetSym ELSE MarkExp(';') END
+      ELSE (* sym = eot *) MarkEnd('Procedure', P.name)
+      END;
+      IF P.exported OR ~exportedOnly THEN AddToList(M.procedures.last(List), P) END
     END
   END
 END ParseProcedureDecl;
@@ -1199,8 +1259,8 @@ 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.consts := NewList(); M.types := NewList();
-  M.vars := NewList(); M.procedures := NewList();
+  M.exportedOnly := exportedOnly; M.consts := NewList();
+  M.types := NewList(); M.vars := NewList(); M.procedures := NewList();
   R := r; c := 0X; line := 1; col := 0; lastError := -1;
   Read; ClearComments; curTitle := '-'; GetSym;
   Debug('Begin ParseModule');
@@ -1237,8 +1297,10 @@ BEGIN NEW(M); InitObject(M); M.foreign := FALSE;
   Debug('End ParseModule');
 RETURN M END ParseModule;
 
-BEGIN curFname[0] := 0X;
+BEGIN
   PrintObject := PrintObject0;
   ParseType := ParseType0;
-  ParseParamType := ParseParamType0
+  ParseParamType := ParseParamType0;
+
+  curFname[0] := 0X; debug := FALSE; exportedOnly := TRUE
 END AutodocParser.

+ 10 - 4
src/Autodoc/Data/style.css

@@ -8,11 +8,18 @@ body, p, h1, h2, h3, h4, h5, h6 {
   padding: 0;
 }
 
+html {
+  height: 100%;
+}
+
 body {
   font-family: customfont, monospace, sans-serif;
   font-size: 14px;
   background: #FBC5AA;
   color: #12365D;
+  min-height: 100%;
+  display: flex;
+  flex-direction: column;
 }
 
 a {
@@ -58,6 +65,7 @@ a:hover {
 
 .main {
   padding: 20px 0;
+  flex: 1;
 }
 
 h2, h3, h4, h5, h6 {
@@ -186,14 +194,12 @@ h2, h3, h4, h5, h6 {
   grid-template-columns: auto 1fr;
 }
 
-.record-fields .var {
-}
-
 .record-fields .comment {
   padding: 0;
 }
 
-.record-field .comment p {
+.export {
+  color: #12365D;
 }
 
 @media screen and (max-width: 500px) {