Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cl/internal/typesutil.NewTypeAndValue #1532

Merged
merged 1 commit into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions cl/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"strings"

"github.com/goplus/gop/ast"
"github.com/goplus/gop/cl/internal/typesutil"
"github.com/goplus/gop/printer"
"github.com/goplus/gop/token"
"github.com/goplus/gox"
Expand Down Expand Up @@ -161,7 +162,7 @@ find:
}
rec.Use(ident, o)
typ, _ := gox.DerefType(e.Type)
tv := types.TypeAndValue{Type: typ, Value: e.CVal}
tv := typesutil.NewTypeAndValue(typ, e.CVal)
rec.Type(ident, tv)
}
return
Expand Down Expand Up @@ -360,7 +361,7 @@ func compileSelectorExprLHS(ctx *blockCtx, v *ast.SelectorExpr) {
compileExpr(ctx, v.X)
if rec := ctx.recorder(); rec != nil {
e := ctx.cb.Get(-1)
rec.Type(v.X, types.TypeAndValue{Type: e.Type, Value: e.CVal})
rec.Type(v.X, typesutil.NewTypeAndValue(e.Type, e.CVal))
}
}
ctx.cb.MemberRef(v.Sel.Name, v)
Expand All @@ -382,7 +383,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, types.TypeAndValue{Type: e.Type, Value: e.CVal})
rec.Type(v.X, typesutil.NewTypeAndValue(e.Type, e.CVal))
}
}
if err := compileMember(ctx, v, v.Sel.Name, flags); err != nil {
Expand Down
61 changes: 61 additions & 0 deletions cl/internal/typesutil/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2023 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package typesutil

import (
"go/constant"
"go/types"
"unsafe"

"github.com/goplus/gox"
)

// An operandMode specifies the (addressing) mode of an operand.
type operandMode byte

const (
invalid operandMode = iota // operand is invalid
novalue // operand represents no value (result of a function call w/o result)
builtin // operand is a built-in function
typexpr // operand is a type
constant_ // operand is a constant; the operand's typ is a Basic type
variable // operand is an addressable variable
mapindex // operand is a map index expression (acts like a variable on lhs, commaok on rhs of an assignment)
value // operand is a computed value
commaok // like value, but operand may be used in a comma,ok expression
commaerr // like commaok, but second value is error, not boolean
cgofunc // operand is a cgo function
)

// TypeAndValue reports the type and value (for constants)
// of the corresponding expression.
type TypeAndValue struct {
mode operandMode
Type types.Type
Value constant.Value
}

func NewTypeAndValue(typ types.Type, val constant.Value) (ret types.TypeAndValue) {
if t, ok := typ.(*gox.TypeType); ok {
ret.Type = t.Type()
(*TypeAndValue)(unsafe.Pointer(&ret)).mode = typexpr
} else {
ret.Type = typ
ret.Value = val
}
return
}
37 changes: 37 additions & 0 deletions cl/internal/typesutil/api_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2023 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package typesutil

import (
"go/constant"
"go/types"
"testing"

"github.com/goplus/gox"
)

func TestTypeAndValue(t *testing.T) {
ty := gox.NewTypeType(types.Typ[types.Int])
ret := NewTypeAndValue(ty, nil)
if !ret.IsType() {
t.Fatal("NewTypeAndValue: not type?")
}
ret = NewTypeAndValue(types.Typ[types.Int], constant.MakeInt64(1))
if ret.Value == nil {
t.Fatal("NewTypeAndValue: not const?")
}
}
28 changes: 21 additions & 7 deletions x/typesutil/gopinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,9 @@ func (info gopRecorder) Type(e ast.Expr, tv types.TypeAndValue) {
if debugVerbose {
log.Println("==> Type:", e, tv.Type)
}
info.Types[e] = tv
if info.Types != nil {
info.Types[e] = tv
}
}

// Instantiate maps identifiers denoting generic types or functions to their
Expand All @@ -201,7 +203,9 @@ func (info gopRecorder) Type(e ast.Expr, tv types.TypeAndValue) {
// Invariant: Instantiating Uses[id].Type() with Instances[id].TypeArgs
// results in an equivalent of Instances[id].Type.
func (info gopRecorder) Instantiate(id *ast.Ident, inst types.Instance) {
info.Instances[id] = inst
if info.Instances != nil {
info.Instances[id] = inst
}
}

// Def maps identifiers to the objects they define (including
Expand All @@ -217,7 +221,9 @@ func (info gopRecorder) Def(id *ast.Ident, obj types.Object) {
if debugVerbose {
log.Println("==> Def:", id, obj)
}
info.Defs[id] = obj
if info.Defs != nil {
info.Defs[id] = obj
}
}

// Use maps identifiers to the objects they denote.
Expand All @@ -229,7 +235,9 @@ func (info gopRecorder) Use(id *ast.Ident, obj types.Object) {
if debugVerbose {
log.Println("==> Use:", id, obj)
}
info.Uses[id] = obj
if info.Uses != nil {
info.Uses[id] = obj
}
}

// Implicit maps nodes to their implicitly declared objects, if any.
Expand All @@ -244,13 +252,17 @@ func (info gopRecorder) Implicit(node ast.Node, obj types.Object) {
if debugVerbose {
log.Println("==> Implicit:", obj)
}
info.Implicits[node] = obj
if info.Implicits != nil {
info.Implicits[node] = obj
}
}

// Select maps selector expressions (excluding qualified identifiers)
// to their corresponding selections.
func (info gopRecorder) Select(e *ast.SelectorExpr, sel *types.Selection) {
info.Selections[e] = sel
if info.Selections != nil {
info.Selections[e] = sel
}
}

// Scope maps ast.Nodes to the scopes they define. Package scopes are not
Expand Down Expand Up @@ -280,7 +292,9 @@ func (info gopRecorder) Scope(n ast.Node, scope *types.Scope) {
if debugVerbose {
log.Println("==> Scope:", scope)
}
info.Scopes[n] = scope
if info.Scopes != nil {
info.Scopes[n] = scope
}
}

// -----------------------------------------------------------------------------