From 6a551f8d54c4accd410b709de09a2f5b1c76ef60 Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Fri, 29 May 2020 16:31:35 +0000 Subject: [PATCH] Use allowed_experiments.json when building SDK summary (reland). Landed: https://dart-review.googlesource.com/c/sdk/+/149052 Reverted: https://dart-review.googlesource.com/c/sdk/+/149201 Change-Id: Ief9430c58254fe8cbdcedc8d3678c61d4c086f67 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149364 Reviewed-by: Brian Wilkerson Commit-Queue: Konstantin Shcheglov --- .../test/context_manager_test.dart | 9 - pkg/analyzer/lib/source/embedder.dart | 5 + .../dart/analysis/feature_set_provider.dart | 18 +- pkg/analyzer/lib/src/dart/sdk/sdk.dart | 18 ++ pkg/analyzer/lib/src/generated/sdk.dart | 4 + pkg/analyzer/lib/src/summary/format.dart | 176 +++++++++++++++--- pkg/analyzer/lib/src/summary/format.fbs | 15 +- pkg/analyzer/lib/src/summary/idl.dart | 19 +- .../lib/src/summary/summary_file_builder.dart | 145 +++++++++++---- pkg/analyzer/lib/src/summary/summary_sdk.dart | 5 + .../lib/src/test_utilities/mock_sdk.dart | 32 ++-- .../tool/summary/build_sdk_summaries.dart | 18 +- pkg/analyzer_cli/lib/src/driver.dart | 7 +- utils/dartanalyzer/BUILD.gn | 4 +- 14 files changed, 340 insertions(+), 135 deletions(-) diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart index 7408c2e3aa2..d84b258f36a 100644 --- a/pkg/analysis_server/test/context_manager_test.dart +++ b/pkg/analysis_server/test/context_manager_test.dart @@ -7,27 +7,23 @@ import 'dart:async'; import 'package:analysis_server/src/context_manager.dart'; import 'package:analysis_server/src/plugin/notification_manager.dart'; import 'package:analysis_server/src/utilities/null_string_sink.dart'; -import 'package:analyzer/dart/analysis/features.dart'; import 'package:analyzer/error/error.dart'; import 'package:analyzer/exception/exception.dart'; import 'package:analyzer/file_system/file_system.dart'; import 'package:analyzer/instrumentation/instrumentation.dart'; import 'package:analyzer/source/error_processor.dart'; import 'package:analyzer/src/context/builder.dart'; -import 'package:analyzer/src/context/context.dart'; import 'package:analyzer/src/context/context_root.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_state.dart'; import 'package:analyzer/src/dart/analysis/performance_logger.dart'; -import 'package:analyzer/src/dart/analysis/session.dart'; import 'package:analyzer/src/error/codes.dart'; import 'package:analyzer/src/generated/engine.dart'; import 'package:analyzer/src/generated/sdk.dart'; import 'package:analyzer/src/generated/source.dart'; import 'package:analyzer/src/generated/source_io.dart'; import 'package:analyzer/src/services/lint.dart'; -import 'package:analyzer/src/summary/summary_file_builder.dart'; import 'package:analyzer/src/test_utilities/mock_sdk.dart'; import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart'; import 'package:analyzer/src/util/glob.dart'; @@ -1811,11 +1807,6 @@ include: package:boo/other_options.yaml var sdkExtPath = '$projPath/sdk_ext'; newFile('$projPath/test', content: 'test.dart'); newFile('$sdkExtPath/entry.dart'); - var synchronousSession = SynchronousSession(analysisOptions, null); - var bytes = - SummaryBuilder([], AnalysisContextImpl(synchronousSession, null)) - .build(featureSet: FeatureSet.fromEnableFlags([])); - newFileWithBytes('$projPath/sdk.ds', bytes); // Setup _embedder.yaml. newFile('$libPath/_embedder.yaml', content: r''' embedded_libs: diff --git a/pkg/analyzer/lib/source/embedder.dart b/pkg/analyzer/lib/source/embedder.dart index 4d57d4956c4..b9c5f9f4b2d 100644 --- a/pkg/analyzer/lib/source/embedder.dart +++ b/pkg/analyzer/lib/source/embedder.dart @@ -39,6 +39,11 @@ class EmbedderSdk extends AbstractDartSdk { } // TODO(danrubel) Determine SDK version + @override + String get allowedExperimentsJson { + return null; + } + @override String get sdkVersion => '0'; diff --git a/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart b/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart index a46645f6bed..0048c0b0bc9 100644 --- a/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart +++ b/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart @@ -4,13 +4,10 @@ import 'package:_fe_analyzer_shared/src/sdk/allowed_experiments.dart'; import 'package:analyzer/dart/analysis/features.dart'; -import 'package:analyzer/file_system/file_system.dart'; import 'package:analyzer/src/context/packages.dart'; import 'package:analyzer/src/dart/analysis/experiments.dart'; -import 'package:analyzer/src/dart/sdk/sdk.dart'; import 'package:analyzer/src/generated/sdk.dart'; import 'package:analyzer/src/generated/source.dart'; -import 'package:analyzer/src/test_utilities/mock_sdk.dart'; import 'package:meta/meta.dart'; import 'package:pub_semver/pub_semver.dart'; @@ -97,20 +94,9 @@ class FeatureSetProvider { } static AllowedExperiments _experimentsForSdk(DartSdk sdk) { - Folder sdkFolder; - if (sdk is FolderBasedDartSdk) { - sdkFolder = sdk.directory; - } else if (sdk is MockSdk) { - sdkFolder = sdk.directory; - } - - if (sdkFolder != null) { + var experimentsContent = sdk.allowedExperimentsJson; + if (experimentsContent != null) { try { - var experimentsContent = sdkFolder - .getChildAssumingFolder('lib') - .getChildAssumingFolder('_internal') - .getChildAssumingFile('allowed_experiments.json') - .readAsStringSync(); return parseAllowedExperiments(experimentsContent); } catch (_) {} } diff --git a/pkg/analyzer/lib/src/dart/sdk/sdk.dart b/pkg/analyzer/lib/src/dart/sdk/sdk.dart index 69b37225c84..94a3c43d817 100644 --- a/pkg/analyzer/lib/src/dart/sdk/sdk.dart +++ b/pkg/analyzer/lib/src/dart/sdk/sdk.dart @@ -277,6 +277,11 @@ class EmbedderSdk extends AbstractDartSdk { } } + @override + String get allowedExperimentsJson { + return null; + } + @override // TODO(danrubel) Determine SDK version String get sdkVersion => '0'; @@ -464,6 +469,19 @@ class FolderBasedDartSdk extends AbstractDartSdk { libraryMap = initialLibraryMap(); } + @override + String get allowedExperimentsJson { + try { + return _sdkDirectory + .getChildAssumingFolder('lib') + .getChildAssumingFolder('_internal') + .getChildAssumingFile('allowed_experiments.json') + .readAsStringSync(); + } catch (_) { + return null; + } + } + /** * Return the directory containing the SDK. */ diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart index e07e96eff9e..67ea8b10d9e 100644 --- a/pkg/analyzer/lib/src/generated/sdk.dart +++ b/pkg/analyzer/lib/src/generated/sdk.dart @@ -42,6 +42,10 @@ abstract class DartSdk { */ static const String DEFAULT_VERSION = "0"; + /// Return the content of the `allowed_experiments.json` file, or `null` + /// if the file cannot be read, e.g. does not exist. + String get allowedExperimentsJson; + /** * Return the analysis context used for all of the sources in this [DartSdk]. */ diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart index 7a1bfcda51e..257823f7767 100644 --- a/pkg/analyzer/lib/src/summary/format.dart +++ b/pkg/analyzer/lib/src/summary/format.dart @@ -17444,6 +17444,7 @@ class PackageBundleBuilder extends Object with _PackageBundleMixin implements idl.PackageBundle { LinkedNodeBundleBuilder _bundle2; + PackageBundleSdkBuilder _sdk; @override LinkedNodeBundleBuilder get bundle2 => _bundle2; @@ -17453,17 +17454,31 @@ class PackageBundleBuilder extends Object this._bundle2 = value; } - PackageBundleBuilder({LinkedNodeBundleBuilder bundle2}) : _bundle2 = bundle2; + @override + PackageBundleSdkBuilder get sdk => _sdk; + + /// The SDK specific data, if this bundle is for SDK. + set sdk(PackageBundleSdkBuilder value) { + this._sdk = value; + } + + PackageBundleBuilder( + {LinkedNodeBundleBuilder bundle2, PackageBundleSdkBuilder sdk}) + : _bundle2 = bundle2, + _sdk = sdk; /// Flush [informative] data recursively. void flushInformative() { _bundle2?.flushInformative(); + _sdk?.flushInformative(); } /// Accumulate non-[informative] data into [signature]. void collectApiSignature(api_sig.ApiSignature signature) { signature.addBool(this._bundle2 != null); this._bundle2?.collectApiSignature(signature); + signature.addBool(this._sdk != null); + this._sdk?.collectApiSignature(signature); } List toBuffer() { @@ -17473,13 +17488,20 @@ class PackageBundleBuilder extends Object fb.Offset finish(fb.Builder fbBuilder) { fb.Offset offset_bundle2; + fb.Offset offset_sdk; if (_bundle2 != null) { offset_bundle2 = _bundle2.finish(fbBuilder); } + if (_sdk != null) { + offset_sdk = _sdk.finish(fbBuilder); + } fbBuilder.startTable(); if (offset_bundle2 != null) { fbBuilder.addOffset(0, offset_bundle2); } + if (offset_sdk != null) { + fbBuilder.addOffset(1, offset_sdk); + } return fbBuilder.endTable(); } } @@ -17506,6 +17528,7 @@ class _PackageBundleImpl extends Object _PackageBundleImpl(this._bc, this._bcOffset); idl.LinkedNodeBundle _bundle2; + idl.PackageBundleSdk _sdk; @override idl.LinkedNodeBundle get bundle2 { @@ -17513,6 +17536,12 @@ class _PackageBundleImpl extends Object const _LinkedNodeBundleReader().vTableGet(_bc, _bcOffset, 0, null); return _bundle2; } + + @override + idl.PackageBundleSdk get sdk { + _sdk ??= const _PackageBundleSdkReader().vTableGet(_bc, _bcOffset, 1, null); + return _sdk; + } } abstract class _PackageBundleMixin implements idl.PackageBundle { @@ -17522,12 +17551,99 @@ abstract class _PackageBundleMixin implements idl.PackageBundle { if (bundle2 != null) { _result["bundle2"] = bundle2.toJson(); } + if (sdk != null) { + _result["sdk"] = sdk.toJson(); + } return _result; } @override Map toMap() => { "bundle2": bundle2, + "sdk": sdk, + }; + + @override + String toString() => convert.json.encode(toJson()); +} + +class PackageBundleSdkBuilder extends Object + with _PackageBundleSdkMixin + implements idl.PackageBundleSdk { + String _allowedExperimentsJson; + + @override + String get allowedExperimentsJson => _allowedExperimentsJson ??= ''; + + /// The content of the `allowed_experiments.json` from SDK. + set allowedExperimentsJson(String value) { + this._allowedExperimentsJson = value; + } + + PackageBundleSdkBuilder({String allowedExperimentsJson}) + : _allowedExperimentsJson = allowedExperimentsJson; + + /// Flush [informative] data recursively. + void flushInformative() {} + + /// Accumulate non-[informative] data into [signature]. + void collectApiSignature(api_sig.ApiSignature signature) { + signature.addString(this._allowedExperimentsJson ?? ''); + } + + fb.Offset finish(fb.Builder fbBuilder) { + fb.Offset offset_allowedExperimentsJson; + if (_allowedExperimentsJson != null) { + offset_allowedExperimentsJson = + fbBuilder.writeString(_allowedExperimentsJson); + } + fbBuilder.startTable(); + if (offset_allowedExperimentsJson != null) { + fbBuilder.addOffset(0, offset_allowedExperimentsJson); + } + return fbBuilder.endTable(); + } +} + +class _PackageBundleSdkReader extends fb.TableReader<_PackageBundleSdkImpl> { + const _PackageBundleSdkReader(); + + @override + _PackageBundleSdkImpl createObject(fb.BufferContext bc, int offset) => + _PackageBundleSdkImpl(bc, offset); +} + +class _PackageBundleSdkImpl extends Object + with _PackageBundleSdkMixin + implements idl.PackageBundleSdk { + final fb.BufferContext _bc; + final int _bcOffset; + + _PackageBundleSdkImpl(this._bc, this._bcOffset); + + String _allowedExperimentsJson; + + @override + String get allowedExperimentsJson { + _allowedExperimentsJson ??= + const fb.StringReader().vTableGet(_bc, _bcOffset, 0, ''); + return _allowedExperimentsJson; + } +} + +abstract class _PackageBundleSdkMixin implements idl.PackageBundleSdk { + @override + Map toJson() { + Map _result = {}; + if (allowedExperimentsJson != '') { + _result["allowedExperimentsJson"] = allowedExperimentsJson; + } + return _result; + } + + @override + Map toMap() => { + "allowedExperimentsJson": allowedExperimentsJson, }; @override @@ -19565,10 +19681,10 @@ class UnlinkedUnit2Builder extends Object List _exports; bool _hasLibraryDirective; bool _hasPartOfDirective; - String _partOfUri; List _imports; List _informativeData; List _lineStarts; + String _partOfUri; List _parts; @override @@ -19606,14 +19722,6 @@ class UnlinkedUnit2Builder extends Object this._hasPartOfDirective = value; } - @override - String get partOfUri => _partOfUri ??= ''; - - /// URI of the `part of` directive. - set partOfUri(String value) { - this._partOfUri = value; - } - @override List get imports => _imports ??= []; @@ -19640,6 +19748,14 @@ class UnlinkedUnit2Builder extends Object this._lineStarts = value; } + @override + String get partOfUri => _partOfUri ??= ''; + + /// URI of the `part of` directive. + set partOfUri(String value) { + this._partOfUri = value; + } + @override List get parts => _parts ??= []; @@ -19653,19 +19769,19 @@ class UnlinkedUnit2Builder extends Object List exports, bool hasLibraryDirective, bool hasPartOfDirective, - String partOfUri, List imports, List informativeData, List lineStarts, + String partOfUri, List parts}) : _apiSignature = apiSignature, _exports = exports, _hasLibraryDirective = hasLibraryDirective, _hasPartOfDirective = hasPartOfDirective, - _partOfUri = partOfUri, _imports = imports, _informativeData = informativeData, _lineStarts = lineStarts, + _partOfUri = partOfUri, _parts = parts; /// Flush [informative] data recursively. @@ -19731,10 +19847,10 @@ class UnlinkedUnit2Builder extends Object fb.Offset finish(fb.Builder fbBuilder) { fb.Offset offset_apiSignature; fb.Offset offset_exports; - fb.Offset offset_partOfUri; fb.Offset offset_imports; fb.Offset offset_informativeData; fb.Offset offset_lineStarts; + fb.Offset offset_partOfUri; fb.Offset offset_parts; if (!(_apiSignature == null || _apiSignature.isEmpty)) { offset_apiSignature = fbBuilder.writeListUint32(_apiSignature); @@ -19743,9 +19859,6 @@ class UnlinkedUnit2Builder extends Object offset_exports = fbBuilder .writeList(_exports.map((b) => b.finish(fbBuilder)).toList()); } - if (_partOfUri != null) { - offset_partOfUri = fbBuilder.writeString(_partOfUri); - } if (!(_imports == null || _imports.isEmpty)) { offset_imports = fbBuilder .writeList(_imports.map((b) => b.finish(fbBuilder)).toList()); @@ -19757,6 +19870,9 @@ class UnlinkedUnit2Builder extends Object if (!(_lineStarts == null || _lineStarts.isEmpty)) { offset_lineStarts = fbBuilder.writeListUint32(_lineStarts); } + if (_partOfUri != null) { + offset_partOfUri = fbBuilder.writeString(_partOfUri); + } if (!(_parts == null || _parts.isEmpty)) { offset_parts = fbBuilder .writeList(_parts.map((b) => fbBuilder.writeString(b)).toList()); @@ -19774,9 +19890,6 @@ class UnlinkedUnit2Builder extends Object if (_hasPartOfDirective == true) { fbBuilder.addBool(3, true); } - if (offset_partOfUri != null) { - fbBuilder.addOffset(8, offset_partOfUri); - } if (offset_imports != null) { fbBuilder.addOffset(2, offset_imports); } @@ -19786,6 +19899,9 @@ class UnlinkedUnit2Builder extends Object if (offset_lineStarts != null) { fbBuilder.addOffset(5, offset_lineStarts); } + if (offset_partOfUri != null) { + fbBuilder.addOffset(8, offset_partOfUri); + } if (offset_parts != null) { fbBuilder.addOffset(4, offset_parts); } @@ -19818,10 +19934,10 @@ class _UnlinkedUnit2Impl extends Object List _exports; bool _hasLibraryDirective; bool _hasPartOfDirective; - String _partOfUri; List _imports; List _informativeData; List _lineStarts; + String _partOfUri; List _parts; @override @@ -19853,12 +19969,6 @@ class _UnlinkedUnit2Impl extends Object return _hasPartOfDirective; } - @override - String get partOfUri { - _partOfUri ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 8, ''); - return _partOfUri; - } - @override List get imports { _imports ??= const fb.ListReader( @@ -19882,6 +19992,12 @@ class _UnlinkedUnit2Impl extends Object return _lineStarts; } + @override + String get partOfUri { + _partOfUri ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 8, ''); + return _partOfUri; + } + @override List get parts { _parts ??= const fb.ListReader(fb.StringReader()) @@ -19906,9 +20022,6 @@ abstract class _UnlinkedUnit2Mixin implements idl.UnlinkedUnit2 { if (hasPartOfDirective != false) { _result["hasPartOfDirective"] = hasPartOfDirective; } - if (partOfUri != '') { - _result["partOfUri"] = partOfUri; - } if (imports.isNotEmpty) { _result["imports"] = imports.map((_value) => _value.toJson()).toList(); } @@ -19919,6 +20032,9 @@ abstract class _UnlinkedUnit2Mixin implements idl.UnlinkedUnit2 { if (lineStarts.isNotEmpty) { _result["lineStarts"] = lineStarts; } + if (partOfUri != '') { + _result["partOfUri"] = partOfUri; + } if (parts.isNotEmpty) { _result["parts"] = parts; } @@ -19931,10 +20047,10 @@ abstract class _UnlinkedUnit2Mixin implements idl.UnlinkedUnit2 { "exports": exports, "hasLibraryDirective": hasLibraryDirective, "hasPartOfDirective": hasPartOfDirective, - "partOfUri": partOfUri, "imports": imports, "informativeData": informativeData, "lineStarts": lineStarts, + "partOfUri": partOfUri, "parts": parts, }; diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs index 9c222aac953..3455b9fbf1b 100644 --- a/pkg/analyzer/lib/src/summary/format.fbs +++ b/pkg/analyzer/lib/src/summary/format.fbs @@ -1253,6 +1253,15 @@ table LinkedNodeUnit { table PackageBundle { /// The version 2 of the summary. bundle2:LinkedNodeBundle (id: 0); + + /// The SDK specific data, if this bundle is for SDK. + sdk:PackageBundleSdk (id: 1); +} + +/// Summary information about a package. +table PackageBundleSdk { + /// The content of the `allowed_experiments.json` from SDK. + allowedExperimentsJson:string (id: 0); } /// Summary information about a top-level type inference error. @@ -1335,9 +1344,6 @@ table UnlinkedUnit2 { /// Is `true` if the unit contains a `part of` directive. hasPartOfDirective:bool (id: 3); - /// URI of the `part of` directive. - partOfUri:string (id: 8); - /// URIs of `import` directives. imports:[UnlinkedNamespaceDirective] (id: 2); @@ -1346,6 +1352,9 @@ table UnlinkedUnit2 { /// Offsets of the first character of each line in the source code. lineStarts:[uint] (id: 5); + /// URI of the `part of` directive. + partOfUri:string (id: 8); + /// URIs of `part` directives. parts:[string] (id: 4); } diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart index 178754b888b..c7f6e2b9b9a 100644 --- a/pkg/analyzer/lib/src/summary/idl.dart +++ b/pkg/analyzer/lib/src/summary/idl.dart @@ -1888,6 +1888,17 @@ abstract class PackageBundle extends base.SummaryClass { /// The version 2 of the summary. @Id(0) LinkedNodeBundle get bundle2; + + /// The SDK specific data, if this bundle is for SDK. + @Id(1) + PackageBundleSdk get sdk; +} + +/// Summary information about a package. +abstract class PackageBundleSdk extends base.SummaryClass { + /// The content of the `allowed_experiments.json` from SDK. + @Id(0) + String get allowedExperimentsJson; } /// Summary information about a top-level type inference error. @@ -2244,10 +2255,6 @@ abstract class UnlinkedUnit2 extends base.SummaryClass { @Id(3) bool get hasPartOfDirective; - /// URI of the `part of` directive. - @Id(8) - String get partOfUri; - /// URIs of `import` directives. @Id(2) List get imports; @@ -2260,6 +2267,10 @@ abstract class UnlinkedUnit2 extends base.SummaryClass { @Id(5) List get lineStarts; + /// URI of the `part of` directive. + @Id(8) + String get partOfUri; + /// URIs of `part` directives. @Id(4) List get parts; diff --git a/pkg/analyzer/lib/src/summary/summary_file_builder.dart b/pkg/analyzer/lib/src/summary/summary_file_builder.dart index 461f6d3d48e..d0e934eef87 100644 --- a/pkg/analyzer/lib/src/summary/summary_file_builder.dart +++ b/pkg/analyzer/lib/src/summary/summary_file_builder.dart @@ -4,6 +4,7 @@ import 'dart:collection'; +import 'package:_fe_analyzer_shared/src/sdk/allowed_experiments.dart'; import 'package:analyzer/dart/analysis/features.dart'; import 'package:analyzer/dart/analysis/utilities.dart'; import 'package:analyzer/dart/ast/ast.dart'; @@ -14,70 +15,104 @@ import 'package:analyzer/src/dart/sdk/sdk.dart'; import 'package:analyzer/src/generated/engine.dart'; import 'package:analyzer/src/generated/sdk.dart'; import 'package:analyzer/src/generated/source.dart'; +import 'package:analyzer/src/summary/format.dart'; import 'package:analyzer/src/summary/summarize_elements.dart'; import 'package:analyzer/src/summary2/link.dart' as summary2; import 'package:analyzer/src/summary2/linked_element_factory.dart' as summary2; import 'package:analyzer/src/summary2/reference.dart' as summary2; import 'package:meta/meta.dart'; -class SummaryBuilder { - final Iterable librarySources; - final AnalysisContext context; +List buildSdkSummary({ + @required ResourceProvider resourceProvider, + @required String sdkPath, +}) { + // + // Prepare SDK. + // + FolderBasedDartSdk sdk = + FolderBasedDartSdk(resourceProvider, resourceProvider.getFolder(sdkPath)); + sdk.useSummary = false; + sdk.analysisOptions = AnalysisOptionsImpl(); - /** - * Create a summary builder for these [librarySources] and [context]. - */ - SummaryBuilder(this.librarySources, this.context); + // + // Prepare 'dart:' URIs to serialize. + // + Set uriSet = + sdk.sdkLibraries.map((SdkLibrary library) => library.shortName).toSet(); + // TODO(scheglov) Why do we need it? + uriSet.add('dart:html_common/html_common_dart2js.dart'); - /** - * Create an SDK summary builder for the dart SDK at the given [sdkPath]. - */ - factory SummaryBuilder.forSdk(String sdkPath) { - // - // Prepare SDK. - // - ResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE; - FolderBasedDartSdk sdk = FolderBasedDartSdk( - resourceProvider, resourceProvider.getFolder(sdkPath)); - sdk.useSummary = false; - sdk.analysisOptions = AnalysisOptionsImpl(); - - // - // Prepare 'dart:' URIs to serialize. - // - Set uriSet = - sdk.sdkLibraries.map((SdkLibrary library) => library.shortName).toSet(); - uriSet.add('dart:html_common/html_common_dart2js.dart'); - - Set librarySources = HashSet(); - for (String uri in uriSet) { - librarySources.add(sdk.mapDartUri(uri)); + Set librarySources = HashSet(); + for (String uri in uriSet) { + var source = sdk.mapDartUri(uri); + // TODO(scheglov) Fix the previous TODO and remove this check. + if (source != null) { + librarySources.add(source); } - - return SummaryBuilder(librarySources, sdk.context); } + String allowedExperimentsJson; + try { + allowedExperimentsJson = sdk.directory + .getChildAssumingFolder('lib') + .getChildAssumingFolder('_internal') + .getChildAssumingFile('allowed_experiments.json') + .readAsStringSync(); + } catch (_) {} + + return _Builder( + sdk.context, + allowedExperimentsJson, + librarySources, + ).build(); +} + +@Deprecated('Use buildSdkSummary()') +class SummaryBuilder { + final ResourceProvider resourceProvider; + final String sdkPath; + + factory SummaryBuilder.forSdk(String sdkPath) { + return SummaryBuilder.forSdk2( + resourceProvider: PhysicalResourceProvider.INSTANCE, + sdkPath: sdkPath, + ); + } + + SummaryBuilder.forSdk2({ + @required this.resourceProvider, + @required this.sdkPath, + }); + /** * Build the linked bundle and return its bytes. */ - List build({ - @required FeatureSet featureSet, - }) { - return _Builder(context, featureSet, librarySources).build(); + List build() { + return buildSdkSummary( + resourceProvider: resourceProvider, + sdkPath: sdkPath, + ); } } class _Builder { final AnalysisContext context; - final FeatureSet featureSet; + final String allowedExperimentsJson; final Iterable librarySources; final Set libraryUris = {}; final List inputLibraries = []; + AllowedExperiments allowedExperiments; final PackageBundleAssembler bundleAssembler = PackageBundleAssembler(); - _Builder(this.context, this.featureSet, this.librarySources); + _Builder( + this.context, + this.allowedExperimentsJson, + this.librarySources, + ) { + allowedExperiments = _parseAllowedExperiments(allowedExperimentsJson); + } /** * Build the linked bundle and return its bytes. @@ -94,7 +129,12 @@ class _Builder { var linkResult = summary2.link(elementFactory, inputLibraries); bundleAssembler.setBundle2(linkResult.bundle); - return bundleAssembler.assemble().toBuffer(); + return PackageBundleBuilder( + bundle2: linkResult.bundle, + sdk: PackageBundleSdkBuilder( + allowedExperimentsJson: allowedExperimentsJson, + ), + ).toBuffer(); } void _addLibrary(Source source) { @@ -130,10 +170,23 @@ class _Builder { ); } + /// Return the [FeatureSet] for the given [uri], must be a `dart:` URI. + FeatureSet _featureSet(Uri uri) { + if (uri.isScheme('dart')) { + var pathSegments = uri.pathSegments; + if (pathSegments.isNotEmpty) { + var libraryName = pathSegments.first; + var experiments = allowedExperiments.forSdkLibrary(libraryName); + return FeatureSet.fromEnableFlags(experiments); + } + } + throw StateError('Expected a valid dart: URI: $uri'); + } + CompilationUnit _parse(Source source) { var result = parseString( content: source.contents.data, - featureSet: featureSet, + featureSet: _featureSet(source.uri), throwIfDiagnostics: false, ); @@ -149,4 +202,16 @@ class _Builder { return result.unit; } + + static AllowedExperiments _parseAllowedExperiments(String content) { + if (content == null) { + return AllowedExperiments( + sdkDefaultExperiments: [], + sdkLibraryExperiments: {}, + packageExperiments: {}, + ); + } + + return parseAllowedExperiments(content); + } } diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart index f1874197a8c..46136e8a630 100644 --- a/pkg/analyzer/lib/src/summary/summary_sdk.dart +++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart @@ -43,6 +43,11 @@ class SummaryBasedDartSdk implements DartSdk { _bundle = bundle; } + @override + String get allowedExperimentsJson { + return _bundle.sdk?.allowedExperimentsJson; + } + /** * Return the [PackageBundle] for this SDK, not `null`. */ diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart index 2f1038ab477..744ecd771ef 100644 --- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart +++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart @@ -2,7 +2,6 @@ // 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/features.dart'; import 'package:analyzer/file_system/file_system.dart'; import 'package:analyzer/file_system/memory_file_system.dart'; import 'package:analyzer/src/context/context.dart'; @@ -1067,7 +1066,7 @@ final Map _librariesDartEntries = { 'ffi': 'const LibraryInfo("ffi/ffi.dart")', 'html': 'const LibraryInfo("html/dart2js/html_dart2js.dart")', 'io': 'const LibraryInfo("io/io.dart")', - 'isolate': 'const LibraryInfo("io/isolate.dart")', + 'isolate': 'const LibraryInfo("isolate/isolate.dart")', 'math': 'const LibraryInfo("math/math.dart")', }; @@ -1158,6 +1157,21 @@ class MockSdk implements DartSdk { ); } + @override + String get allowedExperimentsJson { + try { + var convertedRoot = resourceProvider.convertPath(sdkRoot); + return resourceProvider + .getFolder(convertedRoot) + .getChildAssumingFolder('lib') + .getChildAssumingFolder('_internal') + .getChildAssumingFile('allowed_experiments.json') + .readAsStringSync(); + } catch (_) { + return null; + } + } + @override AnalysisContextImpl get context { if (_analysisContext == null) { @@ -1167,11 +1181,6 @@ class MockSdk implements DartSdk { return _analysisContext; } - Folder get directory { - var convertedRoot = resourceProvider.convertPath(sdkRoot); - return resourceProvider.getFolder(convertedRoot); - } - @override String get sdkVersion => throw UnimplementedError(); @@ -1255,12 +1264,9 @@ class MockSdk implements DartSdk { /// Compute the bytes of the linked bundle associated with this SDK. List _computeLinkedBundleBytes() { - List librarySources = sdkLibraries - .map((SdkLibrary library) => mapDartUri(library.shortName)) - .toList(); - var featureSet = FeatureSet.fromEnableFlags(['non-nullable']); - return SummaryBuilder(librarySources, context).build( - featureSet: featureSet, + return buildSdkSummary( + resourceProvider: resourceProvider, + sdkPath: sdkRoot, ); } } diff --git a/pkg/analyzer/tool/summary/build_sdk_summaries.dart b/pkg/analyzer/tool/summary/build_sdk_summaries.dart index 7bfc71e1fb0..4fa2b7e6e01 100644 --- a/pkg/analyzer/tool/summary/build_sdk_summaries.dart +++ b/pkg/analyzer/tool/summary/build_sdk_summaries.dart @@ -4,7 +4,6 @@ import 'dart:io'; -import 'package:analyzer/dart/analysis/features.dart'; import 'package:analyzer/file_system/physical_file_system.dart'; import 'package:analyzer/src/dart/sdk/sdk.dart'; import 'package:analyzer/src/summary/summary_file_builder.dart'; @@ -42,18 +41,10 @@ void main(List args) { // // Handle commands. // - if (command == 'build-non-nullable') { + if (command == 'build-strong') { _buildSummary( sdkPath, outFilePath, - enabledExperiments: ['non-nullable'], - title: 'non-nullable', - ); - } else if (command == 'build-legacy' || command == 'build-strong') { - _buildSummary( - sdkPath, - outFilePath, - enabledExperiments: [], title: 'legacy', ); } else { @@ -70,14 +61,13 @@ const BINARY_NAME = "build_sdk_summaries"; void _buildSummary( String sdkPath, String outPath, { - @required List enabledExperiments, @required String title, }) { print('Generating $title summary.'); Stopwatch sw = Stopwatch()..start(); - var featureSet = FeatureSet.fromEnableFlags(enabledExperiments); - List bytes = SummaryBuilder.forSdk(sdkPath).build( - featureSet: featureSet, + List bytes = buildSdkSummary( + resourceProvider: PhysicalResourceProvider.INSTANCE, + sdkPath: sdkPath, ); File(outPath).writeAsBytesSync(bytes, mode: FileMode.writeOnly); print('\tDone in ${sw.elapsedMilliseconds} ms.'); diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart index 3cd2c60574a..c709f5744e6 100644 --- a/pkg/analyzer_cli/lib/src/driver.dart +++ b/pkg/analyzer_cli/lib/src/driver.dart @@ -6,7 +6,6 @@ import 'dart:async'; import 'dart:io' as io; import 'dart:isolate'; -import 'package:analyzer/dart/analysis/features.dart'; import 'package:analyzer/error/error.dart'; import 'package:analyzer/file_system/file_system.dart'; import 'package:analyzer/file_system/physical_file_system.dart'; @@ -159,9 +158,9 @@ class Driver with HasContextMixin implements CommandLineStarter { final stopwatch = Stopwatch()..start(); for (var i = 0; i < 3; i++) { - var featureSet = FeatureSet.fromEnableFlags([]); - SummaryBuilder.forSdk(options.dartSdkPath).build( - featureSet: featureSet, + buildSdkSummary( + resourceProvider: PhysicalResourceProvider.INSTANCE, + sdkPath: options.dartSdkPath, ); } diff --git a/utils/dartanalyzer/BUILD.gn b/utils/dartanalyzer/BUILD.gn index ad342365697..b262009bec7 100644 --- a/utils/dartanalyzer/BUILD.gn +++ b/utils/dartanalyzer/BUILD.gn @@ -46,13 +46,13 @@ prebuilt_dart_action("generate_summary_strong") { outputs = [ output ] if (!dont_use_nnbd) { args = [ - "build-non-nullable", + "build-strong", rebase_path(output), rebase_path("../../sdk_nnbd"), ] } else { args = [ - "build-legacy", + "build-strong", rebase_path(output), rebase_path("../../sdk"), ]