import sys import re def parse_stream(stream_text): # Splits the stream by our custom file delimiters files = {} parts = re.split(r'=== FILE: (.*?) ===\n', stream_text) # The first part is the original monolithic file if parts: files['original'] = parts[0] for i in range(1, len(parts), 2): filename = parts[i] content = parts[i+1] if i+1 < len(parts) else "" files[filename] = content return files def strip_comments(text): text = re.sub(r'/\*.*?\*/', '', text, flags=re.DOTALL) text = re.sub(r'//.*', '', text) return text def extract_declarations(text): clean = strip_comments(text) # Matches method/function declarations inside a class in Dart # e.g., void myMethod(..., Future myMethod(..., myMethod(..., get myProp, set myProp # We look for word followed by ( or get/set followed by word. method_decl_pattern = re.compile( r'(?:[a-zA-Z0-9_<>\?\[\]]+(?:\s+[a-zA-Z0-9_<>\?\[\]]+)*\s+)?([a-zA-Z0-9_]+)\s*\([^\)]*\)\s*(?:async)?\s*(?:=>|\{)' ) methods = set() for match in method_decl_pattern.finditer(clean): method_name = match.group(1) if method_name not in keywords and not method_name.isdigit(): methods.add(method_name) # Also extract getters and setters getset_pattern = re.compile(r'\b(?:get|set)\s+([a-zA-Z0-9_]+)\b') for match in getset_pattern.finditer(clean): name = match.group(1) if name not in keywords: methods.add(name) # Extract variables/fields declarations var_decl_pattern = re.compile( r'\b(?:var|final|const|late|RxBool|RxInt|RxDouble|RxString|RxList|RxMap|RxSet|Rx|String|int|double|bool|List|Map|Set|Timer|LatLng|Position|SiroMapController)\??\s+([a-zA-Z0-9_]+)\b' ) variables = set() for match in var_decl_pattern.finditer(clean): var_name = match.group(1) if var_name not in keywords and not var_name.isdigit(): variables.add(var_name) return methods, variables keywords = { 'if', 'for', 'while', 'switch', 'catch', 'super', 'await', 'print', 'assert', 'dynamic', 'void', 'return', 'with', 'override', 'get', 'set', 'class', 'import', 'extends', 'implements', 'mixin', 'this', 'else', 'try', 'final', 'const', 'var', 'late', 'static', 'factory', 'new', 'abstract', 'covariant', 'external', 'operator', 'part', 'required', 'typedef', 'yield' } def main(): stream_text = sys.stdin.read() files = parse_stream(stream_text) orig_content = files.get('original', '') split_contents = {k: v for k, v in files.items() if k != 'original'} orig_methods, orig_vars = extract_declarations(orig_content) # Combined declarations in split files split_methods = set() split_vars = set() for filename, content in split_contents.items(): m, v = extract_declarations(content) split_methods.update(m) split_vars.update(v) missing_methods = sorted(orig_methods - split_methods) missing_vars = sorted(orig_vars - split_vars) print("--- PRECISE MISSING METHODS ---") print(f"Total original methods/getters/setters: {len(orig_methods)}") print(f"Total defined in split controllers: {len(split_methods)}") print(f"Total missing: {len(missing_methods)}") for m in missing_methods: print(f" - {m}") print("\n--- PRECISE MISSING VARIABLES/FIELDS ---") print(f"Total original variables: {len(orig_vars)}") print(f"Total defined in split controllers: {len(split_vars)}") print(f"Total missing: {len(missing_vars)}") for v in missing_vars: print(f" - {v}") if __name__ == '__main__': main()