#!/usr/bin/env python3 from __future__ import print_function import os.path import sys import re import glob import io from collections import defaultdict # keyed on unique type, values are lists of (unique, name) pairs def find_uniques(source_files): uniques = defaultdict(lambda: defaultdict(lambda: set())) unique_re = re.compile(r"([\w\d]+)\s*=\s*mk([\w\d']+)Unique\s+(\d+)") for f in source_files: ms = unique_re.findall(io.open(f, encoding='utf8').read()) for m in ms: name = m[0] _type = m[1] n = int(m[2]) uniques[_type][n].add(name) return uniques def print_all(uniques): for _type, uniqs in uniques.items(): print('{_type} uniques'.format(**locals())) for n,names in uniqs.items(): all_names = ', '.join(names) print(' {n} = {all_names}'.format(**locals())) def find_conflicts(uniques): return [ (uniqueType, number, names) for uniqueType, uniqs in uniques.items() for number, names in uniqs.items() if len(names) > 1 ] top_dir = sys.argv[1] uniques = find_uniques(glob.glob(os.path.join(top_dir, 'compiler', 'prelude', '*.hs'))) #print_all(uniques) conflicts = find_conflicts(uniques) if len(conflicts) > 0: print("Error: check-uniques: Found Unique conflict") print() for (ty, n, names) in conflicts: print(' %s unique %d conflict: %s' % (ty, n, ', '.join(names))) print() sys.exit(1)