comparison mercurial/filesetlang.py @ 38872:ca4de8ba5b5f

fileset: optimize 'x and not y' to 'x - y' 'x - y' is first rewritten to 'x and not y' so that x and y are reordered by weight.
author Yuya Nishihara <yuya@tcha.org>
date Sat, 21 Jul 2018 16:49:01 +0900
parents b975c5801487
children 61ab546b71c3
comparison
equal deleted inserted replaced
38871:b975c5801487 38872:ca4de8ba5b5f
147 if op == 'negate': 147 if op == 'negate':
148 raise error.ParseError(_("can't use negate operator in this context")) 148 raise error.ParseError(_("can't use negate operator in this context"))
149 if op == 'not': 149 if op == 'not':
150 t = _analyze(x[1]) 150 t = _analyze(x[1])
151 return (op, t) 151 return (op, t)
152 if op in {'and', 'minus'}: 152 if op == 'and':
153 ta = _analyze(x[1]) 153 ta = _analyze(x[1])
154 tb = _analyze(x[2]) 154 tb = _analyze(x[2])
155 return (op, ta, tb) 155 return (op, ta, tb)
156 if op == 'minus':
157 return _analyze(('and', x[1], ('not', x[2])))
156 if op in {'list', 'or'}: 158 if op in {'list', 'or'}:
157 ts = tuple(_analyze(y) for y in x[1:]) 159 ts = tuple(_analyze(y) for y in x[1:])
158 return (op,) + ts 160 return (op,) + ts
159 if op == 'func': 161 if op == 'func':
160 getsymbol(x[1]) # function name must be a symbol 162 getsymbol(x[1]) # function name must be a symbol
168 170
169 All pseudo operations should be mapped to real operations or functions 171 All pseudo operations should be mapped to real operations or functions
170 defined in methods or symbols table respectively. 172 defined in methods or symbols table respectively.
171 """ 173 """
172 return _analyze(x) 174 return _analyze(x)
175
176 def _optimizeandops(op, ta, tb):
177 if tb is not None and tb[0] == 'not':
178 return ('minus', ta, tb[1])
179 return (op, ta, tb)
173 180
174 def _optimize(x): 181 def _optimize(x):
175 if x is None: 182 if x is None:
176 return 0, x 183 return 0, x
177 184
186 return w, (op, t) 193 return w, (op, t)
187 if op == 'and': 194 if op == 'and':
188 wa, ta = _optimize(x[1]) 195 wa, ta = _optimize(x[1])
189 wb, tb = _optimize(x[2]) 196 wb, tb = _optimize(x[2])
190 if wa <= wb: 197 if wa <= wb:
191 return wa, (op, ta, tb) 198 return wa, _optimizeandops(op, ta, tb)
192 else: 199 else:
193 return wb, (op, tb, ta) 200 return wb, _optimizeandops(op, tb, ta)
194 if op == 'minus':
195 wa, ta = _optimize(x[1])
196 wb, tb = _optimize(x[2])
197 return max(wa, wb), (op, ta, tb)
198 if op == 'or': 201 if op == 'or':
199 ws, ts = zip(*(_optimize(y) for y in x[1:])) 202 ws, ts = zip(*(_optimize(y) for y in x[1:]))
200 return max(ws), (op,) + ts 203 return max(ws), (op,) + ts
201 if op == 'list': 204 if op == 'list':
202 ws, ts = zip(*(_optimize(y) for y in x[1:])) 205 ws, ts = zip(*(_optimize(y) for y in x[1:]))