Skip to content

Commit

Permalink
Revert "options map support scaffolding in driver"
Browse files Browse the repository at this point in the history
This reverts commit 717ce7a.

Reason for revert: breaking Google3

Original change's description:
> options map support scaffolding in driver
>
> Konstantin and I chatted a bit about this so at least some of it shouldn't be too surprising to him but please do feel free to grab me to chat.
>
> That said a few pointers would be handy. Notably, this change:
>
> * introduces a new `SharedOptionsOptionsMap` for use in SDK drivers (and preserve current semantics)
>   * this is currently public but will be private once driver is more evolved to accommodate multiple options files
> * removes the shared `_analysisOptions` from the analysis driver with a baby step to using the one shared in SharedOptionsOptionsMap
> * removes context_builder and collection v2 experiments (and tests)
>   * I'll harvest some more functionality from these in future changes but for now they're distracting and hard to maintain
>
> This work is all to setup moving analysis options awareness into file state objects which will allow us to remove `sdkVersionConstraint` info from options (finally) and a host of other good stuff (see #54124).
>
>
>
> Change-Id: Ic4278184016d1018b4b5b1c6ac5ba9e2546927a5
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/344860
> Reviewed-by: Brian Wilkerson <[email protected]>
> Reviewed-by: Konstantin Shcheglov <[email protected]>
> Commit-Queue: Phil Quitslund <[email protected]>

Change-Id: Ia988c5c9cd328d0adce3d8e6ff019e389819a957
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/344960
Auto-Submit: Phil Quitslund <[email protected]>
Bot-Commit: Rubber Stamper <[email protected]>
Reviewed-by: Konstantin Shcheglov <[email protected]>
Commit-Queue: Konstantin Shcheglov <[email protected]>
  • Loading branch information
pq authored and Commit Queue committed Jan 5, 2024
1 parent 437767f commit 3e319ba
Show file tree
Hide file tree
Showing 12 changed files with 996 additions and 135 deletions.
4 changes: 1 addition & 3 deletions pkg/analyzer/lib/dart/sdk/build_sdk_summary.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import 'dart:typed_data';

import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/packages.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/performance_logger.dart';
Expand Down Expand Up @@ -50,7 +49,6 @@ Future<Uint8List> buildSdkSummary({

final logger = PerformanceLog(StringBuffer());
final scheduler = AnalysisDriverScheduler(logger);
final optionsMap = AnalysisOptionsMap.forSharedOptions(AnalysisOptionsImpl());
final analysisDriver = AnalysisDriver(
scheduler: scheduler,
logger: logger,
Expand All @@ -59,7 +57,7 @@ Future<Uint8List> buildSdkSummary({
sourceFactory: SourceFactory([
DartUriResolver(sdk),
]),
analysisOptionsMap: optionsMap,
analysisOptions: AnalysisOptionsImpl(),
packages: Packages({}),
);
scheduler.start();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import 'package:analyzer/dart/analysis/analysis_context_collection.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_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/performance_logger.dart';
Expand Down Expand Up @@ -54,15 +53,13 @@ AnalysisDriverForPackageBuild createAnalysisDriver({

var logger = PerformanceLog(null);
var scheduler = AnalysisDriverScheduler(logger);
var sharedOptions = analysisOptions as AnalysisOptionsImpl;
var optionsMap = AnalysisOptionsMap.forSharedOptions(sharedOptions);
var driver = AnalysisDriver(
scheduler: scheduler,
logger: logger,
resourceProvider: resourceProvider,
byteStore: byteStore ?? MemoryByteStore(),
sourceFactory: sourceFactory,
analysisOptionsMap: optionsMap,
analysisOptions: analysisOptions as AnalysisOptionsImpl,
externalSummaries: dataStore,
packages: packages,
);
Expand Down
178 changes: 178 additions & 0 deletions pkg/analyzer/lib/src/dart/analysis/analysis_context_collection2.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
// Copyright (c) 2018, 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_collection.dart';
import 'package:analyzer/dart/analysis/context_root.dart';
import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/context_builder2.dart';
import 'package:analyzer/src/dart/analysis/context_locator2.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/file_content_cache.dart';
import 'package:analyzer/src/dart/analysis/info_declaration_store.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/analysis/unlinked_unit_store.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/summary2/kernel_compilation_service.dart';
import 'package:analyzer/src/summary2/macro.dart';
import 'package:analyzer/src/util/sdk.dart';

/// An implementation of [AnalysisContextCollection].
class AnalysisContextCollectionImpl2 implements AnalysisContextCollection {
/// The resource provider used to access the file system.
final ResourceProvider resourceProvider;

/// The support for executing macros.
late final MacroSupport macroSupport;

/// The shared container into which drivers record files ownership.
final OwnedFiles ownedFiles = OwnedFiles();

/// The list of analysis contexts.
@override
final List<DriverBasedAnalysisContext> contexts = [];

/// Initialize a newly created analysis context manager.
AnalysisContextCollectionImpl2({
ByteStore? byteStore,
Map<String, String>? declaredVariables,
bool drainStreams = true,
bool enableIndex = false,
required List<String> includedPaths,
List<String>? excludedPaths,
List<String>? librarySummaryPaths,
String? optionsFile,
String? packagesFile,
PerformanceLog? performanceLog,
ResourceProvider? resourceProvider,
bool retainDataForTesting = false,
String? sdkPath,
String? sdkSummaryPath,
AnalysisDriverScheduler? scheduler,
FileContentCache? fileContentCache,
UnlinkedUnitStore? unlinkedUnitStore,
InfoDeclarationStore? infoDeclarationStore,
@Deprecated('Use updateAnalysisOptions2, which must be a function that '
'accepts a second parameter')
void Function(AnalysisOptionsImpl)? updateAnalysisOptions,
void Function({
required AnalysisOptionsImpl analysisOptions,
required ContextRoot contextRoot,
required DartSdk sdk,
})? updateAnalysisOptions2,
MacroSupport? macroSupport,
}) : resourceProvider =
resourceProvider ?? PhysicalResourceProvider.INSTANCE {
sdkPath ??= getSdkPath();

_throwIfAnyNotAbsoluteNormalizedPath(includedPaths);
_throwIfNotAbsoluteNormalizedPath(sdkPath);

if (updateAnalysisOptions != null && updateAnalysisOptions2 != null) {
throw ArgumentError(
'Either updateAnalysisOptions or updateAnalysisOptions2 must be '
'given, but not both.');
}

this.macroSupport = macroSupport ??= KernelMacroSupport();

var contextLocator = ContextLocatorImpl2(
resourceProvider: this.resourceProvider,
);
var roots = contextLocator.locateRoots(
includedPaths: includedPaths,
excludedPaths: excludedPaths,
optionsFile: optionsFile,
packagesFile: packagesFile,
);
for (var root in roots) {
var contextBuilder = ContextBuilderImpl2(
resourceProvider: this.resourceProvider,
);
var context = contextBuilder.createContext(
byteStore: byteStore,
contextRoot: root,
declaredVariables: DeclaredVariables.fromMap(declaredVariables ?? {}),
drainStreams: drainStreams,
enableIndex: enableIndex,
librarySummaryPaths: librarySummaryPaths,
performanceLog: performanceLog,
retainDataForTesting: retainDataForTesting,
sdkPath: sdkPath,
sdkSummaryPath: sdkSummaryPath,
scheduler: scheduler,
// ignore: deprecated_member_use_from_same_package
updateAnalysisOptions: updateAnalysisOptions,
updateAnalysisOptions2: updateAnalysisOptions2,
fileContentCache: fileContentCache,
unlinkedUnitStore: unlinkedUnitStore ?? UnlinkedUnitStoreImpl(),
infoDeclarationStore: infoDeclarationStore,
macroSupport: macroSupport,
ownedFiles: ownedFiles,
);
contexts.add(context);
}
}

/// Return `true` if the read state of configuration files is consistent
/// with their current state on the file system. We use this as a work
/// around an issue with watching for file system changes.
bool get areWorkspacesConsistent {
for (var analysisContext in contexts) {
var contextRoot = analysisContext.contextRoot;
var workspace = contextRoot.workspace;
if (!workspace.isConsistentWithFileSystem) {
return false;
}
}
return true;
}

@override
DriverBasedAnalysisContext contextFor(String path) {
_throwIfNotAbsoluteNormalizedPath(path);

for (var context in contexts) {
if (context.contextRoot.isAnalyzed(path)) {
return context;
}
}

throw StateError('Unable to find the context to $path');
}

Future<void> dispose({
bool forTesting = false,
}) async {
for (final analysisContext in contexts) {
await analysisContext.driver.dispose2();
}
await macroSupport.dispose();
// If there are other collections, they will have to start it again.
if (!forTesting) {
await KernelCompilationService.dispose();
}
}

/// Check every element with [_throwIfNotAbsoluteNormalizedPath].
void _throwIfAnyNotAbsoluteNormalizedPath(List<String> paths) {
for (var path in paths) {
_throwIfNotAbsoluteNormalizedPath(path);
}
}

/// The driver supports only absolute normalized paths, this method is used
/// to validate any input paths to prevent errors later.
void _throwIfNotAbsoluteNormalizedPath(String path) {
var pathContext = resourceProvider.pathContext;
if (!pathContext.isAbsolute(path) || pathContext.normalize(path) != path) {
throw ArgumentError(
'Only absolute normalized paths are supported: $path');
}
}
}
48 changes: 8 additions & 40 deletions pkg/analyzer/lib/src/dart/analysis/analysis_options_map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,29 @@
// 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_options.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/clients/build_resolvers/build_resolvers.dart';

/// Instances of the class [AnalysisOptionsMap] map [File]s under analysis to
/// their corresponding [AnalysisOptions].
/// Instances of the class [AnalysisOptionsMap] map [File]s under analysis to their
/// corresponding [AnalysisOptions].
class AnalysisOptionsMap {
final List<OptionsMapEntry> entries = [];

/// Create an empty [AnalysisOptionsMap] instance.
AnalysisOptionsMap();
// TODO(pq): final backing representation TBD.
final List<({Folder folder, AnalysisOptions options})> _entries = [];

/// Map this [folder] to the given [options].
void add(Folder folder, AnalysisOptions options) {
entries.add(OptionsMapEntry(folder, options));
_entries.add((folder: folder, options: options));
// Sort entries by (reverse) containment (for now).
entries.sort((e1, e2) => e1.folder.contains(e2.folder.path) ? 1 : -1);
_entries.sort((e1, e2) => e1.folder.contains(e2.folder.path) ? 1 : -1);
}

/// Get the [AnalysisOptions] instance for the given [file] (or `null` if none
/// has been set).
AnalysisOptions? getOptions(File file) {
for (var entry in entries) {
for (var entry in _entries) {
if (entry.folder.contains(file.path)) return entry.options;
}

return null;
}

/// Create an [AnalysisOptionsMap] that holds one set of [sharedOptions] for all
/// associated files.
// TODO(pq): replace w/ a factory constructor when SharedOptionsOptionsMap is made private
static SharedOptionsOptionsMap forSharedOptions(
AnalysisOptionsImpl sharedOptions) =>
SharedOptionsOptionsMap(sharedOptions);
}

/// Instances of [OptionsMapEntry] associate [Folder]s with their
/// corresponding [AnalysisOptions].
class OptionsMapEntry {
/// The folder containing an options file.
final Folder folder;

/// The corresponding options object.
final AnalysisOptions options;

/// Create a new entry for the give [folder] and corresponding [options];
OptionsMapEntry(this.folder, this.options);
}

// TODO(pq): make private when no longer referenced.
class SharedOptionsOptionsMap extends AnalysisOptionsMap {
/// The [entries] list is empty but that's OK. We'll always just return
/// the shared options.
final AnalysisOptionsImpl sharedOptions;
SharedOptionsOptionsMap(this.sharedOptions);
@override
AnalysisOptions getOptions(File file) => sharedOptions;
}
67 changes: 2 additions & 65 deletions pkg/analyzer/lib/src/dart/analysis/context_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@ import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/analysis_options/apply_options.dart';
import 'package:analyzer/src/context/builder.dart' show EmbedderYamlLocator;
import 'package:analyzer/src/context/packages.dart';
import 'package:analyzer/src/dart/analysis/analysis_options_map.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart'
show ByteStore, MemoryByteStore;
import 'package:analyzer/src/dart/analysis/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver.dart'
show
AnalysisDriver,
Expand Down Expand Up @@ -130,18 +128,17 @@ class ContextBuilderImpl implements ContextBuilder {
sdk: sdk,
);
}
// TODO(pq): replace w/ a map created directly via `_createOptionsMap`
var analysisOptionsMap = AnalysisOptionsMap.forSharedOptions(options);

final analysisContext =
DriverBasedAnalysisContext(resourceProvider, contextRoot);

var driver = AnalysisDriver(
scheduler: scheduler,
logger: performanceLog,
resourceProvider: resourceProvider,
byteStore: byteStore,
sourceFactory: sourceFactory,
analysisOptionsMap: analysisOptionsMap,
analysisOptions: options,
packages: _createPackageMap(
contextRoot: contextRoot,
),
Expand All @@ -168,66 +165,6 @@ class ContextBuilderImpl implements ContextBuilder {
return analysisContext;
}

/// Create an [AnalysisOptionsMap] for the given [contextRoot].
// ignore: unused_element
AnalysisOptionsMap _createOptionsMap(
ContextRoot contextRoot,
SourceFactory sourceFactory,
@Deprecated("Use 'updateAnalysisOptions2' instead")
void Function(AnalysisOptionsImpl p1)? updateAnalysisOptions,
void Function(
{required AnalysisOptionsImpl analysisOptions,
required ContextRoot contextRoot,
required DartSdk sdk})?
updateAnalysisOptions2,
DartSdk sdk) {
var map = AnalysisOptionsMap();
var provider = AnalysisOptionsProvider(sourceFactory);
var pubspecFile = _findPubspecFile(contextRoot);

void updateOptions(AnalysisOptionsImpl options) {
if (pubspecFile != null) {
var extractor = SdkConstraintExtractor(pubspecFile);
var sdkVersionConstraint = extractor.constraint();
if (sdkVersionConstraint != null) {
// TODO(pq): remove
// ignore: deprecated_member_use_from_same_package
options.sdkVersionConstraint = sdkVersionConstraint;
}
}
if (updateAnalysisOptions != null) {
updateAnalysisOptions(options);
} else if (updateAnalysisOptions2 != null) {
updateAnalysisOptions2(
analysisOptions: options,
contextRoot: contextRoot,
sdk: sdk,
);
}
}

var optionsMappings =
(contextRoot as ContextRootImpl).optionsFileMap.entries;

// If there are no options files, we still want to propagate sdk constraints
// and options updates to the context root.
if (optionsMappings.isEmpty) {
var options = AnalysisOptionsImpl();
updateOptions(options);
map.add(contextRoot.root, options);
} else {
for (var entry in optionsMappings) {
var options = AnalysisOptionsImpl();
var optionsYaml = provider.getOptionsFromFile(entry.value);
options.applyOptions(optionsYaml);
updateOptions(options);
map.add(entry.key, options);
}
}

return map;
}

/// Return [Packages] to analyze the [contextRoot].
///
// TODO(scheglov): Get [Packages] from [Workspace]?
Expand Down
Loading

0 comments on commit 3e319ba

Please sign in to comment.