34fb48bb8a
Migrates libraries dependent only on already migrated libraries. Change-Id: I0e85ee8dbc2afce031b92e0009e71c206a55af28 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/179502 Commit-Queue: Johnni Winther <johnniwinther@google.com> Reviewed-by: Jens Johansen <jensj@google.com>
222 lines
7.8 KiB
Dart
222 lines
7.8 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.
|
|
|
|
// @dart = 2.9
|
|
|
|
import 'dart:io' show Directory, Platform;
|
|
import 'package:_fe_analyzer_shared/src/testing/id.dart';
|
|
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart'
|
|
show DataInterpreter, runTests;
|
|
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
|
|
import 'package:_fe_analyzer_shared/src/testing/features.dart';
|
|
import 'package:front_end/src/api_prototype/experimental_flags.dart';
|
|
import 'package:front_end/src/base/nnbd_mode.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:front_end/src/api_prototype/lowering_predicates.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';
|
|
|
|
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 TestConfig(isNullMarker, 'use is-null',
|
|
explicitExperimentalFlags: const {
|
|
ExperimentalFlag.nonNullable: true
|
|
},
|
|
targetFlags: const TargetFlags(
|
|
forceLateLoweringsForTesting: LateLowering.all,
|
|
forceLateLoweringSentinelForTesting: false),
|
|
nnbdMode: NnbdMode.Strong),
|
|
const TestConfig(sentinelMarker, 'use sentinel',
|
|
explicitExperimentalFlags: const {
|
|
ExperimentalFlag.nonNullable: true
|
|
},
|
|
targetFlags: const TargetFlags(
|
|
forceLateLoweringsForTesting: LateLowering.all,
|
|
forceLateLoweringSentinelForTesting: true),
|
|
nnbdMode: NnbdMode.Strong)
|
|
]));
|
|
}
|
|
|
|
class Tags {
|
|
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';
|
|
}
|
|
|
|
class PredicateDataComputer extends DataComputer<Features> {
|
|
const PredicateDataComputer();
|
|
|
|
/// Function that computes a data mapping for [library].
|
|
///
|
|
/// Fills [actualMap] with the data.
|
|
void computeLibraryData(
|
|
TestConfig config,
|
|
InternalCompilerResult compilerResult,
|
|
Library library,
|
|
Map<Id, ActualData<Features>> actualMap,
|
|
{bool verbose}) {
|
|
new PredicateDataExtractor(compilerResult, actualMap)
|
|
.computeForLibrary(library);
|
|
}
|
|
|
|
@override
|
|
void computeMemberData(
|
|
TestConfig config,
|
|
InternalCompilerResult compilerResult,
|
|
Member member,
|
|
Map<Id, ActualData<Features>> actualMap,
|
|
{bool verbose}) {
|
|
member.accept(new PredicateDataExtractor(compilerResult, actualMap));
|
|
}
|
|
|
|
@override
|
|
DataInterpreter<Features> get dataValidator =>
|
|
const FeaturesDataInterpreter();
|
|
}
|
|
|
|
class PredicateDataExtractor extends CfeDataExtractor<Features> {
|
|
Map<String, Features> featureMap = {};
|
|
Map<String, 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) {
|
|
if (node is Field) {
|
|
Features features = new Features();
|
|
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);
|
|
}
|
|
return features;
|
|
} else if (node is Procedure) {
|
|
Features features = new Features();
|
|
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);
|
|
}
|
|
return features;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
void visitProcedure(Procedure node) {
|
|
super.visitProcedure(node);
|
|
nodeIdMap.forEach((String name, NodeId id) {
|
|
Features features = featureMap[name];
|
|
if (features != null) {
|
|
TreeNode nodeWithOffset = computeTreeNodeWithOffset(node);
|
|
registerValue(
|
|
nodeWithOffset.location.file, id.value, id, features, name);
|
|
}
|
|
});
|
|
nodeIdMap.clear();
|
|
featureMap.clear();
|
|
}
|
|
|
|
void visitVariableDeclaration(VariableDeclaration node) {
|
|
String name;
|
|
String tag;
|
|
if (isLateLoweredLocal(node)) {
|
|
name = extractLocalNameFromLateLoweredLocal(node.name);
|
|
tag = Tags.lateLocal;
|
|
} else if (isLateLoweredIsSetLocal(node)) {
|
|
name = extractLocalNameFromLateLoweredIsSet(node.name);
|
|
tag = Tags.lateIsSetLocal;
|
|
} else if (isLateLoweredLocalGetter(node)) {
|
|
name = extractLocalNameFromLateLoweredGetter(node.name);
|
|
tag = Tags.lateLocalGetter;
|
|
} else if (isLateLoweredLocalSetter(node)) {
|
|
name = extractLocalNameFromLateLoweredSetter(node.name);
|
|
tag = Tags.lateLocalSetter;
|
|
} else if (isExtensionThis(node)) {
|
|
name = extractLocalNameForExtensionThis(node.name);
|
|
tag = Tags.extensionThis;
|
|
} else if (node.name != null) {
|
|
name = node.name;
|
|
}
|
|
if (name != null) {
|
|
if (node.fileOffset != TreeNode.noOffset) {
|
|
nodeIdMap[name] ??= new NodeId(node.fileOffset, IdKind.node);
|
|
}
|
|
if (tag != null) {
|
|
Features features = featureMap[name] ??= new Features();
|
|
features.add(tag);
|
|
}
|
|
}
|
|
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;
|
|
}
|
|
}
|