##// END OF EJS Templates
revset: move tagging of alias arguments from tokenization to parsing phase...
Yuya Nishihara -
r28689:a14732e0 default
parent child Browse files
Show More
@@ -2261,14 +2261,10 b' def optimize(x, small):'
2261 2261 return w + wa, (op, x[1], ta)
2262 2262 return 1, x
2263 2263
2264 _aliasarg = ('func', ('symbol', '_aliasarg'))
2265 2264 def _getaliasarg(tree):
2266 """If tree matches ('func', ('symbol', '_aliasarg'), ('string', X))
2267 return X, None otherwise.
2268 """
2269 if (len(tree) == 3 and tree[:2] == _aliasarg
2270 and tree[2][0] == 'string'):
2271 return tree[2][1]
2265 """If tree matches ('_aliasarg', X) return X, None otherwise"""
2266 if tree[0] == '_aliasarg':
2267 return tree[1]
2272 2268 return None
2273 2269
2274 2270 def _checkaliasarg(tree, known=None):
@@ -2369,70 +2365,64 b' def _parsealiasdecl(decl):'
2369 2365 except error.ParseError as inst:
2370 2366 return (decl, None, None, parseerrordetail(inst))
2371 2367
2368 def _relabelaliasargs(tree, args):
2369 if not isinstance(tree, tuple):
2370 return tree
2371 op = tree[0]
2372 if op != 'symbol':
2373 return (op,) + tuple(_relabelaliasargs(x, args) for x in tree[1:])
2374
2375 assert len(tree) == 2
2376 sym = tree[1]
2377 if sym in args:
2378 op = '_aliasarg'
2379 elif sym.startswith('$'):
2380 raise error.ParseError(_("'$' not for alias arguments"))
2381 return (op, sym)
2382
2372 2383 def _parsealiasdefn(defn, args):
2373 2384 """Parse alias definition ``defn``
2374 2385
2375 This function also replaces alias argument references in the
2376 specified definition by ``_aliasarg(ARGNAME)``.
2386 This function marks alias argument references as ``_aliasarg``.
2377 2387
2378 2388 ``args`` is a list of alias argument names, or None if the alias
2379 2389 is declared as a symbol.
2380 2390
2381 2391 This returns "tree" as parsing result.
2382 2392
2393 >>> def prettyformat(tree):
2394 ... return parser.prettyformat(tree, ('_aliasarg', 'string', 'symbol'))
2383 2395 >>> args = ['$1', '$2', 'foo']
2384 2396 >>> print prettyformat(_parsealiasdefn('$1 or foo', args))
2385 2397 (or
2386 (func
2387 ('symbol', '_aliasarg')
2388 ('string', '$1'))
2389 (func
2390 ('symbol', '_aliasarg')
2391 ('string', 'foo')))
2398 ('_aliasarg', '$1')
2399 ('_aliasarg', 'foo'))
2392 2400 >>> try:
2393 2401 ... _parsealiasdefn('$1 or $bar', args)
2394 2402 ... except error.ParseError, inst:
2395 2403 ... print parseerrordetail(inst)
2396 at 6: '$' not for alias arguments
2404 '$' not for alias arguments
2397 2405 >>> args = ['$1', '$10', 'foo']
2398 2406 >>> print prettyformat(_parsealiasdefn('$10 or foobar', args))
2399 2407 (or
2400 (func
2401 ('symbol', '_aliasarg')
2402 ('string', '$10'))
2408 ('_aliasarg', '$10')
2403 2409 ('symbol', 'foobar'))
2404 2410 >>> print prettyformat(_parsealiasdefn('"$1" or "foo"', args))
2405 2411 (or
2406 2412 ('string', '$1')
2407 2413 ('string', 'foo'))
2408 2414 """
2409 def tokenizedefn(program, lookup=None):
2410 if args:
2411 argset = set(args)
2412 else:
2413 argset = set()
2414
2415 for t, value, pos in _tokenizealias(program, lookup=lookup):
2416 if t == 'symbol':
2417 if value in argset:
2418 # emulate tokenization of "_aliasarg('ARGNAME')":
2419 # "_aliasarg()" is an unknown symbol only used separate
2420 # alias argument placeholders from regular strings.
2421 yield ('symbol', '_aliasarg', pos)
2422 yield ('(', None, pos)
2423 yield ('string', value, pos)
2424 yield (')', None, pos)
2425 continue
2426 elif value.startswith('$'):
2427 raise error.ParseError(_("'$' not for alias arguments"),
2428 pos)
2429 yield (t, value, pos)
2415 if args:
2416 args = set(args)
2417 else:
2418 args = set()
2430 2419
2431 2420 p = parser.parser(elements)
2432 tree, pos = p.parse(tokenizedefn(defn))
2421 tree, pos = p.parse(_tokenizealias(defn))
2433 2422 if pos != len(defn):
2434 2423 raise error.ParseError(_('invalid token'), pos)
2435 return parser.simplifyinfixops(tree, ('list', 'or'))
2424 tree = parser.simplifyinfixops(tree, ('list', 'or'))
2425 return _relabelaliasargs(tree, args)
2436 2426
2437 2427 class revsetalias(object):
2438 2428 # whether own `error` information is already shown or not.
@@ -2523,7 +2513,6 b' def _expandaliases(aliases, tree, expand'
2523 2513 return result
2524 2514
2525 2515 def findaliases(ui, tree, showwarning=None):
2526 _checkaliasarg(tree)
2527 2516 aliases = {}
2528 2517 for k, v in ui.configitems('revsetalias'):
2529 2518 alias = revsetalias(k, v)
@@ -1820,25 +1820,12 b" but 'all()' should never be substituded "
1820 1820 <spanset+ 0:9>>
1821 1821 0
1822 1822
1823 $ echo 'injectparamasstring2 = max(_aliasarg("$1"))' >> .hg/hgrc
1824 $ echo 'callinjection2($1) = descendants(injectparamasstring2)' >> .hg/hgrc
1825 $ try 'callinjection2(2:5)'
1826 (func
1827 ('symbol', 'callinjection2')
1828 (range
1829 ('symbol', '2')
1830 ('symbol', '5')))
1831 abort: failed to parse the definition of revset alias "injectparamasstring2": unknown identifier: _aliasarg
1832 [255]
1833 1823 $ hg debugrevspec --debug --config revsetalias.anotherbadone='branch(' "tip"
1834 1824 ('symbol', 'tip')
1835 1825 warning: failed to parse the definition of revset alias "anotherbadone": at 7: not a prefix: end
1836 warning: failed to parse the definition of revset alias "injectparamasstring2": unknown identifier: _aliasarg
1837 1826 * set:
1838 1827 <baseset [9]>
1839 1828 9
1840 >>> data = file('.hg/hgrc', 'rb').read()
1841 >>> file('.hg/hgrc', 'wb').write(data.replace('_aliasarg', ''))
1842 1829
1843 1830 $ try 'tip'
1844 1831 ('symbol', 'tip')
General Comments 0
You need to be logged in to leave comments. Login now