@@ -150,7 +150,7 @@ Statement declare(
150150 String ? expectInferredType,
151151}) {
152152 var location = computeLocation ();
153- return new Declare ._(
153+ return new PatternVariableDeclaration ._(
154154 new VariablePattern ._(
155155 type == null ? null : Type (type),
156156 variable,
@@ -444,22 +444,6 @@ Pattern mapPatternWithTypeArguments({
444444 );
445445}
446446
447- Statement match (
448- Pattern pattern,
449- ProtoExpression initializer, {
450- bool isLate = false ,
451- bool isFinal = false ,
452- }) {
453- var location = computeLocation ();
454- return new Declare ._(
455- pattern,
456- initializer.asExpression (location: location),
457- isLate: isLate,
458- isFinal: isFinal,
459- location: location,
460- );
461- }
462-
463447Pattern objectPattern ({
464448 required String requiredType,
465449 required List <RecordPatternField > fields,
@@ -519,6 +503,22 @@ CollectionElement patternForInElement(
519503 );
520504}
521505
506+ Statement patternVariableDeclaration (
507+ Pattern pattern,
508+ ProtoExpression initializer, {
509+ bool isLate = false ,
510+ bool isFinal = false ,
511+ }) {
512+ var location = computeLocation ();
513+ return new PatternVariableDeclaration ._(
514+ pattern,
515+ initializer.asExpression (location: location),
516+ isLate: isLate,
517+ isFinal: isFinal,
518+ location: location,
519+ );
520+ }
521+
522522Pattern recordPattern (List <RecordPatternField > fields) =>
523523 RecordPattern ._(fields, location: computeLocation ());
524524
@@ -1302,149 +1302,6 @@ class Continue extends Statement {
13021302 }
13031303}
13041304
1305- class Declare extends Statement {
1306- final bool isLate;
1307- final bool isFinal;
1308- final Pattern pattern;
1309- final Expression ? initializer;
1310-
1311- Declare ._(
1312- this .pattern,
1313- this .initializer, {
1314- required this .isLate,
1315- required this .isFinal,
1316- required super .location,
1317- });
1318-
1319- @override
1320- void preVisit (PreVisitor visitor) {
1321- var variableBinder = _VariableBinder (visitor);
1322- variableBinder.casePatternStart ();
1323- pattern.preVisit (visitor, variableBinder, isInAssignment: false );
1324- variableBinder.casePatternFinish ();
1325- variableBinder.finish ();
1326- if (isLate) {
1327- visitor._assignedVariables.beginNode ();
1328- }
1329- initializer? .preVisit (visitor);
1330- if (isLate) {
1331- visitor._assignedVariables.endNode (this );
1332- }
1333- }
1334-
1335- @override
1336- String toString () {
1337- var parts = < String > [
1338- if (isLate) 'late' ,
1339- if (isFinal) 'final' ,
1340- pattern._debugString (needsKeywordOrType: ! isFinal),
1341- if (initializer != null ) '= $initializer ' ,
1342- ];
1343- return '${parts .join (' ' )};' ;
1344- }
1345-
1346- @override
1347- void visit (Harness h) {
1348- String irName;
1349- List <Kind > argKinds;
1350- List <String > names = const [];
1351- var initializer = this .initializer;
1352- if (isLate) {
1353- // Late declarations are not allowed using patterns, so interpret the
1354- // declaration as an old-fashioned variable declaration.
1355- var pattern = this .pattern as VariablePattern ;
1356- var variable = pattern.variable;
1357- h.irBuilder.atom (variable.name, Kind .variable, location: location);
1358- var declaredType = pattern.declaredType;
1359- Type staticType;
1360- if (initializer == null ) {
1361- // Use the shared logic for analyzing uninitialized variable
1362- // declarations.
1363- staticType =
1364- h.typeAnalyzer
1365- .analyzeUninitializedVariableDeclaration (
1366- this ,
1367- pattern.variable,
1368- declaredType? .wrapSharedTypeView (),
1369- isFinal: isFinal,
1370- )
1371- .unwrapTypeView ();
1372- irName = 'declare' ;
1373- argKinds = [Kind .variable];
1374- } else {
1375- // There's no shared logic for analyzing initialized late variable
1376- // declarations, so analyze the declaration directly.
1377- h.flow.lateInitializer_begin (this );
1378- var initializerType =
1379- h.typeAnalyzer
1380- .analyzeExpression (
1381- initializer,
1382- declaredType? .wrapSharedTypeSchemaView () ??
1383- h.operations.unknownType,
1384- )
1385- .unwrapTypeView <Type >();
1386- h.flow.lateInitializer_end ();
1387- staticType = variable.type = declaredType ?? initializerType;
1388- h.flow.declare (variable, SharedTypeView (staticType), initialized: true );
1389- h.flow.initialize (
1390- variable,
1391- SharedTypeView (initializerType),
1392- initializer,
1393- isFinal: isFinal,
1394- isLate: true ,
1395- isImplicitlyTyped: declaredType == null ,
1396- );
1397- h.irBuilder.atom (initializerType.type, Kind .type, location: location);
1398- h.irBuilder.atom (staticType.type, Kind .type, location: location);
1399- irName = 'declare' ;
1400- argKinds = [Kind .variable, Kind .expression, Kind .type, Kind .type];
1401- names = (['initializerType' , 'staticType' ]);
1402- }
1403- // Finally, double check the inferred variable type, if necessary for the
1404- // test.
1405- var expectInferredType = pattern.expectInferredType;
1406- if (expectInferredType != null ) {
1407- expect (staticType, expectInferredType);
1408- }
1409- } else if (initializer == null ) {
1410- var pattern = this .pattern as VariablePattern ;
1411- var declaredType = pattern.declaredType;
1412- var staticType =
1413- h.typeAnalyzer
1414- .analyzeUninitializedVariableDeclaration (
1415- this ,
1416- pattern.variable,
1417- declaredType? .wrapSharedTypeView (),
1418- isFinal: isFinal,
1419- )
1420- .unwrapTypeView <Type >();
1421- h.typeAnalyzer.handleDeclaredVariablePattern (
1422- pattern,
1423- matchedType: staticType,
1424- staticType: staticType,
1425- );
1426- irName = 'declare' ;
1427- argKinds = [Kind .pattern];
1428- } else {
1429- h.typeAnalyzer.analyzePatternVariableDeclaration (
1430- this ,
1431- pattern,
1432- initializer,
1433- isFinal: isFinal,
1434- );
1435- irName = 'match' ;
1436- argKinds = [Kind .expression, Kind .pattern];
1437- }
1438- h.irBuilder.apply (
1439- [irName, if (isLate) 'late' , if (isFinal) 'final' ].join ('_' ),
1440- argKinds,
1441- Kind .statement,
1442- location: location,
1443- names: names,
1444- );
1445- }
1446- }
1447-
14481305class Do extends Statement {
14491306 final Statement body;
14501307 final Expression condition;
@@ -4224,6 +4081,149 @@ class PatternForInElement extends CollectionElement {
42244081 }
42254082}
42264083
4084+ class PatternVariableDeclaration extends Statement {
4085+ final bool isLate;
4086+ final bool isFinal;
4087+ final Pattern pattern;
4088+ final Expression ? initializer;
4089+
4090+ PatternVariableDeclaration ._(
4091+ this .pattern,
4092+ this .initializer, {
4093+ required this .isLate,
4094+ required this .isFinal,
4095+ required super .location,
4096+ });
4097+
4098+ @override
4099+ void preVisit (PreVisitor visitor) {
4100+ var variableBinder = _VariableBinder (visitor);
4101+ variableBinder.casePatternStart ();
4102+ pattern.preVisit (visitor, variableBinder, isInAssignment: false );
4103+ variableBinder.casePatternFinish ();
4104+ variableBinder.finish ();
4105+ if (isLate) {
4106+ visitor._assignedVariables.beginNode ();
4107+ }
4108+ initializer? .preVisit (visitor);
4109+ if (isLate) {
4110+ visitor._assignedVariables.endNode (this );
4111+ }
4112+ }
4113+
4114+ @override
4115+ String toString () {
4116+ var parts = < String > [
4117+ if (isLate) 'late' ,
4118+ if (isFinal) 'final' ,
4119+ pattern._debugString (needsKeywordOrType: ! isFinal),
4120+ if (initializer != null ) '= $initializer ' ,
4121+ ];
4122+ return '${parts .join (' ' )};' ;
4123+ }
4124+
4125+ @override
4126+ void visit (Harness h) {
4127+ String irName;
4128+ List <Kind > argKinds;
4129+ List <String > names = const [];
4130+ var initializer = this .initializer;
4131+ if (isLate) {
4132+ // Late declarations are not allowed using patterns, so interpret the
4133+ // declaration as an old-fashioned variable declaration.
4134+ var pattern = this .pattern as VariablePattern ;
4135+ var variable = pattern.variable;
4136+ h.irBuilder.atom (variable.name, Kind .variable, location: location);
4137+ var declaredType = pattern.declaredType;
4138+ Type staticType;
4139+ if (initializer == null ) {
4140+ // Use the shared logic for analyzing uninitialized variable
4141+ // declarations.
4142+ staticType =
4143+ h.typeAnalyzer
4144+ .analyzeUninitializedVariableDeclaration (
4145+ this ,
4146+ pattern.variable,
4147+ declaredType? .wrapSharedTypeView (),
4148+ isFinal: isFinal,
4149+ )
4150+ .unwrapTypeView ();
4151+ irName = 'declare' ;
4152+ argKinds = [Kind .variable];
4153+ } else {
4154+ // There's no shared logic for analyzing initialized late variable
4155+ // declarations, so analyze the declaration directly.
4156+ h.flow.lateInitializer_begin (this );
4157+ var initializerType =
4158+ h.typeAnalyzer
4159+ .analyzeExpression (
4160+ initializer,
4161+ declaredType? .wrapSharedTypeSchemaView () ??
4162+ h.operations.unknownType,
4163+ )
4164+ .unwrapTypeView <Type >();
4165+ h.flow.lateInitializer_end ();
4166+ staticType = variable.type = declaredType ?? initializerType;
4167+ h.flow.declare (variable, SharedTypeView (staticType), initialized: true );
4168+ h.flow.initialize (
4169+ variable,
4170+ SharedTypeView (initializerType),
4171+ initializer,
4172+ isFinal: isFinal,
4173+ isLate: true ,
4174+ isImplicitlyTyped: declaredType == null ,
4175+ );
4176+ h.irBuilder.atom (initializerType.type, Kind .type, location: location);
4177+ h.irBuilder.atom (staticType.type, Kind .type, location: location);
4178+ irName = 'declare' ;
4179+ argKinds = [Kind .variable, Kind .expression, Kind .type, Kind .type];
4180+ names = (['initializerType' , 'staticType' ]);
4181+ }
4182+ // Finally, double check the inferred variable type, if necessary for the
4183+ // test.
4184+ var expectInferredType = pattern.expectInferredType;
4185+ if (expectInferredType != null ) {
4186+ expect (staticType, expectInferredType);
4187+ }
4188+ } else if (initializer == null ) {
4189+ var pattern = this .pattern as VariablePattern ;
4190+ var declaredType = pattern.declaredType;
4191+ var staticType =
4192+ h.typeAnalyzer
4193+ .analyzeUninitializedVariableDeclaration (
4194+ this ,
4195+ pattern.variable,
4196+ declaredType? .wrapSharedTypeView (),
4197+ isFinal: isFinal,
4198+ )
4199+ .unwrapTypeView <Type >();
4200+ h.typeAnalyzer.handleDeclaredVariablePattern (
4201+ pattern,
4202+ matchedType: staticType,
4203+ staticType: staticType,
4204+ );
4205+ irName = 'declare' ;
4206+ argKinds = [Kind .pattern];
4207+ } else {
4208+ h.typeAnalyzer.analyzePatternVariableDeclaration (
4209+ this ,
4210+ pattern,
4211+ initializer,
4212+ isFinal: isFinal,
4213+ );
4214+ irName = 'match' ;
4215+ argKinds = [Kind .expression, Kind .pattern];
4216+ }
4217+ h.irBuilder.apply (
4218+ [irName, if (isLate) 'late' , if (isFinal) 'final' ].join ('_' ),
4219+ argKinds,
4220+ Kind .statement,
4221+ location: location,
4222+ names: names,
4223+ );
4224+ }
4225+ }
4226+
42274227/// A variable modelling an implicit join of variables declared inside
42284228/// logical-or patterns or switch cases sharing a body.
42294229///
0 commit comments