56a86e599e
This adds support using experimental features in id testing in DDC and uses it to add tests for scopes in extensions, extension types and mixins. The tests show that the DartScopeBuilder and DartScopeBuilder2 differ on the scope on instance members in extensions and extension types for the synthetic #this variable. Change-Id: Iec0f3b938da567578b1245ada885370fb2a8b33f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/335824 Reviewed-by: Jens Johansen <jensj@google.com> Reviewed-by: Nicholas Shahan <nshahan@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
149 lines
5.1 KiB
Dart
149 lines
5.1 KiB
Dart
// Copyright (c) 2023, 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 'package:_fe_analyzer_shared/src/testing/id.dart';
|
|
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
|
|
import 'package:front_end/src/api_prototype/experimental_flags.dart' as fe;
|
|
import 'package:front_end/src/fasta/messages.dart';
|
|
import 'package:front_end/src/testing/id_extractor.dart';
|
|
import 'package:front_end/src/testing/kernel_id_testing.dart';
|
|
import 'package:kernel/ast.dart';
|
|
|
|
import 'memory_compiler.dart';
|
|
|
|
/// Test configuration used for testing CFE in its default state.
|
|
const DdcTestConfig defaultDdcConfig = DdcTestConfig(ddcMarker, 'ddc');
|
|
|
|
class DdcTestConfig extends TestConfig {
|
|
final Map<fe.ExperimentalFlag, bool>? experimentalFlags;
|
|
|
|
const DdcTestConfig(super.marker, super.name, {this.experimentalFlags});
|
|
}
|
|
|
|
/// Convert relative file paths into an absolute Uri as expected by the test
|
|
/// helpers above.
|
|
Uri toTestUri(String relativePath) => memoryDirectory.resolve(relativePath);
|
|
|
|
/// Create the testing URI used for [fileName] in annotated tests.
|
|
Uri createUriForFileName(String fileName) => toTestUri(fileName);
|
|
|
|
/// Helper called when an error is found through the id-testing.
|
|
void onFailure(String message) => throw StateError(message);
|
|
|
|
/// DDC-specific [TestResultData] which holds a [MemoryCompilerResult] as its
|
|
/// [compilerResult].
|
|
class DdcTestResultData
|
|
extends TestResultData<TestConfig, MemoryCompilerResult> {
|
|
DdcTestResultData(super.config, super.compilerResult);
|
|
|
|
@override
|
|
Component get component => compilerResult.ddcResult.component;
|
|
}
|
|
|
|
/// Base class for computing id-test data from a DDC compilation.
|
|
abstract class DdcDataComputer<T> extends DataComputer<T, TestConfig,
|
|
MemoryCompilerResult, DdcTestResultData> {
|
|
const DdcDataComputer();
|
|
}
|
|
|
|
/// Creates a test runner for [dataComputer] on [testedConfigs].
|
|
RunTestFunction<T> runTestFor<T>(
|
|
DdcDataComputer<T> dataComputer, List<DdcTestConfig> testedConfigs) {
|
|
return (MarkerOptions markerOptions, TestData testData,
|
|
{required bool testAfterFailures,
|
|
required bool verbose,
|
|
required bool succinct,
|
|
required bool printCode,
|
|
Map<String, List<String>>? skipMap,
|
|
required Uri nullUri}) {
|
|
return runTest(markerOptions, testData, dataComputer, testedConfigs,
|
|
testAfterFailures: testAfterFailures,
|
|
verbose: verbose,
|
|
succinct: succinct,
|
|
printCode: printCode,
|
|
onFailure: onFailure,
|
|
skipMap: skipMap,
|
|
nullUri: nullUri);
|
|
};
|
|
}
|
|
|
|
/// Runs [dataComputer] on [testData] for each [testedConfigs].
|
|
Future<Map<String, TestResult<T>>> runTest<T>(
|
|
MarkerOptions markerOptions,
|
|
TestData testData,
|
|
DdcDataComputer<T> dataComputer,
|
|
List<DdcTestConfig> testedConfigs,
|
|
{required bool testAfterFailures,
|
|
required bool verbose,
|
|
required bool succinct,
|
|
required bool printCode,
|
|
bool forUserLibrariesOnly = true,
|
|
Iterable<Id> globalIds = const <Id>[],
|
|
required void Function(String message) onFailure,
|
|
Map<String, List<String>>? skipMap,
|
|
required Uri nullUri}) async {
|
|
var results = <String, TestResult<T>>{};
|
|
for (var config in testedConfigs) {
|
|
results[config.marker] = await runTestForConfig(
|
|
markerOptions, testData, dataComputer, config,
|
|
fatalErrors: !testAfterFailures,
|
|
onFailure: onFailure,
|
|
verbose: verbose,
|
|
succinct: succinct,
|
|
printCode: printCode,
|
|
nullUri: nullUri);
|
|
}
|
|
return results;
|
|
}
|
|
|
|
/// Computes the [TestResult] for running [dataComputer] on [testData] for
|
|
/// the given test [config].
|
|
Future<TestResult<T>> runTestForConfig<T>(MarkerOptions markerOptions,
|
|
TestData testData, DdcDataComputer<T> dataComputer, DdcTestConfig config,
|
|
{required bool fatalErrors,
|
|
required bool verbose,
|
|
required bool succinct,
|
|
required bool printCode,
|
|
bool forUserLibrariesOnly = true,
|
|
Iterable<Id> globalIds = const <Id>[],
|
|
required void Function(String message) onFailure,
|
|
required Uri nullUri}) async {
|
|
var result = await compileFromMemory(
|
|
testData.memorySourceFiles, testData.entryPoint,
|
|
explicitExperimentalFlags: config.experimentalFlags);
|
|
|
|
var errors = <FormattedMessage>[];
|
|
for (var error in result.errors) {
|
|
if (error is FormattedMessage) {
|
|
errors.add(error);
|
|
}
|
|
}
|
|
var testResultData = DdcTestResultData(config, result);
|
|
return processCompiledResult(
|
|
markerOptions, testData, dataComputer, testResultData, errors,
|
|
fatalErrors: fatalErrors,
|
|
verbose: verbose,
|
|
succinct: succinct,
|
|
onFailure: onFailure,
|
|
nullUri: nullUri);
|
|
}
|
|
|
|
/// Base class for extracting AST-based test data from a DDC compilation.
|
|
class DdcDataExtractor<T> extends DataExtractor<T> {
|
|
final MemoryCompilerResult compilerResult;
|
|
|
|
DdcDataExtractor(this.compilerResult, super.actualMap);
|
|
|
|
@override
|
|
void fail(String message) {
|
|
onFailure(message);
|
|
}
|
|
|
|
@override
|
|
void report(Uri uri, int offset, String message) {
|
|
printMessageInLocation(
|
|
compilerResult.ddcResult.component.uriToSource, uri, offset, message);
|
|
}
|
|
}
|