Skip to content

Commit 4def8bf

Browse files
author
Charith Ellawala
committed
Casting variables or function results
1 parent 65db901 commit 4def8bf

2 files changed

Lines changed: 27 additions & 14 deletions

File tree

durationcheck.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,39 +64,39 @@ func check(pass *analysis.Pass) func(ast.Node) {
6464
return
6565
}
6666

67-
if isDuration(x) && isDuration(y) {
67+
if isDuration(x.Type) && isDuration(y.Type) {
6868
// check that both sides are acceptable expressions
69-
if isUnacceptableExpr(expr.X) && isUnacceptableExpr(expr.Y) {
69+
if isUnacceptableExpr(pass, expr.X) && isUnacceptableExpr(pass, expr.Y) {
7070
pass.Reportf(expr.Pos(), "Multiplication of durations: `%s`", formatNode(expr))
7171
}
7272
}
7373
}
7474
}
7575

76-
func isDuration(x types.TypeAndValue) bool {
77-
return x.Type.String() == "time.Duration"
76+
func isDuration(x types.Type) bool {
77+
return x.String() == "time.Duration"
7878
}
7979

8080
// isUnacceptableExpr returns true if the argument is not an acceptable time.Duration expression
81-
func isUnacceptableExpr(expr ast.Expr) bool {
81+
func isUnacceptableExpr(pass *analysis.Pass, expr ast.Expr) bool {
8282
switch e := expr.(type) {
8383
case *ast.BasicLit: // constants are acceptable
8484
return false
8585
case *ast.CallExpr: // explicit casting of constants such as `time.Duration(10)` is acceptable
86-
return !isConstExprCastToDuration(e)
86+
return !isAcceptableCast(pass, e)
8787
}
8888
return true
8989
}
9090

91-
// isConstExprCastToDuration returns true if the argument is a constant expression cast to time.Duration
92-
func isConstExprCastToDuration(e *ast.CallExpr) bool {
91+
// isAcceptableCast returns true if the argument is a constant expression cast to time.Duration
92+
func isAcceptableCast(pass *analysis.Pass, e *ast.CallExpr) bool {
9393
// check that there's a single argument
9494
if len(e.Args) != 1 {
9595
return false
9696
}
9797

98-
// check that the argument is a constant expression
99-
if !allConstArgs(e.Args[0]) {
98+
// check that the argument is acceptable
99+
if !isAcceptableCastArg(pass, e.Args[0]) {
100100
return false
101101
}
102102

@@ -118,15 +118,15 @@ func isConstExprCastToDuration(e *ast.CallExpr) bool {
118118
return selector.Sel.Name == "Duration"
119119
}
120120

121-
// allConstArgs checks that the argument is a constant expression
122-
func allConstArgs(n ast.Node) bool {
121+
func isAcceptableCastArg(pass *analysis.Pass, n ast.Expr) bool {
123122
switch e := n.(type) {
124123
case *ast.BasicLit:
125124
return true
126125
case *ast.BinaryExpr:
127-
return allConstArgs(e.X) && allConstArgs(e.Y)
126+
return isAcceptableCastArg(pass, e.X) && isAcceptableCastArg(pass, e.Y)
128127
default:
129-
return false
128+
argType := pass.TypesInfo.TypeOf(n)
129+
return !isDuration(argType)
130130
}
131131
}
132132

testdata/src/a/a.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const timeout = 10 * time.Second
88

99
func multiplyTwoDurations() {
1010
x := 30 * time.Second
11+
y := 10
1112

1213
_ = time.Second * 30
1314

@@ -19,6 +20,14 @@ func multiplyTwoDurations() {
1920

2021
_ = time.Second * time.Duration(10+20*5)
2122

23+
_ = time.Duration(y) * time.Second
24+
25+
_ = time.Second * time.Duration(y)
26+
27+
_ = time.Duration(someDurationMillis()) * time.Millisecond
28+
29+
_ = time.Millisecond * time.Duration(someDurationMillis())
30+
2231
_ = timeout / time.Millisecond
2332

2433
_ = timeout * time.Millisecond // want `Multiplication of durations`
@@ -43,3 +52,7 @@ func multiplyTwoDurations() {
4352
func someDuration() time.Duration {
4453
return 10 * time.Second
4554
}
55+
56+
func someDurationMillis() int {
57+
return 10
58+
}

0 commit comments

Comments
 (0)