mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 02:57:35 +00:00
Working compiler in browser.
BUG= R=jmesserly@google.com Review URL: https://codereview.chromium.org/2183603003 .
This commit is contained in:
parent
d18ab46592
commit
d2ec49d1f7
|
@ -3,15 +3,17 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:analyzer/file_system/file_system.dart' show ResourceUriResolver;
|
||||
import 'package:args/args.dart' show ArgParser, ArgResults;
|
||||
import 'package:analyzer/file_system/file_system.dart'
|
||||
show ResourceProvider, ResourceUriResolver;
|
||||
import 'package:analyzer/file_system/physical_file_system.dart'
|
||||
show PhysicalResourceProvider;
|
||||
import 'package:args/args.dart' show ArgParser, ArgResults;
|
||||
import 'package:analyzer/src/context/context.dart' show AnalysisContextImpl;
|
||||
import 'package:analyzer/src/generated/engine.dart'
|
||||
show AnalysisContext, AnalysisEngine, AnalysisOptionsImpl;
|
||||
import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
|
||||
import 'package:analyzer/src/generated/sdk_io.dart' show DirectoryBasedDartSdk;
|
||||
import 'package:analyzer/src/generated/source.dart';
|
||||
import 'package:analyzer/src/generated/source_io.dart'
|
||||
show
|
||||
CustomUriResolver,
|
||||
|
@ -107,7 +109,9 @@ class AnalyzerOptions {
|
|||
/// Creates an [AnalysisContext] with dev_compiler type rules and inference,
|
||||
/// using [createSourceFactory] to set up its [SourceFactory].
|
||||
AnalysisContext createAnalysisContextWithSources(AnalyzerOptions options,
|
||||
{DartUriResolver sdkResolver, List<UriResolver> fileResolvers}) {
|
||||
{DartUriResolver sdkResolver,
|
||||
List<UriResolver> fileResolvers,
|
||||
ResourceProvider resourceProvider}) {
|
||||
AnalysisEngine.instance.processRequiredPlugins();
|
||||
|
||||
sdkResolver ??=
|
||||
|
@ -122,7 +126,8 @@ AnalysisContext createAnalysisContextWithSources(AnalyzerOptions options,
|
|||
var srcFactory = _createSourceFactory(options,
|
||||
sdkResolver: sdkResolver,
|
||||
fileResolvers: fileResolvers,
|
||||
summaryData: summaryData);
|
||||
summaryData: summaryData,
|
||||
resourceProvider: resourceProvider);
|
||||
|
||||
var context = createAnalysisContext();
|
||||
context.sourceFactory = srcFactory;
|
||||
|
@ -153,7 +158,8 @@ AnalysisContextImpl createAnalysisContext() {
|
|||
SourceFactory _createSourceFactory(AnalyzerOptions options,
|
||||
{DartUriResolver sdkResolver,
|
||||
List<UriResolver> fileResolvers,
|
||||
SummaryDataStore summaryData}) {
|
||||
SummaryDataStore summaryData,
|
||||
ResourceProvider resourceProvider}) {
|
||||
var resolvers = <UriResolver>[];
|
||||
if (options.customUrlMappings.isNotEmpty) {
|
||||
resolvers.add(new CustomUriResolver(options.customUrlMappings));
|
||||
|
@ -165,7 +171,7 @@ SourceFactory _createSourceFactory(AnalyzerOptions options,
|
|||
|
||||
if (fileResolvers == null) fileResolvers = createFileResolvers(options);
|
||||
resolvers.addAll(fileResolvers);
|
||||
return new SourceFactory(resolvers);
|
||||
return new SourceFactory(resolvers, null, resourceProvider);
|
||||
}
|
||||
|
||||
List<UriResolver> createFileResolvers(AnalyzerOptions options) {
|
||||
|
|
|
@ -12,8 +12,12 @@ import 'package:analyzer/analyzer.dart'
|
|||
CompileTimeErrorCode,
|
||||
ErrorSeverity,
|
||||
StaticWarningCode;
|
||||
import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
|
||||
import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
|
||||
import 'package:analyzer/src/generated/source_io.dart' show Source, SourceKind;
|
||||
import 'package:analyzer/src/generated/java_engine.dart' show AnalysisException;
|
||||
import 'package:analyzer/src/generated/source.dart' show DartUriResolver;
|
||||
import 'package:analyzer/src/generated/source_io.dart'
|
||||
show Source, SourceKind, UriResolver;
|
||||
import 'package:func/func.dart' show Func1;
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
|
@ -55,8 +59,14 @@ class ModuleCompiler {
|
|||
}
|
||||
}
|
||||
|
||||
ModuleCompiler(AnalyzerOptions analyzerOptions)
|
||||
: this.withContext(createAnalysisContextWithSources(analyzerOptions));
|
||||
ModuleCompiler(AnalyzerOptions analyzerOptions,
|
||||
{DartUriResolver sdkResolver,
|
||||
ResourceProvider resourceProvider,
|
||||
List<UriResolver> fileResolvers})
|
||||
: this.withContext(createAnalysisContextWithSources(analyzerOptions,
|
||||
sdkResolver: sdkResolver,
|
||||
fileResolvers: fileResolvers,
|
||||
resourceProvider: resourceProvider));
|
||||
|
||||
/// Compiles a single Dart build unit into a JavaScript module.
|
||||
///
|
||||
|
|
|
@ -37,6 +37,12 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
browser:
|
||||
description:
|
||||
name: browser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.0+2"
|
||||
charcode:
|
||||
description:
|
||||
name: charcode
|
||||
|
|
|
@ -11,6 +11,7 @@ dependencies:
|
|||
analyzer: ^0.27.4-alpha.19
|
||||
args: ^0.13.0
|
||||
bazel_worker: ^0.1.0
|
||||
browser: ^0.10.0
|
||||
cli_util: ^0.0.1
|
||||
func: ^0.1.0
|
||||
html: ^0.12.0
|
||||
|
|
1
pkg/dev_compiler/web/dart_sdk.sum
Normal file
1
pkg/dev_compiler/web/dart_sdk.sum
Normal file
File diff suppressed because one or more lines are too long
12
pkg/dev_compiler/web/index.html
Normal file
12
pkg/dev_compiler/web/index.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Dart Browser</title>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/dart" src="main.dart"></script>
|
||||
<script src="packages/browser/dart.js"></script>
|
||||
</body>
|
||||
</html>
|
114
pkg/dev_compiler/web/main.dart
Executable file
114
pkg/dev_compiler/web/main.dart
Executable file
|
@ -0,0 +1,114 @@
|
|||
#!/usr/bin/env dart
|
||||
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
/// Command line entry point for Dart Development Compiler (dartdevc).
|
||||
///
|
||||
/// Supported commands are
|
||||
/// * compile: builds a collection of dart libraries into a single JS module
|
||||
///
|
||||
/// Additionally, these commands are being considered
|
||||
/// * link: combines several JS modules into a single JS file
|
||||
/// * build: compiles & links a set of code, automatically determining
|
||||
/// appropriate groupings of libraries to combine into JS modules
|
||||
/// * watch: watch a directory and recompile build units automatically
|
||||
/// * serve: uses `watch` to recompile and exposes a simple static file server
|
||||
/// for local development
|
||||
///
|
||||
/// These commands are combined so we have less names to expose on the PATH,
|
||||
/// and for development simplicity while the precise UI has not been determined.
|
||||
///
|
||||
/// A more typical structure for web tools is simply to have the compiler with
|
||||
/// "watch" as an option. The challenge for us is:
|
||||
///
|
||||
/// * Dart used to assume whole-program compiles, so we don't have a
|
||||
/// user-declared unit of building, and neither "libraries" or "packages" will
|
||||
/// work,
|
||||
/// * We do not assume a `node` JS installation, so we cannot easily reuse
|
||||
/// existing tools for the "link" step, or assume users have a local
|
||||
/// file server,
|
||||
/// * We didn't have a file watcher API at first,
|
||||
/// * We had no conventions about where compiled output should go (or even
|
||||
/// that we would be compiling at all, vs running on an in-browser Dart VM),
|
||||
/// * We wanted a good first impression with our simple examples, so we used
|
||||
/// local file servers, and users have an expectation of it now, even though
|
||||
/// it doesn't scale to typical apps that need their own real servers.
|
||||
|
||||
@JS()
|
||||
library dev_compiler.web.main;
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:js/js.dart';
|
||||
|
||||
import 'web_command.dart';
|
||||
|
||||
@JS()
|
||||
external set compileDartExpression(Function function);
|
||||
|
||||
typedef String CompileFn(String dart);
|
||||
typedef void OnLoadFn(CompileFn compile);
|
||||
|
||||
Future main() async {
|
||||
var args = ['compile'];
|
||||
_runCommand((result) {
|
||||
compileDartExpression = allowInterop(result);
|
||||
}, args);
|
||||
}
|
||||
|
||||
/// Runs a single compile command, and returns an exit code.
|
||||
Future<int> _runCommand(OnLoadFn onload, List<String> args,
|
||||
{MessageHandler messageHandler}) async {
|
||||
try {
|
||||
var runner = new CommandRunner('dartdevc', 'Dart Development Compiler');
|
||||
runner
|
||||
.addCommand(new WebCompileCommand(onload, messageHandler: messageHandler));
|
||||
await runner.run(args);
|
||||
} catch (e, s) {
|
||||
return _handleError(e, s, args, messageHandler: messageHandler);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// Handles [error] in a uniform fashion. Returns the proper exit code and calls
|
||||
/// [messageHandler] with messages.
|
||||
int _handleError(dynamic error, dynamic stackTrace, List<String> args,
|
||||
{MessageHandler messageHandler}) {
|
||||
messageHandler ??= print;
|
||||
|
||||
if (error is UsageException) {
|
||||
// Incorrect usage, input file not found, etc.
|
||||
messageHandler(error);
|
||||
return 64;
|
||||
} else if (error is CompileErrorException) {
|
||||
// Code has error(s) and failed to compile.
|
||||
messageHandler(error);
|
||||
return 1;
|
||||
} else {
|
||||
// Anything else is likely a compiler bug.
|
||||
//
|
||||
// --unsafe-force-compile is a bit of a grey area, but it's nice not to
|
||||
// crash while compiling
|
||||
// (of course, output code may crash, if it had errors).
|
||||
//
|
||||
messageHandler("");
|
||||
messageHandler("We're sorry, you've found a bug in our compiler.");
|
||||
messageHandler("You can report this bug at:");
|
||||
messageHandler(" https://github.com/dart-lang/dev_compiler/issues");
|
||||
messageHandler("");
|
||||
messageHandler(
|
||||
"Please include the information below in your report, along with");
|
||||
messageHandler(
|
||||
"any other information that may help us track it down. Thanks!");
|
||||
messageHandler("");
|
||||
messageHandler(" dartdevc arguments: " + args.join(' '));
|
||||
messageHandler("");
|
||||
messageHandler("```");
|
||||
messageHandler(error);
|
||||
messageHandler(stackTrace);
|
||||
messageHandler("```");
|
||||
return 70;
|
||||
}
|
||||
}
|
103
pkg/dev_compiler/web/web_command.dart
Normal file
103
pkg/dev_compiler/web/web_command.dart
Normal file
|
@ -0,0 +1,103 @@
|
|||
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
import 'dart:html' show HttpRequest;
|
||||
import 'dart:convert' show BASE64;
|
||||
|
||||
import 'package:analyzer/file_system/file_system.dart'
|
||||
show ResourceProvider, ResourceUriResolver;
|
||||
import 'package:analyzer/file_system/memory_file_system.dart'
|
||||
show MemoryResourceProvider;
|
||||
import 'package:analyzer/src/context/cache.dart'
|
||||
show AnalysisCache, CachePartition;
|
||||
import 'package:analyzer/src/context/context.dart' show AnalysisContextImpl;
|
||||
import 'package:analyzer/src/generated/engine.dart'
|
||||
show AnalysisContext, AnalysisEngine, TimestampedData;
|
||||
import 'package:analyzer/src/generated/sdk.dart'
|
||||
show DartSdk, SdkLibrary, SdkLibraryImpl;
|
||||
import 'package:analyzer/src/generated/source.dart'
|
||||
show DartUriResolver, Source, SourceFactory, UriKind;
|
||||
import 'package:analyzer/src/summary/idl.dart' show PackageBundle;
|
||||
import 'package:analyzer/src/summary/summary_sdk.dart' show SummaryBasedDartSdk;
|
||||
|
||||
import 'package:args/command_runner.dart';
|
||||
|
||||
import 'package:dev_compiler/src/analyzer/context.dart' show AnalyzerOptions;
|
||||
import 'package:dev_compiler/src/compiler/compiler.dart'
|
||||
show BuildUnit, CompilerOptions, JSModuleFile, ModuleCompiler;
|
||||
|
||||
typedef void MessageHandler(Object message);
|
||||
typedef String CompileFn(String dart);
|
||||
typedef void OnLoadFn(CompileFn compile);
|
||||
|
||||
/// The command for invoking the modular compiler.
|
||||
class WebCompileCommand extends Command {
|
||||
get name => 'compile';
|
||||
get description => 'Compile a set of Dart files into a JavaScript module.';
|
||||
final MessageHandler messageHandler;
|
||||
final OnLoadFn onload;
|
||||
|
||||
WebCompileCommand(this.onload, {MessageHandler messageHandler})
|
||||
: this.messageHandler = messageHandler ?? print {
|
||||
CompilerOptions.addArguments(argParser);
|
||||
AnalyzerOptions.addArguments(argParser);
|
||||
}
|
||||
|
||||
@override
|
||||
void run() {
|
||||
var request = new HttpRequest();
|
||||
|
||||
request.onReadyStateChange.listen((_) {
|
||||
if (request.readyState == HttpRequest.DONE &&
|
||||
(request.status == 200 || request.status == 0)) {
|
||||
var response = request.responseText;
|
||||
var sdkBytes = BASE64.decode(response);
|
||||
var result = setUpCompile(sdkBytes);
|
||||
onload(result);
|
||||
}
|
||||
});
|
||||
|
||||
request.open('get', 'dart_sdk.sum');
|
||||
request.send();
|
||||
}
|
||||
|
||||
CompileFn setUpCompile(List<int> sdkBytes) {
|
||||
var resourceProvider = new MemoryResourceProvider();
|
||||
var packageBundle = new PackageBundle.fromBuffer(sdkBytes);
|
||||
var webDartSdk = new SummaryBasedDartSdk.fromBundle(
|
||||
true, packageBundle, resourceProvider);
|
||||
|
||||
var sdkResolver = new DartUriResolver(webDartSdk);
|
||||
var fileResolvers = [new ResourceUriResolver(resourceProvider)];
|
||||
|
||||
var compiler = new ModuleCompiler(
|
||||
new AnalyzerOptions(dartSdkPath: '/dart-sdk'),
|
||||
sdkResolver: sdkResolver,
|
||||
fileResolvers: fileResolvers,
|
||||
resourceProvider: resourceProvider);
|
||||
|
||||
var compilerOptions = new CompilerOptions.fromArguments(argResults);
|
||||
|
||||
var number = 0;
|
||||
|
||||
return (String dart) {
|
||||
// Create a new virtual File that contains the given Dart source.
|
||||
number++;
|
||||
resourceProvider.newFile("/expression$number.dart", dart);
|
||||
|
||||
var unit =
|
||||
new BuildUnit("", "", ["file:///expression$number.dart"], null);
|
||||
|
||||
JSModuleFile module = compiler.compile(unit, compilerOptions);
|
||||
module.errors.forEach(messageHandler);
|
||||
|
||||
if (!module.isValid) throw new CompileErrorException();
|
||||
return module.code;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// Thrown when the input source code has errors.
|
||||
class CompileErrorException implements Exception {
|
||||
toString() => '\nPlease fix all errors before compiling (warnings are okay).';
|
||||
}
|
Loading…
Reference in a new issue