Files
sdk/pkg/analyzer_plugin/test/support/abstract_context.dart
T
Sam Rawlins 38e3414748 analyzer_plugin: Prepare tests for Null safety flag flip.
Only one test suite featured tests which needed to be in Null safety, so
that was split into two suites. Otherwise, the changes very nearly mirror
those in https://dart-review.googlesource.com/c/sdk/+/169141.


Bug: https://github.com/dart-lang/sdk/issues/43777
Change-Id: I39219dc0157ac33d4be1d902930060577e659cad
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/169244
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
2020-10-28 04:26:17 +00:00

209 lines
6.5 KiB
Dart

// Copyright (c) 2017, 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:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/testing/element_search.dart';
import 'package:analyzer/src/test_utilities/mock_packages.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:meta/meta.dart';
/// Finds an [Element] with the given [name].
Element findChildElement(Element root, String name, [ElementKind kind]) {
Element result;
root.accept(_ElementVisitorFunctionWrapper((Element element) {
if (element.name != name) {
return;
}
if (kind != null && element.kind != kind) {
return;
}
result = element;
}));
return result;
}
/// A function to be called for every [Element].
typedef _ElementVisitorFunction = void Function(Element element);
class AbstractContextTest with ResourceProviderMixin {
final ByteStore _byteStore = MemoryByteStore();
final Map<String, String> _declaredVariables = {};
AnalysisContextCollection _analysisContextCollection;
List<String> get collectionIncludedPaths => [workspaceRootPath];
AnalysisSession get session => contextFor(testPackageRootPath).currentSession;
/// The file system-specific `analysis_options.yaml` path.
String get testPackageAnalysisOptionsPath =>
convertPath('$testPackageRootPath/analysis_options.yaml');
String get testPackageLanguageVersion => '2.9';
/// The file system-specific `pubspec.yaml` path.
String get testPackagePubspecPath =>
convertPath('$testPackageRootPath/pubspec.yaml');
String get testPackageRootPath => convertPath('/home/test');
String get workspaceRootPath => convertPath('/home');
Source addSource(String path, String content, [Uri uri]) {
var file = newFile(path, content: content);
var source = file.createSource(uri);
return source;
}
AnalysisContext contextFor(String path) {
_createAnalysisContexts();
path = convertPath(path);
return _analysisContextCollection.contextFor(path);
}
/// Create an analysis options file based on the given arguments.
void createAnalysisOptionsFile({List<String> experiments}) {
var buffer = StringBuffer();
buffer.writeln('analyzer:');
if (experiments != null) {
buffer.writeln(' enable-experiment:');
for (var experiment in experiments) {
buffer.writeln(' - $experiment');
}
}
newFile(testPackageAnalysisOptionsPath, content: buffer.toString());
}
AnalysisDriver driverFor(String path) {
var context = contextFor(path) as DriverBasedAnalysisContext;
return context.driver;
}
Element findElementInUnit(CompilationUnit unit, String name,
[ElementKind kind]) {
return findElementsByName(unit, name)
.where((e) => kind == null || e.kind == kind)
.single;
}
Future<ResolvedUnitResult> resolveFile(String path) async {
return contextFor(path).currentSession.getResolvedUnit(path);
}
void setUp() {
MockSdk(resourceProvider: resourceProvider);
newFolder(testPackageRootPath);
writeTestPackageConfig();
}
void tearDown() {
AnalysisEngine.instance.clearCaches();
}
void writePackageConfig(String path, PackageConfigFileBuilder config) {
newFile(path, content: config.toContent(toUriStr: toUriStr));
}
void writeTestPackageConfig({
PackageConfigFileBuilder config,
String languageVersion,
bool meta = false,
}) {
if (config == null) {
config = PackageConfigFileBuilder();
} else {
config = config.copy();
}
config.add(
name: 'test',
rootPath: testPackageRootPath,
languageVersion: languageVersion ?? testPackageLanguageVersion,
);
if (meta) {
var metaPath = '/packages/meta';
MockPackages.addMetaPackageFiles(
getFolder(metaPath),
);
config.add(name: 'meta', rootPath: metaPath);
}
var path = '$testPackageRootPath/.dart_tool/package_config.json';
writePackageConfig(path, config);
}
/// Create all analysis contexts in [collectionIncludedPaths].
void _createAnalysisContexts() {
if (_analysisContextCollection != null) {
return;
}
_analysisContextCollection = AnalysisContextCollectionImpl(
byteStore: _byteStore,
declaredVariables: _declaredVariables,
enableIndex: true,
includedPaths: collectionIncludedPaths.map(convertPath).toList(),
resourceProvider: resourceProvider,
sdkPath: convertPath('/sdk'),
);
}
}
mixin WithNullSafetyMixin on AbstractContextTest {
@override
String get testPackageLanguageVersion =>
Feature.non_nullable.isEnabledByDefault ? '2.12' : '2.11';
bool get withPackageMeta => false;
/// TODO(scheglov) https://github.com/dart-lang/sdk/issues/43837
/// Remove when Null Safety is enabled by default.
@nonVirtual
@override
void setUp() {
super.setUp();
writeTestPackageConfig(
languageVersion: testPackageLanguageVersion,
meta: withPackageMeta,
);
createAnalysisOptionsFile(experiments: [EnableString.non_nullable]);
}
}
/// Wraps the given [_ElementVisitorFunction] into an instance of
/// [engine.GeneralizingElementVisitor].
class _ElementVisitorFunctionWrapper extends GeneralizingElementVisitor {
final _ElementVisitorFunction function;
_ElementVisitorFunctionWrapper(this.function);
@override
void visitElement(Element element) {
function(element);
super.visitElement(element);
}
}