| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library analyzer.src.summary.summary_file_builder; | 5 library analyzer.src.summary.summary_file_builder; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 import 'dart:io' as io; | |
| 9 | 8 |
| 10 import 'package:analyzer/dart/ast/ast.dart'; | |
| 11 import 'package:analyzer/dart/element/element.dart'; | 9 import 'package:analyzer/dart/element/element.dart'; |
| 12 import 'package:analyzer/file_system/file_system.dart'; | 10 import 'package:analyzer/file_system/file_system.dart'; |
| 13 import 'package:analyzer/file_system/physical_file_system.dart'; | 11 import 'package:analyzer/file_system/physical_file_system.dart'; |
| 14 import 'package:analyzer/src/dart/sdk/sdk.dart'; | 12 import 'package:analyzer/src/dart/sdk/sdk.dart'; |
| 15 import 'package:analyzer/src/generated/engine.dart'; | 13 import 'package:analyzer/src/generated/engine.dart'; |
| 16 import 'package:analyzer/src/generated/sdk.dart'; | 14 import 'package:analyzer/src/generated/sdk.dart'; |
| 17 import 'package:analyzer/src/generated/source.dart'; | 15 import 'package:analyzer/src/generated/source.dart'; |
| 18 import 'package:analyzer/src/summary/flat_buffers.dart' as fb; | |
| 19 import 'package:analyzer/src/summary/index_unit.dart'; | |
| 20 import 'package:analyzer/src/summary/summarize_elements.dart'; | 16 import 'package:analyzer/src/summary/summarize_elements.dart'; |
| 21 import 'package:path/path.dart'; | |
| 22 | 17 |
| 23 const int FIELD_SPEC_INDEX = 1; | 18 class SummaryBuilder { |
| 24 const int FIELD_SPEC_SUM = 0; | 19 final Iterable<Source> librarySources; |
| 25 const int FIELD_STRONG_INDEX = 3; | 20 final AnalysisContext context; |
| 26 const int FIELD_STRONG_SUM = 2; | 21 final bool strong; |
| 27 | |
| 28 class BuilderOutput { | |
| 29 final List<int> sum; | |
| 30 final List<int> index; | |
| 31 | |
| 32 BuilderOutput(this.sum, this.index); | |
| 33 | |
| 34 void writeMultiple(String outputDirectoryPath, String modeName) { | |
| 35 // Write summary. | |
| 36 { | |
| 37 String outputPath = join(outputDirectoryPath, '$modeName.sum'); | |
| 38 io.File file = new io.File(outputPath); | |
| 39 file.writeAsBytesSync(sum, mode: io.FileMode.WRITE_ONLY); | |
| 40 } | |
| 41 // Write index. | |
| 42 { | |
| 43 String outputPath = join(outputDirectoryPath, '$modeName.index'); | |
| 44 io.File file = new io.File(outputPath); | |
| 45 file.writeAsBytesSync(index, mode: io.FileMode.WRITE_ONLY); | |
| 46 } | |
| 47 } | |
| 48 } | |
| 49 | |
| 50 /** | |
| 51 * Summary build configuration. | |
| 52 */ | |
| 53 class SummaryBuildConfig { | |
| 54 /** | |
| 55 * Whether to use exclude informative data from created summaries. | |
| 56 */ | |
| 57 final bool buildSummaryExcludeInformative; | |
| 58 | 22 |
| 59 /** | 23 /** |
| 60 * Whether to output a summary in "fallback mode". | 24 * Create a summary builder for these [librarySources] and [context]. |
| 61 */ | 25 */ |
| 62 final bool buildSummaryFallback; | 26 SummaryBuilder(this.librarySources, this.context, this.strong); |
| 63 | 27 |
| 64 /** | 28 /** |
| 65 * Whether to create summaries directly from ASTs, i.e. don't create a | 29 * Create an SDK summary builder for the dart SDK at the given [sdkPath]. |
| 66 * full element model. | |
| 67 */ | 30 */ |
| 68 final bool buildSummaryOnlyAst; | 31 factory SummaryBuilder.forSdk(String sdkPath, bool strong) { |
| 69 | |
| 70 /** | |
| 71 * Path to the dart SDK summary file. | |
| 72 */ | |
| 73 final String dartSdkSummaryPath; | |
| 74 | |
| 75 /** | |
| 76 * Whether to use strong static checking. | |
| 77 */ | |
| 78 final bool strongMode; | |
| 79 | |
| 80 /** | |
| 81 * List of summary input file paths. | |
| 82 */ | |
| 83 final Iterable<String> summaryInputs; | |
| 84 | |
| 85 /** | |
| 86 * Create a build configuration with the given set options. | |
| 87 */ | |
| 88 SummaryBuildConfig( | |
| 89 {this.strongMode: false, | |
| 90 this.summaryInputs, | |
| 91 this.dartSdkSummaryPath, | |
| 92 this.buildSummaryExcludeInformative: false, | |
| 93 this.buildSummaryFallback: false, | |
| 94 this.buildSummaryOnlyAst: false}); | |
| 95 } | |
| 96 | |
| 97 class SummaryBuilder { | |
| 98 final AnalysisContext context; | |
| 99 final Iterable<Source> librarySources; | |
| 100 final SummaryBuildConfig config; | |
| 101 | |
| 102 /** | |
| 103 * Create a summary builder for these [librarySources] and [context] using the | |
| 104 * given [config]. | |
| 105 */ | |
| 106 SummaryBuilder(this.librarySources, this.context, this.config); | |
| 107 | |
| 108 /** | |
| 109 * Create an SDK summary builder for the dart SDK at the given [sdkPath], | |
| 110 * using this [config]. | |
| 111 */ | |
| 112 factory SummaryBuilder.forSdk(String sdkPath, SummaryBuildConfig config) { | |
| 113 bool strongMode = config.strongMode; | |
| 114 | |
| 115 // | 32 // |
| 116 // Prepare SDK. | 33 // Prepare SDK. |
| 117 // | 34 // |
| 118 ResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE; | 35 ResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE; |
| 119 FolderBasedDartSdk sdk = new FolderBasedDartSdk( | 36 FolderBasedDartSdk sdk = new FolderBasedDartSdk( |
| 120 resourceProvider, resourceProvider.getFolder(sdkPath), strongMode); | 37 resourceProvider, resourceProvider.getFolder(sdkPath), strong); |
| 121 sdk.useSummary = false; | 38 sdk.useSummary = false; |
| 122 sdk.analysisOptions = new AnalysisOptionsImpl()..strongMode = strongMode; | 39 sdk.analysisOptions = new AnalysisOptionsImpl()..strongMode = strong; |
| 123 | 40 |
| 124 // | 41 // |
| 125 // Prepare 'dart:' URIs to serialize. | 42 // Prepare 'dart:' URIs to serialize. |
| 126 // | 43 // |
| 127 Set<String> uriSet = | 44 Set<String> uriSet = |
| 128 sdk.sdkLibraries.map((SdkLibrary library) => library.shortName).toSet(); | 45 sdk.sdkLibraries.map((SdkLibrary library) => library.shortName).toSet(); |
| 129 if (!strongMode) { | 46 if (!strong) { |
| 130 uriSet.add('dart:html/nativewrappers.dart'); | 47 uriSet.add('dart:html/nativewrappers.dart'); |
| 131 } | 48 } |
| 132 uriSet.add('dart:html_common/html_common_dart2js.dart'); | 49 uriSet.add('dart:html_common/html_common_dart2js.dart'); |
| 133 | 50 |
| 134 Set<Source> librarySources = new HashSet<Source>(); | 51 Set<Source> librarySources = new HashSet<Source>(); |
| 135 for (String uri in uriSet) { | 52 for (String uri in uriSet) { |
| 136 librarySources.add(sdk.mapDartUri(uri)); | 53 librarySources.add(sdk.mapDartUri(uri)); |
| 137 } | 54 } |
| 138 | 55 |
| 139 return new SummaryBuilder(librarySources, sdk.context, config); | 56 return new SummaryBuilder(librarySources, sdk.context, strong); |
| 140 } | 57 } |
| 141 | 58 |
| 142 BuilderOutput build() => new _Builder(context, librarySources).build(); | |
| 143 } | |
| 144 | |
| 145 /** | |
| 146 * Intermediary summary output result. | |
| 147 */ | |
| 148 class SummaryOutput { | |
| 149 final BuilderOutput spec; | |
| 150 final BuilderOutput strong; | |
| 151 SummaryOutput(this.spec, this.strong); | |
| 152 | |
| 153 /** | 59 /** |
| 154 * Write this summary output to the given [outputPath] and return the | 60 * Build the linked bundle and return its bytes. |
| 155 * created file. | |
| 156 */ | 61 */ |
| 157 io.File write(String outputPath) { | 62 List<int> build() => new _Builder(context, librarySources).build(); |
| 158 fb.Builder builder = new fb.Builder(); | |
| 159 fb.Offset specSumOffset = builder.writeListUint8(spec.sum); | |
| 160 fb.Offset specIndexOffset = builder.writeListUint8(spec.index); | |
| 161 fb.Offset strongSumOffset = builder.writeListUint8(strong.sum); | |
| 162 fb.Offset strongIndexOffset = builder.writeListUint8(strong.index); | |
| 163 builder.startTable(); | |
| 164 builder.addOffset(FIELD_SPEC_SUM, specSumOffset); | |
| 165 builder.addOffset(FIELD_SPEC_INDEX, specIndexOffset); | |
| 166 builder.addOffset(FIELD_STRONG_SUM, strongSumOffset); | |
| 167 builder.addOffset(FIELD_STRONG_INDEX, strongIndexOffset); | |
| 168 fb.Offset offset = builder.endTable(); | |
| 169 return new io.File(outputPath) | |
| 170 ..writeAsBytesSync(builder.finish(offset), mode: io.FileMode.WRITE_ONLY); | |
| 171 } | |
| 172 } | 63 } |
| 173 | 64 |
| 174 class _Builder { | 65 class _Builder { |
| 175 final Set<Source> processedSources = new Set<Source>(); | |
| 176 | |
| 177 final PackageBundleAssembler bundleAssembler = new PackageBundleAssembler(); | |
| 178 final PackageIndexAssembler indexAssembler = new PackageIndexAssembler(); | |
| 179 | |
| 180 final AnalysisContext context; | 66 final AnalysisContext context; |
| 181 final Iterable<Source> librarySources; | 67 final Iterable<Source> librarySources; |
| 182 | 68 |
| 69 final Set<Source> processedSources = new Set<Source>(); |
| 70 final PackageBundleAssembler bundleAssembler = new PackageBundleAssembler(); |
| 71 |
| 183 _Builder(this.context, this.librarySources); | 72 _Builder(this.context, this.librarySources); |
| 184 | 73 |
| 185 /** | 74 /** |
| 186 * Build summary output. | 75 * Build the linked bundle and return its bytes. |
| 187 */ | 76 */ |
| 188 BuilderOutput build() { | 77 List<int> build() { |
| 189 // | 78 librarySources.forEach(_serializeLibrary); |
| 190 // Serialize each source. | 79 return bundleAssembler.assemble().toBuffer(); |
| 191 // | |
| 192 for (Source source in librarySources) { | |
| 193 _serializeLibrary(source); | |
| 194 } | |
| 195 // | |
| 196 // Assemble the output. | |
| 197 // | |
| 198 List<int> sumBytes = bundleAssembler.assemble().toBuffer(); | |
| 199 List<int> indexBytes = indexAssembler.assemble().toBuffer(); | |
| 200 return new BuilderOutput(sumBytes, indexBytes); | |
| 201 } | 80 } |
| 202 | 81 |
| 203 /** | 82 /** |
| 204 * Serialize the library with the given [source] and all its direct or | 83 * Serialize the library with the given [source] and all its direct or |
| 205 * indirect imports and exports. | 84 * indirect imports and exports. |
| 206 */ | 85 */ |
| 207 void _serializeLibrary(Source source) { | 86 void _serializeLibrary(Source source) { |
| 208 if (!processedSources.add(source)) { | 87 if (!processedSources.add(source)) { |
| 209 return; | 88 return; |
| 210 } | 89 } |
| 211 LibraryElement element = context.computeLibraryElement(source); | 90 LibraryElement element = context.computeLibraryElement(source); |
| 212 bundleAssembler.serializeLibraryElement(element); | 91 bundleAssembler.serializeLibraryElement(element); |
| 213 element.importedLibraries.forEach((e) => _serializeLibrary(e.source)); | 92 element.importedLibraries.forEach((e) => _serializeLibrary(e.source)); |
| 214 element.exportedLibraries.forEach((e) => _serializeLibrary(e.source)); | 93 element.exportedLibraries.forEach((e) => _serializeLibrary(e.source)); |
| 215 // Index every unit of the library. | |
| 216 for (CompilationUnitElement unitElement in element.units) { | |
| 217 Source unitSource = unitElement.source; | |
| 218 CompilationUnit unit = | |
| 219 context.resolveCompilationUnit2(unitSource, source); | |
| 220 indexAssembler.indexUnit(unit); | |
| 221 } | |
| 222 } | 94 } |
| 223 } | 95 } |
| OLD | NEW |