mirror of
https://github.com/dart-lang/sdk
synced 2024-09-19 20:51:50 +00:00
Launch Leg independently of Frog.
Review URL: https://chromiumcodereview.appspot.com//9719019 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@5630 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
a4b6cb96d1
commit
34cb21fce4
22
dart.gyp
22
dart.gyp
|
@ -4,7 +4,7 @@
|
|||
|
||||
{
|
||||
'variables': {
|
||||
# These variables are used in the creation of the .vcproj file on
|
||||
# These variables are used in the creation of the .vcproj file on
|
||||
# Windows.
|
||||
'cygwin_dir': 'third_party/cygwin',
|
||||
},
|
||||
|
@ -26,20 +26,6 @@
|
|||
'runtime/dart-runtime.gyp:process_test',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'frog',
|
||||
'type': 'none',
|
||||
'dependencies': [
|
||||
'frog/dart-frog.gyp:frog',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'frogsh',
|
||||
'type': 'none',
|
||||
'dependencies': [
|
||||
'frog/dart-frog.gyp:frogsh',
|
||||
],
|
||||
},
|
||||
{
|
||||
'target_name': 'create_sdk',
|
||||
'type': 'none',
|
||||
|
@ -111,6 +97,12 @@
|
|||
'type': 'none',
|
||||
'dependencies': [
|
||||
'utils/compiler/compiler.gyp:dart2js',
|
||||
|
||||
# TODO(ahe): Remove dependencies on frog and frogsh, they are
|
||||
# just here to simplify
|
||||
# frog/scripts/buildbot_annotated_steps.py temporarily.
|
||||
'frog/dart-frog.gyp:frog',
|
||||
'frog/dart-frog.gyp:frogsh',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -9,73 +9,61 @@ main() {
|
|||
List<String> arguments = new Options().arguments;
|
||||
Uri uri = new Uri(scheme: 'file', path: '${arguments[0]}/');
|
||||
String dartVmLocation = uri.resolve(arguments[1]).path;
|
||||
String productionLauncherLocation = uri.resolve(arguments[2]).path;
|
||||
String developerLauncherLocation = uri.resolve(arguments[3]).path;
|
||||
String productionLaunch = '#!$dartVmLocation\n';
|
||||
String developerLaunch = '#!$dartVmLocation --enable_checked_mode\n';
|
||||
String launcherScript = """
|
||||
Uri productionLauncher = uri.resolve(arguments[2]);
|
||||
Uri developerLauncher = uri.resolve(arguments[3]);
|
||||
String launcherScript = buildScript(uri);
|
||||
|
||||
writeScript(productionLauncher,
|
||||
['#!$dartVmLocation\n',
|
||||
launcherScript]);
|
||||
writeScript(developerLauncher,
|
||||
['#!$dartVmLocation --enable_checked_mode\n',
|
||||
launcherScript]);
|
||||
}
|
||||
|
||||
writeScript(Uri uri, List<String> chunks) {
|
||||
var f = new File(uri.path);
|
||||
var stream = f.openSync(FileMode.WRITE);
|
||||
for (String chunk in chunks) {
|
||||
stream.writeStringSync(chunk);
|
||||
}
|
||||
stream.closeSync();
|
||||
|
||||
// TODO(ahe): Make script executable.
|
||||
// TODO(ahe): Also make a .bat file for Windows.
|
||||
}
|
||||
|
||||
buildScript(Uri uri) {
|
||||
return """
|
||||
|
||||
#import('dart:io');
|
||||
|
||||
#import('${uri.resolve('../../frog/file_system_vm.dart').path}', prefix: 'fs');
|
||||
#import('${uri.resolve('../../frog/lang.dart').path}', prefix: 'lang');
|
||||
#import('${uri.resolve('../../frog/leg/frog_leg.dart').path}', prefix: 'leg');
|
||||
#import('${uri.resolve('../../utils/compiler/dart2js.dart').path}');
|
||||
|
||||
void main() {
|
||||
lang.legCompile = leg.compile;
|
||||
try {
|
||||
|
||||
List<String> argv = (new Options()).arguments;
|
||||
|
||||
// Infer --out if there is none defined.
|
||||
var outFileDefined = false;
|
||||
for (var arg in argv) {
|
||||
if (arg.startsWith('--out=')) outFileDefined = true;
|
||||
}
|
||||
|
||||
if (!outFileDefined) {
|
||||
argv.insertRange(0, 1, '--out=' + argv[argv.length-1] + '.js');
|
||||
}
|
||||
|
||||
// TODO(dgrove) we're simulating node by placing the arguments to frogc
|
||||
// starting at index 2.
|
||||
argv.insertRange(0, 4, null);
|
||||
|
||||
argv[2] = '--leg';
|
||||
argv[3] = '--libdir=${uri.resolve('../../frog/lib').path}';
|
||||
|
||||
// TODO(dgrove) Until we have a way of getting the executable's path, we'll
|
||||
// run from '.'
|
||||
var homedir = (new File('.')).fullPathSync();
|
||||
|
||||
if (!lang.compile(homedir, argv, new fs.VMFileSystem())) {
|
||||
print('Compilation failed');
|
||||
exit(1);
|
||||
}
|
||||
} catch (var exception, var trace) {
|
||||
class Helper {
|
||||
void run() {
|
||||
try {
|
||||
print('Internal error: \$exception');
|
||||
} catch (var ignored) {
|
||||
print('Internal error: error while printing exception');
|
||||
}
|
||||
try {
|
||||
print(trace);
|
||||
} finally {
|
||||
exit(253);
|
||||
List<String> argv =
|
||||
['--library-root=${uri.resolve('../../frog/leg/lib').path}'];
|
||||
argv.addAll(new Options().arguments);
|
||||
compile(argv);
|
||||
} catch (var exception, var trace) {
|
||||
try {
|
||||
print('Internal error: \$exception');
|
||||
} catch (var ignored) {
|
||||
print('Internal error: error while printing exception');
|
||||
}
|
||||
try {
|
||||
print(trace);
|
||||
} finally {
|
||||
exit(253); // 253 is recognized as a crash by our test scripts.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""";
|
||||
var f = new File(productionLauncherLocation);
|
||||
var stream = f.openSync(FileMode.WRITE);
|
||||
stream.writeStringSync(productionLaunch);
|
||||
stream.writeStringSync(launcherScript);
|
||||
stream.closeSync();
|
||||
f = new File(developerLauncherLocation);
|
||||
stream = f.openSync(FileMode.WRITE);
|
||||
stream.writeStringSync(developerLaunch);
|
||||
stream.writeStringSync(launcherScript);
|
||||
stream.closeSync();
|
||||
// TODO(ahe): Make scripts executable.
|
||||
// TODO(ahe): Also make .bat files for Windows.
|
||||
|
||||
void main() {
|
||||
new Helper().run();
|
||||
}
|
||||
""";
|
||||
}
|
||||
|
|
|
@ -2,12 +2,16 @@
|
|||
// 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.
|
||||
|
||||
#library('frog_leg');
|
||||
#library('dart2js');
|
||||
|
||||
#import('dart:io');
|
||||
#import('dart:utf');
|
||||
|
||||
#import('../../lib/uri/uri.dart');
|
||||
#import('../lang.dart', prefix: 'frog');
|
||||
#import('api.dart', prefix: 'api');
|
||||
#import('io/io.dart', prefix: 'io');
|
||||
#import('../../frog/leg/api.dart', prefix: 'api');
|
||||
#import('../../frog/leg/io/io.dart', prefix: 'io');
|
||||
#import('../../frog/leg/colors.dart');
|
||||
#import('source_file.dart');
|
||||
|
||||
String relativize(Uri base, Uri uri) {
|
||||
if (base.scheme == 'file' &&
|
||||
|
@ -39,53 +43,89 @@ String relativize(Uri base, Uri uri) {
|
|||
return uri.toString();
|
||||
}
|
||||
|
||||
bool compile(frog.World world) {
|
||||
final throwOnError = frog.options.throwOnErrors;
|
||||
final showWarnings = frog.options.showWarnings;
|
||||
// final compiler = new WorldCompiler(world, throwOnError);
|
||||
void compile(List<String> argv) {
|
||||
Uri cwd = new Uri(scheme: 'file', path: io.getCurrentDirectory());
|
||||
Uri uri = cwd.resolve(frog.options.dartScript);
|
||||
String frogLibDir = frog.options.libDir;
|
||||
if (!frogLibDir.endsWith("/")) frogLibDir = "$frogLibDir/";
|
||||
Uri frogLib = new Uri(scheme: 'file', path: frogLibDir);
|
||||
Uri libraryRoot = frogLib.resolve('../leg/lib/');
|
||||
Map<String, frog.SourceFile> sourceFiles = <frog.SourceFile>{};
|
||||
bool throwOnError = false;
|
||||
bool showWarnings = true;
|
||||
bool verbose = false;
|
||||
Uri libraryRoot = cwd;
|
||||
Uri out = cwd.resolve('out.js');
|
||||
|
||||
List<String> arguments = <String>[];
|
||||
for (String argument in argv) {
|
||||
if ('--throw-on-error' == argument) {
|
||||
throwOnError = true;
|
||||
} else if ('--suppress-warnings' == argument) {
|
||||
showWarnings = false;
|
||||
} else if ('--verbose' == argument) {
|
||||
verbose = true;
|
||||
} else if (argument.startsWith('--library-root=')) {
|
||||
String path = argument.substring(argument.indexOf('=') + 1);
|
||||
if (!path.endsWith("/")) path = "$path/";
|
||||
libraryRoot = cwd.resolve(path);
|
||||
} else if (argument.startsWith('--out=')) {
|
||||
String path = argument.substring(argument.indexOf('=') + 1);
|
||||
out = cwd.resolve(path);
|
||||
} else if (argument.startsWith('-')) {
|
||||
throw new AbortLeg('unknown option $argument');
|
||||
} else {
|
||||
arguments.add(argument);
|
||||
}
|
||||
}
|
||||
if (arguments.isEmpty()) {
|
||||
throw new AbortLeg('no files to compile');
|
||||
}
|
||||
if (arguments.length > 1) {
|
||||
var extra = arguments.getRange(1, arguments.length - 1);
|
||||
throw new AbortLeg('extra arguments: $extra');
|
||||
}
|
||||
|
||||
Map<String, SourceFile> sourceFiles = <SourceFile>{};
|
||||
int dartBytesRead = 0;
|
||||
|
||||
Future<String> provider(Uri uri) {
|
||||
if (uri.scheme != 'file') {
|
||||
throw new IllegalArgumentException(uri);
|
||||
}
|
||||
String source = world.files.readAll(uri.path);
|
||||
world.dartBytesRead += source.length;
|
||||
String source = readAll(uri.path);
|
||||
dartBytesRead += source.length;
|
||||
sourceFiles[uri.toString()] =
|
||||
new frog.SourceFile(relativize(cwd, uri), source);
|
||||
new SourceFile(relativize(cwd, uri), source);
|
||||
Completer<String> completer = new Completer<String>();
|
||||
completer.complete(source);
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
void info(var message) {
|
||||
if (verbose) print('${green("info:")} $message');
|
||||
}
|
||||
|
||||
void handler(Uri uri, int begin, int end, String message, bool fatal) {
|
||||
if (uri === null && !fatal) {
|
||||
world.info('[leg] $message');
|
||||
info(message);
|
||||
return;
|
||||
}
|
||||
if (uri === null) {
|
||||
assert(fatal);
|
||||
print(message);
|
||||
} else if (fatal || showWarnings) {
|
||||
frog.SourceFile file = sourceFiles[uri.toString()];
|
||||
SourceFile file = sourceFiles[uri.toString()];
|
||||
print(file.getLocationMessage(message, begin, end, true));
|
||||
}
|
||||
if (fatal && throwOnError) throw new AbortLeg(message);
|
||||
}
|
||||
|
||||
Uri uri = cwd.resolve(arguments[0]);
|
||||
info('compiling $uri');
|
||||
|
||||
// TODO(ahe): We expect the future to be complete and call value
|
||||
// directly. In effect, we don't support truly asynchronous API.
|
||||
String code = api.compile(uri, libraryRoot, provider, handler).value;
|
||||
if (code === null) return false;
|
||||
world.legCode = code;
|
||||
world.jsBytesWritten = code.length;
|
||||
return true;
|
||||
if (code === null) throw new AbortLeg('compilation failed');
|
||||
writeString(out, code);
|
||||
int jsBytesWritten = code.length;
|
||||
info('compiled $dartBytesRead bytes Dart -> $jsBytesWritten bytes JS '
|
||||
+ 'in ${relativize(cwd, out)}');
|
||||
}
|
||||
|
||||
class AbortLeg {
|
||||
|
@ -93,3 +133,21 @@ class AbortLeg {
|
|||
AbortLeg(this.message);
|
||||
toString() => 'Aborted due to --throw-on-error: $message';
|
||||
}
|
||||
|
||||
void writeString(Uri uri, String text) {
|
||||
if (uri.scheme != 'file') {
|
||||
throw new AbortLeg('unhandled scheme ${uri.scheme}');
|
||||
}
|
||||
var file = new File(uri.path).openSync(FileMode.WRITE);
|
||||
file.writeStringSync(text);
|
||||
file.closeSync();
|
||||
}
|
||||
|
||||
String readAll(String filename) {
|
||||
var file = (new File(filename)).openSync();
|
||||
var length = file.lengthSync();
|
||||
var buffer = new List<int>(length);
|
||||
var bytes = file.readListSync(buffer, 0, length);
|
||||
file.closeSync();
|
||||
return new String.fromCharCodes(new Utf8Decoder(buffer).decodeRest());
|
||||
}
|
||||
|
|
|
@ -2,43 +2,24 @@
|
|||
// 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.
|
||||
|
||||
// TODO(jimhug): This should be an interface to work better with tools.
|
||||
#library('source_file');
|
||||
|
||||
#import('../../frog/leg/colors.dart');
|
||||
|
||||
/**
|
||||
* Represents a file of source code.
|
||||
*/
|
||||
class SourceFile implements Comparable {
|
||||
// TODO(terry): This filename for in memory buffer. May need to rework if
|
||||
// filename is used for more than informational.
|
||||
static String IN_MEMORY_FILE = '<buffer>';
|
||||
class SourceFile {
|
||||
|
||||
/** The name of the file. */
|
||||
final String filename;
|
||||
|
||||
/** The text content of the file. */
|
||||
String _text;
|
||||
|
||||
/**
|
||||
* The order of the source file in a given library. This is used while we're
|
||||
* writing code for a library. A single source file can be used
|
||||
*/
|
||||
// TODO(jmesserly): I don't like having properties that are only valid
|
||||
// sometimes. An alternative would be to store it in a Map that's used by
|
||||
// WorldGenerator while it's emitting code. This seems simpler.
|
||||
int orderInLibrary;
|
||||
final String text;
|
||||
|
||||
List<int> _lineStarts;
|
||||
|
||||
SourceFile(this.filename, this._text);
|
||||
|
||||
String get text() => _text;
|
||||
|
||||
set text(String newText) {
|
||||
if (newText != _text) {
|
||||
_text = newText;
|
||||
_lineStarts = null;
|
||||
orderInLibrary = null;
|
||||
}
|
||||
}
|
||||
SourceFile(this.filename, this.text);
|
||||
|
||||
List<int> get lineStarts() {
|
||||
if (_lineStarts == null) {
|
||||
|
@ -73,7 +54,7 @@ class SourceFile implements Comparable {
|
|||
* in the file.
|
||||
*/
|
||||
String getLocationMessage(String message, int start,
|
||||
[int end, bool includeText=false]) {
|
||||
[int end, bool includeText=false, bool useColors = true]) {
|
||||
var line = getLine(start);
|
||||
var column = getColumn(line, start);
|
||||
|
||||
|
@ -90,11 +71,11 @@ class SourceFile implements Comparable {
|
|||
}
|
||||
|
||||
int toColumn = Math.min(column + (end-start), textLine.length);
|
||||
if (options.useColors) {
|
||||
if (useColors) {
|
||||
buf.add(textLine.substring(0, column));
|
||||
buf.add(_RED_COLOR);
|
||||
buf.add(RED_COLOR);
|
||||
buf.add(textLine.substring(column, toColumn));
|
||||
buf.add(_NO_COLOR);
|
||||
buf.add(NO_COLOR);
|
||||
buf.add(textLine.substring(toColumn));
|
||||
} else {
|
||||
buf.add(textLine);
|
||||
|
@ -105,82 +86,13 @@ class SourceFile implements Comparable {
|
|||
buf.add(' ');
|
||||
}
|
||||
|
||||
if (options.useColors) buf.add(_RED_COLOR);
|
||||
if (useColors) buf.add(RED_COLOR);
|
||||
for (; i < toColumn; i++) {
|
||||
buf.add('^');
|
||||
}
|
||||
if (options.useColors) buf.add(_NO_COLOR);
|
||||
if (useColors) buf.add(NO_COLOR);
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/** Compares two source files. */
|
||||
int compareTo(SourceFile other) {
|
||||
if (orderInLibrary != null && other.orderInLibrary != null) {
|
||||
return orderInLibrary - other.orderInLibrary;
|
||||
} else {
|
||||
return filename.compareTo(other.filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A range of characters in a [SourceFile]. Used to represent the source
|
||||
* positions of [Token]s and [Node]s for error reporting or other tooling
|
||||
* work.
|
||||
*/
|
||||
// TODO(jmesserly): Rename to Span - but first write cool refactoring tool
|
||||
class SourceSpan implements Comparable {
|
||||
/** The [SourceFile] that contains this span. */
|
||||
final SourceFile file;
|
||||
|
||||
/** The character position of the start of this span. */
|
||||
final int start;
|
||||
|
||||
/** The character position of the end of this span. */
|
||||
final int end;
|
||||
|
||||
SourceSpan(this.file, this.start, this.end);
|
||||
|
||||
/** Returns the source text corresponding to this [Span]. */
|
||||
String get text() {
|
||||
return file.text.substring(start, end);
|
||||
}
|
||||
|
||||
toMessageString(String message) {
|
||||
return file.getLocationMessage(message, start, end: end, includeText: true);
|
||||
}
|
||||
|
||||
int get line() {
|
||||
return file.getLine(start);
|
||||
}
|
||||
|
||||
int get column() {
|
||||
return file.getColumn(line, start);
|
||||
}
|
||||
|
||||
int get endLine() {
|
||||
return file.getLine(end);
|
||||
}
|
||||
|
||||
int get endColumn() {
|
||||
return file.getColumn(endLine, end);
|
||||
}
|
||||
|
||||
String get locationText() {
|
||||
var line = file.getLine(start);
|
||||
var column = file.getColumn(line, start);
|
||||
return '${file.filename}:${line + 1}:${column + 1}';
|
||||
}
|
||||
|
||||
/** Compares two source spans by file and position. Handles nulls. */
|
||||
int compareTo(SourceSpan other) {
|
||||
if (file == other.file) {
|
||||
int d = start - other.start;
|
||||
return d == 0 ? (end - other.end) : d;
|
||||
}
|
||||
return file.compareTo(other.file);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue