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

Unified Diff: lib/devc.dart

Issue 1141013002: Fixes #179 -- compile error if editing files during server mode (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 7 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
Index: lib/devc.dart
diff --git a/lib/devc.dart b/lib/devc.dart
index 66627e826b0630b0b4e0080cea1ec00e22cdc96b..c046ebaba83bba5b93d7248c17f00e27cc9eeb82 100644
--- a/lib/devc.dart
+++ b/lib/devc.dart
@@ -9,7 +9,10 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
-import 'package:analyzer/src/generated/engine.dart' show ChangeSet;
+import 'package:analyzer/src/generated/error.dart' as analyzer;
+import 'package:analyzer/src/generated/engine.dart'
+ show AnalysisContext, ChangeSet;
+import 'package:analyzer/src/generated/source.dart' show Source;
import 'package:logging/logging.dart' show Level, Logger, LogRecord;
import 'package:path/path.dart' as path;
import 'package:shelf/shelf.dart' as shelf;
@@ -39,19 +42,25 @@ StreamSubscription setupLogger(Level level, printFn) {
});
}
+abstract class CompilerContext {
Jennifer Messerly 2015/05/13 23:21:16 these 4 things get passed around together a lot
vsm 2015/05/14 22:02:08 "Context" is a bit overloaded here with CompilerCo
Jennifer Messerly 2015/05/14 23:42:21 yeah, the idea was to be our equivalent of Analysi
+ CompilerOptions get options;
+ AnalysisContext get context;
+ TypeRules get rules;
+ Uri get entryPointUri;
+}
+
/// Encapsulates the logic to do a one-off compilation or a partial compilation
/// when the compiler is run as a development server.
-class Compiler {
- final CompilerOptions _options;
- final TypeResolver _resolver;
+class Compiler implements CompilerContext {
+ final CompilerOptions options;
+ final AnalysisContext context;
final CheckerReporter _reporter;
- final TypeRules _rules;
+ final TypeRules rules;
final CodeChecker _checker;
- final SourceGraph _graph;
final SourceNode _entryNode;
List<LibraryInfo> _libraries = <LibraryInfo>[];
- final List<CodeGenerator> _generators;
- final bool _hashing;
+ final List _generators = <CodeGenerator>[];
vsm 2015/05/14 22:02:08 Could drop the lhs type.
Jennifer Messerly 2015/05/14 23:42:21 Done.
+ bool _hashing;
bool _failure = false;
factory Compiler(CompilerOptions options,
@@ -61,15 +70,15 @@ class Compiler {
? new TypeResolver.fromMock(mockSdkSources, options)
: new TypeResolver.fromDir(options.dartSdkPath, options);
}
+ var context = resolver.context;
if (reporter == null) {
reporter = options.dumpInfo
- ? new SummaryReporter()
- : new LogReporter(options.useColors);
+ ? new SummaryReporter(context)
+ : new LogReporter(context, useColors: options.useColors);
}
- var graph = new SourceGraph(resolver.context, reporter, options);
- var rules =
- new RestrictedRules(resolver.context.typeProvider, options: options);
+ var graph = new SourceGraph(context, reporter, options);
+ var rules = new RestrictedRules(context.typeProvider, options: options);
var checker = new CodeChecker(rules, reporter, options);
var inputFile = options.entryPointFile;
var uri = inputFile.startsWith('dart:') || inputFile.startsWith('package:')
@@ -77,26 +86,25 @@ class Compiler {
: new Uri.file(path.absolute(inputFile));
var entryNode = graph.nodeFromUri(uri);
- var outputDir = options.outputDir;
- var generators = <CodeGenerator>[];
+ return new Compiler._(
+ options, context, reporter, rules, checker, entryNode);
+ }
+
+ Compiler._(this.options, this.context, this._reporter, this.rules,
+ this._checker, this._entryNode) {
if (options.dumpSrcDir != null) {
- generators.add(new EmptyDartGenerator(
- options.dumpSrcDir, entryNode.uri, rules, options));
+ _generators.add(new EmptyDartGenerator(this));
}
- if (outputDir != null) {
- generators.add(options.outputDart
- ? new DartGenerator(outputDir, entryNode.uri, rules, options)
- : new JSGenerator(outputDir, entryNode.uri, rules, options));
+ if (options.outputDir != null) {
+ _generators.add(
+ options.outputDart ? new DartGenerator(this) : new JSGenerator(this));
}
- return new Compiler._(options, resolver, reporter, rules, checker, graph,
- entryNode, generators,
- // TODO(sigmund): refactor to support hashing of the dart output?
- options.enableHashing && generators.length == 1 && !options.outputDart);
+ // TODO(sigmund): refactor to support hashing of the dart output?
+ _hashing =
+ options.enableHashing && _generators.length == 1 && !options.outputDart;
}
- Compiler._(this._options, this._resolver, this._reporter, this._rules,
- this._checker, this._graph, this._entryNode, this._generators,
- this._hashing);
+ Uri get entryPointUri => _entryNode.uri;
bool _buildSource(SourceNode node) {
if (node is HtmlSourceNode) {
@@ -115,30 +123,30 @@ class Compiler {
}
void _buildHtmlFile(HtmlSourceNode node) {
- if (_options.outputDir == null) return;
+ if (options.outputDir == null) return;
var uri = node.source.uri;
_reporter.enterHtml(uri);
- var output = generateEntryHtml(node, _options);
+ var output = generateEntryHtml(node, options);
if (output == null) {
_failure = true;
return;
}
_reporter.leaveHtml();
var filename = path.basename(node.uri.path);
- String outputFile = path.join(_options.outputDir, filename);
+ String outputFile = path.join(options.outputDir, filename);
new File(outputFile).writeAsStringSync(output);
- if (_options.outputDart) return;
+ if (options.outputDart) return;
}
void _buildResourceFile(ResourceSourceNode node) {
// ResourceSourceNodes files that just need to be copied over to the output
// location. These can be external dependencies or pieces of the
// dev_compiler runtime.
- if (_options.outputDir == null || _options.outputDart) return;
+ if (options.outputDir == null || options.outputDart) return;
var filepath = resourceOutputPath(node.uri, _entryNode.uri);
assert(filepath != null);
- filepath = path.join(_options.outputDir, filepath);
+ filepath = path.join(options.outputDir, filepath);
var dir = path.dirname(filepath);
new Directory(dir).createSync(recursive: true);
new File.fromUri(node.source.uri).copySync(filepath);
@@ -153,10 +161,10 @@ class Compiler {
void _buildDartLibrary(DartSourceNode node) {
var source = node.source;
// TODO(sigmund): find out from analyzer team if there is a better way
- _resolver.context.applyChanges(new ChangeSet()..changedSource(source));
- var entryUnit = _resolver.context.resolveCompilationUnit2(source, source);
+ context.applyChanges(new ChangeSet()..changedSource(source));
+ var entryUnit = context.resolveCompilationUnit2(source, source);
var lib = entryUnit.element.enclosingElement;
- if (!_options.checkSdk && lib.isInSdk) return;
+ if (!options.checkSdk && lib.isInSdk) return;
var current = node.info;
if (current != null) {
assert(current.library == lib);
@@ -165,25 +173,25 @@ class Compiler {
}
_reporter.enterLibrary(source.uri);
_libraries.add(current);
- _rules.currentLibraryInfo = current;
+ rules.currentLibraryInfo = current;
var resolvedParts = node.parts
- .map((p) => _resolver.context.resolveCompilationUnit2(p.source, source))
+ .map((p) => context.resolveCompilationUnit2(p.source, source))
.toList(growable: false);
var libraryUnit = new LibraryUnit(entryUnit, resolvedParts);
bool failureInLib = false;
for (var unit in libraryUnit.libraryThenParts) {
var unitSource = unit.element.source;
- _reporter.enterSource(unitSource);
+ _reporter.enterCompilationUnit(unit);
// TODO(sigmund): integrate analyzer errors with static-info (issue #6).
- failureInLib = _resolver.logErrors(unitSource, _reporter) || failureInLib;
+ failureInLib = logErrors(unitSource) || failureInLib;
_checker.visitCompilationUnit(unit);
if (_checker.failure) failureInLib = true;
- _reporter.leaveSource();
+ _reporter.leaveCompilationUnit();
}
if (failureInLib) {
_failure = true;
- if (!_options.forceCompile) return;
+ if (!options.forceCompile) return;
}
for (var cg in _generators) {
@@ -193,6 +201,21 @@ class Compiler {
_reporter.leaveLibrary();
}
+ /// Log any errors encountered when resolving [source] and return whether any
+ /// errors were found.
+ bool logErrors(Source source) {
Jennifer Messerly 2015/05/13 23:21:16 moved from "TypeResolver"
+ List<analyzer.AnalysisError> errors = context.getErrors(source).errors;
+ bool failure = false;
+ if (errors.isNotEmpty) {
+ for (var error in errors) {
+ var message = new AnalyzerError.from(error);
+ if (message.level == Level.SEVERE) failure = true;
+ _reporter.log(message);
+ }
+ }
+ return failure;
+ }
+
CheckerResults run() {
var clock = new Stopwatch()..start();
@@ -201,13 +224,13 @@ class Compiler {
// like more than one script tag (see .severe messages in
// dependency_graph.dart). Such failures should be reported back
// here so we can mark failure=true in the CheckerResutls.
- rebuild(_entryNode, _graph, _buildSource);
+ rebuild(_entryNode, _buildSource);
_dumpInfoIfRequested();
clock.stop();
var time = (clock.elapsedMilliseconds / 1000).toStringAsFixed(2);
_log.fine('Compiled ${_libraries.length} libraries in ${time} s\n');
return new CheckerResults(
- _libraries, _rules, _failure || _options.forceCompile);
+ _libraries, rules, _failure || options.forceCompile);
}
void _runAgain() {
@@ -216,7 +239,7 @@ class Compiler {
int changed = 0;
// TODO(sigmund): propagate failures here (see TODO in run).
- rebuild(_entryNode, _graph, (n) {
+ rebuild(_entryNode, (n) {
changed++;
return _buildSource(n);
});
@@ -227,12 +250,12 @@ class Compiler {
}
_dumpInfoIfRequested() {
- if (!_options.dumpInfo || _reporter is! SummaryReporter) return;
+ if (!options.dumpInfo || _reporter is! SummaryReporter) return;
var result = (_reporter as SummaryReporter).result;
- if (!_options.serverMode) print(summaryToString(result));
- var filepath = _options.serverMode
- ? path.join(_options.outputDir, 'messages.json')
- : _options.dumpInfoFile;
+ if (!options.serverMode) print(summaryToString(result));
+ var filepath = options.serverMode
+ ? path.join(options.outputDir, 'messages.json')
+ : options.dumpInfoFile;
if (filepath == null) return;
new File(filepath).writeAsStringSync(JSON.encode(result.toJsonMap()));
}
@@ -313,3 +336,17 @@ class CompilerServer {
final _log = new Logger('dev_compiler');
final _earlyErrorResult = new CheckerResults(const [], null, true);
+
+class AnalyzerError extends Message {
vsm 2015/05/14 22:02:08 Perhaps this would fit better in info.dart where w
Jennifer Messerly 2015/05/14 23:42:21 good idea, done!
+ factory AnalyzerError.from(analyzer.AnalysisError error) {
+ var severity = error.errorCode.type.severity;
+ var isError = severity == analyzer.ErrorSeverity.ERROR;
+ var level = isError ? Level.SEVERE : Level.WARNING;
+ int begin = error.offset;
+ int end = begin + error.length;
+ return new AnalyzerError(error.message, level, begin, end);
+ }
+
+ const AnalyzerError(String message, Level level, int begin, int end)
+ : super('[from analyzer]: $message', level, begin, end);
+}

Powered by Google App Engine
This is Rietveld 408576698