Skip to content

Commit 08fb252

Browse files
authored
Merge pull request #294 from xushiwei/q
cb.startBlockStmt: set start/end
2 parents 3d1b2e0 + 27b5995 commit 08fb252

File tree

4 files changed

+54
-45
lines changed

4 files changed

+54
-45
lines changed

codebuild.go

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,10 @@ func (p *CodeBuilder) Pkg() *Package {
237237
return p.pkg
238238
}
239239

240-
func (p *CodeBuilder) startFuncBody(fn *Func, old *funcBodyCtx) *CodeBuilder {
240+
func (p *CodeBuilder) startFuncBody(fn *Func, src []ast.Node, old *funcBodyCtx) *CodeBuilder {
241241
p.current.fn, old.fn = fn, p.current.fn
242242
p.current.labels, old.labels = nil, p.current.labels
243-
p.startBlockStmt(fn, "func "+fn.Name(), &old.codeBlockCtx)
243+
p.startBlockStmt(fn, src, "func "+fn.Name(), &old.codeBlockCtx)
244244
scope := p.current.scope
245245
sig := fn.Type().(*types.Signature)
246246
insertParams(scope, sig.Params())
@@ -268,8 +268,12 @@ func (p *CodeBuilder) endFuncBody(old funcBodyCtx) []ast.Stmt {
268268
return stmts
269269
}
270270

271-
func (p *CodeBuilder) startBlockStmt(current codeBlock, comment string, old *codeBlockCtx) *CodeBuilder {
272-
scope := types.NewScope(p.current.scope, token.NoPos, token.NoPos, comment)
271+
func (p *CodeBuilder) startBlockStmt(current codeBlock, src []ast.Node, comment string, old *codeBlockCtx) *CodeBuilder {
272+
var start, end token.Pos
273+
if src != nil {
274+
start, end = src[0].Pos(), src[0].End()
275+
}
276+
scope := types.NewScope(p.current.scope, start, end, comment)
273277
p.current.codeBlockCtx, *old = codeBlockCtx{current, scope, p.stk.Len(), nil, nil, 0}, p.current.codeBlockCtx
274278
return p
275279
}
@@ -537,7 +541,7 @@ func (p *CodeBuilder) CallInlineClosureStart(sig *types.Signature, arity int, el
537541
for i, n := 0, results.Len(); i < n; i++ {
538542
p.emitVar(pkg, closure, results.At(i), false)
539543
}
540-
p.startFuncBody(closure, &closure.old)
544+
p.startFuncBody(closure, nil, &closure.old)
541545
args := p.stk.GetArgs(arity)
542546
var flags InstrFlags
543547
if ellipsis {
@@ -2182,12 +2186,12 @@ func (p *CodeBuilder) Go() *CodeBuilder {
21822186
}
21832187

21842188
// Block starts a block statement.
2185-
func (p *CodeBuilder) Block() *CodeBuilder {
2189+
func (p *CodeBuilder) Block(src ...ast.Node) *CodeBuilder {
21862190
if debugInstr {
21872191
log.Println("Block")
21882192
}
21892193
stmt := &blockStmt{}
2190-
p.startBlockStmt(stmt, "block statement", &stmt.old)
2194+
p.startBlockStmt(stmt, src, "block statement", &stmt.old)
21912195
return p
21922196
}
21932197

@@ -2208,37 +2212,37 @@ func (p *CodeBuilder) InVBlock() bool {
22082212
}
22092213

22102214
// Block starts a if statement.
2211-
func (p *CodeBuilder) If() *CodeBuilder {
2215+
func (p *CodeBuilder) If(src ...ast.Node) *CodeBuilder {
22122216
if debugInstr {
22132217
log.Println("If")
22142218
}
22152219
stmt := &ifStmt{}
2216-
p.startBlockStmt(stmt, "if statement", &stmt.old)
2220+
p.startBlockStmt(stmt, src, "if statement", &stmt.old)
22172221
return p
22182222
}
22192223

22202224
// Then starts body of a if/switch/for statement.
2221-
func (p *CodeBuilder) Then() *CodeBuilder {
2225+
func (p *CodeBuilder) Then(src ...ast.Node) *CodeBuilder {
22222226
if debugInstr {
22232227
log.Println("Then")
22242228
}
22252229
if p.stk.Len() == p.current.base {
22262230
panic("use None() for empty expr")
22272231
}
22282232
if flow, ok := p.current.codeBlock.(controlFlow); ok {
2229-
flow.Then(p)
2233+
flow.Then(p, src...)
22302234
return p
22312235
}
22322236
panic("use if..then or switch..then or for..then please")
22332237
}
22342238

22352239
// Else starts else body of a if..else statement.
2236-
func (p *CodeBuilder) Else() *CodeBuilder {
2240+
func (p *CodeBuilder) Else(src ...ast.Node) *CodeBuilder {
22372241
if debugInstr {
22382242
log.Println("Else")
22392243
}
22402244
if flow, ok := p.current.codeBlock.(*ifStmt); ok {
2241-
flow.Else(p)
2245+
flow.Else(p, src...)
22422246
return p
22432247
}
22442248
panic("use if..else please")
@@ -2260,12 +2264,12 @@ func (p *CodeBuilder) Else() *CodeBuilder {
22602264
//
22612265
// end
22622266
// </pre>
2263-
func (p *CodeBuilder) TypeSwitch(name string) *CodeBuilder {
2267+
func (p *CodeBuilder) TypeSwitch(name string, src ...ast.Node) *CodeBuilder {
22642268
if debugInstr {
22652269
log.Println("TypeSwitch")
22662270
}
22672271
stmt := &typeSwitchStmt{name: name}
2268-
p.startBlockStmt(stmt, "type switch statement", &stmt.old)
2272+
p.startBlockStmt(stmt, src, "type switch statement", &stmt.old)
22692273
return p
22702274
}
22712275

@@ -2333,59 +2337,59 @@ func (p *CodeBuilder) TypeAssertThen() *CodeBuilder {
23332337
}
23342338

23352339
// TypeCase starts case body of a type switch statement.
2336-
func (p *CodeBuilder) TypeCase(n int) *CodeBuilder { // n=0 means default case
2340+
func (p *CodeBuilder) TypeCase(n int, src ...ast.Node) *CodeBuilder { // n=0 means default case
23372341
if debugInstr {
23382342
log.Println("TypeCase", n)
23392343
}
23402344
if flow, ok := p.current.codeBlock.(*typeSwitchStmt); ok {
2341-
flow.TypeCase(p, n)
2345+
flow.TypeCase(p, n, src...)
23422346
return p
23432347
}
23442348
panic("use switch x.(type) .. case please")
23452349
}
23462350

23472351
// Select starts a select statement.
2348-
func (p *CodeBuilder) Select() *CodeBuilder {
2352+
func (p *CodeBuilder) Select(src ...ast.Node) *CodeBuilder {
23492353
if debugInstr {
23502354
log.Println("Select")
23512355
}
23522356
stmt := &selectStmt{}
2353-
p.startBlockStmt(stmt, "select statement", &stmt.old)
2357+
p.startBlockStmt(stmt, src, "select statement", &stmt.old)
23542358
return p
23552359
}
23562360

23572361
// CommCase starts case body of a select..case statement.
2358-
func (p *CodeBuilder) CommCase(n int) *CodeBuilder {
2362+
func (p *CodeBuilder) CommCase(n int, src ...ast.Node) *CodeBuilder {
23592363
if debugInstr {
23602364
log.Println("CommCase", n)
23612365
}
23622366
if n > 1 {
23632367
panic("TODO: multi commStmt in select..case?")
23642368
}
23652369
if flow, ok := p.current.codeBlock.(*selectStmt); ok {
2366-
flow.CommCase(p, n)
2370+
flow.CommCase(p, n, src...)
23672371
return p
23682372
}
23692373
panic("use select..case please")
23702374
}
23712375

23722376
// Switch starts a switch statement.
2373-
func (p *CodeBuilder) Switch() *CodeBuilder {
2377+
func (p *CodeBuilder) Switch(src ...ast.Node) *CodeBuilder {
23742378
if debugInstr {
23752379
log.Println("Switch")
23762380
}
23772381
stmt := &switchStmt{}
2378-
p.startBlockStmt(stmt, "switch statement", &stmt.old)
2382+
p.startBlockStmt(stmt, src, "switch statement", &stmt.old)
23792383
return p
23802384
}
23812385

23822386
// Case starts case body of a switch..case statement.
2383-
func (p *CodeBuilder) Case(n int) *CodeBuilder { // n=0 means default case
2387+
func (p *CodeBuilder) Case(n int, src ...ast.Node) *CodeBuilder { // n=0 means default case
23842388
if debugInstr {
23852389
log.Println("Case", n)
23862390
}
23872391
if flow, ok := p.current.codeBlock.(*switchStmt); ok {
2388-
flow.Case(p, n)
2392+
flow.Case(p, n, src...)
23892393
return p
23902394
}
23912395
panic("use switch..case please")
@@ -2483,12 +2487,12 @@ func (p *CodeBuilder) Fallthrough() *CodeBuilder {
24832487
}
24842488

24852489
// For func
2486-
func (p *CodeBuilder) For() *CodeBuilder {
2490+
func (p *CodeBuilder) For(src ...ast.Node) *CodeBuilder {
24872491
if debugInstr {
24882492
log.Println("For")
24892493
}
24902494
stmt := &forStmt{}
2491-
p.startBlockStmt(stmt, "for statement", &stmt.old)
2495+
p.startBlockStmt(stmt, src, "for statement", &stmt.old)
24922496
return p
24932497
}
24942498

@@ -2506,11 +2510,16 @@ func (p *CodeBuilder) Post() *CodeBuilder {
25062510

25072511
// ForRange func
25082512
func (p *CodeBuilder) ForRange(names ...string) *CodeBuilder {
2513+
return p.ForRangeEx(names)
2514+
}
2515+
2516+
// ForRangeEx func
2517+
func (p *CodeBuilder) ForRangeEx(names []string, src ...ast.Node) *CodeBuilder {
25092518
if debugInstr {
25102519
log.Println("ForRange", names)
25112520
}
25122521
stmt := &forRangeStmt{names: names}
2513-
p.startBlockStmt(stmt, "for range statement", &stmt.old)
2522+
p.startBlockStmt(stmt, src, "for range statement", &stmt.old)
25142523
return p
25152524
}
25162525

func.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func (p *Func) Ancestor() *Func {
9797
}
9898

9999
// BodyStart func
100-
func (p *Func) BodyStart(pkg *Package) *CodeBuilder {
100+
func (p *Func) BodyStart(pkg *Package, src ...ast.Node) *CodeBuilder {
101101
if debugInstr {
102102
var recv string
103103
tag := "NewFunc "
@@ -111,7 +111,7 @@ func (p *Func) BodyStart(pkg *Package) *CodeBuilder {
111111
}
112112
log.Printf("%v%v%v %v\n", tag, name, recv, sig)
113113
}
114-
return pkg.cb.startFuncBody(p, &p.old)
114+
return pkg.cb.startFuncBody(p, src, &p.old)
115115
}
116116

117117
// End is for internal use.

package_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,7 @@ func main() {
840840
func TestTypeAssert(t *testing.T) {
841841
pkg := newMainPackage()
842842
params := types.NewTuple(pkg.NewParam(token.NoPos, "v", gox.TyEmptyInterface))
843-
pkg.NewFunc(nil, "foo", params, nil, false).BodyStart(pkg).
843+
pkg.NewFunc(nil, "foo", params, nil, false).BodyStart(pkg, source("{}", 1, 5)).
844844
DefineVarStart(0, "x").VarVal("v").TypeAssert(types.Typ[types.Int], false).EndInit(1).
845845
DefineVarStart(0, "y", "ok").VarVal("v").TypeAssert(types.Typ[types.String], true).EndInit(1).
846846
End()

stmt.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import (
2323
)
2424

2525
type controlFlow interface {
26-
Then(cb *CodeBuilder)
26+
Then(cb *CodeBuilder, src ...ast.Node)
2727
}
2828

2929
// ----------------------------------------------------------------------------
@@ -77,7 +77,7 @@ type ifStmt struct {
7777
old2 codeBlockCtx
7878
}
7979

80-
func (p *ifStmt) Then(cb *CodeBuilder) {
80+
func (p *ifStmt) Then(cb *CodeBuilder, src ...ast.Node) {
8181
cond := cb.stk.Pop()
8282
if !types.AssignableTo(cond.Type, types.Typ[types.Bool]) {
8383
panic("TODO: if statement condition is not a boolean expr")
@@ -91,10 +91,10 @@ func (p *ifStmt) Then(cb *CodeBuilder) {
9191
default:
9292
panic("TODO: if statement has too many init statements")
9393
}
94-
cb.startBlockStmt(p, "if body", &p.old2)
94+
cb.startBlockStmt(p, src, "if body", &p.old2)
9595
}
9696

97-
func (p *ifStmt) Else(cb *CodeBuilder) {
97+
func (p *ifStmt) Else(cb *CodeBuilder, src ...ast.Node) {
9898
if p.body != nil {
9999
panic("TODO: else statement already exists")
100100
}
@@ -103,7 +103,7 @@ func (p *ifStmt) Else(cb *CodeBuilder) {
103103
cb.current.flows |= flows
104104

105105
p.body = &ast.BlockStmt{List: stmts}
106-
cb.startBlockStmt(p, "else body", &p.old2)
106+
cb.startBlockStmt(p, src, "else body", &p.old2)
107107
}
108108

109109
func (p *ifStmt) End(cb *CodeBuilder, src ast.Node) {
@@ -144,7 +144,7 @@ type switchStmt struct {
144144
old codeBlockCtx
145145
}
146146

147-
func (p *switchStmt) Then(cb *CodeBuilder) {
147+
func (p *switchStmt) Then(cb *CodeBuilder, src ...ast.Node) {
148148
p.tag = cb.stk.Pop()
149149
switch stmts := cb.clearBlockStmt(); len(stmts) {
150150
case 0:
@@ -156,7 +156,7 @@ func (p *switchStmt) Then(cb *CodeBuilder) {
156156
}
157157
}
158158

159-
func (p *switchStmt) Case(cb *CodeBuilder, n int) {
159+
func (p *switchStmt) Case(cb *CodeBuilder, n int, src ...ast.Node) {
160160
var list []ast.Expr
161161
if n > 0 {
162162
list = make([]ast.Expr, n)
@@ -178,7 +178,7 @@ func (p *switchStmt) Case(cb *CodeBuilder, n int) {
178178
cb.stk.PopN(n)
179179
}
180180
stmt := &caseStmt{list: list}
181-
cb.startBlockStmt(stmt, "case statement", &stmt.old)
181+
cb.startBlockStmt(stmt, src, "case statement", &stmt.old)
182182
}
183183

184184
func (p *switchStmt) End(cb *CodeBuilder, src ast.Node) {
@@ -225,13 +225,13 @@ type selectStmt struct {
225225
old codeBlockCtx
226226
}
227227

228-
func (p *selectStmt) CommCase(cb *CodeBuilder, n int) {
228+
func (p *selectStmt) CommCase(cb *CodeBuilder, n int, src ...ast.Node) {
229229
var comm ast.Stmt
230230
if n == 1 {
231231
comm = cb.popStmt()
232232
}
233233
stmt := &commCase{comm: comm}
234-
cb.startBlockStmt(stmt, "comm case statement", &stmt.old)
234+
cb.startBlockStmt(stmt, src, "comm case statement", &stmt.old)
235235
}
236236

237237
func (p *selectStmt) End(cb *CodeBuilder, src ast.Node) {
@@ -291,7 +291,7 @@ func (p *typeSwitchStmt) TypeAssertThen(cb *CodeBuilder) {
291291
p.x, p.xSrc, p.xType = x.Val, x.Src, xType
292292
}
293293

294-
func (p *typeSwitchStmt) TypeCase(cb *CodeBuilder, n int) {
294+
func (p *typeSwitchStmt) TypeCase(cb *CodeBuilder, n int, src ...ast.Node) {
295295
var list []ast.Expr
296296
var typ types.Type
297297
if n > 0 {
@@ -318,7 +318,7 @@ func (p *typeSwitchStmt) TypeCase(cb *CodeBuilder, n int) {
318318
}
319319

320320
stmt := &typeCaseStmt{list: list}
321-
cb.startBlockStmt(stmt, "type case statement", &stmt.old)
321+
cb.startBlockStmt(stmt, src, "type case statement", &stmt.old)
322322

323323
if p.name != "" {
324324
if n != 1 { // default, or case with multi expr
@@ -400,7 +400,7 @@ type forStmt struct {
400400
loopBodyHandler
401401
}
402402

403-
func (p *forStmt) Then(cb *CodeBuilder) {
403+
func (p *forStmt) Then(cb *CodeBuilder, src ...ast.Node) {
404404
cond := cb.stk.Pop()
405405
if cond.Val != nil {
406406
if !types.AssignableTo(cond.Type, types.Typ[types.Bool]) {
@@ -416,7 +416,7 @@ func (p *forStmt) Then(cb *CodeBuilder) {
416416
default:
417417
panic("TODO: for condition has too many init statements")
418418
}
419-
cb.startBlockStmt(p, "for body", &p.old2)
419+
cb.startBlockStmt(p, src, "for body", &p.old2)
420420
}
421421

422422
func (p *forStmt) Post(cb *CodeBuilder) {

0 commit comments

Comments
 (0)