@@ -177,101 +177,119 @@ class NullSafetyDeadCodeVerifier {
177
177
/// the current dead code interval.
178
178
void flowEnd (AstNode node) {
179
179
var firstDeadNode = _firstDeadNode;
180
- if (firstDeadNode != null ) {
181
- if (! _containsFirstDeadNode (node)) {
182
- return ;
183
- }
180
+ if (firstDeadNode == null ) {
181
+ return ;
182
+ }
184
183
185
- if (node is SwitchMember && node == firstDeadNode) {
186
- _errorReporter.atToken (
187
- node.keyword,
188
- WarningCode .DEAD_CODE ,
189
- );
190
- _firstDeadNode = null ;
191
- return ;
192
- }
184
+ if (! _containsFirstDeadNode (node)) {
185
+ return ;
186
+ }
193
187
194
- var parent = firstDeadNode.parent;
195
- if (parent is Assertion && identical (firstDeadNode, parent.message)) {
196
- // Don't report "dead code" for the message part of an assert statement ,
197
- // because this causes nuisance warnings for redundant `!= null`
198
- // asserts.
199
- } else {
200
- var offset = firstDeadNode.offset ;
201
- // We know that [node] is the first dead node, or contains it.
202
- // So, technically the code interval ends at the end of [node].
203
- // But we trim it to the last statement for presentation purposes.
204
- if (node != firstDeadNode) {
205
- if (node is FunctionDeclaration ) {
206
- node = node.functionExpression.body;
207
- }
208
- if (node is FunctionExpression ) {
209
- node = node.body;
210
- }
211
- if (node is MethodDeclaration ) {
212
- node = node.body;
213
- }
214
- if (node is BlockFunctionBody ) {
215
- node = node. block;
216
- }
217
- if (node is Block && node.statements.isNotEmpty) {
218
- node = node.statements.last ;
219
- }
220
- if (node is SwitchMember && node.statements.isNotEmpty) {
221
- node = node.statements.last;
222
- }
223
- } else if (parent is BinaryExpression && node == parent.rightOperand ) {
224
- offset = parent. operator .offset ;
188
+ if (node is SwitchMember && node == firstDeadNode) {
189
+ _errorReporter. atToken (
190
+ node.keyword ,
191
+ WarningCode . DEAD_CODE ,
192
+ );
193
+ _firstDeadNode = null ;
194
+ return ;
195
+ }
196
+
197
+ var parent = firstDeadNode.parent;
198
+ if (parent is Assertion && identical ( firstDeadNode, parent.message) ) {
199
+ // Don't report "dead code" for the message part of an assert statement,
200
+ // because this causes nuisance warnings for redundant `!= null`
201
+ // asserts.
202
+ } else if (parent is ConstructorDeclaration &&
203
+ firstDeadNode is EmptyFunctionBody ) {
204
+ // Don't report "dead code" for an unreachable, but syntacically required,
205
+ // semicolon that follows one or more constructor initializers.
206
+ } else if (parent is ConstructorDeclaration &&
207
+ firstDeadNode is BlockFunctionBody &&
208
+ firstDeadNode.block.statements.isEmpty ) {
209
+ // Don't report "dead code" for an unreachable, but empty block body that
210
+ // follows one or more constructor initializers.
211
+ } else {
212
+ var offset = firstDeadNode.offset ;
213
+ // We know that [node] is the first dead node, or contains it.
214
+ // So, technically the code interval ends at the end of [ node].
215
+ // But we trim it to the last statement for presentation purposes.
216
+ if (node != firstDeadNode) {
217
+ if (node is FunctionDeclaration ) {
218
+ node = node.functionExpression.body ;
225
219
}
226
- if (parent is DoStatement ) {
227
- var doOffset = parent.doKeyword.offset;
228
- var doEnd = parent.doKeyword.end;
229
- var whileOffset = parent.whileKeyword.offset;
230
- var whileEnd = parent.semicolon.end;
231
- var body = parent.body;
232
- if (body is Block ) {
233
- doEnd = body.leftBracket.end;
234
- whileOffset = body.rightBracket.offset;
235
- }
236
- _errorReporter.atOffset (
237
- offset: doOffset,
238
- length: doEnd - doOffset,
239
- errorCode: WarningCode .DEAD_CODE ,
240
- );
241
- _errorReporter.atOffset (
242
- offset: whileOffset,
243
- length: whileEnd - whileOffset,
244
- errorCode: WarningCode .DEAD_CODE ,
245
- );
246
- offset = parent.semicolon.next! .offset;
247
- if (parent.hasBreakStatement) {
248
- offset = node.end;
249
- }
250
- } else if (parent is ForParts ) {
251
- node = parent.updaters.last;
252
- } else if (parent is ForStatement ) {
253
- _reportForUpdaters (parent);
254
- } else if (parent is Block ) {
255
- var grandParent = parent.parent;
256
- if (grandParent is ForStatement ) {
257
- _reportForUpdaters (grandParent);
258
- }
259
- } else if (parent is LogicalOrPattern && node == parent.rightOperand) {
260
- offset = parent.operator .offset;
220
+ if (node is FunctionExpression ) {
221
+ node = node.body;
261
222
}
262
-
263
- var length = node.end - offset ;
264
- if (length > 0 ) {
265
- _errorReporter. atOffset (
266
- offset : offset,
267
- length : length,
268
- errorCode : WarningCode . DEAD_CODE ,
269
- ) ;
223
+ if (node is MethodDeclaration ) {
224
+ node = node.body ;
225
+ }
226
+ if (node is BlockFunctionBody ) {
227
+ node = node.block;
228
+ }
229
+ if (node is Block && node.statements.isNotEmpty) {
230
+ node = node.statements.last ;
270
231
}
232
+ if (node is SwitchMember && node.statements.isNotEmpty) {
233
+ node = node.statements.last;
234
+ }
235
+ } else if (parent is BinaryExpression && node == parent.rightOperand) {
236
+ offset = parent.operator .offset;
237
+ }
238
+ if (parent is ConstructorInitializer ) {
239
+ _errorReporter.atOffset (
240
+ offset: parent.offset,
241
+ length: parent.end - parent.offset,
242
+ errorCode: WarningCode .DEAD_CODE ,
243
+ );
244
+ offset = node.end;
245
+ } else if (parent is DoStatement ) {
246
+ var doOffset = parent.doKeyword.offset;
247
+ var doEnd = parent.doKeyword.end;
248
+ var whileOffset = parent.whileKeyword.offset;
249
+ var whileEnd = parent.semicolon.end;
250
+ var body = parent.body;
251
+ if (body is Block ) {
252
+ doEnd = body.leftBracket.end;
253
+ whileOffset = body.rightBracket.offset;
254
+ }
255
+ _errorReporter.atOffset (
256
+ offset: doOffset,
257
+ length: doEnd - doOffset,
258
+ errorCode: WarningCode .DEAD_CODE ,
259
+ );
260
+ _errorReporter.atOffset (
261
+ offset: whileOffset,
262
+ length: whileEnd - whileOffset,
263
+ errorCode: WarningCode .DEAD_CODE ,
264
+ );
265
+ offset = parent.semicolon.next! .offset;
266
+ if (parent.hasBreakStatement) {
267
+ offset = node.end;
268
+ }
269
+ } else if (parent is ForParts ) {
270
+ node = parent.updaters.last;
271
+ } else if (parent is ForStatement ) {
272
+ _reportForUpdaters (parent);
273
+ } else if (parent is Block ) {
274
+ var grandParent = parent.parent;
275
+ if (grandParent is ForStatement ) {
276
+ _reportForUpdaters (grandParent);
277
+ }
278
+ } else if (parent is LogicalOrPattern && node == parent.rightOperand) {
279
+ offset = parent.operator .offset;
271
280
}
272
281
273
- _firstDeadNode = null ;
282
+ var length = node.end - offset;
283
+ if (length > 0 ) {
284
+ _errorReporter.atOffset (
285
+ offset: offset,
286
+ length: length,
287
+ errorCode: WarningCode .DEAD_CODE ,
288
+ );
289
+ }
274
290
}
291
+
292
+ _firstDeadNode = null ;
275
293
}
276
294
277
295
void tryStatementEnter (TryStatement node) {
0 commit comments