| 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 /// Tests code generation. | 5 /// Tests code generation. | 
| 6 /// | 6 /// | 
| 7 /// Runs Dart Dev Compiler on all input in the `codegen` directory and checks | 7 /// Runs Dart Dev Compiler on all input in the `codegen` directory and checks | 
| 8 /// that the output is what we expected. | 8 /// that the output is what we expected. | 
| 9 library dev_compiler.test.codegen_test; | 9 library dev_compiler.test.codegen_test; | 
| 10 | 10 | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 33 import 'multitest.dart' show extractTestsFromMultitest, isMultiTest; | 33 import 'multitest.dart' show extractTestsFromMultitest, isMultiTest; | 
| 34 import '../tool/build_sdk.dart' as build_sdk; | 34 import '../tool/build_sdk.dart' as build_sdk; | 
| 35 import 'package:dev_compiler/src/compiler/compiler.dart'; | 35 import 'package:dev_compiler/src/compiler/compiler.dart'; | 
| 36 | 36 | 
| 37 final ArgParser argParser = new ArgParser() | 37 final ArgParser argParser = new ArgParser() | 
| 38   ..addOption('dart-sdk', help: 'Dart SDK Path', defaultsTo: null); | 38   ..addOption('dart-sdk', help: 'Dart SDK Path', defaultsTo: null); | 
| 39 | 39 | 
| 40 /// The `test/codegen` directory. | 40 /// The `test/codegen` directory. | 
| 41 final codegenDir = path.join(testDirectory, 'codegen'); | 41 final codegenDir = path.join(testDirectory, 'codegen'); | 
| 42 | 42 | 
|  | 43 /// The `test/codegen/expect` directory. | 
|  | 44 final codegenExpectDir = path.join(codegenDir, 'expect'); | 
|  | 45 | 
| 43 /// The generated directory where tests, expanded multitests, and other test | 46 /// The generated directory where tests, expanded multitests, and other test | 
| 44 /// support libraries are copied to. | 47 /// support libraries are copied to. | 
| 45 /// | 48 /// | 
| 46 /// The tests sometimes import utility libraries using a relative path. | 49 /// The tests sometimes import utility libraries using a relative path. | 
| 47 /// Likewise, the multitests do too, and one multitest even imports its own | 50 /// Likewise, the multitests do too, and one multitest even imports its own | 
| 48 /// non-expanded form (!). To make that simpler, we copy the entire test tree | 51 /// non-expanded form (!). To make that simpler, we copy the entire test tree | 
| 49 /// to a generated directory and expand that multitests in there too. | 52 /// to a generated directory and expand that multitests in there too. | 
| 50 final codegenTestDir = path.join(repoDirectory, 'gen', 'codegen_tests'); | 53 final codegenTestDir = path.join(repoDirectory, 'gen', 'codegen_tests'); | 
| 51 | 54 | 
| 52 /// The generated directory where tests and packages compiled to JS are | 55 /// The generated directory where tests and packages compiled to JS are | 
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 98 | 101 | 
| 99   // Compile each test file to JS and put the result in gen/codegen_output. | 102   // Compile each test file to JS and put the result in gen/codegen_output. | 
| 100   for (var testFile in testFiles) { | 103   for (var testFile in testFiles) { | 
| 101     var relativePath = path.relative(testFile, from: codegenTestDir); | 104     var relativePath = path.relative(testFile, from: codegenTestDir); | 
| 102 | 105 | 
| 103     // Only compile the top-level files for generating coverage. | 106     // Only compile the top-level files for generating coverage. | 
| 104     if (codeCoverage && path.dirname(relativePath) != ".") continue; | 107     if (codeCoverage && path.dirname(relativePath) != ".") continue; | 
| 105 | 108 | 
| 106     var name = path.withoutExtension(relativePath); | 109     var name = path.withoutExtension(relativePath); | 
| 107     test('dartdevc $name', () { | 110     test('dartdevc $name', () { | 
| 108       var outDir = path.join(codegenOutputDir, path.dirname(relativePath)); | 111       var relativeDir = path.dirname(relativePath); | 
| 109       _ensureDirectory(outDir); | 112       var outDir = path.join(codegenOutputDir, relativeDir); | 
|  | 113       var expectDir = path.join(codegenExpectDir, relativeDir); | 
| 110 | 114 | 
| 111       // Check if we need to use special compile options. | 115       // Check if we need to use special compile options. | 
| 112       var contents = new File(testFile).readAsStringSync(); | 116       var contents = new File(testFile).readAsStringSync(); | 
| 113       var match = | 117       var match = | 
| 114           new RegExp(r'// compile options: (.*)').matchAsPrefix(contents); | 118           new RegExp(r'// compile options: (.*)').matchAsPrefix(contents); | 
| 115 | 119 | 
| 116       var args = defaultOptions.toList(); | 120       var args = defaultOptions.toList(); | 
| 117       if (match != null) { | 121       if (match != null) { | 
| 118         args.addAll(match.group(1).split(' ')); | 122         args.addAll(match.group(1).split(' ')); | 
| 119       } | 123       } | 
| 120       var options = | 124       var options = | 
| 121           new CompilerOptions.fromArguments(compilerArgParser.parse(args)); | 125           new CompilerOptions.fromArguments(compilerArgParser.parse(args)); | 
| 122 | 126 | 
| 123       // Collect any other files we've imported. | 127       // Collect any other files we've imported. | 
| 124       var files = new Set<String>(); | 128       var files = new Set<String>(); | 
| 125       _collectTransitiveImports(contents, files, from: testFile); | 129       _collectTransitiveImports(contents, files, from: testFile); | 
| 126       var moduleName = | 130       var moduleName = | 
| 127           path.withoutExtension(path.relative(testFile, from: codegenTestDir)); | 131           path.withoutExtension(path.relative(testFile, from: codegenTestDir)); | 
| 128       var unit = new BuildUnit(moduleName, path.dirname(testFile), | 132       var unit = new BuildUnit(moduleName, path.dirname(testFile), | 
| 129           files.toList(), _moduleForLibrary); | 133           files.toList(), _moduleForLibrary); | 
| 130       var module = compiler.compile(unit, options); | 134       var module = compiler.compile(unit, options); | 
| 131       _writeModule( | 135       _writeModule( | 
| 132           path.join(outDir, path.basenameWithoutExtension(testFile)), module); | 136           path.join(outDir, path.basenameWithoutExtension(testFile)), | 
|  | 137           path.join(expectDir, path.basenameWithoutExtension(testFile)), | 
|  | 138           module); | 
| 133     }); | 139     }); | 
| 134   } | 140   } | 
| 135 | 141 | 
| 136   if (codeCoverage) { | 142   if (codeCoverage) { | 
| 137     test('build_sdk code coverage', () { | 143     test('build_sdk code coverage', () { | 
| 138       return build_sdk.main(['--dart-sdk', sdkDir, '-o', codegenOutputDir]); | 144       return build_sdk.main(['--dart-sdk', sdkDir, '-o', codegenOutputDir]); | 
| 139     }); | 145     }); | 
| 140   } | 146   } | 
| 141 } | 147 } | 
| 142 | 148 | 
| 143 void _writeModule(String outPath, JSModuleFile result) { | 149 void _writeModule(String outPath, String expectPath, JSModuleFile result) { | 
| 144   _ensureDirectory(path.dirname(outPath)); | 150   _ensureDirectory(path.dirname(outPath)); | 
|  | 151   _ensureDirectory(path.dirname(expectPath)); | 
| 145 | 152 | 
| 146   String errors = result.errors.join('\n'); | 153   String errors = result.errors.join('\n'); | 
| 147   if (errors.isNotEmpty && !errors.endsWith('\n')) errors += '\n'; | 154   if (errors.isNotEmpty && !errors.endsWith('\n')) errors += '\n'; | 
| 148   new File(outPath + '.txt').writeAsStringSync(errors); | 155   new File(outPath + '.txt').writeAsStringSync(errors); | 
| 149 | 156 | 
| 150   var jsFile = new File(outPath + '.js'); | 157   var jsFile = new File(outPath + '.js'); | 
|  | 158   var expectFile = new File(expectPath + '.js'); | 
| 151   var errorFile = new File(outPath + '.err'); | 159   var errorFile = new File(outPath + '.err'); | 
| 152 | 160 | 
| 153   if (result.isValid) { | 161   if (result.isValid) { | 
| 154     jsFile.writeAsStringSync(result.code); | 162     jsFile.writeAsStringSync(result.code); | 
| 155     if (result.sourceMap != null) { | 163     if (result.sourceMap != null) { | 
| 156       var mapPath = outPath + '.js.map'; | 164       var mapPath = outPath + '.js.map'; | 
| 157       new File(mapPath) | 165       new File(mapPath) | 
| 158           .writeAsStringSync(JSON.encode(result.placeSourceMap(mapPath))); | 166           .writeAsStringSync(JSON.encode(result.placeSourceMap(mapPath))); | 
| 159     } | 167     } | 
| 160 | 168 | 
|  | 169     expectFile.writeAsStringSync(result.code); | 
|  | 170 | 
| 161     // There are no errors, so delete any stale ".err" file. | 171     // There are no errors, so delete any stale ".err" file. | 
| 162     if (errorFile.existsSync()) { | 172     if (errorFile.existsSync()) { | 
| 163       errorFile.deleteSync(); | 173       errorFile.deleteSync(); | 
| 164     } | 174     } | 
| 165   } else { | 175   } else { | 
| 166     // Also write the errors to a '.err' file for easy counting. | 176     // Also write the errors to a '.err' file for easy counting. | 
| 167     var moduleName = result.name; | 177     var moduleName = result.name; | 
| 168     var libraryName = path.split(moduleName).last; | 178     var libraryName = path.split(moduleName).last; | 
| 169     var count = "[error]".allMatches(errors).length; | 179     var count = "[error]".allMatches(errors).length; | 
| 170     var text = ''' | 180     var text = ''' | 
| 171 dart_library.library('$moduleName', null, [ | 181 dart_library.library('$moduleName', null, [ | 
| 172   'dart_sdk', | 182   'dart_sdk', | 
| 173   'expect' | 183   'expect' | 
| 174 ], function(exports, dart_sdk, expect) { | 184 ], function(exports, dart_sdk, expect) { | 
| 175   const message = `DDC Compilation Error: $moduleName has $count errors`; | 185   const message = `DDC Compilation Error: $moduleName has $count errors`; | 
| 176   const error = new Error(message); | 186   const error = new Error(message); | 
| 177   exports.$libraryName = Object.create(null); | 187   exports.$libraryName = Object.create(null); | 
| 178   exports.$libraryName.main = function() { | 188   exports.$libraryName.main = function() { | 
| 179     throw error; | 189     throw error; | 
| 180   } | 190   } | 
| 181 }); | 191 }); | 
| 182     '''; | 192     '''; | 
| 183     errorFile.writeAsStringSync(text); | 193     errorFile.writeAsStringSync(text); | 
| 184 | 194 | 
| 185     // There are errors, so delete any stale ".js" file. | 195     // There are errors, so delete any stale ".js" file. | 
| 186     if (jsFile.existsSync()) { | 196     if (jsFile.existsSync()) { | 
| 187       jsFile.deleteSync(); | 197       jsFile.deleteSync(); | 
| 188     } | 198     } | 
|  | 199 | 
|  | 200     // There are errors, so delete any stale expect ".js" file. | 
|  | 201     if (expectFile.existsSync()) { | 
|  | 202       expectFile.deleteSync(); | 
|  | 203     } | 
|  | 204     expectFile.writeAsStringSync("//FAILED TO COMPILE"); | 
| 189   } | 205   } | 
| 190 } | 206 } | 
| 191 | 207 | 
| 192 void _buildAllPackages(ModuleCompiler compiler) { | 208 void _buildAllPackages(ModuleCompiler compiler) { | 
| 193   group('dartdevc package', () { | 209   group('dartdevc package', () { | 
| 194     _buildPackages(compiler, codegenOutputDir); | 210       _buildPackages(compiler, codegenOutputDir, codegenExpectDir); | 
| 195 | 211 | 
| 196     var packages = ['matcher', 'path', 'stack_trace']; | 212     var packages = ['matcher', 'path', 'stack_trace']; | 
| 197     for (var package in packages) { | 213     for (var package in packages) { | 
| 198       test(package, () { | 214       test(package, () { | 
| 199         _buildPackage(compiler, codegenOutputDir, package); | 215           _buildPackage(compiler, codegenOutputDir, codegenExpectDir, package); | 
| 200       }); | 216       }); | 
| 201     } | 217     } | 
| 202 | 218 | 
| 203     test('unittest', () { | 219     test('unittest', () { | 
| 204       // Only build files applicable to the web - html_*.dart and its | 220       // Only build files applicable to the web - html_*.dart and its | 
| 205       // internal dependences. | 221       // internal dependences. | 
| 206       _buildPackage(compiler, codegenOutputDir, "unittest", packageFiles: [ | 222         _buildPackage(compiler, codegenOutputDir, codegenExpectDir, "unittest", 
     packageFiles: [ | 
| 207         'unittest.dart', | 223         'unittest.dart', | 
| 208         'html_config.dart', | 224         'html_config.dart', | 
| 209         'html_individual_config.dart', | 225         'html_individual_config.dart', | 
| 210         'html_enhanced_config.dart' | 226         'html_enhanced_config.dart' | 
| 211       ]); | 227       ]); | 
| 212     }); | 228     }); | 
| 213   }); | 229   }); | 
| 214 | 230 | 
| 215   test('dartdevc sunflower', () { | 231   test('dartdevc sunflower', () { | 
| 216     _buildSunflower(compiler, codegenOutputDir); | 232     _buildSunflower(compiler, codegenOutputDir, codegenExpectDir); | 
| 217   }); | 233   }); | 
| 218 } | 234 } | 
| 219 | 235 | 
| 220 void _buildSunflower(ModuleCompiler compiler, String outputDir) { | 236 void _buildSunflower(ModuleCompiler compiler, String outputDir, String expectDir
     ) { | 
| 221   var baseDir = path.join(codegenDir, 'sunflower'); | 237   var baseDir = path.join(codegenDir, 'sunflower'); | 
| 222   var files = ['sunflower', 'circle', 'painter'] | 238   var files = ['sunflower', 'circle', 'painter'] | 
| 223       .map((f) => path.join(baseDir, '$f.dart')) | 239       .map((f) => path.join(baseDir, '$f.dart')) | 
| 224       .toList(); | 240       .toList(); | 
| 225   var input = new BuildUnit('sunflower', baseDir, files, _moduleForLibrary); | 241   var input = new BuildUnit('sunflower', baseDir, files, _moduleForLibrary); | 
| 226   var options = new CompilerOptions(summarizeApi: false); | 242   var options = new CompilerOptions(summarizeApi: false); | 
| 227 | 243 | 
| 228   var built = compiler.compile(input, options); | 244   var built = compiler.compile(input, options); | 
| 229   _writeModule(path.join(outputDir, 'sunflower', 'sunflower'), built); | 245   _writeModule(path.join(outputDir, 'sunflower', 'sunflower'), | 
|  | 246                path.join(expectDir, 'sunflower', 'sunflower'), built); | 
| 230 } | 247 } | 
| 231 | 248 | 
| 232 void _buildPackages(ModuleCompiler compiler, String outputDir) { | 249 void _buildPackages(ModuleCompiler compiler, String outputDir, String expectDir)
      { | 
| 233   // Note: we don't summarize these, as we're going to rely on our in-memory | 250   // Note: we don't summarize these, as we're going to rely on our in-memory | 
| 234   // shared analysis context for caching, and `_moduleForLibrary` below | 251   // shared analysis context for caching, and `_moduleForLibrary` below | 
| 235   // understands these are from other modules. | 252   // understands these are from other modules. | 
| 236   var options = new CompilerOptions(sourceMap: false, summarizeApi: false); | 253   var options = new CompilerOptions(sourceMap: false, summarizeApi: false); | 
| 237 | 254 | 
| 238   for (var uri in packageUrlMappings.keys) { | 255   for (var uri in packageUrlMappings.keys) { | 
| 239     assert(uri.startsWith('package:')); | 256     assert(uri.startsWith('package:')); | 
| 240     var uriPath = uri.substring('package:'.length); | 257     var uriPath = uri.substring('package:'.length); | 
| 241     var name = path.basenameWithoutExtension(uriPath); | 258     var name = path.basenameWithoutExtension(uriPath); | 
| 242     test(name, () { | 259     test(name, () { | 
| 243       var input = new BuildUnit(name, codegenDir, [uri], _moduleForLibrary); | 260       var input = new BuildUnit(name, codegenDir, [uri], _moduleForLibrary); | 
| 244       var built = compiler.compile(input, options); | 261       var built = compiler.compile(input, options); | 
| 245 | 262 | 
| 246       var outPath = path.join(outputDir, path.withoutExtension(uriPath)); | 263       var outPath = path.join(outputDir, path.withoutExtension(uriPath)); | 
| 247       _writeModule(outPath, built); | 264       var expectPath = path.join(expectDir, path.withoutExtension(uriPath)); | 
|  | 265       _writeModule(outPath, expectPath, built); | 
| 248     }); | 266     }); | 
| 249   } | 267   } | 
| 250 } | 268 } | 
| 251 | 269 | 
| 252 void _buildPackage(ModuleCompiler compiler, String outputDir, packageName, | 270 void _buildPackage(ModuleCompiler compiler, String outputDir, String expectDir, 
     packageName, | 
| 253     {List<String> packageFiles}) { | 271     {List<String> packageFiles}) { | 
| 254   var options = new CompilerOptions(sourceMap: false, summarizeApi: false); | 272   var options = new CompilerOptions(sourceMap: false, summarizeApi: false); | 
| 255 | 273 | 
| 256   var packageRoot = path.join(codegenDir, 'packages'); | 274   var packageRoot = path.join(codegenDir, 'packages'); | 
| 257   var packageInputDir = path.join(packageRoot, packageName); | 275   var packageInputDir = path.join(packageRoot, packageName); | 
| 258   List<String> files; | 276   List<String> files; | 
| 259   if (packageFiles != null) { | 277   if (packageFiles != null) { | 
| 260     // Only collect files transitively reachable from packageFiles. | 278     // Only collect files transitively reachable from packageFiles. | 
| 261     var reachable = new Set<String>(); | 279     var reachable = new Set<String>(); | 
| 262     for (var file in packageFiles) { | 280     for (var file in packageFiles) { | 
| 263       file = path.join(packageInputDir, file); | 281       file = path.join(packageInputDir, file); | 
| 264       _collectTransitiveImports(new File(file).readAsStringSync(), reachable, | 282       _collectTransitiveImports(new File(file).readAsStringSync(), reachable, | 
| 265           packageRoot: packageRoot, from: file); | 283           packageRoot: packageRoot, from: file); | 
| 266     } | 284     } | 
| 267     files = reachable.toList(); | 285     files = reachable.toList(); | 
| 268   } else { | 286   } else { | 
| 269     // Collect all files in the packages directory. | 287     // Collect all files in the packages directory. | 
| 270     files = new Directory(packageInputDir) | 288     files = new Directory(packageInputDir) | 
| 271         .listSync(recursive: true) | 289         .listSync(recursive: true) | 
| 272         .where((entry) => entry.path.endsWith('.dart')) | 290         .where((entry) => entry.path.endsWith('.dart')) | 
| 273         .map((entry) => entry.path) | 291         .map((entry) => entry.path) | 
| 274         .toList(); | 292         .toList(); | 
| 275   } | 293   } | 
| 276 | 294 | 
| 277   var unit = | 295   var unit = | 
| 278       new BuildUnit(packageName, packageInputDir, files, _moduleForLibrary); | 296       new BuildUnit(packageName, packageInputDir, files, _moduleForLibrary); | 
| 279   var module = compiler.compile(unit, options); | 297   var module = compiler.compile(unit, options); | 
| 280 | 298 | 
| 281   var outPath = path.join(outputDir, packageName, packageName); | 299   var outPath = path.join(outputDir, packageName, packageName); | 
| 282   _writeModule(outPath, module); | 300   var expectPath = path.join(expectDir, packageName, packageName); | 
|  | 301   _writeModule(outPath, expectPath, module); | 
| 283 } | 302 } | 
| 284 | 303 | 
| 285 String _moduleForLibrary(Source source) { | 304 String _moduleForLibrary(Source source) { | 
| 286   var scheme = source.uri.scheme; | 305   var scheme = source.uri.scheme; | 
| 287   if (scheme == 'package') { | 306   if (scheme == 'package') { | 
| 288     return source.uri.pathSegments.first; | 307     return source.uri.pathSegments.first; | 
| 289   } | 308   } | 
| 290   throw new Exception('Module not found for library "${source.fullName}"'); | 309   throw new Exception('Module not found for library "${source.fullName}"'); | 
| 291 } | 310 } | 
| 292 | 311 | 
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 399 /// Simplified from ParseDartTask.resolveDirective. | 418 /// Simplified from ParseDartTask.resolveDirective. | 
| 400 String _resolveDirective(UriBasedDirective directive) { | 419 String _resolveDirective(UriBasedDirective directive) { | 
| 401   StringLiteral uriLiteral = directive.uri; | 420   StringLiteral uriLiteral = directive.uri; | 
| 402   String uriContent = uriLiteral.stringValue; | 421   String uriContent = uriLiteral.stringValue; | 
| 403   if (uriContent != null) { | 422   if (uriContent != null) { | 
| 404     uriContent = uriContent.trim(); | 423     uriContent = uriContent.trim(); | 
| 405     directive.uriContent = uriContent; | 424     directive.uriContent = uriContent; | 
| 406   } | 425   } | 
| 407   return directive.validate() == null ? uriContent : null; | 426   return directive.validate() == null ? uriContent : null; | 
| 408 } | 427 } | 
| OLD | NEW | 
|---|