| 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 @JS() | 4 @JS() |
| 5 library dev_compiler.web.web_command; | 5 library dev_compiler.web.web_command; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:convert'; | 8 import 'dart:convert'; |
| 9 import 'dart:html' show HttpRequest; | 9 import 'dart:html' show HttpRequest; |
| 10 | 10 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 : this.messageHandler = messageHandler ?? print { | 60 : this.messageHandler = messageHandler ?? print { |
| 61 CompilerOptions.addArguments(argParser); | 61 CompilerOptions.addArguments(argParser); |
| 62 AnalyzerOptions.addArguments(argParser); | 62 AnalyzerOptions.addArguments(argParser); |
| 63 } | 63 } |
| 64 | 64 |
| 65 @override | 65 @override |
| 66 Function run() { | 66 Function run() { |
| 67 return requestSummaries; | 67 return requestSummaries; |
| 68 } | 68 } |
| 69 | 69 |
| 70 void requestSummaries(String sdkUrl, List<String> summaryUrls, | 70 void requestSummaries(String summaryRoot, String sdkUrl, List<String> summaryU
rls, |
| 71 Function onCompileReady, Function onError) { | 71 Function onCompileReady, Function onError) { |
| 72 HttpRequest.request(sdkUrl).then((sdkRequest) { | 72 HttpRequest |
| 73 var sdkResponse = sdkRequest.responseText; | 73 .request(summaryRoot + sdkUrl, |
| 74 var sdkBytes = BASE64.decode(sdkResponse); | 74 responseType: "arraybuffer", mimeType: "application/octet-stream") |
| 75 .then((sdkRequest) { |
| 76 var sdkBytes = sdkRequest.response.asUint8List(); |
| 75 | 77 |
| 76 // Map summary URLs to HttpRequests. | 78 // Map summary URLs to HttpRequests. |
| 77 var summaryRequests = summaryUrls | 79 var summaryRequests = summaryUrls.map((summary) => new Future(() => |
| 78 .map((summary) => new Future(() => HttpRequest.request(summary))); | 80 HttpRequest.request(summaryRoot + summary, |
| 81 responseType: "arraybuffer", |
| 82 mimeType: "application/octet-stream"))); |
| 79 | 83 |
| 80 Future.wait(summaryRequests).then((summaryResponses) { | 84 Future.wait(summaryRequests).then((summaryResponses) { |
| 81 // Map summary responses to summary bytes. | 85 // Map summary responses to summary bytes. |
| 82 var summaryBytes = <List<int>>[]; | 86 var summaryBytes = <List<int>>[]; |
| 83 for (var response in summaryResponses) { | 87 for (var response in summaryResponses) { |
| 84 summaryBytes.add(BASE64.decode(response.responseText)); | 88 summaryBytes.add(response.response.asUint8List()); |
| 85 } | 89 } |
| 86 | 90 |
| 87 var compileFn = setUpCompile(sdkBytes, summaryBytes, summaryUrls); | 91 onCompileReady(setUpCompile(sdkBytes, summaryBytes, summaryUrls)); |
| 88 onCompileReady(compileFn); | |
| 89 }).catchError((error) => onError('Summaries failed to load: $error')); | 92 }).catchError((error) => onError('Summaries failed to load: $error')); |
| 90 }).catchError( | 93 }).catchError( |
| 91 (error) => onError('Dart sdk summaries failed to load: $error')); | 94 (error) => onError('Dart sdk summaries failed to load: $error. url:
$sdkUrl')); |
| 92 } | 95 } |
| 93 | 96 |
| 94 CompileModule setUpCompile(List<int> sdkBytes, List<List<int>> summaryBytes, | 97 List<Function> setUpCompile(List<int> sdkBytes, List<List<int>> summaryBytes, |
| 95 List<String> summaryUrls) { | 98 List<String> summaryUrls) { |
| 96 var dartSdkSummaryPath = '/dart-sdk/lib/_internal/web_sdk.sum'; | 99 var dartSdkSummaryPath = '/dart-sdk/lib/_internal/web_sdk.sum'; |
| 97 | 100 |
| 98 var resourceProvider = new MemoryResourceProvider() | 101 var resourceProvider = new MemoryResourceProvider() |
| 99 ..newFileWithBytes(dartSdkSummaryPath, sdkBytes); | 102 ..newFileWithBytes(dartSdkSummaryPath, sdkBytes); |
| 100 | 103 |
| 101 var resourceUriResolver = new ResourceUriResolver(resourceProvider); | 104 var resourceUriResolver = new ResourceUriResolver(resourceProvider); |
| 102 | 105 |
| 103 var summaryDataStore = new SummaryDataStore([]); | 106 var options = new AnalyzerOptions.basic( |
| 107 dartSdkPath: '/dart-sdk', dartSdkSummaryPath: dartSdkSummaryPath); |
| 108 |
| 109 var summaryDataStore = |
| 110 new SummaryDataStore(options.summaryPaths, resourceProvider: resourcePro
vider, recordDependencyInfo: true); |
| 104 for (var i = 0; i < summaryBytes.length; i++) { | 111 for (var i = 0; i < summaryBytes.length; i++) { |
| 105 var bytes = summaryBytes[i]; | 112 var bytes = summaryBytes[i]; |
| 106 var url = summaryUrls[i]; | 113 var url = '/' + summaryUrls[i]; |
| 107 var summaryBundle = new PackageBundle.fromBuffer(bytes); | 114 var summaryBundle = new PackageBundle.fromBuffer(bytes); |
| 108 summaryDataStore.addBundle(url, summaryBundle); | 115 summaryDataStore.addBundle(url, summaryBundle); |
| 109 } | 116 } |
| 110 var summaryResolver = | 117 var summaryResolver = |
| 111 new InSummaryUriResolver(resourceProvider, summaryDataStore); | 118 new InSummaryUriResolver(resourceProvider, summaryDataStore); |
| 112 | 119 |
| 113 var fileResolvers = [summaryResolver, resourceUriResolver]; | 120 var fileResolvers = [summaryResolver, resourceUriResolver]; |
| 114 | 121 |
| 115 var compiler = new ModuleCompiler( | 122 var compiler = new ModuleCompiler( |
| 116 new AnalyzerOptions.basic( | 123 options, |
| 117 dartSdkPath: '/dart-sdk', dartSdkSummaryPath: dartSdkSummaryPath), | |
| 118 analysisRoot: '/web-compile-root', | 124 analysisRoot: '/web-compile-root', |
| 119 fileResolvers: fileResolvers, | 125 fileResolvers: fileResolvers, |
| 120 resourceProvider: resourceProvider); | 126 resourceProvider: resourceProvider, |
| 127 summaryData: summaryDataStore); |
| 121 | 128 |
| 122 var context = compiler.context as AnalysisContextImpl; | 129 var context = compiler.context as AnalysisContextImpl; |
| 123 context.resultProvider = | |
| 124 new InputPackagesResultProvider(compiler.context, summaryDataStore); | |
| 125 | 130 |
| 126 var compilerOptions = new CompilerOptions.fromArguments(argResults); | 131 var compilerOptions = new CompilerOptions.fromArguments(argResults); |
| 127 | 132 |
| 133 var resolveFn = (String url) { |
| 134 var packagePrefix = 'package:'; |
| 135 var uri = Uri.parse(url); |
| 136 var base = path.basename(url); |
| 137 var parts = uri.pathSegments; |
| 138 var match = null; |
| 139 int bestScore = 0; |
| 140 for (var candidate in summaryDataStore.uriToSummaryPath.keys) { |
| 141 if (path.basename(candidate) != base) continue; |
| 142 List<String> candidateParts = path.dirname(candidate).split('/'); |
| 143 var first = candidateParts.first; |
| 144 |
| 145 // Process and strip "package:" prefix. |
| 146 if (first.startsWith(packagePrefix)) { |
| 147 first = first.substring(packagePrefix.length); |
| 148 candidateParts[0] = first; |
| 149 // Handle convention that directory foo/bar/baz is given package name |
| 150 // foo.bar.baz |
| 151 if (first.contains('.')) { |
| 152 candidateParts = (first.split('.'))..addAll(candidateParts.skip(1)); |
| 153 } |
| 154 } |
| 155 |
| 156 // If file name and extension don't match... give up. |
| 157 int i = parts.length - 1; |
| 158 int j = candidateParts.length - 1; |
| 159 |
| 160 int score = 1; |
| 161 // Greedy algorithm finding matching path segments from right to left |
| 162 // skipping segments on the candidate path unless the target path |
| 163 // segment is named lib. |
| 164 while (i >= 0 && j >= 0) { |
| 165 if (parts[i] == candidateParts[j]) { |
| 166 i--; |
| 167 j--; |
| 168 score++; |
| 169 if (j == 0 && i == 0) { |
| 170 // Arbitrary bonus if we matched all parts of the input |
| 171 // and used up all parts of the output. |
| 172 score += 10; |
| 173 } |
| 174 } else { |
| 175 // skip unmatched lib directories from the input |
| 176 // otherwise skip unmatched parts of the candidate. |
| 177 if (parts[i] == 'lib') { |
| 178 i--; |
| 179 } else { |
| 180 j--; |
| 181 } |
| 182 } |
| 183 } |
| 184 |
| 185 if (score > bestScore) { |
| 186 match = candidate; |
| 187 } |
| 188 } |
| 189 return match; |
| 190 }; |
| 191 |
| 128 CompileModule compileFn = (String imports, String body, String libraryName, | 192 CompileModule compileFn = (String imports, String body, String libraryName, |
| 129 String existingLibrary, String fileName) { | 193 String existingLibrary, String fileName) { |
| 194 // Instead of returning a single function, return a pair of functions. |
| 130 // Create a new virtual File that contains the given Dart source. | 195 // Create a new virtual File that contains the given Dart source. |
| 131 String sourceCode; | 196 String sourceCode; |
| 132 if (existingLibrary == null) { | 197 if (existingLibrary == null) { |
| 133 sourceCode = imports + body; | 198 sourceCode = imports + body; |
| 134 } else { | 199 } else { |
| 135 var dir = path.dirname(existingLibrary); | 200 var dir = path.dirname(existingLibrary); |
| 136 // Need to pull in all the imports from the existing library and | 201 // Need to pull in all the imports from the existing library and |
| 137 // re-export all privates as privates in this library. | 202 // re-export all privates as privates in this library. |
| 138 var source = context.sourceFactory.forUri(existingLibrary); | 203 var source = context.sourceFactory.forUri(existingLibrary); |
| 139 if (source == null) { | 204 if (source == null) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 moduleCode = module | 265 moduleCode = module |
| 201 .getCode(ModuleFormat.legacy, unit.name, unit.name + '.map', | 266 .getCode(ModuleFormat.legacy, unit.name, unit.name + '.map', |
| 202 singleOutFile: true) | 267 singleOutFile: true) |
| 203 .code; | 268 .code; |
| 204 } | 269 } |
| 205 | 270 |
| 206 return new CompileResult( | 271 return new CompileResult( |
| 207 code: moduleCode, isValid: module.isValid, errors: module.errors); | 272 code: moduleCode, isValid: module.isValid, errors: module.errors); |
| 208 }; | 273 }; |
| 209 | 274 |
| 210 // TODO(vsm): Cast is due to https://github.com/dart-lang/sdk/issues/28507 | 275 return [allowInterop(compileFn), allowInterop(resolveFn)]; |
| 211 return allowInterop(compileFn) as CompileModule; | |
| 212 } | 276 } |
| 213 } | 277 } |
| 214 | 278 |
| 215 // Given path, determine corresponding dart library. | 279 // Given path, determine corresponding dart library. |
| 216 String _moduleForLibrary(source) { | 280 String _moduleForLibrary(source) { |
| 217 if (source is InSummarySource) { | 281 if (source is InSummarySource) { |
| 218 return source.summaryPath.substring(1).replaceAll('.api.ds', ''); | 282 return source.summaryPath.substring(1).replaceAll('.api.ds', ''); |
| 219 } | 283 } |
| 220 return source.toString().substring(1).replaceAll('.dart', ''); | 284 return source.toString().substring(1).replaceAll('.dart', ''); |
| 221 } | 285 } |
| 222 | 286 |
| 223 /// Thrown when the input source code has errors. | 287 /// Thrown when the input source code has errors. |
| 224 class CompileErrorException implements Exception { | 288 class CompileErrorException implements Exception { |
| 225 toString() => '\nPlease fix all errors before compiling (warnings are okay).'; | 289 toString() => '\nPlease fix all errors before compiling (warnings are okay).'; |
| 226 } | 290 } |
| OLD | NEW |