e20704c3b0
Move PackageConfigFileBuilder into the analyzer_testing public API and deprecate the copy exposed from package:analyzer. The builder is only used by test infrastructure, so keeping it in analyzer_testing makes the ownership clearer and avoids exposing test-only utilities from analyzer. Update the builder API to accept a rootFolder instead of a rootPath. This lets callers pass the resource-provider folder directly, so the generated rootUri is derived from the same file-system abstraction that created the test files. This avoids accidentally passing POSIX paths where resource provider paths are required, such as on Windows. Update existing test utilities and callers to import the new library and pass Folder objects. Remove the production analysis server dependency on the builder by emitting the temporary plugin package config JSON directly. Change-Id: I46b14710626e0d6d5884afcdc5a05b23077acfc9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/499081 Reviewed-by: Paul Berry <paulberry@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com> Reviewed-by: Samuel Rawlins <srawlins@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
179 lines
5.6 KiB
Dart
179 lines
5.6 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/results.dart';
|
|
import 'package:analyzer/dart/analysis/session.dart';
|
|
import 'package:analyzer/file_system/file_system.dart';
|
|
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
|
|
import 'package:analyzer/src/dart/analysis/byte_store.dart';
|
|
import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
|
|
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
|
|
import 'package:analyzer_testing/experiments/experiments.dart';
|
|
import 'package:analyzer_testing/mock_packages/mock_packages.dart';
|
|
import 'package:analyzer_testing/package_config_file_builder.dart';
|
|
import 'package:analyzer_testing/resource_provider_mixin.dart';
|
|
import 'package:linter/src/rules.dart';
|
|
import 'package:meta/meta.dart';
|
|
|
|
class AbstractContextTest with MockPackagesMixin, ResourceProviderMixin {
|
|
final ByteStore _byteStore = MemoryByteStore();
|
|
|
|
final Map<String, String> _declaredVariables = {};
|
|
|
|
AnalysisContextCollection? _analysisContextCollection;
|
|
|
|
List<String> get collectionIncludedPaths => [workspaceRootPath];
|
|
|
|
/// Return a list of the experiments that are to be enabled for tests in this
|
|
/// class, an empty list if there are no experiments that should be enabled.
|
|
List<String> get experiments => experimentsForTests;
|
|
|
|
@override
|
|
String get packagesRootPath => '/packages';
|
|
|
|
Folder get sdkRoot => newFolder('/sdk');
|
|
|
|
Future<AnalysisSession> get session => sessionFor(testPackageRootPath);
|
|
|
|
/// The file system-specific `analysis_options.yaml` path.
|
|
String get testPackageAnalysisOptionsPath =>
|
|
convertPath('$testPackageRootPath/analysis_options.yaml');
|
|
|
|
String? get testPackageLanguageVersion => null;
|
|
|
|
/// 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');
|
|
|
|
void addSource(String path, String content) {
|
|
newFile(path, content);
|
|
}
|
|
|
|
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, buffer.toString());
|
|
}
|
|
|
|
@override
|
|
File newFile(String path, String content) {
|
|
if (_analysisContextCollection != null && !path.endsWith('.dart')) {
|
|
throw StateError('Only dart files can be changed after analysis.');
|
|
}
|
|
|
|
return super.newFile(path, content);
|
|
}
|
|
|
|
Future<ResolvedUnitResult> resolveFile(String path) async {
|
|
var session = await sessionFor(path);
|
|
return await session.getResolvedUnit(path) as ResolvedUnitResult;
|
|
}
|
|
|
|
Future<AnalysisSession> sessionFor(String path) async {
|
|
var analysisContext = contextFor(path);
|
|
await analysisContext.applyPendingFileChanges();
|
|
return analysisContext.currentSession;
|
|
}
|
|
|
|
@mustCallSuper
|
|
void setUp() {
|
|
createMockSdk(resourceProvider: resourceProvider, root: sdkRoot);
|
|
|
|
newFolder(testPackageRootPath);
|
|
writeTestPackageConfig();
|
|
createAnalysisOptionsFile(experiments: experiments);
|
|
}
|
|
|
|
@mustCallSuper
|
|
void tearDown() {
|
|
AnalysisEngine.instance.clearCaches();
|
|
}
|
|
|
|
void writePackageConfig(String path, PackageConfigFileBuilder config) {
|
|
newFile(path, config.toContent());
|
|
}
|
|
|
|
/// Write an analysis options file based on the given arguments.
|
|
// TODO(asashour): Use AnalysisOptionsFileConfig
|
|
void writeTestPackageAnalysisOptionsFile({List<String>? lints}) {
|
|
var buffer = StringBuffer();
|
|
|
|
if (lints != null) {
|
|
registerLintRules();
|
|
buffer.writeln('linter:');
|
|
buffer.writeln(' rules:');
|
|
for (var lint in lints) {
|
|
buffer.writeln(' - $lint');
|
|
}
|
|
}
|
|
|
|
newFile(testPackageAnalysisOptionsPath, buffer.toString());
|
|
}
|
|
|
|
void writeTestPackageConfig({
|
|
PackageConfigFileBuilder? config,
|
|
String? languageVersion,
|
|
bool meta = false,
|
|
}) {
|
|
if (config == null) {
|
|
config = PackageConfigFileBuilder();
|
|
} else {
|
|
config = config.copy();
|
|
}
|
|
|
|
config.add(
|
|
name: 'test',
|
|
rootFolder: getFolder(testPackageRootPath),
|
|
languageVersion: languageVersion ?? testPackageLanguageVersion,
|
|
);
|
|
|
|
if (meta) {
|
|
var metaRoot = addMeta().parent;
|
|
config.add(name: 'meta', rootFolder: metaRoot);
|
|
}
|
|
|
|
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: sdkRoot.path,
|
|
withFineDependencies: true,
|
|
);
|
|
}
|
|
}
|