OLD | NEW |
1 // Copyright 2012 The Go Authors. All rights reserved. | 1 // Copyright 2012 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Common Playground functionality. | 5 // Common Playground functionality. |
6 | 6 |
7 package main | 7 package main |
8 | 8 |
9 import ( | 9 import ( |
10 "bytes" | |
11 "encoding/json" | 10 "encoding/json" |
12 "fmt" | 11 "fmt" |
13 » "go/ast" | 12 » "go/format" |
14 » "go/parser" | |
15 » "go/printer" | |
16 » "go/token" | |
17 "net/http" | 13 "net/http" |
18 ) | 14 ) |
19 | 15 |
20 // The server that will service compile and share requests. | 16 // The server that will service compile and share requests. |
21 const playgroundBaseURL = "http://play.golang.org" | 17 const playgroundBaseURL = "http://play.golang.org" |
22 | 18 |
23 func registerPlaygroundHandlers(mux *http.ServeMux) { | 19 func registerPlaygroundHandlers(mux *http.ServeMux) { |
24 if *showPlayground { | 20 if *showPlayground { |
25 mux.HandleFunc("/compile", bounceToPlayground) | 21 mux.HandleFunc("/compile", bounceToPlayground) |
26 mux.HandleFunc("/share", bounceToPlayground) | 22 mux.HandleFunc("/share", bounceToPlayground) |
27 } else { | 23 } else { |
28 mux.HandleFunc("/compile", disabledHandler) | 24 mux.HandleFunc("/compile", disabledHandler) |
29 mux.HandleFunc("/share", disabledHandler) | 25 mux.HandleFunc("/share", disabledHandler) |
30 } | 26 } |
31 http.HandleFunc("/fmt", fmtHandler) | 27 http.HandleFunc("/fmt", fmtHandler) |
32 } | 28 } |
33 | 29 |
34 type fmtResponse struct { | 30 type fmtResponse struct { |
35 Body string | 31 Body string |
36 Error string | 32 Error string |
37 } | 33 } |
38 | 34 |
39 // fmtHandler takes a Go program in its "body" form value, formats it with | 35 // fmtHandler takes a Go program in its "body" form value, formats it with |
40 // standard gofmt formatting, and writes a fmtResponse as a JSON object. | 36 // standard gofmt formatting, and writes a fmtResponse as a JSON object. |
41 func fmtHandler(w http.ResponseWriter, r *http.Request) { | 37 func fmtHandler(w http.ResponseWriter, r *http.Request) { |
42 resp := new(fmtResponse) | 38 resp := new(fmtResponse) |
43 » body, err := gofmt(r.FormValue("body")) | 39 » body, err := format.Source([]byte(r.FormValue("body"))) |
44 if err != nil { | 40 if err != nil { |
45 resp.Error = err.Error() | 41 resp.Error = err.Error() |
46 } else { | 42 } else { |
47 » » resp.Body = body | 43 » » resp.Body = string(body) |
48 } | 44 } |
49 json.NewEncoder(w).Encode(resp) | 45 json.NewEncoder(w).Encode(resp) |
50 } | 46 } |
51 | 47 |
52 // gofmt takes a Go program, formats it using the standard Go formatting | |
53 // rules, and returns it or an error. | |
54 func gofmt(body string) (string, error) { | |
55 fset := token.NewFileSet() | |
56 f, err := parser.ParseFile(fset, "prog.go", body, parser.ParseComments) | |
57 if err != nil { | |
58 return "", err | |
59 } | |
60 ast.SortImports(fset, f) | |
61 var buf bytes.Buffer | |
62 config := printer.Config{ | |
63 Mode: printer.UseSpaces | printer.TabIndent, | |
64 Tabwidth: 8, | |
65 } | |
66 err = config.Fprint(&buf, fset, f) | |
67 if err != nil { | |
68 return "", err | |
69 } | |
70 return buf.String(), nil | |
71 } | |
72 | |
73 // disabledHandler serves a 501 "Not Implemented" response. | 48 // disabledHandler serves a 501 "Not Implemented" response. |
74 func disabledHandler(w http.ResponseWriter, r *http.Request) { | 49 func disabledHandler(w http.ResponseWriter, r *http.Request) { |
75 w.WriteHeader(http.StatusNotImplemented) | 50 w.WriteHeader(http.StatusNotImplemented) |
76 fmt.Fprint(w, "This functionality is not available via local godoc.") | 51 fmt.Fprint(w, "This functionality is not available via local godoc.") |
77 } | 52 } |
OLD | NEW |