d810c7d0c0
This commit was generated by the following steps: - Manually change the SDK constraint in `pkg/front_end/pubspec.yaml` - Run `gclient sync` - Run `find pkg/front_end/benchmarks pkg/front_end/lib pkg/front_end/presubmit_helper.dart pkg/front_end/presubmit_helper_spawn.dart pkg/front_end/test pkg/front_end/tool -iname '*.dart' | xargs tools/sdks/dart-sdk/bin/dart format` - Manually fix remaining long lines and add dead code ignore comments. - Fix coverage by running `dart --enable-asserts pkg/front_end/test/coverage_suite.dart --tasks=5 --add-and-remove-comments` - Fix `pkg/front_end/test/coverage_merger/assert_message_auto_ignored` by running `dart pkg/front_end/test/unit_test_suites.dart -p pkg/front_end/test/coverage_merger/assert_message_auto_ignored -DupdateExpectations=true` The diff is large because the version bump causes the formatter to switch into "tall mode". Change-Id: I6a6a696410da8b168060acfe0e4d6e91e294c4f0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/447628 Auto-Submit: Paul Berry <paulberry@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
277 lines
9.0 KiB
Dart
277 lines
9.0 KiB
Dart
// Copyright (c) 2020, 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' show Directory, Platform;
|
|
|
|
import 'package:_fe_analyzer_shared/src/testing/features.dart';
|
|
import 'package:_fe_analyzer_shared/src/testing/id.dart';
|
|
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart'
|
|
show DataInterpreter, runTests;
|
|
import 'package:front_end/src/api_prototype/experimental_flags.dart';
|
|
import 'package:front_end/src/api_prototype/lowering_predicates.dart';
|
|
import 'package:front_end/src/testing/id_extractor.dart';
|
|
import 'package:front_end/src/testing/id_testing_helper.dart';
|
|
import 'package:front_end/src/testing/id_testing_utils.dart';
|
|
import 'package:kernel/ast.dart';
|
|
import 'package:kernel/src/printer.dart';
|
|
import 'package:kernel/target/targets.dart';
|
|
|
|
const String isNullMarker = 'is-null';
|
|
const String sentinelMarker = 'sentinel';
|
|
|
|
Future<void> main(List<String> args) async {
|
|
Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
|
|
await runTests<Features>(
|
|
dataDir,
|
|
args: args,
|
|
createUriForFileName: createUriForFileName,
|
|
onFailure: onFailure,
|
|
runTest: runTestFor(const PredicateDataComputer(), [
|
|
const CfeTestConfig(
|
|
isNullMarker,
|
|
'use is-null',
|
|
explicitExperimentalFlags: const {ExperimentalFlag.nonNullable: true},
|
|
targetFlags: const TestTargetFlags(
|
|
forceConstructorTearOffLoweringForTesting:
|
|
ConstructorTearOffLowering.all,
|
|
forceLateLoweringsForTesting: LateLowering.all,
|
|
forceLateLoweringSentinelForTesting: false,
|
|
),
|
|
),
|
|
const CfeTestConfig(
|
|
sentinelMarker,
|
|
'use sentinel',
|
|
explicitExperimentalFlags: const {ExperimentalFlag.nonNullable: true},
|
|
targetFlags: const TestTargetFlags(
|
|
forceConstructorTearOffLoweringForTesting:
|
|
ConstructorTearOffLowering.all,
|
|
forceLateLoweringsForTesting: LateLowering.all,
|
|
forceLateLoweringSentinelForTesting: true,
|
|
),
|
|
),
|
|
]),
|
|
);
|
|
}
|
|
|
|
class Tags {
|
|
static const String name = 'name';
|
|
|
|
static const String lateField = 'lateField';
|
|
static const String lateFieldName = 'lateFieldName';
|
|
static const String lateIsSetField = 'lateIsSetField';
|
|
static const String lateFieldGetter = 'lateFieldGetter';
|
|
static const String lateFieldSetter = 'lateFieldSetter';
|
|
static const String lateFieldTarget = 'lateFieldTarget';
|
|
static const String lateFieldInitializer = 'lateFieldInitializer';
|
|
|
|
static const String lateLocal = 'lateLocal';
|
|
static const String lateIsSetLocal = 'lateIsSetLocal';
|
|
static const String lateLocalGetter = 'lateLocalGetter';
|
|
static const String lateLocalSetter = 'lateLocalSetter';
|
|
|
|
static const String extensionThis = 'extensionThis';
|
|
static const String extensionName = 'extensionName';
|
|
|
|
static const String tearoffLowering = 'tearoffLowering';
|
|
static const String tearoffConstructor = 'tearoffConstructor';
|
|
static const String tearoffTypedef = 'tearoffTypedef';
|
|
|
|
static const String joinedIntermediate = 'joinedIntermediate';
|
|
}
|
|
|
|
class PredicateDataComputer extends CfeDataComputer<Features> {
|
|
const PredicateDataComputer();
|
|
|
|
/// Function that computes a data mapping for [library].
|
|
///
|
|
/// Fills [actualMap] with the data.
|
|
@override
|
|
void computeLibraryData(
|
|
CfeTestResultData testResultData,
|
|
Library library,
|
|
Map<Id, ActualData<Features>> actualMap, {
|
|
bool? verbose,
|
|
}) {
|
|
new PredicateDataExtractor(
|
|
testResultData.compilerResult,
|
|
actualMap,
|
|
).computeForLibrary(library);
|
|
}
|
|
|
|
@override
|
|
void computeMemberData(
|
|
CfeTestResultData testResultData,
|
|
Member member,
|
|
Map<Id, ActualData<Features>> actualMap, {
|
|
bool? verbose,
|
|
}) {
|
|
member.accept(
|
|
new PredicateDataExtractor(testResultData.compilerResult, actualMap),
|
|
);
|
|
}
|
|
|
|
@override
|
|
DataInterpreter<Features> get dataValidator =>
|
|
const FeaturesDataInterpreter();
|
|
}
|
|
|
|
class PredicateDataExtractor extends CfeDataExtractor<Features> {
|
|
Map<Object?, Features> featureMap = {};
|
|
Map<Object?, NodeId> nodeIdMap = {};
|
|
|
|
PredicateDataExtractor(
|
|
InternalCompilerResult compilerResult,
|
|
Map<Id, ActualData<Features>> actualMap,
|
|
) : super(compilerResult, actualMap);
|
|
|
|
@override
|
|
Features? computeLibraryValue(Id id, Library node) {
|
|
return null;
|
|
}
|
|
|
|
@override
|
|
Features? computeMemberValue(Id id, Member node) {
|
|
Features features = new Features();
|
|
if (node is Field) {
|
|
if (isLateLoweredField(node)) {
|
|
features.add(Tags.lateField);
|
|
features[Tags.lateFieldName] = extractFieldNameFromLateLoweredField(
|
|
node,
|
|
).text;
|
|
}
|
|
if (isLateLoweredIsSetField(node)) {
|
|
features.add(Tags.lateIsSetField);
|
|
features[Tags.lateFieldName] =
|
|
extractFieldNameFromLateLoweredIsSetField(node).text;
|
|
}
|
|
Field? target = getLateFieldTarget(node);
|
|
if (target != null) {
|
|
features[Tags.lateFieldTarget] = getQualifiedMemberName(target);
|
|
}
|
|
Expression? initializer = getLateFieldInitializer(node);
|
|
if (initializer != null) {
|
|
features[Tags.lateFieldInitializer] = initializer.toText(
|
|
astTextStrategyForTesting,
|
|
);
|
|
}
|
|
} else if (node is Procedure) {
|
|
if (isLateLoweredFieldGetter(node)) {
|
|
features.add(Tags.lateFieldGetter);
|
|
features[Tags.lateFieldName] =
|
|
extractFieldNameFromLateLoweredFieldGetter(node).text;
|
|
}
|
|
if (isLateLoweredFieldSetter(node)) {
|
|
features.add(Tags.lateFieldSetter);
|
|
features[Tags.lateFieldName] =
|
|
extractFieldNameFromLateLoweredFieldSetter(node).text;
|
|
}
|
|
Field? target = getLateFieldTarget(node);
|
|
if (target != null) {
|
|
features[Tags.lateFieldTarget] = getQualifiedMemberName(target);
|
|
}
|
|
Expression? initializer = getLateFieldInitializer(node);
|
|
if (initializer != null) {
|
|
features[Tags.lateFieldInitializer] = initializer.toText(
|
|
astTextStrategyForTesting,
|
|
);
|
|
}
|
|
if (isConstructorTearOffLowering(node)) {
|
|
features.add(Tags.tearoffConstructor);
|
|
}
|
|
if (isTypedefTearOffLowering(node)) {
|
|
features.add(Tags.tearoffTypedef);
|
|
}
|
|
if (node.isExtensionMember || node.isExtensionTypeMember) {
|
|
features[Tags.extensionName] = extractQualifiedNameFromExtensionMember(
|
|
node,
|
|
)!;
|
|
}
|
|
}
|
|
if (isTearOffLowering(node)) {
|
|
features.add(Tags.tearoffLowering);
|
|
}
|
|
return features;
|
|
}
|
|
|
|
@override
|
|
void visitProcedure(Procedure node) {
|
|
super.visitProcedure(node);
|
|
nodeIdMap.forEach((Object? identity, NodeId id) {
|
|
Features? features = featureMap[identity];
|
|
if (features != null) {
|
|
TreeNode nodeWithOffset = computeTreeNodeWithOffset(node)!;
|
|
registerValue(
|
|
nodeWithOffset.location!.file,
|
|
id.value,
|
|
id,
|
|
features,
|
|
'$identity',
|
|
);
|
|
}
|
|
});
|
|
nodeIdMap.clear();
|
|
featureMap.clear();
|
|
}
|
|
|
|
@override
|
|
void visitVariableDeclaration(VariableDeclaration node) {
|
|
Object? identity;
|
|
String? name;
|
|
String? tag;
|
|
if (isLateLoweredLocal(node)) {
|
|
name = extractLocalNameFromLateLoweredLocal(node.name!);
|
|
tag = Tags.lateLocal;
|
|
identity = name;
|
|
} else if (isLateLoweredIsSetLocal(node)) {
|
|
name = extractLocalNameFromLateLoweredIsSet(node.name!);
|
|
tag = Tags.lateIsSetLocal;
|
|
identity = name;
|
|
} else if (isLateLoweredLocalGetter(node)) {
|
|
name = extractLocalNameFromLateLoweredGetter(node.name!);
|
|
tag = Tags.lateLocalGetter;
|
|
identity = name;
|
|
} else if (isLateLoweredLocalSetter(node)) {
|
|
name = extractLocalNameFromLateLoweredSetter(node.name!);
|
|
tag = Tags.lateLocalSetter;
|
|
identity = name;
|
|
} else if (isExtensionThis(node)) {
|
|
name = extractLocalNameForExtensionThis(node.name!);
|
|
tag = Tags.extensionThis;
|
|
identity = name;
|
|
} else if (isJoinedIntermediateVariable(node)) {
|
|
name = extractJoinedIntermediateName(node.name!);
|
|
tag = Tags.joinedIntermediate;
|
|
identity = node;
|
|
} else if (node.name != null) {
|
|
name = node.name;
|
|
identity = name;
|
|
}
|
|
if (name != null) {
|
|
if (node.fileOffset != TreeNode.noOffset) {
|
|
nodeIdMap[identity] ??= new NodeId(node.fileOffset, IdKind.node);
|
|
}
|
|
if (tag != null) {
|
|
Features features = featureMap[identity] ??= new Features();
|
|
features.add(tag);
|
|
features[Tags.name] = name;
|
|
}
|
|
}
|
|
super.visitVariableDeclaration(node);
|
|
}
|
|
|
|
@override
|
|
ActualData<Features>? mergeData(
|
|
ActualData<Features> value1,
|
|
ActualData<Features> value2,
|
|
) {
|
|
if ('${value1.value}' == '${value2.value}') {
|
|
// The extension this parameter is seen twice in the extension method
|
|
// and the corresponding tearoff. The features are identical, though, so
|
|
// we just use the first.
|
|
return value1;
|
|
}
|
|
return null;
|
|
}
|
|
}
|