e655e9fd6c
Add `ClassBody.members` and `EnumBody.constants`/`members` so callers can access class and enum contents through the common body interfaces instead of pattern matching on `BlockClassBody` and `BlockEnumBody`. Implement empty node lists for empty class and enum bodies, update the public API, and migrate analyzer, analysis_server, analyzer_plugin, and linter code to use the new accessors directly. This removes the ad hoc `members2` helper extensions and a large amount of repeated `tryCast` and `switch` logic, making body traversal more uniform. Change-Id: I51d75f2253c7e6f75efecae84bf0443ff5eb6788 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/488263 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Paul Berry <paulberry@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
82 lines
3.0 KiB
Dart
82 lines
3.0 KiB
Dart
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
import 'dart:io';
|
|
|
|
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
|
|
import 'package:analyzer/dart/analysis/results.dart';
|
|
import 'package:analyzer/dart/ast/ast.dart';
|
|
import 'package:analyzer/file_system/physical_file_system.dart';
|
|
import 'package:analyzer_testing/package_root.dart';
|
|
|
|
class BulkFixDetails {
|
|
Future<Map<String, CorrectionDetails>> collectOverrides() async {
|
|
var overrideDetails = <String, CorrectionDetails>{};
|
|
|
|
var pkgRootPath = PhysicalResourceProvider.INSTANCE.pathContext.normalize(
|
|
packageRoot,
|
|
);
|
|
var directory = Directory(
|
|
'$pkgRootPath/analysis_server/lib/src/services/correction/dart',
|
|
);
|
|
var collection = AnalysisContextCollection(
|
|
includedPaths: [directory.absolute.path],
|
|
resourceProvider: PhysicalResourceProvider.INSTANCE,
|
|
);
|
|
var context = collection.contexts[0];
|
|
|
|
for (var file in directory.listSync()) {
|
|
var resolvedFile =
|
|
await context.currentSession.getResolvedUnit(file.absolute.path)
|
|
as ResolvedUnitResult;
|
|
for (var classDecl
|
|
in resolvedFile.unit.declarations.whereType<ClassDeclaration>()) {
|
|
var classElement = classDecl.declaredFragment?.element;
|
|
if (classElement != null &&
|
|
classElement.allSupertypes.any(
|
|
(element) => element.element.name == 'CorrectionProducer',
|
|
)) {
|
|
var correctionName = classDecl.namePart.typeName.lexeme;
|
|
|
|
for (var method
|
|
in classDecl.body.members.whereType<MethodDeclaration>()) {
|
|
if (method.name.lexeme == 'canBeAppliedInBulk') {
|
|
var hasComment =
|
|
method.returnType?.beginToken.precedingComments != null;
|
|
|
|
var body = method.body;
|
|
if (body is BlockFunctionBody) {
|
|
var last = body.block.statements.last;
|
|
if (last is ReturnStatement) {
|
|
var canBeBulkApplied =
|
|
(last.expression as BooleanLiteral).value;
|
|
overrideDetails[correctionName] = CorrectionDetails(
|
|
canBeBulkApplied: canBeBulkApplied,
|
|
hasComment: hasComment,
|
|
);
|
|
}
|
|
} else if (body is ExpressionFunctionBody) {
|
|
var expression = body.expression;
|
|
var canBeBulkApplied = (expression as BooleanLiteral).value;
|
|
overrideDetails[correctionName] = CorrectionDetails(
|
|
canBeBulkApplied: canBeBulkApplied,
|
|
hasComment: hasComment,
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return overrideDetails;
|
|
}
|
|
}
|
|
|
|
class CorrectionDetails {
|
|
bool canBeBulkApplied;
|
|
bool hasComment;
|
|
|
|
CorrectionDetails({required this.canBeBulkApplied, required this.hasComment});
|
|
}
|