OLD | NEW |
---|---|
1 import 'dart:io'; | 1 import 'dart:io'; |
2 | 2 |
3 import 'package:analyzer/dart/ast/ast.dart'; | 3 import 'package:analyzer/dart/ast/ast.dart'; |
4 import 'package:analyzer/dart/element/element.dart'; | 4 import 'package:analyzer/dart/element/element.dart'; |
5 import 'package:analyzer/src/generated/engine.dart'; | 5 import 'package:analyzer/src/generated/engine.dart'; |
6 import 'package:analyzer/src/generated/java_io.dart'; | 6 import 'package:analyzer/src/generated/java_io.dart'; |
7 import 'package:analyzer/src/generated/sdk.dart'; | 7 import 'package:analyzer/src/generated/sdk.dart'; |
8 import 'package:analyzer/src/generated/sdk_io.dart'; | 8 import 'package:analyzer/src/generated/sdk_io.dart'; |
9 import 'package:analyzer/src/generated/source.dart'; | 9 import 'package:analyzer/src/generated/source.dart'; |
10 import 'package:analyzer/src/summary/format.dart'; | 10 import 'package:analyzer/src/summary/flat_buffers.dart' as fb; |
11 import 'package:analyzer/src/summary/index_unit.dart'; | 11 import 'package:analyzer/src/summary/index_unit.dart'; |
12 import 'package:analyzer/src/summary/summarize_elements.dart'; | 12 import 'package:analyzer/src/summary/summarize_elements.dart'; |
13 import 'package:path/path.dart'; | 13 import 'package:path/path.dart'; |
14 | 14 |
15 main(List<String> args) { | 15 main(List<String> args) { |
16 if (args.length < 1 || args.length > 2) { | 16 if (args.length < 1) { |
17 _printUsage(); | 17 _printUsage(); |
18 exitCode = 1; | 18 exitCode = 1; |
19 return; | 19 return; |
20 } | 20 } |
21 // | 21 String command = args[0]; |
22 // Prepare output file path. | 22 if (command == 'multiple-outputs') { |
Paul Berry
2016/03/09 18:23:21
Add `&& args.length >= 2 && args.length <= 3`. Ot
| |
23 // | 23 // |
24 String outputDirectoryPath = args[0]; | 24 // Prepare the output path. |
25 if (!FileSystemEntity.isDirectorySync(outputDirectoryPath)) { | 25 // |
26 print("'$outputDirectoryPath' is not a directory."); | 26 String outputDirectoryPath = args[1]; |
27 if (!FileSystemEntity.isDirectorySync(outputDirectoryPath)) { | |
28 print("'$outputDirectoryPath' is not a directory."); | |
29 _printUsage(); | |
30 exitCode = 1; | |
31 return; | |
32 } | |
33 // | |
34 // Prepare results. | |
35 // | |
36 String sdkPath = args.length > 2 ? args[2] : null; | |
37 _Output output = _buildMultipleOutputs(sdkPath); | |
38 if (output == null) { | |
39 exitCode = 1; | |
40 return; | |
41 } | |
42 // | |
43 // Write results. | |
44 // | |
45 output.spec.writeMultiple(outputDirectoryPath, 'spec'); | |
46 output.strong.writeMultiple(outputDirectoryPath, 'strong'); | |
47 } else if (command == 'single-output') { | |
Paul Berry
2016/03/09 18:23:21
Same comment here.
| |
48 String outputPath = args[1]; | |
49 String sdkPath = args.length > 2 ? args[2] : null; | |
50 // | |
51 // Prepare results. | |
52 // | |
53 _Output output = _buildMultipleOutputs(sdkPath); | |
54 if (output == null) { | |
55 exitCode = 1; | |
56 return; | |
57 } | |
58 // | |
59 // Write results. | |
60 // | |
61 fb.Builder builder = new fb.Builder(); | |
62 fb.Offset specSumOffset = builder.writeListUint8(output.spec.sum); | |
63 fb.Offset specIndexOffset = builder.writeListUint8(output.spec.index); | |
64 fb.Offset strongSumOffset = builder.writeListUint8(output.strong.sum); | |
65 fb.Offset strongIndexOffset = builder.writeListUint8(output.strong.index); | |
66 builder.startTable(); | |
67 builder.addOffset(_FIELD_SPEC_SUM, specSumOffset); | |
68 builder.addOffset(_FIELD_SPEC_INDEX, specIndexOffset); | |
69 builder.addOffset(_FIELD_STRONG_SUM, strongSumOffset); | |
70 builder.addOffset(_FIELD_STRONG_INDEX, strongIndexOffset); | |
71 fb.Offset offset = builder.endTable(); | |
72 new File(outputPath) | |
73 .writeAsBytesSync(builder.finish(offset), mode: FileMode.WRITE_ONLY); | |
74 } else if (command == 'extract-spec-sum' && args.length == 3) { | |
75 String inputPath = args[1]; | |
76 String outputPath = args[2]; | |
77 _extractSingleOutput(inputPath, _FIELD_SPEC_SUM, outputPath); | |
78 } else if (command == 'extract-spec-index' && args.length == 3) { | |
79 String inputPath = args[1]; | |
80 String outputPath = args[2]; | |
81 _extractSingleOutput(inputPath, _FIELD_SPEC_INDEX, outputPath); | |
82 } else if (command == 'extract-strong-sum' && args.length == 3) { | |
83 String inputPath = args[1]; | |
84 String outputPath = args[2]; | |
85 _extractSingleOutput(inputPath, _FIELD_STRONG_SUM, outputPath); | |
86 } else if (command == 'extract-strong-index' && args.length == 3) { | |
87 String inputPath = args[1]; | |
88 String outputPath = args[2]; | |
89 _extractSingleOutput(inputPath, _FIELD_STRONG_INDEX, outputPath); | |
90 } else { | |
27 _printUsage(); | 91 _printUsage(); |
28 exitCode = 1; | 92 exitCode = 1; |
29 return; | 93 return; |
30 } | 94 } |
31 // | |
32 // Prepare SDK path. | |
33 // | |
34 String sdkPath; | |
35 if (args.length == 2) { | |
36 sdkPath = args[1]; | |
37 if (!FileSystemEntity.isDirectorySync('$sdkPath/lib')) { | |
38 print("'$sdkPath/lib' does not exist."); | |
39 _printUsage(); | |
40 exitCode = 1; | |
41 return; | |
42 } | |
43 } else { | |
44 sdkPath = DirectoryBasedDartSdk.defaultSdkDirectory.getAbsolutePath(); | |
45 } | |
46 // | |
47 // Build spec and strong summaries. | |
48 // | |
49 new _Builder(sdkPath, outputDirectoryPath, false).build(); | |
50 new _Builder(sdkPath, outputDirectoryPath, true).build(); | |
51 } | 95 } |
52 | 96 |
53 /** | 97 /** |
54 * The name of the SDK summaries builder application. | 98 * The name of the SDK summaries builder application. |
55 */ | 99 */ |
56 const BINARY_NAME = "build_sdk_summaries"; | 100 const BINARY_NAME = "build_sdk_summaries"; |
57 | 101 |
102 const int _FIELD_SPEC_INDEX = 1; | |
103 const int _FIELD_SPEC_SUM = 0; | |
104 const int _FIELD_STRONG_INDEX = 3; | |
105 const int _FIELD_STRONG_SUM = 2; | |
106 | |
107 _Output _buildMultipleOutputs(String sdkPath) { | |
108 // | |
109 // Validate the SDK path. | |
110 // | |
111 if (sdkPath != null) { | |
112 if (!FileSystemEntity.isDirectorySync('$sdkPath/lib')) { | |
113 print("'$sdkPath/lib' does not exist."); | |
114 _printUsage(); | |
115 return null; | |
116 } | |
117 } else { | |
118 sdkPath = DirectoryBasedDartSdk.defaultSdkDirectory.getAbsolutePath(); | |
119 } | |
120 // | |
121 // Build spec and strong outputs. | |
122 // | |
123 _BuilderOutput spec = new _Builder(sdkPath, false).build(); | |
124 _BuilderOutput strong = new _Builder(sdkPath, true).build(); | |
125 return new _Output(spec, strong); | |
126 } | |
127 | |
128 /** | |
129 * Open the flat buffer in [inputPath] and extract the byte array in the [field] | |
130 * into the [outputPath] file. | |
131 */ | |
132 void _extractSingleOutput(String inputPath, int field, String outputPath) { | |
133 List<int> bytes = new File(inputPath).readAsBytesSync(); | |
134 fb.BufferPointer bp = new fb.BufferPointer.fromBytes(bytes); | |
135 fb.BufferPointer table = bp.derefObject(); | |
136 List<int> fieldBytes = | |
137 const fb.ListReader(const fb.Uint8Reader()).vTableGet(table, field); | |
138 new File(outputPath).writeAsBytesSync(fieldBytes, mode: FileMode.WRITE_ONLY); | |
139 } | |
140 | |
58 /** | 141 /** |
59 * Print information about how to use the SDK summaries builder. | 142 * Print information about how to use the SDK summaries builder. |
60 */ | 143 */ |
61 void _printUsage() { | 144 void _printUsage() { |
62 print('Usage: $BINARY_NAME output_directory_path [sdk_path]'); | 145 // print('Usage: $BINARY_NAME command output_directory_path [sdk_path]'); |
63 print('Build files spec.sum and strong.sum in the output directory.'); | 146 print('Usage: $BINARY_NAME command arguments'); |
147 print('Where command can be one of the following:'); | |
148 print(' multiple-outputs output_directory_path [sdk_path]'); | |
149 print(' Generate separate summary and index files.'); | |
150 print(' single-output output_file_path [sdk_path]'); | |
151 print(' Generate a single file with summary and index.'); | |
152 print(' extract-spec-sum input_file output_file'); | |
153 print(' Extract the spec-mode summary file.'); | |
154 print(' extract-strong-sum input_file output_file'); | |
155 print(' Extract the strong-mode summary file.'); | |
156 print(' extract-spec-index input_file output_file'); | |
157 print(' Extract the spec-mode index file.'); | |
158 print(' extract-strong-index input_file output_file'); | |
159 print(' Extract the strong-mode index file.'); | |
64 } | 160 } |
65 | 161 |
66 class _Builder { | 162 class _Builder { |
67 final String sdkPath; | 163 final String sdkPath; |
68 final String outputDirectoryPath; | |
69 final bool strongMode; | 164 final bool strongMode; |
70 | 165 |
71 AnalysisContext context; | 166 AnalysisContext context; |
72 final Set<Source> processedSources = new Set<Source>(); | 167 final Set<Source> processedSources = new Set<Source>(); |
73 | 168 |
74 final PackageBundleAssembler bundleAssembler = new PackageBundleAssembler(); | 169 final PackageBundleAssembler bundleAssembler = new PackageBundleAssembler(); |
75 final PackageIndexAssembler indexAssembler = new PackageIndexAssembler(); | 170 final PackageIndexAssembler indexAssembler = new PackageIndexAssembler(); |
76 | 171 |
77 _Builder(this.sdkPath, this.outputDirectoryPath, this.strongMode); | 172 _Builder(this.sdkPath, this.strongMode); |
78 | 173 |
79 /** | 174 /** |
80 * Build a strong or spec mode summary for the Dart SDK at [sdkPath]. | 175 * Build a strong or spec mode summary for the Dart SDK at [sdkPath]. |
81 */ | 176 */ |
82 void build() { | 177 _BuilderOutput build() { |
83 String modeName = strongMode ? 'strong' : 'spec'; | 178 String modeName = strongMode ? 'strong' : 'spec'; |
84 print('Generating $modeName mode summary and index.'); | 179 print('Generating $modeName mode summary and index.'); |
85 Stopwatch sw = new Stopwatch()..start(); | 180 Stopwatch sw = new Stopwatch()..start(); |
86 // | 181 // |
87 // Prepare SDK. | 182 // Prepare SDK. |
88 // | 183 // |
89 DirectoryBasedDartSdk sdk = | 184 DirectoryBasedDartSdk sdk = |
90 new DirectoryBasedDartSdk(new JavaFile(sdkPath)); | 185 new DirectoryBasedDartSdk(new JavaFile(sdkPath)); |
91 sdk.useSummary = false; | 186 sdk.useSummary = false; |
92 context = sdk.context; | 187 context = sdk.context; |
93 context.analysisOptions = new AnalysisOptionsImpl() | 188 context.analysisOptions = new AnalysisOptionsImpl() |
94 ..strongMode = strongMode; | 189 ..strongMode = strongMode; |
95 // | 190 // |
96 // Prepare 'dart:' URIs to serialize. | 191 // Prepare 'dart:' URIs to serialize. |
97 // | 192 // |
98 Set<String> uriSet = | 193 Set<String> uriSet = |
99 sdk.sdkLibraries.map((SdkLibrary library) => library.shortName).toSet(); | 194 sdk.sdkLibraries.map((SdkLibrary library) => library.shortName).toSet(); |
100 uriSet.add('dart:html/nativewrappers.dart'); | 195 uriSet.add('dart:html/nativewrappers.dart'); |
101 uriSet.add('dart:html_common/html_common_dart2js.dart'); | 196 uriSet.add('dart:html_common/html_common_dart2js.dart'); |
102 // | 197 // |
103 // Serialize each SDK library. | 198 // Serialize each SDK library. |
104 // | 199 // |
105 for (String uri in uriSet) { | 200 for (String uri in uriSet) { |
106 Source libSource = sdk.mapDartUri(uri); | 201 Source libSource = sdk.mapDartUri(uri); |
107 _serializeLibrary(libSource); | 202 _serializeLibrary(libSource); |
108 } | 203 } |
109 // | 204 // |
110 // Write the whole SDK bundle. | 205 // Assemble the output. |
111 // | 206 // |
112 { | 207 List<int> sumBytes = bundleAssembler.assemble().toBuffer(); |
113 PackageBundleBuilder bundle = bundleAssembler.assemble(); | 208 List<int> indexBytes = indexAssembler.assemble().toBuffer(); |
114 String outputPath = join(outputDirectoryPath, '$modeName.sum'); | |
115 File file = new File(outputPath); | |
116 file.writeAsBytesSync(bundle.toBuffer(), mode: FileMode.WRITE_ONLY); | |
117 } | |
118 // | |
119 // Write the whole SDK index. | |
120 // | |
121 { | |
122 PackageIndexBuilder index = indexAssembler.assemble(); | |
123 String outputPath = join(outputDirectoryPath, '$modeName.index'); | |
124 File file = new File(outputPath); | |
125 file.writeAsBytesSync(index.toBuffer(), mode: FileMode.WRITE_ONLY); | |
126 } | |
127 // | |
128 // Done. | |
129 // | |
130 print('\tDone in ${sw.elapsedMilliseconds} ms.'); | 209 print('\tDone in ${sw.elapsedMilliseconds} ms.'); |
210 return new _BuilderOutput(sumBytes, indexBytes); | |
131 } | 211 } |
132 | 212 |
133 /** | 213 /** |
134 * Serialize the library with the given [source] and all its direct or | 214 * Serialize the library with the given [source] and all its direct or |
135 * indirect imports and exports. | 215 * indirect imports and exports. |
136 */ | 216 */ |
137 void _serializeLibrary(Source source) { | 217 void _serializeLibrary(Source source) { |
138 if (!processedSources.add(source)) { | 218 if (!processedSources.add(source)) { |
139 return; | 219 return; |
140 } | 220 } |
141 LibraryElement element = context.computeLibraryElement(source); | 221 LibraryElement element = context.computeLibraryElement(source); |
142 bundleAssembler.serializeLibraryElement(element); | 222 bundleAssembler.serializeLibraryElement(element); |
143 element.importedLibraries.forEach((e) => _serializeLibrary(e.source)); | 223 element.importedLibraries.forEach((e) => _serializeLibrary(e.source)); |
144 element.exportedLibraries.forEach((e) => _serializeLibrary(e.source)); | 224 element.exportedLibraries.forEach((e) => _serializeLibrary(e.source)); |
145 // Index every unit of the library. | 225 // Index every unit of the library. |
146 for (CompilationUnitElement unitElement in element.units) { | 226 for (CompilationUnitElement unitElement in element.units) { |
147 Source unitSource = unitElement.source; | 227 Source unitSource = unitElement.source; |
148 CompilationUnit unit = | 228 CompilationUnit unit = |
149 context.resolveCompilationUnit2(unitSource, source); | 229 context.resolveCompilationUnit2(unitSource, source); |
150 indexAssembler.index(unit); | 230 indexAssembler.index(unit); |
151 } | 231 } |
152 } | 232 } |
153 } | 233 } |
234 | |
235 class _BuilderOutput { | |
236 final List<int> sum; | |
237 final List<int> index; | |
238 | |
239 _BuilderOutput(this.sum, this.index); | |
240 | |
241 void writeMultiple(String outputDirectoryPath, String modeName) { | |
242 // Write summary. | |
243 { | |
244 String outputPath = join(outputDirectoryPath, '$modeName.sum'); | |
245 File file = new File(outputPath); | |
246 file.writeAsBytesSync(sum, mode: FileMode.WRITE_ONLY); | |
247 } | |
248 // Write index. | |
249 { | |
250 String outputPath = join(outputDirectoryPath, '$modeName.index'); | |
251 File file = new File(outputPath); | |
252 file.writeAsBytesSync(index, mode: FileMode.WRITE_ONLY); | |
253 } | |
254 } | |
255 } | |
256 | |
257 class _Output { | |
258 final _BuilderOutput spec; | |
259 final _BuilderOutput strong; | |
260 | |
261 _Output(this.spec, this.strong); | |
262 } | |
OLD | NEW |