phase3: nullfix.py batch script — bang/late/param-nullable

Automated null-safety fixes driven by dart analyze (no corruption):
- unchecked_use_of_nullable_value: insert '!' on receiver (property/method/[]/op)
- not_initialized field/var: mark 'late'
- missing_default_value_for_parameter: nullable param
Errors: 2374(peak) -> 907
This commit is contained in:
2026-07-25 18:13:01 +08:00
parent 8f3d3509ea
commit fce670664b
99 changed files with 1013 additions and 838 deletions

View File

@@ -45,17 +45,17 @@ class MobileCheckout extends StatefulWidget {
}
class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin {
CartInfo cartInfo;
Address shipAddress;
bool canSubmit;
List<ErrorMessage> errorMessages;
List<BookingTime> bookingTimeList;
List<BookingDateTime> bookingDateTimeList;
List<PaymentPlatform> paymentPlatforms;
TextValue durationInTraffic;
int selectedCoupon;
late CartInfo cartInfo;
late Address shipAddress;
late bool canSubmit;
late List<ErrorMessage> errorMessages;
late List<BookingTime> bookingTimeList;
late List<BookingDateTime> bookingDateTimeList;
late List<PaymentPlatform> paymentPlatforms;
late TextValue durationInTraffic;
late int selectedCoupon;
double couponDiscountAmount = 0;
List<Coupon> coupons;
late List<Coupon> coupons;
int peopleCount = 2;
@@ -63,25 +63,25 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
String orderRemark = '';
int deliveryMethodIndex = 0;
String deliveryMethod;
late String deliveryMethod;
List<ShippingRate> shippingRates = [];
ShippingRate selectedShippingRate;
late ShippingRate selectedShippingRate;
List<String> shippingMethodLabels = [];
List<IconData> shippingMethodIcons = [];
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
int bookingDateIndex;
int bookingTimeIndex;
int paymentPlatformIndex;
late int bookingDateIndex;
late int bookingTimeIndex;
late int paymentPlatformIndex;
GlobalKey slidingUpPanelKey = GlobalKey();
SlidingUpPanel slidingUpPanel;
late SlidingUpPanel slidingUpPanel;
PanelController panelController = PanelController();
Widget panel;
late Widget panel;
double subtotal;
late double subtotal;
TextEditingController newCouponController = TextEditingController();
@@ -102,7 +102,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
);
}
if (cartInfo.businessInfo.deliveryPickup == false && cartInfo.businessInfo.deliveryCanadaPost == false && cartInfo.businessInfo.deliveryStoreDelivery == false) {
if (cartInfo.businessInfo!.deliveryPickup == false && cartInfo.businessInfo!.deliveryCanadaPost == false && cartInfo.businessInfo!.deliveryStoreDelivery == false) {
return Scaffold(
body: Container(
child: Center(
@@ -197,13 +197,13 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'\$${(cartInfo.totalPrice - couponDiscountAmount).toStringAsFixed(2)}',
'\$${(cartInfo.totalPrice! - couponDiscountAmount).toStringAsFixed(2)}',
style: TextStyle(
fontSize: 20.0,
color: Colors.white,
),
),
cartInfo.businessInfo.isPublic ? SizedBox.shrink() : Container(
cartInfo.businessInfo!.isPublic ? SizedBox.shrink() : Container(
padding: EdgeInsets.only(top: 2.0, bottom: 2.0, left: 5.0, right: 5.0),
width: 100.0,
color: Colors.red,
@@ -267,7 +267,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
itemCount: 6,
addAutomaticKeepAlives: true,
itemBuilder: (BuildContext context, int position) {
var deliveryTimeInSeconds = cartInfo.businessInfo.shippingTime * 60 + (durationInTraffic != null ? durationInTraffic.value : 0);
var deliveryTimeInSeconds = cartInfo.businessInfo!.shippingTime! * 60 + (durationInTraffic != null ? durationInTraffic.value : 0);
print('aaa: $deliveryTimeInSeconds');
DateTime now = DateTime.now();
var formatter = DateFormat('H:mm');
@@ -341,7 +341,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
);
switch (position) {
case 0:
if (cartInfo.businessInfo.deliveryPickup) {
if (cartInfo.businessInfo!.deliveryPickup) {
return Container(
padding: EdgeInsets.only(
top: 16.0, bottom: 16.0, left: 16.0, right: 16.0),
@@ -355,8 +355,8 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
),
child: Container(
alignment: Alignment.centerLeft,
child: store.state.deviceId != null && store.state.deviceId.isNotEmpty ? (
store.state.tableNumber != null && store.state.tableNumber.isNotEmpty ?
child: store.state.deviceId != null && store.state.deviceId!.isNotEmpty ? (
store.state.tableNumber != null && store.state.tableNumber!.isNotEmpty ?
peopleCountSelection :
SizedBox.shrink()
) : Center(child: toggleSwitch,),
@@ -369,8 +369,8 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
}
break;
case 1:
if (store.state.deviceId != null && store.state.deviceId.isNotEmpty ||
store.state.tableNumber != null && store.state.tableNumber.isNotEmpty) {
if (store.state.deviceId != null && store.state.deviceId!.isNotEmpty ||
store.state.tableNumber != null && store.state.tableNumber!.isNotEmpty) {
return SizedBox.shrink();
}
if (deliveryMethod == 'pickup') {
@@ -389,7 +389,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
Container(
margin: EdgeInsets.only(top: 10.0),
child: Text(
cartInfo.businessInfo.name,
cartInfo.businessInfo!.name,
style: TextStyle(
fontSize: 17.0,
),
@@ -398,7 +398,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
Container(
margin: EdgeInsets.only(top: 5.0),
child: Text(
cartInfo.businessInfo.address.addressLine1,
cartInfo.businessInfo!.address!.addressLine1,
style: TextStyle(
fontSize: 14.0,
color: Colors.black45,
@@ -406,9 +406,9 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
),
),
Container(
child: cartInfo.businessInfo.address.addressLine2 != null
&& cartInfo.businessInfo.address.addressLine2.length > 0 ?
Text(cartInfo.businessInfo.address.addressLine2,
child: cartInfo.businessInfo!.address!.addressLine2 != null
&& cartInfo.businessInfo!.address!.addressLine2!.length > 0 ?
Text(cartInfo.businessInfo!.address!.addressLine2,
style: TextStyle(
fontSize: 14.0,
color: Colors.black45,
@@ -417,7 +417,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
),
Container(
child: Text(
'${cartInfo.businessInfo.address.city}, ${cartInfo.businessInfo.address.state}, ${cartInfo.businessInfo.address.zip}',
'${cartInfo.businessInfo!.address!.city}, ${cartInfo.businessInfo!.address!.state}, ${cartInfo.businessInfo!.address!.zip}',
style: TextStyle(
fontSize: 14.0,
color: Colors.black45,
@@ -427,7 +427,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
Container(
margin: EdgeInsets.only(top: 5.0),
child: Text(
'Tel: ${cartInfo.businessInfo.phone}',
'Tel: ${cartInfo.businessInfo!.phone}',
style: TextStyle(
fontSize: 15.0,
color: Colors.black54,
@@ -480,7 +480,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
Container(
padding: EdgeInsets.only(top: 6.0),
child: Text(
shipAddress != null ? shipAddress.contactName + ' ' + shipAddress.phone : '',
shipAddress != null ? shipAddress.contactName! + ' ' + shipAddress.phone : '',
style: TextStyle(
fontSize: 14.0,
color: Colors.black38,
@@ -504,13 +504,13 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
),
),
onTap: () {
Routes.router.navigateTo(context, '/my-addresses/${cartInfo.businessInfo.id}', replace: true);
Routes.router.navigateTo(context, '/my-addresses/${cartInfo.businessInfo!.id}', replace: true);
},
);
break;
case 2:
if (deliveryMethod == 'pickup' || store.state.deviceId != null && store.state.deviceId.isNotEmpty ||
store.state.tableNumber != null && store.state.tableNumber.isNotEmpty) {
if (deliveryMethod == 'pickup' || store.state.deviceId != null && store.state.deviceId!.isNotEmpty ||
store.state.tableNumber != null && store.state.tableNumber!.isNotEmpty) {
return SizedBox.shrink();
}
if (deliveryMethod == 'canada-post') {
@@ -553,7 +553,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
alignment: Alignment.centerRight,
child: Text(
selectedShippingRate != null ?
'${selectedShippingRate.name} \$${selectedShippingRate.price.toStringAsFixed(2)}' :
'${selectedShippingRate.name} \$${selectedShippingRate.price!.toStringAsFixed(2)}' :
S.of(context).please_select,
style: TextStyle(
fontSize: 15.0,
@@ -583,7 +583,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
},
);
}
if (!cartInfo.businessInfo.instanceDelivery) {
if (!cartInfo.businessInfo!.instanceDelivery) {
return Container(
padding: EdgeInsets.only(left: 16.0, right: 16.0, top: 0.0, bottom: 16.0),
child: Text(S.of(context).no_instance_delivery_desc),
@@ -629,7 +629,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
child: Text(
bookingTimeList.length > 0 ? '${Utils.timestampToString(context, bookingTimeList[bookingTimeIndex].unixTime)}'
: ((bookingTimeList.length == 0 && bookingDateTimeList.length == 0) ? ''
: bookingDateTimeList[bookingDateIndex].viewDate + ' ' + (bookingDateTimeList[bookingDateIndex].bookTimes.length > 0 ? bookingDateTimeList[bookingDateIndex].bookTimes[bookingTimeIndex].viewTime : '')),
: bookingDateTimeList[bookingDateIndex].viewDate! + ' ' + (bookingDateTimeList[bookingDateIndex].bookTimes!.length > 0 ? bookingDateTimeList[bookingDateIndex].bookTimes![bookingTimeIndex].viewTime : '')),
),
),
Container(
@@ -712,7 +712,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
width: double.infinity,
padding: EdgeInsets.only(bottom: 10.0),
child: Text(
cartInfo.businessInfo.name,
cartInfo.businessInfo!.name,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 16.0,
@@ -731,9 +731,9 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
subtotal = 0.0;
for (var i = 0; i < cartInfo.productList.length; i++) {
subtotal += cartInfo.productList[i].totalPrice;
column.children.add(lineItem(cartInfo.productList[i]));
for (var i = 0; i < cartInfo.productList!.length; i++) {
subtotal += cartInfo.productList![i].totalPrice;
column.children.add(lineItem(cartInfo.productList![i]));
}
column.children.add(GestureDetector(
child: Container(
@@ -826,8 +826,8 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
),
));
if (cartInfo.extraFeeList.length > 0) {
for (var i = 0; i < cartInfo.extraFeeList.length; i++) {
if (cartInfo.extraFeeList!.length > 0) {
for (var i = 0; i < cartInfo.extraFeeList!.length; i++) {
column.children.add(Container(
padding: EdgeInsets.only(bottom: 16.0),
alignment: Alignment.centerRight,
@@ -838,7 +838,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
Container(
alignment: Alignment.centerRight,
child: Text(
S.of(context).extra_fee_token(cartInfo.extraFeeList[i].name, cartInfo.extraFeeList[i].rate),
S.of(context).extra_fee_token(cartInfo.extraFeeList![i].name, cartInfo.extraFeeList![i].rate),
style: TextStyle(
color: Colors.grey,
),
@@ -848,7 +848,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
width: 100.0,
alignment: Alignment.centerRight,
child: Text(
'${cartInfo.extraFeeList[i].price.toStringAsFixed(2)}'
'${cartInfo.extraFeeList![i].price!.toStringAsFixed(2)}'
),
),
],
@@ -876,7 +876,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
width: 100.0,
alignment: Alignment.centerRight,
child: Text(
'${(cartInfo.totalPrice - couponDiscountAmount).toStringAsFixed(2)}',
'${(cartInfo.totalPrice! - couponDiscountAmount).toStringAsFixed(2)}',
style: TextStyle(
fontSize: 19.0,
fontWeight: FontWeight.bold,
@@ -974,7 +974,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
children: <Widget>[
Container(
padding: EdgeInsets.all(5.0),
child: Util.showImage('${cartLineItem.product.imagePath}',
child: Util.showImage('${cartLineItem.product!.imagePath}',
width: 40.0,
height: 40.0,
fit: BoxFit.fill,
@@ -1011,14 +1011,14 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
alignment: Alignment.centerRight,
margin: EdgeInsets.only(right: 10.0),
child: Text(
'x${cartLineItem.quantity.round()}',
'x${cartLineItem.quantity!.round()}',
),
),
Container(
width: 60.0,
alignment: Alignment.centerRight,
child: Text(
'${cartLineItem.totalPrice.toStringAsFixed(2)}',
'${cartLineItem.totalPrice!.toStringAsFixed(2)}',
),
),
],
@@ -1074,7 +1074,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
shippingRates = (response.data['shipping_rates'] as List).map((e) => ShippingRate.fromJson(e)).toList();
selectedShippingRate = (response.data['selected_shipping_rate'] as String).length > 0 ? ShippingRate.fromJson(json.decode(response.data['selected_shipping_rate'])) : null;
int i = 0;
if (cartInfo.businessInfo.deliveryStoreDelivery) {
if (cartInfo.businessInfo!.deliveryStoreDelivery) {
shippingMethodLabels.add(S.of(context).delivery);
shippingMethodIcons.add(Icons.directions_car);
if (deliveryMethod == 'store-delivery') {
@@ -1082,7 +1082,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
}
i++;
}
if (cartInfo.businessInfo.deliveryCanadaPost) {
if (cartInfo.businessInfo!.deliveryCanadaPost) {
shippingMethodLabels.add(S.of(context).canada_post);
shippingMethodIcons.add(Icons.local_shipping);
if (deliveryMethod == 'canada-post') {
@@ -1090,7 +1090,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
}
i++;
}
if (cartInfo.businessInfo.deliveryPickup) {
if (cartInfo.businessInfo!.deliveryPickup) {
shippingMethodLabels.add(S.of(context).pickup);
shippingMethodIcons.add(Icons.store);
if (deliveryMethod == 'pickup') {
@@ -1310,14 +1310,14 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
Expanded(
child: SizedBox.expand(
child: ListView.builder(
itemCount: bookingDateTimeList[bookingDateIndex].bookTimes.length,
itemCount: bookingDateTimeList[bookingDateIndex].bookTimes!.length,
itemBuilder: (BuildContext context, int position) {
BookingDateTime bookingDateTime = bookingDateTimeList[bookingDateIndex];
return GestureDetector(
child: Container(
padding: EdgeInsets.only(left: 12.0, right: 12.0, top: 12.0, bottom: 12.0),
child: Text(
bookingDateTime.bookTimes[position].viewTime,
bookingDateTime.bookTimes![position].viewTime,
),
decoration: BoxDecoration(
border: Border(
@@ -1442,16 +1442,16 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
itemBuilder: (BuildContext context, int position) {
PaymentPlatform paymentPlatform = paymentPlatforms[position];
if (paymentPlatform.code == Constants.PAYMENT_METHOD_CODE_SQUARE &&
(paymentPlatform.squareAppId == null || paymentPlatform.squareAppId.isEmpty) &&
(paymentPlatform.squareAccessToken == null || paymentPlatform.squareAccessToken.isEmpty) &&
(paymentPlatform.squareLocationId == null || paymentPlatform.squareLocationId.isEmpty)
(paymentPlatform.squareAppId == null || paymentPlatform.squareAppId!.isEmpty) &&
(paymentPlatform.squareAccessToken == null || paymentPlatform.squareAccessToken!.isEmpty) &&
(paymentPlatform.squareLocationId == null || paymentPlatform.squareLocationId!.isEmpty)
) {
return SizedBox.shrink();
}
if (paymentPlatform.code == Constants.PAYMENT_METHOD_CODE_CHASE &&
(paymentPlatform.xLogin == null || paymentPlatform.xLogin.isEmpty) &&
(paymentPlatform.transactionKey == null || paymentPlatform.transactionKey.isEmpty) &&
(paymentPlatform.responseKey == null || paymentPlatform.responseKey.isEmpty)
(paymentPlatform.xLogin == null || paymentPlatform.xLogin!.isEmpty) &&
(paymentPlatform.transactionKey == null || paymentPlatform.transactionKey!.isEmpty) &&
(paymentPlatform.responseKey == null || paymentPlatform.responseKey!.isEmpty)
) {
return SizedBox.shrink();
}
@@ -1681,7 +1681,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
return GestureDetector(
child: Container(
decoration: selectedCoupon == 0 ? BoxDecoration(
color: subtotal > cartInfo.businessInfo.minPrice ? Colors
color: subtotal > cartInfo.businessInfo!.minPrice ? Colors
.transparent : Colors.black38,
border: Border(
top: BorderSide(
@@ -1702,7 +1702,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
),
),
) : BoxDecoration(
color: subtotal > cartInfo.businessInfo.minPrice ? Colors
color: subtotal > cartInfo.businessInfo!.minPrice ? Colors
.transparent : Colors.black38,
),
child: Row(
@@ -1743,7 +1743,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
return GestureDetector(
child: Container(
decoration: selectedCoupon == coupon.id ? BoxDecoration(
color: subtotal > cartInfo.businessInfo.minPrice ? Colors
color: subtotal > cartInfo.businessInfo!.minPrice ? Colors
.transparent : Colors.black38,
border: Border(
top: BorderSide(
@@ -1857,7 +1857,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
),
Container(
child: Text(
coupon.minAmount > 0 ?
coupon.minAmount! > 0 ?
S.of(context).min_order_amount_token(
coupon.minAmount) :
S.of(context)
@@ -1917,7 +1917,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
crossAxisAlignment: CrossAxisAlignment.start,
children: [],
);
if (cartInfo.businessInfo.quickInputs.length > 0) {
if (cartInfo.businessInfo!.quickInputs!.length > 0) {
Wrap w = Wrap(
children: [],
);
@@ -1931,8 +1931,8 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
),
),
));
for (int i = 0; i < cartInfo.businessInfo.quickInputs.length; i++) {
String qi = cartInfo.businessInfo.quickInputs[i].value;
for (int i = 0; i < cartInfo.businessInfo!.quickInputs!.length; i++) {
String qi = cartInfo.businessInfo!.quickInputs![i].value;
w.children.add(TextButton(
child: Text(
qi,
@@ -2112,7 +2112,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
child: Container(
alignment: Alignment.centerRight,
child: Text(
'${shippingRate.price.toStringAsFixed(2)}',
'${shippingRate.price!.toStringAsFixed(2)}',
style: TextStyle(
fontSize: 16.0,
color: Colors.black38,
@@ -2203,7 +2203,7 @@ class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProvide
: (
(bookingTimeList.length == 0 && bookingDateTimeList.length == 0) ?
0 :
bookingDateTimeList[bookingDateIndex].bookTimes[bookingTimeIndex]
bookingDateTimeList[bookingDateIndex].bookTimes![bookingTimeIndex]
.unixTime
),
'delivery': deliveryMethod,