comparison mercurial/revset.py @ 14723:b9faf94ee196 stable

revset: fix aliases with 0 or more than 2 parameters The existing code seemed to have incorrect assumptions about how parameter lists are represented by the parser. Now the match and replace functions have been merged and simplified by using getlist().
author Mads Kiilerich <mads@kiilerich.com>
date Wed, 22 Jun 2011 01:55:00 +0200
parents c8ee2729e89f
children 805651777188
comparison
equal deleted inserted replaced
14722:b6dc362b051c 14723:b9faf94ee196
952 return w + wa, (op, x[1], ta) 952 return w + wa, (op, x[1], ta)
953 return 1, x 953 return 1, x
954 954
955 class revsetalias(object): 955 class revsetalias(object):
956 funcre = re.compile('^([^(]+)\(([^)]+)\)$') 956 funcre = re.compile('^([^(]+)\(([^)]+)\)$')
957 args = () 957 args = None
958 958
959 def __init__(self, token, value): 959 def __init__(self, name, value):
960 '''Aliases like: 960 '''Aliases like:
961 961
962 h = heads(default) 962 h = heads(default)
963 b($1) = ancestors($1) - ancestors(default) 963 b($1) = ancestors($1) - ancestors(default)
964 ''' 964 '''
965 if isinstance(token, tuple): 965 if isinstance(name, tuple): # parameter substitution
966 self.type, self.name = token 966 self.tree = name
967 else: 967 self.replacement = value
968 m = self.funcre.search(token) 968 else: # alias definition
969 m = self.funcre.search(name)
969 if m: 970 if m:
970 self.type = 'func' 971 self.tree = ('func', ('symbol', m.group(1)))
971 self.name = m.group(1)
972 self.args = [x.strip() for x in m.group(2).split(',')] 972 self.args = [x.strip() for x in m.group(2).split(',')]
973 for arg in self.args:
974 value = value.replace(arg, repr(arg))
973 else: 975 else:
974 self.type = 'symbol' 976 self.tree = ('symbol', name)
975 self.name = token 977
976
977 if isinstance(value, str):
978 for arg in self.args:
979 value = value.replace(arg, repr(arg))
980 self.replacement, pos = parse(value) 978 self.replacement, pos = parse(value)
981 if pos != len(value): 979 if pos != len(value):
982 raise error.ParseError(_('invalid token'), pos) 980 raise error.ParseError(_('invalid token'), pos)
983 else:
984 self.replacement = value
985
986 def match(self, tree):
987 if not tree:
988 return False
989 if tree == (self.type, self.name):
990 return True
991 if tree[0] != self.type:
992 return False
993 if len(tree) > 1 and tree[1] != ('symbol', self.name):
994 return False
995 # 'func' + funcname + args
996 if ((self.args and len(tree) != 3) or
997 (len(self.args) == 1 and tree[2][0] == 'list') or
998 (len(self.args) > 1 and (tree[2][0] != 'list' or
999 len(tree[2]) - 1 != len(self.args)))):
1000 raise error.ParseError(_('invalid amount of arguments'),
1001 len(tree) - 2)
1002 return True
1003
1004 def replace(self, tree):
1005 if tree == (self.type, self.name):
1006 return self.replacement
1007 result = self.replacement
1008 def getsubtree(i):
1009 if tree[2][0] == 'list':
1010 return tree[2][i + 1]
1011 return tree[i + 2]
1012 for i, v in enumerate(self.args):
1013 valalias = revsetalias(('string', v), getsubtree(i))
1014 result = valalias.process(result)
1015 return result
1016 981
1017 def process(self, tree): 982 def process(self, tree):
1018 if self.match(tree):
1019 return self.replace(tree)
1020 if isinstance(tree, tuple): 983 if isinstance(tree, tuple):
984 if self.args is None:
985 if tree == self.tree:
986 return self.replacement
987 elif tree[:2] == self.tree:
988 l = getlist(tree[2])
989 if len(l) != len(self.args):
990 raise error.ParseError(
991 _('invalid number of arguments: %s') % len(l))
992 result = self.replacement
993 for a, v in zip(self.args, l):
994 valalias = revsetalias(('string', a), v)
995 result = valalias.process(result)
996 return result
1021 return tuple(map(self.process, tree)) 997 return tuple(map(self.process, tree))
1022 return tree 998 return tree
1023 999
1024 def findaliases(ui, tree): 1000 def findaliases(ui, tree):
1025 for k, v in ui.configitems('revsetalias'): 1001 for k, v in ui.configitems('revsetalias'):