From ad162fdc626b444080fc2d9600a39bddf5b5ec11 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 8 Mar 2024 18:39:31 +0800 Subject: [PATCH 1/8] yap: classfile v2 --- classfile.go | 4 ++ classfile_v2.go | 63 +++++++++++++++++++ demo/classfile2_hello/get_p_:id.yap | 3 + demo/classfile2_hello/gop_autogen.go | 32 ++++++++++ demo/classfile2_hello/handle.yap | 1 + gop.mod | 4 ++ router.go | 94 ++++++++++++++-------------- 7 files changed, 154 insertions(+), 47 deletions(-) create mode 100644 classfile_v2.go create mode 100644 demo/classfile2_hello/get_p_:id.yap create mode 100644 demo/classfile2_hello/gop_autogen.go create mode 100644 demo/classfile2_hello/handle.yap diff --git a/classfile.go b/classfile.go index 9863dc9..0102f25 100644 --- a/classfile.go +++ b/classfile.go @@ -28,6 +28,7 @@ const ( GopPackage = true ) +// App is project class of YAP classfile (old version). type App struct { Engine } @@ -86,6 +87,9 @@ func (p *App) Static__2(pattern string, fs http.FileSystem, allowRedirect ...boo type AppType interface { InitYap(fs ...fs.FS) SetLAS(listenAndServe func(addr string, handler http.Handler) error) + Route(method, path string, handle func(ctx *Context)) + Handle(pattern string, f func(ctx *Context)) + Run(addr string, mws ...func(h http.Handler) http.Handler) error } var ( diff --git a/classfile_v2.go b/classfile_v2.go new file mode 100644 index 0000000..bd9c255 --- /dev/null +++ b/classfile_v2.go @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package yap + +import ( + "reflect" + "strings" +) + +// Handler is worker class of YAP classfile (v2). +type Handler struct { + Context +} + +func (p *Handler) Main(ctx *Context) { + p.Context = *ctx +} + +func parseHandlerName(name string) (method, path string) { + pos := strings.IndexByte(name, '_') + if pos < 0 { + return name, "/" + } + return name[:pos], strings.ReplaceAll(name[pos:], "_", "/") +} + +// AppV2 is project class of YAP classfile (v2). +type AppV2 struct { + App +} + +// Gopt_AppV2_Main is required by Go+ compiler as the entry of a YAP project. +func Gopt_AppV2_Main(app AppType, handlers ...interface{ Main(ctx *Context) }) { + app.InitYap() + for _, h := range handlers { + name := reflect.TypeOf(h).Elem().Name() // class name of handler + switch method, path := parseHandlerName(name); method { + case "handle": + app.Handle(path, h.Main) + default: + app.Route(method, path, h.Main) + } + } + if me, ok := app.(interface{ MainEntry() }); ok { + me.MainEntry() + } else { + app.Run(":8080") + } +} diff --git a/demo/classfile2_hello/get_p_:id.yap b/demo/classfile2_hello/get_p_:id.yap new file mode 100644 index 0000000..fbc76b9 --- /dev/null +++ b/demo/classfile2_hello/get_p_:id.yap @@ -0,0 +1,3 @@ +json { + "id": param("id"), +} diff --git a/demo/classfile2_hello/gop_autogen.go b/demo/classfile2_hello/gop_autogen.go new file mode 100644 index 0000000..2b8e7cf --- /dev/null +++ b/demo/classfile2_hello/gop_autogen.go @@ -0,0 +1,32 @@ +// Code generated by gop (Go+); DO NOT EDIT. + +package main + +import "github.com/goplus/yap" + +const GopPackage = "github.com/goplus/yap" +const _ = true + +type get_p_id struct { + yap.Handler +} +type handle struct { + yap.Handler +} + +func main() { + yap.Gopt_AppV2_Main(new(yap.AppV2), new(get_p_id), new(handle)) +} +//line demo/classfile2_hello/get_p_:id.yap:1 +func (this *get_p_id) Main(_gop_arg0 *yap.Context) { + this.Handler.Main(_gop_arg0) +//line demo/classfile2_hello/get_p_:id.yap:1:1 + this.Json__1(map[string]string{"id": this.Param("id")}) +} +//line demo/classfile2_hello/handle.yap:1 +func (this *handle) Main(_gop_arg0 *yap.Context) { +//line demo/classfile2_hello/get_p_:id.yap:1:1 + this.Handler.Main(_gop_arg0) +//line demo/classfile2_hello/handle.yap:1:1 + this.Html__1(`Hello, Yap!`) +} diff --git a/demo/classfile2_hello/handle.yap b/demo/classfile2_hello/handle.yap new file mode 100644 index 0000000..79f1936 --- /dev/null +++ b/demo/classfile2_hello/handle.yap @@ -0,0 +1 @@ +html `Hello, Yap!` diff --git a/gop.mod b/gop.mod index ce75052..e656abd 100644 --- a/gop.mod +++ b/gop.mod @@ -1,5 +1,9 @@ gop 1.2 +project .yap AppV2 github.com/goplus/yap + +class .yap Handler + project _yap.gox App github.com/goplus/yap project _yapt.gox App github.com/goplus/yap/ytest github.com/goplus/yap/test diff --git a/router.go b/router.go index 89605d0..5345196 100644 --- a/router.go +++ b/router.go @@ -82,46 +82,46 @@ type router struct { HandleOPTIONS bool } -func (r *router) init() { - r.RedirectTrailingSlash = true - r.RedirectFixedPath = true - r.HandleMethodNotAllowed = true - r.HandleOPTIONS = true +func (p *router) init() { + p.RedirectTrailingSlash = true + p.RedirectFixedPath = true + p.HandleMethodNotAllowed = true + p.HandleOPTIONS = true } // GET is a shortcut for router.Route(http.MethodGet, path, handle) -func (r *router) GET(path string, handle func(ctx *Context)) { - r.Route(http.MethodGet, path, handle) +func (p *router) GET(path string, handle func(ctx *Context)) { + p.Route(http.MethodGet, path, handle) } // HEAD is a shortcut for router.Route(http.MethodHead, path, handle) -func (r *router) HEAD(path string, handle func(ctx *Context)) { - r.Route(http.MethodHead, path, handle) +func (p *router) HEAD(path string, handle func(ctx *Context)) { + p.Route(http.MethodHead, path, handle) } // OPTIONS is a shortcut for router.Route(http.MethodOptions, path, handle) -func (r *router) OPTIONS(path string, handle func(ctx *Context)) { - r.Route(http.MethodOptions, path, handle) +func (p *router) OPTIONS(path string, handle func(ctx *Context)) { + p.Route(http.MethodOptions, path, handle) } // POST is a shortcut for router.Route(http.MethodPost, path, handle) -func (r *router) POST(path string, handle func(ctx *Context)) { - r.Route(http.MethodPost, path, handle) +func (p *router) POST(path string, handle func(ctx *Context)) { + p.Route(http.MethodPost, path, handle) } // PUT is a shortcut for router.Route(http.MethodPut, path, handle) -func (r *router) PUT(path string, handle func(ctx *Context)) { - r.Route(http.MethodPut, path, handle) +func (p *router) PUT(path string, handle func(ctx *Context)) { + p.Route(http.MethodPut, path, handle) } // PATCH is a shortcut for router.Route(http.MethodPatch, path, handle) -func (r *router) PATCH(path string, handle func(ctx *Context)) { - r.Route(http.MethodPatch, path, handle) +func (p *router) PATCH(path string, handle func(ctx *Context)) { + p.Route(http.MethodPatch, path, handle) } // DELETE is a shortcut for router.Route(http.MethodDelete, path, handle) -func (r *router) DELETE(path string, handle func(ctx *Context)) { - r.Route(http.MethodDelete, path, handle) +func (p *router) DELETE(path string, handle func(ctx *Context)) { + p.Route(http.MethodDelete, path, handle) } // Route registers a new request handle with the given path and method. @@ -132,7 +132,7 @@ func (r *router) DELETE(path string, handle func(ctx *Context)) { // This function is intended for bulk loading and to allow the usage of less // frequently used, non-standardized or custom methods (e.g. for internal // communication with a proxy). -func (r *router) Route(method, path string, handle func(ctx *Context)) { +func (p *router) Route(method, path string, handle func(ctx *Context)) { if method == "" { panic("method must not be empty") } @@ -143,34 +143,34 @@ func (r *router) Route(method, path string, handle func(ctx *Context)) { panic("handle must not be nil") } - if r.trees == nil { - r.trees = make(map[string]*node) + if p.trees == nil { + p.trees = make(map[string]*node) } - root := r.trees[method] + root := p.trees[method] if root == nil { root = new(node) - r.trees[method] = root + p.trees[method] = root - r.globalAllowed = r.allowed("*", "") + p.globalAllowed = p.allowed("*", "") } root.addRoute(path, handle) } -func (r *router) recv(w http.ResponseWriter, req *http.Request) { +func (p *router) recv(w http.ResponseWriter, req *http.Request) { if rcv := recover(); rcv != nil { - r.PanicHandler(w, req, rcv) + p.PanicHandler(w, req, rcv) } } -func (r *router) allowed(path, reqMethod string) (allow string) { +func (p *router) allowed(path, reqMethod string) (allow string) { allowed := make([]string, 0, 9) if path == "*" { // server-wide // empty method is used for internal calls to refresh the cache if reqMethod == "" { - for method := range r.trees { + for method := range p.trees { if method == http.MethodOptions { continue } @@ -178,16 +178,16 @@ func (r *router) allowed(path, reqMethod string) (allow string) { allowed = append(allowed, method) } } else { - return r.globalAllowed + return p.globalAllowed } } else { // specific path - for method := range r.trees { + for method := range p.trees { // Skip the requested method - we already tried this one if method == reqMethod || method == http.MethodOptions { continue } - handle, _ := r.trees[method].getValue(path, nil) + handle, _ := p.trees[method].getValue(path, nil) if handle != nil { // Route request method to list of allowed methods allowed = append(allowed, method) @@ -215,13 +215,13 @@ func (r *router) allowed(path, reqMethod string) (allow string) { return allow } -func (r *router) serveHTTP(w http.ResponseWriter, req *http.Request, e *Engine) { - if r.PanicHandler != nil { - defer r.recv(w, req) +func (p *router) serveHTTP(w http.ResponseWriter, req *http.Request, e *Engine) { + if p.PanicHandler != nil { + defer p.recv(w, req) } path := req.URL.Path - root := r.trees[req.Method] + root := p.trees[req.Method] if root != nil { ctx := e.NewContext(w, req) if handle, tsr := root.getValue(path, ctx); handle != nil { @@ -235,7 +235,7 @@ func (r *router) serveHTTP(w http.ResponseWriter, req *http.Request, e *Engine) code = http.StatusPermanentRedirect } - if tsr && r.RedirectTrailingSlash { + if tsr && p.RedirectTrailingSlash { if len(path) > 1 && path[len(path)-1] == '/' { req.URL.Path = path[:len(path)-1] } else { @@ -246,10 +246,10 @@ func (r *router) serveHTTP(w http.ResponseWriter, req *http.Request, e *Engine) } // Try to fix the request path - if r.RedirectFixedPath { + if p.RedirectFixedPath { fixedPath, found := root.findCaseInsensitivePath( url.CleanPath(path), - r.RedirectTrailingSlash, + p.RedirectTrailingSlash, ) if found { req.URL.Path = fixedPath @@ -260,20 +260,20 @@ func (r *router) serveHTTP(w http.ResponseWriter, req *http.Request, e *Engine) } } - if req.Method == http.MethodOptions && r.HandleOPTIONS { + if req.Method == http.MethodOptions && p.HandleOPTIONS { // Route OPTIONS requests - if allow := r.allowed(path, http.MethodOptions); allow != "" { + if allow := p.allowed(path, http.MethodOptions); allow != "" { w.Header().Set("Allow", allow) - if r.GlobalOPTIONS != nil { - r.GlobalOPTIONS.ServeHTTP(w, req) + if p.GlobalOPTIONS != nil { + p.GlobalOPTIONS.ServeHTTP(w, req) } return } - } else if r.HandleMethodNotAllowed { // Route 405 - if allow := r.allowed(path, req.Method); allow != "" { + } else if p.HandleMethodNotAllowed { // Route 405 + if allow := p.allowed(path, req.Method); allow != "" { w.Header().Set("Allow", allow) - if r.MethodNotAllowed != nil { - r.MethodNotAllowed.ServeHTTP(w, req) + if p.MethodNotAllowed != nil { + p.MethodNotAllowed.ServeHTTP(w, req) } else { http.Error(w, http.StatusText(http.StatusMethodNotAllowed), From c98c500c75ee7e2697f0097456955c7753b2fc82 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 8 Mar 2024 18:42:35 +0800 Subject: [PATCH 2/8] classfile_hello: use v2 --- demo/classfile_hello/gop_autogen.go | 20 +++++++++---------- .../{hello_yap.gox => main.yap} | 0 2 files changed, 10 insertions(+), 10 deletions(-) rename demo/classfile_hello/{hello_yap.gox => main.yap} (100%) diff --git a/demo/classfile_hello/gop_autogen.go b/demo/classfile_hello/gop_autogen.go index 5137d51..aa7f026 100644 --- a/demo/classfile_hello/gop_autogen.go +++ b/demo/classfile_hello/gop_autogen.go @@ -6,24 +6,24 @@ import "github.com/goplus/yap" const _ = true -type hello struct { - yap.App +type AppV2 struct { + yap.AppV2 } -//line demo/classfile_hello/hello_yap.gox:1 -func (this *hello) MainEntry() { -//line demo/classfile_hello/hello_yap.gox:1:1 +//line demo/classfile_hello/main.yap:1 +func (this *AppV2) MainEntry() { +//line demo/classfile_hello/main.yap:1:1 this.Get("/p/:id", func(ctx *yap.Context) { -//line demo/classfile_hello/hello_yap.gox:2:1 +//line demo/classfile_hello/main.yap:2:1 ctx.Json__1(map[string]string{"id": ctx.Param("id")}) }) -//line demo/classfile_hello/hello_yap.gox:6:1 +//line demo/classfile_hello/main.yap:6:1 this.Handle("/", func(ctx *yap.Context) { -//line demo/classfile_hello/hello_yap.gox:7:1 +//line demo/classfile_hello/main.yap:7:1 ctx.Html__1(`Hello, Yap!`) }) -//line demo/classfile_hello/hello_yap.gox:10:1 +//line demo/classfile_hello/main.yap:10:1 this.Run(":8080") } func main() { - yap.Gopt_App_Main(new(hello)) + yap.Gopt_AppV2_Main(new(AppV2)) } diff --git a/demo/classfile_hello/hello_yap.gox b/demo/classfile_hello/main.yap similarity index 100% rename from demo/classfile_hello/hello_yap.gox rename to demo/classfile_hello/main.yap From c6210f6646eb681ee477c74bf7a2b1c703b3cca7 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 8 Mar 2024 19:54:44 +0800 Subject: [PATCH 3/8] classfile2_blog --- classfile_v2.go | 15 ++++++++------ demo/classfile2_blog/get_p_:id.yap | 3 +++ demo/classfile2_blog/gop_autogen.go | 25 +++++++++++++++++++++++ demo/classfile2_blog/yap/article_yap.html | 8 ++++++++ demo/classfile2_hello/gop_autogen.go | 7 ++++++- 5 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 demo/classfile2_blog/get_p_:id.yap create mode 100644 demo/classfile2_blog/gop_autogen.go create mode 100644 demo/classfile2_blog/yap/article_yap.html diff --git a/classfile_v2.go b/classfile_v2.go index bd9c255..d9ebbc3 100644 --- a/classfile_v2.go +++ b/classfile_v2.go @@ -17,7 +17,6 @@ package yap import ( - "reflect" "strings" ) @@ -30,7 +29,7 @@ func (p *Handler) Main(ctx *Context) { p.Context = *ctx } -func parseHandlerName(name string) (method, path string) { +func parseClassfname(name string) (method, path string) { pos := strings.IndexByte(name, '_') if pos < 0 { return name, "/" @@ -43,16 +42,20 @@ type AppV2 struct { App } +type iHandler interface { + Main(ctx *Context) + Classfname() string +} + // Gopt_AppV2_Main is required by Go+ compiler as the entry of a YAP project. -func Gopt_AppV2_Main(app AppType, handlers ...interface{ Main(ctx *Context) }) { +func Gopt_AppV2_Main(app AppType, handlers ...iHandler) { app.InitYap() for _, h := range handlers { - name := reflect.TypeOf(h).Elem().Name() // class name of handler - switch method, path := parseHandlerName(name); method { + switch method, path := parseClassfname(h.Classfname()); method { case "handle": app.Handle(path, h.Main) default: - app.Route(method, path, h.Main) + app.Route(strings.ToUpper(method), path, h.Main) } } if me, ok := app.(interface{ MainEntry() }); ok { diff --git a/demo/classfile2_blog/get_p_:id.yap b/demo/classfile2_blog/get_p_:id.yap new file mode 100644 index 0000000..3a4aa21 --- /dev/null +++ b/demo/classfile2_blog/get_p_:id.yap @@ -0,0 +1,3 @@ +yap "article", { + "id": param("id"), +} diff --git a/demo/classfile2_blog/gop_autogen.go b/demo/classfile2_blog/gop_autogen.go new file mode 100644 index 0000000..ff8fc0d --- /dev/null +++ b/demo/classfile2_blog/gop_autogen.go @@ -0,0 +1,25 @@ +// Code generated by gop (Go+); DO NOT EDIT. + +package main + +import "github.com/goplus/yap" + +const GopPackage = "github.com/goplus/yap" +const _ = true + +type get_p_id struct { + yap.Handler +} + +func main() { + yap.Gopt_AppV2_Main(new(yap.AppV2), new(get_p_id)) +} +//line demo/classfile2_blog/get_p_:id.yap:1 +func (this *get_p_id) Main(_gop_arg0 *yap.Context) { + this.Handler.Main(_gop_arg0) +//line demo/classfile2_blog/get_p_:id.yap:1:1 + this.Yap__1("article", map[string]string{"id": this.Param("id")}) +} +func (this *get_p_id) Classfname() string { + return "get_p_:id" +} diff --git a/demo/classfile2_blog/yap/article_yap.html b/demo/classfile2_blog/yap/article_yap.html new file mode 100644 index 0000000..7985956 --- /dev/null +++ b/demo/classfile2_blog/yap/article_yap.html @@ -0,0 +1,8 @@ + + + + + +Article {{.id}} + + diff --git a/demo/classfile2_hello/gop_autogen.go b/demo/classfile2_hello/gop_autogen.go index 2b8e7cf..6ad2b5f 100644 --- a/demo/classfile2_hello/gop_autogen.go +++ b/demo/classfile2_hello/gop_autogen.go @@ -23,10 +23,15 @@ func (this *get_p_id) Main(_gop_arg0 *yap.Context) { //line demo/classfile2_hello/get_p_:id.yap:1:1 this.Json__1(map[string]string{"id": this.Param("id")}) } +func (this *get_p_id) Classfname() string { + return "get_p_:id" +} //line demo/classfile2_hello/handle.yap:1 func (this *handle) Main(_gop_arg0 *yap.Context) { -//line demo/classfile2_hello/get_p_:id.yap:1:1 this.Handler.Main(_gop_arg0) //line demo/classfile2_hello/handle.yap:1:1 this.Html__1(`Hello, Yap!`) } +func (this *handle) Classfname() string { + return "handle" +} From 66d18451503a7c44e84d6a02ba794a81af058cd6 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 8 Mar 2024 20:00:20 +0800 Subject: [PATCH 4/8] classfile2_hello: handle.yap => get.yap --- demo/classfile2_hello/{handle.yap => get.yap} | 0 demo/classfile2_hello/gop_autogen.go | 24 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) rename demo/classfile2_hello/{handle.yap => get.yap} (100%) diff --git a/demo/classfile2_hello/handle.yap b/demo/classfile2_hello/get.yap similarity index 100% rename from demo/classfile2_hello/handle.yap rename to demo/classfile2_hello/get.yap diff --git a/demo/classfile2_hello/gop_autogen.go b/demo/classfile2_hello/gop_autogen.go index 6ad2b5f..5012819 100644 --- a/demo/classfile2_hello/gop_autogen.go +++ b/demo/classfile2_hello/gop_autogen.go @@ -7,15 +7,24 @@ import "github.com/goplus/yap" const GopPackage = "github.com/goplus/yap" const _ = true -type get_p_id struct { +type get struct { yap.Handler } -type handle struct { +type get_p_id struct { yap.Handler } func main() { - yap.Gopt_AppV2_Main(new(yap.AppV2), new(get_p_id), new(handle)) + yap.Gopt_AppV2_Main(new(yap.AppV2), new(get), new(get_p_id)) +} +//line demo/classfile2_hello/get.yap:1 +func (this *get) Main(_gop_arg0 *yap.Context) { + this.Handler.Main(_gop_arg0) +//line demo/classfile2_hello/get.yap:1:1 + this.Html__1(`Hello, Yap!`) +} +func (this *get) Classfname() string { + return "get" } //line demo/classfile2_hello/get_p_:id.yap:1 func (this *get_p_id) Main(_gop_arg0 *yap.Context) { @@ -26,12 +35,3 @@ func (this *get_p_id) Main(_gop_arg0 *yap.Context) { func (this *get_p_id) Classfname() string { return "get_p_:id" } -//line demo/classfile2_hello/handle.yap:1 -func (this *handle) Main(_gop_arg0 *yap.Context) { - this.Handler.Main(_gop_arg0) -//line demo/classfile2_hello/handle.yap:1:1 - this.Html__1(`Hello, Yap!`) -} -func (this *handle) Classfname() string { - return "handle" -} From 6f7a1cc60d4d6625ef4ca419d03895dba7003c47 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 8 Mar 2024 20:06:10 +0800 Subject: [PATCH 5/8] classfile2: static --- demo/classfile2_static/gop_autogen.go | 23 ++++++++++++++++++ .../main.yap} | 0 .../yap/public/a.html | 0 .../yap/public/b.txt | 0 .../yap/static/hello.txt | 0 .../yap/static/index.html | 0 demo/classfile2_statichttp/gop_autogen.go | 24 +++++++++++++++++++ .../main.yap} | 2 +- demo/classfile_static/gop_autogen.go | 23 ------------------ demo/classfile_statichttp/gop_autogen.go | 24 ------------------- 10 files changed, 48 insertions(+), 48 deletions(-) create mode 100644 demo/classfile2_static/gop_autogen.go rename demo/{classfile_static/staticfile_yap.gox => classfile2_static/main.yap} (100%) rename demo/{classfile_static => classfile2_static}/yap/public/a.html (100%) rename demo/{classfile_static => classfile2_static}/yap/public/b.txt (100%) rename demo/{classfile_static => classfile2_static}/yap/static/hello.txt (100%) rename demo/{classfile_static => classfile2_static}/yap/static/index.html (100%) create mode 100644 demo/classfile2_statichttp/gop_autogen.go rename demo/{classfile_statichttp/statichttp_yap.gox => classfile2_statichttp/main.yap} (87%) delete mode 100644 demo/classfile_static/gop_autogen.go delete mode 100644 demo/classfile_statichttp/gop_autogen.go diff --git a/demo/classfile2_static/gop_autogen.go b/demo/classfile2_static/gop_autogen.go new file mode 100644 index 0000000..7120a97 --- /dev/null +++ b/demo/classfile2_static/gop_autogen.go @@ -0,0 +1,23 @@ +// Code generated by gop (Go+); DO NOT EDIT. + +package main + +import "github.com/goplus/yap" + +const _ = true + +type AppV2 struct { + yap.AppV2 +} +//line demo/classfile2_static/main.yap:1 +func (this *AppV2) MainEntry() { +//line demo/classfile2_static/main.yap:1:1 + this.Static__0("/foo", this.FS("public")) +//line demo/classfile2_static/main.yap:2:1 + this.Static__0("/") +//line demo/classfile2_static/main.yap:4:1 + this.Run(":8080") +} +func main() { + yap.Gopt_AppV2_Main(new(AppV2)) +} diff --git a/demo/classfile_static/staticfile_yap.gox b/demo/classfile2_static/main.yap similarity index 100% rename from demo/classfile_static/staticfile_yap.gox rename to demo/classfile2_static/main.yap diff --git a/demo/classfile_static/yap/public/a.html b/demo/classfile2_static/yap/public/a.html similarity index 100% rename from demo/classfile_static/yap/public/a.html rename to demo/classfile2_static/yap/public/a.html diff --git a/demo/classfile_static/yap/public/b.txt b/demo/classfile2_static/yap/public/b.txt similarity index 100% rename from demo/classfile_static/yap/public/b.txt rename to demo/classfile2_static/yap/public/b.txt diff --git a/demo/classfile_static/yap/static/hello.txt b/demo/classfile2_static/yap/static/hello.txt similarity index 100% rename from demo/classfile_static/yap/static/hello.txt rename to demo/classfile2_static/yap/static/hello.txt diff --git a/demo/classfile_static/yap/static/index.html b/demo/classfile2_static/yap/static/index.html similarity index 100% rename from demo/classfile_static/yap/static/index.html rename to demo/classfile2_static/yap/static/index.html diff --git a/demo/classfile2_statichttp/gop_autogen.go b/demo/classfile2_statichttp/gop_autogen.go new file mode 100644 index 0000000..3a1517c --- /dev/null +++ b/demo/classfile2_statichttp/gop_autogen.go @@ -0,0 +1,24 @@ +// Code generated by gop (Go+); DO NOT EDIT. + +package main + +import ( + "github.com/goplus/yap" + "github.com/qiniu/x/http/fs" +) + +const _ = true + +type AppV2 struct { + yap.AppV2 +} +//line demo/classfile2_statichttp/main.yap:3 +func (this *AppV2) MainEntry() { +//line demo/classfile2_statichttp/main.yap:3:1 + this.Static__2("/", fs.Http("https://goplus.org"), false) +//line demo/classfile2_statichttp/main.yap:4:1 + this.Run(":8080") +} +func main() { + yap.Gopt_AppV2_Main(new(AppV2)) +} diff --git a/demo/classfile_statichttp/statichttp_yap.gox b/demo/classfile2_statichttp/main.yap similarity index 87% rename from demo/classfile_statichttp/statichttp_yap.gox rename to demo/classfile2_statichttp/main.yap index deeb80d..df0ba1c 100644 --- a/demo/classfile_statichttp/statichttp_yap.gox +++ b/demo/classfile2_statichttp/main.yap @@ -1,4 +1,4 @@ import "github.com/qiniu/x/http/fs" static "/", fs.http("https://goplus.org"), false -run ":8888" +run ":8080" diff --git a/demo/classfile_static/gop_autogen.go b/demo/classfile_static/gop_autogen.go deleted file mode 100644 index f85061f..0000000 --- a/demo/classfile_static/gop_autogen.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by gop (Go+); DO NOT EDIT. - -package main - -import "github.com/goplus/yap" - -const _ = true - -type staticfile struct { - yap.App -} -//line demo/classfile_static/staticfile_yap.gox:1 -func (this *staticfile) MainEntry() { -//line demo/classfile_static/staticfile_yap.gox:1:1 - this.Static__0("/foo", this.FS("public")) -//line demo/classfile_static/staticfile_yap.gox:2:1 - this.Static__0("/") -//line demo/classfile_static/staticfile_yap.gox:4:1 - this.Run(":8080") -} -func main() { - yap.Gopt_App_Main(new(staticfile)) -} diff --git a/demo/classfile_statichttp/gop_autogen.go b/demo/classfile_statichttp/gop_autogen.go deleted file mode 100644 index 8525207..0000000 --- a/demo/classfile_statichttp/gop_autogen.go +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by gop (Go+); DO NOT EDIT. - -package main - -import ( - "github.com/goplus/yap" - "github.com/qiniu/x/http/fs" -) - -const _ = true - -type statichttp struct { - yap.App -} -//line demo/classfile_statichttp/statichttp_yap.gox:3 -func (this *statichttp) MainEntry() { -//line demo/classfile_statichttp/statichttp_yap.gox:3:1 - this.Static__2("/", fs.Http("https://goplus.org"), false) -//line demo/classfile_statichttp/statichttp_yap.gox:4:1 - this.Run(":8888") -} -func main() { - yap.Gopt_App_Main(new(statichttp)) -} From 695010076d1fa063789bcad6b1948bbc8e3ec01d Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 8 Mar 2024 23:05:56 +0800 Subject: [PATCH 6/8] Classfname --- demo/classfile2_blog/gop_autogen.go | 1 - demo/classfile2_hello/gop_autogen.go | 1 - ydb/demo/foo/gop_autogen.go | 9 +++++++-- ytest/demo/basic/gop_autogen_test.go | 6 +++++- ytest/demo/foo/gop_autogen_test.go | 11 +++++++++-- ytest/demo/jwtdemo/gop_autogen_test.go | 6 +++++- 6 files changed, 26 insertions(+), 8 deletions(-) diff --git a/demo/classfile2_blog/gop_autogen.go b/demo/classfile2_blog/gop_autogen.go index ff8fc0d..d853ae9 100644 --- a/demo/classfile2_blog/gop_autogen.go +++ b/demo/classfile2_blog/gop_autogen.go @@ -4,7 +4,6 @@ package main import "github.com/goplus/yap" -const GopPackage = "github.com/goplus/yap" const _ = true type get_p_id struct { diff --git a/demo/classfile2_hello/gop_autogen.go b/demo/classfile2_hello/gop_autogen.go index 5012819..709e9b2 100644 --- a/demo/classfile2_hello/gop_autogen.go +++ b/demo/classfile2_hello/gop_autogen.go @@ -4,7 +4,6 @@ package main import "github.com/goplus/yap" -const GopPackage = "github.com/goplus/yap" const _ = true type get struct { diff --git a/ydb/demo/foo/gop_autogen.go b/ydb/demo/foo/gop_autogen.go index 62149a7..211436e 100644 --- a/ydb/demo/foo/gop_autogen.go +++ b/ydb/demo/foo/gop_autogen.go @@ -224,6 +224,9 @@ func (this *articles) Main() { //line ydb/demo/foo/articles_ydb.gox:135:1 this.Ret(test.Set__2(doc2.ArticleEntry, doc3.ArticleEntry)) } +func (this *articles) Classfname() string { + return "articles" +} var ErrNoEmailAndTel = errors.New("no email and telephone") var rnd = rand.New(rand.NewSource(time.Now().UnixMicro())) @@ -251,8 +254,7 @@ func Diff(new []string, old []string) (add []string, del []string) { //line ydb/demo/foo/foo.gop:38:1 // Info calls Output to print to the standard logger. // Arguments are handled in the manner of fmt.Println. -func Info(args ...interface { -}) { +func Info(args ...interface{}) { //line ydb/demo/foo/foo.gop:41:1 log.Println(args...) } @@ -321,3 +323,6 @@ func (this *users) Main() { //line ydb/demo/foo/users_ydb.gox:58:1 this.Ret(true) } +func (this *users) Classfname() string { + return "users" +} diff --git a/ytest/demo/basic/gop_autogen_test.go b/ytest/demo/basic/gop_autogen_test.go index ad1bb20..4dfb8b0 100644 --- a/ytest/demo/basic/gop_autogen_test.go +++ b/ytest/demo/basic/gop_autogen_test.go @@ -4,6 +4,7 @@ package main import ( "github.com/goplus/yap/ytest" + "github.com/qiniu/x/stringutil" "testing" ) @@ -23,13 +24,16 @@ func (this *case_foo) Main() { //line ytest/demo/basic/foo_ytest.gox:6:1 id := "123" //line ytest/demo/basic/foo_ytest.gox:7:1 - this.Get("http://foo.com/p/" + id) + this.Get(stringutil.Concat("http://foo.com/p/", id)) //line ytest/demo/basic/foo_ytest.gox:8:1 this.RetWith(200) //line ytest/demo/basic/foo_ytest.gox:9:1 this.Json(map[string]string{"id": id}) }) } +func (this *case_foo) Classfname() string { + return "foo" +} func Test_foo(t *testing.T) { ytest.Gopt_Case_TestMain(new(case_foo), t) } diff --git a/ytest/demo/foo/gop_autogen_test.go b/ytest/demo/foo/gop_autogen_test.go index fd170c6..debbd6c 100644 --- a/ytest/demo/foo/gop_autogen_test.go +++ b/ytest/demo/foo/gop_autogen_test.go @@ -5,6 +5,7 @@ package main import ( "github.com/goplus/yap/test" "github.com/goplus/yap/ytest" + "github.com/qiniu/x/stringutil" "testing" ) @@ -23,7 +24,7 @@ func (this *case_bar) Main() { //line ytest/demo/foo/bar_ytest.gox:4:1 id := "123" //line ytest/demo/foo/bar_ytest.gox:5:1 - this.Get("http://foo.com/p/" + id) + this.Get(stringutil.Concat("http://foo.com/p/", id)) //line ytest/demo/foo/bar_ytest.gox:6:1 this.Send() //line ytest/demo/foo/bar_ytest.gox:7:1 @@ -32,6 +33,9 @@ func (this *case_bar) Main() { this.Json(map[string]string{"id": id}) }) } +func (this *case_bar) Classfname() string { + return "bar" +} //line ytest/demo/foo/foo_ytest.gox:1 func (this *case_foo) Main() { //line ytest/demo/foo/foo_ytest.gox:1:1 @@ -41,13 +45,16 @@ func (this *case_foo) Main() { //line ytest/demo/foo/foo_ytest.gox:4:1 id := "123" //line ytest/demo/foo/foo_ytest.gox:5:1 - this.Get("http://foo.com/p/" + id) + this.Get(stringutil.Concat("http://foo.com/p/", id)) //line ytest/demo/foo/foo_ytest.gox:6:1 this.RetWith(200) //line ytest/demo/foo/foo_ytest.gox:7:1 this.Json(map[string]string{"id": id}) }) } +func (this *case_foo) Classfname() string { + return "foo" +} func Test_bar(t *testing.T) { ytest.Gopt_Case_TestMain(new(case_bar), t) } diff --git a/ytest/demo/jwtdemo/gop_autogen_test.go b/ytest/demo/jwtdemo/gop_autogen_test.go index 7f47fec..f2766ca 100644 --- a/ytest/demo/jwtdemo/gop_autogen_test.go +++ b/ytest/demo/jwtdemo/gop_autogen_test.go @@ -5,6 +5,7 @@ package main import ( "github.com/goplus/yap/ytest" "github.com/goplus/yap/ytest/auth/jwt" + "github.com/qiniu/x/stringutil" "testing" "time" ) @@ -23,7 +24,7 @@ func (this *case_jwtdemo) Main() { //line ytest/demo/jwtdemo/jwtdemo_ytest.gox:12:1 id := "123" //line ytest/demo/jwtdemo/jwtdemo_ytest.gox:13:1 - this.Get("http://foo.com/p/" + id) + this.Get(stringutil.Concat("http://foo.com/p/", id)) //line ytest/demo/jwtdemo/jwtdemo_ytest.gox:14:1 this.Auth(testuser) //line ytest/demo/jwtdemo/jwtdemo_ytest.gox:15:1 @@ -32,6 +33,9 @@ func (this *case_jwtdemo) Main() { this.Json(map[string]string{"id": id}) }) } +func (this *case_jwtdemo) Classfname() string { + return "jwtdemo" +} func Test_jwtdemo(t *testing.T) { ytest.Gopt_Case_TestMain(new(case_jwtdemo), t) } From cb98731143a10287805ddc5126dd6f57a3f83a90 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 8 Mar 2024 23:16:33 +0800 Subject: [PATCH 7/8] windows: use # to replace : --- classfile_v2.go | 6 +++++- .../{get_p_:id.yap => get_p_#id.yap} | 0 demo/classfile2_blog/gop_autogen.go | 14 +++++++------- .../{get_p_:id.yap => get_p_#id.yap} | 0 demo/classfile2_hello/gop_autogen.go | 14 +++++++------- 5 files changed, 19 insertions(+), 15 deletions(-) rename demo/classfile2_blog/{get_p_:id.yap => get_p_#id.yap} (100%) rename demo/classfile2_hello/{get_p_:id.yap => get_p_#id.yap} (100%) diff --git a/classfile_v2.go b/classfile_v2.go index d9ebbc3..3409896 100644 --- a/classfile_v2.go +++ b/classfile_v2.go @@ -29,12 +29,16 @@ func (p *Handler) Main(ctx *Context) { p.Context = *ctx } +var ( + repl = strings.NewReplacer("_", "/", "#", ":") +) + func parseClassfname(name string) (method, path string) { pos := strings.IndexByte(name, '_') if pos < 0 { return name, "/" } - return name[:pos], strings.ReplaceAll(name[pos:], "_", "/") + return name[:pos], repl.Replace(name[pos:]) } // AppV2 is project class of YAP classfile (v2). diff --git a/demo/classfile2_blog/get_p_:id.yap b/demo/classfile2_blog/get_p_#id.yap similarity index 100% rename from demo/classfile2_blog/get_p_:id.yap rename to demo/classfile2_blog/get_p_#id.yap diff --git a/demo/classfile2_blog/gop_autogen.go b/demo/classfile2_blog/gop_autogen.go index d853ae9..e28c795 100644 --- a/demo/classfile2_blog/gop_autogen.go +++ b/demo/classfile2_blog/gop_autogen.go @@ -6,19 +6,19 @@ import "github.com/goplus/yap" const _ = true -type get_p_id struct { +type get_p_#id struct { yap.Handler } func main() { - yap.Gopt_AppV2_Main(new(yap.AppV2), new(get_p_id)) + yap.Gopt_AppV2_Main(new(yap.AppV2), new(get_p_#id)) } -//line demo/classfile2_blog/get_p_:id.yap:1 -func (this *get_p_id) Main(_gop_arg0 *yap.Context) { +//line demo/classfile2_blog/get_p_#id.yap:1 +func (this *get_p_#id) Main(_gop_arg0 *yap.Context) { this.Handler.Main(_gop_arg0) -//line demo/classfile2_blog/get_p_:id.yap:1:1 +//line demo/classfile2_blog/get_p_#id.yap:1:1 this.Yap__1("article", map[string]string{"id": this.Param("id")}) } -func (this *get_p_id) Classfname() string { - return "get_p_:id" +func (this *get_p_#id) Classfname() string { + return "get_p_#id" } diff --git a/demo/classfile2_hello/get_p_:id.yap b/demo/classfile2_hello/get_p_#id.yap similarity index 100% rename from demo/classfile2_hello/get_p_:id.yap rename to demo/classfile2_hello/get_p_#id.yap diff --git a/demo/classfile2_hello/gop_autogen.go b/demo/classfile2_hello/gop_autogen.go index 709e9b2..b591ecf 100644 --- a/demo/classfile2_hello/gop_autogen.go +++ b/demo/classfile2_hello/gop_autogen.go @@ -9,12 +9,12 @@ const _ = true type get struct { yap.Handler } -type get_p_id struct { +type get_p_#id struct { yap.Handler } func main() { - yap.Gopt_AppV2_Main(new(yap.AppV2), new(get), new(get_p_id)) + yap.Gopt_AppV2_Main(new(yap.AppV2), new(get), new(get_p_#id)) } //line demo/classfile2_hello/get.yap:1 func (this *get) Main(_gop_arg0 *yap.Context) { @@ -25,12 +25,12 @@ func (this *get) Main(_gop_arg0 *yap.Context) { func (this *get) Classfname() string { return "get" } -//line demo/classfile2_hello/get_p_:id.yap:1 -func (this *get_p_id) Main(_gop_arg0 *yap.Context) { +//line demo/classfile2_hello/get_p_#id.yap:1 +func (this *get_p_#id) Main(_gop_arg0 *yap.Context) { this.Handler.Main(_gop_arg0) -//line demo/classfile2_hello/get_p_:id.yap:1:1 +//line demo/classfile2_hello/get_p_#id.yap:1:1 this.Json__1(map[string]string{"id": this.Param("id")}) } -func (this *get_p_id) Classfname() string { - return "get_p_:id" +func (this *get_p_#id) Classfname() string { + return "get_p_#id" } From 847406303c2fc609c83a26851a7e9f99b6cff792 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 8 Mar 2024 23:20:03 +0800 Subject: [PATCH 8/8] autogen --- demo/classfile2_blog/gop_autogen.go | 8 ++++---- demo/classfile2_hello/gop_autogen.go | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/demo/classfile2_blog/gop_autogen.go b/demo/classfile2_blog/gop_autogen.go index e28c795..84a4161 100644 --- a/demo/classfile2_blog/gop_autogen.go +++ b/demo/classfile2_blog/gop_autogen.go @@ -6,19 +6,19 @@ import "github.com/goplus/yap" const _ = true -type get_p_#id struct { +type get_p_id struct { yap.Handler } func main() { - yap.Gopt_AppV2_Main(new(yap.AppV2), new(get_p_#id)) + yap.Gopt_AppV2_Main(new(yap.AppV2), new(get_p_id)) } //line demo/classfile2_blog/get_p_#id.yap:1 -func (this *get_p_#id) Main(_gop_arg0 *yap.Context) { +func (this *get_p_id) Main(_gop_arg0 *yap.Context) { this.Handler.Main(_gop_arg0) //line demo/classfile2_blog/get_p_#id.yap:1:1 this.Yap__1("article", map[string]string{"id": this.Param("id")}) } -func (this *get_p_#id) Classfname() string { +func (this *get_p_id) Classfname() string { return "get_p_#id" } diff --git a/demo/classfile2_hello/gop_autogen.go b/demo/classfile2_hello/gop_autogen.go index b591ecf..a05e04f 100644 --- a/demo/classfile2_hello/gop_autogen.go +++ b/demo/classfile2_hello/gop_autogen.go @@ -9,12 +9,12 @@ const _ = true type get struct { yap.Handler } -type get_p_#id struct { +type get_p_id struct { yap.Handler } func main() { - yap.Gopt_AppV2_Main(new(yap.AppV2), new(get), new(get_p_#id)) + yap.Gopt_AppV2_Main(new(yap.AppV2), new(get), new(get_p_id)) } //line demo/classfile2_hello/get.yap:1 func (this *get) Main(_gop_arg0 *yap.Context) { @@ -26,11 +26,11 @@ func (this *get) Classfname() string { return "get" } //line demo/classfile2_hello/get_p_#id.yap:1 -func (this *get_p_#id) Main(_gop_arg0 *yap.Context) { +func (this *get_p_id) Main(_gop_arg0 *yap.Context) { this.Handler.Main(_gop_arg0) //line demo/classfile2_hello/get_p_#id.yap:1:1 this.Json__1(map[string]string{"id": this.Param("id")}) } -func (this *get_p_#id) Classfname() string { +func (this *get_p_id) Classfname() string { return "get_p_#id" }