Skip to content
This repository has been archived by the owner on Nov 18, 2021. It is now read-only.

Commit

Permalink
tools/fix: eliminate x & _ and unnecessary parens
Browse files Browse the repository at this point in the history
Change-Id: I4612a0578703d7b13328d052ad6bae85c46cf69c
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/8302
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Paul Jolly <paul@myitcv.org.uk>
  • Loading branch information
mpvl committed Jan 28, 2021
1 parent 257486c commit f55f17e
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 34 deletions.
36 changes: 4 additions & 32 deletions tools/fix/fix.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ import (
type Option func(*options)

type options struct {
simplify bool
simplify bool
deprecated bool
}

// Simplify enables fixes that simplify the code, but are not strictly
Expand Down Expand Up @@ -265,38 +266,9 @@ func File(f *ast.File, o ...Option) *ast.File {
// return true
// }, nil).(*ast.File)

if !options.simplify {
return f
if options.simplify {
f = simplify(f)
}

// Rewrite disjunctions with _ to _.
f = astutil.Apply(f, func(c astutil.Cursor) bool {
if x := findTop(c.Node()); x != nil {
c.Replace(x)
}
return true
}, nil).(*ast.File)

return f
}

func findTop(x ast.Node) ast.Expr {
switch x := x.(type) {
case *ast.BinaryExpr:
if x.Op != token.OR {
break
}
if v := findTop(x.X); v != nil {
return v
}
if v := findTop(x.Y); v != nil {
return v
}

case *ast.Ident:
if x.Name == "_" {
return x
}
}
return nil
}
14 changes: 12 additions & 2 deletions tools/fix/fix_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,19 @@ let y = foo
}, {
simplify: true,
in: `
y: _ | {[string]: int}
x1: 3 & _
x2: _ | {[string]: int}
x3: 4 & (9 | _)
x4: (_ | 9) & 4
x5: (_ & 9) & 4
x6: 4 & (_ & 9)
`,
out: `y: _
out: `x1: 3
x2: _
x3: 4
x4: 4
x5: 9 & 4
x6: 4 & 9
`,

// }, {
Expand Down
73 changes: 73 additions & 0 deletions tools/fix/simplify.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright 2021 CUE Authors
//
// 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 fix

import (
"cuelang.org/go/cue/ast"
"cuelang.org/go/cue/ast/astutil"
"cuelang.org/go/cue/token"
)

func simplify(f *ast.File) *ast.File {
// Rewrite disjunctions with _ to _.
f = astutil.Apply(f, nil, func(c astutil.Cursor) bool {
if x, ok := c.Node().(ast.Expr); ok {
if y := elideTop(x); x != y {
c.Replace(y)
}
}
return true
}).(*ast.File)

return f
}

func elideTop(x ast.Expr) ast.Expr {
switch x := x.(type) {
case *ast.BinaryExpr:
switch x.Op {
case token.OR:
if isTop(x.X) {
return x.X
}
if isTop(x.Y) {
ast.SetRelPos(x.Y, token.NoRelPos)
return x.Y
}

case token.AND:
if isTop(x.X) {
ast.SetRelPos(x.Y, token.NoRelPos)
return x.Y
}
if isTop(x.Y) {
return x.X
}
}

case *ast.ParenExpr:
switch x.X.(type) {
case *ast.BinaryExpr, *ast.UnaryExpr:
default:
return x.X
}
}
return x
}

func isTop(x ast.Expr) bool {
v, ok := x.(*ast.Ident)
return ok && v.Name == "_"
}

0 comments on commit f55f17e

Please sign in to comment.