mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 10:49:00 +00:00
Remove dart2js_incremental.
Review-Url: https://codereview.chromium.org/2667793003 .
This commit is contained in:
parent
6595c05864
commit
35d4cccd05
10 changed files with 0 additions and 2999 deletions
|
@ -1,189 +0,0 @@
|
|||
// Copyright (c) 2013, 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.
|
||||
|
||||
part of dart2js_incremental;
|
||||
|
||||
/// Do not call this method directly. It will be made private.
|
||||
// TODO(ahe): Make this method private.
|
||||
Future<CompilerImpl> reuseCompiler(
|
||||
{CompilerDiagnostics diagnosticHandler,
|
||||
CompilerInput inputProvider,
|
||||
CompilerOutput outputProvider,
|
||||
List<String> options: const [],
|
||||
CompilerImpl cachedCompiler,
|
||||
Uri libraryRoot,
|
||||
Uri packageRoot,
|
||||
Uri packageConfig,
|
||||
bool packagesAreImmutable: false,
|
||||
Map<String, dynamic> environment,
|
||||
Future<bool> reuseLibrary(LibraryElement library)}) {
|
||||
UserTag oldTag = new UserTag('_reuseCompiler').makeCurrent();
|
||||
if (libraryRoot == null) {
|
||||
throw 'Missing libraryRoot';
|
||||
}
|
||||
if (inputProvider == null) {
|
||||
throw 'Missing inputProvider';
|
||||
}
|
||||
if (diagnosticHandler == null) {
|
||||
throw 'Missing diagnosticHandler';
|
||||
}
|
||||
if (outputProvider == null) {
|
||||
outputProvider = const NullCompilerOutput();
|
||||
}
|
||||
if (environment == null) {
|
||||
environment = {};
|
||||
}
|
||||
CompilerImpl compiler = cachedCompiler;
|
||||
JavaScriptBackend backend = compiler?.backend;
|
||||
if (compiler == null ||
|
||||
compiler.libraryRoot != libraryRoot ||
|
||||
!compiler.options.hasIncrementalSupport ||
|
||||
compiler.hasCrashed ||
|
||||
backend.mirrorsAnalysis.resolutionHandler.hasEnqueuedReflectiveElements ||
|
||||
compiler.deferredLoadTask.isProgramSplit) {
|
||||
if (compiler != null && compiler.options.hasIncrementalSupport) {
|
||||
print('***FLUSH***');
|
||||
if (compiler.hasCrashed) {
|
||||
print('Unable to reuse compiler due to crash.');
|
||||
} else if (backend.mirrorsAnalysis.resolutionHandler
|
||||
.hasEnqueuedReflectiveElements) {
|
||||
print('Unable to reuse compiler due to dart:mirrors.');
|
||||
} else if (compiler.deferredLoadTask.isProgramSplit) {
|
||||
print('Unable to reuse compiler due to deferred loading.');
|
||||
} else {
|
||||
print('Unable to reuse compiler.');
|
||||
}
|
||||
}
|
||||
oldTag.makeCurrent();
|
||||
compiler = new CompilerImpl(
|
||||
inputProvider,
|
||||
outputProvider,
|
||||
diagnosticHandler,
|
||||
new CompilerOptions.parse(
|
||||
libraryRoot: libraryRoot,
|
||||
packageRoot: packageRoot,
|
||||
packageConfig: packageConfig,
|
||||
options: options,
|
||||
environment: environment));
|
||||
backend = compiler.backend;
|
||||
|
||||
Uri core = Uri.parse("dart:core");
|
||||
|
||||
return compiler.setupSdk().then((_) {
|
||||
return compiler.libraryLoader.loadLibrary(core).then((_) {
|
||||
// Likewise, always be prepared for runtimeType support.
|
||||
// TODO(johnniwinther): Add global switch to force RTI.
|
||||
compiler.resolutionWorldBuilder.hasRuntimeTypeSupport = true;
|
||||
compiler.enqueuer.resolution.applyImpact(backend.registerRuntimeType());
|
||||
return compiler;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
compiler.tasks.forEach((t) => t.clearMeasurements());
|
||||
compiler
|
||||
..userOutputProvider = outputProvider
|
||||
..provider = inputProvider
|
||||
..handler = diagnosticHandler
|
||||
..enqueuer.resolution.queueIsClosed = false
|
||||
..enqueuer.resolution.hasEnqueuedReflectiveElements = false
|
||||
..enqueuer.resolution.hasEnqueuedReflectiveStaticFields = false
|
||||
..enqueuer.codegen.queueIsClosed = false
|
||||
..enqueuer.codegen.hasEnqueuedReflectiveElements = false
|
||||
..enqueuer.codegen.hasEnqueuedReflectiveStaticFields = false
|
||||
..compilationFailed = false;
|
||||
JavaScriptBackend backend = compiler.backend;
|
||||
full.Emitter emitter = backend.emitter.emitter;
|
||||
|
||||
// TODO(ahe): Seems this cache only serves to tell
|
||||
// [emitter.invalidateCaches] if it was invoked on a full compile (in
|
||||
// which case nothing should be invalidated), or if it is an incremental
|
||||
// compilation (in which case, holders/owners of newly compiled methods
|
||||
// must be invalidated).
|
||||
emitter.cachedElements.add(null);
|
||||
|
||||
compiler.enqueuer.codegen
|
||||
..newlyEnqueuedElements.clear()
|
||||
..newlySeenSelectors.clear();
|
||||
|
||||
emitter.nsmEmitter
|
||||
..trivialNsmHandlers.clear();
|
||||
|
||||
backend.emitter.typeTestRegistry
|
||||
..checkedClasses = null
|
||||
..checkedFunctionTypes = null
|
||||
..rtiNeededClasses.clear()
|
||||
..cachedClassesUsingTypeVariableTests = null;
|
||||
|
||||
emitter.interceptorEmitter
|
||||
..interceptorInvocationNames.clear();
|
||||
|
||||
backend.emitter.nativeEmitter
|
||||
..hasNativeClasses = false
|
||||
..nativeMethods.clear();
|
||||
|
||||
backend.emitter.readTypeVariables.clear();
|
||||
|
||||
emitter
|
||||
..outputBuffers.clear()
|
||||
..classesCollector = null
|
||||
..mangledFieldNames.clear()
|
||||
..mangledGlobalFieldNames.clear()
|
||||
..recordedMangledNames.clear()
|
||||
..clearCspPrecompiledNodes()
|
||||
..elementDescriptors.clear();
|
||||
|
||||
backend
|
||||
..preMirrorsMethodCount = 0;
|
||||
|
||||
if (reuseLibrary == null) {
|
||||
reuseLibrary = (LibraryElement library) {
|
||||
return new Future.value(
|
||||
library.isPlatformLibrary ||
|
||||
(packagesAreImmutable && library.isPackageLibrary));
|
||||
};
|
||||
}
|
||||
return compiler.libraryLoader.resetAsync(reuseLibrary).then((_) {
|
||||
oldTag.makeCurrent();
|
||||
return compiler;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper class to collect sources.
|
||||
class StringEventSink implements EventSink<String> {
|
||||
List<String> data = <String>[];
|
||||
|
||||
final Function onClose;
|
||||
|
||||
StringEventSink(this.onClose);
|
||||
|
||||
void add(String event) {
|
||||
if (data == null) throw 'StringEventSink is closed.';
|
||||
data.add(event);
|
||||
}
|
||||
|
||||
void addError(errorEvent, [StackTrace stackTrace]) {
|
||||
throw 'addError($errorEvent, $stackTrace)';
|
||||
}
|
||||
|
||||
void close() {
|
||||
if (data != null) {
|
||||
onClose(data.join());
|
||||
data = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Output provider which collect output in [output].
|
||||
class OutputProvider implements CompilerOutput {
|
||||
final Map<String, String> output = new Map<String, String>();
|
||||
|
||||
EventSink<String> createEventSink(String name, String extension) {
|
||||
return new StringEventSink((String data) {
|
||||
output['$name.$extension'] = data;
|
||||
});
|
||||
}
|
||||
|
||||
String operator[] (String key) => output[key];
|
||||
}
|
|
@ -1,211 +0,0 @@
|
|||
// Copyright (c) 2015, 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:io';
|
||||
|
||||
import 'dart:async' show
|
||||
EventSink,
|
||||
Future,
|
||||
Stream,
|
||||
StreamController,
|
||||
StreamSubscription;
|
||||
|
||||
import 'package:dart2js_incremental/dart2js_incremental.dart' show
|
||||
IncrementalCompilationFailed,
|
||||
IncrementalCompiler;
|
||||
|
||||
import 'package:compiler/compiler_new.dart' show
|
||||
CompilerOutput;
|
||||
|
||||
import 'package:compiler/src/old_to_new_api.dart' show
|
||||
LegacyCompilerDiagnostics,
|
||||
LegacyCompilerInput;
|
||||
|
||||
import 'package:compiler/src/source_file_provider.dart' show
|
||||
FormattingDiagnosticHandler;
|
||||
|
||||
import 'watcher.dart';
|
||||
|
||||
main(List<String> arguments) {
|
||||
int updateCount = 0;
|
||||
StreamSubscription<CompilerEvent> subscription =
|
||||
compile(Uri.base.resolve(arguments.first)).listen(null);
|
||||
subscription.onData((CompilerEvent event) {
|
||||
switch (event.kind) {
|
||||
case IncrementalKind.FULL:
|
||||
updateCount = 0;
|
||||
print('// Compiled JavaScript:');
|
||||
print(event['.js']);
|
||||
break;
|
||||
|
||||
case IncrementalKind.INCREMENTAL:
|
||||
Stopwatch sw = event.stopwatch..start();
|
||||
String updates = '${event.compiler.allUpdates()}';
|
||||
sw.stop();
|
||||
|
||||
print('// Patch after ${++updateCount} updates,');
|
||||
print('// computed in ${sw.elapsedMicroseconds/1000000} seconds:');
|
||||
print(updates);
|
||||
break;
|
||||
|
||||
case IncrementalKind.ERROR:
|
||||
updateCount = 0;
|
||||
print("Compilation failed");
|
||||
break;
|
||||
|
||||
default:
|
||||
throw "Unknown kind: ${event.kind}";
|
||||
}
|
||||
});
|
||||
subscription.onError((error, StackTrace trace) {
|
||||
if (error is IncrementalCompilationFailed) {
|
||||
print("Incremental compilation failed due to:\n${error.reason}");
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Stream<CompilerEvent> compile(Uri originalInput) {
|
||||
StreamController<CompilerEvent> controller =
|
||||
new StreamController<CompilerEvent>();
|
||||
compileToStream(originalInput, controller);
|
||||
return controller.stream;
|
||||
}
|
||||
|
||||
compileToStream(
|
||||
Uri originalInput,
|
||||
StreamController<CompilerEvent> controller) async {
|
||||
var watcher = new Watcher();
|
||||
|
||||
Uri libraryRoot = Uri.base.resolve('sdk/');
|
||||
Uri packageRoot = Uri.base.resolve('packages/');
|
||||
|
||||
FormattingDiagnosticHandler diagnosticHandler =
|
||||
new FormattingDiagnosticHandler();
|
||||
|
||||
OutputProvider outputProvider = new OutputProvider();
|
||||
|
||||
void resilientDiagnosticHandler(
|
||||
Uri uri, int begin, int end, String message, kind) {
|
||||
try {
|
||||
diagnosticHandler(uri, begin, end, message, kind);
|
||||
} catch (e) {
|
||||
String name = diagnosticHandler.provider.relativizeUri(uri);
|
||||
print('$name@$begin+${end - begin}: [$kind] $message}');
|
||||
}
|
||||
}
|
||||
|
||||
Future inputProvider(Uri uri) {
|
||||
if (uri.scheme == "file") {
|
||||
if (!'$uri'.startsWith('$libraryRoot')) {
|
||||
watcher.watchFile(uri);
|
||||
}
|
||||
}
|
||||
return diagnosticHandler.provider(uri);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
Stopwatch sw = new Stopwatch()..start();
|
||||
IncrementalCompiler compiler = new IncrementalCompiler(
|
||||
libraryRoot: libraryRoot,
|
||||
packageRoot: packageRoot,
|
||||
inputProvider: new LegacyCompilerInput(inputProvider),
|
||||
diagnosticHandler:
|
||||
new LegacyCompilerDiagnostics(resilientDiagnosticHandler),
|
||||
outputProvider: outputProvider);
|
||||
|
||||
bool success = await compiler.compile(originalInput);
|
||||
sw.stop();
|
||||
if (success) {
|
||||
controller.add(
|
||||
new CompilerEvent(
|
||||
IncrementalKind.FULL, compiler, outputProvider.output, sw));
|
||||
} else {
|
||||
controller.add(
|
||||
new CompilerEvent(
|
||||
IncrementalKind.ERROR, compiler, outputProvider.output, sw));
|
||||
}
|
||||
|
||||
while (await watcher.hasChanges()) {
|
||||
try {
|
||||
Map<Uri, Uri> changes = watcher.readChanges();
|
||||
|
||||
sw = new Stopwatch()..start();
|
||||
String updates = await compiler.compileUpdates(changes);
|
||||
sw.stop();
|
||||
|
||||
controller.add(
|
||||
new CompilerEvent(
|
||||
IncrementalKind.INCREMENTAL, compiler, outputProvider.output,
|
||||
sw, updates: updates));
|
||||
|
||||
} on IncrementalCompilationFailed catch (error, trace) {
|
||||
controller.addError(error, trace);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Output provider which collects output in [output].
|
||||
class OutputProvider implements CompilerOutput {
|
||||
final Map<String, String> output = new Map<String, String>();
|
||||
|
||||
EventSink<String> createEventSink(String name, String extension) {
|
||||
return new StringEventSink((String data) {
|
||||
output['$name.$extension'] = data;
|
||||
});
|
||||
}
|
||||
|
||||
String operator[](String key) => output[key];
|
||||
}
|
||||
|
||||
/// Helper class to collect sources.
|
||||
class StringEventSink implements EventSink<String> {
|
||||
List<String> data = <String>[];
|
||||
|
||||
final Function onClose;
|
||||
|
||||
StringEventSink(this.onClose);
|
||||
|
||||
void add(String event) {
|
||||
if (data == null) throw 'StringEventSink is closed.';
|
||||
data.add(event);
|
||||
}
|
||||
|
||||
void addError(errorEvent, [StackTrace stackTrace]) {
|
||||
throw 'addError($errorEvent, $stackTrace)';
|
||||
}
|
||||
|
||||
void close() {
|
||||
if (data != null) {
|
||||
onClose(data.join());
|
||||
data = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum IncrementalKind {
|
||||
FULL,
|
||||
INCREMENTAL,
|
||||
ERROR,
|
||||
}
|
||||
|
||||
class CompilerEvent {
|
||||
final IncrementalKind kind;
|
||||
|
||||
final IncrementalCompiler compiler;
|
||||
|
||||
final Map<String, String> _output;
|
||||
|
||||
final Stopwatch stopwatch;
|
||||
|
||||
final String updates;
|
||||
|
||||
CompilerEvent(
|
||||
this.kind, this.compiler, this._output, this.stopwatch, {this.updates});
|
||||
|
||||
String operator[](String key) => _output[key];
|
||||
}
|
|
@ -1,176 +0,0 @@
|
|||
// Copyright (c) 2014, 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.
|
||||
|
||||
library dart2js_incremental;
|
||||
|
||||
import 'dart:async' show
|
||||
EventSink,
|
||||
Future;
|
||||
|
||||
import 'dart:developer' show
|
||||
UserTag;
|
||||
|
||||
import 'package:compiler/src/apiimpl.dart' show
|
||||
CompilerImpl;
|
||||
|
||||
import 'package:compiler/compiler_new.dart' show
|
||||
CompilerDiagnostics,
|
||||
CompilerInput,
|
||||
CompilerOutput,
|
||||
Diagnostic;
|
||||
|
||||
import 'package:compiler/src/options.dart' show
|
||||
CompilerOptions;
|
||||
|
||||
import 'package:compiler/src/null_compiler_output.dart' show
|
||||
NullCompilerOutput;
|
||||
|
||||
import 'package:compiler/src/js_backend/js_backend.dart' show
|
||||
JavaScriptBackend;
|
||||
|
||||
import 'package:compiler/src/js_emitter/full_emitter/emitter.dart'
|
||||
as full show Emitter;
|
||||
|
||||
import 'package:compiler/src/elements/elements.dart' show
|
||||
LibraryElement;
|
||||
|
||||
import 'library_updater.dart' show
|
||||
IncrementalCompilerContext,
|
||||
LibraryUpdater,
|
||||
Logger;
|
||||
|
||||
import 'package:compiler/src/js/js.dart' as jsAst;
|
||||
|
||||
part 'caching_compiler.dart';
|
||||
|
||||
const List<String> INCREMENTAL_OPTIONS = const <String>[
|
||||
'--disable-type-inference',
|
||||
'--incremental-support',
|
||||
'--generate-code-with-compile-time-errors',
|
||||
'--no-source-maps', // TODO(ahe): Remove this.
|
||||
];
|
||||
|
||||
class IncrementalCompiler {
|
||||
final Uri libraryRoot;
|
||||
final Uri packageRoot;
|
||||
final Uri packageConfig;
|
||||
final CompilerInput inputProvider;
|
||||
final CompilerDiagnostics diagnosticHandler;
|
||||
final List<String> options;
|
||||
final CompilerOutput outputProvider;
|
||||
final Map<String, dynamic> environment;
|
||||
final List<String> _updates = <String>[];
|
||||
final IncrementalCompilerContext _context = new IncrementalCompilerContext();
|
||||
|
||||
CompilerImpl _compiler;
|
||||
|
||||
IncrementalCompiler({
|
||||
this.libraryRoot,
|
||||
this.packageRoot,
|
||||
this.packageConfig,
|
||||
this.inputProvider,
|
||||
this.diagnosticHandler,
|
||||
this.options,
|
||||
this.outputProvider,
|
||||
this.environment}) {
|
||||
if (libraryRoot == null) {
|
||||
throw new ArgumentError('libraryRoot is null.');
|
||||
}
|
||||
if (inputProvider == null) {
|
||||
throw new ArgumentError('inputProvider is null.');
|
||||
}
|
||||
if (outputProvider == null) {
|
||||
throw new ArgumentError('outputProvider is null.');
|
||||
}
|
||||
if (diagnosticHandler == null) {
|
||||
throw new ArgumentError('diagnosticHandler is null.');
|
||||
}
|
||||
_context.incrementalCompiler = this;
|
||||
}
|
||||
|
||||
LibraryElement get mainApp => _compiler.mainApp;
|
||||
|
||||
CompilerImpl get compiler => _compiler;
|
||||
|
||||
Future<bool> compile(Uri script) {
|
||||
return _reuseCompiler(null).then((CompilerImpl compiler) {
|
||||
_compiler = compiler;
|
||||
return compiler.run(script);
|
||||
});
|
||||
}
|
||||
|
||||
Future<CompilerImpl> _reuseCompiler(
|
||||
Future<bool> reuseLibrary(LibraryElement library)) {
|
||||
List<String> options = this.options == null
|
||||
? <String> [] : new List<String>.from(this.options);
|
||||
options.addAll(INCREMENTAL_OPTIONS);
|
||||
return reuseCompiler(
|
||||
cachedCompiler: _compiler,
|
||||
libraryRoot: libraryRoot,
|
||||
packageRoot: packageRoot,
|
||||
packageConfig: packageConfig,
|
||||
inputProvider: inputProvider,
|
||||
diagnosticHandler: diagnosticHandler,
|
||||
options: options,
|
||||
outputProvider: outputProvider,
|
||||
environment: environment,
|
||||
reuseLibrary: reuseLibrary);
|
||||
}
|
||||
|
||||
Future<String> compileUpdates(
|
||||
Map<Uri, Uri> updatedFiles,
|
||||
{Logger logTime,
|
||||
Logger logVerbose}) {
|
||||
if (logTime == null) {
|
||||
logTime = (_) {};
|
||||
}
|
||||
if (logVerbose == null) {
|
||||
logVerbose = (_) {};
|
||||
}
|
||||
Future mappingInputProvider(Uri uri) {
|
||||
Uri updatedFile = updatedFiles[uri];
|
||||
return inputProvider.readFromUri(updatedFile == null ? uri : updatedFile);
|
||||
}
|
||||
LibraryUpdater updater = new LibraryUpdater(
|
||||
_compiler,
|
||||
mappingInputProvider,
|
||||
logTime,
|
||||
logVerbose,
|
||||
_context);
|
||||
_context.registerUriWithUpdates(updatedFiles.keys);
|
||||
Future<CompilerImpl> future = _reuseCompiler(updater.reuseLibrary);
|
||||
return future.then((CompilerImpl compiler) {
|
||||
_compiler = compiler;
|
||||
if (compiler.compilationFailed) {
|
||||
return null;
|
||||
} else {
|
||||
String update = updater.computeUpdateJs();
|
||||
_updates.add(update);
|
||||
return update;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
String allUpdates() {
|
||||
jsAst.Node updates = jsAst.js.escapedString(_updates.join(""));
|
||||
|
||||
JavaScriptBackend backend = _compiler.backend;
|
||||
|
||||
jsAst.FunctionDeclaration mainRunner = jsAst.js.statement(r"""
|
||||
function dartMainRunner(main, args) {
|
||||
#helper.patch(#updates + "\n//# sourceURL=initial_patch.js\n");
|
||||
return main(args);
|
||||
}""", {'updates': updates, 'helper': backend.namer.accessIncrementalHelper});
|
||||
|
||||
return jsAst.prettyPrint(mainRunner, _compiler).getText();
|
||||
}
|
||||
}
|
||||
|
||||
class IncrementalCompilationFailed {
|
||||
final String reason;
|
||||
|
||||
const IncrementalCompilationFailed(this.reason);
|
||||
|
||||
String toString() => "Can't incrementally compile program.\n\n$reason";
|
||||
}
|
|
@ -1,122 +0,0 @@
|
|||
// Copyright (c) 2014, 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.
|
||||
|
||||
library trydart.poi.diff;
|
||||
|
||||
import 'package:compiler/src/elements/elements.dart' show
|
||||
AbstractFieldElement,
|
||||
ClassElement,
|
||||
CompilationUnitElement,
|
||||
Element,
|
||||
ElementCategory,
|
||||
FunctionElement,
|
||||
LibraryElement,
|
||||
ScopeContainerElement;
|
||||
|
||||
import 'package:compiler/src/elements/modelx.dart' as modelx;
|
||||
|
||||
import 'package:compiler/src/elements/modelx.dart' show
|
||||
DeclarationSite;
|
||||
|
||||
import 'package:compiler/src/parser/partial_elements.dart' show
|
||||
PartialClassElement,
|
||||
PartialElement;
|
||||
|
||||
import 'package:compiler/src/tokens/token.dart' show
|
||||
ErrorToken,
|
||||
Token;
|
||||
|
||||
import 'package:compiler/src/tokens/token_constants.dart' show
|
||||
EOF_TOKEN,
|
||||
IDENTIFIER_TOKEN,
|
||||
KEYWORD_TOKEN;
|
||||
|
||||
class Difference {
|
||||
final DeclarationSite before;
|
||||
final DeclarationSite after;
|
||||
|
||||
/// Records the position of first difference between [before] and [after]. If
|
||||
/// either [before] or [after] are null, [token] is null.
|
||||
Token token;
|
||||
|
||||
Difference(this.before, this.after) {
|
||||
if (before == after) {
|
||||
throw '[before] and [after] are the same.';
|
||||
}
|
||||
}
|
||||
|
||||
String toString() {
|
||||
if (before == null) return 'Added($after)';
|
||||
if (after == null) return 'Removed($before)';
|
||||
return 'Modified($after -> $before)';
|
||||
}
|
||||
}
|
||||
|
||||
List<Difference> computeDifference(
|
||||
ScopeContainerElement before,
|
||||
ScopeContainerElement after) {
|
||||
Map<String, DeclarationSite> beforeMap = <String, DeclarationSite>{};
|
||||
before.forEachLocalMember((modelx.ElementX element) {
|
||||
DeclarationSite site = element.declarationSite;
|
||||
assert(site != null || element.isSynthesized);
|
||||
if (!element.isSynthesized) {
|
||||
beforeMap[element.name] = site;
|
||||
}
|
||||
});
|
||||
List<Difference> modifications = <Difference>[];
|
||||
List<Difference> potentiallyChanged = <Difference>[];
|
||||
after.forEachLocalMember((modelx.ElementX element) {
|
||||
DeclarationSite existing = beforeMap.remove(element.name);
|
||||
if (existing == null) {
|
||||
modifications.add(new Difference(null, element.declarationSite));
|
||||
} else {
|
||||
potentiallyChanged.add(new Difference(existing, element.declarationSite));
|
||||
}
|
||||
});
|
||||
|
||||
modifications.addAll(
|
||||
beforeMap.values.map(
|
||||
(DeclarationSite site) => new Difference(site, null)));
|
||||
|
||||
modifications.addAll(
|
||||
potentiallyChanged.where(areDifferentElements));
|
||||
|
||||
return modifications;
|
||||
}
|
||||
|
||||
bool areDifferentElements(Difference diff) {
|
||||
DeclarationSite before = diff.before;
|
||||
DeclarationSite after = diff.after;
|
||||
if (before is PartialElement && after is PartialElement) {
|
||||
Token beforeToken = before.beginToken;
|
||||
Token afterToken = after.beginToken;
|
||||
Token stop = before.endToken;
|
||||
int beforeKind = beforeToken.kind;
|
||||
int afterKind = afterToken.kind;
|
||||
while (beforeKind != EOF_TOKEN && afterKind != EOF_TOKEN) {
|
||||
|
||||
if (beforeKind != afterKind) {
|
||||
diff.token = afterToken;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (beforeToken is! ErrorToken && afterToken is! ErrorToken) {
|
||||
if (beforeToken.value != afterToken.value) {
|
||||
diff.token = afterToken;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (beforeToken == stop) return false;
|
||||
|
||||
beforeToken = beforeToken.next;
|
||||
afterToken = afterToken.next;
|
||||
beforeKind = beforeToken.kind;
|
||||
afterKind = afterToken.kind;
|
||||
}
|
||||
return beforeKind != afterKind;
|
||||
}
|
||||
print("$before isn't a PartialElement");
|
||||
return true;
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,301 +0,0 @@
|
|||
// Copyright (c) 2012, 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.
|
||||
|
||||
library dart2js_incremental.server;
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'dart:async' show
|
||||
Completer,
|
||||
Future,
|
||||
Stream,
|
||||
StreamController,
|
||||
StreamSubscription;
|
||||
|
||||
import 'dart:convert' show
|
||||
HtmlEscape,
|
||||
JSON,
|
||||
UTF8;
|
||||
|
||||
import 'src/options.dart';
|
||||
|
||||
import 'compiler.dart' show
|
||||
CompilerEvent,
|
||||
IncrementalKind,
|
||||
compile;
|
||||
|
||||
class Conversation {
|
||||
HttpRequest request;
|
||||
HttpResponse response;
|
||||
|
||||
static const String PACKAGES_PATH = '/packages';
|
||||
|
||||
static const String CONTENT_TYPE = HttpHeaders.CONTENT_TYPE;
|
||||
|
||||
static Uri documentRoot = Uri.base;
|
||||
|
||||
static Uri packageRoot = Uri.base.resolve('packages/');
|
||||
|
||||
static Map<Uri, Future<String>> generatedFiles =
|
||||
new Map<Uri, Future<String>>();
|
||||
|
||||
static Map<Uri, StreamController<String>> updateControllers =
|
||||
new Map<Uri, StreamController<String>>();
|
||||
|
||||
Conversation(this.request, this.response);
|
||||
|
||||
onClosed(_) {
|
||||
if (response.statusCode == HttpStatus.OK) return;
|
||||
print('Request for ${request.uri} ${response.statusCode}');
|
||||
}
|
||||
|
||||
Future notFound(Uri uri) {
|
||||
response
|
||||
..headers.set(CONTENT_TYPE, 'text/html')
|
||||
..statusCode = HttpStatus.NOT_FOUND
|
||||
..write(htmlInfo("Not Found", "The file '$uri' could not be found."));
|
||||
return response.close();
|
||||
}
|
||||
|
||||
Future badRequest(String problem) {
|
||||
response
|
||||
..headers.set(CONTENT_TYPE, 'text/html')
|
||||
..statusCode = HttpStatus.BAD_REQUEST
|
||||
..write(
|
||||
htmlInfo("Bad request", "Bad request '${request.uri}': $problem"));
|
||||
return response.close();
|
||||
}
|
||||
|
||||
Future handleSocket() async {
|
||||
StreamController<String> controller = updateControllers[request.uri];
|
||||
if (controller != null) {
|
||||
WebSocket socket = await WebSocketTransformer.upgrade(request);
|
||||
print(
|
||||
"Patches to ${request.uri} will be pushed to "
|
||||
"${request.connectionInfo.remoteAddress.host}:"
|
||||
"${request.connectionInfo.remotePort}.");
|
||||
controller.stream.pipe(socket);
|
||||
} else {
|
||||
response.done
|
||||
.then(onClosed)
|
||||
.catchError(onError);
|
||||
return await notFound(request.uri);
|
||||
}
|
||||
}
|
||||
|
||||
Future handle() {
|
||||
response.done
|
||||
.then(onClosed)
|
||||
.catchError(onError);
|
||||
|
||||
Uri uri = request.uri;
|
||||
if (uri.path.endsWith('/')) {
|
||||
uri = uri.resolve('index.html');
|
||||
}
|
||||
if (uri.path.contains('..') || uri.path.contains('%')) {
|
||||
return notFound(uri);
|
||||
}
|
||||
String path = uri.path;
|
||||
Uri root = documentRoot;
|
||||
if (path.startsWith('${PACKAGES_PATH}/')) {
|
||||
root = packageRoot;
|
||||
path = path.substring(PACKAGES_PATH.length);
|
||||
}
|
||||
|
||||
Uri resolvedRequest = root.resolve('.$path');
|
||||
switch (request.method) {
|
||||
case 'GET':
|
||||
return handleGet(resolvedRequest);
|
||||
default:
|
||||
String method = const HtmlEscape().convert(request.method);
|
||||
return badRequest("Unsupported method: '$method'");
|
||||
}
|
||||
}
|
||||
|
||||
Future handleGet(Uri uri) async {
|
||||
String path = uri.path;
|
||||
var f = new File.fromUri(uri);
|
||||
if (!await f.exists()) {
|
||||
return await handleNonExistingFile(uri);
|
||||
} else {
|
||||
setContentType(path);
|
||||
}
|
||||
return await f.openRead().pipe(response);
|
||||
}
|
||||
|
||||
void setContentType(String path) {
|
||||
if (path.endsWith('.html')) {
|
||||
response.headers.set(CONTENT_TYPE, 'text/html');
|
||||
} else if (path.endsWith('.dart')) {
|
||||
response.headers.set(CONTENT_TYPE, 'application/dart');
|
||||
} else if (path.endsWith('.js')) {
|
||||
response.headers.set(CONTENT_TYPE, 'application/javascript');
|
||||
} else if (path.endsWith('.ico')) {
|
||||
response.headers.set(CONTENT_TYPE, 'image/x-icon');
|
||||
} else if (path.endsWith('.appcache')) {
|
||||
response.headers.set(CONTENT_TYPE, 'text/cache-manifest');
|
||||
} else if (path.endsWith('.css')) {
|
||||
response.headers.set(CONTENT_TYPE, 'text/css');
|
||||
} else if (path.endsWith('.png')) {
|
||||
response.headers.set(CONTENT_TYPE, 'image/png');
|
||||
}
|
||||
}
|
||||
|
||||
Future handleNonExistingFile(Uri uri) async {
|
||||
String path = uri.path;
|
||||
String generated = await generatedFiles[request.uri];
|
||||
if (generated != null) {
|
||||
print("Serving ${request.uri} from memory.");
|
||||
setContentType(path);
|
||||
response.write(generated);
|
||||
return await response.close();
|
||||
}
|
||||
if (path.endsWith('.dart.js')) {
|
||||
Uri dartScript = uri.resolve(path.substring(0, path.length - 3));
|
||||
if (await new File.fromUri(dartScript).exists()) {
|
||||
return await compileToJavaScript(dartScript);
|
||||
}
|
||||
}
|
||||
return await notFound(request.uri);
|
||||
}
|
||||
|
||||
compileToJavaScript(Uri dartScript) {
|
||||
Uri outputUri = request.uri;
|
||||
Completer<String> completer = new Completer<String>();
|
||||
generatedFiles[outputUri] = completer.future;
|
||||
StreamController controller = updateControllers[outputUri];
|
||||
if (controller != null) {
|
||||
controller.close();
|
||||
}
|
||||
updateControllers[outputUri] = new StreamController<String>.broadcast();
|
||||
print("Compiling $dartScript to $outputUri.");
|
||||
StreamSubscription<CompilerEvent> subscription;
|
||||
subscription = compile(dartScript).listen((CompilerEvent event) {
|
||||
subscription.onData(
|
||||
(CompilerEvent event) => onCompilerEvent(completer, event));
|
||||
if (event.kind != IncrementalKind.FULL) {
|
||||
notFound(request.uri);
|
||||
// TODO(ahe): Do something about this situation.
|
||||
} else {
|
||||
print("Done compiling $dartScript to $outputUri.");
|
||||
completer.complete(event['.js']);
|
||||
setContentType(outputUri.path);
|
||||
response.write(event['.js']);
|
||||
response.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onCompilerEvent(Completer completer, CompilerEvent event) {
|
||||
Uri outputUri = request.uri;
|
||||
print("Got ${event.kind} for $outputUri");
|
||||
|
||||
switch (event.kind) {
|
||||
case IncrementalKind.FULL:
|
||||
generatedFiles[outputUri] = new Future.value(event['.js']);
|
||||
break;
|
||||
|
||||
case IncrementalKind.INCREMENTAL:
|
||||
generatedFiles[outputUri] = completer.future.then(
|
||||
(String full) => '$full\n\n${event.compiler.allUpdates()}');
|
||||
pushUpdates(event.updates);
|
||||
break;
|
||||
|
||||
case IncrementalKind.ERROR:
|
||||
generatedFiles.removeKey(outputUri);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void pushUpdates(String updates) {
|
||||
if (updates == null) return;
|
||||
StreamController<String> controller = updateControllers[request.uri];
|
||||
if (controller == null) return;
|
||||
print("Adding updates to controller");
|
||||
controller.add(updates);
|
||||
}
|
||||
|
||||
Future dispatch() async {
|
||||
try {
|
||||
return await WebSocketTransformer.isUpgradeRequest(request)
|
||||
? handleSocket()
|
||||
: handle();
|
||||
} catch (e, s) {
|
||||
onError(e, s);
|
||||
}
|
||||
}
|
||||
|
||||
static Future onRequest(HttpRequest request) async {
|
||||
HttpResponse response = request.response;
|
||||
try {
|
||||
return await new Conversation(request, response).dispatch();
|
||||
} catch (e, s) {
|
||||
try {
|
||||
onStaticError(e, s);
|
||||
return await response.close();
|
||||
} catch (e, s) {
|
||||
onStaticError(e, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future onError(error, [stack]) async {
|
||||
try {
|
||||
onStaticError(error, stack);
|
||||
return await response.close();
|
||||
} catch (e, s) {
|
||||
onStaticError(e, s);
|
||||
}
|
||||
}
|
||||
|
||||
static void onStaticError(error, [stack]) {
|
||||
if (error is HttpException) {
|
||||
print('Error: ${error.message}');
|
||||
} else {
|
||||
print('Error: ${error}');
|
||||
}
|
||||
if (stack != null) {
|
||||
print(stack);
|
||||
}
|
||||
}
|
||||
|
||||
String htmlInfo(String title, String text) {
|
||||
// No script injection, please.
|
||||
title = const HtmlEscape().convert(title);
|
||||
text = const HtmlEscape().convert(text);
|
||||
return """
|
||||
<!DOCTYPE html>
|
||||
<html lang='en'>
|
||||
<head>
|
||||
<title>$title</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>$title</h1>
|
||||
<p style='white-space:pre'>$text</p>
|
||||
</body>
|
||||
</html>
|
||||
""";
|
||||
}
|
||||
}
|
||||
|
||||
main(List<String> arguments) async {
|
||||
Options options = Options.parse(arguments);
|
||||
if (options == null) {
|
||||
exit(1);
|
||||
}
|
||||
if (!options.arguments.isEmpty) {
|
||||
Conversation.documentRoot = Uri.base.resolve(options.arguments.single);
|
||||
}
|
||||
Conversation.packageRoot = options.packageRoot;
|
||||
String host = options.host;
|
||||
int port = options.port;
|
||||
try {
|
||||
HttpServer server = await HttpServer.bind(host, port);
|
||||
print('HTTP server started on http://$host:${server.port}/');
|
||||
server.listen(Conversation.onRequest, onError: Conversation.onStaticError);
|
||||
} catch (e) {
|
||||
print("HttpServer.bind error: $e");
|
||||
exit(1);
|
||||
};
|
||||
}
|
|
@ -1,134 +0,0 @@
|
|||
// Copyright (c) 2015, 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.
|
||||
|
||||
library dart2js_incremental.options;
|
||||
|
||||
class Options {
|
||||
final List<String> arguments;
|
||||
final Uri packageRoot;
|
||||
final String host;
|
||||
final int port;
|
||||
|
||||
Options({this.arguments, this.packageRoot, this.host, this.port});
|
||||
|
||||
static String extractArgument(String option, String short, {String long}) {
|
||||
if (option.startsWith(short)) {
|
||||
return option.substring(short.length);
|
||||
}
|
||||
if (long != null && option.startsWith(long)) {
|
||||
return option.substring(long.length);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static Options parse(List<String> commandLine) {
|
||||
Iterator<String> iterator = commandLine.iterator;
|
||||
List<String> arguments = <String>[];
|
||||
Uri packageRoot;
|
||||
String host = "127.0.0.1";
|
||||
int port = 0;
|
||||
bool showHelp = false;
|
||||
List<String> unknownOptions = <String>[];
|
||||
|
||||
LOOP: while (iterator.moveNext()) {
|
||||
String option = iterator.current;
|
||||
switch (option) {
|
||||
case "-p":
|
||||
iterator.moveNext();
|
||||
packageRoot = Uri.base.resolve(iterator.current);
|
||||
continue;
|
||||
|
||||
case "-h":
|
||||
iterator.moveNext();
|
||||
host = iterator.current;
|
||||
continue;
|
||||
|
||||
case "-n":
|
||||
iterator.moveNext();
|
||||
port = int.parse(iterator.current);
|
||||
continue;
|
||||
|
||||
case "--help":
|
||||
showHelp = true;
|
||||
continue;
|
||||
|
||||
case "--":
|
||||
break LOOP;
|
||||
|
||||
default:
|
||||
String argument;
|
||||
|
||||
argument = extractArgument(option, "-p", long: "--package-root");
|
||||
if (argument != null) {
|
||||
packageRoot = Uri.base.resolve(argument);
|
||||
continue;
|
||||
}
|
||||
|
||||
argument = extractArgument(option, "-h", long: "--host");
|
||||
if (argument != null) {
|
||||
host = argument;
|
||||
continue;
|
||||
}
|
||||
|
||||
argument = extractArgument(option, "-n", long: "--port");
|
||||
if (argument != null) {
|
||||
port = int.parse(option);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (option.startsWith("-")) {
|
||||
unknownOptions.add(option);
|
||||
continue;
|
||||
}
|
||||
|
||||
arguments.add(option);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (showHelp) {
|
||||
print(USAGE);
|
||||
}
|
||||
if (!unknownOptions.isEmpty) {
|
||||
print(USAGE);
|
||||
print("Unknown options: '${unknownOptions.join('\', \'')}'");
|
||||
return null;
|
||||
}
|
||||
while (iterator.moveNext()) {
|
||||
arguments.add(iterator.current);
|
||||
}
|
||||
if (arguments.length > 1) {
|
||||
print(USAGE);
|
||||
print("Extra arguments: '${arguments.skip(1).join('\', \'')}'");
|
||||
return null;
|
||||
}
|
||||
if (packageRoot == null) {
|
||||
packageRoot = Uri.base.resolve('packages/');
|
||||
}
|
||||
return new Options(
|
||||
arguments: arguments, packageRoot: packageRoot, host: host, port: port);
|
||||
}
|
||||
}
|
||||
|
||||
const String USAGE = """
|
||||
Usage: server.dart [options] [--] documentroot
|
||||
|
||||
Development web server which serves files relative to [documentroot]. If a file
|
||||
is missing, and the requested file name ends with '.dart.js', the server will
|
||||
look for a file with the same name save '.js', compile it to JavaScript, and
|
||||
serve that file instead.
|
||||
|
||||
Supported options:
|
||||
|
||||
-p<path>, --package-root=<path>
|
||||
Where to find packages, that is, "package:..." imports.
|
||||
|
||||
-h<name>, --host=<name>
|
||||
Host name to bind the web server to (default 127.0.0.1).
|
||||
|
||||
-n<port>, --port=<port>
|
||||
Port number to bind the web server to.
|
||||
|
||||
--help
|
||||
Show this message.
|
||||
""";
|
|
@ -1,62 +0,0 @@
|
|||
// Copyright (c) 2015, 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.
|
||||
|
||||
library dart2js_incremental.watcher;
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
class Watcher {
|
||||
final Set<String> _watchedDirectories = new Set<String>();
|
||||
|
||||
final Map<String, Set<Uri>> _watchedFiles = new Map<String, Set<Uri>>();
|
||||
|
||||
final Set<Uri> _changes = new Set<Uri>();
|
||||
|
||||
bool _hasEarlyChanges = false;
|
||||
|
||||
Completer<bool> _changesCompleter;
|
||||
|
||||
Future<bool> hasChanges() {
|
||||
if (_changesCompleter == null && _hasEarlyChanges) {
|
||||
return new Future.value(true);
|
||||
}
|
||||
_changesCompleter = new Completer<bool>();
|
||||
return _changesCompleter.future;
|
||||
}
|
||||
|
||||
void _onFileSystemEvent(FileSystemEvent event) {
|
||||
Set<Uri> uris = _watchedFiles[event.path];
|
||||
if (uris == null) return;
|
||||
_changes.addAll(uris);
|
||||
if (_changesCompleter == null) {
|
||||
_hasEarlyChanges = true;
|
||||
} else if (!_changesCompleter.isCompleted) {
|
||||
_changesCompleter.complete(true);
|
||||
}
|
||||
}
|
||||
|
||||
Map<Uri, Uri> readChanges() {
|
||||
if (_changes.isEmpty) {
|
||||
throw new StateError("No changes");
|
||||
}
|
||||
Map<Uri, Uri> result = new Map<Uri, Uri>();
|
||||
for (Uri uri in _changes) {
|
||||
result[uri] = uri;
|
||||
}
|
||||
_changes.clear();
|
||||
return result;
|
||||
}
|
||||
|
||||
void watchFile(Uri uri) {
|
||||
String realpath = new File.fromUri(uri).resolveSymbolicLinksSync();
|
||||
_watchedFiles.putIfAbsent(realpath, () => new Set<Uri>()).add(uri);
|
||||
Directory directory = new File(realpath).parent;
|
||||
if (_watchedDirectories.add(directory.path)) {
|
||||
print("Watching ${directory.path}");
|
||||
directory.watch().listen(_onFileSystemEvent);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,179 +0,0 @@
|
|||
// Copyright (c) 2014, 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.
|
||||
|
||||
// Helper file that can be used to manually test the stability of incremental
|
||||
// compilation. Currently this test is not run automatically.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'dart:developer' show UserTag;
|
||||
|
||||
import 'package:dart2js_incremental/dart2js_incremental.dart'
|
||||
show IncrementalCompiler;
|
||||
import 'package:compiler/src/source_file_provider.dart'
|
||||
show FormattingDiagnosticHandler;
|
||||
|
||||
import '../memory_source_file_helper.dart' show CompilerImpl;
|
||||
|
||||
import '../memory_compiler.dart' show compilerFor;
|
||||
|
||||
const bool verbose = false;
|
||||
|
||||
main(List<String> arguments) {
|
||||
Stopwatch sw = new Stopwatch()..start();
|
||||
Map<String, String> sources = <String, String>{};
|
||||
for (String argument in arguments) {
|
||||
Uri uri = new Uri(scheme: 'memory', path: argument);
|
||||
String source =
|
||||
new File.fromUri(Uri.base.resolve(argument)).readAsStringSync();
|
||||
sources['${uri.path}'] = source;
|
||||
}
|
||||
sw.stop();
|
||||
print(sw.elapsedMilliseconds);
|
||||
compileTests(sources);
|
||||
}
|
||||
|
||||
void compileTests(Map<String, String> sources) {
|
||||
int testCount = 0;
|
||||
int skipCount = 0;
|
||||
Set<String> crashes = new Set<String>();
|
||||
CompilerImpl memoryCompiler = compilerFor(memorySourceFiles: sources);
|
||||
FormattingDiagnosticHandler handler = memoryCompiler.handler;
|
||||
handler.verbose = verbose;
|
||||
var options = ['--analyze-main'];
|
||||
if (true || verbose) options.add('--verbose');
|
||||
IncrementalCompiler compiler = new IncrementalCompiler(
|
||||
libraryRoot: memoryCompiler.libraryRoot,
|
||||
inputProvider: memoryCompiler.provider,
|
||||
outputProvider: memoryCompiler.userOutputProvider,
|
||||
diagnosticHandler: memoryCompiler.handler,
|
||||
packageRoot: memoryCompiler.options.packageRoot,
|
||||
options: options);
|
||||
Future.forEach(sources.keys, (String path) {
|
||||
UserTag.defaultTag.makeCurrent();
|
||||
if (!path.endsWith('_test.dart')) return new Future.value(null);
|
||||
testCount++;
|
||||
for (String brokenTest in brokenTests) {
|
||||
if (path.endsWith(brokenTest)) {
|
||||
print('Skipped broken test $path');
|
||||
skipCount++;
|
||||
return new Future.value(null);
|
||||
}
|
||||
}
|
||||
Stopwatch sw = new Stopwatch()..start();
|
||||
return compiler.compile(Uri.parse('memory:$path')).then((bool success) {
|
||||
UserTag.defaultTag.makeCurrent();
|
||||
sw.stop();
|
||||
print('Compiled $path in ${sw.elapsedMilliseconds}');
|
||||
sw
|
||||
..reset()
|
||||
..start();
|
||||
}).catchError((error, trace) {
|
||||
sw.stop();
|
||||
print('$error\n$trace');
|
||||
print('Crash when compiling $path after ${sw.elapsedMilliseconds}');
|
||||
sw
|
||||
..reset()
|
||||
..start();
|
||||
crashes.add(path);
|
||||
});
|
||||
}).then((_) {
|
||||
percent(i) => '${(i/testCount*100).toStringAsFixed(3)}%';
|
||||
print('''
|
||||
|
||||
Total: $testCount tests
|
||||
* ${crashes.length} tests (${percent(crashes.length)}) crashed the compiler
|
||||
* $skipCount tests (${percent(skipCount)}) were skipped
|
||||
''');
|
||||
for (String crash in crashes) {
|
||||
print('Crashed: $crash');
|
||||
}
|
||||
if (!crashes.isEmpty) {
|
||||
throw 'Test had crashes';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Set<String> brokenTests = new Set<String>.from([
|
||||
// TODO(ahe): Fix the outputProvider to not throw an error.
|
||||
"/dart2js_extra/deferred/deferred_class_library.dart",
|
||||
"/dart2js_extra/deferred/deferred_class_library2.dart",
|
||||
"/dart2js_extra/deferred/deferred_class_test.dart",
|
||||
"/dart2js_extra/deferred/deferred_constant2_test.dart",
|
||||
"/dart2js_extra/deferred/deferred_constant3_test.dart",
|
||||
"/dart2js_extra/deferred/deferred_constant4_test.dart",
|
||||
"/dart2js_extra/deferred/deferred_constant_test.dart",
|
||||
"/dart2js_extra/deferred/deferred_function_library.dart",
|
||||
"/dart2js_extra/deferred/deferred_function_test.dart",
|
||||
"/dart2js_extra/deferred/deferred_overlapping_lib1.dart",
|
||||
"/dart2js_extra/deferred/deferred_overlapping_lib2.dart",
|
||||
"/dart2js_extra/deferred/deferred_overlapping_lib3.dart",
|
||||
"/dart2js_extra/deferred/deferred_overlapping_test.dart",
|
||||
"/dart2js_extra/deferred/deferred_unused_classes_test.dart",
|
||||
"/language/deferred_closurize_load_library_lib.dart",
|
||||
"/language/deferred_closurize_load_library_test.dart",
|
||||
"/language/deferred_constraints_constants_lib.dart",
|
||||
"/language/deferred_constraints_constants_old_syntax_lib.dart",
|
||||
"/language/deferred_constraints_constants_old_syntax_test.dart",
|
||||
"/language/deferred_constraints_constants_test.dart",
|
||||
"/language/deferred_constraints_lib.dart",
|
||||
"/language/deferred_constraints_lib2.dart",
|
||||
"/language/deferred_constraints_old_syntax_lib.dart",
|
||||
"/language/deferred_constraints_type_annotation_old_syntax_test.dart",
|
||||
"/language/deferred_constraints_type_annotation_test.dart",
|
||||
"/language/deferred_duplicate_prefix1_test.dart",
|
||||
"/language/deferred_duplicate_prefix2_test.dart",
|
||||
"/language/deferred_duplicate_prefix3_test.dart",
|
||||
"/language/deferred_load_inval_code_lib.dart",
|
||||
"/language/deferred_load_inval_code_test.dart",
|
||||
"/language/deferred_load_library_wrong_args_lib.dart",
|
||||
"/language/deferred_load_library_wrong_args_test.dart",
|
||||
"/language/deferred_no_prefix_test.dart",
|
||||
"/language/deferred_no_such_method_lib.dart",
|
||||
"/language/deferred_no_such_method_test.dart",
|
||||
"/language/deferred_not_loaded_check_lib.dart",
|
||||
"/language/deferred_not_loaded_check_test.dart",
|
||||
"/language/deferred_prefix_constraints_lib.dart",
|
||||
"/language/deferred_prefix_constraints_lib2.dart",
|
||||
"/language/deferred_shadow_load_library_lib.dart",
|
||||
"/language/deferred_shadow_load_library_test.dart",
|
||||
|
||||
"/language/bad_constructor_test.dart",
|
||||
"/language/black_listed_test.dart",
|
||||
"/language/built_in_identifier_illegal_test.dart",
|
||||
"/language/built_in_identifier_prefix_test.dart",
|
||||
"/language/built_in_identifier_test.dart",
|
||||
"/language/class_cycle2_test.dart",
|
||||
"/language/class_syntax_test.dart",
|
||||
"/language/cyclic_typedef_test.dart",
|
||||
"/language/external_test.dart",
|
||||
"/language/factory3_negative_test.dart",
|
||||
"/language/generic_field_mixin4_test.dart",
|
||||
"/language/generic_field_mixin5_test.dart",
|
||||
"/language/interface_cycle_test.dart",
|
||||
"/language/interface_injection1_negative_test.dart",
|
||||
"/language/interface_injection2_negative_test.dart",
|
||||
"/language/internal_library_test.dart",
|
||||
"/language/malformed_inheritance_test.dart",
|
||||
"/language/metadata_test.dart",
|
||||
"/language/method_override2_test.dart",
|
||||
"/language/mixin_illegal_syntax_test.dart",
|
||||
"/language/mixin_invalid_inheritance1_test.dart",
|
||||
"/language/null_test.dart",
|
||||
"/language/override_inheritance_generic_test.dart",
|
||||
"/language/prefix18_negative_test.dart",
|
||||
"/language/prefix3_negative_test.dart",
|
||||
"/language/script2_negative_test.dart",
|
||||
"/language/setter_declaration2_negative_test.dart",
|
||||
"/language/source_self_negative_test.dart",
|
||||
"/language/syntax_test.dart",
|
||||
"/language/type_variable_bounds2_test.dart",
|
||||
"/language/type_variable_conflict2_test.dart",
|
||||
"/language/type_variable_field_initializer_test.dart",
|
||||
"/language/type_variable_nested_test.dart",
|
||||
"/language/vm/reflect_core_vm_test.dart",
|
||||
"/language/vm/regress_14903_test.dart",
|
||||
]);
|
|
@ -1,104 +0,0 @@
|
|||
// Copyright (c) 2014, 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.
|
||||
|
||||
// Test a sequence of modifications to hello-world which used to cause problems
|
||||
// on Try Dart.
|
||||
|
||||
import 'dart:io' show Platform;
|
||||
|
||||
import 'dart:async' show Future;
|
||||
|
||||
import 'package:dart2js_incremental/dart2js_incremental.dart'
|
||||
show IncrementalCompiler;
|
||||
|
||||
import 'package:compiler/compiler.dart' show Diagnostic;
|
||||
|
||||
import 'package:compiler/src/null_compiler_output.dart' show NullCompilerOutput;
|
||||
|
||||
import 'package:compiler/src/old_to_new_api.dart'
|
||||
show LegacyCompilerDiagnostics;
|
||||
|
||||
import 'package:async_helper/async_helper.dart' show asyncTest;
|
||||
|
||||
import 'package:expect/expect.dart' show Expect;
|
||||
|
||||
import '../memory_source_file_helper.dart' show MemorySourceFileProvider;
|
||||
|
||||
var tests = {
|
||||
'/test1.dart': '''
|
||||
var greeting = "Hello, World!";
|
||||
|
||||
void main() {
|
||||
print(greeting);
|
||||
}
|
||||
''',
|
||||
'/test2.dart': '''
|
||||
va greeting = "Hello, World!";
|
||||
|
||||
void main() {
|
||||
print(greeting);
|
||||
}
|
||||
''',
|
||||
'/test3.dart': '''
|
||||
greeting = "Hello, World!";
|
||||
|
||||
void main() {
|
||||
print(greeting);
|
||||
}
|
||||
''',
|
||||
'/test4.dart': '''
|
||||
in greeting = "Hello, World!";
|
||||
|
||||
void main() {
|
||||
print(greeting);
|
||||
}
|
||||
''',
|
||||
'/test5.dart': '''
|
||||
int greeting = "Hello, World!";
|
||||
|
||||
void main() {
|
||||
print(greeting);
|
||||
}
|
||||
''',
|
||||
};
|
||||
|
||||
var testResults = {
|
||||
'/test1.dart': true,
|
||||
'/test2.dart': true,
|
||||
'/test3.dart': false,
|
||||
'/test4.dart': false,
|
||||
'/test5.dart': true,
|
||||
};
|
||||
|
||||
main() {
|
||||
Uri libraryRoot = Uri.base.resolve('sdk/');
|
||||
Uri packageConfig = Uri.base.resolve('.packages');
|
||||
MemorySourceFileProvider provider = new MemorySourceFileProvider(tests);
|
||||
asyncTest(() => runTests(libraryRoot, packageConfig, provider));
|
||||
}
|
||||
|
||||
Future runTests(
|
||||
Uri libraryRoot, Uri packageConfig, MemorySourceFileProvider provider) {
|
||||
IncrementalCompiler compiler = new IncrementalCompiler(
|
||||
diagnosticHandler: new LegacyCompilerDiagnostics(handler),
|
||||
inputProvider: provider,
|
||||
outputProvider: const NullCompilerOutput(),
|
||||
options: ['--analyze-main'],
|
||||
libraryRoot: libraryRoot,
|
||||
packageConfig: packageConfig);
|
||||
|
||||
return Future.forEach(tests.keys, (String testName) {
|
||||
Uri testUri = Uri.parse('memory:$testName');
|
||||
return compiler.compile(testUri).then((bool success) {
|
||||
Expect.equals(testResults[testName], success,
|
||||
'Compilation unexpectedly ${success ? "succeed" : "failed"}.');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void handler(Uri uri, int begin, int end, String message, Diagnostic kind) {
|
||||
if (kind != Diagnostic.VERBOSE_INFO) {
|
||||
print('$uri:$begin:$end:$message:$kind');
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue