Chromium Code Reviews| Index: dart/frog/leg/compiler.dart |
| diff --git a/dart/frog/leg/compiler.dart b/dart/frog/leg/compiler.dart |
| index 7cb97460389ddd5696730111b63332cd793e2720..9f72ace65b9ef3de0a890ceb8b6efc8874041d38 100644 |
| --- a/dart/frog/leg/compiler.dart |
| +++ b/dart/frog/leg/compiler.dart |
| @@ -125,11 +125,22 @@ class Compiler implements DiagnosticListener { |
| void cancel([String reason, Node node, Token token, |
| HInstruction instruction, Element element]) { |
| + SourceSpan span = const SourceSpan(null, null, null); |
| + if (node !== null) { |
| + span = spanFromNode(node); |
| + } else if (token !== null) { |
| + span = spanFromToken(token); |
| + } else if (instruction !== null) { |
| + span = spanFromElement(currentElement); |
| + } else if (element !== null) { |
| + span = spanFromElement(element); |
| + } |
| + reportDiagnostic(span.uri, span.begin, span.end, reason, true); |
|
kasperl
2012/03/09 09:59:00
Maybe have a way of reporting diagnostics given a
ahe
2012/03/10 00:08:19
I like that better. Will do.
|
| throw new CompilerCancelledException(reason); |
| } |
| void log(message) { |
| - // Do nothing. |
| + reportDiagnostic(null, null, null, message, false); |
| } |
| void enqueue(WorkItem work) { |
| @@ -366,9 +377,55 @@ class Compiler implements DiagnosticListener { |
| }); |
| } |
| - reportWarning(Node node, var message) {} |
| + reportWarning(Node node, var message) { |
| + SourceSpan span = spanFromNode(node); |
| + reportDiagnostic(span.uri, span.begin, span.end, message.toString(), false); |
| + } |
| - reportError(Node node, var message) => cancel(message.toString(), node: node); |
| + reportError(Node node, var message) { |
| + SourceSpan span = spanFromNode(node); |
| + reportDiagnostic(span.uri, span.begin, span.end, message.toString(), true); |
| + throw new CompilerCancelledException(reason); |
| + } |
| + |
| + abstract void reportDiagnostic(Uri uri, int begin, int end, |
| + String message, bool fatal); |
| + |
| + SourceSpan spanFromTokens(Token begin, Token end) { |
| + if (begin === null || end === null) { |
| + throw 'cannot find tokens to produce error message'; |
| + } |
| + final startOffset = begin.charOffset; |
| + // TODO(ahe): Compute proper end offset. |
| + final endOffset = end.next.charOffset - 1; |
| + Uri uri = currentElement.getCompilationUnit().script.uri; |
| + return new SourceSpan(uri, startOffset, endOffset); |
| + } |
| + |
| + SourceSpan spanFromNode(Node node) { |
| + return spanFromTokens(node.getBeginToken(), node.getEndToken()); |
| + } |
| + |
| + SourceSpan spanFromElement(Element element) { |
| + if (element.position() === null) { |
| + // Sometimes, the backend fakes up elements that have no |
| + // position. So we use the enclosing element instead. It is |
| + // not a good error location, but cancel really is "internal |
| + // error" or "not implemented yet", so the vicinity is good |
| + // enough for now. |
| + element = element.enclosingElement; |
| + // TODO(ahe): I plan to overhaul this infrastructure anyways. |
| + } |
| + if (element === null) { |
| + element = currentElement; |
| + } |
| + Token position = element.position(); |
| + if (position === null) { |
| + // TODO(ahe): Find the enclosing library. |
| + return const SourceSpan(null, null, null); |
| + } |
| + return spanFromTokens(position, position); |
| + } |
| Script readScript(Uri uri, [ScriptTag node]) { |
| unimplemented('Compiler.readScript'); |
| @@ -430,3 +487,11 @@ class LTracer implements Tracer { |
| void close() { |
| } |
| } |
| + |
| +class SourceSpan { |
| + final Uri uri; |
| + final int begin; |
| + final int end; |
| + |
| + const SourceSpan(this.uri, this.begin, this.end); |
| +} |