diff --git a/cl/compile.go b/cl/compile.go index bdb9d3d22..d6d64bba0 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -28,6 +28,7 @@ import ( "github.com/goplus/gop/ast" "github.com/goplus/gop/ast/fromgo" + "github.com/goplus/gop/cl/internal/typesutil" "github.com/goplus/gop/token" "github.com/goplus/gox" "github.com/goplus/gox/cpackages" @@ -220,7 +221,7 @@ type goxRecorder struct { // Member maps identifiers to the objects they denote. func (p *goxRecorder) Member(id ast.Node, obj types.Object) { - tv := types.TypeAndValue{Type: obj.Type()} + tv := typesutil.NewTypeAndValueForObject(obj) switch v := id.(type) { case *ast.SelectorExpr: sel := v.Sel diff --git a/cl/expr.go b/cl/expr.go index 00d90fe98..3752c6529 100644 --- a/cl/expr.go +++ b/cl/expr.go @@ -158,12 +158,11 @@ find: e := ctx.cb.Get(-1) if oldo != nil && gox.IsTypeEx(e.Type) { rec.Use(ident, oldo) + rec.Type(ident, typesutil.NewTypeAndValueForObject(oldo)) return } rec.Use(ident, o) - typ, _ := gox.DerefType(e.Type) - tv := typesutil.NewTypeAndValue(typ, e.CVal) - rec.Type(ident, tv) + rec.Type(ident, typesutil.NewTypeAndValueForObject(o)) } return } @@ -199,6 +198,7 @@ func compileExprLHS(ctx *blockCtx, expr ast.Expr) { compileIndexExprLHS(ctx, v) case *ast.SelectorExpr: compileSelectorExprLHS(ctx, v) + recordTypesVariable(ctx, v, -1) case *ast.StarExpr: compileStarExprLHS(ctx, v) default: @@ -210,6 +210,21 @@ func twoValue(inFlags []int) bool { return inFlags != nil && (inFlags[0]&clCallWithTwoValue) != 0 } +func recordTypesValue(ctx *blockCtx, expr ast.Expr, n int) { + if rec := ctx.recorder(); rec != nil { + e := ctx.cb.Get(n) + rec.Type(expr, typesutil.NewTypeAndValueForValue(e.Type, e.CVal)) + } +} + +func recordTypesVariable(ctx *blockCtx, expr ast.Expr, n int) { + if rec := ctx.recorder(); rec != nil { + e := ctx.cb.Get(n) + t, _ := gox.DerefType(e.Type) + rec.Type(expr, typesutil.NewTypeAndValueForVariable(t)) + } +} + func compileExpr(ctx *blockCtx, expr ast.Expr, inFlags ...int) { switch v := expr.(type) { case *ast.Ident: @@ -220,6 +235,7 @@ func compileExpr(ctx *blockCtx, expr ast.Expr, inFlags ...int) { compileIdent(ctx, v, flags) case *ast.BasicLit: compileBasicLit(ctx, v) + recordTypesValue(ctx, v, -1) case *ast.CallExpr: flags := 0 if inFlags != nil { @@ -234,8 +250,10 @@ func compileExpr(ctx *blockCtx, expr ast.Expr, inFlags ...int) { compileSelectorExpr(ctx, v, flags) case *ast.BinaryExpr: compileBinaryExpr(ctx, v) + recordTypesValue(ctx, v, -1) case *ast.UnaryExpr: compileUnaryExpr(ctx, v, twoValue(inFlags)) + recordTypesValue(ctx, v, -1) case *ast.FuncLit: compileFuncLit(ctx, v) case *ast.CompositeLit: @@ -359,10 +377,6 @@ func compileSelectorExprLHS(ctx *blockCtx, v *ast.SelectorExpr) { } default: compileExpr(ctx, v.X) - if rec := ctx.recorder(); rec != nil { - e := ctx.cb.Get(-1) - rec.Type(v.X, typesutil.NewTypeAndValue(e.Type, e.CVal)) - } } ctx.cb.MemberRef(v.Sel.Name, v) } @@ -383,7 +397,7 @@ func compileSelectorExpr(ctx *blockCtx, v *ast.SelectorExpr, flags int) { compileExpr(ctx, v.X) if rec := ctx.recorder(); rec != nil { e := ctx.cb.Get(-1) - rec.Type(v.X, typesutil.NewTypeAndValue(e.Type, e.CVal)) + rec.Type(v.X, typesutil.NewTypeAndValueForType(e.Type)) } } if err := compileMember(ctx, v, v.Sel.Name, flags); err != nil { @@ -544,6 +558,9 @@ func compileCallExpr(ctx *blockCtx, v *ast.CallExpr, inFlags int) { for fn != nil { err := compileCallArgs(fn, fnt, ctx, v, ellipsis, flags) if err == nil { + if rec := ctx.recorder(); rec != nil { + rec.Type(v, typesutil.NewTypeAndValueForCallResult(ctx.cb.Get(-1).Type)) + } break } if fn.next == nil { @@ -794,6 +811,9 @@ func compileStructLitInKeyVal(ctx *blockCtx, elts []ast.Expr, t *types.Struct, t err := ctx.newCodeErrorf(name.Pos(), "%s undefined (type %v has no field or method %s)", src, typ, name.Name) panic(err) } + if rec := ctx.recorder(); rec != nil { + rec.Use(name, t.Field(idx)) + } switch expr := kv.Value.(type) { case *ast.LambdaExpr, *ast.LambdaExpr2: sig := checkLambdaFuncType(ctx, expr, t.Field(idx).Type(), clLambaField, kv.Key) @@ -878,6 +898,9 @@ func compileCompositeLit(ctx *blockCtx, v *ast.CompositeLit, expected types.Type } if t, ok := underlying.(*types.Struct); ok && kind == compositeLitKeyVal { compileStructLitInKeyVal(ctx, v.Elts, t, typ, v) + if rec := ctx.recorder(); rec != nil { + rec.Type(v, typesutil.NewTypeAndValueForValue(typ, nil)) + } if hasPtr { ctx.cb.UnaryOp(gotoken.AND) } @@ -892,6 +915,10 @@ func compileCompositeLit(ctx *blockCtx, v *ast.CompositeLit, expected types.Type ctx.cb.MapLit(nil, n<<1) return } + if rec := ctx.recorder(); rec != nil { + rec.Type(v.Type, typesutil.NewTypeAndValueForType(typ)) + rec.Type(v, typesutil.NewTypeAndValueForValue(typ, nil)) + } switch underlying.(type) { case *types.Slice: ctx.cb.SliceLitEx(typ, n<