Skip to content

Commit

Permalink
Merge pull request #262 from xushiwei/q
Browse files Browse the repository at this point in the history
  • Loading branch information
xushiwei authored Sep 26, 2023
2 parents 93ea06e + 547c58a commit e9b564a
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 74 deletions.
6 changes: 3 additions & 3 deletions builtin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ func TestVarDeclEnd(t *testing.T) {
t.Fatal("TestVarDeclEnd failed: no error?")
}
}()
decl.End(nil)
decl.End(nil, nil)
}

func TestCheckParenExpr(t *testing.T) {
Expand Down Expand Up @@ -935,7 +935,7 @@ func TestForRangeStmtPanic(t *testing.T) {
}
}()
var s forRangeStmt
s.End(nil)
s.End(nil, nil)
}

func TestNewFuncDeclPanic(t *testing.T) {
Expand Down Expand Up @@ -969,7 +969,7 @@ func TestSwitchStmtPanic(t *testing.T) {
}
}()
var s switchStmt
s.End(nil)
s.End(nil, nil)
}

func TestCallIncDec(t *testing.T) {
Expand Down
80 changes: 52 additions & 28 deletions codebuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func getSrc(node []ast.Node) ast.Node {
// ----------------------------------------------------------------------------

type codeBlock interface {
End(cb *CodeBuilder)
End(cb *CodeBuilder, src ast.Node)
}

type vblockCtx struct {
Expand Down Expand Up @@ -314,9 +314,10 @@ func (p *CodeBuilder) startStmtAt(stmt ast.Stmt) int {
}

// Usage:
// idx := cb.startStmtAt(stmt)
// ...
// cb.commitStmt(idx)
//
// idx := cb.startStmtAt(stmt)
// ...
// cb.commitStmt(idx)
func (p *CodeBuilder) commitStmt(idx int) {
stmts := p.current.stmts
n := len(stmts) - 1
Expand Down Expand Up @@ -751,7 +752,7 @@ retry:
}

// MapLit func
func (p *CodeBuilder) MapLit(typ types.Type, arity int) *CodeBuilder {
func (p *CodeBuilder) MapLit(typ types.Type, arity int, src ...ast.Node) *CodeBuilder {
if debugInstr {
log.Println("MapLit", typ, arity)
}
Expand All @@ -777,7 +778,7 @@ func (p *CodeBuilder) MapLit(typ types.Type, arity int) *CodeBuilder {
typExpr = toMapType(pkg, t)
}
ret := &ast.CompositeLit{Type: typExpr}
p.stk.Push(&internal.Elem{Type: typ, Val: ret})
p.stk.Push(&internal.Elem{Type: typ, Val: ret, Src: getSrc(src)})
return p
}
if (arity & 1) != 0 {
Expand Down Expand Up @@ -810,7 +811,9 @@ func (p *CodeBuilder) MapLit(typ types.Type, arity int) *CodeBuilder {
}
}
}
p.stk.Ret(arity, &internal.Elem{Type: typ, Val: &ast.CompositeLit{Type: typExpr, Elts: elts}})
p.stk.Ret(arity, &internal.Elem{
Type: typ, Val: &ast.CompositeLit{Type: typExpr, Elts: elts}, Src: getSrc(src),
})
return p
}

Expand Down Expand Up @@ -860,10 +863,15 @@ func (p *CodeBuilder) indexElemExpr(args []*internal.Elem, i int) ast.Expr {

// SliceLit func
func (p *CodeBuilder) SliceLit(typ types.Type, arity int, keyVal ...bool) *CodeBuilder {
var elts []ast.Expr
var keyValMode = (keyVal != nil && keyVal[0])
return p.SliceLitEx(typ, arity, keyValMode)
}

// SliceLitEx func
func (p *CodeBuilder) SliceLitEx(typ types.Type, arity int, keyVal bool, src ...ast.Node) *CodeBuilder {
var elts []ast.Expr
if debugInstr {
log.Println("SliceLit", typ, arity, keyValMode)
log.Println("SliceLit", typ, arity, keyVal)
}
var t *types.Slice
var typExpr ast.Expr
Expand All @@ -880,7 +888,7 @@ func (p *CodeBuilder) SliceLit(typ types.Type, arity int, keyVal ...bool) *CodeB
log.Panicln("SliceLit: typ isn't a slice type -", reflect.TypeOf(typ))
}
}
if keyValMode { // in keyVal mode
if keyVal { // in keyVal mode
if (arity & 1) != 0 {
log.Panicln("SliceLit: invalid arity, can't be odd in keyVal mode -", arity)
}
Expand All @@ -904,7 +912,9 @@ func (p *CodeBuilder) SliceLit(typ types.Type, arity int, keyVal ...bool) *CodeB
typ = t
typExpr = toSliceType(pkg, t)
}
p.stk.Push(&internal.Elem{Type: typ, Val: &ast.CompositeLit{Type: typExpr}})
p.stk.Push(&internal.Elem{
Type: typ, Val: &ast.CompositeLit{Type: typExpr}, Src: getSrc(src),
})
return p
}
var val types.Type
Expand All @@ -930,16 +940,23 @@ func (p *CodeBuilder) SliceLit(typ types.Type, arity int, keyVal ...bool) *CodeB
}
}
}
p.stk.Ret(arity, &internal.Elem{Type: typ, Val: &ast.CompositeLit{Type: typExpr, Elts: elts}})
p.stk.Ret(arity, &internal.Elem{
Type: typ, Val: &ast.CompositeLit{Type: typExpr, Elts: elts}, Src: getSrc(src),
})
return p
}

