105 lines
3.7 KiB
Python
105 lines
3.7 KiB
Python
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<void> 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|IntaleqMapController)\??\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()
|