github.com/jmigpin/editor@v1.6.0/core/godebug/annotatorctx.go (about)

     1  package godebug
     2  
     3  import (
     4  	"go/ast"
     5  )
     6  
     7  type Ctx struct {
     8  	pctx  *Ctx
     9  	id    ctxId
    10  	value interface{}
    11  }
    12  
    13  func (ctx *Ctx) WithValue(id ctxId, value interface{}) *Ctx {
    14  	return &Ctx{ctx, id, value}
    15  }
    16  func (ctx *Ctx) Value(id ctxId) (interface{}, *Ctx) {
    17  	for c := ctx; c != nil; c = c.pctx {
    18  		if c.id == id {
    19  			return c.value, c
    20  		}
    21  	}
    22  	return nil, nil
    23  }
    24  func (ctx *Ctx) SetValue(value interface{}) {
    25  	ctx.value = value
    26  }
    27  
    28  //----------
    29  
    30  func (ctx *Ctx) withBoolean(id ctxId, v bool) *Ctx {
    31  	return ctx.WithValue(id, v)
    32  }
    33  func (ctx *Ctx) boolean(id ctxId) bool {
    34  	v, _ := ctx.Value(id)
    35  	if v == nil {
    36  		return false
    37  	}
    38  	return v.(bool)
    39  }
    40  
    41  //----------
    42  
    43  func (ctx *Ctx) withExpr(e *ast.Expr) *Ctx {
    44  	return ctx.WithValue(ctxIdExpr, e)
    45  }
    46  func (ctx *Ctx) replaceExpr(e ast.Expr) {
    47  	v, _ := ctx.Value(ctxIdExpr)
    48  	if v == nil {
    49  		panic("ctx: missing expr")
    50  	}
    51  	u := v.(*ast.Expr)
    52  	*u = e
    53  }
    54  
    55  //----------
    56  
    57  func (ctx *Ctx) withExprs(es *[]ast.Expr) *Ctx {
    58  	return ctx.WithValue(ctxIdExprs, es)
    59  }
    60  func (ctx *Ctx) replaceExprs(es []ast.Expr) {
    61  	v, _ := ctx.Value(ctxIdExprs)
    62  	if v == nil {
    63  		panic("ctx: missing exprs")
    64  	}
    65  	u := v.(*[]ast.Expr)
    66  	*u = es
    67  }
    68  
    69  //----------
    70  
    71  func (ctx *Ctx) withCallExpr(cep **ast.CallExpr) *Ctx {
    72  	return ctx.WithValue(ctxIdCallExpr, cep)
    73  }
    74  func (ctx *Ctx) replaceCallExpr(ce *ast.CallExpr) {
    75  	v, _ := ctx.Value(ctxIdCallExpr)
    76  	if v == nil {
    77  		panic("ctx: missing call expr")
    78  	}
    79  	u := v.(**ast.CallExpr)
    80  	*u = ce
    81  }
    82  
    83  //----------
    84  
    85  func (ctx *Ctx) withStmtsIter(si *StmtsIter) *Ctx {
    86  	return ctx.WithValue(ctxIdStmtsIter, si)
    87  }
    88  func (ctx *Ctx) stmtsIter() *StmtsIter {
    89  	v, _ := ctx.Value(ctxIdStmtsIter)
    90  	if v == nil {
    91  		panic("ctx: stmtsiter not set")
    92  	}
    93  	return v.(*StmtsIter)
    94  }
    95  
    96  //----------
    97  
    98  func (ctx *Ctx) withStmts(stmts *[]ast.Stmt) *Ctx {
    99  	si := &StmtsIter{stmts: stmts}
   100  	return ctx.withStmtsIter(si)
   101  }
   102  func (ctx *Ctx) insertStmt(stmt ast.Stmt) {
   103  	si := ctx.stmtsIter()
   104  	if ctx.insertStmtAfter() {
   105  		si.after++
   106  		k := si.index + si.after
   107  		*si.stmts = insertStmtAt(*si.stmts, k, stmt)
   108  		return
   109  	}
   110  	*si.stmts = insertStmtAt(*si.stmts, si.index, stmt)
   111  	si.index++
   112  }
   113  func (ctx *Ctx) replaceStmt(stmt ast.Stmt) {
   114  	si := ctx.stmtsIter()
   115  	(*si.stmts)[si.index] = stmt
   116  }
   117  func (ctx *Ctx) nilifyStmt(stmt *ast.Stmt) {
   118  	*stmt = nil
   119  }
   120  func (ctx *Ctx) curStmt() ast.Stmt { // can be nil
   121  	si := ctx.stmtsIter()
   122  	if si.index >= len(*si.stmts) {
   123  		return nil
   124  	}
   125  	return (*si.stmts)[si.index]
   126  }
   127  func (ctx *Ctx) nextStmt() ast.Stmt { // can be nil
   128  	si := ctx.stmtsIter()
   129  
   130  	// advance
   131  	si.index += si.after + 1
   132  	si.after = 0
   133  
   134  	return ctx.curStmt()
   135  }
   136  
   137  //----------
   138  
   139  func (ctx *Ctx) withInsertStmtAfter(v bool) *Ctx {
   140  	return ctx.withBoolean(ctxIdStmtsIterInsertAfter, v)
   141  }
   142  func (ctx *Ctx) insertStmtAfter() bool {
   143  	return ctx.boolean(ctxIdStmtsIterInsertAfter)
   144  }
   145  
   146  //----------
   147  
   148  func (ctx *Ctx) withNResults(n int) *Ctx {
   149  	return ctx.WithValue(ctxIdNResults, n)
   150  }
   151  func (ctx *Ctx) nResults() int {
   152  	v, _ := ctx.Value(ctxIdNResults)
   153  	if v == nil {
   154  		return 0
   155  	}
   156  	u := v.(int)
   157  	return u
   158  }
   159  
   160  //----------
   161  
   162  func (ctx *Ctx) withDebugIndex(v int) *Ctx {
   163  	return ctx.WithValue(ctxIdDebugIndex, &v)
   164  }
   165  func (ctx *Ctx) debugIndex() *int {
   166  	v, _ := ctx.Value(ctxIdDebugIndex)
   167  	if v == nil {
   168  		panic("ctx: debugindex not set")
   169  	}
   170  	return v.(*int)
   171  }
   172  func (ctx *Ctx) nextDebugIndex() int {
   173  	u := ctx.debugIndex()
   174  	r := *u
   175  
   176  	fdi, ok := ctx.fixedDebugIndex()
   177  	if ok {
   178  		if fdi.added {
   179  			return fdi.index
   180  		}
   181  		fdi.added = true
   182  		fdi.index = r
   183  	}
   184  
   185  	*u++
   186  	return r
   187  }
   188  
   189  //----------
   190  
   191  func (ctx *Ctx) withFixedDebugIndex() *Ctx {
   192  	if _, ok := ctx.fixedDebugIndex(); ok {
   193  		return ctx
   194  	}
   195  	v := &FixedDebugIndex{}
   196  	return ctx.WithValue(ctxIdFixedDebugIndex, v)
   197  }
   198  func (ctx *Ctx) fixedDebugIndex() (*FixedDebugIndex, bool) {
   199  	v, _ := ctx.Value(ctxIdFixedDebugIndex)
   200  	if v == nil {
   201  		return nil, false
   202  	}
   203  	return v.(*FixedDebugIndex), true
   204  }
   205  func (ctx *Ctx) withNilFixedDebugIndex() *Ctx {
   206  	return ctx.WithValue(ctxIdFixedDebugIndex, nil)
   207  }
   208  
   209  //----------
   210  
   211  func (ctx *Ctx) withFuncType(ft *ast.FuncType) *Ctx {
   212  	return ctx.WithValue(ctxIdFuncType, ft)
   213  }
   214  func (ctx *Ctx) funcType() (*ast.FuncType, bool) {
   215  	v, _ := ctx.Value(ctxIdFuncType)
   216  	if v == nil {
   217  		return nil, false
   218  	}
   219  	u := v.(*ast.FuncType)
   220  	return u, true
   221  }
   222  
   223  //----------
   224  
   225  func (ctx *Ctx) withTakingVarAddress(e ast.Expr) *Ctx {
   226  	return ctx.WithValue(ctxIdTakingVarAddress, e)
   227  }
   228  func (ctx *Ctx) takingVarAddress() (ast.Expr, bool) {
   229  	v, _ := ctx.Value(ctxIdTakingVarAddress)
   230  	if v == nil {
   231  		return nil, false
   232  	}
   233  	return v.(ast.Expr), true
   234  }
   235  
   236  //----------
   237  
   238  func (ctx *Ctx) withTypeInsteadOfValue(e *ast.Expr) *Ctx {
   239  	return ctx.WithValue(ctxIdTypeInsteadOfValue, e)
   240  }
   241  func (ctx *Ctx) typeInsteadOfValue() (*ast.Expr, bool) {
   242  	v, _ := ctx.Value(ctxIdTypeInsteadOfValue)
   243  	if v == nil {
   244  		return nil, false
   245  	}
   246  	return v.(*ast.Expr), true
   247  }
   248  
   249  //----------
   250  
   251  func (ctx *Ctx) withLabeledStmt(ls *ast.LabeledStmt) *Ctx {
   252  	return ctx.WithValue(ctxIdLabeledStmt, ls)
   253  }
   254  func (ctx *Ctx) labeledStmt() (*ast.LabeledStmt, bool) {
   255  	v, _ := ctx.Value(ctxIdLabeledStmt)
   256  	if v == nil {
   257  		return nil, false
   258  	}
   259  	return v.(*ast.LabeledStmt), true
   260  }
   261  
   262  //----------
   263  
   264  func (ctx *Ctx) withResetForFuncLit() *Ctx {
   265  	ctx2 := &Ctx{} // new ctx (full reset)
   266  
   267  	v, _ := ctx.Value(ctxIdDebugIndex)
   268  	ctx2 = ctx2.WithValue(ctxIdDebugIndex, v)
   269  
   270  	v2 := ctx.boolean(ctxIdNoAnnotations)
   271  	if v2 {
   272  		ctx2 = ctx2.withBoolean(ctxIdNoAnnotations, v2)
   273  	}
   274  
   275  	return ctx2
   276  }
   277  
   278  //----------
   279  //----------
   280  //----------
   281  
   282  type ctxId int
   283  
   284  const (
   285  	ctxIdNone ctxId = iota
   286  	ctxIdFuncType
   287  	ctxIdTakingVarAddress
   288  	ctxIdTypeInsteadOfValue
   289  	ctxIdLabeledStmt
   290  	ctxIdNResults // int
   291  	ctxIdStmtsIter
   292  	ctxIdStmtsIterInsertAfter // bool
   293  	ctxIdExpr
   294  	ctxIdExprs
   295  	ctxIdCallExpr        // pointer
   296  	ctxIdDebugIndex      // int
   297  	ctxIdFixedDebugIndex // struct
   298  
   299  	ctxIdExprInLhs          // bool
   300  	ctxIdNoAnnotations      // bool
   301  	ctxIdNameInsteadOfValue // bool
   302  	ctxIdFirstArgIsType     // bool
   303  	ctxIdInTypeArg          // bool
   304  	ctxIdInDeclStmt         // bool
   305  )
   306  
   307  //----------
   308  
   309  type StmtsIter struct {
   310  	stmts *[]ast.Stmt
   311  	index int // current
   312  	after int // n inserted after
   313  }
   314  
   315  //----------
   316  
   317  type DebugIndex struct {
   318  	index int
   319  }
   320  type FixedDebugIndex struct {
   321  	index int
   322  	added bool
   323  }
   324  
   325  //----------
   326  
   327  func insertStmtAt(ss []ast.Stmt, index int, stmt ast.Stmt) []ast.Stmt {
   328  	if len(ss) <= index { // nil or empty slice or after last element
   329  		return append(ss, stmt)
   330  	}
   331  	ss = append(ss[:index+1], ss[index:]...) // get space, index < len(a)
   332  	ss[index] = stmt
   333  	return ss
   334  }