Skip to content

Commit a996783

Browse files
johnniwinthercommit-bot@chromium.org
authored andcommitted
[cfe+analyzer] Move StackListener to _fe_analyzer_shared
Change-Id: I7e0ebef15b904afc14ed3b1c0f72cde5389d9c59 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/123730 Reviewed-by: Paul Berry <paulberry@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
1 parent 28cc459 commit a996783

File tree

17 files changed

+416
-371
lines changed

17 files changed

+416
-371
lines changed

pkg/front_end/lib/src/fasta/quote.dart renamed to pkg/_fe_analyzer_shared/lib/src/parser/quote.dart

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ import 'package:_fe_analyzer_shared/src/scanner/characters.dart'
3030
hexDigitValue,
3131
isHexDigit;
3232

33-
import 'problems.dart' show unhandled;
34-
35-
import 'fasta_codes.dart' as fasta;
33+
import 'package:_fe_analyzer_shared/src/messages/codes.dart' as codes;
3634

3735
enum Quote {
3836
Single,
@@ -54,7 +52,7 @@ Quote analyzeQuote(String first) {
5452
if (first.startsWith('r"')) return Quote.RawDouble;
5553
if (first.startsWith("'")) return Quote.Single;
5654
if (first.startsWith("r'")) return Quote.RawSingle;
57-
return unhandled(first, "analyzeQuote", -1, null);
55+
return throw UnsupportedError("'$first' in analyzeQuote");
5856
}
5957

6058
// Note: based on [StringValidator.quotingFromString]
@@ -104,7 +102,7 @@ int firstQuoteLength(String first, Quote quote) {
104102
case Quote.RawMultiLineDouble:
105103
return lengthOfOptionalWhitespacePrefix(first, 4);
106104
}
107-
return unhandled("$quote", "firstQuoteLength", -1, null);
105+
return throw UnsupportedError("'$quote' in firstQuoteLength");
108106
}
109107

110108
int lastQuoteLength(Quote quote) {
@@ -121,7 +119,7 @@ int lastQuoteLength(Quote quote) {
121119
case Quote.RawMultiLineDouble:
122120
return 3;
123121
}
124-
return unhandled("$quote", "lastQuoteLength", -1, null);
122+
return throw UnsupportedError("'$quote' in lastQuoteLength");
125123
}
126124

127125
String unescapeFirstStringPart(String first, Quote quote, Object location,
@@ -174,7 +172,7 @@ String unescape(String string, Quote quote, Object location,
174172
? string
175173
: unescapeCodeUnits(string.codeUnits, true, location, listener);
176174
}
177-
return unhandled("$quote", "unescape", -1, null);
175+
return throw new UnsupportedError("'$quote' in unescape");
178176
}
179177