// ArrayLit func
func (p *CodeBuilder) ArrayLit(typ types.Type, arity int, keyVal ...bool) *CodeBuilder {
var elts []ast.Expr
var keyValMode = (keyVal != nil && keyVal[0])
return p.ArrayLitEx(typ, arity, keyValMode)
}

// ArrayLitEx func
func (p *CodeBuilder) ArrayLitEx(typ types.Type, arity int, keyVal bool, src ...ast.Node) *CodeBuilder {
var elts []ast.Expr
if debugInstr {
log.Println("ArrayLit", typ, arity, keyValMode)
log.Println("ArrayLit", typ, arity, keyVal)
}
var t *types.Array
var typExpr ast.Expr
Expand All @@ -954,7 +971,7 @@ func (p *CodeBuilder) ArrayLit(typ types.Type, arity int, keyVal ...bool) *CodeB
default:
log.Panicln("ArrayLit: typ isn't a array type -", reflect.TypeOf(typ))
}
if keyValMode { // in keyVal mode
if keyVal { // in keyVal mode
if (arity & 1) != 0 {
log.Panicln("ArrayLit: invalid arity, can't be odd in keyVal mode -", arity)
}
Expand Down Expand Up @@ -995,12 +1012,14 @@ func (p *CodeBuilder) ArrayLit(typ types.Type, arity int, keyVal ...bool) *CodeB
}
}
}
p.stk.Ret(arity, &internal.Elem{Type: typ, Val: &ast.CompositeLit{Type: typExpr, Elts: elts}})
p.stk.Ret(arity, &internal.Elem{
Type: typ, Val: &ast.CompositeLit{Type: typExpr, Elts: elts}, Src: getSrc(src),
})
return p
}

// StructLit func
func (p *CodeBuilder) StructLit(typ types.Type, arity int, keyVal bool) *CodeBuilder {
func (p *CodeBuilder) StructLit(typ types.Type, arity int, keyVal bool, src ...ast.Node) *CodeBuilder {
if debugInstr {
log.Println("StructLit", typ, arity, keyVal)
}
Expand Down Expand Up @@ -1062,7 +1081,9 @@ func (p *CodeBuilder) StructLit(typ types.Type, arity int, keyVal bool) *CodeBui
}
}
}
p.stk.Ret(arity, &internal.Elem{Type: typ, Val: &ast.CompositeLit{Type: typExpr, Elts: elts}})
p.stk.Ret(arity, &internal.Elem{
Type: typ, Val: &ast.CompositeLit{Type: typExpr, Elts: elts}, Src: getSrc(src),
})
return p
}

Expand Down Expand Up @@ -2059,9 +2080,9 @@ func (p *CodeBuilder) CompareNil(op token.Token, src ...ast.Node) *CodeBuilder {
}

// UnaryOp:
// - cb.UnaryOp(op token.Token)
// - cb.UnaryOp(op token.Token, twoValue bool)
// - cb.UnaryOp(op token.Token, twoValue bool, src ast.Node)
// - cb.UnaryOp(op token.Token)
// - cb.UnaryOp(op token.Token, twoValue bool)
// - cb.UnaryOp(op token.Token, twoValue bool, src ast.Node)
func (p *CodeBuilder) UnaryOp(op token.Token, params ...interface{}) *CodeBuilder {
var src ast.Node
var flags InstrFlags
Expand Down Expand Up @@ -2194,14 +2215,17 @@ func (p *CodeBuilder) Else() *CodeBuilder {
// <pre>
// typeSwitch(name) init; expr typeAssertThen
// type1, type2, ... typeN typeCase(N)
// ...
// end
//
// ...
// end
//
// type1, type2, ... typeM typeCase(M)
// ...
// end
//
// ...
// end
//
// end
// </pre>
//
func (p *CodeBuilder) TypeSwitch(name string) *CodeBuilder {
if debugInstr {
log.Println("TypeSwitch")
Expand Down Expand Up @@ -2491,7 +2515,7 @@ func (p *CodeBuilder) EndStmt() *CodeBuilder {
}

// End func
func (p *CodeBuilder) End() *CodeBuilder {
func (p *CodeBuilder) End(src ...ast.Node) *CodeBuilder {
if debugInstr {
typ := reflect.TypeOf(p.current.codeBlock)
if typ.Kind() == reflect.Ptr {
Expand All @@ -2503,7 +2527,7 @@ func (p *CodeBuilder) End() *CodeBuilder {
panic("forget to call EndStmt()?")
}
}
p.current.End(p)
p.current.End(p, getSrc(src))
return p
}

Expand Down
4 changes: 2 additions & 2 deletions func.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func (p *Func) BodyStart(pkg *Package) *CodeBuilder {
}

// End is for internal use.
func (p *Func) End(cb *CodeBuilder) {
func (p *Func) End(cb *CodeBuilder, src ast.Node) {
if p.isInline() {
p.inlineClosureEnd(cb)
return
Expand All @@ -112,7 +112,7 @@ func (p *Func) End(cb *CodeBuilder) {
t, _ := toNormalizeSignature(nil, p.Type().(*types.Signature))
if fn := p.decl; fn == nil { // is closure
expr := &ast.FuncLit{Type: toFuncType(pkg, t), Body: body}
cb.stk.Push(&internal.Elem{Val: expr, Type: t})
cb.stk.Push(&internal.Elem{Val: expr, Type: t, Src: src})
} else {
fn.Name, fn.Type, fn.Body = ident(p.Name()), toFuncType(pkg, t), body
if recv := t.Recv(); IsMethodRecv(recv) {
Expand Down
Loading

0 comments on commit e9b564a

Please sign in to comment.