# HG changeset patch # User Yuya Nishihara # Date 2016-08-21 04:16:21 # Node ID 45bf56a891970b3975f45984a34683bc04e19360 # Parent 429fd2747d9a8d819f1aa9d54dcd637434ac0940 debugrevspec: add option to verify optimized result This provides a convenient way to diff "hg debugrevspec" outputs generated with/without --no-optimized option. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -3516,6 +3516,7 @@ def debugrevlog(ui, repo, file_=None, ** ('p', 'show-stage', [], _('print parsed tree at the given stage'), _('NAME')), ('', 'no-optimized', False, _('evaluate tree without optimization')), + ('', 'verify-optimized', False, _('verify optimized result')), ], ('REVSPEC')) def debugrevspec(ui, repo, expr, **opts): @@ -3523,6 +3524,9 @@ def debugrevspec(ui, repo, expr, **opts) Use -p/--show-stage option to print the parsed tree at the given stages. Use -p all to print tree at every stage. + + Use --verify-optimized to compare the optimized result with the unoptimized + one. Returns 1 if the optimized result differs. """ stages = [ ('parsed', lambda tree: tree), @@ -3533,6 +3537,9 @@ def debugrevspec(ui, repo, expr, **opts) ] if opts['no_optimized']: stages = stages[:-1] + if opts['verify_optimized'] and opts['no_optimized']: + raise error.Abort(_('cannot use --verify-optimized with ' + '--no-optimized')) stagenames = set(n for n, f in stages) showalways = set() @@ -3553,16 +3560,42 @@ def debugrevspec(ui, repo, expr, **opts) raise error.Abort(_('invalid stage name: %s') % n) showalways.update(opts['show_stage']) + treebystage = {} printedtree = None tree = revset.parse(expr, lookup=repo.__contains__) for n, f in stages: - tree = f(tree) + treebystage[n] = tree = f(tree) if n in showalways or (n in showchanged and tree != printedtree): if opts['show_stage'] or n != 'parsed': ui.write(("* %s:\n") % n) ui.write(revset.prettyformat(tree), "\n") printedtree = tree + if opts['verify_optimized']: + arevs = revset.makematcher(treebystage['analyzed'])(repo) + brevs = revset.makematcher(treebystage['optimized'])(repo) + if ui.verbose: + ui.note(("* analyzed set:\n"), revset.prettyformatset(arevs), "\n") + ui.note(("* optimized set:\n"), revset.prettyformatset(brevs), "\n") + arevs = list(arevs) + brevs = list(brevs) + if arevs == brevs: + return 0 + ui.write(('--- analyzed\n'), label='diff.file_a') + ui.write(('+++ optimized\n'), label='diff.file_b') + sm = difflib.SequenceMatcher(None, arevs, brevs) + for tag, alo, ahi, blo, bhi in sm.get_opcodes(): + if tag in ('delete', 'replace'): + for c in arevs[alo:ahi]: + ui.write('-%s\n' % c, label='diff.deleted') + if tag in ('insert', 'replace'): + for c in brevs[blo:bhi]: + ui.write('+%s\n' % c, label='diff.inserted') + if tag == 'equal': + for c in arevs[alo:ahi]: + ui.write(' %s\n' % c) + return 1 + func = revset.makematcher(tree) revs = func(repo) if ui.verbose: diff --git a/tests/test-completion.t b/tests/test-completion.t --- a/tests/test-completion.t +++ b/tests/test-completion.t @@ -269,7 +269,7 @@ Show all commands + options debugrebuildfncache: debugrename: rev debugrevlog: changelog, manifest, dir, dump - debugrevspec: optimize, show-stage, no-optimized + debugrevspec: optimize, show-stage, no-optimized, verify-optimized debugsetparents: debugsub: rev debugsuccessorssets: diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -554,6 +554,37 @@ parsed tree at stages: abort: cannot use --optimize with --show-stage [255] +verify optimized tree: + + $ hg debugrevspec --verify '0|1' + + $ hg debugrevspec --verify -v -p analyzed -p optimized 'r3232() & 2' + * analyzed: + (and + (func + ('symbol', 'r3232') + None) + ('symbol', '2')) + * optimized: + (and + ('symbol', '2') + (func + ('symbol', 'r3232') + None)) + * analyzed set: + + * optimized set: + + --- analyzed + +++ optimized + 2 + +2 + [1] + + $ hg debugrevspec --no-optimized --verify-optimized '0' + abort: cannot use --verify-optimized with --no-optimized + [255] + Test that symbols only get parsed as functions if there's an opening parenthesis.