Skip to content

Commit c5235fd

Browse files
committed
Add token invariant to DiagnosticReporter
Closes #3675 [email protected] Review URL: https://codereview.chromium.org/1520293002.
1 parent 212ba4a commit c5235fd

File tree

10 files changed

+96
-21
lines changed

10 files changed

+96
-21
lines changed

pkg/compiler/lib/src/compiler.dart

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,6 +1792,67 @@ class _CompilerDiagnosticReporter extends DiagnosticReporter {
17921792
}
17931793
if (uri == null && currentElement != null) {
17941794
uri = currentElement.compilationUnit.script.resourceUri;
1795+
assert(invariant(currentElement, () {
1796+
1797+
/// Check that [begin] and [end] can be found between [from] and [to].
1798+
validateToken(Token from, Token to) {
1799+
if (from == null || to == null) return true;
1800+
bool foundBegin = false;
1801+
bool foundEnd = false;
1802+
Token token = from;
1803+
while (true) {
1804+
if (token == begin) {
1805+
foundBegin = true;
1806+
}
1807+
if (token == end) {
1808+
foundEnd = true;
1809+
}
1810+
if (foundBegin && foundEnd) {
1811+
return true;
1812+
}
1813+
if (token == to || token == token.next || token.next == null) {
1814+
break;
1815+
}
1816+
token = token.next;
1817+
}
1818+
1819+
// Create a good message for when the tokens were not found.
1820+
StringBuffer sb = new StringBuffer();
1821+
sb.write('Invalid current element: $currentElement. ');
1822+
sb.write('Looking for ');
1823+
sb.write('[${begin} (${begin.hashCode}),');
1824+
sb.write('${end} (${end.hashCode})] in');
1825+
1826+
token = from;
1827+
while (true) {
1828+
sb.write('\n ${token} (${token.hashCode})');
1829+
if (token == to || token == token.next || token.next == null) {
1830+
break;
1831+
}
1832+
token = token.next;
1833+
}
1834+
return sb.toString();
1835+
}
1836+
1837+
if (currentElement.enclosingClass != null &&
1838+
currentElement.enclosingClass.isEnumClass) {
1839+
// Enums ASTs are synthesized (and give messed up messages).
1840+
return true;
1841+
}
1842+
1843+
if (currentElement is AstElement) {
1844+
AstElement astElement = currentElement;
1845+
if (astElement.hasNode) {
1846+
Token from = astElement.node.getBeginToken();
1847+
Token to = astElement.node.getEndToken();
1848+
if (astElement.metadata.isNotEmpty) {
1849+
from = astElement.metadata.first.beginToken;
1850+
}
1851+
return validateToken(from, to);
1852+
}
1853+
}
1854+
return true;
1855+
}, message: "Invalid current element: $currentElement [$begin,$end]."));
17951856
}
17961857
return new SourceSpan.fromTokens(uri, begin, end);
17971858
}

pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ abstract class DiagnosticReporter {
6969

7070
internalError(Spannable spannable, message);
7171

72+
/// Creates a [SourceSpan] for [node] in scope of the current element.
73+
///
74+
/// If [node] is a [Node] or [Token] we assert in checked mode that the
75+
/// corresponding tokens can be found within the tokens of the current
76+
/// element.
7277
SourceSpan spanFromSpannable(Spannable node);
7378

7479
void reportErrorMessage(
@@ -109,10 +114,8 @@ abstract class DiagnosticReporter {
109114
void reportInfo(Spannable node, MessageKind errorCode,
110115
[Map arguments = const {}]);
111116

112-
// TODO(ahe): We should not expose this here. Perhaps a
113-
// [SourceSpan] should implement [Spannable], and we should have a
114-
// way to construct a [SourceSpan] from a [Spannable] and an
115-
// [Element].
117+
/// Set current element of this reporter to [element]. This is used for
118+
/// creating [SourceSpan] in [spanFromSpannable].
116119
withCurrentElement(Element element, f());
117120

118121
DiagnosticMessage createMessage(

pkg/compiler/lib/src/diagnostics/invariant.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ bool invariant(Spannable spannable, var condition, {var message: null}) {
4848
}
4949
if (condition is Function){
5050
condition = condition();
51+
if (condition is String) {
52+
message = condition;
53+
condition = false;
54+
}
5155
}
5256
if (!condition) {
5357
if (message is Function) {

pkg/compiler/lib/src/resolution/constructors.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ class InitializerResolver {
6666
return node.receiver.asIdentifier().isThis();
6767
}
6868

69-
reportDuplicateInitializerError(Element field, Node init, Node existing) {
69+
reportDuplicateInitializerError(Element field,
70+
Node init,
71+
Spannable existing) {
7072
reporter.reportError(
7173
reporter.createMessage(
7274
init,
@@ -90,7 +92,9 @@ class InitializerResolver {
9092
field.parseNode(visitor.resolution.parsing);
9193
Expression initializer = field.initializer;
9294
if (initializer != null) {
93-
reportDuplicateInitializerError(field, init, initializer);
95+
reportDuplicateInitializerError(field, init,
96+
reporter.withCurrentElement(field,
97+
() => reporter.spanFromSpannable(initializer)));
9498
}
9599
}
96100
initialized[field] = init;

pkg/compiler/lib/src/resolution/enum_creator.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ class AstBuilder {
180180
}
181181
}
182182

183+
// TODO(johnniwinther): Avoid creating synthesized ASTs for enums when SSA is
184+
// removed.
183185
class EnumCreator {
184186
final DiagnosticReporter reporter;
185187
final CoreTypes coreTypes;

pkg/compiler/lib/src/resolution/members.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,7 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
802802
registry.registerFeature(Feature.COMPILE_TIME_ERROR);
803803
return new StaticAccess.invalid(error);
804804
}
805-
registry.registerSuperUse(node);
805+
registry.registerSuperUse(reporter.spanFromSpannable(node));
806806
return null;
807807
}
808808

pkg/compiler/lib/src/resolution/registry.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import '../compiler.dart' show
1919
Compiler;
2020
import '../constants/expressions.dart';
2121
import '../dart_types.dart';
22+
import '../diagnostics/source_span.dart';
2223
import '../enqueue.dart' show
2324
ResolutionEnqueuer;
2425
import '../elements/elements.dart';
@@ -314,8 +315,8 @@ class ResolutionRegistry extends Registry {
314315
worldImpact.registerTypeUse(typeUse);
315316
}
316317

317-
void registerSuperUse(Node node) {
318-
mapping.addSuperUse(node);
318+
void registerSuperUse(SourceSpan span) {
319+
mapping.addSuperUse(span);
319320
}
320321

321322
void registerTypeLiteral(Send node, DartType type) {

pkg/compiler/lib/src/resolution/resolution.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ class ResolverTask extends CompilerTask {
513513
* called by [resolveClass] and [ClassSupertypeResolver].
514514
*/
515515
void loadSupertypes(BaseClassElementX cls, Spannable from) {
516-
reporter.withCurrentElement(cls, () => measure(() {
516+
measure(() {
517517
if (cls.supertypeLoadState == STATE_DONE) return;
518518
if (cls.supertypeLoadState == STATE_STARTED) {
519519
reporter.reportErrorMessage(
@@ -540,7 +540,7 @@ class ResolverTask extends CompilerTask {
540540
cls.supertypeLoadState = STATE_DONE;
541541
}
542542
});
543-
}));
543+
});
544544
}
545545

546546
// TODO(johnniwinther): Remove this queue when resolution has been split into
@@ -763,15 +763,15 @@ class ResolverTask extends CompilerTask {
763763
ClassElement mixin) {
764764
// TODO(johnniwinther): Avoid the use of [TreeElements] here.
765765
if (resolutionTree == null) return;
766-
Iterable<Node> superUses = resolutionTree.superUses;
766+
Iterable<SourceSpan> superUses = resolutionTree.superUses;
767767
if (superUses.isEmpty) return;
768768
DiagnosticMessage error = reporter.createMessage(
769769
mixinApplication,
770770
MessageKind.ILLEGAL_MIXIN_WITH_SUPER,
771771
{'className': mixin.name});
772772
// Show the user the problematic uses of 'super' in the mixin.
773773
List<DiagnosticMessage> infos = <DiagnosticMessage>[];
774-
for (Node use in superUses) {
774+
for (SourceSpan use in superUses) {
775775
infos.add(reporter.createMessage(
776776
use,
777777
MessageKind.ILLEGAL_MIXIN_SUPER_USE));

pkg/compiler/lib/src/resolution/tree_elements.dart

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ library dart2js.resolution.tree_elements;
77
import '../common.dart';
88
import '../constants/expressions.dart';
99
import '../dart_types.dart';
10+
import '../diagnostics/source_span.dart';
1011
import '../elements/elements.dart';
1112
import '../types/types.dart' show
1213
TypeMask;
@@ -22,7 +23,7 @@ import 'send_structure.dart';
2223

2324
abstract class TreeElements {
2425
AnalyzableElement get analyzedElement;
25-
Iterable<Node> get superUses;
26+
Iterable<SourceSpan> get superUses;
2627

2728
void forEachConstantNode(f(Node n, ConstantExpression c));
2829

@@ -111,7 +112,7 @@ class TreeElementMapping extends TreeElements {
111112
Map<Spannable, TypeMask> _typeMasks;
112113
Map<Node, DartType> _types;
113114
Map<Node, DartType> typesCache = <Node, DartType>{};
114-
Setlet<Node> _superUses;
115+
Setlet<SourceSpan> _superUses;
115116
Map<Node, ConstantExpression> _constants;
116117
Map<VariableElement, List<Node>> _potentiallyMutated;
117118
Map<Node, Map<VariableElement, List<Node>>> _potentiallyMutatedIn;
@@ -191,15 +192,15 @@ class TreeElementMapping extends TreeElements {
191192

192193
DartType getType(Node node) => _types != null ? _types[node] : null;
193194

194-
Iterable<Node> get superUses {
195-
return _superUses != null ? _superUses : const <Node>[];
195+
Iterable<SourceSpan> get superUses {
196+
return _superUses != null ? _superUses : const <SourceSpan>[];
196197
}
197198

198-
void addSuperUse(Node node) {
199+
void addSuperUse(SourceSpan span) {
199200
if (_superUses == null) {
200-
_superUses = new Setlet<Node>();
201+
_superUses = new Setlet<SourceSpan>();
201202
}
202-
_superUses.add(node);
203+
_superUses.add(span);
203204
}
204205

205206
Selector _getSelector(Spannable node) {

tests/co19/co19-dart2js.status

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ Language/Reference/Lexical_Rules/whitespace_t06: MissingCompileTimeError # Check
134134
Language/Statements/Local_Function_Declaration/reference_before_declaration_t01: MissingCompileTimeError # Issue 21050
135135
Language/Statements/Local_Function_Declaration/reference_before_declaration_t03: MissingCompileTimeError # Issue 21050
136136
Language/Types/Interface_Types/subtype_t27: Skip # Times out or crashes. Issue 21174
137-
Language/Types/Interface_Types/subtype_t28: crash # Issue 21174
138137
Language/Types/Interface_Types/subtype_t30: fail # Issue 14654
139138
Language/Variables/final_t01: fail # Issue 21093
140139
Language/Variables/final_t02: fail # Issue 21093

0 commit comments

Comments
 (0)