Skip to content

Commit

Permalink
add untyped const coerce checker
Browse files Browse the repository at this point in the history
Fixes #4

Signed-off-by: Iskander Sharipov <quasilyte@gmail.com>
  • Loading branch information
quasilyte committed Oct 25, 2018
1 parent b6de4f3 commit b22fb90
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 0 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,15 @@ LabelName:
// C: lower camel case
labelName:
```

#### untyped const coerce

```go
// A: LHS type
var x int32 = 10
const y float32 = 1.6

// B: RHS type
var x = int32(10)
const y = float32(1.6)
```
72 changes: 72 additions & 0 deletions checkers.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,78 @@ func (c *labelCaseChecker) Visit(n ast.Node) bool {
return true
}

type untypedConstCoerceChecker struct {
checkerBase

lhsType opVariant
rhsType opVariant
}

func newUntypedConstCoerceChecker(ctxt *context) checker {
c := &untypedConstCoerceChecker{}
c.ctxt = ctxt
c.lhsType.warning = "specify type in LHS, like in `var x T = const`"
c.rhsType.warning = "specity type in RHS, like in `var x = T(const)`"
c.op = &operation{
name: "untyped const coerce",
variants: []*opVariant{&c.lhsType, &c.rhsType},
}
return c
}

func (c *untypedConstCoerceChecker) Visit(n ast.Node) bool {
decl, ok := n.(*ast.GenDecl)
if !ok {
return true
}
if decl.Tok != token.VAR && decl.Tok != token.CONST {
return false
}
if len(decl.Specs) != 1 {
return false
}
spec := decl.Specs[0].(*ast.ValueSpec)
if len(spec.Names) != 1 {
return false
}

if spec.Type != nil {
if !c.isUntypedConst(spec.Values[0]) {
return false
}
c.ctxt.mark(n, &c.lhsType)
} else {
conv, ok := spec.Values[0].(*ast.CallExpr)
if !ok {
return false
}
if len(conv.Args) != 1 || !c.isUntypedConst(conv.Args[0]) {
return false
}
c.ctxt.mark(n, &c.rhsType)
}

return false
}

func (c *untypedConstCoerceChecker) isUntypedConst(e ast.Expr) bool {
switch e := e.(type) {
case *ast.BasicLit:
return true
case *ast.Ident:
typ, ok := c.ctxt.info.ObjectOf(e).Type().(*types.Basic)
return ok && typ.Info()&types.IsUntyped != 0
case *ast.BinaryExpr:
return c.isUntypedConst(e.X) && c.isUntypedConst(e.Y)
case *ast.UnaryExpr:
return c.isUntypedConst(e.X)
case *ast.ParenExpr:
return c.isUntypedConst(e.X)
default:
return false
}
}

type emptyMapChecker struct {
checkerBase

Expand Down
1 change: 1 addition & 0 deletions end2end_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

func TestEnd2End(t *testing.T) {
filenames := []string{
// "positive_tests0.go",
"positive_tests1.go",
"positive_tests2.go",
"positive_tests3.go",
Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ func (ctxt *context) initCheckers() error {
newAndNotChecker(ctxt),
newFloatLitChecker(ctxt),
newLabelCaseChecker(ctxt),
newUntypedConstCoerceChecker(ctxt),
}

variantID := 0
Expand Down
8 changes: 8 additions & 0 deletions testdata/negative_tests1.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,11 @@ FOO:
UPPER_CAMEL_CASE:
LOWER_CAMEL_CASE:
}

func untypedConstCoerce() {
const zero = 0

var _ int = zero
var _ int32 = 10
var _ int64 = (zero + 1)
}
8 changes: 8 additions & 0 deletions testdata/negative_tests2.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,11 @@ Foo:
UpperCamelCase:
LowerCamelCase:
}

func untypedConstCoerce() {
const zero = 0

var _ = int(zero)
var _ = int32(10)
var _ = int64(zero + 1)
}
9 changes: 9 additions & 0 deletions testdata/positive_tests1.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,12 @@ UpperCamelCase:
//= label case: use ALL_UPPER
lowerCamelCase:
}

func untypedConstCoerce() {
const zero = 0

var _ int = zero
var _ int32 = 10
//= untyped const coerce: specify type in LHS, like in `var x T = const`
var _ = int64(zero + 1)
}
9 changes: 9 additions & 0 deletions testdata/positive_tests2.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,12 @@ UpperCamelCase:
//= label case: use UpperCamelCase
lowerCamelCase:
}

func untypedConstCoerce() {
const zero = 0

//= untyped const coerce: specity type in RHS, like in `var x = T(const)`
var _ int = zero
var _ = int32(10)
var _ = int64(zero + 1)
}

0 comments on commit b22fb90

Please sign in to comment.