33Parses POCO entity classes with data annotations from C# source files
44into the internal schema representation.
55"""
6+
67from __future__ import annotations
78
89import contextlib
1415# Regex: extract class declaration and body
1516_CLASS_RE = re .compile (
1617 r'(?:\[Table\((?:"([^"]+)"|name:\s*"([^"]+)"(?:,\s*Schema\s*=\s*"([^"]+)")?)\)\])?\s*'
17- r' (?:public\s+)?(?:partial\s+)?class\s+(\w+)(?:\s*:\s*\w+)?\s*\{' ,
18+ r" (?:public\s+)?(?:partial\s+)?class\s+(\w+)(?:\s*:\s*\w+)?\s*\{" ,
1819 re .MULTILINE ,
1920)
2021
2122# Regex: extract property annotations (one annotation line per property)
22- _ANNOTATION_RE = re .compile (r' \[(\w+)(?:\(([^)]*)\))?\]' )
23+ _ANNOTATION_RE = re .compile (r" \[(\w+)(?:\(([^)]*)\))?\]" )
2324
2425# Regex: property declaration
2526_PROPERTY_RE = re .compile (
26- r' (?:public\s+)?'
27- r' (?P<type>[\w?<>[\]]+)\s+' # Type: string, int?, List<int>
28- r' (?P<name>\w+)\s*'
29- r' \{\s*get;\s*set;\s*\}'
30- r' (?:\s*=\s*[^;]+;)?' # Optional default
27+ r" (?:public\s+)?"
28+ r" (?P<type>[\w?<>[\]]+)\s+" # Type: string, int?, List<int>
29+ r" (?P<name>\w+)\s*"
30+ r" \{\s*get;\s*set;\s*\}"
31+ r" (?:\s*=\s*[^;]+;)?" # Optional default
3132)
3233
3334# Map C# types to ColumnType
@@ -122,9 +123,7 @@ def parse(self, text: str) -> Schema:
122123 # Collect annotation lines
123124 if stripped .startswith ("[" ):
124125 for ann in _ANNOTATION_RE .finditer (stripped ):
125- current_annotations .append (
126- (ann .group (1 ), ann .group (2 ) or "" )
127- )
126+ current_annotations .append ((ann .group (1 ), ann .group (2 ) or "" ))
128127 continue
129128
130129 # Skip non-property lines
@@ -136,9 +135,7 @@ def parse(self, text: str) -> Schema:
136135 cs_type = prop_m .group ("type" )
137136 prop_name = prop_m .group ("name" )
138137
139- col = self ._property_to_column (
140- prop_name , cs_type , current_annotations
141- )
138+ col = self ._property_to_column (prop_name , cs_type , current_annotations )
142139 if col :
143140 table .columns .append (col )
144141
@@ -187,7 +184,9 @@ def _property_to_column(
187184 if ann_args and "=" not in ann_args :
188185 pass # Column name override — skip for now
189186 elif ann_name == "Index" :
190- is_unique = "Unique" in ann_args or "IsUnique=true" in ann_args .replace (" " , "" )
187+ is_unique = "Unique" in ann_args or "IsUnique=true" in ann_args .replace (
188+ " " , ""
189+ )
191190 elif ann_name == "Table" :
192191 pass # Already handled at class level
193192
0 commit comments