//===================================================================== /// <summary> /// Writes a file that documents a single class. /// </summary> public void WriteClassFile(String fileName, ClassDef cd) { System.Console.Out.WriteLine("writing " + fileName); StreamWriter w = new StreamWriter(fileName); w.WriteLine("<html>\r\n<head>" + "<link rel=stylesheet type=\"text/css\" " + "href=\"../libref.css\">" + "<title>" + cd.Name + "</title>" // + "<script type=\"text/javascript\" " // + "src=\"../libref.js\"></script>" // + "</head><body onload=\"frmLd()\">"); + "</head><body>"); this.WriteFileTitle(w, (cd.IsGrammar ? "grammar" : "class"), cd.Name, this.FileLinks(cd.Source), cd.Modifications); w.WriteLine("<table class=nav><tr>"); w.WriteLine("<td>" + Hyperlink(null, "_SuperClassTree_", null, "Superclass<br>Tree")); if (!cd.IsGrammar) { w.WriteLine("<td>" + Hyperlink(null, "_SubClassTree_", null, "Subclass<br>Tree")); w.WriteLine("<td>" + Hyperlink(null, "_ObjectSummary_", null, "Global<br>Objects")); } w.WriteLine("<td>" + Hyperlink(null, "_PropSummary_", null, "Property<br>Summary")); w.WriteLine("<td>" + Hyperlink(null, "_MethodSummary_", null, "Method<br>Summary")); w.WriteLine("<td>" + Hyperlink(null, "_Properties_", null, "Property<br>Details")); w.WriteLine("<td>" + Hyperlink(null, "_Methods_", null, "Method<br>Details")); w.WriteLine("</table><div class=fdesc>"); if (cd.Description == "") w.WriteLine("<i>no description available</i>"); else w.WriteLine(EncodeEntities(cd.Description)); foreach (Modification mod in cd.ModificationMods) { if (mod.Description != "") { w.WriteLine("<p><i>Modified in " + FileLinks(mod.Source) + ":</i><br>"); w.WriteLine(EncodeEntities(mod.Description)); } } w.WriteLine("<p>"); WriteObjectDecl(w, cd, false); w.WriteLine("</div>"); /* w.Write("Subclasses: <code>"); foreach (ClassDef sc in cd.SubClasses) w.Write(" <a href=\"" + sc.Name + ".html\">" + sc.Name + "</a>"); w.WriteLine("</code>"); w.WriteLine("<p>"); */ this.WriteMajorHeading(w, "_SuperClassTree_", "Superclass Tree", "(in declaration order)"); this.WriteParentTree(w, cd); if (!cd.IsGrammar) { this.WriteMajorHeading(w, "_SubClassTree_", "Subclass Tree", ""); this.WriteChildTree(w, cd); this.WriteMajorHeading(w, "_ObjectSummary_", "Global Objects", ""); if (cd.GlobalObjects.Count == 0) w.WriteLine("<i>(none)</i>"); else { w.WriteLine("<code>"); foreach (ObjectDef od in cd.GlobalObjects) w.WriteLine(Hyperlink( "../" + this.ObjectFileName(od), od.Name) + " "); w.WriteLine("</code>"); } } this.WriteMajorHeading(w, "_PropSummary_", "Summary of Properties", ""); this.WritePropertySummary(w, cd); this.WriteMajorHeading(w, "_MethodSummary_", "Summary of Methods", ""); this.WriteMethodSummary(w, cd); this.WriteMajorHeading(w, "_Properties_", "Properties", ""); if (cd.Properties.Count == 0) w.WriteLine("<i>(none)</i>"); else { foreach (PropertyDef p in cd.Properties) this.WriteProperty(w, p); } this.WriteMajorHeading(w, "_Methods_", "Methods", ""); if (cd.Methods.Count == 0) w.WriteLine("<i>(none)</i>"); else { foreach (MethodDef m in cd.Methods) this.WriteMethod(w, m); } this.WriteHtmlFooter(w); w.Close(); }
private void WriteChildTree(StreamWriter w, ClassDef cd, String indent) { w.Write("<code>" + indent); if (indent == "") w.WriteLine("<b>" + cd.Name + "</b></code><br>"); // else w.WriteLine("<a href=\"" + cd.Name + ".html\">" + cd.Name + "</a></code><br>"); else w.WriteLine(Hyperlink("../" + this.ObjectFileName(cd), cd.Name) + "</code><br>"); indent += " "; foreach (object parent in cd.SubClasses) { if (parent is ClassDef) this.WriteChildTree(w, (ClassDef) parent, indent); else w.WriteLine("<code>" + indent + parent.ToString() + "</code><br>"); } }
//===================================================================== /// <summary> /// Writes the tree of child classes. /// </summary> private void WriteChildTree(StreamWriter w, ClassDef cd) { if (cd.SubClasses.Count == 0) w.WriteLine("<i>(none)</i>"); else this.WriteChildTree(w, cd, ""); }
//===================================================================== /// <summary> /// Processes a line which appears to define an intrinsic class. /// "intrinsic class" space identifier "'" stuff "'" ":" [identifier List] /// </summary> private void ProcessIntrinsicClass(String line) { // note: the keyboards "intrinsic class" have already been parsed ClassDef cr = new ClassDef(Path.GetFileName(CurrentFileName), LineNumber); cr.Name = GetNextToken(ref line); cr.Description = LastComment; LastComment = ""; if (cr.Name == "") return; // must not be a class after all int n = line.IndexOf(':'); if (n >= 0) { line = line.Substring(n+1); while (line != "") // collect base class names { cr.BaseClasses.Add(GetNextToken(ref line)); GetNextToken(ref line); // throw away comma } } cr.IsIntrinsic = true; SymbolTable.SetObjectFileName(cr); SymbolTable.Classes.Add(cr); this.CurrentSourceFile.Classes.Add(cr); CurrClassOrObj = cr; }
//===================================================================== /// <summary> /// Processes a line which appears to define a grammar object. /// "grammar" identifier "(" identifier ")" ":" [token-list] /// ":" [class-identifier-list] /// </summary> private void ProcessGrammar(String line, String origLine) { // note: the keyword "grammar" has already been parsed ClassDef cr = new ClassDef(Path.GetFileName(CurrentFileName), LineNumber); cr.Name = GetNextToken(ref line); cr.Description = LastComment; cr.IsGrammar = true; String origLine2 = origLine; bool isVerbRule = (GetNextToken(ref origLine2) == "VerbRule"); LastComment = ""; if (cr.Name == "") return; // must not be a class after all // parse the tag, if present if (cr.Name == "(" || GetNextToken(ref line) == "(") { // store the tagged version of the name String tag = GetNextToken(ref line); if (GetNextToken(ref line) != ")") return; if (isVerbRule) cr.Name = "VerbRule"; cr.Name += "(" + tag + ")"; // if we created this with VerbRule, remember this if (isVerbRule) { origLine = origLine.Trim(); int idx = origLine.IndexOf(")"); cr.OrigDef = origLine.Substring(0, idx + 1); } } // check for the ":" if (GetNextToken(ref line) != ":" && !isVerbRule) return; // must not be a grammar statement after all // skip the production token list, which probably spans // multiple lines String rule = ""; for (char qu = '\0' ; ; ) { int idx; bool found = false; // scan to the ":", or to end of line for (idx = 0 ; idx < line.Length ; ++idx) { switch (line[idx]) { case '\\': // skip the next character ++idx; break; case ':': // stop unless in a string if (qu == '\0') found = true; break; case '\'': case '"': if (qu != '\0') { if (qu == line[idx]) qu = '\0'; } else qu = line[idx]; break; } // if we found the ':', stop here if (found) break; } // add up to the end of this scan to the rule if (found) { // found it - add up to the ':' to the rule rule += line.Substring(0, idx).TrimEnd(); // continue from just past the ':' line = line.Substring(idx + 1); // we're done scanning the rule break; } // didn't find it - add this line and a newline to the rule if (line.Trim() != "") rule += line + "\u0001"; // continue to the next line of the rule line = GetNextLine(); } // now parse the class list line = line.Trim(); while (line != "") // collect base class names { // get the token cr.BaseClasses.Add(GetNextToken(ref line)); // check for and skip the comma if (GetNextToken(ref line) != ",") break; } // add the grammar list to the class cr.GrammarRule = rule; SymbolTable.SetObjectFileName(cr); SymbolTable.Classes.Add(cr); this.CurrentSourceFile.Classes.Add(cr); CurrClassOrObj = cr; // get the GrammarProd name - this is just the class name // sans the (tag) part int n; String gpName; if ((n = cr.Name.IndexOf('(')) >= 0) gpName = cr.Name.Substring(0, n); else gpName = cr.Name; // find the existing GrammarProd GrammarProd g = SymbolTable.FindGrammarProd(gpName); // if we didn't find one, create it if (g == null) { g = new GrammarProd(Path.GetFileName(CurrentFileName), LineNumber); g.Name = gpName; SymbolTable.SetObjectFileName(g); SymbolTable.GrammarProds.Add(g); } // add me to the GrammarProd's list of match objects g.MatchObjects.Add(cr); cr.GrammarProdObj = g; //if (isVerbRule) //{ // while (!line.Contains("action")) // { // line = GetNextLine(); // if (line.Contains(";")) // break; // } // if (line.Contains("action")) // { // while (GetNextToken(ref line) != "action") // ; // if (GetNextToken(ref line) != "=") // return; // String action = GetNextToken(ref line); // } //} }
//===================================================================== /// <summary> /// Processes a line which appears to define a class. /// "class" space identifier ":" [identifier List] /// </summary> private void ProcessClass(String line, String origLine) { // note: the keyword "class" has already been parsed ClassDef cr = new ClassDef(Path.GetFileName(CurrentFileName), LineNumber); cr.Name = GetNextToken(ref line); cr.Description = LastComment; LastComment = ""; if (cr.Name == "") return; // must not be a class after all if (GetNextToken(ref line) != ":") return; // must not be a class after all line = line.Trim(); while (line != "") // collect base class names { cr.BaseClasses.Add(GetNextToken(ref line)); // stop when we reach anything other than a comma if (GetNextToken(ref line) != ",") break; } // add the defined-as string to the description if applicable String origLine2 = origLine; String otok = GetNextToken(ref origLine2); if (otok.StartsWith("Define") && (otok.EndsWith("Action") || otok.EndsWith("ActionSub"))) { origLine = origLine.Trim(); int idx = origLine.IndexOf(")"); cr.OrigDef = origLine.Substring(0, idx + 1); cr.IsAction = true; } SymbolTable.SetObjectFileName(cr); SymbolTable.Classes.Add(cr); this.CurrentSourceFile.Classes.Add(cr); CurrClassOrObj = cr; }