Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Unified Diff: pkg/dev_compiler/web/web_command.dart

Issue 2423313002: Emulate compiling a source file in the context of an existing library. Add --debugger-compile flag … (Closed)
Patch Set: Code review comments. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/dev_compiler/web/main.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/dev_compiler/web/web_command.dart
diff --git a/pkg/dev_compiler/web/web_command.dart b/pkg/dev_compiler/web/web_command.dart
index 5f6514a9b789711f31bc79a99c4919d4e2dfd3c9..68b216a7ddb01eb71f9c96ac9432e6d73ec33653 100644
--- a/pkg/dev_compiler/web/web_command.dart
+++ b/pkg/dev_compiler/web/web_command.dart
@@ -5,9 +5,15 @@
library dev_compiler.web.web_command;
import 'dart:async';
+import 'dart:convert';
import 'dart:html' show HttpRequest;
-import 'dart:convert' show BASE64;
+import 'package:analyzer/dart/element/element.dart'
+ show
+ LibraryElement,
+ ImportElement,
+ ShowElementCombinator,
+ HideElementCombinator;
import 'package:analyzer/file_system/file_system.dart' show ResourceUriResolver;
import 'package:analyzer/file_system/memory_file_system.dart'
show MemoryResourceProvider;
@@ -20,6 +26,7 @@ import 'package:analyzer/src/summary/package_bundle_reader.dart'
InSummaryUriResolver,
InputPackagesResultProvider,
InSummarySource;
+import 'package:analyzer/src/dart/resolver/scope.dart' show Scope;
import 'package:analyzer/src/summary/summary_sdk.dart' show SummaryBasedDartSdk;
import 'package:args/command_runner.dart';
@@ -30,6 +37,7 @@ import 'package:dev_compiler/src/compiler/compiler.dart'
import 'package:dev_compiler/src/compiler/module_builder.dart';
import 'package:js/js.dart';
+import 'package:path/path.dart' as path;
typedef void MessageHandler(Object message);
@@ -40,8 +48,8 @@ class CompileResult {
{String code, List<String> errors, bool isValid});
}
-typedef CompileResult CompileModule(
- String code, String libraryName, String fileName);
+typedef CompileModule(String imports, String body, String libraryName,
+ String existingLibrary, String fileName);
/// The command for invoking the modular compiler.
class WebCompileCommand extends Command {
@@ -102,7 +110,8 @@ class WebCompileCommand extends Command {
var summaryBundle = new PackageBundle.fromBuffer(bytes);
summaryDataStore.addBundle(url, summaryBundle);
}
- var summaryResolver = new InSummaryUriResolver(resourceProvider, summaryDataStore);
+ var summaryResolver =
+ new InSummaryUriResolver(resourceProvider, summaryDataStore);
var fileResolvers = [summaryResolver, resourceUriResolver];
@@ -112,24 +121,85 @@ class WebCompileCommand extends Command {
fileResolvers: fileResolvers,
resourceProvider: resourceProvider);
- (compiler.context as AnalysisContextImpl).resultProvider =
+ var context = compiler.context as AnalysisContextImpl;
+ context.resultProvider =
new InputPackagesResultProvider(compiler.context, summaryDataStore);
var compilerOptions = new CompilerOptions.fromArguments(argResults);
- CompileModule compileFn =
- (String sourceCode, String libraryName, String fileName) {
+ CompileModule compileFn = (String imports, String body, String libraryName,
+ String existingLibrary, String fileName) {
// Create a new virtual File that contains the given Dart source.
- resourceProvider.newFile("/$fileName", sourceCode);
+ String sourceCode;
+ if (existingLibrary == null) {
+ sourceCode = imports + body;
+ } else {
+ var dir = path.dirname(existingLibrary);
+ // Need to pull in all the imports from the existing library and
+ // re-export all privates as privates in this library.
+ var source = context.sourceFactory.forUri(existingLibrary);
+ if (source == null) {
+ throw "Unable to load source for library $existingLibrary";
+ }
+
+ LibraryElement libraryElement = context.computeLibraryElement(source);
+ if (libraryElement == null) {
+ throw "Unable to get library element.";
+ }
+ var sb = new StringBuffer(imports);
+ sb.write('\n');
+
+ // TODO(jacobr): we need to add a proper Analyzer flag specifing that
+ // cross-library privates should be in scope instead of this hack.
+ // We set the private name prefix for scope resolution to an invalid
+ // character code so that the analyzer ignores normal Dart private
+ // scoping rules for top level names allowing REPL users to access
+ // privates in arbitrary libraries. The downside of this scheme is it is
+ // possible to get errors if privates in the current library and
+ // imported libraries happen to have exactly the same name.
+ Scope.PRIVATE_NAME_PREFIX = -1;
+
+ // We emulate running code in the context of an existing library by
+ // importing that library and all libraries it imports.
+ sb.write('import ${JSON.encode(existingLibrary)};\n');
+
+ for (ImportElement importElement in libraryElement.imports) {
+ if (importElement.uri == null) continue;
+ var uri = importElement.uri;
+ // dart: and package: uris are not relative but the path package
+ // thinks they are. We have to provide absolute uris as our library
+ // has a different directory than the library we are pretending to be.
+ if (path.isRelative(uri) &&
+ !uri.startsWith('package:') &&
+ !uri.startsWith('dart:')) {
+ uri = path.normalize(path.join(dir, uri));
+ }
+ sb.write('import ${JSON.encode(uri)}');
+ if (importElement.prefix != null)
+ sb.write(' as ${importElement.prefix.name}');
+ for (var combinator in importElement.combinators) {
+ if (combinator is ShowElementCombinator) {
+ sb.write(' show ${combinator.shownNames.join(', ')}');
+ } else if (combinator is HideElementCombinator) {
+ sb.write(' hide ${combinator.hiddenNames.join(', ')}');
+ } else {
+ throw 'Unexpected element combinator';
+ }
+ }
+ sb.write(';\n');
+ }
+ sb.write(body);
+ sourceCode = sb.toString();
+ }
+ resourceProvider.newFile(fileName, sourceCode);
- var unit = new BuildUnit(
- libraryName, "", ["file:///$fileName"], _moduleForLibrary);
+ var unit = new BuildUnit(libraryName, "", [fileName], _moduleForLibrary);
JSModuleFile module = compiler.compile(unit, compilerOptions);
var moduleCode = module.isValid
? module
- .getCode(ModuleFormat.legacy, false, unit.name, unit.name + '.map')
+ .getCode(ModuleFormat.legacy, true, unit.name, unit.name + '.map')
.code
: '';
« no previous file with comments | « pkg/dev_compiler/web/main.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698