Commit 77a8448d authored by Hugo Moreau's avatar Hugo Moreau

global: detecting global var before transform

Global var can be placed in all the file and not necessarily before its
actual using. So it is now detected before applying the transform.

 * main.go,
   transform/global.go,
   transform/preglobal.go : Here.
parent 48c998ec
Pipeline #26353 failed with stage
in 4 minutes and 34 seconds
......@@ -426,7 +426,15 @@ func treatGlobal(src []byte) ([]byte, bool) {
fset := token.NewFileSet()
node, err := parser.ParseFile(fset, "", src, 0)
meta := transform.NewMeta(fset, info)
setter, getter := &transform.Global{Setter: true}, &transform.Global{Setter: false}
preglobal := &transform.PreGlobal{}
transform.Apply(node, meta, preglobal)
if len(preglobal.GlobalVar) == 0 {
return src, false
}
setter, getter := &transform.Global{Setter: true, GlobalVar: preglobal.GlobalVar},
&transform.Global{Setter: false, GlobalVar: preglobal.GlobalVar}
res := transform.ApplyAll(node, meta, []transform.Transform{setter, getter})
res = transform.Apply(res, meta, &transform.PostGlobal{
FirstFunc: setter.FirstFunc,
......@@ -450,7 +458,7 @@ func treatGlobal(src []byte) ([]byte, bool) {
fmt.Println(err)
os.Exit(1)
}
return src, len(getter.Funcs) > 0 || len(setter.Funcs) > 0
return src, true
}
type packageTemplate struct {
......
......@@ -10,6 +10,7 @@ import (
The Global transform will detect all global variables modification in
function's scope and will summon a Getter or Setter depending on the
context.
All global variables are detected with the PreGlobal transform.
This transform is called twice depending on it's the Setter or Getter
modification.
Transform:
......@@ -38,7 +39,7 @@ type Global struct {
FuncCallToAdd map[string][]*ast.Ident
Funcs []*ast.FuncDecl
funcsVar map[string][]string
globalVar []string
GlobalVar []string
Setter bool
}
......@@ -71,10 +72,8 @@ func (t *Global) handleFuncDecl(node *ast.FuncDecl) {
// When transform encounter an *ast.ValueSpec, handleValueSpec will
// register global variables or local variables in their appropriate map
func (t *Global) handleValueSpec(node *ast.ValueSpec) {
for i := 0; i < len(node.Names); i++ {
if t.currentFunction == nil {
t.globalVar = append(t.globalVar, node.Names[i].Name)
} else {
if t.currentFunction != nil {
for i := 0; i < len(node.Names); i++ {
t.funcsVar[t.currentFunction.Name] = append(
t.funcsVar[t.currentFunction.Name],
node.Names[i].Name)
......@@ -89,7 +88,7 @@ func (t *Global) reguralizeAssign(node *ast.AssignStmt) {
if tok := TokenAssignLess(node.Tok); tok != token.ASSIGN {
switch lhs := node.Lhs[0].(type) {
case *ast.Ident:
if find(t.globalVar, lhs.Name) && !find(t.funcsVar[t.currentFunction.Name], lhs.Name) {
if find(t.GlobalVar, lhs.Name) && !find(t.funcsVar[t.currentFunction.Name], lhs.Name) {
node.Tok = token.ASSIGN
node.Rhs[0] = &ast.BinaryExpr{
X: lhs,
......@@ -241,7 +240,7 @@ func (t *Global) Pre(meta *Meta, v *Visitor) bool {
for i := 0; i < len(node.Lhs); i++ {
switch lhs := node.Lhs[i].(type) {
case *ast.Ident:
if find(t.globalVar, lhs.Name) && !find(t.funcsVar[t.currentFunction.Name], lhs.Name) {
if find(t.GlobalVar, lhs.Name) && !find(t.funcsVar[t.currentFunction.Name], lhs.Name) {
var ident *ast.Ident
ident, i = t.createIdent(c, lhs, i, node)
if findIdent(t.funcArgToAdd[t.currentFunction.Name], ident.Name) {
......@@ -257,7 +256,7 @@ func (t *Global) Pre(meta *Meta, v *Visitor) bool {
if t.currentFunction == nil || t.currentFunction.Name == "main" {
return true
}
if !t.Setter && find(t.globalVar, node.Name) && !find(t.funcsVar[t.currentFunction.Name], node.Name) {
if !t.Setter && find(t.GlobalVar, node.Name) && !find(t.funcsVar[t.currentFunction.Name], node.Name) {
ident, _ := t.createIdent(c, node, -1, nil)
if findIdent(t.funcArgToAdd[t.currentFunction.Name], ident.Name) {
return true
......
package transform
import (
"go/ast"
)
/*
The PreGlobal will detect all global variables and store them in GlobalVar.
*/
type PreGlobal struct {
currentFunction *ast.Object
GlobalVar []string
}
// Pre traversal applies the transformation
func (t *PreGlobal) Pre(meta *Meta, v *Visitor) bool {
c := v.Cursor()
switch node := c.Node().(type) {
case *ast.FuncDecl:
t.currentFunction = node.Name.Obj
case *ast.GenDecl:
switch c.Parent().(type) {
case *ast.File:
t.currentFunction = nil
}
case *ast.ValueSpec:
if t.currentFunction == nil {
for i := 0; i < len(node.Names); i++ {
t.GlobalVar = append(t.GlobalVar, node.Names[i].Name)
}
}
}
return true
}
// Post traversal applies the transformation
func (t *PreGlobal) Post(meta *Meta, v *Visitor) bool {
return true
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment