1// Copyright 2021 CUE Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package fix 16 17import ( 18 "cuelang.org/go/cue/ast" 19 "cuelang.org/go/cue/ast/astutil" 20 "cuelang.org/go/cue/token" 21) 22 23func simplify(f *ast.File) *ast.File { 24 // Rewrite disjunctions with _ to _. 25 f = astutil.Apply(f, nil, func(c astutil.Cursor) bool { 26 if x, ok := c.Node().(ast.Expr); ok { 27 if y := elideTop(x); x != y { 28 c.Replace(y) 29 } 30 } 31 return true 32 }).(*ast.File) 33 34 return f 35} 36 37func elideTop(x ast.Expr) ast.Expr { 38 switch x := x.(type) { 39 case *ast.BinaryExpr: 40 switch x.Op { 41 case token.OR: 42 if isTop(x.X) { 43 return x.X 44 } 45 if isTop(x.Y) { 46 ast.SetRelPos(x.Y, token.NoRelPos) 47 return x.Y 48 } 49 50 case token.AND: 51 if isTop(x.X) { 52 ast.SetRelPos(x.Y, token.NoRelPos) 53 return x.Y 54 } 55 if isTop(x.Y) { 56 return x.X 57 } 58 } 59 60 case *ast.ParenExpr: 61 switch x.X.(type) { 62 case *ast.BinaryExpr, *ast.UnaryExpr: 63 default: 64 return x.X 65 } 66 } 67 return x 68} 69 70func isTop(x ast.Expr) bool { 71 v, ok := x.(*ast.Ident) 72 return ok && v.Name == "_" 73} 74