323 ... _trygetfunc = staticmethod(trygetfunc) |
323 ... _trygetfunc = staticmethod(trygetfunc) |
324 >>> builddecl = aliasrules._builddecl |
324 >>> builddecl = aliasrules._builddecl |
325 >>> builddecl('foo') |
325 >>> builddecl('foo') |
326 ('foo', None, None) |
326 ('foo', None, None) |
327 >>> builddecl('$foo') |
327 >>> builddecl('$foo') |
328 ('$foo', None, "'$' not for alias arguments") |
328 ('$foo', None, "invalid symbol '$foo'") |
329 >>> builddecl('foo::bar') |
329 >>> builddecl('foo::bar') |
330 ('foo::bar', None, 'invalid format') |
330 ('foo::bar', None, 'invalid format') |
331 >>> builddecl('foo()') |
331 >>> builddecl('foo()') |
332 ('foo', [], None) |
332 ('foo', [], None) |
333 >>> builddecl('$foo()') |
333 >>> builddecl('$foo()') |
334 ('$foo()', None, "'$' not for alias arguments") |
334 ('$foo()', None, "invalid function '$foo'") |
335 >>> builddecl('foo($1, $2)') |
335 >>> builddecl('foo($1, $2)') |
336 ('foo', ['$1', '$2'], None) |
336 ('foo', ['$1', '$2'], None) |
337 >>> builddecl('foo(bar_bar, baz.baz)') |
337 >>> builddecl('foo(bar_bar, baz.baz)') |
338 ('foo', ['bar_bar', 'baz.baz'], None) |
338 ('foo', ['bar_bar', 'baz.baz'], None) |
339 >>> builddecl('foo($1, $2, nested($1, $2))') |
339 >>> builddecl('foo($1, $2, nested($1, $2))') |
356 |
356 |
357 if tree[0] == cls._symbolnode: |
357 if tree[0] == cls._symbolnode: |
358 # "name = ...." style |
358 # "name = ...." style |
359 name = tree[1] |
359 name = tree[1] |
360 if name.startswith('$'): |
360 if name.startswith('$'): |
361 return (decl, None, _("'$' not for alias arguments")) |
361 return (decl, None, _("invalid symbol '%s'") % name) |
362 return (name, None, None) |
362 return (name, None, None) |
363 |
363 |
364 func = cls._trygetfunc(tree) |
364 func = cls._trygetfunc(tree) |
365 if func: |
365 if func: |
366 # "name(arg, ....) = ...." style |
366 # "name(arg, ....) = ...." style |
367 name, args = func |
367 name, args = func |
368 if name.startswith('$'): |
368 if name.startswith('$'): |
369 return (decl, None, _("'$' not for alias arguments")) |
369 return (decl, None, _("invalid function '%s'") % name) |
370 if any(t[0] != cls._symbolnode for t in args): |
370 if any(t[0] != cls._symbolnode for t in args): |
371 return (decl, None, _("invalid argument list")) |
371 return (decl, None, _("invalid argument list")) |
372 if len(args) != len(set(args)): |
372 if len(args) != len(set(args)): |
373 return (name, None, _("argument names collide with each other")) |
373 return (name, None, _("argument names collide with each other")) |
374 return (name, [t[1] for t in args], None) |
374 return (name, [t[1] for t in args], None) |
387 assert len(tree) == 2 |
387 assert len(tree) == 2 |
388 sym = tree[1] |
388 sym = tree[1] |
389 if sym in args: |
389 if sym in args: |
390 op = '_aliasarg' |
390 op = '_aliasarg' |
391 elif sym.startswith('$'): |
391 elif sym.startswith('$'): |
392 raise error.ParseError(_("'$' not for alias arguments")) |
392 raise error.ParseError(_("invalid symbol '%s'") % sym) |
393 return (op, sym) |
393 return (op, sym) |
394 |
394 |
395 @classmethod |
395 @classmethod |
396 def _builddefn(cls, defn, args): |
396 def _builddefn(cls, defn, args): |
397 """Parse an alias definition into a tree and marks substitutions |
397 """Parse an alias definition into a tree and marks substitutions |
421 ('_aliasarg', 'foo')) |
421 ('_aliasarg', 'foo')) |
422 >>> try: |
422 >>> try: |
423 ... builddefn('$1 or $bar', args) |
423 ... builddefn('$1 or $bar', args) |
424 ... except error.ParseError as inst: |
424 ... except error.ParseError as inst: |
425 ... print parseerrordetail(inst) |
425 ... print parseerrordetail(inst) |
426 '$' not for alias arguments |
426 invalid symbol '$bar' |
427 >>> args = ['$1', '$10', 'foo'] |
427 >>> args = ['$1', '$10', 'foo'] |
428 >>> pprint(builddefn('$10 or baz', args)) |
428 >>> pprint(builddefn('$10 or baz', args)) |
429 (or |
429 (or |
430 ('_aliasarg', '$10') |
430 ('_aliasarg', '$10') |
431 ('symbol', 'baz')) |
431 ('symbol', 'baz')) |