Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions build_runner/lib/src/build/resolver/analysis_driver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@
import 'dart:io';

import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
// ignore: implementation_imports
import 'package:analyzer/src/clients/build_resolvers/build_resolvers.dart';
import 'package:package_config/package_config.dart' show PackageConfig;
import 'package:path/path.dart' as p;
import 'package:pub_semver/pub_semver.dart';

import 'analysis_driver_filesystem.dart';
import 'analysis_driver_model.dart';
import 'build_resolvers.dart';

/// Builds an [AnalysisDriverForPackageBuild] backed by a summary SDK.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.

import 'dart:convert';
import 'dart:io' as io;

import 'dart:typed_data';

import 'package:analyzer/file_system/file_system.dart';
Expand All @@ -28,7 +30,14 @@ class AnalysisDriverFilesystem implements UriResolver, ResourceProvider {
/// Reads the data previously written to [path].
///
/// Throws if ![exists].
String read(String path) => _data[path]!;
String read(String path) {
if (path.contains('/sdk/') || path.contains('/dart-sdk/')) {
return io.File(path).readAsStringSync();
}
final result = _data[path];
if (result == null) throw ArgumentError('Path does not exist: $path');
return result;
}

/// Deletes the data previously written to [path].
///
Expand Down Expand Up @@ -171,6 +180,9 @@ class _Resource implements File, Folder {
@override
String get shortName => filesystem.pathContext.basename(path);

@override
Folder get parent => _Resource(filesystem, p.dirname(path));

// `File` methods.
@override
Uint8List readAsBytesSync() {
Expand All @@ -183,6 +195,9 @@ class _Resource implements File, Folder {
@override
String readAsStringSync() => filesystem.read(path);

@override
String canonicalizePath(String path) => path;

// Analyzer methods such as `CompilationUnitElement.source` provide access to
// source and return a `TimestampedData` with this value.
//
Expand All @@ -198,6 +213,14 @@ class _Resource implements File, Folder {
bool contains(String path) =>
filesystem.pathContext.isWithin(this.path, path);

@override
File getChildAssumingFile(String relPath) =>
_Resource(filesystem, '$path/$relPath');

@override
Folder getChildAssumingFolder(String relPath) =>
_Resource(filesystem, '$path/$relPath');

// Most `File` and/or `Folder` methods are not needed.

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

import 'dart:async';

// ignore: implementation_imports
import 'package:analyzer/src/clients/build_resolvers/build_resolvers.dart';
import 'package:build/build.dart';

import '../../logging/timed_activities.dart';
Expand All @@ -15,6 +13,8 @@ import '../library_cycle_graph/library_cycle_graph_loader.dart';
import '../library_cycle_graph/phased_asset_deps.dart';
import 'analysis_driver_filesystem.dart';

import 'build_resolvers.dart';

/// Manages analysis driver and related build state.
///
/// - Tracks the import graph of all sources needed for analysis.
Expand Down
160 changes: 160 additions & 0 deletions build_runner/lib/src/build/resolver/build_resolvers.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// Copyright (c) 2021, 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.

// ignore_for_file: implementation_imports

import 'dart:io';
import 'dart:io' as io;
import 'dart:typed_data';

import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/dart/analysis/analysis_options.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/packages.dart';
import 'package:analyzer/src/dart/analysis/analysis_options.dart';
import 'package:analyzer/src/dart/analysis/analysis_options_map.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_content_cache.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/summary_sdk.dart';
import 'package:analyzer/src/summary2/package_bundle_format.dart';
import 'package:package_config/package_config_types.dart';
import 'package:path/path.dart' as p;
import 'package:yaml/yaml.dart';

export 'package:analyzer/dart/analysis/analysis_options.dart'
show AnalysisOptions;
export 'package:analyzer/source/source.dart' show Source;
export 'package:analyzer/src/context/packages.dart' show Package, Packages;
export 'package:analyzer/src/dart/analysis/analysis_options.dart'
show AnalysisOptionsImpl;
export 'package:analyzer/src/dart/analysis/byte_store.dart' show ByteStore;
export 'package:analyzer/src/dart/analysis/experiments.dart'
show ExperimentStatus;
export 'package:analyzer/src/generated/source.dart' show UriResolver;

/// A somewhat low level API to create [AnalysisSession].
///
/// Ideally we want clients to use [AnalysisContextCollection], which
/// encapsulates any internals and is driven by `package_config.json` and
/// `analysis_options.yaml` files. But so far it looks that `build_resolvers`
/// wants to provide [UriResolver], and push [Packages] created by other means
/// than parsing `package_config.json`.
AnalysisDriverForPackageBuild createAnalysisDriver({
required ResourceProvider resourceProvider,
required Uint8List sdkSummaryBytes,
required AnalysisOptions analysisOptions,
FileContentCache? fileContentCache,
required List<UriResolver> uriResolvers,
required Packages packages,
ByteStore? byteStore,
}) {
final sdkBundle = PackageBundleReader(sdkSummaryBytes);
final bundleSdk = SummaryBasedDartSdk.forBundle(sdkBundle);

final runningDartSdkPath = p.dirname(p.dirname(Platform.resolvedExecutable));

AbstractDartSdk sdk = FolderBasedDartSdk(
resourceProvider,
resourceProvider.getFolder(runningDartSdkPath),
);

final dartUiPath = p.normalize(
p.join(runningDartSdkPath, '..', 'pkg', 'sky_engine', 'lib'),
);
final isFlutter =
Platform.version.contains('flutter') ||
Directory(dartUiPath).existsSync();
if (isFlutter) {
final embedderYamlPath = p.join(dartUiPath, '_embedder.yaml');
final content = io.File(embedderYamlPath).readAsStringSync();
final map = loadYaml(content) as YamlMap;
final embedderSdk = EmbedderSdk(resourceProvider, {
resourceProvider.getFolder(p.dirname(embedderYamlPath)): map,
}, languageVersion: sdk.languageVersion);
for (final library in embedderSdk.sdkLibraries) {
final uriStr = library.shortName;
if (sdk.libraryMap.getLibrary(uriStr) == null) {
sdk.libraryMap.setLibrary(uriStr, library);
}
}
}

//final sourceFactory = SourceFactory([DartUriResolver(sdk), ...uriResolvers]);
final sourceFactory = SourceFactory([DartUriResolver(sdk), ...uriResolvers]);

//final dataStore = SummaryDataStore();
//dataStore.addBundle('', sdkBundle);

final logger = PerformanceLog(null);
byteStore ??= MemoryByteStore();

final scheduler = AnalysisDriverScheduler(logger);
scheduler.events.drain<void>().ignore();

final sharedOptions = analysisOptions as AnalysisOptionsImpl;
final optionsMap = AnalysisOptionsMap.forSharedOptions(sharedOptions);
final driver = AnalysisDriver(
scheduler: scheduler,
logger: logger,
resourceProvider: resourceProvider,
byteStore: byteStore,
sourceFactory: sourceFactory,
analysisOptionsMap: optionsMap,
fileContentCache: fileContentCache,
// externalSummaries: dataStore,
packages: packages,
withFineDependencies: true,
shouldReportInconsistentAnalysisException: false,
);

scheduler.start();

return AnalysisDriverForPackageBuild._(bundleSdk.libraryUris, driver);
}

/// [AnalysisSession] plus a tiny bit more.
class AnalysisDriverForPackageBuild {
final List<Uri> _sdkLibraryUris;
final AnalysisDriver _driver;

AnalysisDriverForPackageBuild._(this._sdkLibraryUris, this._driver);

AnalysisSession get currentSession {
return _driver.currentSession;
}

/// Returns URIs of libraries in the given SDK.
List<Uri> get sdkLibraryUris {
return _sdkLibraryUris;
}

/// Return a [Future] that completes after pending file changes are applied,
/// so that [currentSession] can be used to compute results.
Future<void> applyPendingFileChanges() {
return _driver.applyPendingFileChanges();
}

/// The file with the given [path] might have changed - updated, added or
/// removed. Or not, we don't know. Or it might have, but then changed back.
///
/// The [path] must be absolute and normalized.
///
/// The [currentSession] most probably will be invalidated.
/// Note, is does NOT at the time of writing this comment.
/// But we are going to fix this.
void changeFile(String path) {
_driver.changeFile(path);
}

/// Return `true` if the [uri] can be resolved to an existing file.
bool isUriOfExistingFile(Uri uri) {
final source = _driver.sourceFactory.forUri2(uri);
return source != null && source.exists();
}
}
3 changes: 1 addition & 2 deletions build_runner/lib/src/build/resolver/resolver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/error/error.dart';
// ignore: implementation_imports
import 'package:analyzer/src/clients/build_resolvers/build_resolvers.dart';
import 'package:async/async.dart';
import 'package:build/build.dart';
import 'package:build/experiments.dart';
Expand All @@ -27,6 +25,7 @@ import '../../logging/timed_activities.dart';
import 'analysis_driver.dart';
import 'analysis_driver_filesystem.dart';
import 'analysis_driver_model.dart';
import 'build_resolvers.dart';
import 'sdk_summary.dart';
import 'shared_resource_pool.dart';

Expand Down
6 changes: 6 additions & 0 deletions build_runner/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,11 @@ dev_dependencies:
test: ^1.25.5
test_descriptor: ^2.0.0

dependency_overrides:
analyzer:
path: ../../dart-sdk/sdk/pkg/analyzer
_fe_analyzer_shared:
path: ../../dart-sdk/sdk/pkg/_fe_analyzer_shared

topics:
- build-runner
Loading