phase3: stabilize nullfix.py (disable risky local-nullable handler)
Script stable handlers (zero corruption): bang(!), late, param-nullable, field-formal field-nullable, arg-bang. Reusable — re-run after manual fixes. Errors: 2374(peak) -> 596 | web build: 1845 -> 571
This commit is contained in:
@@ -11,7 +11,7 @@ class Blog extends StatelessWidget {
|
||||
final Key? key;
|
||||
final int businessId;
|
||||
|
||||
const Blog({this.key, int businessId}) :
|
||||
const Blog({this.key, int? businessId}) :
|
||||
businessId = businessId ?? Constants.BUSINESS_ID;
|
||||
|
||||
@override
|
||||
|
||||
@@ -16,7 +16,7 @@ class EditAddress extends StatelessWidget {
|
||||
final Key? key;
|
||||
final Address address;
|
||||
final int businessId;
|
||||
const EditAddress(this.address, {this.key, int businessId}) :
|
||||
const EditAddress(this.address, {this.key, int? businessId}) :
|
||||
businessId = businessId ?? Constants.BUSINESS_ID;
|
||||
|
||||
@override
|
||||
|
||||
@@ -11,7 +11,7 @@ class MyAddresses extends StatelessWidget {
|
||||
final Key? key;
|
||||
final int businessId;
|
||||
|
||||
const MyAddresses({this.key, int businessId}) :
|
||||
const MyAddresses({this.key, int? businessId}) :
|
||||
businessId = businessId ?? Constants.BUSINESS_ID;
|
||||
|
||||
@override
|
||||
|
||||
@@ -11,7 +11,7 @@ class MySupport extends StatelessWidget {
|
||||
final Key? key;
|
||||
final int businessId;
|
||||
|
||||
const MySupport({this.key, int businessId}) :
|
||||
const MySupport({this.key, int? businessId}) :
|
||||
businessId = businessId ?? Constants.BUSINESS_ID;
|
||||
|
||||
@override
|
||||
|
||||
@@ -17,7 +17,7 @@ class NewTicket extends StatefulWidget {
|
||||
final Key? key;
|
||||
final int businessId;
|
||||
|
||||
const NewTicket({this.key, int businessId}) :
|
||||
const NewTicket({this.key, int? businessId}) :
|
||||
businessId = businessId ?? Constants.BUSINESS_ID;
|
||||
|
||||
@override
|
||||
|
||||
@@ -23,7 +23,7 @@ class DesktopEditAddress extends StatefulWidget {
|
||||
final Key? key;
|
||||
final Address address;
|
||||
final int businessId;
|
||||
const DesktopEditAddress(this.address, {this.key, int businessId}) :
|
||||
const DesktopEditAddress(this.address, {this.key, int? businessId}) :
|
||||
businessId = businessId ?? Constants.BUSINESS_ID;
|
||||
|
||||
@override
|
||||
|
||||
@@ -21,7 +21,7 @@ class DesktopNewTicket extends StatefulWidget {
|
||||
final Key? key;
|
||||
final int businessId;
|
||||
|
||||
const DesktopNewTicket({this.key, int businessId}) :
|
||||
const DesktopNewTicket({this.key, int? businessId}) :
|
||||
businessId = businessId ?? Constants.BUSINESS_ID;
|
||||
|
||||
@override
|
||||
|
||||
@@ -21,7 +21,7 @@ class MobileEditAddress extends StatefulWidget {
|
||||
final Key? key;
|
||||
final Address address;
|
||||
final int businessId;
|
||||
const MobileEditAddress(this.address, {this.key, int businessId}) :
|
||||
const MobileEditAddress(this.address, {this.key, int? businessId}) :
|
||||
businessId = businessId ?? Constants.BUSINESS_ID;
|
||||
|
||||
@override
|
||||
|
||||
@@ -20,7 +20,7 @@ class MobileNewTicket extends StatefulWidget {
|
||||
final Key? key;
|
||||
final int businessId;
|
||||
|
||||
const MobileNewTicket({this.key, int businessId}) :
|
||||
const MobileNewTicket({this.key, int? businessId}) :
|
||||
businessId = businessId ?? Constants.BUSINESS_ID;
|
||||
|
||||
@override
|
||||
|
||||
@@ -33,9 +33,7 @@ PROP = re.compile(r"The property '([^']+)'")
|
||||
METH = re.compile(r"The method '([^']+)'")
|
||||
OPR = re.compile(r"The operator '([^']+)'")
|
||||
NAME = re.compile(r"'([^']+)'")
|
||||
KEYWORDS = {'return','throw','await','yield','break','continue','assert','new','const',
|
||||
'final','var','late','switch','case','default','if','else','for','while',
|
||||
'do','try','catch','finally','in','is','as','super','this'}
|
||||
KEYWORDS = {'return','throw','yield','await','break','continue'}
|
||||
|
||||
def analyze():
|
||||
out = subprocess.run(['dart','analyze','lib'], capture_output=True, text=True).stdout
|
||||
@@ -101,6 +99,19 @@ def insert_bang(line, col0, name, kind):
|
||||
return None
|
||||
return None
|
||||
|
||||
def make_local_nullable(lines, name, upto_line):
|
||||
"""从 upto_line 向上找局部变量声明 'Type name;' 并改可空。"""
|
||||
pat = re.compile(r'^(\s+)(final\s+|const\s+)?(static\s+)?([\w<>?,\s\.]+?)\s+'+re.escape(name)+r'\s*;\s*$')
|
||||
for i in range(upto_line-1, -1, -1):
|
||||
L=lines[i]
|
||||
m=pat.match(L)
|
||||
if not m: continue
|
||||
indent, fmod, smod, typ = m.groups()
|
||||
if typ in ('var',) or '?' in typ or '=' in L: continue
|
||||
return i, f"{indent}{fmod or ''}{smod or ''}{typ}? {name};"
|
||||
break
|
||||
return None, None
|
||||
|
||||
def insert_arg_bang(line, col0):
|
||||
"""在参数值末尾插 '!'(仅限简单值:标识符/成员/调用/下标)。"""
|
||||
depth=0; end=None
|
||||
@@ -195,6 +206,15 @@ def apply_round(errs):
|
||||
new=insert_late(old)
|
||||
elif rule in ('argument_type_not_assignable','invalid_assignment'):
|
||||
new=insert_arg_bang(old, col-1)
|
||||
# not_assigned_potentially_non_nullable_local_variable 不自动处理
|
||||
# (make_local_nullable 易误改 return/throw 语句,风险高,留 IDE)
|
||||
elif False and rule=='not_assigned_potentially_non_nullable_local_variable':
|
||||
nm=NAME.search(msg)
|
||||
if nm:
|
||||
fl=get(path)
|
||||
fi, fnew = make_local_nullable(fl, nm.group(1), line)
|
||||
if fi is not None and fl[fi]!=fnew:
|
||||
fl[fi]=fnew; changed+=1
|
||||
if new and new!=old:
|
||||
L[line-1]=new; changed+=1
|
||||
flush()
|
||||
|
||||
Reference in New Issue
Block a user