| // Copyright (c) 2019, 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, File, Platform; | |
| import 'package:_fe_analyzer_shared/src/testing/features.dart'; | |
| import 'package:_fe_analyzer_shared/src/testing/id.dart' show Id, ActualDataMap; | |
| import 'package:_fe_analyzer_shared/src/testing/id_testing.dart'; | |
| import 'package:front_end/src/api_prototype/compiler_options.dart'; | |
| import 'package:front_end/src/api_prototype/language_version.dart' as lv; | |
| import 'package:front_end/src/base/messages.dart' show FormattedMessage; | |
| import 'package:front_end/src/builder/library_builder.dart'; | |
| import 'package:front_end/src/source/source_library_builder.dart'; | |
| import 'package:front_end/src/testing/id_testing_helper.dart' | |
| show | |
| CfeDataExtractor, | |
| CfeDataComputer, | |
| CfeTestConfig, | |
| CfeTestResultData, | |
| createUriForFileName, | |
| onFailure, | |
| runTestFor; | |
| import 'package:front_end/src/testing/id_testing_utils.dart'; | |
| import 'package:kernel/ast.dart' show Component, Library, Version; | |
| import '../utils/symbolic_language_versions.dart'; | |
| Future<void> main(List<String> args) async { | |
| // Fix default/max major and minor version so we can test it. | |
| // This config sets it to 2.8. | |
| TestConfigWithLanguageVersion cfeConfig = new TestConfigWithLanguageVersion( | |
| cfeMarker, | |
| "cfe", | |
| ); | |
| Directory dataDir = new Directory.fromUri(Platform.script.resolve('data')); | |
| await runTests<Features>( | |
| dataDir, | |
| args: args, | |
| createUriForFileName: createUriForFileName, | |
| onFailure: onFailure, | |
| runTest: runTestFor(const LanguageVersioningDataComputer(), [cfeConfig]), | |
| skipList: [ | |
| // Two language versions specified, the last one is ok and is used here. | |
| "package_default_version_is_wrong_2", | |
| ], | |
| preProcessFile: replaceMarkersWithVersions, | |
| postProcessFile: replaceVersionsWithMarkers, | |
| ); | |
| } | |
| class TestConfigWithLanguageVersion extends CfeTestConfig { | |
| new(String marker, String name) : super(marker, name); | |
| @override | |
| CompilerOptions customizeCompilerOptions( | |
| CompilerOptions options, | |
| TestData testData, | |
| ) { | |
| options.currentSdkVersion = SymbolicLanguageVersion.currentVersion.version | |
| .toText(); | |
| File f = new File.fromUri(testData.testFileUri.resolve("test.options")); | |
| if (f.existsSync()) { | |
| List<String> lines = f.readAsStringSync().split("\n"); | |
| for (String line in lines) { | |
| const String packages = "--packages="; | |
| if (line == "" || line.startsWith("#")) continue; | |
| if (line.startsWith(packages)) { | |
| String value = line.substring(packages.length); | |
| options.packagesFileUri = testData.entryPoint.resolve(value); | |
| print("Setting package file uri to ${options.packagesFileUri}"); | |
| } else { | |
| throw "Unsupported: $line"; | |
| } | |
| } | |
| } | |
| return options; | |
| } | |
| } | |
| class Tags { | |
| static const String languageVersion = 'languageVersion'; | |
| static const String packageUri = 'packageUri'; | |
| static const String errors = 'errors'; | |
| } | |
| class LanguageVersioningDataComputer extends CfeDataComputer<Features> { | |
| const new(); | |
| @override | |
| Future<void> inspectTestResultData(CfeTestResultData testResultData) async { | |
| CompilerOptions options = testResultData.customData; | |
| Component component = testResultData.compilerResult.component!; | |
| for (Library library in component.libraries) { | |
| if (library.importUri.isScheme("dart")) continue; | |
| Version lvFile = (await lv.languageVersionForUri( | |
| library.fileUri, | |
| options, | |
| )).version; | |
| Version lvImportUri = (await lv.languageVersionForUri( | |
| library.importUri, | |
| options, | |
| )).version; | |
| if ((lvFile != lvImportUri || lvFile != library.languageVersion)) { | |
| throw """ | |
| Language version disagreement: | |
| Library: ${library.languageVersion} | |
| Language version API (file URI): ${lvFile} | |
| Language version API (import URI): ${lvImportUri} | |
| """; | |
| } | |
| } | |
| } | |
| @override | |
| void computeLibraryData( | |
| CfeTestResultData testResultData, | |
| Library library, | |
| ActualDataMap<Features> actualMap, { | |
| bool? verbose, | |
| }) { | |
| new LanguageVersioningDataExtractor( | |
| testResultData.compilerResult, | |
| actualMap, | |
| ).computeForLibrary(library); | |
| } | |
| @override | |
| bool get supportsErrors => true; | |
| @override | |
| Features computeErrorData( | |
| CfeTestResultData testResultData, | |
| Id id, | |
| List<FormattedMessage> errors, | |
| ) { | |
| Features features = new Features(); | |
| features[Tags.errors] = errors.map((m) => m.code.name).join(','); | |
| return features; | |
| } | |
| @override | |
| DataInterpreter<Features> get dataValidator => | |
| const FeaturesDataInterpreter(); | |
| } | |
| class LanguageVersioningDataExtractor extends CfeDataExtractor<Features> { | |
| new(super.compilerResult, super.actualMap); | |
| @override | |
| Features computeLibraryValue(Id id, Library library) { | |
| Features features = new Features(); | |
| features[Tags.languageVersion] = | |
| "${library.languageVersion.major}.${library.languageVersion.minor}"; | |
| LibraryBuilder? libraryBuilder = lookupLibraryBuilder( | |
| compilerResult, | |
| library, | |
| ); | |
| if (libraryBuilder is SourceLibraryBuilder && | |
| libraryBuilder.packageUriForTesting != null) { | |
| features[Tags.packageUri] = libraryBuilder.packageUriForTesting | |
| .toString(); | |
| } | |
| return features; | |
| } | |
| } |