diff --git a/doc/style.css b/doc/style.css index 6a99b810c9238b8f9ba6bcda6f52042a4dd376e5..fb9018507098d77ba1407695ebf54a79b8d001ef 100644 --- a/doc/style.css +++ b/doc/style.css @@ -194,6 +194,7 @@ span.comment { } span.highlight { + font-weight: bold; background-color: #ffffa0; } diff --git a/lib/godoc/parseerror.txt b/lib/godoc/parseerror.txt deleted file mode 100644 index 609cb511b5da7ccafcb9b1ffab25b74bf6e7a400..0000000000000000000000000000000000000000 --- a/lib/godoc/parseerror.txt +++ /dev/null @@ -1,6 +0,0 @@ -parse errors: -{.repeated section list} -{.section msg} -{filename}:{line}: {msg} -{.end} -{.end} diff --git a/lib/godoc/parseerror.html b/lib/godoc/source.html similarity index 56% rename from lib/godoc/parseerror.html rename to lib/godoc/source.html index 4fa97a5e1fa27565482268ad7fe182ba279c4cdb..4189f4ef8050012e83d398a5394e45550f9ba7d3 100644 --- a/lib/godoc/parseerror.html +++ b/lib/godoc/source.html @@ -4,7 +4,10 @@ license that can be found in the LICENSE file. --> -<pre> -{.repeated section list} -{src|html}{.section msg}<b><span class="alert">芦{msg|html}禄</span></b>{.end}{.end} -</pre> +{.section Error} + <p> + <span class="alert" style="font-size:120%">{@|html}</span> + </p> +{.or} + <pre>{Source|html}</pre> +{.end} diff --git a/src/cmd/godoc/godoc.go b/src/cmd/godoc/godoc.go index dd5278f8e746361eacbc5049096921a6db768a06..5f86100cbb2ddab04c8178c178745619e66f6d3d 100644 --- a/src/cmd/godoc/godoc.go +++ b/src/cmd/godoc/godoc.go @@ -12,7 +12,6 @@ import ( "go/doc"; "go/parser"; "go/printer"; - "go/scanner"; "go/token"; "http"; "io"; @@ -122,7 +121,7 @@ func isPkgDir(dir *os.Dir) bool { func pkgName(filename string) string { - file, err := parse(filename, parser.PackageClauseOnly); + file, err := parser.ParseFile(filename, nil, parser.PackageClauseOnly); if err != nil || file == nil { return "" } @@ -397,74 +396,6 @@ func listing(dirs []*os.Dir) *DirList { } -// ---------------------------------------------------------------------------- -// Parsing - -// A single error in the parsed file. -type parseError struct { - src []byte; // source before error - line int; // line number of error - msg string; // error message -} - - -// All the errors in the parsed file, plus surrounding source code. -// Each error has a slice giving the source text preceding it -// (starting where the last error occurred). The final element in list[] -// has msg = "", to give the remainder of the source code. -// This data structure is handed to the templates parseerror.txt and parseerror.html. -// -type parseErrors struct { - filename string; // path to file - list []parseError; // the errors - src []byte; // the file's entire source code -} - - -// Parses a file (path) and returns the corresponding AST and -// a sorted list (by file position) of errors, if any. -// -func parse(path string, mode uint) (*ast.File, *parseErrors) { - src, err := io.ReadFile(path); - if err != nil { - log.Stderrf("%v", err); - errs := []parseError{parseError{nil, 0, err.String()}}; - return nil, &parseErrors{path, errs, nil}; - } - - prog, err := parser.ParseFile(path, src, mode); - if err != nil { - var errs []parseError; - if errors, ok := err.(scanner.ErrorList); ok { - // convert error list (already sorted) - // TODO(gri) If the file contains //line comments, the errors - // may not be sorted in increasing file offset value - // which will lead to incorrect output. - errs = make([]parseError, len(errors)+1); // +1 for final fragment of source - offs := 0; - for i, r := range errors { - // Should always be true, but check for robustness. - if 0 <= r.Pos.Offset && r.Pos.Offset <= len(src) { - errs[i].src = src[offs:r.Pos.Offset]; - offs = r.Pos.Offset; - } - errs[i].line = r.Pos.Line; - errs[i].msg = r.Msg; - } - errs[len(errors)].src = src[offs:]; - } else { - // single error of unspecified type - errs = make([]parseError, 2); - errs[0] = parseError{[]byte{}, 0, err.String()}; - errs[1].src = src; - } - return nil, &parseErrors{path, errs, src}; - } - - return prog, nil; -} - - // ---------------------------------------------------------------------------- // HTML formatting support @@ -544,6 +475,12 @@ func writeText(w io.Writer, text []byte, html bool) { } +type StyledNode struct { + node interface{}; + styler printer.Styler; +} + + // Write anything to w; optionally html-escaped. func writeAny(w io.Writer, x interface{}, html bool) { switch v := x.(type) { @@ -551,10 +488,10 @@ func writeAny(w io.Writer, x interface{}, html bool) { writeText(w, v, html) case string: writeText(w, strings.Bytes(v), html) - case ast.Decl: - writeNode(w, v, html, &defaultStyler) - case ast.Expr: - writeNode(w, v, html, &defaultStyler) + case ast.Decl, ast.Expr, ast.Stmt, *ast.File: + writeNode(w, x, html, &defaultStyler) + case StyledNode: + writeNode(w, v.node, html, v.styler) default: if html { var buf bytes.Buffer; @@ -713,9 +650,8 @@ var ( godocHTML, packageHTML, packageText, - parseerrorHTML, - parseerrorText, - searchHTML *template.Template; + searchHTML, + sourceHTML *template.Template; ) func readTemplates() { @@ -725,9 +661,8 @@ func readTemplates() { godocHTML = readTemplate("godoc.html"); packageHTML = readTemplate("package.html"); packageText = readTemplate("package.txt"); - parseerrorHTML = readTemplate("parseerror.html"); - parseerrorText = readTemplate("parseerror.txt"); searchHTML = readTemplate("search.html"); + sourceHTML = readTemplate("source.html"); } @@ -802,29 +737,24 @@ func serveHTMLDoc(c *http.Conn, r *http.Request, path string) { } -func serveParseErrors(c *http.Conn, errors *parseErrors) { - // format errors - var buf bytes.Buffer; - if err := parseerrorHTML.Execute(errors, &buf); err != nil { - log.Stderrf("parseerrorHTML.Execute: %s", err) +func serveGoSource(c *http.Conn, r *http.Request, path string) { + var info struct { + Source StyledNode; + Error string; } - servePage(c, "Parse errors in source file "+errors.filename, "", buf.Bytes()); -} - -func serveGoSource(c *http.Conn, r *http.Request, path string, styler printer.Styler) { - prog, errors := parse(path, parser.ParseComments); - if errors != nil { - serveParseErrors(c, errors); - return; + file, err := parser.ParseFile(path, nil, parser.ParseComments); + info.Source = StyledNode{file, &Styler{linetags: true, highlight: r.FormValue("h")}}; + if err != nil { + info.Error = err.String() } var buf bytes.Buffer; - fmt.Fprintln(&buf, "<pre>"); - writeNode(&buf, prog, true, styler); - fmt.Fprintln(&buf, "</pre>"); + if err := sourceHTML.Execute(info, &buf); err != nil { + log.Stderrf("sourceHTML.Execute: %s", err) + } - servePage(c, "Source file "+r.URL.Path, "", buf.Bytes()); + servePage(c, "Source file "+path, "", buf.Bytes()); } @@ -940,7 +870,7 @@ func serveFile(c *http.Conn, r *http.Request) { return; case ext == ".go": - serveGoSource(c, r, path, &Styler{linetags: true, highlight: r.FormValue("h")}); + serveGoSource(c, r, path); return; } diff --git a/src/cmd/godoc/main.go b/src/cmd/godoc/main.go index f303b987f879e78a3a399ae9f694e951d4888f52..51be3e98598078539ca90f8198f61f14849e02b9 100644 --- a/src/cmd/godoc/main.go +++ b/src/cmd/godoc/main.go @@ -217,8 +217,7 @@ func main() { // Command line mode. if *html { - packageText = packageHTML; - parseerrorText = parseerrorHTML; + packageText = packageHTML } info := pkgHandler.getPageInfo(flag.Arg(0));