Skip to content

Commit

Permalink
feat: add migrate gin to hertz
Browse files Browse the repository at this point in the history
  • Loading branch information
Skyenought committed Mar 2, 2024
1 parent b9b0a6d commit 711dcd4
Show file tree
Hide file tree
Showing 40 changed files with 2,151 additions and 929 deletions.
362 changes: 237 additions & 125 deletions cmd/hertz_migrate/internal/cli/cli.go

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package netHttp
package internal

import (
. "go/ast"
import "errors"

"golang.org/x/tools/go/ast/astutil"
var (
ErrCollectGoFiles = errors.New("collect go files error")
ErrSearchGoMod = errors.New("search go.mod dir fail")
ErrParseFile = errors.New("parse go file fail")
ErrSaveChanges = errors.New("change go file fail")
ErrGetAbsPath = errors.New("get absolute path fail")
ErrRunCommand = errors.New("run command fail")
ErrChangeDir = errors.New("change directory fail")
)

func ReplaceRespNotFound(cur *astutil.Cursor) {
callExpr, ok := cur.Node().(*CallExpr)
if !ok {
return
}

selExpr, ok := callExpr.Fun.(*SelectorExpr)
if !ok {
return
}

ident, ok := selExpr.X.(*Ident)
if !ok || ident.Name != "http" || selExpr.Sel.Name != "NotFound" {
return
}

callExpr.Fun = &SelectorExpr{
X: NewIdent("c"),
Sel: NewIdent("NotFound"),
}
callExpr.Args = []Expr{}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,22 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package netHttp
package internal

import (
. "go/ast"
"go/ast"

"golang.org/x/tools/go/ast/astutil"
mapset "github.com/deckarep/golang-set/v2"
)

func ReplaceReqURLString(cur *astutil.Cursor) {
selExpr, ok := cur.Node().(*SelectorExpr)
if !ok || selExpr.Sel == nil || selExpr.Sel.Name != "String" {
return
}
ce, ok := selExpr.X.(*SelectorExpr)
if !ok || ce.Sel.Name != "URL" {
return
}
selExpr.X = &CallExpr{
Fun: &SelectorExpr{
X: NewIdent("c"),
Sel: NewIdent("URI"),
},
}
var (
CtxSet mapset.Set[string]
WebCtxSet mapset.Set[string]
Options []ast.Expr
ServerName string
)

func init() {
CtxSet = mapset.NewSet[string]()
WebCtxSet = mapset.NewSet[string]()
}
25 changes: 6 additions & 19 deletions cmd/hertz_migrate/internal/logic/chi/packChiMux.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,14 @@ package chi
import (
. "go/ast"

"github.com/hertz-contrib/migrate/cmd/hertz_migrate/internal/types"
"github.com/hertz-contrib/migrate/cmd/hertz_migrate/internal/utils"

"golang.org/x/tools/go/ast/astutil"
)

func PackChiMux(cur *astutil.Cursor) {
funcType, ok := cur.Node().(*FuncType)
if !ok || funcType.Results == nil {
return
}

if len(funcType.Results.List) == 1 {
starExpr, ok := funcType.Results.List[0].Type.(*StarExpr)
if !ok {
return
}
selExpr, ok := starExpr.X.(*SelectorExpr)
if !ok {
return
}
if selExpr.Sel.Name == "Mux" && selExpr.X.(*Ident).Name == "chi" {
selExpr.X.(*Ident).Name = "hzserver"
selExpr.Sel.Name = "Hertz"
}
func PackChiMux(c *astutil.Cursor, node *StarExpr) {
if utils.CheckPtrPkgAndStructName(node, "chi", "Mux") {
c.Replace(types.StarServerHertz)
}
}
16 changes: 12 additions & 4 deletions cmd/hertz_migrate/internal/logic/chi/packChiRouterMethod.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,27 @@ import (
"go/token"

"github.com/hertz-contrib/migrate/cmd/hertz_migrate/internal/utils"
"golang.org/x/tools/go/ast/astutil"
)

func PackChiRouterMethod(cur *astutil.Cursor) {
callExpr, ok := cur.Node().(*CallExpr)
if !ok || len(callExpr.Args) < 2 {
func PackChiRouterMethod(callExpr *CallExpr) {
if len(callExpr.Args) < 2 {
return
}
selExpr, ok := callExpr.Fun.(*SelectorExpr)
if !ok || selExpr.Sel == nil {
return
}

if ident, ok := selExpr.X.(*Ident); ok {
if !utils.CheckObjStarExpr(ident.Obj, "chi", "Mux") {
return
}
}

if _, ok := selExpr.X.(*SelectorExpr); ok {
return
}

if len(callExpr.Args) == 2 {
switch selExpr.Sel.Name {
case "Get":
Expand Down
136 changes: 136 additions & 0 deletions cmd/hertz_migrate/internal/logic/gin/findCtxInFieldList.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// Copyright 2024 CloudWeGo Authors
//
// 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 gin

import (
. "go/ast"

"github.com/hertz-contrib/migrate/cmd/hertz_migrate/internal"
"github.com/hertz-contrib/migrate/cmd/hertz_migrate/internal/utils"

"golang.org/x/tools/go/ast/astutil"
)

func GetFuncNameHasGinCtx(c *astutil.Cursor) {
findInnerFuncName(c)
findFuncName(c)
findTypePropName(c)
findExprStmtFuncName(c)
}

func findTypePropName(cur *astutil.Cursor) {
var paramList []*Field
if field, ok := cur.Node().(*Field); ok {
if funcType, ok := field.Type.(*FuncType); ok {
paramList = funcType.Params.List
for _, _field := range paramList {
switch t := _field.Type.(type) {
case *StarExpr:
if selExpr, ok := t.X.(*SelectorExpr); ok {
if selExpr.Sel.Name == "Context" {
internal.WebCtxSet.Add(field.Names[0].Name)
}
}
case *SelectorExpr:
if utils.CheckSelPkgAndStruct(t, "context", "Context") {
internal.CtxSet.Add(field.Names[0].Name)
}
}
}
}
}
}

func findExprStmtFuncName(cur *astutil.Cursor) {
if exprStmt, ok := cur.Node().(*ExprStmt); ok {
if callExpr, ok := exprStmt.X.(*CallExpr); ok {
if ident, ok := callExpr.Fun.(*Ident); ok {
funcName := ident.Name
for _, arg := range callExpr.Args {
switch node := arg.(type) {
case *Ident:
if utils.CheckObjStarExpr(node.Obj, "gin", "Context") {
internal.WebCtxSet.Add(funcName)
}
case *SelectorExpr:
if utils.CheckSelPkgAndStruct(node, "gin", "Context") {
internal.CtxSet.Add(funcName)
}
}
}
}
}
}
}

func findInnerFuncName(cur *astutil.Cursor) {
var (
funcName string
paramList []*Field
)
if blockStmt, ok := cur.Node().(*BlockStmt); ok {
for _, stmt := range blockStmt.List {
if as, ok := stmt.(*AssignStmt); ok {
if len(as.Lhs) == 1 {
if ident, ok := as.Lhs[0].(*Ident); ok {
funcName = ident.Name
}
}
if len(as.Rhs) == 1 {
if funcLit, ok := as.Rhs[0].(*FuncLit); ok {
paramList = funcLit.Type.Params.List
for _, field := range paramList {
switch t := field.Type.(type) {
case *StarExpr:
if selExpr, ok := t.X.(*SelectorExpr); ok {
if utils.CheckSelPkgAndStruct(selExpr, "gin", "Context") {
internal.WebCtxSet.Add(funcName)
}
}
case *SelectorExpr:
if utils.CheckSelPkgAndStruct(t, "context", "Context") {
internal.CtxSet.Add(funcName)
}
}
}
}
}
}
}
}
}

func findFuncName(cur *astutil.Cursor) {
var paramList []*Field
if funcDecl, ok := cur.Node().(*FuncDecl); ok {
funcType := funcDecl.Type
paramList = funcType.Params.List

for _, field := range paramList {
switch t := field.Type.(type) {
case *StarExpr:
if selExpr, ok := t.X.(*SelectorExpr); ok {
if selExpr.Sel.Name == "Context" {
internal.WebCtxSet.Add(funcDecl.Name.Name)
}
}
case *SelectorExpr:
if utils.CheckSelPkgAndStruct(t, "context", "Context") {
internal.CtxSet.Add(funcDecl.Name.Name)
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,25 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package netHttp
package gin

import (
. "go/ast"

"github.com/hertz-contrib/migrate/cmd/hertz_migrate/internal/types"
"github.com/hertz-contrib/migrate/cmd/hertz_migrate/internal/utils"
"go/ast"

"golang.org/x/tools/go/ast/astutil"
)

func ReplaceRespHeader(cur *astutil.Cursor) {
callExpr, ok := cur.Node().(*CallExpr)
if !ok {
return
}

selExpr, ok := callExpr.Fun.(*SelectorExpr)
if !ok || selExpr.Sel == nil {
return
}

if selExpr.Sel.Name == "Header" {
if utils.CheckStructName(selExpr, "ResponseWriter") {
callExpr := &SelectorExpr{
X: &SelectorExpr{
X: NewIdent("c"),
Sel: NewIdent("Response"),
},
Sel: NewIdent("Header"),
func ReplaceBinding(se *ast.SelectorExpr, cur *astutil.Cursor) {
if ident, ok := se.X.(*ast.Ident); ok {
if utils.CheckObjStarExpr(ident.Obj, "hzapp", "RequestContext") {
switch se.Sel.Name {
case "Bind":
cur.Replace(types.ExportCtxOp(ident.Name, "Bind"))
case "ShouldBind", "ShouldBindJSON", "ShouldBindQuery", "ShouldBindHeader":
cur.Replace(types.ExportCtxOp(ident.Name, "BindAndValidate"))
}
// Replace the right-hand side of the assignment statement
cur.Replace(callExpr)
}
}
}
Loading

0 comments on commit 711dcd4

Please sign in to comment.