180178
// Note: based on
@@ -195,7 +193,7 @@ String unescapeCodeUnits(List<int> codeUnits, bool isRaw, Object location,
195193
} else if (!isRaw && code == $BACKSLASH) {
196194
if (codeUnits.length == ++i) {
197195
listener.handleUnescapeError(
198-
fasta.messageInvalidUnicodeEscape, location, i, 1);
196+
codes.messageInvalidUnicodeEscape, location, i, 1);
199197
return new String.fromCharCodes(codeUnits);
200198
}
201199
code = codeUnits[i];
@@ -224,7 +222,7 @@ String unescapeCodeUnits(List<int> codeUnits, bool isRaw, Object location,
224222
// Expect exactly 2 hex digits.
225223
int begin = i;
226224
if (codeUnits.length <= i + 2) {
227-
listener.handleUnescapeError(fasta.messageInvalidHexEscape, location,
225+
listener.handleUnescapeError(codes.messageInvalidHexEscape, location,
228226
begin, codeUnits.length + 1 - begin);
229227
return new String.fromCharCodes(codeUnits);
230228
}
@@ -233,37 +231,37 @@ String unescapeCodeUnits(List<int> codeUnits, bool isRaw, Object location,
233231
int digit = codeUnits[++i];
234232
if (!isHexDigit(digit)) {
235233
listener.handleUnescapeError(
236-
fasta.messageInvalidHexEscape, location, begin, i + 1 - begin);
234+
codes.messageInvalidHexEscape, location, begin, i + 1 - begin);
237235
return new String.fromCharCodes(codeUnits);
238236
}
239237
code = (code << 4) + hexDigitValue(digit);
240238
}
241239
} else if (code == $u) {
242240
int begin = i;
243241
if (codeUnits.length == i + 1) {
244-
listener.handleUnescapeError(fasta.messageInvalidUnicodeEscape,
242+
listener.handleUnescapeError(codes.messageInvalidUnicodeEscape,
245243
location, begin, codeUnits.length + 1 - begin);
246244
return new String.fromCharCodes(codeUnits);
247245
}
248246
code = codeUnits[i + 1];
249247
if (code == $OPEN_CURLY_BRACKET) {
250248
// Expect 1-6 hex digits followed by '}'.
251249
if (codeUnits.length == ++i) {
252-
listener.handleUnescapeError(fasta.messageInvalidUnicodeEscape,
250+
listener.handleUnescapeError(codes.messageInvalidUnicodeEscape,
253251
location, begin, i + 1 - begin);
254252
return new String.fromCharCodes(codeUnits);
255253
}
256254
code = 0;
257255
for (int j = 0; j < 7; j++) {
258256
if (codeUnits.length == ++i) {
259-
listener.handleUnescapeError(fasta.messageInvalidUnicodeEscape,
257+
listener.handleUnescapeError(codes.messageInvalidUnicodeEscape,
260258
location, begin, i + 1 - begin);
261259
return new String.fromCharCodes(codeUnits);
262260
}
263261
int digit = codeUnits[i];
264262
if (j != 0 && digit == $CLOSE_CURLY_BRACKET) break;
265263
if (!isHexDigit(digit)) {
266-
listener.handleUnescapeError(fasta.messageInvalidUnicodeEscape,
264+
listener.handleUnescapeError(codes.messageInvalidUnicodeEscape,
267265
location, begin, i + 2 - begin);
268266
return new String.fromCharCodes(codeUnits);
269267
}
@@ -272,15 +270,15 @@ String unescapeCodeUnits(List<int> codeUnits, bool isRaw, Object location,
272270
} else {
273271
// Expect exactly 4 hex digits.
274272
if (codeUnits.length <= i + 4) {
275-
listener.handleUnescapeError(fasta.messageInvalidUnicodeEscape,
273+
listener.handleUnescapeError(codes.messageInvalidUnicodeEscape,
276274
location, begin, codeUnits.length + 1 - begin);
277275
return new String.fromCharCodes(codeUnits);
278276
}
279277
code = 0;
280278
for (int j = 0; j < 4; j++) {
281279
int digit = codeUnits[++i];
282280
if (!isHexDigit(digit)) {
283-
listener.handleUnescapeError(fasta.messageInvalidUnicodeEscape,
281+
listener.handleUnescapeError(codes.messageInvalidUnicodeEscape,
284282
location, begin, i + 1 - begin);
285283
return new String.fromCharCodes(codeUnits);
286284
}
@@ -289,7 +287,7 @@ String unescapeCodeUnits(List<int> codeUnits, bool isRaw, Object location,
289287
}
290288
if (code > 0x10FFFF) {
291289
listener.handleUnescapeError(
292-
fasta.messageInvalidCodePoint, location, begin, i + 1 - begin);
290+
codes.messageInvalidCodePoint, location, begin, i + 1 - begin);
293291
return new String.fromCharCodes(codeUnits);
294292
}
295293
} else {

pkg/front_end/lib/src/fasta/source/stack_listener.dart renamed to pkg/_fe_analyzer_shared/lib/src/parser/stack_listener.dart

Lines changed: 31 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,27 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
library fasta.stack_listener;
5+
library _fe_analyzer_shared.stack_listener;
66

7-
import 'package:_fe_analyzer_shared/src/parser/parser.dart'
8-
show Listener, MemberKind, Parser, lengthOfSpan;
9-
10-
import 'package:_fe_analyzer_shared/src/parser/identifier_context.dart'
11-
show IdentifierContext;
12-
13-
import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' show Token;
14-
15-
import 'package:kernel/ast.dart'
16-
show AsyncMarker, Expression, FunctionNode, TreeNode;
17-
18-
import '../fasta_codes.dart'
7+
import '../messages/codes.dart'
198
show
209
Code,
2110
LocatedMessage,
2211
Message,
2312
codeCatchSyntaxExtraParameters,
2413
codeNativeClauseShouldBeAnnotation,
25-
templateInternalProblemStackNotEmpty;
14+
templateInternalProblemStackNotEmpty,
15+
templateInternalProblemUnhandled;
16+
17+
import '../scanner/scanner.dart' show Token;
18+
19+
import 'identifier_context.dart' show IdentifierContext;
2620

27-
import '../problems.dart'
28-
show internalProblem, unhandled, unimplemented, unsupported;
21+
import 'parser.dart' show Listener, MemberKind, lengthOfSpan;
2922

30-
import '../quote.dart' show unescapeString;
23+
import 'quote.dart' show unescapeString;
3124

32-
import 'value_kinds.dart';
25+
import 'value_kind.dart';
3326

3427
enum NullValue {
3528
Arguments,
@@ -80,6 +73,9 @@ enum NullValue {
8073
abstract class StackListener extends Listener {
8174
final Stack stack = new Stack();
8275

76+
/// Used to report an internal error encountered in the stack listener.
77+
dynamic internalProblem(Message message, int charOffset, Uri uri);
78+
8379
/// Checks that [value] matches the expected [kind].
8480
///
8581
/// Use this in assert statements like
@@ -214,37 +210,13 @@ abstract class StackListener extends Listener {
214210
}
215211
}
216212

217-
// TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart
218-
// and ast_builder.dart.
219-
void finishFunction(
220-
covariant formals, AsyncMarker asyncModifier, covariant body) {
221-
return unsupported("finishFunction", -1, uri);
222-
}
223-
224-
// TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart
225-
// and ast_builder.dart.
226-
dynamic finishFields() {
227-
return unsupported("finishFields", -1, uri);
228-
}
229-
230-
// TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart
231-
// and ast_builder.dart.
232-
List<Expression> finishMetadata(TreeNode parent) {
233-
return unsupported("finishMetadata", -1, uri);
234-
}
235-
236-
// TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart
237-
// and ast_builder.dart.
238-
void exitLocalScope() => unsupported("exitLocalScope", -1, uri);
239-
240-
// TODO(ahe): This doesn't belong here. Only implemented by body_builder.dart.
241-
dynamic parseSingleExpression(
242-
Parser parser, Token token, FunctionNode parameters) {
243-
return unsupported("finishSingleExpression", -1, uri);
244-
}
245-
246213
void push(Object node) {
247-
if (node == null) unhandled("null", "push", -1, uri);
214+
if (node == null) {
215+
internalProblem(
216+
templateInternalProblemUnhandled.withArguments("null", "push"),
217+
-1,
218+
uri);
219+
}
248220
stack.push(node);
249221
}
250222

@@ -282,7 +254,10 @@ abstract class StackListener extends Listener {
282254
@override
283255
void logEvent(String name) {
284256
printEvent(name);
285-
unhandled(name, "$runtimeType", -1, uri);
257+
internalProblem(
258+
templateInternalProblemUnhandled.withArguments(name, "$runtimeType"),
259+
-1,
260+
uri);
286261
}
287262

288263
@override
@@ -453,7 +428,11 @@ abstract class StackListener extends Listener {
453428
Token token = pop();
454429
push(unescapeString(token.lexeme, token, this));
455430
} else {
456-
unimplemented("string interpolation", endToken.charOffset, uri);
431+
internalProblem(
432+
templateInternalProblemUnhandled.withArguments(
433+
"string interpolation", "endLiteralString"),
434+
endToken.charOffset,
435+
uri);
457436
}
458437
}
459438

@@ -490,8 +469,8 @@ abstract class StackListener extends Listener {
490469
Message message, Token startToken, Token endToken) {
491470
debugEvent("Error: ${message.message}");
492471
if (isIgnoredError(message.code, startToken)) return;
493-
addProblem(message, offsetForToken(startToken),
494-
lengthOfSpan(startToken, endToken));
472+
addProblem(
473+
message, startToken.charOffset, lengthOfSpan(startToken, endToken));
495474
}
496475

497476
bool isIgnoredError(Code<dynamic> code, Token token) {
@@ -627,9 +606,3 @@ class ParserRecovery {
627606

628607
String toString() => "ParserRecovery(@$charOffset)";
629608
}
630-
631-
/// A null-aware alternative to `token.offset`. If [token] is `null`, returns
632-
/// `TreeNode.noOffset`.
633-
int offsetForToken(Token token) {
634-
return token == null ? TreeNode.noOffset : token.offset;
635-
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'stack_listener.dart' show NullValue;
6+
7+
/// [ValueKind] is used in [StackListener.checkState] to document and check the
8+
/// expected values of the stack.
9+
///
10+
/// Add new value kinds as needed for documenting and checking the various stack
11+
/// listener implementations.
12+
abstract class ValueKind {
13+
const ValueKind();
14+
15+
/// Checks the [value] an returns `true` if the value is of the expected kind.
16+
bool check(Object value);
17+
}
18+
19+
/// A [ValueKind] for a particular type [T], optionally with a recognized
20+
/// [NullValue].
21+
class SingleValueKind<T> implements ValueKind {
22+
final NullValue nullValue;
23+
24+
const SingleValueKind([this.nullValue]);
25+
26+
@override
27+
bool check(Object value) {
28+
if (nullValue != null && value == nullValue) {
29+
return true;
30+
}
31+
return value is T;
32+
}
33+
34+
String toString() {
35+
if (nullValue != null) {
36+
return '$T or $nullValue';
37+
}
38+
return '$T';
39+
}
40+
}
41+
42+
/// A [ValueKind] for the union of a list of [ValueKind]s.
43+
class UnionValueKind implements ValueKind {
44+
final List<ValueKind> kinds;
45+
46+
const UnionValueKind(this.kinds);
47+
48+
@override
49+
bool check(Object value) {
50+
for (ValueKind kind in kinds) {
51+
if (kind.check(value)) {
52+
return true;
53+
}
54+
}
55+
return false;
56+
}
57+
58+
String toString() {
59+
StringBuffer sb = new StringBuffer();
60+
String or = '';
61+
for (ValueKind kind in kinds) {
62+
sb.write(or);
63+
sb.write(kind);
64+
or = ' or ';
65+
}
66+
return sb.toString();
67+
}
68+
}
69+
70+
/// Helper method for creating a list of [ValueKind]s of the given length
71+
/// [count].
72+
List<ValueKind> repeatedKinds(ValueKind kind, int count) {
73+
return new List.generate(count, (_) => kind);
74+
}
75+
76+
/// Helper method for creating a union of a list of [ValueKind]s.
77+
ValueKind unionOfKinds(List<ValueKind> kinds) {
78+
return new UnionValueKind(kinds);
79+
}

0 commit comments

Comments
 (0)