mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 16:00:45 +00:00
Use parser and scanner from package:front_end.
Originally reviewed as: Review-Url: https://codereview.chromium.org/2650413002 . Review-Url: https://codereview.chromium.org/2652203002 . Review-Url: https://codereview.chromium.org/2655843002 . Review-Url: https://codereview.chromium.org/2654433009 . Review-Url: https://codereview.chromium.org/2647343003 . Review-Url: https://codereview.chromium.org/2652663005 . Review-Url: https://codereview.chromium.org/2650813002 . Review-Url: https://codereview.chromium.org/2650803002 . Review-Url: https://codereview.chromium.org/2651843004 . Review-Url: https://codereview.chromium.org/2649923002 . Review-Url: https://codereview.chromium.org/2651563003 . Review-Url: https://codereview.chromium.org/2649123002 . Review-Url: https://codereview.chromium.org/2644843006 . Review-Url: https://codereview.chromium.org/2647043002 . Review-Url: https://codereview.chromium.org/2642903003 . Review-Url: https://codereview.chromium.org/2645513002 . Review-Url: https://codereview.chromium.org/2642663003 . Review-Url: https://codereview.chromium.org/2642713002 . Review-Url: https://codereview.chromium.org/2635473002 . Review-Url: https://codereview.chromium.org/2624373003 . Review-Url: https://codereview.chromium.org/2627723006 . Review-Url: https://codereview.chromium.org/2627093007 . Review-Url: https://codereview.chromium.org/2629543008 . Review-Url: https://codereview.chromium.org/2629543007 . Review-Url: https://codereview.chromium.org/2631503002 . Review-Url: https://codereview.chromium.org/2621153006 .
This commit is contained in:
parent
2a4bc2c7e5
commit
d0d27c1c38
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -75,3 +75,6 @@ editor/util/testing/mac/CodeLab.suite/Results
|
||||||
editor/util/testing/mac/DartEditor.suite/Results
|
editor/util/testing/mac/DartEditor.suite/Results
|
||||||
editor/util/testing/mac/Samples.suite/Results
|
editor/util/testing/mac/Samples.suite/Results
|
||||||
.test-outcome.log
|
.test-outcome.log
|
||||||
|
/outline.dill
|
||||||
|
/generated/
|
||||||
|
/crash_logs/
|
||||||
|
|
|
@ -28,7 +28,6 @@ compiler_unsupported:pkg/compiler/lib
|
||||||
convert:third_party/pkg/convert/lib
|
convert:third_party/pkg/convert/lib
|
||||||
crypto:third_party/pkg/crypto/lib
|
crypto:third_party/pkg/crypto/lib
|
||||||
csslib:third_party/pkg/csslib/lib
|
csslib:third_party/pkg/csslib/lib
|
||||||
dart2js_incremental:pkg/dart2js_incremental/lib
|
|
||||||
dart2js_info:third_party/pkg/dart2js_info/lib
|
dart2js_info:third_party/pkg/dart2js_info/lib
|
||||||
dart_messages:pkg/dart_messages/lib
|
dart_messages:pkg/dart_messages/lib
|
||||||
dart_style:third_party/pkg_tested/dart_style/lib
|
dart_style:third_party/pkg_tested/dart_style/lib
|
||||||
|
@ -90,7 +89,8 @@ stack_trace:third_party/pkg/stack_trace/lib
|
||||||
stream_channel:third_party/pkg/stream_channel/lib
|
stream_channel:third_party/pkg/stream_channel/lib
|
||||||
string_scanner:third_party/pkg/string_scanner/lib
|
string_scanner:third_party/pkg/string_scanner/lib
|
||||||
test:third_party/pkg/test/lib
|
test:third_party/pkg/test/lib
|
||||||
testing:third_party/testing/lib
|
test_dart:tools/testing/dart
|
||||||
|
testing:pkg/testing/lib
|
||||||
test_reflective_loader:third_party/pkg/test_reflective_loader/lib
|
test_reflective_loader:third_party/pkg/test_reflective_loader/lib
|
||||||
typed_data:third_party/pkg/typed_data/lib
|
typed_data:third_party/pkg/typed_data/lib
|
||||||
typed_mock:pkg/typed_mock/lib
|
typed_mock:pkg/typed_mock/lib
|
||||||
|
|
|
@ -18,7 +18,7 @@ import 'elements/modelx.dart'
|
||||||
import 'elements/visitor.dart' show ElementVisitor;
|
import 'elements/visitor.dart' show ElementVisitor;
|
||||||
import 'js_backend/js_backend.dart' show JavaScriptBackend;
|
import 'js_backend/js_backend.dart' show JavaScriptBackend;
|
||||||
import 'resolution/tree_elements.dart' show TreeElements;
|
import 'resolution/tree_elements.dart' show TreeElements;
|
||||||
import 'tokens/token.dart' show Token;
|
import 'package:front_end/src/fasta/scanner.dart' show Token;
|
||||||
import 'tree/tree.dart';
|
import 'tree/tree.dart';
|
||||||
import 'util/util.dart';
|
import 'util/util.dart';
|
||||||
import 'world.dart' show ClosedWorldRefiner;
|
import 'world.dart' show ClosedWorldRefiner;
|
||||||
|
|
|
@ -17,7 +17,6 @@ import '../elements/elements.dart'
|
||||||
FunctionElement,
|
FunctionElement,
|
||||||
LocalFunctionElement,
|
LocalFunctionElement,
|
||||||
ResolvedAst;
|
ResolvedAst;
|
||||||
import '../enqueue.dart' show Enqueuer;
|
|
||||||
import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse;
|
import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse;
|
||||||
import '../universe/world_impact.dart'
|
import '../universe/world_impact.dart'
|
||||||
show WorldImpact, WorldImpactBuilderImpl, WorldImpactVisitor;
|
show WorldImpact, WorldImpactBuilderImpl, WorldImpactVisitor;
|
||||||
|
|
|
@ -30,6 +30,7 @@ import '../mirrors_used.dart';
|
||||||
import '../options.dart' show CompilerOptions;
|
import '../options.dart' show CompilerOptions;
|
||||||
import '../parser/element_listener.dart' show ScannerOptions;
|
import '../parser/element_listener.dart' show ScannerOptions;
|
||||||
import '../parser/parser_task.dart';
|
import '../parser/parser_task.dart';
|
||||||
|
import '../scanner/scanner_task.dart';
|
||||||
import '../patch_parser.dart';
|
import '../patch_parser.dart';
|
||||||
import '../resolution/resolution.dart';
|
import '../resolution/resolution.dart';
|
||||||
import '../tree/tree.dart' show Send, TypeAnnotation;
|
import '../tree/tree.dart' show Send, TypeAnnotation;
|
||||||
|
@ -215,10 +216,12 @@ abstract class Resolution implements Frontend {
|
||||||
/// A container of commonly used dependencies for tasks that involve parsing.
|
/// A container of commonly used dependencies for tasks that involve parsing.
|
||||||
abstract class ParsingContext {
|
abstract class ParsingContext {
|
||||||
factory ParsingContext(DiagnosticReporter reporter, ParserTask parser,
|
factory ParsingContext(DiagnosticReporter reporter, ParserTask parser,
|
||||||
PatchParserTask patchParser, Backend backend) = _ParsingContext;
|
ScannerTask scanner, PatchParserTask patchParser, Backend backend)
|
||||||
|
= _ParsingContext;
|
||||||
|
|
||||||
DiagnosticReporter get reporter;
|
DiagnosticReporter get reporter;
|
||||||
ParserTask get parser;
|
ParserTask get parser;
|
||||||
|
ScannerTask get scanner;
|
||||||
PatchParserTask get patchParser;
|
PatchParserTask get patchParser;
|
||||||
|
|
||||||
/// Use [patchParser] directly instead.
|
/// Use [patchParser] directly instead.
|
||||||
|
@ -236,10 +239,12 @@ abstract class ParsingContext {
|
||||||
class _ParsingContext implements ParsingContext {
|
class _ParsingContext implements ParsingContext {
|
||||||
final DiagnosticReporter reporter;
|
final DiagnosticReporter reporter;
|
||||||
final ParserTask parser;
|
final ParserTask parser;
|
||||||
|
final ScannerTask scanner;
|
||||||
final PatchParserTask patchParser;
|
final PatchParserTask patchParser;
|
||||||
final Backend backend;
|
final Backend backend;
|
||||||
|
|
||||||
_ParsingContext(this.reporter, this.parser, this.patchParser, this.backend);
|
_ParsingContext(this.reporter, this.parser, this.scanner, this.patchParser,
|
||||||
|
this.backend);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
measure(f()) => parser.measure(f);
|
measure(f()) => parser.measure(f);
|
||||||
|
|
|
@ -5,9 +5,7 @@
|
||||||
library dart2js.common.work;
|
library dart2js.common.work;
|
||||||
|
|
||||||
import '../common.dart';
|
import '../common.dart';
|
||||||
import '../compiler.dart' show Compiler;
|
|
||||||
import '../elements/elements.dart' show AstElement;
|
import '../elements/elements.dart' show AstElement;
|
||||||
import '../enqueue.dart' show Enqueuer;
|
|
||||||
import '../universe/world_impact.dart' show WorldImpact;
|
import '../universe/world_impact.dart' show WorldImpact;
|
||||||
|
|
||||||
abstract class WorkItem {
|
abstract class WorkItem {
|
||||||
|
|
|
@ -1294,7 +1294,7 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator {
|
||||||
Function compileArgument = (element) => definitions[element];
|
Function compileArgument = (element) => definitions[element];
|
||||||
Function compileConstant = handler.compileConstant;
|
Function compileConstant = handler.compileConstant;
|
||||||
FunctionElement target = constructor.definingConstructor.implementation;
|
FunctionElement target = constructor.definingConstructor.implementation;
|
||||||
Elements.addForwardingElementArgumentsToList<AstConstant>(constructor,
|
Elements.addForwardingElementArgumentsToList(constructor,
|
||||||
compiledArguments, target, compileArgument, compileConstant);
|
compiledArguments, target, compileArgument, compileConstant);
|
||||||
CallStructure callStructure = new CallStructure(
|
CallStructure callStructure = new CallStructure(
|
||||||
target.functionSignature.parameterCount, target.type.namedParameters);
|
target.functionSignature.parameterCount, target.type.namedParameters);
|
||||||
|
|
|
@ -66,9 +66,9 @@ import 'scanner/scanner_task.dart' show ScannerTask;
|
||||||
import 'script.dart' show Script;
|
import 'script.dart' show Script;
|
||||||
import 'serialization/task.dart' show SerializationTask;
|
import 'serialization/task.dart' show SerializationTask;
|
||||||
import 'ssa/nodes.dart' show HInstruction;
|
import 'ssa/nodes.dart' show HInstruction;
|
||||||
import 'tokens/token.dart' show StringToken, Token, TokenPair;
|
import 'package:front_end/src/fasta/scanner.dart'
|
||||||
|
show StringToken, Token;
|
||||||
import 'tokens/token_map.dart' show TokenMap;
|
import 'tokens/token_map.dart' show TokenMap;
|
||||||
import 'tracer.dart' show Tracer;
|
|
||||||
import 'tree/tree.dart' show Node, TypeAnnotation;
|
import 'tree/tree.dart' show Node, TypeAnnotation;
|
||||||
import 'typechecker.dart' show TypeCheckerTask;
|
import 'typechecker.dart' show TypeCheckerTask;
|
||||||
import 'types/types.dart' show GlobalTypeInferenceTask;
|
import 'types/types.dart' show GlobalTypeInferenceTask;
|
||||||
|
@ -80,7 +80,6 @@ import 'universe/world_impact.dart'
|
||||||
show
|
show
|
||||||
ImpactStrategy,
|
ImpactStrategy,
|
||||||
WorldImpact,
|
WorldImpact,
|
||||||
WorldImpactBuilder,
|
|
||||||
WorldImpactBuilderImpl;
|
WorldImpactBuilderImpl;
|
||||||
import 'util/util.dart' show Link, Setlet;
|
import 'util/util.dart' show Link, Setlet;
|
||||||
import 'world.dart' show ClosedWorld, ClosedWorldRefiner, ClosedWorldImpl;
|
import 'world.dart' show ClosedWorld, ClosedWorldRefiner, ClosedWorldImpl;
|
||||||
|
@ -266,7 +265,7 @@ abstract class Compiler implements LibraryLoaderListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
_parsingContext =
|
_parsingContext =
|
||||||
new ParsingContext(reporter, parser, patchParser, backend);
|
new ParsingContext(reporter, parser, scanner, patchParser, backend);
|
||||||
|
|
||||||
tasks.addAll(backend.tasks);
|
tasks.addAll(backend.tasks);
|
||||||
}
|
}
|
||||||
|
@ -1214,9 +1213,6 @@ class _CompilerCommonElements extends CommonElementsMixin {
|
||||||
return _findLibraryMember(library, name, required: required);
|
return _findLibraryMember(library, name, required: required);
|
||||||
}
|
}
|
||||||
|
|
||||||
Element _findRequired(LibraryElement library, String name) =>
|
|
||||||
_findLibraryMember(library, name);
|
|
||||||
|
|
||||||
Element _findLibraryMember(LibraryElement library, String name,
|
Element _findLibraryMember(LibraryElement library, String name,
|
||||||
{bool required: true}) {
|
{bool required: true}) {
|
||||||
// If the script of the library is synthesized, the library does not exist
|
// If the script of the library is synthesized, the library does not exist
|
||||||
|
@ -1398,6 +1394,9 @@ class CompilerDiagnosticReporter extends DiagnosticReporter {
|
||||||
api.Diagnostic.CRASH);
|
api.Diagnostic.CRASH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
SourceSpan spanFromToken(Token token) => spanFromTokens(token, token);
|
||||||
|
|
||||||
SourceSpan spanFromTokens(Token begin, Token end, [Uri uri]) {
|
SourceSpan spanFromTokens(Token begin, Token end, [Uri uri]) {
|
||||||
if (begin == null || end == null) {
|
if (begin == null || end == null) {
|
||||||
// TODO(ahe): We can almost always do better. Often it is only
|
// TODO(ahe): We can almost always do better. Often it is only
|
||||||
|
@ -1546,10 +1545,6 @@ class CompilerDiagnosticReporter extends DiagnosticReporter {
|
||||||
return node;
|
return node;
|
||||||
} else if (node is Node) {
|
} else if (node is Node) {
|
||||||
return spanFromNode(node);
|
return spanFromNode(node);
|
||||||
} else if (node is TokenPair) {
|
|
||||||
return spanFromTokens(node.begin, node.end);
|
|
||||||
} else if (node is Token) {
|
|
||||||
return spanFromTokens(node, node);
|
|
||||||
} else if (node is HInstruction) {
|
} else if (node is HInstruction) {
|
||||||
return spanFromHInstruction(node);
|
return spanFromHInstruction(node);
|
||||||
} else if (node is Element) {
|
} else if (node is Element) {
|
||||||
|
@ -1715,7 +1710,6 @@ class CompilerResolution implements Resolution {
|
||||||
MirrorUsageAnalyzerTask get mirrorUsageAnalyzerTask =>
|
MirrorUsageAnalyzerTask get mirrorUsageAnalyzerTask =>
|
||||||
_compiler.mirrorUsageAnalyzerTask;
|
_compiler.mirrorUsageAnalyzerTask;
|
||||||
|
|
||||||
@override
|
|
||||||
LibraryElement get coreLibrary => _compiler._commonElements.coreLibrary;
|
LibraryElement get coreLibrary => _compiler._commonElements.coreLibrary;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -122,7 +122,6 @@ Future<api.CompilationResult> compile(List<String> argv) {
|
||||||
Uri resolutionOutput = currentDirectory.resolve('out.data');
|
Uri resolutionOutput = currentDirectory.resolve('out.data');
|
||||||
bool allowNativeExtensions = false;
|
bool allowNativeExtensions = false;
|
||||||
bool trustTypeAnnotations = false;
|
bool trustTypeAnnotations = false;
|
||||||
bool trustJSInteropTypeAnnotations = false;
|
|
||||||
bool checkedMode = false;
|
bool checkedMode = false;
|
||||||
List<String> hints = <String>[];
|
List<String> hints = <String>[];
|
||||||
bool verbose;
|
bool verbose;
|
||||||
|
@ -243,7 +242,6 @@ Future<api.CompilationResult> compile(List<String> argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTrustJSInteropTypeAnnotations(String argument) {
|
void setTrustJSInteropTypeAnnotations(String argument) {
|
||||||
trustJSInteropTypeAnnotations = true;
|
|
||||||
implyCompilation(argument);
|
implyCompilation(argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ import 'universe/world_impact.dart'
|
||||||
show ImpactUseCase, WorldImpact, WorldImpactVisitorImpl;
|
show ImpactUseCase, WorldImpact, WorldImpactVisitorImpl;
|
||||||
import 'util/setlet.dart' show Setlet;
|
import 'util/setlet.dart' show Setlet;
|
||||||
import 'util/uri_extras.dart' as uri_extras;
|
import 'util/uri_extras.dart' as uri_extras;
|
||||||
import 'util/util.dart' show Link, makeUnique;
|
import 'util/util.dart' show makeUnique;
|
||||||
|
|
||||||
/// A "hunk" of the program that will be loaded whenever one of its [imports]
|
/// A "hunk" of the program that will be loaded whenever one of its [imports]
|
||||||
/// are loaded.
|
/// are loaded.
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
library dart2js.diagnostic_listener;
|
library dart2js.diagnostic_listener;
|
||||||
|
|
||||||
|
import 'package:front_end/src/fasta/scanner.dart' show Token;
|
||||||
import '../elements/elements.dart' show Element;
|
import '../elements/elements.dart' show Element;
|
||||||
import '../options.dart' show DiagnosticOptions;
|
import '../options.dart' show DiagnosticOptions;
|
||||||
import 'messages.dart';
|
import 'messages.dart';
|
||||||
|
@ -21,11 +22,16 @@ abstract class DiagnosticReporter {
|
||||||
|
|
||||||
/// Creates a [SourceSpan] for [node] in scope of the current element.
|
/// Creates a [SourceSpan] for [node] in scope of the current element.
|
||||||
///
|
///
|
||||||
/// If [node] is a [Node] or [Token] we assert in checked mode that the
|
/// If [node] is a [Node] we assert in checked mode that the corresponding
|
||||||
/// corresponding tokens can be found within the tokens of the current
|
/// tokens can be found within the tokens of the current element.
|
||||||
/// element.
|
|
||||||
SourceSpan spanFromSpannable(Spannable node);
|
SourceSpan spanFromSpannable(Spannable node);
|
||||||
|
|
||||||
|
/// Creates a [SourceSpan] for [token] in scope of the current element.
|
||||||
|
///
|
||||||
|
/// In checked mode we assert that the token can be found within the tokens
|
||||||
|
/// of the current element.
|
||||||
|
SourceSpan spanFromToken(Token token);
|
||||||
|
|
||||||
void reportErrorMessage(Spannable spannable, MessageKind messageKind,
|
void reportErrorMessage(Spannable spannable, MessageKind messageKind,
|
||||||
[Map arguments = const {}]) {
|
[Map arguments = const {}]) {
|
||||||
reportError(createMessage(spannable, messageKind, arguments));
|
reportError(createMessage(spannable, messageKind, arguments));
|
||||||
|
|
|
@ -62,7 +62,8 @@
|
||||||
|
|
||||||
library dart2js.messages;
|
library dart2js.messages;
|
||||||
|
|
||||||
import '../tokens/token.dart' show ErrorToken, Token;
|
import 'package:front_end/src/fasta/scanner.dart'
|
||||||
|
show ErrorToken, Token;
|
||||||
import 'generated/shared_messages.dart' as shared_messages;
|
import 'generated/shared_messages.dart' as shared_messages;
|
||||||
import 'invariant.dart' show invariant;
|
import 'invariant.dart' show invariant;
|
||||||
import 'spannable.dart' show CURRENT_ELEMENT_SPANNABLE;
|
import 'spannable.dart' show CURRENT_ELEMENT_SPANNABLE;
|
||||||
|
@ -3090,7 +3091,9 @@ main() => r\"\"\"
|
||||||
examples: const [
|
examples: const [
|
||||||
"main(",
|
"main(",
|
||||||
"main(){",
|
"main(){",
|
||||||
"main(){]}",
|
"main(){[}",
|
||||||
|
// TODO(ahe): https://github.com/dart-lang/sdk/issues/28495
|
||||||
|
// "main(){]}",
|
||||||
]),
|
]),
|
||||||
|
|
||||||
MessageKind.UNTERMINATED_TOKEN: const MessageTemplate(
|
MessageKind.UNTERMINATED_TOKEN: const MessageTemplate(
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
library dart2js.diagnostics.source_span;
|
library dart2js.diagnostics.source_span;
|
||||||
|
|
||||||
import '../tokens/token.dart' show Token;
|
import 'package:front_end/src/fasta/scanner.dart' show Token;
|
||||||
import '../tree/tree.dart' show Node;
|
import '../tree/tree.dart' show Node;
|
||||||
import 'spannable.dart' show Spannable;
|
import 'spannable.dart' show Spannable;
|
||||||
|
|
||||||
|
|
|
@ -13,11 +13,11 @@ import '../ordered_typeset.dart' show OrderedTypeSet;
|
||||||
import '../resolution/scope.dart' show Scope;
|
import '../resolution/scope.dart' show Scope;
|
||||||
import '../resolution/tree_elements.dart' show TreeElements;
|
import '../resolution/tree_elements.dart' show TreeElements;
|
||||||
import '../script.dart';
|
import '../script.dart';
|
||||||
import '../tokens/token.dart'
|
import 'package:front_end/src/fasta/scanner.dart'
|
||||||
show Token, isUserDefinableOperator, isMinusOperator;
|
show Token, isUserDefinableOperator, isMinusOperator;
|
||||||
import '../tree/tree.dart';
|
import '../tree/tree.dart';
|
||||||
import '../universe/call_structure.dart';
|
import '../universe/call_structure.dart';
|
||||||
import '../util/characters.dart' show $_;
|
import 'package:front_end/src/fasta/scanner/characters.dart' show $_;
|
||||||
import '../util/util.dart';
|
import '../util/util.dart';
|
||||||
import '../world.dart' show ClosedWorld;
|
import '../world.dart' show ClosedWorld;
|
||||||
import 'entities.dart';
|
import 'entities.dart';
|
||||||
|
|
|
@ -20,8 +20,10 @@ import '../resolution/scope.dart'
|
||||||
import '../resolution/tree_elements.dart' show TreeElements;
|
import '../resolution/tree_elements.dart' show TreeElements;
|
||||||
import '../resolution/typedefs.dart' show TypedefCyclicVisitor;
|
import '../resolution/typedefs.dart' show TypedefCyclicVisitor;
|
||||||
import '../script.dart';
|
import '../script.dart';
|
||||||
import '../tokens/token.dart' show ErrorToken, Token;
|
import 'package:front_end/src/fasta/scanner.dart'
|
||||||
import '../tokens/token_constants.dart' as Tokens show EOF_TOKEN;
|
show ErrorToken, Token;
|
||||||
|
import 'package:front_end/src/fasta/scanner.dart' as Tokens
|
||||||
|
show EOF_TOKEN;
|
||||||
import '../tree/tree.dart';
|
import '../tree/tree.dart';
|
||||||
import '../util/util.dart';
|
import '../util/util.dart';
|
||||||
import 'common.dart';
|
import 'common.dart';
|
||||||
|
@ -314,7 +316,6 @@ class ErroneousConstructorElementX extends ErroneousElementX
|
||||||
@override
|
@override
|
||||||
bool isRedirectingGenerativeInternal;
|
bool isRedirectingGenerativeInternal;
|
||||||
|
|
||||||
@override
|
|
||||||
void set isRedirectingGenerative(_) {
|
void set isRedirectingGenerative(_) {
|
||||||
throw new UnsupportedError("isRedirectingGenerative");
|
throw new UnsupportedError("isRedirectingGenerative");
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,6 @@ int _rotl32(int val, int shift) {
|
||||||
// functions.
|
// functions.
|
||||||
abstract class _HashBase implements Hash {
|
abstract class _HashBase implements Hash {
|
||||||
final int _chunkSizeInWords;
|
final int _chunkSizeInWords;
|
||||||
final int _digestSizeInWords;
|
|
||||||
final bool _bigEndianWords;
|
final bool _bigEndianWords;
|
||||||
final List<int> _currentChunk;
|
final List<int> _currentChunk;
|
||||||
final List<int> _h;
|
final List<int> _h;
|
||||||
|
@ -91,8 +90,7 @@ abstract class _HashBase implements Hash {
|
||||||
: _pendingData = [],
|
: _pendingData = [],
|
||||||
_currentChunk = new List(chunkSizeInWords),
|
_currentChunk = new List(chunkSizeInWords),
|
||||||
_h = new List(digestSizeInWords),
|
_h = new List(digestSizeInWords),
|
||||||
_chunkSizeInWords = chunkSizeInWords,
|
_chunkSizeInWords = chunkSizeInWords;
|
||||||
_digestSizeInWords = digestSizeInWords;
|
|
||||||
|
|
||||||
// Update the hasher with more data.
|
// Update the hasher with more data.
|
||||||
void add(List<int> data) {
|
void add(List<int> data) {
|
||||||
|
|
|
@ -102,7 +102,6 @@ StackTraceLines stackTrace({int offset: 1, int limit: null}) {
|
||||||
rangeEnd: rangeEnd,
|
rangeEnd: rangeEnd,
|
||||||
filePrefix: stackTraceFilePrefix);
|
filePrefix: stackTraceFilePrefix);
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A stack trace as a sequence of [StackTraceLine]s.
|
/// A stack trace as a sequence of [StackTraceLine]s.
|
||||||
|
|
|
@ -1215,7 +1215,6 @@ class ElementGraphBuilder extends ast.Visitor<TypeInformation>
|
||||||
(element != null && element.isInstanceMember);
|
(element != null && element.isInstanceMember);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
TypeInformation handleSendSet(ast.SendSet node) {
|
TypeInformation handleSendSet(ast.SendSet node) {
|
||||||
Element element = elements[node];
|
Element element = elements[node];
|
||||||
if (!Elements.isUnresolved(element) && element.impliesType) {
|
if (!Elements.isUnresolved(element) && element.impliesType) {
|
||||||
|
@ -2280,7 +2279,6 @@ class ElementGraphBuilder extends ast.Visitor<TypeInformation>
|
||||||
return inferrer.registerAwait(node, futureType);
|
return inferrer.registerAwait(node, futureType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
TypeInformation handleTypeLiteralInvoke(ast.NodeList arguments) {
|
TypeInformation handleTypeLiteralInvoke(ast.NodeList arguments) {
|
||||||
// This is reached when users forget to put a `new` in front of a type
|
// This is reached when users forget to put a `new` in front of a type
|
||||||
// literal. The emitter will generate an actual call (even though it is
|
// literal. The emitter will generate an actual call (even though it is
|
||||||
|
|
|
@ -6,7 +6,6 @@ library type_graph_inferrer;
|
||||||
|
|
||||||
import 'dart:collection' show Queue;
|
import 'dart:collection' show Queue;
|
||||||
|
|
||||||
import '../common.dart';
|
|
||||||
import '../compiler.dart' show Compiler;
|
import '../compiler.dart' show Compiler;
|
||||||
import '../elements/elements.dart';
|
import '../elements/elements.dart';
|
||||||
import '../tree/tree.dart' as ast show Node;
|
import '../tree/tree.dart' as ast show Node;
|
||||||
|
|
|
@ -12,7 +12,7 @@ import '../diagnostics/messages.dart' show MessageTemplate;
|
||||||
import '../elements/elements.dart' show ResolvedAst, ResolvedAstKind;
|
import '../elements/elements.dart' show ResolvedAst, ResolvedAstKind;
|
||||||
import '../js/js.dart' as js;
|
import '../js/js.dart' as js;
|
||||||
import '../js/js_source_mapping.dart';
|
import '../js/js_source_mapping.dart';
|
||||||
import '../tokens/token.dart' show Token;
|
import 'package:front_end/src/fasta/scanner.dart' show Token;
|
||||||
import '../tree/tree.dart' show Node;
|
import '../tree/tree.dart' show Node;
|
||||||
import 'source_file.dart';
|
import 'source_file.dart';
|
||||||
import 'source_information.dart';
|
import 'source_information.dart';
|
||||||
|
|
|
@ -129,7 +129,6 @@ abstract class ReferenceCountedAstNode implements Node {
|
||||||
/// This is used when generated code needs to be represented as a string,
|
/// This is used when generated code needs to be represented as a string,
|
||||||
/// for example by the lazy emitter or when generating code generators.
|
/// for example by the lazy emitter or when generating code generators.
|
||||||
class UnparsedNode extends DeferredString implements AstContainer {
|
class UnparsedNode extends DeferredString implements AstContainer {
|
||||||
@override
|
|
||||||
final Node tree;
|
final Node tree;
|
||||||
final Compiler _compiler;
|
final Compiler _compiler;
|
||||||
final bool _protectForEval;
|
final bool _protectForEval;
|
||||||
|
|
|
@ -905,7 +905,8 @@ class JavaScriptBackend extends Backend {
|
||||||
if (elements.isEmpty) return false;
|
if (elements.isEmpty) return false;
|
||||||
return elements.any((element) {
|
return elements.any((element) {
|
||||||
return selector.applies(element) &&
|
return selector.applies(element) &&
|
||||||
(mask == null || mask.canHit(element, selector, _closedWorld));
|
(mask == null ||
|
||||||
|
mask.canHit(element as MemberElement, selector, _closedWorld));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -206,8 +206,6 @@ class BackendHelpers {
|
||||||
// TODO(johnniwinther): Split into _findHelperFunction and _findHelperClass
|
// TODO(johnniwinther): Split into _findHelperFunction and _findHelperClass
|
||||||
// and add a check that the element has the expected kind.
|
// and add a check that the element has the expected kind.
|
||||||
Element _findHelper(String name) => _find(jsHelperLibrary, name);
|
Element _findHelper(String name) => _find(jsHelperLibrary, name);
|
||||||
FunctionElement _findHelperFunction(String name) =>
|
|
||||||
_find(jsHelperLibrary, name);
|
|
||||||
Element _findAsyncHelper(String name) => _find(asyncLibrary, name);
|
Element _findAsyncHelper(String name) => _find(asyncLibrary, name);
|
||||||
Element _findInterceptor(String name) => _find(interceptorsLibrary, name);
|
Element _findInterceptor(String name) => _find(interceptorsLibrary, name);
|
||||||
Element _find(LibraryElement library, String name) {
|
Element _find(LibraryElement library, String name) {
|
||||||
|
|
|
@ -12,7 +12,6 @@ import '../elements/elements.dart' show ClassElement, Element;
|
||||||
import '../universe/selector.dart';
|
import '../universe/selector.dart';
|
||||||
import '../util/enumset.dart';
|
import '../util/enumset.dart';
|
||||||
import 'backend_helpers.dart';
|
import 'backend_helpers.dart';
|
||||||
import 'constant_system_javascript.dart';
|
|
||||||
import 'js_backend.dart';
|
import 'js_backend.dart';
|
||||||
|
|
||||||
/// Backend specific features required by a backend impact.
|
/// Backend specific features required by a backend impact.
|
||||||
|
|
|
@ -6,7 +6,6 @@ import '../compiler.dart' show Compiler;
|
||||||
import '../constants/values.dart';
|
import '../constants/values.dart';
|
||||||
import '../elements/resolution_types.dart';
|
import '../elements/resolution_types.dart';
|
||||||
import '../elements/elements.dart';
|
import '../elements/elements.dart';
|
||||||
import '../enqueue.dart' show Enqueuer;
|
|
||||||
import '../universe/use.dart' show StaticUse;
|
import '../universe/use.dart' show StaticUse;
|
||||||
import '../universe/world_impact.dart'
|
import '../universe/world_impact.dart'
|
||||||
show WorldImpact, StagedWorldImpactBuilder;
|
show WorldImpact, StagedWorldImpactBuilder;
|
||||||
|
|
|
@ -17,7 +17,6 @@ import '../constants/values.dart'
|
||||||
NullConstantValue,
|
NullConstantValue,
|
||||||
StringConstantValue,
|
StringConstantValue,
|
||||||
TypeConstantValue;
|
TypeConstantValue;
|
||||||
import '../elements/resolution_types.dart' show ResolutionDartType;
|
|
||||||
import '../elements/resolution_types.dart' show ResolutionInterfaceType;
|
import '../elements/resolution_types.dart' show ResolutionInterfaceType;
|
||||||
import '../elements/elements.dart'
|
import '../elements/elements.dart'
|
||||||
show ClassElement, FieldElement, LibraryElement, VariableElement;
|
show ClassElement, FieldElement, LibraryElement, VariableElement;
|
||||||
|
|
|
@ -317,25 +317,20 @@ class _ConstructorBodyNamingScope {
|
||||||
|
|
||||||
int get numberOfConstructors => _constructors.length;
|
int get numberOfConstructors => _constructors.length;
|
||||||
|
|
||||||
_ConstructorBodyNamingScope _superScope;
|
|
||||||
|
|
||||||
_ConstructorBodyNamingScope.rootScope(ClassElement cls)
|
_ConstructorBodyNamingScope.rootScope(ClassElement cls)
|
||||||
: _superScope = null,
|
: _startIndex = 0,
|
||||||
_startIndex = 0,
|
|
||||||
_constructors = cls.constructors.toList(growable: false);
|
_constructors = cls.constructors.toList(growable: false);
|
||||||
|
|
||||||
_ConstructorBodyNamingScope.forClass(
|
_ConstructorBodyNamingScope.forClass(
|
||||||
ClassElement cls, _ConstructorBodyNamingScope superScope)
|
ClassElement cls, _ConstructorBodyNamingScope superScope)
|
||||||
: _superScope = superScope,
|
: _startIndex = superScope._startIndex + superScope.numberOfConstructors,
|
||||||
_startIndex = superScope._startIndex + superScope.numberOfConstructors,
|
|
||||||
_constructors = cls.constructors.toList(growable: false);
|
_constructors = cls.constructors.toList(growable: false);
|
||||||
|
|
||||||
// Mixin Applications have constructors but we never generate code for them,
|
// Mixin Applications have constructors but we never generate code for them,
|
||||||
// so they do not count in the inheritance chain.
|
// so they do not count in the inheritance chain.
|
||||||
_ConstructorBodyNamingScope.forMixinApplication(
|
_ConstructorBodyNamingScope.forMixinApplication(
|
||||||
ClassElement cls, _ConstructorBodyNamingScope superScope)
|
ClassElement cls, _ConstructorBodyNamingScope superScope)
|
||||||
: _superScope = superScope,
|
: _startIndex = superScope._startIndex + superScope.numberOfConstructors,
|
||||||
_startIndex = superScope._startIndex + superScope.numberOfConstructors,
|
|
||||||
_constructors = const [];
|
_constructors = const [];
|
||||||
|
|
||||||
factory _ConstructorBodyNamingScope(ClassElement cls,
|
factory _ConstructorBodyNamingScope(ClassElement cls,
|
||||||
|
|
|
@ -11,7 +11,6 @@ import 'package:js_runtime/shared/embedded_names.dart' show JsGetName;
|
||||||
import '../closure.dart';
|
import '../closure.dart';
|
||||||
import '../common.dart';
|
import '../common.dart';
|
||||||
import '../common/names.dart' show Identifiers, Selectors;
|
import '../common/names.dart' show Identifiers, Selectors;
|
||||||
import '../compiler.dart' show Compiler;
|
|
||||||
import '../constants/values.dart';
|
import '../constants/values.dart';
|
||||||
import '../core_types.dart' show CommonElements;
|
import '../core_types.dart' show CommonElements;
|
||||||
import '../elements/resolution_types.dart';
|
import '../elements/resolution_types.dart';
|
||||||
|
@ -24,7 +23,7 @@ import '../tree/tree.dart';
|
||||||
import '../universe/call_structure.dart' show CallStructure;
|
import '../universe/call_structure.dart' show CallStructure;
|
||||||
import '../universe/selector.dart' show Selector, SelectorKind;
|
import '../universe/selector.dart' show Selector, SelectorKind;
|
||||||
import '../universe/world_builder.dart' show CodegenWorldBuilder;
|
import '../universe/world_builder.dart' show CodegenWorldBuilder;
|
||||||
import '../util/characters.dart';
|
import 'package:front_end/src/fasta/scanner/characters.dart';
|
||||||
import '../util/util.dart';
|
import '../util/util.dart';
|
||||||
import '../world.dart' show ClosedWorld;
|
import '../world.dart' show ClosedWorld;
|
||||||
import 'backend.dart';
|
import 'backend.dart';
|
||||||
|
|
|
@ -589,7 +589,6 @@ class _RuntimeTypes implements RuntimeTypes {
|
||||||
|
|
||||||
class _RuntimeTypesEncoder implements RuntimeTypesEncoder {
|
class _RuntimeTypesEncoder implements RuntimeTypesEncoder {
|
||||||
final Compiler compiler;
|
final Compiler compiler;
|
||||||
@override
|
|
||||||
final TypeRepresentationGenerator representationGenerator;
|
final TypeRepresentationGenerator representationGenerator;
|
||||||
|
|
||||||
_RuntimeTypesEncoder(Compiler compiler)
|
_RuntimeTypesEncoder(Compiler compiler)
|
||||||
|
|
|
@ -8,12 +8,10 @@ import '../constants/expressions.dart';
|
||||||
import '../constants/values.dart';
|
import '../constants/values.dart';
|
||||||
import '../elements/resolution_types.dart';
|
import '../elements/resolution_types.dart';
|
||||||
import '../elements/elements.dart';
|
import '../elements/elements.dart';
|
||||||
import '../enqueue.dart' show Enqueuer;
|
|
||||||
import '../js/js.dart' as jsAst;
|
import '../js/js.dart' as jsAst;
|
||||||
import '../js_emitter/js_emitter.dart'
|
import '../js_emitter/js_emitter.dart'
|
||||||
show CodeEmitterTask, MetadataCollector, Placeholder;
|
show CodeEmitterTask, MetadataCollector, Placeholder;
|
||||||
import '../universe/call_structure.dart' show CallStructure;
|
import '../universe/call_structure.dart' show CallStructure;
|
||||||
import '../universe/use.dart' show StaticUse;
|
|
||||||
import '../universe/world_impact.dart';
|
import '../universe/world_impact.dart';
|
||||||
import '../util/util.dart';
|
import '../util/util.dart';
|
||||||
import 'backend.dart';
|
import 'backend.dart';
|
||||||
|
@ -101,7 +99,6 @@ class TypeVariableHandler {
|
||||||
// Do not process classes twice.
|
// Do not process classes twice.
|
||||||
if (_typeVariables.containsKey(cls)) return;
|
if (_typeVariables.containsKey(cls)) return;
|
||||||
|
|
||||||
ResolutionInterfaceType typeVariableType = _typeVariableClass.thisType;
|
|
||||||
List<jsAst.Expression> constants = <jsAst.Expression>[];
|
List<jsAst.Expression> constants = <jsAst.Expression>[];
|
||||||
|
|
||||||
for (ResolutionTypeVariableType currentTypeVariable in cls.typeVariables) {
|
for (ResolutionTypeVariableType currentTypeVariable in cls.typeVariables) {
|
||||||
|
@ -111,8 +108,6 @@ class TypeVariableHandler {
|
||||||
_metadataCollector.reifyType(typeVariableElement.bound);
|
_metadataCollector.reifyType(typeVariableElement.bound);
|
||||||
ConstantValue boundValue = new SyntheticConstantValue(
|
ConstantValue boundValue = new SyntheticConstantValue(
|
||||||
SyntheticConstantKind.TYPEVARIABLE_REFERENCE, boundIndex);
|
SyntheticConstantKind.TYPEVARIABLE_REFERENCE, boundIndex);
|
||||||
ConstantExpression boundExpression =
|
|
||||||
new SyntheticConstantExpression(boundValue);
|
|
||||||
ConstantExpression constant = new ConstructedConstantExpression(
|
ConstantExpression constant = new ConstructedConstantExpression(
|
||||||
_typeVariableConstructor.enclosingClass.thisType,
|
_typeVariableConstructor.enclosingClass.thisType,
|
||||||
_typeVariableConstructor,
|
_typeVariableConstructor,
|
||||||
|
|
|
@ -9,7 +9,8 @@ import '../../js/js.dart' as jsAst;
|
||||||
import '../../js/js.dart' show js;
|
import '../../js/js.dart' show js;
|
||||||
import '../../js_backend/js_backend.dart' show GetterName, SetterName;
|
import '../../js_backend/js_backend.dart' show GetterName, SetterName;
|
||||||
import '../../universe/selector.dart' show Selector;
|
import '../../universe/selector.dart' show Selector;
|
||||||
import '../../util/characters.dart' show $$, $A, $HASH, $Z, $a, $z;
|
import 'package:front_end/src/fasta/scanner/characters.dart'
|
||||||
|
show $$, $A, $HASH, $Z, $a, $z;
|
||||||
import '../../world.dart' show ClosedWorld;
|
import '../../world.dart' show ClosedWorld;
|
||||||
import '../js_emitter.dart' hide Emitter, EmitterFactory;
|
import '../js_emitter.dart' hide Emitter, EmitterFactory;
|
||||||
import '../model.dart';
|
import '../model.dart';
|
||||||
|
|
|
@ -281,7 +281,6 @@ class Collector {
|
||||||
}
|
}
|
||||||
|
|
||||||
void computeNeededStaticNonFinalFields() {
|
void computeNeededStaticNonFinalFields() {
|
||||||
JavaScriptConstantCompiler handler = backend.constants;
|
|
||||||
addToOutputUnit(Element element) {
|
addToOutputUnit(Element element) {
|
||||||
List<VariableElement> list = outputStaticNonFinalFieldLists.putIfAbsent(
|
List<VariableElement> list = outputStaticNonFinalFieldLists.putIfAbsent(
|
||||||
compiler.deferredLoadTask.outputUnitForElement(element),
|
compiler.deferredLoadTask.outputUnitForElement(element),
|
||||||
|
|
|
@ -183,7 +183,7 @@ class ProgramBuilder {
|
||||||
List<js.TokenFinalizer> finalizers = [_task.metadataCollector];
|
List<js.TokenFinalizer> finalizers = [_task.metadataCollector];
|
||||||
if (backend.namer is js.TokenFinalizer) {
|
if (backend.namer is js.TokenFinalizer) {
|
||||||
var namingFinalizer = backend.namer;
|
var namingFinalizer = backend.namer;
|
||||||
finalizers.add(namingFinalizer);
|
finalizers.add(namingFinalizer as js.TokenFinalizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Program(fragments, holders, _buildLoadMap(), _symbolsMap,
|
return new Program(fragments, holders, _buildLoadMap(), _symbolsMap,
|
||||||
|
|
|
@ -1037,11 +1037,8 @@ class KernelVisitor extends Object
|
||||||
}
|
}
|
||||||
ir.SwitchCase irCase = casesIterator.current;
|
ir.SwitchCase irCase = casesIterator.current;
|
||||||
List<ir.Statement> statements = <ir.Statement>[];
|
List<ir.Statement> statements = <ir.Statement>[];
|
||||||
bool hasVariableDeclaration = false;
|
|
||||||
for (Statement statement in caseNode.statements.nodes) {
|
for (Statement statement in caseNode.statements.nodes) {
|
||||||
if (buildStatement(statement, statements)) {
|
buildStatement(statement, statements);
|
||||||
hasVariableDeclaration = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (statements.isEmpty || fallsThrough(statements.last)) {
|
if (statements.isEmpty || fallsThrough(statements.last)) {
|
||||||
if (isLastCase) {
|
if (isLastCase) {
|
||||||
|
@ -2116,7 +2113,6 @@ class KernelVisitor extends Object
|
||||||
// [body] must be `null`.
|
// [body] must be `null`.
|
||||||
} else if (function.isConstructor) {
|
} else if (function.isConstructor) {
|
||||||
// TODO(johnniwinther): Clean this up pending kernel issue #28.
|
// TODO(johnniwinther): Clean this up pending kernel issue #28.
|
||||||
ConstructorElement constructor = function;
|
|
||||||
if (bodyNode == null || bodyNode.asEmptyStatement() != null) {
|
if (bodyNode == null || bodyNode.asEmptyStatement() != null) {
|
||||||
body = new ir.EmptyStatement();
|
body = new ir.EmptyStatement();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:collection' show Queue;
|
|
||||||
|
|
||||||
import '../common.dart';
|
import '../common.dart';
|
||||||
import '../common/backend_api.dart' show ForeignResolver;
|
import '../common/backend_api.dart' show ForeignResolver;
|
||||||
import '../common/resolution.dart' show Resolution;
|
import '../common/resolution.dart' show Resolution;
|
||||||
|
@ -17,8 +15,10 @@ import '../elements/resolution_types.dart';
|
||||||
import '../js_backend/backend_helpers.dart' show BackendHelpers;
|
import '../js_backend/backend_helpers.dart' show BackendHelpers;
|
||||||
import '../js_backend/js_backend.dart';
|
import '../js_backend/js_backend.dart';
|
||||||
import '../js_emitter/js_emitter.dart' show CodeEmitterTask, NativeEmitter;
|
import '../js_emitter/js_emitter.dart' show CodeEmitterTask, NativeEmitter;
|
||||||
import '../tokens/token.dart' show BeginGroupToken, Token;
|
import 'package:front_end/src/fasta/scanner.dart'
|
||||||
import '../tokens/token_constants.dart' as Tokens show EOF_TOKEN;
|
show BeginGroupToken, Token;
|
||||||
|
import 'package:front_end/src/fasta/scanner.dart' as Tokens
|
||||||
|
show EOF_TOKEN;
|
||||||
import '../tree/tree.dart';
|
import '../tree/tree.dart';
|
||||||
import '../universe/use.dart' show StaticUse, TypeUse;
|
import '../universe/use.dart' show StaticUse, TypeUse;
|
||||||
import '../universe/world_impact.dart'
|
import '../universe/world_impact.dart'
|
||||||
|
|
|
@ -4,12 +4,14 @@
|
||||||
|
|
||||||
import '../common.dart';
|
import '../common.dart';
|
||||||
import '../parser/element_listener.dart' show ElementListener;
|
import '../parser/element_listener.dart' show ElementListener;
|
||||||
import '../tokens/token.dart' show BeginGroupToken, Token;
|
import 'package:front_end/src/fasta/scanner.dart'
|
||||||
import '../tokens/token_constants.dart' as Tokens show STRING_TOKEN;
|
show BeginGroupToken, Token;
|
||||||
|
import 'package:front_end/src/fasta/scanner/token_constants.dart' as Tokens
|
||||||
|
show STRING_TOKEN;
|
||||||
|
|
||||||
void checkAllowedLibrary(ElementListener listener, Token token) {
|
void checkAllowedLibrary(ElementListener listener, Token token) {
|
||||||
if (listener.scannerOptions.canUseNative) return;
|
if (listener.scannerOptions.canUseNative) return;
|
||||||
listener.reportError(token, MessageKind.NATIVE_NOT_SUPPORTED);
|
listener.reportErrorFromToken(token, MessageKind.NATIVE_NOT_SUPPORTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
Token handleNativeBlockToSkip(ElementListener listener, Token token) {
|
Token handleNativeBlockToSkip(ElementListener listener, Token token) {
|
||||||
|
|
|
@ -9,7 +9,8 @@ import 'elements/resolution_types.dart';
|
||||||
import 'diagnostics/diagnostic_listener.dart' show DiagnosticReporter;
|
import 'diagnostics/diagnostic_listener.dart' show DiagnosticReporter;
|
||||||
import 'elements/elements.dart' show ClassElement;
|
import 'elements/elements.dart' show ClassElement;
|
||||||
import 'util/util.dart' show Link, LinkBuilder;
|
import 'util/util.dart' show Link, LinkBuilder;
|
||||||
import 'util/util_implementation.dart' show LinkEntry;
|
import 'package:front_end/src/fasta/util/link_implementation.dart'
|
||||||
|
show LinkEntry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An ordered set of the supertypes of a class. The supertypes of a class are
|
* An ordered set of the supertypes of a class. The supertypes of a class are
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
// Copyright (c) 2011, 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.parser.classes;
|
|
||||||
|
|
||||||
import '../tokens/token.dart' show Token;
|
|
||||||
import 'listener.dart' show Listener;
|
|
||||||
import 'partial_parser.dart' show PartialParser;
|
|
||||||
|
|
||||||
class ClassElementParser extends PartialParser {
|
|
||||||
ClassElementParser(Listener listener) : super(listener);
|
|
||||||
|
|
||||||
Token parseClassBody(Token token) => fullParseClassBody(token);
|
|
||||||
}
|
|
|
@ -9,10 +9,17 @@ import '../common/backend_api.dart' show Backend;
|
||||||
import '../common/tasks.dart' show CompilerTask, Measurer;
|
import '../common/tasks.dart' show CompilerTask, Measurer;
|
||||||
import '../elements/elements.dart' show CompilationUnitElement;
|
import '../elements/elements.dart' show CompilationUnitElement;
|
||||||
import '../id_generator.dart';
|
import '../id_generator.dart';
|
||||||
import '../tokens/token.dart' show Token;
|
import 'package:front_end/src/fasta/scanner.dart' show Token;
|
||||||
import 'element_listener.dart' show ElementListener, ScannerOptions;
|
import 'element_listener.dart' show ElementListener, ScannerOptions;
|
||||||
import 'listener.dart' show ParserError;
|
import 'package:front_end/src/fasta/parser.dart'
|
||||||
import 'partial_parser.dart' show PartialParser;
|
show Listener, ParserError, TopLevelParser;
|
||||||
|
|
||||||
|
class PartialParser extends TopLevelParser {
|
||||||
|
PartialParser(Listener listener)
|
||||||
|
: super(listener);
|
||||||
|
|
||||||
|
Token parseFormalParameters(Token token) => skipFormalParameters(token);
|
||||||
|
}
|
||||||
|
|
||||||
class DietParserTask extends CompilerTask {
|
class DietParserTask extends CompilerTask {
|
||||||
final IdGenerator _idGenerator;
|
final IdGenerator _idGenerator;
|
||||||
|
|
|
@ -22,14 +22,16 @@ import '../elements/modelx.dart'
|
||||||
import '../id_generator.dart';
|
import '../id_generator.dart';
|
||||||
import '../native/native.dart' as native;
|
import '../native/native.dart' as native;
|
||||||
import '../string_validator.dart' show StringValidator;
|
import '../string_validator.dart' show StringValidator;
|
||||||
import '../tokens/keyword.dart' show Keyword;
|
import 'package:front_end/src/fasta/scanner.dart'
|
||||||
import '../tokens/precedence_constants.dart' as Precedence show BAD_INPUT_INFO;
|
show Keyword, BeginGroupToken, ErrorToken, KeywordToken, StringToken, Token;
|
||||||
import '../tokens/token.dart'
|
import 'package:front_end/src/fasta/scanner.dart' as Tokens
|
||||||
show BeginGroupToken, ErrorToken, KeywordToken, Token;
|
show EOF_TOKEN;
|
||||||
import '../tokens/token_constants.dart' as Tokens show EOF_TOKEN;
|
import 'package:front_end/src/fasta/scanner/precedence.dart' as Precedence show
|
||||||
|
BAD_INPUT_INFO, IDENTIFIER_INFO;
|
||||||
import '../tree/tree.dart';
|
import '../tree/tree.dart';
|
||||||
import '../util/util.dart' show Link, LinkBuilder;
|
import '../util/util.dart' show Link, LinkBuilder;
|
||||||
import 'listener.dart' show closeBraceFor, Listener, ParserError, VERBOSE;
|
import 'package:front_end/src/fasta/parser.dart'
|
||||||
|
show ErrorKind, Listener, ParserError, optional;
|
||||||
import 'partial_elements.dart'
|
import 'partial_elements.dart'
|
||||||
show
|
show
|
||||||
PartialClassElement,
|
PartialClassElement,
|
||||||
|
@ -39,6 +41,8 @@ import 'partial_elements.dart'
|
||||||
PartialMetadataAnnotation,
|
PartialMetadataAnnotation,
|
||||||
PartialTypedefElement;
|
PartialTypedefElement;
|
||||||
|
|
||||||
|
const bool VERBOSE = false;
|
||||||
|
|
||||||
/// Options used for scanning.
|
/// Options used for scanning.
|
||||||
///
|
///
|
||||||
/// Use this to conditionally support special tokens.
|
/// Use this to conditionally support special tokens.
|
||||||
|
@ -82,6 +86,10 @@ class ElementListener extends Listener {
|
||||||
|
|
||||||
bool suppressParseErrors = false;
|
bool suppressParseErrors = false;
|
||||||
|
|
||||||
|
/// Set to true each time we parse a native function body. It is reset in
|
||||||
|
/// [handleInvalidFunctionBody] which is called immediately after.
|
||||||
|
bool lastErrorWasNativeFunctionBody = false;
|
||||||
|
|
||||||
ElementListener(this.scannerOptions, DiagnosticReporter reporter,
|
ElementListener(this.scannerOptions, DiagnosticReporter reporter,
|
||||||
this.compilationUnitElement, this.idGenerator)
|
this.compilationUnitElement, this.idGenerator)
|
||||||
: this.reporter = reporter,
|
: this.reporter = reporter,
|
||||||
|
@ -121,12 +129,14 @@ class ElementListener extends Listener {
|
||||||
library.entryCompilationUnit == compilationUnitElement;
|
library.entryCompilationUnit == compilationUnitElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endLibraryName(Token libraryKeyword, Token semicolon) {
|
void endLibraryName(Token libraryKeyword, Token semicolon) {
|
||||||
Expression name = popNode();
|
Expression name = popNode();
|
||||||
addLibraryTag(new LibraryName(
|
addLibraryTag(new LibraryName(
|
||||||
libraryKeyword, name, popMetadata(compilationUnitElement)));
|
libraryKeyword, name, popMetadata(compilationUnitElement)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endImport(Token importKeyword, Token deferredKeyword, Token asKeyword,
|
void endImport(Token importKeyword, Token deferredKeyword, Token asKeyword,
|
||||||
Token semicolon) {
|
Token semicolon) {
|
||||||
NodeList combinators = popNode();
|
NodeList combinators = popNode();
|
||||||
|
@ -142,11 +152,13 @@ class ElementListener extends Listener {
|
||||||
isDeferred: isDeferred));
|
isDeferred: isDeferred));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endDottedName(int count, Token token) {
|
void endDottedName(int count, Token token) {
|
||||||
NodeList identifiers = makeNodeList(count, null, null, '.');
|
NodeList identifiers = makeNodeList(count, null, null, '.');
|
||||||
pushNode(new DottedName(token, identifiers));
|
pushNode(new DottedName(token, identifiers));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endConditionalUris(int count) {
|
void endConditionalUris(int count) {
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
pushNode(null);
|
pushNode(null);
|
||||||
|
@ -155,6 +167,7 @@ class ElementListener extends Listener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endConditionalUri(Token ifToken, Token equalSign) {
|
void endConditionalUri(Token ifToken, Token equalSign) {
|
||||||
StringNode uri = popNode();
|
StringNode uri = popNode();
|
||||||
LiteralString conditionValue = (equalSign != null) ? popNode() : null;
|
LiteralString conditionValue = (equalSign != null) ? popNode() : null;
|
||||||
|
@ -162,6 +175,7 @@ class ElementListener extends Listener {
|
||||||
pushNode(new ConditionalUri(ifToken, identifier, conditionValue, uri));
|
pushNode(new ConditionalUri(ifToken, identifier, conditionValue, uri));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endEnum(Token enumKeyword, Token endBrace, int count) {
|
void endEnum(Token enumKeyword, Token endBrace, int count) {
|
||||||
NodeList names = makeNodeList(count, enumKeyword.next.next, endBrace, ",");
|
NodeList names = makeNodeList(count, enumKeyword.next.next, endBrace, ",");
|
||||||
Identifier name = popNode();
|
Identifier name = popNode();
|
||||||
|
@ -173,6 +187,7 @@ class ElementListener extends Listener {
|
||||||
rejectBuiltInIdentifier(name);
|
rejectBuiltInIdentifier(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endExport(Token exportKeyword, Token semicolon) {
|
void endExport(Token exportKeyword, Token semicolon) {
|
||||||
NodeList combinators = popNode();
|
NodeList combinators = popNode();
|
||||||
NodeList conditionalUris = popNode();
|
NodeList conditionalUris = popNode();
|
||||||
|
@ -181,6 +196,7 @@ class ElementListener extends Listener {
|
||||||
popMetadata(compilationUnitElement)));
|
popMetadata(compilationUnitElement)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endCombinators(int count) {
|
void endCombinators(int count) {
|
||||||
if (0 == count) {
|
if (0 == count) {
|
||||||
pushNode(null);
|
pushNode(null);
|
||||||
|
@ -189,8 +205,10 @@ class ElementListener extends Listener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endHide(Token hideKeyword) => pushCombinator(hideKeyword);
|
void endHide(Token hideKeyword) => pushCombinator(hideKeyword);
|
||||||
|
|
||||||
|
@override
|
||||||
void endShow(Token showKeyword) => pushCombinator(showKeyword);
|
void endShow(Token showKeyword) => pushCombinator(showKeyword);
|
||||||
|
|
||||||
void pushCombinator(Token keywordToken) {
|
void pushCombinator(Token keywordToken) {
|
||||||
|
@ -198,20 +216,24 @@ class ElementListener extends Listener {
|
||||||
pushNode(new Combinator(identifiers, keywordToken));
|
pushNode(new Combinator(identifiers, keywordToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endIdentifierList(int count) {
|
void endIdentifierList(int count) {
|
||||||
pushNode(makeNodeList(count, null, null, ","));
|
pushNode(makeNodeList(count, null, null, ","));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endTypeList(int count) {
|
void endTypeList(int count) {
|
||||||
pushNode(makeNodeList(count, null, null, ","));
|
pushNode(makeNodeList(count, null, null, ","));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endPart(Token partKeyword, Token semicolon) {
|
void endPart(Token partKeyword, Token semicolon) {
|
||||||
StringNode uri = popLiteralString();
|
StringNode uri = popLiteralString();
|
||||||
addLibraryTag(
|
addLibraryTag(
|
||||||
new Part(partKeyword, uri, popMetadata(compilationUnitElement)));
|
new Part(partKeyword, uri, popMetadata(compilationUnitElement)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endPartOf(Token partKeyword, Token semicolon) {
|
void endPartOf(Token partKeyword, Token semicolon) {
|
||||||
Expression name = popNode();
|
Expression name = popNode();
|
||||||
addPartOfTag(
|
addPartOfTag(
|
||||||
|
@ -222,6 +244,7 @@ class ElementListener extends Listener {
|
||||||
compilationUnitElement.setPartOf(tag, reporter);
|
compilationUnitElement.setPartOf(tag, reporter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
|
void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
|
||||||
if (periodBeforeName != null) {
|
if (periodBeforeName != null) {
|
||||||
popNode(); // Discard name.
|
popNode(); // Discard name.
|
||||||
|
@ -230,14 +253,17 @@ class ElementListener extends Listener {
|
||||||
pushMetadata(new PartialMetadataAnnotation(beginToken, endToken));
|
pushMetadata(new PartialMetadataAnnotation(beginToken, endToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endTopLevelDeclaration(Token token) {
|
void endTopLevelDeclaration(Token token) {
|
||||||
if (!metadata.isEmpty) {
|
if (!metadata.isEmpty) {
|
||||||
MetadataAnnotationX first = metadata.first;
|
MetadataAnnotationX first = metadata.first;
|
||||||
recoverableError(first.beginToken, 'Metadata not supported here.');
|
recoverableError(reporter.spanFromToken(first.beginToken),
|
||||||
|
'Metadata not supported here.');
|
||||||
metadata.clear();
|
metadata.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endClassDeclaration(int interfacesCount, Token beginToken,
|
void endClassDeclaration(int interfacesCount, Token beginToken,
|
||||||
Token extendsKeyword, Token implementsKeyword, Token endToken) {
|
Token extendsKeyword, Token implementsKeyword, Token endToken) {
|
||||||
makeNodeList(interfacesCount, implementsKeyword, null, ","); // interfaces
|
makeNodeList(interfacesCount, implementsKeyword, null, ","); // interfaces
|
||||||
|
@ -260,6 +286,7 @@ class ElementListener extends Listener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endFunctionTypeAlias(Token typedefKeyword, Token endToken) {
|
void endFunctionTypeAlias(Token typedefKeyword, Token endToken) {
|
||||||
popNode(); // TODO(karlklose): do not throw away typeVariables.
|
popNode(); // TODO(karlklose): do not throw away typeVariables.
|
||||||
Identifier name = popNode();
|
Identifier name = popNode();
|
||||||
|
@ -269,6 +296,7 @@ class ElementListener extends Listener {
|
||||||
rejectBuiltInIdentifier(name);
|
rejectBuiltInIdentifier(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endNamedMixinApplication(
|
void endNamedMixinApplication(
|
||||||
Token classKeyword, Token implementsKeyword, Token endToken) {
|
Token classKeyword, Token implementsKeyword, Token endToken) {
|
||||||
NodeList interfaces = (implementsKeyword != null) ? popNode() : null;
|
NodeList interfaces = (implementsKeyword != null) ? popNode() : null;
|
||||||
|
@ -292,16 +320,19 @@ class ElementListener extends Listener {
|
||||||
rejectBuiltInIdentifier(name);
|
rejectBuiltInIdentifier(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endMixinApplication() {
|
void endMixinApplication() {
|
||||||
NodeList mixins = popNode();
|
NodeList mixins = popNode();
|
||||||
TypeAnnotation superclass = popNode();
|
TypeAnnotation superclass = popNode();
|
||||||
pushNode(new MixinApplication(superclass, mixins));
|
pushNode(new MixinApplication(superclass, mixins));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleVoidKeyword(Token token) {
|
void handleVoidKeyword(Token token) {
|
||||||
pushNode(new TypeAnnotation(new Identifier(token), null));
|
pushNode(new TypeAnnotation(new Identifier(token), null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
|
void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
|
||||||
bool hasParseError = currentMemberHasParseError;
|
bool hasParseError = currentMemberHasParseError;
|
||||||
memberErrors = memberErrors.tail;
|
memberErrors = memberErrors.tail;
|
||||||
|
@ -315,6 +346,7 @@ class ElementListener extends Listener {
|
||||||
pushElement(element);
|
pushElement(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endTopLevelFields(int count, Token beginToken, Token endToken) {
|
void endTopLevelFields(int count, Token beginToken, Token endToken) {
|
||||||
bool hasParseError = currentMemberHasParseError;
|
bool hasParseError = currentMemberHasParseError;
|
||||||
memberErrors = memberErrors.tail;
|
memberErrors = memberErrors.tail;
|
||||||
|
@ -351,20 +383,24 @@ class ElementListener extends Listener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleIdentifier(Token token) {
|
void handleIdentifier(Token token) {
|
||||||
pushNode(new Identifier(token));
|
pushNode(new Identifier(token));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleQualified(Token period) {
|
void handleQualified(Token period) {
|
||||||
Identifier last = popNode();
|
Identifier last = popNode();
|
||||||
Expression first = popNode();
|
Expression first = popNode();
|
||||||
pushNode(new Send(first, last));
|
pushNode(new Send(first, last));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleNoType(Token token) {
|
void handleNoType(Token token) {
|
||||||
pushNode(null);
|
pushNode(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endTypeVariable(Token token, Token extendsOrSuper) {
|
void endTypeVariable(Token token, Token extendsOrSuper) {
|
||||||
TypeAnnotation bound = popNode();
|
TypeAnnotation bound = popNode();
|
||||||
Identifier name = popNode();
|
Identifier name = popNode();
|
||||||
|
@ -372,37 +408,45 @@ class ElementListener extends Listener {
|
||||||
rejectBuiltInIdentifier(name);
|
rejectBuiltInIdentifier(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endTypeVariables(int count, Token beginToken, Token endToken) {
|
void endTypeVariables(int count, Token beginToken, Token endToken) {
|
||||||
pushNode(makeNodeList(count, beginToken, endToken, ','));
|
pushNode(makeNodeList(count, beginToken, endToken, ','));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleNoTypeVariables(Token token) {
|
void handleNoTypeVariables(Token token) {
|
||||||
pushNode(null);
|
pushNode(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endTypeArguments(int count, Token beginToken, Token endToken) {
|
void endTypeArguments(int count, Token beginToken, Token endToken) {
|
||||||
pushNode(makeNodeList(count, beginToken, endToken, ','));
|
pushNode(makeNodeList(count, beginToken, endToken, ','));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleNoTypeArguments(Token token) {
|
void handleNoTypeArguments(Token token) {
|
||||||
pushNode(null);
|
pushNode(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endType(Token beginToken, Token endToken) {
|
void endType(Token beginToken, Token endToken) {
|
||||||
NodeList typeArguments = popNode();
|
NodeList typeArguments = popNode();
|
||||||
Expression typeName = popNode();
|
Expression typeName = popNode();
|
||||||
pushNode(new TypeAnnotation(typeName, typeArguments));
|
pushNode(new TypeAnnotation(typeName, typeArguments));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleParenthesizedExpression(BeginGroupToken token) {
|
void handleParenthesizedExpression(BeginGroupToken token) {
|
||||||
Expression expression = popNode();
|
Expression expression = popNode();
|
||||||
pushNode(new ParenthesizedExpression(expression, token));
|
pushNode(new ParenthesizedExpression(expression, token));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleModifier(Token token) {
|
void handleModifier(Token token) {
|
||||||
pushNode(new Identifier(token));
|
pushNode(new Identifier(token));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleModifiers(int count) {
|
void handleModifiers(int count) {
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
pushNode(Modifiers.EMPTY);
|
pushNode(Modifiers.EMPTY);
|
||||||
|
@ -412,29 +456,234 @@ class ElementListener extends Listener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Token expected(String string, Token token) {
|
@override
|
||||||
if (token is ErrorToken) {
|
Token handleUnrecoverableError(Token token, ErrorKind kind, Map arguments) {
|
||||||
reportErrorToken(token);
|
Token next = handleError(token, kind, arguments);
|
||||||
} else if (identical(';', string)) {
|
if (next == null &&
|
||||||
// When a semicolon is missing, it often leads to an error on the
|
kind != ErrorKind.UnterminatedComment &&
|
||||||
// following line. So we try to find the token preceding the semicolon
|
kind != ErrorKind.UnterminatedString) {
|
||||||
// and report that something is missing *after* it.
|
throw new ParserError.fromTokens(token, token, kind, arguments);
|
||||||
Token preceding = findPrecedingToken(token);
|
|
||||||
if (preceding == token) {
|
|
||||||
reportError(
|
|
||||||
token, MessageKind.MISSING_TOKEN_BEFORE_THIS, {'token': string});
|
|
||||||
} else {
|
|
||||||
reportError(
|
|
||||||
preceding, MessageKind.MISSING_TOKEN_AFTER_THIS, {'token': string});
|
|
||||||
}
|
|
||||||
return token;
|
|
||||||
} else {
|
} else {
|
||||||
reportFatalError(
|
return next;
|
||||||
token,
|
|
||||||
MessageTemplate.TEMPLATES[MessageKind.MISSING_TOKEN_BEFORE_THIS]
|
|
||||||
.message({'token': string}, true).toString());
|
|
||||||
}
|
}
|
||||||
return skipToEof(token);
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void handleRecoverableError(Token token, ErrorKind kind, Map arguments) {
|
||||||
|
handleError(token, kind, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void handleInvalidExpression(Token token) {
|
||||||
|
pushNode(new ErrorExpression(token));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void handleInvalidFunctionBody(Token token) {
|
||||||
|
lastErrorWasNativeFunctionBody = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void handleInvalidTypeReference(Token token) {
|
||||||
|
pushNode(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
Token handleError(Token token, ErrorKind kind, Map arguments) {
|
||||||
|
MessageKind errorCode;
|
||||||
|
|
||||||
|
switch (kind) {
|
||||||
|
case ErrorKind.ExpectedButGot:
|
||||||
|
String expected = arguments["expected"];
|
||||||
|
if (identical(";", expected)) {
|
||||||
|
// When a semicolon is missing, it often leads to an error on the
|
||||||
|
// following line. So we try to find the token preceding the semicolon
|
||||||
|
// and report that something is missing *after* it.
|
||||||
|
Token preceding = findPrecedingToken(token);
|
||||||
|
if (preceding == token) {
|
||||||
|
reportErrorFromToken(
|
||||||
|
token, MessageKind.MISSING_TOKEN_BEFORE_THIS,
|
||||||
|
{'token': expected});
|
||||||
|
} else {
|
||||||
|
reportErrorFromToken(
|
||||||
|
preceding, MessageKind.MISSING_TOKEN_AFTER_THIS,
|
||||||
|
{'token': expected});
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
} else {
|
||||||
|
reportFatalError(
|
||||||
|
reporter.spanFromToken(token),
|
||||||
|
MessageTemplate.TEMPLATES[MessageKind.MISSING_TOKEN_BEFORE_THIS]
|
||||||
|
.message({'token': expected}, true).toString());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.ExpectedIdentifier:
|
||||||
|
if (token is KeywordToken) {
|
||||||
|
reportErrorFromToken(token,
|
||||||
|
MessageKind.EXPECTED_IDENTIFIER_NOT_RESERVED_WORD,
|
||||||
|
{'keyword': token.value});
|
||||||
|
} else if (token is ErrorToken) {
|
||||||
|
// TODO(ahe): This is dead code.
|
||||||
|
return synthesizeIdentifier(token);
|
||||||
|
} else {
|
||||||
|
reportFatalError(reporter.spanFromToken(token),
|
||||||
|
"Expected identifier, but got '${token.value}'.");
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
|
||||||
|
case ErrorKind.ExpectedType:
|
||||||
|
reportFatalError(reporter.spanFromToken(token),
|
||||||
|
"Expected a type, but got '${token.value}'.");
|
||||||
|
return null;
|
||||||
|
|
||||||
|
case ErrorKind.ExpectedExpression:
|
||||||
|
reportFatalError(
|
||||||
|
reporter.spanFromToken(token),
|
||||||
|
"Expected an expression, but got '${token.value}'.");
|
||||||
|
return null;
|
||||||
|
|
||||||
|
case ErrorKind.UnexpectedToken:
|
||||||
|
String message = "Unexpected token '${token.value}'.";
|
||||||
|
if (token.info == Precedence.BAD_INPUT_INFO) {
|
||||||
|
message = token.value;
|
||||||
|
}
|
||||||
|
reportFatalError(reporter.spanFromToken(token), message);
|
||||||
|
return null;
|
||||||
|
|
||||||
|
case ErrorKind.ExpectedBlockToSkip:
|
||||||
|
if (optional("native", token)) {
|
||||||
|
return native.handleNativeBlockToSkip(this, token);
|
||||||
|
} else {
|
||||||
|
errorCode = MessageKind.BODY_EXPECTED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.ExpectedFunctionBody:
|
||||||
|
if (optional("native", token)) {
|
||||||
|
lastErrorWasNativeFunctionBody = true;
|
||||||
|
return native.handleNativeFunctionBody(this, token);
|
||||||
|
} else {
|
||||||
|
reportFatalError(
|
||||||
|
reporter.spanFromToken(token),
|
||||||
|
"Expected a function body, but got '${token.value}'.");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
|
||||||
|
case ErrorKind.ExpectedClassBodyToSkip:
|
||||||
|
case ErrorKind.ExpectedClassBody:
|
||||||
|
reportFatalError(
|
||||||
|
reporter.spanFromToken(token),
|
||||||
|
"Expected a class body, but got '${token.value}'.");
|
||||||
|
return null;
|
||||||
|
|
||||||
|
case ErrorKind.ExpectedDeclaration:
|
||||||
|
reportFatalError(
|
||||||
|
reporter.spanFromToken(token),
|
||||||
|
"Expected a declaration, but got '${token.value}'.");
|
||||||
|
return null;
|
||||||
|
|
||||||
|
case ErrorKind.UnmatchedToken:
|
||||||
|
reportErrorFromToken(token, MessageKind.UNMATCHED_TOKEN, arguments);
|
||||||
|
Token next = token.next;
|
||||||
|
while (next is ErrorToken) {
|
||||||
|
next = next.next;
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
|
||||||
|
case ErrorKind.EmptyNamedParameterList:
|
||||||
|
errorCode = MessageKind.EMPTY_NAMED_PARAMETER_LIST;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.EmptyOptionalParameterList:
|
||||||
|
errorCode = MessageKind.EMPTY_OPTIONAL_PARAMETER_LIST;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.ExpectedBody:
|
||||||
|
errorCode = MessageKind.BODY_EXPECTED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.ExpectedHexDigit:
|
||||||
|
errorCode = MessageKind.HEX_DIGIT_EXPECTED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.ExpectedOpenParens:
|
||||||
|
errorCode = MessageKind.GENERIC;
|
||||||
|
arguments = {"text": "Expected '('."};
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.ExpectedString:
|
||||||
|
reportFatalError(
|
||||||
|
reporter.spanFromToken(token),
|
||||||
|
"Expected a String, but got '${token.value}'.");
|
||||||
|
return null;
|
||||||
|
|
||||||
|
case ErrorKind.ExtraneousModifier:
|
||||||
|
errorCode = MessageKind.EXTRANEOUS_MODIFIER;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.ExtraneousModifierReplace:
|
||||||
|
errorCode = MessageKind.EXTRANEOUS_MODIFIER_REPLACE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.InvalidAwaitFor:
|
||||||
|
errorCode = MessageKind.INVALID_AWAIT_FOR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.InvalidInputCharacter:
|
||||||
|
errorCode = MessageKind.BAD_INPUT_CHARACTER;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.InvalidSyncModifier:
|
||||||
|
errorCode = MessageKind.INVALID_SYNC_MODIFIER;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.InvalidVoid:
|
||||||
|
errorCode = MessageKind.VOID_NOT_ALLOWED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.MalformedStringLiteral:
|
||||||
|
errorCode = MessageKind.MALFORMED_STRING_LITERAL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.MissingExponent:
|
||||||
|
errorCode = MessageKind.EXPONENT_MISSING;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.PositionalParameterWithEquals:
|
||||||
|
errorCode = MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.RequiredParameterWithDefault:
|
||||||
|
errorCode = MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.UnmatchedToken:
|
||||||
|
errorCode = MessageKind.UNMATCHED_TOKEN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.UnsupportedPrefixPlus:
|
||||||
|
errorCode = MessageKind.UNSUPPORTED_PREFIX_PLUS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.UnterminatedComment:
|
||||||
|
errorCode = MessageKind.UNTERMINATED_COMMENT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.UnterminatedString:
|
||||||
|
errorCode = MessageKind.UNTERMINATED_STRING;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.UnterminatedToken:
|
||||||
|
errorCode = MessageKind.UNTERMINATED_TOKEN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ErrorKind.Unspecified:
|
||||||
|
errorCode = MessageKind.GENERIC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SourceSpan span = reporter.spanFromToken(token);
|
||||||
|
reportError(span, errorCode, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds the preceding token via the begin token of the last AST node pushed
|
/// Finds the preceding token via the begin token of the last AST node pushed
|
||||||
|
@ -494,113 +743,13 @@ class ElementListener extends Listener {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token expectedIdentifier(Token token) {
|
/// Finds the preceding token via the begin token of the last AST node pushed
|
||||||
if (token is KeywordToken) {
|
/// on the [nodes] stack.
|
||||||
reportError(token, MessageKind.EXPECTED_IDENTIFIER_NOT_RESERVED_WORD,
|
Token synthesizeIdentifier(Token token) {
|
||||||
{'keyword': token.value});
|
Token synthesizedToken = new StringToken.fromString(
|
||||||
} else if (token is ErrorToken) {
|
Precedence.IDENTIFIER_INFO, '?', token.charOffset);
|
||||||
reportErrorToken(token);
|
synthesizedToken.next = token.next;
|
||||||
return synthesizeIdentifier(token);
|
return synthesizedToken;
|
||||||
} else {
|
|
||||||
reportFatalError(token, "Expected identifier, but got '${token.value}'.");
|
|
||||||
}
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
Token expectedType(Token token) {
|
|
||||||
pushNode(null);
|
|
||||||
if (token is ErrorToken) {
|
|
||||||
reportErrorToken(token);
|
|
||||||
return synthesizeIdentifier(token);
|
|
||||||
} else {
|
|
||||||
reportFatalError(token, "Expected a type, but got '${token.value}'.");
|
|
||||||
return skipToEof(token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Token expectedExpression(Token token) {
|
|
||||||
if (token is ErrorToken) {
|
|
||||||
reportErrorToken(token);
|
|
||||||
pushNode(new ErrorExpression(token));
|
|
||||||
return token.next;
|
|
||||||
} else {
|
|
||||||
reportFatalError(
|
|
||||||
token, "Expected an expression, but got '${token.value}'.");
|
|
||||||
pushNode(null);
|
|
||||||
return skipToEof(token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Token unexpected(Token token) {
|
|
||||||
if (token is ErrorToken) {
|
|
||||||
reportErrorToken(token);
|
|
||||||
} else {
|
|
||||||
String message = "Unexpected token '${token.value}'.";
|
|
||||||
if (token.info == Precedence.BAD_INPUT_INFO) {
|
|
||||||
message = token.value;
|
|
||||||
}
|
|
||||||
reportFatalError(token, message);
|
|
||||||
}
|
|
||||||
return skipToEof(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
Token expectedBlockToSkip(Token token) {
|
|
||||||
if (identical(token.stringValue, 'native')) {
|
|
||||||
return native.handleNativeBlockToSkip(this, token);
|
|
||||||
} else {
|
|
||||||
return unexpected(token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Token expectedFunctionBody(Token token) {
|
|
||||||
if (token is ErrorToken) {
|
|
||||||
reportErrorToken(token);
|
|
||||||
} else {
|
|
||||||
String printString = token.value;
|
|
||||||
reportFatalError(
|
|
||||||
token, "Expected a function body, but got '$printString'.");
|
|
||||||
}
|
|
||||||
return skipToEof(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
Token expectedClassBody(Token token) {
|
|
||||||
if (token is ErrorToken) {
|
|
||||||
reportErrorToken(token);
|
|
||||||
} else {
|
|
||||||
reportFatalError(
|
|
||||||
token, "Expected a class body, but got '${token.value}'.");
|
|
||||||
}
|
|
||||||
return skipToEof(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
Token expectedClassBodyToSkip(Token token) {
|
|
||||||
return unexpected(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
Token expectedDeclaration(Token token) {
|
|
||||||
if (token is ErrorToken) {
|
|
||||||
reportErrorToken(token);
|
|
||||||
} else {
|
|
||||||
reportFatalError(
|
|
||||||
token, "Expected a declaration, but got '${token.value}'.");
|
|
||||||
}
|
|
||||||
return skipToEof(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
Token unmatched(Token token) {
|
|
||||||
if (token is ErrorToken) {
|
|
||||||
reportErrorToken(token);
|
|
||||||
} else {
|
|
||||||
String begin = token.value;
|
|
||||||
String end = closeBraceFor(begin);
|
|
||||||
reportError(
|
|
||||||
token, MessageKind.UNMATCHED_TOKEN, {'begin': begin, 'end': end});
|
|
||||||
}
|
|
||||||
Token next = token.next;
|
|
||||||
while (next is ErrorToken) {
|
|
||||||
next = next.next;
|
|
||||||
}
|
|
||||||
return next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void recoverableError(Spannable node, String message) {
|
void recoverableError(Spannable node, String message) {
|
||||||
|
@ -663,6 +812,7 @@ class ElementListener extends Listener {
|
||||||
return new NodeList(beginToken, poppedNodes, endToken, delimiter);
|
return new NodeList(beginToken, poppedNodes, endToken, delimiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void beginLiteralString(Token token) {
|
void beginLiteralString(Token token) {
|
||||||
String source = token.value;
|
String source = token.value;
|
||||||
StringQuoting quoting = StringValidator.quotingFromString(source);
|
StringQuoting quoting = StringValidator.quotingFromString(source);
|
||||||
|
@ -672,12 +822,14 @@ class ElementListener extends Listener {
|
||||||
pushNode(new LiteralString(token, null));
|
pushNode(new LiteralString(token, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleStringPart(Token token) {
|
void handleStringPart(Token token) {
|
||||||
// Just push an unvalidated token now, and replace it when we know the
|
// Just push an unvalidated token now, and replace it when we know the
|
||||||
// end of the interpolation.
|
// end of the interpolation.
|
||||||
pushNode(new LiteralString(token, null));
|
pushNode(new LiteralString(token, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endLiteralString(int count) {
|
void endLiteralString(int count) {
|
||||||
StringQuoting quoting = popQuoting();
|
StringQuoting quoting = popQuoting();
|
||||||
|
|
||||||
|
@ -711,6 +863,7 @@ class ElementListener extends Listener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleStringJuxtaposition(int stringCount) {
|
void handleStringJuxtaposition(int stringCount) {
|
||||||
assert(stringCount != 0);
|
assert(stringCount != 0);
|
||||||
Expression accumulator = popNode();
|
Expression accumulator = popNode();
|
||||||
|
@ -723,14 +876,17 @@ class ElementListener extends Listener {
|
||||||
pushNode(accumulator);
|
pushNode(accumulator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void beginMember(Token token) {
|
void beginMember(Token token) {
|
||||||
memberErrors = memberErrors.prepend(false);
|
memberErrors = memberErrors.prepend(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void beginTopLevelMember(Token token) {
|
void beginTopLevelMember(Token token) {
|
||||||
beginMember(token);
|
beginMember(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endMember() {
|
void endMember() {
|
||||||
memberErrors = memberErrors.tail;
|
memberErrors = memberErrors.tail;
|
||||||
}
|
}
|
||||||
|
@ -740,11 +896,12 @@ class ElementListener extends Listener {
|
||||||
void reportFatalError(Spannable spannable, String message) {
|
void reportFatalError(Spannable spannable, String message) {
|
||||||
reportError(spannable, MessageKind.GENERIC, {'text': message});
|
reportError(spannable, MessageKind.GENERIC, {'text': message});
|
||||||
// Some parse errors are infeasible to recover from, so we throw an error.
|
// Some parse errors are infeasible to recover from, so we throw an error.
|
||||||
throw new ParserError(message);
|
SourceSpan span = reporter.spanFromSpannable(spannable);
|
||||||
|
throw new ParserError(
|
||||||
|
span.begin, span.end, ErrorKind.Unspecified, {'text': message});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
void reportError(Spannable spannable, MessageKind errorCode,
|
||||||
void reportErrorHelper(Spannable spannable, MessageKind errorCode,
|
|
||||||
[Map arguments = const {}]) {
|
[Map arguments = const {}]) {
|
||||||
if (currentMemberHasParseError) return; // Error already reported.
|
if (currentMemberHasParseError) return; // Error already reported.
|
||||||
if (suppressParseErrors) return;
|
if (suppressParseErrors) return;
|
||||||
|
@ -753,4 +910,9 @@ class ElementListener extends Listener {
|
||||||
}
|
}
|
||||||
reporter.reportErrorMessage(spannable, errorCode, arguments);
|
reporter.reportErrorMessage(spannable, errorCode, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reportErrorFromToken(Token token, MessageKind errorCode,
|
||||||
|
[Map arguments = const {}]) {
|
||||||
|
reportError(reporter.spanFromToken(token), errorCode, arguments);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import '../common.dart';
|
||||||
import '../elements/elements.dart' show Element, ElementKind, Elements;
|
import '../elements/elements.dart' show Element, ElementKind, Elements;
|
||||||
import '../elements/modelx.dart'
|
import '../elements/modelx.dart'
|
||||||
show ClassElementX, ElementX, FieldElementX, VariableList;
|
show ClassElementX, ElementX, FieldElementX, VariableList;
|
||||||
import '../tokens/token.dart' show Token;
|
import 'package:front_end/src/fasta/scanner.dart' show Token;
|
||||||
import '../tree/tree.dart';
|
import '../tree/tree.dart';
|
||||||
import 'element_listener.dart' show ScannerOptions;
|
import 'element_listener.dart' show ScannerOptions;
|
||||||
import 'node_listener.dart' show NodeListener;
|
import 'node_listener.dart' show NodeListener;
|
||||||
|
@ -67,6 +67,7 @@ class MemberListener extends NodeListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endMethod(Token getOrSet, Token beginToken, Token endToken) {
|
void endMethod(Token getOrSet, Token beginToken, Token endToken) {
|
||||||
super.endMethod(getOrSet, beginToken, endToken);
|
super.endMethod(getOrSet, beginToken, endToken);
|
||||||
FunctionExpression method = popNode();
|
FunctionExpression method = popNode();
|
||||||
|
@ -76,7 +77,7 @@ class MemberListener extends NodeListener {
|
||||||
Element memberElement;
|
Element memberElement;
|
||||||
if (isConstructor) {
|
if (isConstructor) {
|
||||||
if (getOrSet != null) {
|
if (getOrSet != null) {
|
||||||
recoverableError(getOrSet, 'illegal modifier');
|
recoverableError(reporter.spanFromToken(getOrSet), 'illegal modifier');
|
||||||
}
|
}
|
||||||
memberElement = new PartialConstructorElement(name, beginToken, endToken,
|
memberElement = new PartialConstructorElement(name, beginToken, endToken,
|
||||||
ElementKind.GENERATIVE_CONSTRUCTOR, method.modifiers, enclosingClass);
|
ElementKind.GENERATIVE_CONSTRUCTOR, method.modifiers, enclosingClass);
|
||||||
|
@ -88,6 +89,7 @@ class MemberListener extends NodeListener {
|
||||||
addMember(memberElement);
|
addMember(memberElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endFactoryMethod(Token beginToken, Token endToken) {
|
void endFactoryMethod(Token beginToken, Token endToken) {
|
||||||
super.endFactoryMethod(beginToken, endToken);
|
super.endFactoryMethod(beginToken, endToken);
|
||||||
FunctionExpression method = popNode();
|
FunctionExpression method = popNode();
|
||||||
|
@ -112,6 +114,7 @@ class MemberListener extends NodeListener {
|
||||||
addMember(memberElement);
|
addMember(memberElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endFields(int count, Token beginToken, Token endToken) {
|
void endFields(int count, Token beginToken, Token endToken) {
|
||||||
bool hasParseError = memberErrors.head;
|
bool hasParseError = memberErrors.head;
|
||||||
super.endFields(count, beginToken, endToken);
|
super.endFields(count, beginToken, endToken);
|
||||||
|
@ -127,12 +130,14 @@ class MemberListener extends NodeListener {
|
||||||
enclosingClass, buildFieldElement, beginToken, endToken, hasParseError);
|
enclosingClass, buildFieldElement, beginToken, endToken, hasParseError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void endInitializer(Token assignmentOperator) {
|
@override
|
||||||
|
void endFieldInitializer(Token assignmentOperator) {
|
||||||
pushNode(null); // Super expects an expression, but
|
pushNode(null); // Super expects an expression, but
|
||||||
// ClassElementParser just skips expressions.
|
// ClassElementParser just skips expressions.
|
||||||
super.endInitializer(assignmentOperator);
|
super.endFieldInitializer(assignmentOperator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endInitializers(int count, Token beginToken, Token endToken) {
|
void endInitializers(int count, Token beginToken, Token endToken) {
|
||||||
pushNode(null);
|
pushNode(null);
|
||||||
}
|
}
|
||||||
|
@ -146,6 +151,7 @@ class MemberListener extends NodeListener {
|
||||||
enclosingClass.addMember(memberElement, reporter);
|
enclosingClass.addMember(memberElement, reporter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
|
void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
|
||||||
super.endMetadata(beginToken, periodBeforeName, endToken);
|
super.endMetadata(beginToken, periodBeforeName, endToken);
|
||||||
pushMetadata(new PartialMetadataAnnotation(beginToken, endToken));
|
pushMetadata(new PartialMetadataAnnotation(beginToken, endToken));
|
||||||
|
|
|
@ -6,27 +6,30 @@ library dart2js.parser.node_listener;
|
||||||
|
|
||||||
import '../common.dart';
|
import '../common.dart';
|
||||||
import '../elements/elements.dart' show CompilationUnitElement;
|
import '../elements/elements.dart' show CompilationUnitElement;
|
||||||
import '../native/native.dart' as native;
|
import 'package:front_end/src/fasta/scanner/precedence.dart' as Precedence show
|
||||||
import '../tokens/precedence_constants.dart' as Precedence show INDEX_INFO;
|
INDEX_INFO;
|
||||||
import '../tokens/token.dart' show ErrorToken, StringToken, Token;
|
import 'package:front_end/src/fasta/scanner.dart' show
|
||||||
|
StringToken, Token;
|
||||||
import '../tree/tree.dart';
|
import '../tree/tree.dart';
|
||||||
import '../util/util.dart' show Link;
|
import '../util/util.dart' show Link;
|
||||||
import 'element_listener.dart' show ElementListener, ScannerOptions;
|
import 'element_listener.dart' show ElementListener, ScannerOptions;
|
||||||
import 'partial_elements.dart' show PartialFunctionElement;
|
|
||||||
|
|
||||||
class NodeListener extends ElementListener {
|
class NodeListener extends ElementListener {
|
||||||
NodeListener(ScannerOptions scannerOptions, DiagnosticReporter reporter,
|
NodeListener(ScannerOptions scannerOptions, DiagnosticReporter reporter,
|
||||||
CompilationUnitElement element)
|
CompilationUnitElement element)
|
||||||
: super(scannerOptions, reporter, element, null);
|
: super(scannerOptions, reporter, element, null);
|
||||||
|
|
||||||
|
@override
|
||||||
void addLibraryTag(LibraryTag tag) {
|
void addLibraryTag(LibraryTag tag) {
|
||||||
pushNode(tag);
|
pushNode(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void addPartOfTag(PartOf tag) {
|
void addPartOfTag(PartOf tag) {
|
||||||
pushNode(tag);
|
pushNode(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endLibraryName(Token libraryKeyword, Token semicolon) {
|
void endLibraryName(Token libraryKeyword, Token semicolon) {
|
||||||
Expression name = popNode();
|
Expression name = popNode();
|
||||||
pushNode(new LibraryName(
|
pushNode(new LibraryName(
|
||||||
|
@ -37,6 +40,7 @@ class NodeListener extends ElementListener {
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endImport(Token importKeyword, Token deferredKeyword, Token asKeyword,
|
void endImport(Token importKeyword, Token deferredKeyword, Token asKeyword,
|
||||||
Token semicolon) {
|
Token semicolon) {
|
||||||
NodeList combinators = popNode();
|
NodeList combinators = popNode();
|
||||||
|
@ -55,6 +59,7 @@ class NodeListener extends ElementListener {
|
||||||
isDeferred: deferredKeyword != null));
|
isDeferred: deferredKeyword != null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endExport(Token exportKeyword, Token semicolon) {
|
void endExport(Token exportKeyword, Token semicolon) {
|
||||||
NodeList combinators = popNode();
|
NodeList combinators = popNode();
|
||||||
NodeList conditionalUris = popNode();
|
NodeList conditionalUris = popNode();
|
||||||
|
@ -69,6 +74,7 @@ class NodeListener extends ElementListener {
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endPart(Token partKeyword, Token semicolon) {
|
void endPart(Token partKeyword, Token semicolon) {
|
||||||
StringNode uri = popLiteralString();
|
StringNode uri = popLiteralString();
|
||||||
pushNode(new Part(
|
pushNode(new Part(
|
||||||
|
@ -79,6 +85,7 @@ class NodeListener extends ElementListener {
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endPartOf(Token partKeyword, Token semicolon) {
|
void endPartOf(Token partKeyword, Token semicolon) {
|
||||||
Expression name = popNode(); // name
|
Expression name = popNode(); // name
|
||||||
pushNode(new PartOf(
|
pushNode(new PartOf(
|
||||||
|
@ -89,6 +96,7 @@ class NodeListener extends ElementListener {
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endClassDeclaration(int interfacesCount, Token beginToken,
|
void endClassDeclaration(int interfacesCount, Token beginToken,
|
||||||
Token extendsKeyword, Token implementsKeyword, Token endToken) {
|
Token extendsKeyword, Token implementsKeyword, Token endToken) {
|
||||||
NodeList body = popNode();
|
NodeList body = popNode();
|
||||||
|
@ -102,6 +110,7 @@ class NodeListener extends ElementListener {
|
||||||
interfaces, beginToken, extendsKeyword, body, endToken));
|
interfaces, beginToken, extendsKeyword, body, endToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endTopLevelDeclaration(Token token) {
|
void endTopLevelDeclaration(Token token) {
|
||||||
// TODO(sigmund): consider moving metadata into each declaration
|
// TODO(sigmund): consider moving metadata into each declaration
|
||||||
// element instead.
|
// element instead.
|
||||||
|
@ -111,10 +120,12 @@ class NodeListener extends ElementListener {
|
||||||
super.endTopLevelDeclaration(token);
|
super.endTopLevelDeclaration(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endCompilationUnit(int count, Token token) {
|
void endCompilationUnit(int count, Token token) {
|
||||||
pushNode(makeNodeList(count, null, null, '\n'));
|
pushNode(makeNodeList(count, null, null, '\n'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endFunctionTypeAlias(Token typedefKeyword, Token endToken) {
|
void endFunctionTypeAlias(Token typedefKeyword, Token endToken) {
|
||||||
NodeList formals = popNode();
|
NodeList formals = popNode();
|
||||||
NodeList typeParameters = popNode();
|
NodeList typeParameters = popNode();
|
||||||
|
@ -124,6 +135,7 @@ class NodeListener extends ElementListener {
|
||||||
returnType, name, typeParameters, formals, typedefKeyword, endToken));
|
returnType, name, typeParameters, formals, typedefKeyword, endToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endNamedMixinApplication(
|
void endNamedMixinApplication(
|
||||||
Token classKeyword, Token implementsKeyword, Token endToken) {
|
Token classKeyword, Token implementsKeyword, Token endToken) {
|
||||||
NodeList interfaces = (implementsKeyword != null) ? popNode() : null;
|
NodeList interfaces = (implementsKeyword != null) ? popNode() : null;
|
||||||
|
@ -135,16 +147,19 @@ class NodeListener extends ElementListener {
|
||||||
mixinApplication, interfaces, classKeyword, endToken));
|
mixinApplication, interfaces, classKeyword, endToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endEnum(Token enumKeyword, Token endBrace, int count) {
|
void endEnum(Token enumKeyword, Token endBrace, int count) {
|
||||||
NodeList names = makeNodeList(count, enumKeyword.next.next, endBrace, ",");
|
NodeList names = makeNodeList(count, enumKeyword.next.next, endBrace, ",");
|
||||||
Identifier name = popNode();
|
Identifier name = popNode();
|
||||||
pushNode(new Enum(enumKeyword, name, names));
|
pushNode(new Enum(enumKeyword, name, names));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endClassBody(int memberCount, Token beginToken, Token endToken) {
|
void endClassBody(int memberCount, Token beginToken, Token endToken) {
|
||||||
pushNode(makeNodeList(memberCount, beginToken, endToken, null));
|
pushNode(makeNodeList(memberCount, beginToken, endToken, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endTopLevelFields(int count, Token beginToken, Token endToken) {
|
void endTopLevelFields(int count, Token beginToken, Token endToken) {
|
||||||
NodeList variables = makeNodeList(count, null, endToken, ",");
|
NodeList variables = makeNodeList(count, null, endToken, ",");
|
||||||
TypeAnnotation type = popNode();
|
TypeAnnotation type = popNode();
|
||||||
|
@ -152,6 +167,7 @@ class NodeListener extends ElementListener {
|
||||||
pushNode(new VariableDefinitions(type, modifiers, variables));
|
pushNode(new VariableDefinitions(type, modifiers, variables));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
|
void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
|
||||||
Statement body = popNode();
|
Statement body = popNode();
|
||||||
AsyncModifier asyncModifier = popNode();
|
AsyncModifier asyncModifier = popNode();
|
||||||
|
@ -164,6 +180,7 @@ class NodeListener extends ElementListener {
|
||||||
modifiers, null, getOrSet, asyncModifier));
|
modifiers, null, getOrSet, asyncModifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endFormalParameter(Token thisKeyword) {
|
void endFormalParameter(Token thisKeyword) {
|
||||||
Expression name = popNode();
|
Expression name = popNode();
|
||||||
if (thisKeyword != null) {
|
if (thisKeyword != null) {
|
||||||
|
@ -181,22 +198,27 @@ class NodeListener extends ElementListener {
|
||||||
metadata, type, modifiers, new NodeList.singleton(name)));
|
metadata, type, modifiers, new NodeList.singleton(name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endFormalParameters(int count, Token beginToken, Token endToken) {
|
void endFormalParameters(int count, Token beginToken, Token endToken) {
|
||||||
pushNode(makeNodeList(count, beginToken, endToken, ","));
|
pushNode(makeNodeList(count, beginToken, endToken, ","));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleNoFormalParameters(Token token) {
|
void handleNoFormalParameters(Token token) {
|
||||||
pushNode(null);
|
pushNode(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endArguments(int count, Token beginToken, Token endToken) {
|
void endArguments(int count, Token beginToken, Token endToken) {
|
||||||
pushNode(makeNodeList(count, beginToken, endToken, ","));
|
pushNode(makeNodeList(count, beginToken, endToken, ","));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleNoArguments(Token token) {
|
void handleNoArguments(Token token) {
|
||||||
pushNode(null);
|
pushNode(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endConstructorReference(
|
void endConstructorReference(
|
||||||
Token start, Token periodBeforeName, Token endToken) {
|
Token start, Token periodBeforeName, Token endToken) {
|
||||||
Identifier name = null;
|
Identifier name = null;
|
||||||
|
@ -228,74 +250,61 @@ class NodeListener extends ElementListener {
|
||||||
pushNode(constructor);
|
pushNode(constructor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endRedirectingFactoryBody(Token beginToken, Token endToken) {
|
void endRedirectingFactoryBody(Token beginToken, Token endToken) {
|
||||||
pushNode(new RedirectingFactoryBody(beginToken, endToken, popNode()));
|
pushNode(new RedirectingFactoryBody(beginToken, endToken, popNode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endReturnStatement(
|
void endReturnStatement(
|
||||||
bool hasExpression, Token beginToken, Token endToken) {
|
bool hasExpression, Token beginToken, Token endToken) {
|
||||||
Expression expression = hasExpression ? popNode() : null;
|
Expression expression = hasExpression ? popNode() : null;
|
||||||
pushNode(new Return(beginToken, endToken, expression));
|
pushNode(new Return(beginToken, endToken, expression));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endYieldStatement(Token yieldToken, Token starToken, Token endToken) {
|
void endYieldStatement(Token yieldToken, Token starToken, Token endToken) {
|
||||||
Expression expression = popNode();
|
Expression expression = popNode();
|
||||||
pushNode(new Yield(yieldToken, starToken, expression, endToken));
|
pushNode(new Yield(yieldToken, starToken, expression, endToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endExpressionStatement(Token token) {
|
void endExpressionStatement(Token token) {
|
||||||
pushNode(new ExpressionStatement(popNode(), token));
|
pushNode(new ExpressionStatement(popNode(), token));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleOnError(Token token, var errorInformation) {
|
void handleOnError(Token token, var errorInformation) {
|
||||||
reporter.internalError(token, "'${token.value}': ${errorInformation}");
|
reporter.internalError(reporter.spanFromToken(token),
|
||||||
}
|
"'${token.value}': ${errorInformation}");
|
||||||
|
|
||||||
Token expectedFunctionBody(Token token) {
|
|
||||||
if (identical(token.stringValue, 'native')) {
|
|
||||||
return native.handleNativeFunctionBody(this, token);
|
|
||||||
} else if (token is ErrorToken) {
|
|
||||||
pushNode(null);
|
|
||||||
reportErrorToken(token);
|
|
||||||
} else {
|
|
||||||
reportFatalError(
|
|
||||||
token, "Expected a function body, but got '${token.value}'.");
|
|
||||||
}
|
|
||||||
return skipToEof(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
Token expectedClassBody(Token token) {
|
|
||||||
if (token is ErrorToken) {
|
|
||||||
reportErrorToken(token);
|
|
||||||
return skipToEof(token);
|
|
||||||
} else {
|
|
||||||
reportFatalError(
|
|
||||||
token, "Expected a class body, but got '${token.value}'.");
|
|
||||||
return skipToEof(token);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleLiteralInt(Token token) {
|
void handleLiteralInt(Token token) {
|
||||||
pushNode(new LiteralInt(token, (t, e) => handleOnError(t, e)));
|
pushNode(new LiteralInt(token, (t, e) => handleOnError(t, e)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleLiteralDouble(Token token) {
|
void handleLiteralDouble(Token token) {
|
||||||
pushNode(new LiteralDouble(token, (t, e) => handleOnError(t, e)));
|
pushNode(new LiteralDouble(token, (t, e) => handleOnError(t, e)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleLiteralBool(Token token) {
|
void handleLiteralBool(Token token) {
|
||||||
pushNode(new LiteralBool(token, (t, e) => handleOnError(t, e)));
|
pushNode(new LiteralBool(token, (t, e) => handleOnError(t, e)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleLiteralNull(Token token) {
|
void handleLiteralNull(Token token) {
|
||||||
pushNode(new LiteralNull(token));
|
pushNode(new LiteralNull(token));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endLiteralSymbol(Token hashToken, int identifierCount) {
|
void endLiteralSymbol(Token hashToken, int identifierCount) {
|
||||||
NodeList identifiers = makeNodeList(identifierCount, null, null, '.');
|
NodeList identifiers = makeNodeList(identifierCount, null, null, '.');
|
||||||
pushNode(new LiteralSymbol(hashToken, identifiers));
|
pushNode(new LiteralSymbol(hashToken, identifiers));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleBinaryExpression(Token token) {
|
void handleBinaryExpression(Token token) {
|
||||||
Node argument = popNode();
|
Node argument = popNode();
|
||||||
Node receiver = popNode();
|
Node receiver = popNode();
|
||||||
|
@ -307,7 +316,8 @@ class NodeListener extends ElementListener {
|
||||||
if (argumentSend == null) {
|
if (argumentSend == null) {
|
||||||
// TODO(ahe): The parser should diagnose this problem, not
|
// TODO(ahe): The parser should diagnose this problem, not
|
||||||
// this listener.
|
// this listener.
|
||||||
reportFatalError(argument, 'Expected an identifier.');
|
reportFatalError(reporter.spanFromSpannable(argument),
|
||||||
|
"Expected an identifier.");
|
||||||
}
|
}
|
||||||
if (argumentSend.receiver != null) internalError(node: argument);
|
if (argumentSend.receiver != null) internalError(node: argument);
|
||||||
if (argument is SendSet) internalError(node: argument);
|
if (argument is SendSet) internalError(node: argument);
|
||||||
|
@ -319,23 +329,27 @@ class NodeListener extends ElementListener {
|
||||||
pushNode(new Send(receiver, new Operator(token), arguments));
|
pushNode(new Send(receiver, new Operator(token), arguments));
|
||||||
}
|
}
|
||||||
if (identical(tokenString, '===')) {
|
if (identical(tokenString, '===')) {
|
||||||
reporter.reportErrorMessage(token, MessageKind.UNSUPPORTED_EQ_EQ_EQ,
|
reporter.reportErrorMessage(reporter.spanFromToken(token),
|
||||||
{'lhs': receiver, 'rhs': argument});
|
MessageKind.UNSUPPORTED_EQ_EQ_EQ, {'lhs': receiver, 'rhs': argument});
|
||||||
}
|
}
|
||||||
if (identical(tokenString, '!==')) {
|
if (identical(tokenString, '!==')) {
|
||||||
reporter.reportErrorMessage(token, MessageKind.UNSUPPORTED_BANG_EQ_EQ,
|
reporter.reportErrorMessage(reporter.spanFromToken(token),
|
||||||
|
MessageKind.UNSUPPORTED_BANG_EQ_EQ,
|
||||||
{'lhs': receiver, 'rhs': argument});
|
{'lhs': receiver, 'rhs': argument});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void beginCascade(Token token) {
|
void beginCascade(Token token) {
|
||||||
pushNode(new CascadeReceiver(popNode(), token));
|
pushNode(new CascadeReceiver(popNode(), token));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endCascade() {
|
void endCascade() {
|
||||||
pushNode(new Cascade(popNode()));
|
pushNode(new Cascade(popNode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleAsOperator(Token operator, Token endToken) {
|
void handleAsOperator(Token operator, Token endToken) {
|
||||||
TypeAnnotation type = popNode();
|
TypeAnnotation type = popNode();
|
||||||
Expression expression = popNode();
|
Expression expression = popNode();
|
||||||
|
@ -343,6 +357,7 @@ class NodeListener extends ElementListener {
|
||||||
pushNode(new Send(expression, new Operator(operator), arguments));
|
pushNode(new Send(expression, new Operator(operator), arguments));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleAssignmentExpression(Token token) {
|
void handleAssignmentExpression(Token token) {
|
||||||
Node arg = popNode();
|
Node arg = popNode();
|
||||||
Node node = popNode();
|
Node node = popNode();
|
||||||
|
@ -367,9 +382,10 @@ class NodeListener extends ElementListener {
|
||||||
void reportNotAssignable(Node node) {
|
void reportNotAssignable(Node node) {
|
||||||
// TODO(ahe): The parser should diagnose this problem, not this
|
// TODO(ahe): The parser should diagnose this problem, not this
|
||||||
// listener.
|
// listener.
|
||||||
reportFatalError(node, 'Not assignable.');
|
reportFatalError(reporter.spanFromSpannable(node), "Not assignable.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleConditionalExpression(Token question, Token colon) {
|
void handleConditionalExpression(Token question, Token colon) {
|
||||||
Node elseExpression = popNode();
|
Node elseExpression = popNode();
|
||||||
Node thenExpression = popNode();
|
Node thenExpression = popNode();
|
||||||
|
@ -378,6 +394,7 @@ class NodeListener extends ElementListener {
|
||||||
condition, thenExpression, elseExpression, question, colon));
|
condition, thenExpression, elseExpression, question, colon));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endSend(Token token) {
|
void endSend(Token token) {
|
||||||
NodeList arguments = popNode();
|
NodeList arguments = popNode();
|
||||||
NodeList typeArguments = popNode();
|
NodeList typeArguments = popNode();
|
||||||
|
@ -386,6 +403,7 @@ class NodeListener extends ElementListener {
|
||||||
pushNode(new Send(null, selector, arguments, typeArguments));
|
pushNode(new Send(null, selector, arguments, typeArguments));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endFunctionBody(int count, Token beginToken, Token endToken) {
|
void endFunctionBody(int count, Token beginToken, Token endToken) {
|
||||||
if (count == 0 && beginToken == null) {
|
if (count == 0 && beginToken == null) {
|
||||||
pushNode(new EmptyStatement(endToken));
|
pushNode(new EmptyStatement(endToken));
|
||||||
|
@ -394,6 +412,7 @@ class NodeListener extends ElementListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleAsyncModifier(Token asyncToken, Token starToken) {
|
void handleAsyncModifier(Token asyncToken, Token starToken) {
|
||||||
if (asyncToken != null) {
|
if (asyncToken != null) {
|
||||||
pushNode(new AsyncModifier(asyncToken, starToken));
|
pushNode(new AsyncModifier(asyncToken, starToken));
|
||||||
|
@ -402,14 +421,17 @@ class NodeListener extends ElementListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void skippedFunctionBody(Token token) {
|
@override
|
||||||
|
void handleFunctionBodySkipped(Token token) {
|
||||||
pushNode(new Block(new NodeList.empty()));
|
pushNode(new Block(new NodeList.empty()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleNoFunctionBody(Token token) {
|
void handleNoFunctionBody(Token token) {
|
||||||
pushNode(new EmptyStatement(token));
|
pushNode(new EmptyStatement(token));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endFunction(Token getOrSet, Token endToken) {
|
void endFunction(Token getOrSet, Token endToken) {
|
||||||
Statement body = popNode();
|
Statement body = popNode();
|
||||||
AsyncModifier asyncModifier = popNode();
|
AsyncModifier asyncModifier = popNode();
|
||||||
|
@ -424,10 +446,12 @@ class NodeListener extends ElementListener {
|
||||||
modifiers, initializers, getOrSet, asyncModifier));
|
modifiers, initializers, getOrSet, asyncModifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endFunctionDeclaration(Token endToken) {
|
void endFunctionDeclaration(Token endToken) {
|
||||||
pushNode(new FunctionDeclaration(popNode()));
|
pushNode(new FunctionDeclaration(popNode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endVariablesDeclaration(int count, Token endToken) {
|
void endVariablesDeclaration(int count, Token endToken) {
|
||||||
// TODO(ahe): Pick one name for this concept, either
|
// TODO(ahe): Pick one name for this concept, either
|
||||||
// VariablesDeclaration or VariableDefinitions.
|
// VariablesDeclaration or VariableDefinitions.
|
||||||
|
@ -437,7 +461,8 @@ class NodeListener extends ElementListener {
|
||||||
pushNode(new VariableDefinitions(type, modifiers, variables));
|
pushNode(new VariableDefinitions(type, modifiers, variables));
|
||||||
}
|
}
|
||||||
|
|
||||||
void endInitializer(Token assignmentOperator) {
|
@override
|
||||||
|
void endVariableInitializer(Token assignmentOperator) {
|
||||||
Expression initializer = popNode();
|
Expression initializer = popNode();
|
||||||
NodeList arguments =
|
NodeList arguments =
|
||||||
initializer == null ? null : new NodeList.singleton(initializer);
|
initializer == null ? null : new NodeList.singleton(initializer);
|
||||||
|
@ -446,6 +471,12 @@ class NodeListener extends ElementListener {
|
||||||
pushNode(new SendSet(null, name, op, arguments));
|
pushNode(new SendSet(null, name, op, arguments));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void endFieldInitializer(Token assignmentOperator) {
|
||||||
|
endVariableInitializer(assignmentOperator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endIfStatement(Token ifToken, Token elseToken) {
|
void endIfStatement(Token ifToken, Token elseToken) {
|
||||||
Statement elsePart = (elseToken == null) ? null : popNode();
|
Statement elsePart = (elseToken == null) ? null : popNode();
|
||||||
Statement thenPart = popNode();
|
Statement thenPart = popNode();
|
||||||
|
@ -453,6 +484,7 @@ class NodeListener extends ElementListener {
|
||||||
pushNode(new If(condition, thenPart, elsePart, ifToken, elseToken));
|
pushNode(new If(condition, thenPart, elsePart, ifToken, elseToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endForStatement(
|
void endForStatement(
|
||||||
int updateExpressionCount, Token beginToken, Token endToken) {
|
int updateExpressionCount, Token beginToken, Token endToken) {
|
||||||
Statement body = popNode();
|
Statement body = popNode();
|
||||||
|
@ -462,10 +494,12 @@ class NodeListener extends ElementListener {
|
||||||
pushNode(new For(initializer, condition, updates, body, beginToken));
|
pushNode(new For(initializer, condition, updates, body, beginToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleNoExpression(Token token) {
|
void handleNoExpression(Token token) {
|
||||||
pushNode(null);
|
pushNode(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endDoWhileStatement(
|
void endDoWhileStatement(
|
||||||
Token doKeyword, Token whileKeyword, Token endToken) {
|
Token doKeyword, Token whileKeyword, Token endToken) {
|
||||||
Expression condition = popNode();
|
Expression condition = popNode();
|
||||||
|
@ -473,42 +507,51 @@ class NodeListener extends ElementListener {
|
||||||
pushNode(new DoWhile(body, condition, doKeyword, whileKeyword, endToken));
|
pushNode(new DoWhile(body, condition, doKeyword, whileKeyword, endToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endWhileStatement(Token whileKeyword, Token endToken) {
|
void endWhileStatement(Token whileKeyword, Token endToken) {
|
||||||
Statement body = popNode();
|
Statement body = popNode();
|
||||||
Expression condition = popNode();
|
Expression condition = popNode();
|
||||||
pushNode(new While(condition, body, whileKeyword));
|
pushNode(new While(condition, body, whileKeyword));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endBlock(int count, Token beginToken, Token endToken) {
|
void endBlock(int count, Token beginToken, Token endToken) {
|
||||||
pushNode(new Block(makeNodeList(count, beginToken, endToken, null)));
|
pushNode(new Block(makeNodeList(count, beginToken, endToken, null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endThrowExpression(Token throwToken, Token endToken) {
|
void endThrowExpression(Token throwToken, Token endToken) {
|
||||||
Expression expression = popNode();
|
Expression expression = popNode();
|
||||||
pushNode(new Throw(expression, throwToken, endToken));
|
pushNode(new Throw(expression, throwToken, endToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endAwaitExpression(Token awaitToken, Token endToken) {
|
void endAwaitExpression(Token awaitToken, Token endToken) {
|
||||||
Expression expression = popNode();
|
Expression expression = popNode();
|
||||||
pushNode(new Await(awaitToken, expression));
|
pushNode(new Await(awaitToken, expression));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endRethrowStatement(Token throwToken, Token endToken) {
|
void endRethrowStatement(Token throwToken, Token endToken) {
|
||||||
pushNode(new Rethrow(throwToken, endToken));
|
pushNode(new Rethrow(throwToken, endToken));
|
||||||
if (identical(throwToken.stringValue, 'throw')) {
|
if (identical(throwToken.stringValue, 'throw')) {
|
||||||
reporter.reportErrorMessage(
|
reporter.reportErrorMessage(
|
||||||
throwToken, MessageKind.MISSING_EXPRESSION_IN_THROW);
|
reporter.spanFromToken(throwToken),
|
||||||
|
MessageKind.MISSING_EXPRESSION_IN_THROW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleUnaryPrefixExpression(Token token) {
|
void handleUnaryPrefixExpression(Token token) {
|
||||||
pushNode(new Send.prefix(popNode(), new Operator(token)));
|
pushNode(new Send.prefix(popNode(), new Operator(token)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleSuperExpression(Token token) {
|
void handleSuperExpression(Token token) {
|
||||||
pushNode(new Identifier(token));
|
pushNode(new Identifier(token));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleThisExpression(Token token) {
|
void handleThisExpression(Token token) {
|
||||||
pushNode(new Identifier(token));
|
pushNode(new Identifier(token));
|
||||||
}
|
}
|
||||||
|
@ -536,22 +579,27 @@ class NodeListener extends ElementListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleUnaryPostfixAssignmentExpression(Token token) {
|
void handleUnaryPostfixAssignmentExpression(Token token) {
|
||||||
handleUnaryAssignmentExpression(token, false);
|
handleUnaryAssignmentExpression(token, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleUnaryPrefixAssignmentExpression(Token token) {
|
void handleUnaryPrefixAssignmentExpression(Token token) {
|
||||||
handleUnaryAssignmentExpression(token, true);
|
handleUnaryAssignmentExpression(token, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endInitializers(int count, Token beginToken, Token endToken) {
|
void endInitializers(int count, Token beginToken, Token endToken) {
|
||||||
pushNode(makeNodeList(count, beginToken, null, ','));
|
pushNode(makeNodeList(count, beginToken, null, ','));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleNoInitializers() {
|
void handleNoInitializers() {
|
||||||
pushNode(null);
|
pushNode(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endMember() {
|
void endMember() {
|
||||||
// TODO(sigmund): consider moving metadata into each declaration
|
// TODO(sigmund): consider moving metadata into each declaration
|
||||||
// element instead.
|
// element instead.
|
||||||
|
@ -561,6 +609,7 @@ class NodeListener extends ElementListener {
|
||||||
super.endMember();
|
super.endMember();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endFields(int count, Token beginToken, Token endToken) {
|
void endFields(int count, Token beginToken, Token endToken) {
|
||||||
NodeList variables = makeNodeList(count, null, endToken, ",");
|
NodeList variables = makeNodeList(count, null, endToken, ",");
|
||||||
TypeAnnotation type = popNode();
|
TypeAnnotation type = popNode();
|
||||||
|
@ -568,6 +617,7 @@ class NodeListener extends ElementListener {
|
||||||
pushNode(new VariableDefinitions(type, modifiers, variables));
|
pushNode(new VariableDefinitions(type, modifiers, variables));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endMethod(Token getOrSet, Token beginToken, Token endToken) {
|
void endMethod(Token getOrSet, Token beginToken, Token endToken) {
|
||||||
Statement body = popNode();
|
Statement body = popNode();
|
||||||
AsyncModifier asyncModifier = popNode();
|
AsyncModifier asyncModifier = popNode();
|
||||||
|
@ -581,6 +631,7 @@ class NodeListener extends ElementListener {
|
||||||
returnType, modifiers, initializers, getOrSet, asyncModifier));
|
returnType, modifiers, initializers, getOrSet, asyncModifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleLiteralMap(
|
void handleLiteralMap(
|
||||||
int count, Token beginToken, Token constKeyword, Token endToken) {
|
int count, Token beginToken, Token constKeyword, Token endToken) {
|
||||||
NodeList entries = makeNodeList(count, beginToken, endToken, ',');
|
NodeList entries = makeNodeList(count, beginToken, endToken, ',');
|
||||||
|
@ -588,18 +639,21 @@ class NodeListener extends ElementListener {
|
||||||
pushNode(new LiteralMap(typeArguments, entries, constKeyword));
|
pushNode(new LiteralMap(typeArguments, entries, constKeyword));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endLiteralMapEntry(Token colon, Token endToken) {
|
void endLiteralMapEntry(Token colon, Token endToken) {
|
||||||
Expression value = popNode();
|
Expression value = popNode();
|
||||||
Expression key = popNode();
|
Expression key = popNode();
|
||||||
pushNode(new LiteralMapEntry(key, colon, value));
|
pushNode(new LiteralMapEntry(key, colon, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleLiteralList(
|
void handleLiteralList(
|
||||||
int count, Token beginToken, Token constKeyword, Token endToken) {
|
int count, Token beginToken, Token constKeyword, Token endToken) {
|
||||||
NodeList elements = makeNodeList(count, beginToken, endToken, ',');
|
NodeList elements = makeNodeList(count, beginToken, endToken, ',');
|
||||||
pushNode(new LiteralList(popNode(), elements, constKeyword));
|
pushNode(new LiteralList(popNode(), elements, constKeyword));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleIndexedExpression(
|
void handleIndexedExpression(
|
||||||
Token openSquareBracket, Token closeSquareBracket) {
|
Token openSquareBracket, Token closeSquareBracket) {
|
||||||
NodeList arguments =
|
NodeList arguments =
|
||||||
|
@ -611,38 +665,45 @@ class NodeListener extends ElementListener {
|
||||||
pushNode(new Send(receiver, selector, arguments));
|
pushNode(new Send(receiver, selector, arguments));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleNewExpression(Token token) {
|
void handleNewExpression(Token token) {
|
||||||
NodeList arguments = popNode();
|
NodeList arguments = popNode();
|
||||||
Node name = popNode();
|
Node name = popNode();
|
||||||
pushNode(new NewExpression(token, new Send(null, name, arguments)));
|
pushNode(new NewExpression(token, new Send(null, name, arguments)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleConstExpression(Token token) {
|
void handleConstExpression(Token token) {
|
||||||
// [token] carries the 'const' information.
|
// [token] carries the 'const' information.
|
||||||
handleNewExpression(token);
|
handleNewExpression(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleOperator(Token token) {
|
void handleOperator(Token token) {
|
||||||
pushNode(new Operator(token));
|
pushNode(new Operator(token));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleOperatorName(Token operatorKeyword, Token token) {
|
void handleOperatorName(Token operatorKeyword, Token token) {
|
||||||
Operator op = new Operator(token);
|
Operator op = new Operator(token);
|
||||||
pushNode(new Send(new Identifier(operatorKeyword), op, null));
|
pushNode(new Send(new Identifier(operatorKeyword), op, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleNamedArgument(Token colon) {
|
void handleNamedArgument(Token colon) {
|
||||||
Expression expression = popNode();
|
Expression expression = popNode();
|
||||||
Identifier name = popNode();
|
Identifier name = popNode();
|
||||||
pushNode(new NamedArgument(name, colon, expression));
|
pushNode(new NamedArgument(name, colon, expression));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endOptionalFormalParameters(
|
void endOptionalFormalParameters(
|
||||||
int count, Token beginToken, Token endToken) {
|
int count, Token beginToken, Token endToken) {
|
||||||
pushNode(makeNodeList(count, beginToken, endToken, ','));
|
pushNode(makeNodeList(count, beginToken, endToken, ','));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleFunctionTypedFormalParameter(Token endToken) {
|
@override
|
||||||
|
void endFunctionTypedFormalParameter(Token endToken) {
|
||||||
NodeList formals = popNode();
|
NodeList formals = popNode();
|
||||||
NodeList typeVariables = popNode();
|
NodeList typeVariables = popNode();
|
||||||
Identifier name = popNode();
|
Identifier name = popNode();
|
||||||
|
@ -652,6 +713,7 @@ class NodeListener extends ElementListener {
|
||||||
returnType, Modifiers.EMPTY, null, null, null));
|
returnType, Modifiers.EMPTY, null, null, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleValuedFormalParameter(Token equals, Token token) {
|
void handleValuedFormalParameter(Token equals, Token token) {
|
||||||
Expression defaultValue = popNode();
|
Expression defaultValue = popNode();
|
||||||
Expression parameterName = popNode();
|
Expression parameterName = popNode();
|
||||||
|
@ -659,6 +721,7 @@ class NodeListener extends ElementListener {
|
||||||
new NodeList.singleton(defaultValue)));
|
new NodeList.singleton(defaultValue)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
|
void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
|
||||||
Block finallyBlock = null;
|
Block finallyBlock = null;
|
||||||
if (finallyKeyword != null) {
|
if (finallyKeyword != null) {
|
||||||
|
@ -670,10 +733,12 @@ class NodeListener extends ElementListener {
|
||||||
tryBlock, catchBlocks, finallyBlock, tryKeyword, finallyKeyword));
|
tryBlock, catchBlocks, finallyBlock, tryKeyword, finallyKeyword));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleCaseMatch(Token caseKeyword, Token colon) {
|
void handleCaseMatch(Token caseKeyword, Token colon) {
|
||||||
pushNode(new CaseMatch(caseKeyword, popNode(), colon));
|
pushNode(new CaseMatch(caseKeyword, popNode(), colon));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleCatchBlock(Token onKeyword, Token catchKeyword) {
|
void handleCatchBlock(Token onKeyword, Token catchKeyword) {
|
||||||
Block block = popNode();
|
Block block = popNode();
|
||||||
NodeList formals = catchKeyword != null ? popNode() : null;
|
NodeList formals = catchKeyword != null ? popNode() : null;
|
||||||
|
@ -681,12 +746,14 @@ class NodeListener extends ElementListener {
|
||||||
pushNode(new CatchBlock(type, formals, block, onKeyword, catchKeyword));
|
pushNode(new CatchBlock(type, formals, block, onKeyword, catchKeyword));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endSwitchStatement(Token switchKeyword, Token endToken) {
|
void endSwitchStatement(Token switchKeyword, Token endToken) {
|
||||||
NodeList cases = popNode();
|
NodeList cases = popNode();
|
||||||
ParenthesizedExpression expression = popNode();
|
ParenthesizedExpression expression = popNode();
|
||||||
pushNode(new SwitchStatement(expression, cases, switchKeyword));
|
pushNode(new SwitchStatement(expression, cases, switchKeyword));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endSwitchBlock(int caseCount, Token beginToken, Token endToken) {
|
void endSwitchBlock(int caseCount, Token beginToken, Token endToken) {
|
||||||
Link<Node> caseNodes = const Link<Node>();
|
Link<Node> caseNodes = const Link<Node>();
|
||||||
while (caseCount > 0) {
|
while (caseCount > 0) {
|
||||||
|
@ -697,6 +764,7 @@ class NodeListener extends ElementListener {
|
||||||
pushNode(new NodeList(beginToken, caseNodes, endToken, null));
|
pushNode(new NodeList(beginToken, caseNodes, endToken, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleSwitchCase(int labelCount, int caseCount, Token defaultKeyword,
|
void handleSwitchCase(int labelCount, int caseCount, Token defaultKeyword,
|
||||||
int statementCount, Token firstToken, Token endToken) {
|
int statementCount, Token firstToken, Token endToken) {
|
||||||
NodeList statements = makeNodeList(statementCount, null, null, null);
|
NodeList statements = makeNodeList(statementCount, null, null, null);
|
||||||
|
@ -706,6 +774,7 @@ class NodeListener extends ElementListener {
|
||||||
new SwitchCase(labelsAndCases, defaultKeyword, statements, firstToken));
|
new SwitchCase(labelsAndCases, defaultKeyword, statements, firstToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleBreakStatement(
|
void handleBreakStatement(
|
||||||
bool hasTarget, Token breakKeyword, Token endToken) {
|
bool hasTarget, Token breakKeyword, Token endToken) {
|
||||||
Identifier target = null;
|
Identifier target = null;
|
||||||
|
@ -715,6 +784,7 @@ class NodeListener extends ElementListener {
|
||||||
pushNode(new BreakStatement(target, breakKeyword, endToken));
|
pushNode(new BreakStatement(target, breakKeyword, endToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleContinueStatement(
|
void handleContinueStatement(
|
||||||
bool hasTarget, Token continueKeyword, Token endToken) {
|
bool hasTarget, Token continueKeyword, Token endToken) {
|
||||||
Identifier target = null;
|
Identifier target = null;
|
||||||
|
@ -724,10 +794,12 @@ class NodeListener extends ElementListener {
|
||||||
pushNode(new ContinueStatement(target, continueKeyword, endToken));
|
pushNode(new ContinueStatement(target, continueKeyword, endToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleEmptyStatement(Token token) {
|
void handleEmptyStatement(Token token) {
|
||||||
pushNode(new EmptyStatement(token));
|
pushNode(new EmptyStatement(token));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endFactoryMethod(Token beginToken, Token endToken) {
|
void endFactoryMethod(Token beginToken, Token endToken) {
|
||||||
super.endFactoryMethod(beginToken, endToken);
|
super.endFactoryMethod(beginToken, endToken);
|
||||||
Statement body = popNode();
|
Statement body = popNode();
|
||||||
|
@ -758,6 +830,7 @@ class NodeListener extends ElementListener {
|
||||||
name, null, formals, body, null, modifiers, null, null, asyncModifier));
|
name, null, formals, body, null, modifiers, null, null, asyncModifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endForIn(
|
void endForIn(
|
||||||
Token awaitToken, Token forToken, Token inKeyword, Token endToken) {
|
Token awaitToken, Token forToken, Token inKeyword, Token endToken) {
|
||||||
Statement body = popNode();
|
Statement body = popNode();
|
||||||
|
@ -772,6 +845,7 @@ class NodeListener extends ElementListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endMetadataStar(int count, bool forParameter) {
|
void endMetadataStar(int count, bool forParameter) {
|
||||||
if (0 == count) {
|
if (0 == count) {
|
||||||
pushNode(null);
|
pushNode(null);
|
||||||
|
@ -780,6 +854,7 @@ class NodeListener extends ElementListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
|
void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
|
||||||
NodeList arguments = popNode();
|
NodeList arguments = popNode();
|
||||||
if (arguments == null) {
|
if (arguments == null) {
|
||||||
|
@ -816,6 +891,7 @@ class NodeListener extends ElementListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleAssertStatement(
|
void handleAssertStatement(
|
||||||
Token assertKeyword, Token commaToken, Token semicolonToken) {
|
Token assertKeyword, Token commaToken, Token semicolonToken) {
|
||||||
Node message;
|
Node message;
|
||||||
|
@ -827,6 +903,7 @@ class NodeListener extends ElementListener {
|
||||||
pushNode(new Assert(assertKeyword, condition, message, semicolonToken));
|
pushNode(new Assert(assertKeyword, condition, message, semicolonToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endUnnamedFunction(Token token) {
|
void endUnnamedFunction(Token token) {
|
||||||
Statement body = popNode();
|
Statement body = popNode();
|
||||||
AsyncModifier asyncModifier = popNode();
|
AsyncModifier asyncModifier = popNode();
|
||||||
|
@ -836,6 +913,7 @@ class NodeListener extends ElementListener {
|
||||||
Modifiers.EMPTY, null, null, asyncModifier));
|
Modifiers.EMPTY, null, null, asyncModifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleIsOperator(Token operator, Token not, Token endToken) {
|
void handleIsOperator(Token operator, Token not, Token endToken) {
|
||||||
TypeAnnotation type = popNode();
|
TypeAnnotation type = popNode();
|
||||||
Expression expression = popNode();
|
Expression expression = popNode();
|
||||||
|
@ -850,21 +928,32 @@ class NodeListener extends ElementListener {
|
||||||
pushNode(new Send(expression, new Operator(operator), arguments));
|
pushNode(new Send(expression, new Operator(operator), arguments));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void handleLabel(Token colon) {
|
void handleLabel(Token colon) {
|
||||||
Identifier name = popNode();
|
Identifier name = popNode();
|
||||||
pushNode(new Label(name, colon));
|
pushNode(new Label(name, colon));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void endLabeledStatement(int labelCount) {
|
void endLabeledStatement(int labelCount) {
|
||||||
Statement statement = popNode();
|
Statement statement = popNode();
|
||||||
NodeList labels = makeNodeList(labelCount, null, null, null);
|
NodeList labels = makeNodeList(labelCount, null, null, null);
|
||||||
pushNode(new LabeledStatement(labels, statement));
|
pushNode(new LabeledStatement(labels, statement));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void log(message) {
|
void log(message) {
|
||||||
reporter.log(message);
|
reporter.log(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void handleInvalidFunctionBody(Token token) {
|
||||||
|
if (!lastErrorWasNativeFunctionBody) {
|
||||||
|
pushNode(null);
|
||||||
|
}
|
||||||
|
lastErrorWasNativeFunctionBody = false;
|
||||||
|
}
|
||||||
|
|
||||||
void internalError({Token token, Node node}) {
|
void internalError({Token token, Node node}) {
|
||||||
// TODO(ahe): This should call reporter.internalError.
|
// TODO(ahe): This should call reporter.internalError.
|
||||||
Spannable spannable = (token == null) ? node : token;
|
Spannable spannable = (token == null) ? node : token;
|
||||||
|
|
|
@ -8,12 +8,11 @@ import '../common.dart';
|
||||||
import '../common/tasks.dart' show CompilerTask;
|
import '../common/tasks.dart' show CompilerTask;
|
||||||
import '../compiler.dart' show Compiler;
|
import '../compiler.dart' show Compiler;
|
||||||
import '../elements/modelx.dart' show ElementX;
|
import '../elements/modelx.dart' show ElementX;
|
||||||
import '../tokens/token.dart' show Token;
|
import 'package:front_end/src/fasta/scanner.dart' show Token;
|
||||||
import '../tree/tree.dart' show Node;
|
import '../tree/tree.dart' show Node;
|
||||||
import 'element_listener.dart' show ScannerOptions;
|
import 'element_listener.dart' show ScannerOptions;
|
||||||
import 'listener.dart' show ParserError;
|
import 'package:front_end/src/fasta/parser.dart' show Parser, ParserError;
|
||||||
import 'node_listener.dart' show NodeListener;
|
import 'node_listener.dart' show NodeListener;
|
||||||
import 'parser.dart' show Parser;
|
|
||||||
|
|
||||||
class ParserTask extends CompilerTask {
|
class ParserTask extends CompilerTask {
|
||||||
final Compiler compiler;
|
final Compiler compiler;
|
||||||
|
@ -36,7 +35,8 @@ class ParserTask extends CompilerTask {
|
||||||
try {
|
try {
|
||||||
parser.parseUnit(token);
|
parser.parseUnit(token);
|
||||||
} on ParserError catch (_) {
|
} on ParserError catch (_) {
|
||||||
assert(invariant(token, compiler.compilationFailed));
|
assert(invariant(compiler.reporter.spanFromToken(token),
|
||||||
|
compiler.compilationFailed));
|
||||||
return listener.makeNodeList(0, null, null, '\n');
|
return listener.makeNodeList(0, null, null, '\n');
|
||||||
}
|
}
|
||||||
Node result = listener.popNode();
|
Node result = listener.popNode();
|
||||||
|
|
|
@ -31,14 +31,20 @@ import '../elements/modelx.dart'
|
||||||
TypedefElementX,
|
TypedefElementX,
|
||||||
VariableList;
|
VariableList;
|
||||||
import '../elements/visitor.dart' show ElementVisitor;
|
import '../elements/visitor.dart' show ElementVisitor;
|
||||||
import '../tokens/token.dart' show Token;
|
import 'package:front_end/src/fasta/scanner.dart' show Token;
|
||||||
import '../tokens/token_constants.dart' as Tokens show EOF_TOKEN;
|
import 'package:front_end/src/fasta/scanner.dart' as Tokens show EOF_TOKEN;
|
||||||
import '../tree/tree.dart';
|
import '../tree/tree.dart';
|
||||||
import 'class_element_parser.dart' show ClassElementParser;
|
import 'package:front_end/src/fasta/parser.dart'
|
||||||
import 'listener.dart' show ParserError;
|
show ClassMemberParser, Listener, Parser, ParserError;
|
||||||
import 'member_listener.dart' show MemberListener;
|
import 'member_listener.dart' show MemberListener;
|
||||||
import 'node_listener.dart' show NodeListener;
|
import 'node_listener.dart' show NodeListener;
|
||||||
import 'parser.dart' show Parser;
|
|
||||||
|
class ClassElementParser extends ClassMemberParser {
|
||||||
|
ClassElementParser(Listener listener)
|
||||||
|
: super(listener);
|
||||||
|
|
||||||
|
Token parseFormalParameters(Token token) => skipFormalParameters(token);
|
||||||
|
}
|
||||||
|
|
||||||
abstract class PartialElement implements DeclarationSite {
|
abstract class PartialElement implements DeclarationSite {
|
||||||
Token beginToken;
|
Token beginToken;
|
||||||
|
@ -379,8 +385,9 @@ class PartialClassElement extends ClassElementX with PartialElement {
|
||||||
Token token = parser.parseTopLevelDeclaration(beginToken);
|
Token token = parser.parseTopLevelDeclaration(beginToken);
|
||||||
assert(identical(token, endToken.next));
|
assert(identical(token, endToken.next));
|
||||||
cachedNode = listener.popNode();
|
cachedNode = listener.popNode();
|
||||||
assert(invariant(beginToken, listener.nodes.isEmpty,
|
assert(invariant(reporter.spanFromToken(beginToken),
|
||||||
message: "Non-empty listener stack: ${listener.nodes}"));
|
listener.nodes.isEmpty,
|
||||||
|
message: "Non-empty listener stack: ${listener.nodes}"));
|
||||||
} on ParserError {
|
} on ParserError {
|
||||||
// TODO(ahe): Often, a ParserError is thrown while parsing the class
|
// TODO(ahe): Often, a ParserError is thrown while parsing the class
|
||||||
// body. This means that the stack actually contains most of the
|
// body. This means that the stack actually contains most of the
|
||||||
|
@ -443,7 +450,7 @@ Node parse(ParsingContext parsing, ElementX element, PartialElement partial,
|
||||||
doParse(new Parser(listener));
|
doParse(new Parser(listener));
|
||||||
} on ParserError catch (e) {
|
} on ParserError catch (e) {
|
||||||
partial.hasParseError = true;
|
partial.hasParseError = true;
|
||||||
return new ErrorNode(element.position, e.reason);
|
return new ErrorNode(element.position, e.kind, e.arguments);
|
||||||
}
|
}
|
||||||
Node node = listener.popNode();
|
Node node = listener.popNode();
|
||||||
assert(listener.nodes.isEmpty);
|
assert(listener.nodes.isEmpty);
|
||||||
|
|
|
@ -134,14 +134,14 @@ import 'id_generator.dart';
|
||||||
import 'js_backend/js_backend.dart' show JavaScriptBackend;
|
import 'js_backend/js_backend.dart' show JavaScriptBackend;
|
||||||
import 'library_loader.dart' show LibraryLoader;
|
import 'library_loader.dart' show LibraryLoader;
|
||||||
import 'parser/element_listener.dart' show ElementListener;
|
import 'parser/element_listener.dart' show ElementListener;
|
||||||
import 'parser/listener.dart' show Listener, ParserError;
|
import 'package:front_end/src/fasta/parser.dart'
|
||||||
|
show Listener, Parser, ParserError;
|
||||||
import 'parser/member_listener.dart' show MemberListener;
|
import 'parser/member_listener.dart' show MemberListener;
|
||||||
import 'parser/parser.dart' show Parser;
|
import 'parser/partial_elements.dart'
|
||||||
import 'parser/partial_elements.dart' show PartialClassElement;
|
show ClassElementParser, PartialClassElement;
|
||||||
import 'parser/partial_parser.dart' show PartialParser;
|
|
||||||
import 'scanner/scanner.dart' show Scanner;
|
|
||||||
import 'script.dart';
|
import 'script.dart';
|
||||||
import 'tokens/token.dart' show StringToken, Token;
|
import 'package:front_end/src/fasta/scanner.dart' show StringToken, Token;
|
||||||
|
import 'parser/diet_parser_task.dart' show PartialParser;
|
||||||
|
|
||||||
class PatchParserTask extends CompilerTask {
|
class PatchParserTask extends CompilerTask {
|
||||||
final String name = "Patching Parser";
|
final String name = "Patching Parser";
|
||||||
|
@ -178,7 +178,7 @@ class PatchParserTask extends CompilerTask {
|
||||||
measure(() {
|
measure(() {
|
||||||
// TODO(johnniwinther): Test that parts and exports are handled correctly.
|
// TODO(johnniwinther): Test that parts and exports are handled correctly.
|
||||||
Script script = compilationUnit.script;
|
Script script = compilationUnit.script;
|
||||||
Token tokens = new Scanner(script.file).tokenize();
|
Token tokens = compiler.scanner.scanFile(script.file);
|
||||||
Listener patchListener = new PatchElementListener(
|
Listener patchListener = new PatchElementListener(
|
||||||
compiler, compilationUnit, compiler.idGenerator);
|
compiler, compilationUnit, compiler.idGenerator);
|
||||||
try {
|
try {
|
||||||
|
@ -199,7 +199,7 @@ class PatchParserTask extends CompilerTask {
|
||||||
|
|
||||||
measure(() => reporter.withCurrentElement(cls, () {
|
measure(() => reporter.withCurrentElement(cls, () {
|
||||||
MemberListener listener = new PatchMemberListener(compiler, cls);
|
MemberListener listener = new PatchMemberListener(compiler, cls);
|
||||||
Parser parser = new PatchClassElementParser(listener);
|
Parser parser = new ClassElementParser(listener);
|
||||||
try {
|
try {
|
||||||
Token token = parser.parseTopLevelDeclaration(cls.beginToken);
|
Token token = parser.parseTopLevelDeclaration(cls.beginToken);
|
||||||
assert(identical(token, cls.endToken.next));
|
assert(identical(token, cls.endToken.next));
|
||||||
|
@ -244,16 +244,6 @@ class PatchMemberListener extends MemberListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Partial parser for patch files that also handles the members of class
|
|
||||||
* declarations.
|
|
||||||
*/
|
|
||||||
class PatchClassElementParser extends PartialParser {
|
|
||||||
PatchClassElementParser(Listener listener) : super(listener);
|
|
||||||
|
|
||||||
Token parseClassBody(Token token) => fullParseClassBody(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension of [ElementListener] for parsing patch files.
|
* Extension of [ElementListener] for parsing patch files.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -9,10 +9,9 @@ import '../core_types.dart' show CommonElements;
|
||||||
import '../elements/resolution_types.dart';
|
import '../elements/resolution_types.dart';
|
||||||
import '../elements/elements.dart';
|
import '../elements/elements.dart';
|
||||||
import '../elements/modelx.dart';
|
import '../elements/modelx.dart';
|
||||||
import '../tokens/keyword.dart' show Keyword;
|
import 'package:front_end/src/fasta/scanner.dart';
|
||||||
import '../tokens/precedence.dart';
|
import 'package:front_end/src/fasta/scanner/precedence.dart';
|
||||||
import '../tokens/precedence_constants.dart' as Precedence;
|
import 'package:front_end/src/fasta/scanner/precedence.dart' as Precedence;
|
||||||
import '../tokens/token.dart';
|
|
||||||
import '../tree/tree.dart';
|
import '../tree/tree.dart';
|
||||||
import '../util/util.dart';
|
import '../util/util.dart';
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ import '../elements/modelx.dart'
|
||||||
VariableElementX,
|
VariableElementX,
|
||||||
VariableList;
|
VariableList;
|
||||||
import '../options.dart';
|
import '../options.dart';
|
||||||
import '../tokens/token.dart' show isUserDefinableOperator;
|
import 'package:front_end/src/fasta/scanner.dart' show isUserDefinableOperator;
|
||||||
import '../tree/tree.dart';
|
import '../tree/tree.dart';
|
||||||
import '../universe/call_structure.dart' show CallStructure;
|
import '../universe/call_structure.dart' show CallStructure;
|
||||||
import '../universe/feature.dart' show Feature;
|
import '../universe/feature.dart' show Feature;
|
||||||
|
@ -2841,7 +2841,7 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
||||||
} else if (member.isFunction) {
|
} else if (member.isFunction) {
|
||||||
// `a = b`, `a++` or `a += b` where `a` is a function.
|
// `a = b`, `a++` or `a += b` where `a` is a function.
|
||||||
MethodElement method = member;
|
MethodElement method = member;
|
||||||
ErroneousElement error = reportAndCreateErroneousElement(
|
reportAndCreateErroneousElement(
|
||||||
node.selector, name.text, MessageKind.ASSIGNING_METHOD, const {});
|
node.selector, name.text, MessageKind.ASSIGNING_METHOD, const {});
|
||||||
registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
|
registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
|
||||||
if (node.isComplex) {
|
if (node.isComplex) {
|
||||||
|
@ -2860,7 +2860,7 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
||||||
registry.registerStaticUse(new StaticUse.staticGet(member));
|
registry.registerStaticUse(new StaticUse.staticGet(member));
|
||||||
}
|
}
|
||||||
if (member.isFinal || member.isConst) {
|
if (member.isFinal || member.isConst) {
|
||||||
ErroneousElement error = reportAndCreateErroneousElement(
|
reportAndCreateErroneousElement(
|
||||||
node.selector,
|
node.selector,
|
||||||
name.text,
|
name.text,
|
||||||
MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER,
|
MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER,
|
||||||
|
@ -3613,7 +3613,8 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
||||||
ResolutionResult visitYield(Yield node) {
|
ResolutionResult visitYield(Yield node) {
|
||||||
if (!resolution.target.supportsAsyncAwait) {
|
if (!resolution.target.supportsAsyncAwait) {
|
||||||
reporter.reportErrorMessage(
|
reporter.reportErrorMessage(
|
||||||
node.yieldToken, MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
|
reporter.spanFromToken(node.yieldToken),
|
||||||
|
MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
|
||||||
} else {
|
} else {
|
||||||
if (!currentAsyncMarker.isYielding) {
|
if (!currentAsyncMarker.isYielding) {
|
||||||
reporter.reportErrorMessage(node, MessageKind.INVALID_YIELD);
|
reporter.reportErrorMessage(node, MessageKind.INVALID_YIELD);
|
||||||
|
@ -3754,7 +3755,8 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
||||||
ResolutionResult visitAwait(Await node) {
|
ResolutionResult visitAwait(Await node) {
|
||||||
if (!resolution.target.supportsAsyncAwait) {
|
if (!resolution.target.supportsAsyncAwait) {
|
||||||
reporter.reportErrorMessage(
|
reporter.reportErrorMessage(
|
||||||
node.awaitToken, MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
|
reporter.spanFromToken(node.awaitToken),
|
||||||
|
MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
|
||||||
} else {
|
} else {
|
||||||
if (!currentAsyncMarker.isAsync) {
|
if (!currentAsyncMarker.isAsync) {
|
||||||
reporter.reportErrorMessage(node, MessageKind.INVALID_AWAIT);
|
reporter.reportErrorMessage(node, MessageKind.INVALID_AWAIT);
|
||||||
|
@ -4017,7 +4019,8 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
||||||
if (resolution.commonElements.isSymbolConstructor(constructor) &&
|
if (resolution.commonElements.isSymbolConstructor(constructor) &&
|
||||||
!resolution.mirrorUsageAnalyzerTask
|
!resolution.mirrorUsageAnalyzerTask
|
||||||
.hasMirrorUsage(enclosingElement)) {
|
.hasMirrorUsage(enclosingElement)) {
|
||||||
reporter.reportHintMessage(node.newToken, MessageKind.NON_CONST_BLOAT,
|
reporter.reportHintMessage(reporter.spanFromToken(node.newToken),
|
||||||
|
MessageKind.NON_CONST_BLOAT,
|
||||||
{'name': commonElements.symbolClass.name});
|
{'name': commonElements.symbolClass.name});
|
||||||
}
|
}
|
||||||
registry.registerNewStructure(
|
registry.registerNewStructure(
|
||||||
|
@ -4289,11 +4292,13 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
||||||
ResolutionResult visitAsyncForIn(AsyncForIn node) {
|
ResolutionResult visitAsyncForIn(AsyncForIn node) {
|
||||||
if (!resolution.target.supportsAsyncAwait) {
|
if (!resolution.target.supportsAsyncAwait) {
|
||||||
reporter.reportErrorMessage(
|
reporter.reportErrorMessage(
|
||||||
node.awaitToken, MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
|
reporter.spanFromToken(node.awaitToken),
|
||||||
|
MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
|
||||||
} else {
|
} else {
|
||||||
if (!currentAsyncMarker.isAsync) {
|
if (!currentAsyncMarker.isAsync) {
|
||||||
reporter.reportErrorMessage(
|
reporter.reportErrorMessage(
|
||||||
node.awaitToken, MessageKind.INVALID_AWAIT_FOR_IN);
|
reporter.spanFromToken(node.awaitToken),
|
||||||
|
MessageKind.INVALID_AWAIT_FOR_IN);
|
||||||
}
|
}
|
||||||
registry.registerFeature(Feature.ASYNC_FOR_IN);
|
registry.registerFeature(Feature.ASYNC_FOR_IN);
|
||||||
registry.registerDynamicUse(new DynamicUse(Selectors.current, null));
|
registry.registerDynamicUse(new DynamicUse(Selectors.current, null));
|
||||||
|
@ -4693,7 +4698,8 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
||||||
visit(node.tryBlock);
|
visit(node.tryBlock);
|
||||||
if (node.catchBlocks.isEmpty && node.finallyBlock == null) {
|
if (node.catchBlocks.isEmpty && node.finallyBlock == null) {
|
||||||
reporter.reportErrorMessage(
|
reporter.reportErrorMessage(
|
||||||
node.getEndToken().next, MessageKind.NO_CATCH_NOR_FINALLY);
|
reporter.spanFromToken(node.getEndToken().next),
|
||||||
|
MessageKind.NO_CATCH_NOR_FINALLY);
|
||||||
}
|
}
|
||||||
visit(node.catchBlocks);
|
visit(node.catchBlocks);
|
||||||
visit(node.finallyBlock);
|
visit(node.finallyBlock);
|
||||||
|
|
|
@ -37,7 +37,7 @@ import '../elements/modelx.dart'
|
||||||
TypedefElementX;
|
TypedefElementX;
|
||||||
import '../enqueue.dart';
|
import '../enqueue.dart';
|
||||||
import '../options.dart';
|
import '../options.dart';
|
||||||
import '../tokens/token.dart'
|
import 'package:front_end/src/fasta/scanner.dart'
|
||||||
show
|
show
|
||||||
isBinaryOperator,
|
isBinaryOperator,
|
||||||
isMinusOperator,
|
isMinusOperator,
|
||||||
|
@ -47,7 +47,7 @@ import '../tokens/token.dart'
|
||||||
import '../tree/tree.dart';
|
import '../tree/tree.dart';
|
||||||
import '../universe/call_structure.dart' show CallStructure;
|
import '../universe/call_structure.dart' show CallStructure;
|
||||||
import '../universe/feature.dart' show Feature;
|
import '../universe/feature.dart' show Feature;
|
||||||
import '../universe/use.dart' show StaticUse, TypeUse;
|
import '../universe/use.dart' show StaticUse;
|
||||||
import '../universe/world_impact.dart' show WorldImpact;
|
import '../universe/world_impact.dart' show WorldImpact;
|
||||||
import '../util/util.dart' show Link, Setlet;
|
import '../util/util.dart' show Link, Setlet;
|
||||||
import '../world.dart';
|
import '../world.dart';
|
||||||
|
@ -518,7 +518,6 @@ class ResolverTask extends CompilerTask {
|
||||||
ResolvedAst resolvedAst = factory.resolvedAst;
|
ResolvedAst resolvedAst = factory.resolvedAst;
|
||||||
assert(invariant(node, resolvedAst != null,
|
assert(invariant(node, resolvedAst != null,
|
||||||
message: 'No ResolvedAst for $factory.'));
|
message: 'No ResolvedAst for $factory.'));
|
||||||
FunctionExpression functionNode = resolvedAst.node;
|
|
||||||
RedirectingFactoryBody redirectionNode = resolvedAst.body;
|
RedirectingFactoryBody redirectionNode = resolvedAst.body;
|
||||||
ResolutionDartType factoryType =
|
ResolutionDartType factoryType =
|
||||||
resolvedAst.elements.getType(redirectionNode);
|
resolvedAst.elements.getType(redirectionNode);
|
||||||
|
|
|
@ -18,7 +18,6 @@ import '../elements/modelx.dart'
|
||||||
LocalParameterElementX,
|
LocalParameterElementX,
|
||||||
TypeVariableElementX;
|
TypeVariableElementX;
|
||||||
import '../tree/tree.dart';
|
import '../tree/tree.dart';
|
||||||
import '../universe/use.dart' show TypeUse;
|
|
||||||
import '../util/util.dart' show Link, LinkBuilder;
|
import '../util/util.dart' show Link, LinkBuilder;
|
||||||
import 'members.dart' show ResolverVisitor;
|
import 'members.dart' show ResolverVisitor;
|
||||||
import 'registry.dart' show ResolutionRegistry;
|
import 'registry.dart' show ResolutionRegistry;
|
||||||
|
|
|
@ -8,7 +8,6 @@ import '../common.dart';
|
||||||
import '../common/resolution.dart';
|
import '../common/resolution.dart';
|
||||||
import '../elements/modelx.dart' show LocalVariableElementX, VariableList;
|
import '../elements/modelx.dart' show LocalVariableElementX, VariableList;
|
||||||
import '../tree/tree.dart';
|
import '../tree/tree.dart';
|
||||||
import '../universe/use.dart' show TypeUse;
|
|
||||||
import '../universe/feature.dart';
|
import '../universe/feature.dart';
|
||||||
import '../util/util.dart' show Link;
|
import '../util/util.dart' show Link;
|
||||||
import 'members.dart' show ResolverVisitor;
|
import 'members.dart' show ResolverVisitor;
|
||||||
|
|
|
@ -9,11 +9,12 @@ import '../diagnostics/diagnostic_listener.dart' show DiagnosticReporter;
|
||||||
import '../elements/elements.dart' show CompilationUnitElement, LibraryElement;
|
import '../elements/elements.dart' show CompilationUnitElement, LibraryElement;
|
||||||
import '../parser/diet_parser_task.dart' show DietParserTask;
|
import '../parser/diet_parser_task.dart' show DietParserTask;
|
||||||
import '../script.dart' show Script;
|
import '../script.dart' show Script;
|
||||||
import '../tokens/token.dart' show Token;
|
import 'package:front_end/src/fasta/scanner.dart'
|
||||||
import '../tokens/token_constants.dart' as Tokens show COMMENT_TOKEN, EOF_TOKEN;
|
show Scanner, StringScanner, Token, Utf8BytesScanner;
|
||||||
|
import 'package:front_end/src/fasta/scanner/token_constants.dart' as Tokens
|
||||||
|
show COMMENT_TOKEN, EOF_TOKEN;
|
||||||
import '../tokens/token_map.dart' show TokenMap;
|
import '../tokens/token_map.dart' show TokenMap;
|
||||||
import 'scanner.dart' show Scanner;
|
import '../io/source_file.dart';
|
||||||
import 'string_scanner.dart' show StringScanner;
|
|
||||||
|
|
||||||
class ScannerTask extends CompilerTask {
|
class ScannerTask extends CompilerTask {
|
||||||
final DietParserTask _dietParser;
|
final DietParserTask _dietParser;
|
||||||
|
@ -52,10 +53,17 @@ class ScannerTask extends CompilerTask {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Token scanFile(SourceFile file, {bool includeComments: false}) {
|
||||||
|
Scanner scanner = file is Utf8BytesSourceFile
|
||||||
|
? new Utf8BytesScanner(file.slowUtf8ZeroTerminatedBytes(),
|
||||||
|
includeComments: includeComments)
|
||||||
|
: new StringScanner(file.slowText(), includeComments: includeComments);
|
||||||
|
return measure(scanner.tokenize);
|
||||||
|
}
|
||||||
|
|
||||||
void scanElements(CompilationUnitElement compilationUnit) {
|
void scanElements(CompilationUnitElement compilationUnit) {
|
||||||
Script script = compilationUnit.script;
|
Script script = compilationUnit.script;
|
||||||
Token tokens =
|
Token tokens = scanFile(script.file, includeComments: _preserveComments);
|
||||||
new Scanner(script.file, includeComments: _preserveComments).tokenize();
|
|
||||||
if (_preserveComments) {
|
if (_preserveComments) {
|
||||||
tokens = processAndStripComments(tokens);
|
tokens = processAndStripComments(tokens);
|
||||||
}
|
}
|
||||||
|
@ -71,8 +79,7 @@ class ScannerTask extends CompilerTask {
|
||||||
*/
|
*/
|
||||||
Token tokenize(String source) {
|
Token tokenize(String source) {
|
||||||
return measure(() {
|
return measure(() {
|
||||||
return new StringScanner.fromString(source, includeComments: false)
|
return new StringScanner(source, includeComments: false).tokenize();
|
||||||
.tokenize();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ import '../native/native.dart' show NativeBehavior;
|
||||||
import '../resolution/access_semantics.dart';
|
import '../resolution/access_semantics.dart';
|
||||||
import '../resolution/send_structure.dart';
|
import '../resolution/send_structure.dart';
|
||||||
import '../resolution/tree_elements.dart';
|
import '../resolution/tree_elements.dart';
|
||||||
import '../tokens/token.dart';
|
import 'package:front_end/src/fasta/scanner.dart';
|
||||||
import '../tree/nodes.dart';
|
import '../tree/nodes.dart';
|
||||||
import '../universe/selector.dart';
|
import '../universe/selector.dart';
|
||||||
import '../universe/feature.dart';
|
import '../universe/feature.dart';
|
||||||
|
@ -1437,7 +1437,10 @@ class NodeEquivalenceVisitor implements Visitor1<bool, Node> {
|
||||||
(Token t1, Token t2) {
|
(Token t1, Token t2) {
|
||||||
if (t1 == t2) return true;
|
if (t1 == t2) return true;
|
||||||
if (t1 == null || t2 == null) return false;
|
if (t1 == null || t2 == null) return false;
|
||||||
return strategy.test(t1, t2, 'hashCode', t1.hashCode, t2.hashCode);
|
return
|
||||||
|
strategy.test(t1, t2, 'charOffset', t1.charOffset, t2.charOffset) &&
|
||||||
|
strategy.test(t1, t2, 'info', t1.info, t2.info) &&
|
||||||
|
strategy.test(t1, t2, 'value', t1.value, t2.value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ import '../resolution/scope.dart' show Scope;
|
||||||
import '../resolution/tree_elements.dart' show TreeElements;
|
import '../resolution/tree_elements.dart' show TreeElements;
|
||||||
import '../script.dart';
|
import '../script.dart';
|
||||||
import '../serialization/constant_serialization.dart';
|
import '../serialization/constant_serialization.dart';
|
||||||
import '../tokens/token.dart' show Token;
|
import 'package:front_end/src/fasta/scanner.dart' show Token;
|
||||||
import '../tree/tree.dart';
|
import '../tree/tree.dart';
|
||||||
import '../util/util.dart' show Link, LinkBuilder;
|
import '../util/util.dart' show Link, LinkBuilder;
|
||||||
import 'keys.dart';
|
import 'keys.dart';
|
||||||
|
@ -1572,7 +1572,6 @@ abstract class MemberElementMixin
|
||||||
@override
|
@override
|
||||||
bool get isInjected => _decoder.getBool(Key.IS_INJECTED);
|
bool get isInjected => _decoder.getBool(Key.IS_INJECTED);
|
||||||
|
|
||||||
@override
|
|
||||||
void forgetElement() {
|
void forgetElement() {
|
||||||
nestedClosures.clear();
|
nestedClosures.clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,16 +11,14 @@ import '../elements/resolution_types.dart';
|
||||||
import '../diagnostics/diagnostic_listener.dart';
|
import '../diagnostics/diagnostic_listener.dart';
|
||||||
import '../elements/elements.dart';
|
import '../elements/elements.dart';
|
||||||
import '../elements/modelx.dart';
|
import '../elements/modelx.dart';
|
||||||
import '../parser/listener.dart' show ParserError;
|
import 'package:front_end/src/fasta/parser.dart' show Parser, ParserError;
|
||||||
import '../parser/node_listener.dart' show NodeListener;
|
import '../parser/node_listener.dart' show NodeListener;
|
||||||
import '../parser/parser.dart' show Parser;
|
|
||||||
import '../resolution/enum_creator.dart';
|
import '../resolution/enum_creator.dart';
|
||||||
import '../resolution/send_structure.dart';
|
import '../resolution/send_structure.dart';
|
||||||
import '../resolution/tree_elements.dart';
|
import '../resolution/tree_elements.dart';
|
||||||
import '../tokens/token.dart';
|
import 'package:front_end/src/fasta/scanner.dart';
|
||||||
import '../tree/tree.dart';
|
import '../tree/tree.dart';
|
||||||
import '../universe/selector.dart';
|
import '../universe/selector.dart';
|
||||||
import '../util/util.dart';
|
|
||||||
import 'keys.dart';
|
import 'keys.dart';
|
||||||
import 'modelz.dart';
|
import 'modelz.dart';
|
||||||
import 'serialization.dart';
|
import 'serialization.dart';
|
||||||
|
@ -374,7 +372,6 @@ class ResolvedAstDeserializer {
|
||||||
ParsingContext parsing,
|
ParsingContext parsing,
|
||||||
Token getBeginToken(Uri uri, int charOffset),
|
Token getBeginToken(Uri uri, int charOffset),
|
||||||
DeserializerPlugin nativeDataDeserializer) {
|
DeserializerPlugin nativeDataDeserializer) {
|
||||||
CompilationUnitElement compilationUnit = element.compilationUnit;
|
|
||||||
DiagnosticReporter reporter = parsing.reporter;
|
DiagnosticReporter reporter = parsing.reporter;
|
||||||
Uri uri = objectDecoder.getUri(Key.URI);
|
Uri uri = objectDecoder.getUri(Key.URI);
|
||||||
|
|
||||||
|
@ -395,7 +392,6 @@ class ResolvedAstDeserializer {
|
||||||
Node doParse(parse(Parser parser)) {
|
Node doParse(parse(Parser parser)) {
|
||||||
return parsing.measure(() {
|
return parsing.measure(() {
|
||||||
return reporter.withCurrentElement(element, () {
|
return reporter.withCurrentElement(element, () {
|
||||||
CompilationUnitElement unit = element.compilationUnit;
|
|
||||||
NodeListener listener = new NodeListener(
|
NodeListener listener = new NodeListener(
|
||||||
parsing.getScannerOptionsFor(element), reporter, null);
|
parsing.getScannerOptionsFor(element), reporter, null);
|
||||||
listener.memberErrors = listener.memberErrors.prepend(false);
|
listener.memberErrors = listener.memberErrors.prepend(false);
|
||||||
|
@ -424,7 +420,6 @@ class ResolvedAstDeserializer {
|
||||||
case AstKind.ENUM_VALUES_FIELD:
|
case AstKind.ENUM_VALUES_FIELD:
|
||||||
EnumClassElement enumClass = element.enclosingClass;
|
EnumClassElement enumClass = element.enclosingClass;
|
||||||
AstBuilder builder = new AstBuilder(element.sourcePosition.begin);
|
AstBuilder builder = new AstBuilder(element.sourcePosition.begin);
|
||||||
List<FieldElement> enumValues = <FieldElement>[];
|
|
||||||
List<Node> valueReferences = <Node>[];
|
List<Node> valueReferences = <Node>[];
|
||||||
for (EnumConstantElement enumConstant in enumClass.enumValues) {
|
for (EnumConstantElement enumConstant in enumClass.enumValues) {
|
||||||
AstBuilder valueBuilder =
|
AstBuilder valueBuilder =
|
||||||
|
@ -532,7 +527,6 @@ class ResolvedAstDeserializer {
|
||||||
Node root = computeNode(kind);
|
Node root = computeNode(kind);
|
||||||
TreeElementMapping elements = new TreeElementMapping(element);
|
TreeElementMapping elements = new TreeElementMapping(element);
|
||||||
AstIndexComputer indexComputer = new AstIndexComputer();
|
AstIndexComputer indexComputer = new AstIndexComputer();
|
||||||
Map<Node, int> nodeIndices = indexComputer.nodeIndices;
|
|
||||||
List<Node> nodeList = indexComputer.nodeList;
|
List<Node> nodeList = indexComputer.nodeList;
|
||||||
root.accept(indexComputer);
|
root.accept(indexComputer);
|
||||||
elements.containsTryStatement = objectDecoder.getBool(Key.CONTAINS_TRY);
|
elements.containsTryStatement = objectDecoder.getBool(Key.CONTAINS_TRY);
|
||||||
|
|
|
@ -659,7 +659,6 @@ bool includeAllElements(Element element) => true;
|
||||||
class Serializer {
|
class Serializer {
|
||||||
List<SerializerPlugin> plugins = <SerializerPlugin>[];
|
List<SerializerPlugin> plugins = <SerializerPlugin>[];
|
||||||
|
|
||||||
Map<Uri, dynamic> _dependencyMap = <Uri, dynamic>{};
|
|
||||||
Map<Element, DataObject> _elementMap = <Element, DataObject>{};
|
Map<Element, DataObject> _elementMap = <Element, DataObject>{};
|
||||||
Map<ConstantExpression, DataObject> _constantMap =
|
Map<ConstantExpression, DataObject> _constantMap =
|
||||||
<ConstantExpression, DataObject>{};
|
<ConstantExpression, DataObject>{};
|
||||||
|
|
|
@ -52,9 +52,6 @@ Selector deserializeSelector(ObjectDecoder decoder) {
|
||||||
int argumentCount = decoder.getInt(Key.ARGUMENTS);
|
int argumentCount = decoder.getInt(Key.ARGUMENTS);
|
||||||
List<String> namedArguments =
|
List<String> namedArguments =
|
||||||
decoder.getStrings(Key.NAMED_ARGUMENTS, isOptional: true);
|
decoder.getStrings(Key.NAMED_ARGUMENTS, isOptional: true);
|
||||||
String name = decoder.getString(Key.NAME);
|
|
||||||
bool isSetter = decoder.getBool(Key.IS_SETTER);
|
|
||||||
LibraryElement library = decoder.getElement(Key.LIBRARY, isOptional: true);
|
|
||||||
return new Selector(kind, deserializeName(decoder),
|
return new Selector(kind, deserializeName(decoder),
|
||||||
new CallStructure(argumentCount, namedArguments));
|
new CallStructure(argumentCount, namedArguments));
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,9 @@ import '../common/resolution.dart';
|
||||||
import '../compiler.dart';
|
import '../compiler.dart';
|
||||||
import '../elements/resolution_types.dart';
|
import '../elements/resolution_types.dart';
|
||||||
import '../elements/elements.dart';
|
import '../elements/elements.dart';
|
||||||
import '../scanner/scanner.dart';
|
|
||||||
import '../script.dart';
|
import '../script.dart';
|
||||||
import '../serialization/impact_serialization.dart';
|
import '../serialization/impact_serialization.dart';
|
||||||
import '../tokens/token.dart';
|
import 'package:front_end/src/fasta/scanner.dart';
|
||||||
import '../universe/call_structure.dart';
|
import '../universe/call_structure.dart';
|
||||||
import '../universe/use.dart';
|
import '../universe/use.dart';
|
||||||
import '../universe/world_impact.dart';
|
import '../universe/world_impact.dart';
|
||||||
|
@ -315,7 +314,7 @@ class ResolvedAstDeserializerPlugin extends DeserializerPlugin {
|
||||||
'No source file found for $uri in:\n ${scripts.keys.join('\n ')}');
|
'No source file found for $uri in:\n ${scripts.keys.join('\n ')}');
|
||||||
}
|
}
|
||||||
if (script.isSynthesized) return null;
|
if (script.isSynthesized) return null;
|
||||||
return new Scanner(script.file).tokenize();
|
return parsingContext.scanner.scanFile(script.file);
|
||||||
});
|
});
|
||||||
if (beginToken == null) return null;
|
if (beginToken == null) return null;
|
||||||
return ResolvedAstDeserializer.findTokenInStream(beginToken, offset);
|
return ResolvedAstDeserializer.findTokenInStream(beginToken, offset);
|
||||||
|
|
|
@ -10,7 +10,6 @@ import '../common/resolution.dart' show ResolutionImpact, ResolutionWorkItem;
|
||||||
import '../common/tasks.dart' show CompilerTask;
|
import '../common/tasks.dart' show CompilerTask;
|
||||||
import '../compiler.dart' show Compiler;
|
import '../compiler.dart' show Compiler;
|
||||||
import '../elements/elements.dart';
|
import '../elements/elements.dart';
|
||||||
import '../enqueue.dart' show ResolutionEnqueuer;
|
|
||||||
import '../universe/world_impact.dart' show WorldImpact;
|
import '../universe/world_impact.dart' show WorldImpact;
|
||||||
import 'json_serializer.dart';
|
import 'json_serializer.dart';
|
||||||
import 'serialization.dart';
|
import 'serialization.dart';
|
||||||
|
|
|
@ -1140,7 +1140,6 @@ class SsaBuilder extends ast.Visitor
|
||||||
if (compiler.elementHasCompileTimeError(member)) return;
|
if (compiler.elementHasCompileTimeError(member)) return;
|
||||||
reporter.withCurrentElement(member, () {
|
reporter.withCurrentElement(member, () {
|
||||||
ResolvedAst fieldResolvedAst = member.resolvedAst;
|
ResolvedAst fieldResolvedAst = member.resolvedAst;
|
||||||
ast.Node node = fieldResolvedAst.node;
|
|
||||||
ast.Expression initializer = fieldResolvedAst.body;
|
ast.Expression initializer = fieldResolvedAst.body;
|
||||||
if (initializer == null) {
|
if (initializer == null) {
|
||||||
// Unassigned fields of native classes are not initialized to
|
// Unassigned fields of native classes are not initialized to
|
||||||
|
|
|
@ -26,7 +26,7 @@ import '../kernel/kernel.dart';
|
||||||
import '../native/native.dart' as native;
|
import '../native/native.dart' as native;
|
||||||
import '../resolution/tree_elements.dart';
|
import '../resolution/tree_elements.dart';
|
||||||
import '../tree/dartstring.dart';
|
import '../tree/dartstring.dart';
|
||||||
import '../tree/nodes.dart' show Node, BreakStatement;
|
import '../tree/nodes.dart' show Node;
|
||||||
import '../types/masks.dart';
|
import '../types/masks.dart';
|
||||||
import '../universe/call_structure.dart' show CallStructure;
|
import '../universe/call_structure.dart' show CallStructure;
|
||||||
import '../universe/selector.dart';
|
import '../universe/selector.dart';
|
||||||
|
@ -663,7 +663,6 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
|
||||||
returnStatement.expression.accept(this);
|
returnStatement.expression.accept(this);
|
||||||
value = pop();
|
value = pop();
|
||||||
if (_targetFunction.asyncMarker == ir.AsyncMarker.Async) {
|
if (_targetFunction.asyncMarker == ir.AsyncMarker.Async) {
|
||||||
var returnType = astAdapter.getDartType(_targetFunction.returnType);
|
|
||||||
if (compiler.options.enableTypeAssertions &&
|
if (compiler.options.enableTypeAssertions &&
|
||||||
!isValidAsyncReturnType(_targetFunction.returnType)) {
|
!isValidAsyncReturnType(_targetFunction.returnType)) {
|
||||||
generateTypeError(
|
generateTypeError(
|
||||||
|
@ -1309,12 +1308,12 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
|
||||||
int switchIndex = 1;
|
int switchIndex = 1;
|
||||||
bool hasDefault = false;
|
bool hasDefault = false;
|
||||||
for (ir.SwitchCase switchCase in switchStatement.cases) {
|
for (ir.SwitchCase switchCase in switchStatement.cases) {
|
||||||
|
if (_isDefaultCase(switchCase)) {
|
||||||
|
hasDefault = true;
|
||||||
|
}
|
||||||
if (SwitchContinueAnalysis.containsContinue(switchCase.body)) {
|
if (SwitchContinueAnalysis.containsContinue(switchCase.body)) {
|
||||||
hasContinue = true;
|
hasContinue = true;
|
||||||
}
|
}
|
||||||
if (switchCase.isDefault) {
|
|
||||||
hasDefault = true;
|
|
||||||
}
|
|
||||||
caseIndex[switchCase] = switchIndex;
|
caseIndex[switchCase] = switchIndex;
|
||||||
switchIndex++;
|
switchIndex++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,10 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
import '../common.dart';
|
|
||||||
import '../common/codegen.dart' show CodegenRegistry;
|
import '../common/codegen.dart' show CodegenRegistry;
|
||||||
import '../compiler.dart';
|
import '../compiler.dart';
|
||||||
import '../elements/elements.dart';
|
import '../elements/elements.dart';
|
||||||
import '../elements/entities.dart';
|
import '../elements/entities.dart' show Entity, Local;
|
||||||
import '../elements/resolution_types.dart';
|
import '../elements/resolution_types.dart';
|
||||||
import '../js_backend/js_backend.dart';
|
import '../js_backend/js_backend.dart';
|
||||||
import '../resolution/tree_elements.dart';
|
import '../resolution/tree_elements.dart';
|
||||||
|
|
|
@ -6,7 +6,6 @@ import '../common.dart';
|
||||||
import '../elements/elements.dart';
|
import '../elements/elements.dart';
|
||||||
import '../tree/tree.dart' as ast;
|
import '../tree/tree.dart' as ast;
|
||||||
|
|
||||||
import 'builder.dart';
|
|
||||||
import 'graph_builder.dart';
|
import 'graph_builder.dart';
|
||||||
import 'locals_handler.dart';
|
import 'locals_handler.dart';
|
||||||
import 'nodes.dart';
|
import 'nodes.dart';
|
||||||
|
|
|
@ -6,7 +6,6 @@ import 'package:js_runtime/shared/embedded_names.dart';
|
||||||
import 'package:kernel/ast.dart' as ir;
|
import 'package:kernel/ast.dart' as ir;
|
||||||
|
|
||||||
import '../common.dart';
|
import '../common.dart';
|
||||||
import '../common/names.dart';
|
|
||||||
import '../compiler.dart';
|
import '../compiler.dart';
|
||||||
import '../constants/expressions.dart';
|
import '../constants/expressions.dart';
|
||||||
import '../constants/values.dart';
|
import '../constants/values.dart';
|
||||||
|
@ -17,7 +16,6 @@ import '../elements/entities.dart';
|
||||||
import '../elements/modelx.dart';
|
import '../elements/modelx.dart';
|
||||||
import '../elements/types.dart';
|
import '../elements/types.dart';
|
||||||
import '../js/js.dart' as js;
|
import '../js/js.dart' as js;
|
||||||
import '../js_backend/backend_helpers.dart';
|
|
||||||
import '../js_backend/js_backend.dart';
|
import '../js_backend/js_backend.dart';
|
||||||
import '../kernel/element_adapter.dart';
|
import '../kernel/element_adapter.dart';
|
||||||
import '../kernel/kernel.dart';
|
import '../kernel/kernel.dart';
|
||||||
|
@ -766,7 +764,7 @@ class Constantifier extends ir.ExpressionVisitor<ConstantExpression> {
|
||||||
ConstantExpression visitStaticGet(ir.StaticGet node) {
|
ConstantExpression visitStaticGet(ir.StaticGet node) {
|
||||||
Element element = astAdapter.getMember(node.target);
|
Element element = astAdapter.getMember(node.target);
|
||||||
if (element.isField) {
|
if (element.isField) {
|
||||||
return new VariableConstantExpression(element);
|
return new VariableConstantExpression(element as VariableElement);
|
||||||
}
|
}
|
||||||
astAdapter.reporter.internalError(
|
astAdapter.reporter.internalError(
|
||||||
CURRENT_ELEMENT_SPANNABLE, "Unexpected constant target: $element.");
|
CURRENT_ELEMENT_SPANNABLE, "Unexpected constant target: $element.");
|
||||||
|
|
|
@ -487,7 +487,6 @@ class LocalsHandler {
|
||||||
Map<Local, HInstruction> savedDirectLocals =
|
Map<Local, HInstruction> savedDirectLocals =
|
||||||
new Map<Local, HInstruction>.from(directLocals);
|
new Map<Local, HInstruction>.from(directLocals);
|
||||||
|
|
||||||
JavaScriptBackend backend = _compiler.backend;
|
|
||||||
// Create phis for all elements in the definitions environment.
|
// Create phis for all elements in the definitions environment.
|
||||||
savedDirectLocals.forEach((Local local, HInstruction instruction) {
|
savedDirectLocals.forEach((Local local, HInstruction instruction) {
|
||||||
if (isAccessedDirectly(local)) {
|
if (isAccessedDirectly(local)) {
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
import '../compiler.dart';
|
import '../compiler.dart';
|
||||||
import '../io/source_information.dart';
|
import '../io/source_information.dart';
|
||||||
import '../js_backend/js_backend.dart';
|
|
||||||
import '../tree/tree.dart' as ast;
|
import '../tree/tree.dart' as ast;
|
||||||
|
|
||||||
import 'graph_builder.dart';
|
import 'graph_builder.dart';
|
||||||
|
|
|
@ -9,10 +9,10 @@ library stringvalidator;
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
|
||||||
import 'common.dart';
|
import 'common.dart';
|
||||||
import 'tokens/token.dart' show Token;
|
import 'package:front_end/src/fasta/scanner.dart' show Token;
|
||||||
import 'tree/dartstring.dart' show DartString;
|
import 'tree/dartstring.dart' show DartString;
|
||||||
import 'tree/nodes.dart' show StringQuoting;
|
import 'tree/nodes.dart' show StringQuoting;
|
||||||
import 'util/characters.dart';
|
import 'package:front_end/src/fasta/scanner/characters.dart';
|
||||||
|
|
||||||
class StringValidator {
|
class StringValidator {
|
||||||
final DiagnosticReporter reporter;
|
final DiagnosticReporter reporter;
|
||||||
|
@ -100,7 +100,8 @@ class StringValidator {
|
||||||
|
|
||||||
void stringParseError(String message, Token token, int offset) {
|
void stringParseError(String message, Token token, int offset) {
|
||||||
reporter.reportErrorMessage(
|
reporter.reportErrorMessage(
|
||||||
token, MessageKind.GENERIC, {'text': "$message @ $offset"});
|
reporter.spanFromToken(token), MessageKind.GENERIC,
|
||||||
|
{'text': "$message @ $offset"});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,19 +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.tokens.precedence;
|
|
||||||
|
|
||||||
import '../util/util.dart' show computeHashCode;
|
|
||||||
|
|
||||||
class PrecedenceInfo {
|
|
||||||
final String value;
|
|
||||||
final int precedence;
|
|
||||||
final int kind;
|
|
||||||
|
|
||||||
const PrecedenceInfo(this.value, this.precedence, this.kind);
|
|
||||||
|
|
||||||
toString() => 'PrecedenceInfo($value, $precedence, $kind)';
|
|
||||||
|
|
||||||
int get hashCode => computeHashCode(value, precedence, kind);
|
|
||||||
}
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
library dart2js.tokens.token_map;
|
library dart2js.tokens.token_map;
|
||||||
|
|
||||||
import 'token.dart' show Token;
|
import 'package:front_end/src/fasta/scanner.dart' show Token;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Key class used in [TokenMap] in which the hash code for a token is based
|
* Key class used in [TokenMap] in which the hash code for a token is based
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
|
||||||
import '../util/characters.dart';
|
import 'package:front_end/src/fasta/scanner/characters.dart';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The [DartString] type represents a Dart string value as a sequence of Unicode
|
* The [DartString] type represents a Dart string value as a sequence of Unicode
|
||||||
|
|
|
@ -8,14 +8,17 @@ import '../common.dart';
|
||||||
import '../elements/elements.dart' show MetadataAnnotation;
|
import '../elements/elements.dart' show MetadataAnnotation;
|
||||||
import '../resolution/secret_tree_element.dart'
|
import '../resolution/secret_tree_element.dart'
|
||||||
show NullTreeElementMixin, StoredTreeElementMixin;
|
show NullTreeElementMixin, StoredTreeElementMixin;
|
||||||
import '../tokens/precedence_constants.dart' as Precedence show FUNCTION_INFO;
|
import 'package:front_end/src/fasta/scanner/precedence.dart' as Precedence
|
||||||
import '../tokens/token.dart' show BeginGroupToken, Token;
|
show FUNCTION_INFO;
|
||||||
import '../tokens/token_constants.dart' as Tokens show PLUS_TOKEN;
|
import 'package:front_end/src/fasta/scanner.dart' show BeginGroupToken, Token;
|
||||||
import '../util/characters.dart';
|
import 'package:front_end/src/fasta/scanner/token_constants.dart' as Tokens
|
||||||
|
show PLUS_TOKEN;
|
||||||
|
import 'package:front_end/src/fasta/scanner/characters.dart';
|
||||||
import '../util/util.dart';
|
import '../util/util.dart';
|
||||||
import 'dartstring.dart';
|
import 'dartstring.dart';
|
||||||
import 'prettyprint.dart';
|
import 'prettyprint.dart';
|
||||||
import 'unparser.dart';
|
import 'unparser.dart';
|
||||||
|
import 'package:front_end/src/fasta/parser.dart' show ErrorKind;
|
||||||
|
|
||||||
abstract class Visitor<R> {
|
abstract class Visitor<R> {
|
||||||
const Visitor();
|
const Visitor();
|
||||||
|
@ -478,7 +481,7 @@ class ClassNode extends Node {
|
||||||
if (token == null) {
|
if (token == null) {
|
||||||
token = name.getEndToken();
|
token = name.getEndToken();
|
||||||
}
|
}
|
||||||
assert(invariant(beginToken, token != null));
|
assert(token != null);
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3086,17 +3089,19 @@ class IsInterpolationVisitor extends Visitor<bool> {
|
||||||
class ErrorNode extends Node
|
class ErrorNode extends Node
|
||||||
implements FunctionExpression, VariableDefinitions, Typedef {
|
implements FunctionExpression, VariableDefinitions, Typedef {
|
||||||
final Token token;
|
final Token token;
|
||||||
final String reason;
|
final ErrorKind kind;
|
||||||
|
final Map arguments;
|
||||||
final Identifier name;
|
final Identifier name;
|
||||||
final NodeList definitions;
|
final NodeList definitions;
|
||||||
|
|
||||||
ErrorNode.internal(this.token, this.reason, this.name, this.definitions);
|
ErrorNode.internal(
|
||||||
|
this.token, this.kind, this.arguments, this.name, this.definitions);
|
||||||
|
|
||||||
factory ErrorNode(Token token, String reason) {
|
factory ErrorNode(Token token, ErrorKind kind, Map arguments) {
|
||||||
Identifier name = new Identifier(token);
|
Identifier name = new Identifier(token);
|
||||||
NodeList definitions =
|
NodeList definitions =
|
||||||
new NodeList(null, const Link<Node>().prepend(name), null, null);
|
new NodeList(null, const Link<Node>().prepend(name), null, null);
|
||||||
return new ErrorNode.internal(token, reason, name, definitions);
|
return new ErrorNode.internal(token, kind, arguments, name, definitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
Token get beginToken => token;
|
Token get beginToken => token;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
import '../tokens/token.dart' show Token;
|
import 'package:front_end/src/fasta/scanner.dart' show Token;
|
||||||
import '../util/util.dart';
|
import '../util/util.dart';
|
||||||
import 'nodes.dart';
|
import 'nodes.dart';
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
import '../tokens/token.dart' show Token;
|
import 'package:front_end/src/fasta/scanner.dart' show Token;
|
||||||
import '../tokens/token_constants.dart' as Tokens
|
import 'package:front_end/src/fasta/scanner/token_constants.dart' as Tokens
|
||||||
show IDENTIFIER_TOKEN, KEYWORD_TOKEN, PLUS_TOKEN;
|
show IDENTIFIER_TOKEN, KEYWORD_TOKEN, PLUS_TOKEN;
|
||||||
import '../util/util.dart';
|
import '../util/util.dart';
|
||||||
import 'nodes.dart';
|
import 'nodes.dart';
|
||||||
|
|
|
@ -5,11 +5,8 @@
|
||||||
library types.constants;
|
library types.constants;
|
||||||
|
|
||||||
import '../common.dart';
|
import '../common.dart';
|
||||||
import '../constants/constant_system.dart' show ConstantSystem;
|
|
||||||
import '../compiler.dart' show Compiler;
|
|
||||||
import '../constants/values.dart';
|
import '../constants/values.dart';
|
||||||
import '../js_backend/js_backend.dart'
|
import '../js_backend/js_backend.dart' show SyntheticConstantKind;
|
||||||
show JavaScriptBackend, SyntheticConstantKind;
|
|
||||||
import '../world.dart' show ClosedWorld;
|
import '../world.dart' show ClosedWorld;
|
||||||
import 'masks.dart';
|
import 'masks.dart';
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
library dart2js.call_structure;
|
library dart2js.call_structure;
|
||||||
|
|
||||||
import '../common.dart';
|
|
||||||
import '../common/names.dart' show Names;
|
import '../common/names.dart' show Names;
|
||||||
import '../elements/types.dart' show FunctionType;
|
import '../elements/types.dart' show FunctionType;
|
||||||
import '../util/util.dart';
|
import '../util/util.dart';
|
||||||
|
|
|
@ -6,7 +6,6 @@ library dart2js.world.class_set;
|
||||||
|
|
||||||
import 'dart:collection' show IterableBase;
|
import 'dart:collection' show IterableBase;
|
||||||
|
|
||||||
import '../common.dart';
|
|
||||||
import '../elements/elements.dart' show ClassElement;
|
import '../elements/elements.dart' show ClassElement;
|
||||||
import '../util/enumset.dart' show EnumSet;
|
import '../util/enumset.dart' show EnumSet;
|
||||||
import '../util/util.dart' show Link;
|
import '../util/util.dart' show Link;
|
||||||
|
|
|
@ -22,7 +22,6 @@ import '../universe/function_set.dart' show FunctionSetBuilder;
|
||||||
import '../util/enumset.dart';
|
import '../util/enumset.dart';
|
||||||
import '../util/util.dart';
|
import '../util/util.dart';
|
||||||
import '../world.dart' show World, ClosedWorld, ClosedWorldImpl, OpenWorld;
|
import '../world.dart' show World, ClosedWorld, ClosedWorldImpl, OpenWorld;
|
||||||
import 'call_structure.dart' show CallStructure;
|
|
||||||
import 'selector.dart' show Selector;
|
import 'selector.dart' show Selector;
|
||||||
import 'use.dart' show DynamicUse, DynamicUseKind, StaticUse, StaticUseKind;
|
import 'use.dart' show DynamicUse, DynamicUseKind, StaticUse, StaticUseKind;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
library dart2js.universe.world_impact;
|
library dart2js.universe.world_impact;
|
||||||
|
|
||||||
import '../elements/elements.dart' show Element;
|
|
||||||
import '../util/util.dart' show Setlet;
|
import '../util/util.dart' show Setlet;
|
||||||
import 'use.dart' show DynamicUse, StaticUse, TypeUse;
|
import 'use.dart' show DynamicUse, StaticUse, TypeUse;
|
||||||
|
|
||||||
|
|
|
@ -4,15 +4,15 @@
|
||||||
|
|
||||||
library dart2js.util;
|
library dart2js.util;
|
||||||
|
|
||||||
import 'characters.dart';
|
import 'package:front_end/src/fasta/scanner/characters.dart';
|
||||||
import 'util_implementation.dart';
|
import 'package:front_end/src/fasta/util/link.dart';
|
||||||
|
|
||||||
export 'emptyset.dart';
|
export 'emptyset.dart';
|
||||||
export 'maplet.dart';
|
export 'maplet.dart';
|
||||||
export 'setlet.dart';
|
export 'setlet.dart';
|
||||||
|
export 'package:front_end/src/fasta/util/link.dart';
|
||||||
|
|
||||||
part 'indentation.dart';
|
part 'indentation.dart';
|
||||||
part 'link.dart';
|
|
||||||
|
|
||||||
/// Helper functions for creating hash codes.
|
/// Helper functions for creating hash codes.
|
||||||
class Hashing {
|
class Hashing {
|
||||||
|
|
42
pkg/front_end/lib/src/fasta/parser.dart
Normal file
42
pkg/front_end/lib/src/fasta/parser.dart
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright (c) 2016, 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.md file.
|
||||||
|
|
||||||
|
library fasta.parser;
|
||||||
|
|
||||||
|
import 'package:front_end/src/fasta/scanner/token.dart' show
|
||||||
|
Token;
|
||||||
|
|
||||||
|
import 'parser/listener.dart' show
|
||||||
|
Listener;
|
||||||
|
|
||||||
|
import 'parser/parser.dart' show
|
||||||
|
Parser;
|
||||||
|
|
||||||
|
import 'parser/listener.dart' show
|
||||||
|
ParserError;
|
||||||
|
|
||||||
|
export 'parser/parser.dart' show
|
||||||
|
Parser,
|
||||||
|
closeBraceFor,
|
||||||
|
optional;
|
||||||
|
|
||||||
|
export 'parser/listener.dart' show
|
||||||
|
Listener,
|
||||||
|
ParserError;
|
||||||
|
|
||||||
|
export 'parser/error_kind.dart' show
|
||||||
|
ErrorKind;
|
||||||
|
|
||||||
|
export 'parser/top_level_parser.dart' show
|
||||||
|
TopLevelParser;
|
||||||
|
|
||||||
|
export 'parser/class_member_parser.dart' show
|
||||||
|
ClassMemberParser;
|
||||||
|
|
||||||
|
List<ParserError> parse(Token tokens) {
|
||||||
|
Listener listener = new Listener();
|
||||||
|
Parser parser = new Parser(listener);
|
||||||
|
parser.parseUnit(tokens);
|
||||||
|
return listener.recoverableErrors;
|
||||||
|
}
|
7
pkg/front_end/lib/src/fasta/parser/bin/parser.dart
Normal file
7
pkg/front_end/lib/src/fasta/parser/bin/parser.dart
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// Copyright (c) 2016, 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 'package:front_end/src/fasta/parser/main.dart' as dart_parser;
|
||||||
|
|
||||||
|
main(List<String> arguments) => dart_parser.main(arguments);
|
|
@ -2,174 +2,32 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
library dart2js.parser.partial;
|
library fasta.parser.class_member_parser;
|
||||||
|
|
||||||
import '../common.dart';
|
import 'package:front_end/src/fasta/scanner/token.dart' show
|
||||||
import '../tokens/token.dart' show BeginGroupToken, ErrorToken, Token;
|
Token;
|
||||||
import '../tokens/token_constants.dart' as Tokens show EOF_TOKEN;
|
|
||||||
import '../util/characters.dart' as Characters show $CLOSE_CURLY_BRACKET;
|
|
||||||
import 'listener.dart' show Listener;
|
|
||||||
import 'parser.dart' show Parser;
|
|
||||||
|
|
||||||
class PartialParser extends Parser {
|
import 'listener.dart' show
|
||||||
PartialParser(Listener listener) : super(listener);
|
Listener;
|
||||||
|
|
||||||
Token parseClassBody(Token token) => skipClassBody(token);
|
import 'parser.dart' show
|
||||||
|
Parser;
|
||||||
|
|
||||||
Token fullParseClassBody(Token token) => super.parseClassBody(token);
|
/// Parser similar to [TopLevelParser] but also parses class members (excluding
|
||||||
|
/// their bodies).
|
||||||
|
class ClassMemberParser extends Parser {
|
||||||
|
ClassMemberParser(Listener listener,
|
||||||
|
{bool asyncAwaitKeywordsEnabled: false})
|
||||||
|
: super(listener, asyncAwaitKeywordsEnabled: asyncAwaitKeywordsEnabled);
|
||||||
|
|
||||||
Token parseExpression(Token token) => skipExpression(token);
|
Token parseExpression(Token token) => skipExpression(token);
|
||||||
|
|
||||||
Token parseArgumentsOpt(Token token) {
|
// This method is overridden for two reasons:
|
||||||
// This method is overridden for two reasons:
|
// 1. Avoid generating events for arguments.
|
||||||
// 1. Avoid generating events for arguments.
|
// 2. Avoid calling skip expression for each argument (which doesn't work).
|
||||||
// 2. Avoid calling skip expression for each argument (which doesn't work).
|
Token parseArgumentsOpt(Token token) => skipArgumentsOpt(token);
|
||||||
listener.handleNoArguments(token);
|
|
||||||
if (optional('(', token)) {
|
|
||||||
BeginGroupToken begin = token;
|
|
||||||
return begin.endGroup.next;
|
|
||||||
} else {
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Token skipExpression(Token token) {
|
|
||||||
while (true) {
|
|
||||||
final kind = token.kind;
|
|
||||||
final value = token.stringValue;
|
|
||||||
if ((identical(kind, Tokens.EOF_TOKEN)) ||
|
|
||||||
(identical(value, ';')) ||
|
|
||||||
(identical(value, ',')) ||
|
|
||||||
(identical(value, '}')) ||
|
|
||||||
(identical(value, ')')) ||
|
|
||||||
(identical(value, ']'))) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (identical(value, '=') ||
|
|
||||||
identical(value, '?') ||
|
|
||||||
identical(value, ':') ||
|
|
||||||
identical(value, '??')) {
|
|
||||||
var nextValue = token.next.stringValue;
|
|
||||||
if (identical(nextValue, 'const')) {
|
|
||||||
token = token.next;
|
|
||||||
nextValue = token.next.stringValue;
|
|
||||||
}
|
|
||||||
if (identical(nextValue, '{')) {
|
|
||||||
// Handle cases like this:
|
|
||||||
// class Foo {
|
|
||||||
// var map;
|
|
||||||
// Foo() : map = {};
|
|
||||||
// Foo.x() : map = true ? {} : {};
|
|
||||||
// }
|
|
||||||
BeginGroupToken begin = token.next;
|
|
||||||
token = (begin.endGroup != null) ? begin.endGroup : token;
|
|
||||||
token = token.next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (identical(nextValue, '<')) {
|
|
||||||
// Handle cases like this:
|
|
||||||
// class Foo {
|
|
||||||
// var map;
|
|
||||||
// Foo() : map = <String, Foo>{};
|
|
||||||
// Foo.x() : map = true ? <String, Foo>{} : <String, Foo>{};
|
|
||||||
// }
|
|
||||||
BeginGroupToken begin = token.next;
|
|
||||||
token = (begin.endGroup != null) ? begin.endGroup : token;
|
|
||||||
token = token.next;
|
|
||||||
if (identical(token.stringValue, '{')) {
|
|
||||||
begin = token;
|
|
||||||
token = (begin.endGroup != null) ? begin.endGroup : token;
|
|
||||||
token = token.next;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!mayParseFunctionExpressions && identical(value, '{')) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (token is BeginGroupToken) {
|
|
||||||
BeginGroupToken begin = token;
|
|
||||||
token = (begin.endGroup != null) ? begin.endGroup : token;
|
|
||||||
} else if (token is ErrorToken) {
|
|
||||||
listener.reportErrorToken(token);
|
|
||||||
}
|
|
||||||
token = token.next;
|
|
||||||
}
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
Token skipClassBody(Token token) {
|
|
||||||
if (!optional('{', token)) {
|
|
||||||
return listener.expectedClassBodyToSkip(token);
|
|
||||||
}
|
|
||||||
BeginGroupToken beginGroupToken = token;
|
|
||||||
Token endGroup = beginGroupToken.endGroup;
|
|
||||||
if (endGroup == null) {
|
|
||||||
return listener.unmatched(beginGroupToken);
|
|
||||||
} else if (!identical(endGroup.kind, Characters.$CLOSE_CURLY_BRACKET)) {
|
|
||||||
return listener.unmatched(beginGroupToken);
|
|
||||||
}
|
|
||||||
return endGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
Token skipAsyncModifier(Token token) {
|
|
||||||
String value = token.stringValue;
|
|
||||||
if (identical(value, 'async')) {
|
|
||||||
token = token.next;
|
|
||||||
value = token.stringValue;
|
|
||||||
|
|
||||||
if (identical(value, '*')) {
|
|
||||||
token = token.next;
|
|
||||||
}
|
|
||||||
} else if (identical(value, 'sync')) {
|
|
||||||
token = token.next;
|
|
||||||
value = token.stringValue;
|
|
||||||
|
|
||||||
if (identical(value, '*')) {
|
|
||||||
token = token.next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
Token parseFunctionBody(Token token, bool isExpression, bool allowAbstract) {
|
Token parseFunctionBody(Token token, bool isExpression, bool allowAbstract) {
|
||||||
assert(!isExpression);
|
return skipFunctionBody(token, isExpression, allowAbstract);
|
||||||
token = skipAsyncModifier(token);
|
|
||||||
String value = token.stringValue;
|
|
||||||
if (identical(value, ';')) {
|
|
||||||
if (!allowAbstract) {
|
|
||||||
listener.reportError(token, MessageKind.BODY_EXPECTED);
|
|
||||||
}
|
|
||||||
listener.handleNoFunctionBody(token);
|
|
||||||
} else {
|
|
||||||
if (identical(value, '=>')) {
|
|
||||||
token = parseExpression(token.next);
|
|
||||||
expectSemicolon(token);
|
|
||||||
} else if (value == '=') {
|
|
||||||
token = parseRedirectingFactoryBody(token);
|
|
||||||
expectSemicolon(token);
|
|
||||||
} else {
|
|
||||||
token = skipBlock(token);
|
|
||||||
}
|
|
||||||
listener.skippedFunctionBody(token);
|
|
||||||
}
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
Token parseFormalParameters(Token token) => skipFormals(token);
|
|
||||||
|
|
||||||
Token skipFormals(Token token) {
|
|
||||||
listener.beginOptionalFormalParameters(token);
|
|
||||||
if (!optional('(', token)) {
|
|
||||||
if (optional(';', token)) {
|
|
||||||
listener.recoverableError(token, "expected '('");
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
return listener.unexpected(token);
|
|
||||||
}
|
|
||||||
BeginGroupToken beginGroupToken = token;
|
|
||||||
Token endToken = beginGroupToken.endGroup;
|
|
||||||
listener.endFormalParameters(0, token, endToken);
|
|
||||||
return endToken.next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
41
pkg/front_end/lib/src/fasta/parser/error_kind.dart
Normal file
41
pkg/front_end/lib/src/fasta/parser/error_kind.dart
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright (c) 2016, 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 fasta.parser.error_kind;
|
||||||
|
|
||||||
|
enum ErrorKind {
|
||||||
|
EmptyNamedParameterList,
|
||||||
|
EmptyOptionalParameterList,
|
||||||
|
ExpectedBlockToSkip,
|
||||||
|
ExpectedBody,
|
||||||
|
ExpectedButGot,
|
||||||
|
ExpectedClassBody,
|
||||||
|
ExpectedClassBodyToSkip,
|
||||||
|
ExpectedDeclaration,
|
||||||
|
ExpectedExpression,
|
||||||
|
ExpectedFunctionBody,
|
||||||
|
ExpectedHexDigit,
|
||||||
|
ExpectedIdentifier,
|
||||||
|
ExpectedOpenParens,
|
||||||
|
ExpectedString,
|
||||||
|
ExpectedType,
|
||||||
|
ExtraneousModifier,
|
||||||
|
ExtraneousModifierReplace,
|
||||||
|
InvalidAwaitFor,
|
||||||
|
InvalidInputCharacter,
|
||||||
|
InvalidSyncModifier,
|
||||||
|
InvalidVoid,
|
||||||
|
MalformedStringLiteral,
|
||||||
|
MissingExponent,
|
||||||
|
PositionalParameterWithEquals,
|
||||||
|
RequiredParameterWithDefault,
|
||||||
|
UnexpectedToken,
|
||||||
|
UnmatchedToken,
|
||||||
|
UnsupportedPrefixPlus,
|
||||||
|
UnterminatedComment,
|
||||||
|
UnterminatedString,
|
||||||
|
UnterminatedToken,
|
||||||
|
|
||||||
|
Unspecified,
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
57
pkg/front_end/lib/src/fasta/parser/main.dart
Normal file
57
pkg/front_end/lib/src/fasta/parser/main.dart
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
// Copyright (c) 2016, 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 fasta.parser.main;
|
||||||
|
|
||||||
|
import 'dart:convert' show
|
||||||
|
LineSplitter,
|
||||||
|
UTF8;
|
||||||
|
|
||||||
|
import 'dart:io' show
|
||||||
|
File;
|
||||||
|
|
||||||
|
import 'package:front_end/src/fasta/scanner/token.dart' show
|
||||||
|
Token;
|
||||||
|
|
||||||
|
import 'package:front_end/src/fasta/scanner/io.dart' show
|
||||||
|
readBytesFromFileSync;
|
||||||
|
|
||||||
|
import 'package:front_end/src/fasta/scanner.dart' show
|
||||||
|
scan;
|
||||||
|
|
||||||
|
import 'listener.dart' show
|
||||||
|
Listener;
|
||||||
|
|
||||||
|
import 'top_level_parser.dart' show
|
||||||
|
TopLevelParser;
|
||||||
|
|
||||||
|
class DebugListener extends Listener {
|
||||||
|
void handleIdentifier(Token token) {
|
||||||
|
logEvent("Identifier: ${token.value}");
|
||||||
|
}
|
||||||
|
|
||||||
|
void logEvent(String name) {
|
||||||
|
print(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main(List<String> arguments) async {
|
||||||
|
for (String argument in arguments) {
|
||||||
|
if (argument.startsWith("@")) {
|
||||||
|
Uri uri = Uri.base.resolve(argument.substring(1));
|
||||||
|
await for (String file in new File.fromUri(uri).openRead()
|
||||||
|
.transform(UTF8.decoder)
|
||||||
|
.transform(const LineSplitter())) {
|
||||||
|
outLine(uri.resolve(file));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
outLine(Uri.base.resolve(argument));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void outLine(Uri uri) {
|
||||||
|
new TopLevelParser(new DebugListener()).parseUnit(
|
||||||
|
scan(readBytesFromFileSync(uri)).tokens);
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
|
@ -2,174 +2,22 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
library dart2js.parser.partial;
|
library fasta.parser.top_level_parser;
|
||||||
|
|
||||||
import '../common.dart';
|
import 'package:front_end/src/fasta/scanner/token.dart' show
|
||||||
import '../tokens/token.dart' show BeginGroupToken, ErrorToken, Token;
|
Token;
|
||||||
import '../tokens/token_constants.dart' as Tokens show EOF_TOKEN;
|
|
||||||
import '../util/characters.dart' as Characters show $CLOSE_CURLY_BRACKET;
|
|
||||||
import 'listener.dart' show Listener;
|
|
||||||
import 'parser.dart' show Parser;
|
|
||||||
|
|
||||||
class PartialParser extends Parser {
|
import 'listener.dart' show
|
||||||
PartialParser(Listener listener) : super(listener);
|
Listener;
|
||||||
|
|
||||||
|
import 'class_member_parser.dart' show
|
||||||
|
ClassMemberParser;
|
||||||
|
|
||||||
|
/// Parser which only parses top-level elements, but ignores their bodies.
|
||||||
|
/// Use [Parser] to parse everything.
|
||||||
|
class TopLevelParser extends ClassMemberParser {
|
||||||
|
TopLevelParser(Listener listener, {bool asyncAwaitKeywordsEnabled: false})
|
||||||
|
: super(listener, asyncAwaitKeywordsEnabled: asyncAwaitKeywordsEnabled);
|
||||||
|
|
||||||
Token parseClassBody(Token token) => skipClassBody(token);
|
Token parseClassBody(Token token) => skipClassBody(token);
|
||||||
|
|
||||||
Token fullParseClassBody(Token token) => super.parseClassBody(token);
|
|
||||||
|
|
||||||
Token parseExpression(Token token) => skipExpression(token);
|
|
||||||
|
|
||||||
Token parseArgumentsOpt(Token token) {
|
|
||||||
// This method is overridden for two reasons:
|
|
||||||
// 1. Avoid generating events for arguments.
|
|
||||||
// 2. Avoid calling skip expression for each argument (which doesn't work).
|
|
||||||
listener.handleNoArguments(token);
|
|
||||||
if (optional('(', token)) {
|
|
||||||
BeginGroupToken begin = token;
|
|
||||||
return begin.endGroup.next;
|
|
||||||
} else {
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Token skipExpression(Token token) {
|
|
||||||
while (true) {
|
|
||||||
final kind = token.kind;
|
|
||||||
final value = token.stringValue;
|
|
||||||
if ((identical(kind, Tokens.EOF_TOKEN)) ||
|
|
||||||
(identical(value, ';')) ||
|
|
||||||
(identical(value, ',')) ||
|
|
||||||
(identical(value, '}')) ||
|
|
||||||
(identical(value, ')')) ||
|
|
||||||
(identical(value, ']'))) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (identical(value, '=') ||
|
|
||||||
identical(value, '?') ||
|
|
||||||
identical(value, ':') ||
|
|
||||||
identical(value, '??')) {
|
|
||||||
var nextValue = token.next.stringValue;
|
|
||||||
if (identical(nextValue, 'const')) {
|
|
||||||
token = token.next;
|
|
||||||
nextValue = token.next.stringValue;
|
|
||||||
}
|
|
||||||
if (identical(nextValue, '{')) {
|
|
||||||
// Handle cases like this:
|
|
||||||
// class Foo {
|
|
||||||
// var map;
|
|
||||||
// Foo() : map = {};
|
|
||||||
// Foo.x() : map = true ? {} : {};
|
|
||||||
// }
|
|
||||||
BeginGroupToken begin = token.next;
|
|
||||||
token = (begin.endGroup != null) ? begin.endGroup : token;
|
|
||||||
token = token.next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (identical(nextValue, '<')) {
|
|
||||||
// Handle cases like this:
|
|
||||||
// class Foo {
|
|
||||||
// var map;
|
|
||||||
// Foo() : map = <String, Foo>{};
|
|
||||||
// Foo.x() : map = true ? <String, Foo>{} : <String, Foo>{};
|
|
||||||
// }
|
|
||||||
BeginGroupToken begin = token.next;
|
|
||||||
token = (begin.endGroup != null) ? begin.endGroup : token;
|
|
||||||
token = token.next;
|
|
||||||
if (identical(token.stringValue, '{')) {
|
|
||||||
begin = token;
|
|
||||||
token = (begin.endGroup != null) ? begin.endGroup : token;
|
|
||||||
token = token.next;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!mayParseFunctionExpressions && identical(value, '{')) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (token is BeginGroupToken) {
|
|
||||||
BeginGroupToken begin = token;
|
|
||||||
token = (begin.endGroup != null) ? begin.endGroup : token;
|
|
||||||
} else if (token is ErrorToken) {
|
|
||||||
listener.reportErrorToken(token);
|
|
||||||
}
|
|
||||||
token = token.next;
|
|
||||||
}
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
Token skipClassBody(Token token) {
|
|
||||||
if (!optional('{', token)) {
|
|
||||||
return listener.expectedClassBodyToSkip(token);
|
|
||||||
}
|
|
||||||
BeginGroupToken beginGroupToken = token;
|
|
||||||
Token endGroup = beginGroupToken.endGroup;
|
|
||||||
if (endGroup == null) {
|
|
||||||
return listener.unmatched(beginGroupToken);
|
|
||||||
} else if (!identical(endGroup.kind, Characters.$CLOSE_CURLY_BRACKET)) {
|
|
||||||
return listener.unmatched(beginGroupToken);
|
|
||||||
}
|
|
||||||
return endGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
Token skipAsyncModifier(Token token) {
|
|
||||||
String value = token.stringValue;
|
|
||||||
if (identical(value, 'async')) {
|
|
||||||
token = token.next;
|
|
||||||
value = token.stringValue;
|
|
||||||
|
|
||||||
if (identical(value, '*')) {
|
|
||||||
token = token.next;
|
|
||||||
}
|
|
||||||
} else if (identical(value, 'sync')) {
|
|
||||||
token = token.next;
|
|
||||||
value = token.stringValue;
|
|
||||||
|
|
||||||
if (identical(value, '*')) {
|
|
||||||
token = token.next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
Token parseFunctionBody(Token token, bool isExpression, bool allowAbstract) {
|
|
||||||
assert(!isExpression);
|
|
||||||
token = skipAsyncModifier(token);
|
|
||||||
String value = token.stringValue;
|
|
||||||
if (identical(value, ';')) {
|
|
||||||
if (!allowAbstract) {
|
|
||||||
listener.reportError(token, MessageKind.BODY_EXPECTED);
|
|
||||||
}
|
|
||||||
listener.handleNoFunctionBody(token);
|
|
||||||
} else {
|
|
||||||
if (identical(value, '=>')) {
|
|
||||||
token = parseExpression(token.next);
|
|
||||||
expectSemicolon(token);
|
|
||||||
} else if (value == '=') {
|
|
||||||
token = parseRedirectingFactoryBody(token);
|
|
||||||
expectSemicolon(token);
|
|
||||||
} else {
|
|
||||||
token = skipBlock(token);
|
|
||||||
}
|
|
||||||
listener.skippedFunctionBody(token);
|
|
||||||
}
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
Token parseFormalParameters(Token token) => skipFormals(token);
|
|
||||||
|
|
||||||
Token skipFormals(Token token) {
|
|
||||||
listener.beginOptionalFormalParameters(token);
|
|
||||||
if (!optional('(', token)) {
|
|
||||||
if (optional(';', token)) {
|
|
||||||
listener.recoverableError(token, "expected '('");
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
return listener.unexpected(token);
|
|
||||||
}
|
|
||||||
BeginGroupToken beginGroupToken = token;
|
|
||||||
Token endToken = beginGroupToken.endGroup;
|
|
||||||
listener.endFormalParameters(0, token, endToken);
|
|
||||||
return endToken.next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
72
pkg/front_end/lib/src/fasta/scanner.dart
Normal file
72
pkg/front_end/lib/src/fasta/scanner.dart
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
// Copyright (c) 2016, 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.md file.
|
||||||
|
|
||||||
|
library fasta.scanner;
|
||||||
|
|
||||||
|
import 'scanner/token.dart' show
|
||||||
|
Token;
|
||||||
|
|
||||||
|
import 'scanner/utf8_bytes_scanner.dart' show
|
||||||
|
Utf8BytesScanner;
|
||||||
|
|
||||||
|
import 'scanner/recover.dart' show
|
||||||
|
defaultRecoveryStrategy;
|
||||||
|
|
||||||
|
export 'scanner/token.dart' show
|
||||||
|
BeginGroupToken,
|
||||||
|
ErrorToken,
|
||||||
|
KeywordToken,
|
||||||
|
StringToken,
|
||||||
|
SymbolToken,
|
||||||
|
Token,
|
||||||
|
isBinaryOperator,
|
||||||
|
isMinusOperator,
|
||||||
|
isTernaryOperator,
|
||||||
|
isUnaryOperator,
|
||||||
|
isUserDefinableOperator;
|
||||||
|
|
||||||
|
export 'scanner/token_constants.dart' show
|
||||||
|
EOF_TOKEN;
|
||||||
|
|
||||||
|
export 'scanner/utf8_bytes_scanner.dart' show
|
||||||
|
Utf8BytesScanner;
|
||||||
|
|
||||||
|
export 'scanner/string_scanner.dart' show
|
||||||
|
StringScanner;
|
||||||
|
|
||||||
|
export 'scanner/keyword.dart' show
|
||||||
|
Keyword;
|
||||||
|
|
||||||
|
typedef Token Recover(List<int> bytes, Token tokens, List<int> lineStarts);
|
||||||
|
|
||||||
|
abstract class Scanner {
|
||||||
|
/// Returns true if an error occured during [tokenize].
|
||||||
|
bool get hasErrors;
|
||||||
|
|
||||||
|
List<int> get lineStarts;
|
||||||
|
|
||||||
|
Token tokenize();
|
||||||
|
}
|
||||||
|
|
||||||
|
class ScannerResult {
|
||||||
|
final Token tokens;
|
||||||
|
final List<int> lineStarts;
|
||||||
|
|
||||||
|
ScannerResult(this.tokens, this.lineStarts);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScannerResult scan(List<int> bytes,
|
||||||
|
{bool includeComments: false, Recover recover}) {
|
||||||
|
if (bytes.last != 0) {
|
||||||
|
throw new ArgumentError("[bytes]: the last byte must be null.");
|
||||||
|
}
|
||||||
|
Scanner scanner =
|
||||||
|
new Utf8BytesScanner(bytes, includeComments: includeComments);
|
||||||
|
Token tokens = scanner.tokenize();
|
||||||
|
if (scanner.hasErrors) {
|
||||||
|
recover ??= defaultRecoveryStrategy;
|
||||||
|
tokens = recover(bytes, tokens, scanner.lineStarts);
|
||||||
|
}
|
||||||
|
return new ScannerResult(tokens, scanner.lineStarts);
|
||||||
|
}
|
|
@ -2,33 +2,32 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
library dart2js.scanner;
|
library fasta.scanner.abstract_scanner;
|
||||||
|
|
||||||
import '../io/source_file.dart' show SourceFile, Utf8BytesSourceFile;
|
import '../scanner.dart' show
|
||||||
import '../tokens/keyword.dart' show Keyword, KeywordState;
|
Scanner;
|
||||||
import '../tokens/precedence.dart';
|
|
||||||
import '../tokens/precedence_constants.dart';
|
|
||||||
import '../tokens/token.dart';
|
|
||||||
import '../tokens/token_constants.dart';
|
|
||||||
import '../util/characters.dart';
|
|
||||||
import 'string_scanner.dart' show StringScanner;
|
|
||||||
import 'utf8_bytes_scanner.dart' show Utf8BytesScanner;
|
|
||||||
|
|
||||||
abstract class Scanner {
|
import 'keyword.dart' show
|
||||||
Token tokenize();
|
KeywordState,
|
||||||
|
Keyword;
|
||||||
|
|
||||||
factory Scanner(SourceFile file, {bool includeComments: false}) {
|
import 'precedence.dart';
|
||||||
if (file is Utf8BytesSourceFile) {
|
|
||||||
return new Utf8BytesScanner(file, includeComments: includeComments);
|
import 'token.dart' show
|
||||||
} else {
|
BadInputToken,
|
||||||
return new StringScanner(file, includeComments: includeComments);
|
BeginGroupToken,
|
||||||
}
|
ErrorToken,
|
||||||
}
|
KeywordToken,
|
||||||
}
|
SymbolToken,
|
||||||
|
Token,
|
||||||
|
UnmatchedToken,
|
||||||
|
UnterminatedToken;
|
||||||
|
|
||||||
|
import 'token_constants.dart';
|
||||||
|
|
||||||
|
import 'characters.dart';
|
||||||
|
|
||||||
abstract class AbstractScanner implements Scanner {
|
abstract class AbstractScanner implements Scanner {
|
||||||
// TODO(ahe): Move this class to implementation.
|
|
||||||
|
|
||||||
final bool includeComments;
|
final bool includeComments;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,16 +53,9 @@ abstract class AbstractScanner implements Scanner {
|
||||||
*/
|
*/
|
||||||
Token tail;
|
Token tail;
|
||||||
|
|
||||||
/**
|
|
||||||
* The source file that is being scanned. This field can be [:null:].
|
|
||||||
* If the source file is available, the scanner assigns its [:lineStarts:] and
|
|
||||||
* [:length:] fields at the end of [tokenize].
|
|
||||||
*/
|
|
||||||
final SourceFile file;
|
|
||||||
|
|
||||||
final List<int> lineStarts = <int>[0];
|
final List<int> lineStarts = <int>[0];
|
||||||
|
|
||||||
AbstractScanner(this.file, this.includeComments) {
|
AbstractScanner(this.includeComments) {
|
||||||
this.tail = this.tokens;
|
this.tail = this.tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,12 +206,8 @@ abstract class AbstractScanner implements Scanner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file != null) {
|
// Always pretend that there's a line at the end of the file.
|
||||||
file.length = stringOffset;
|
lineStarts.add(stringOffset + 1);
|
||||||
// One additional line start at the end, see [SourceFile.lineStarts].
|
|
||||||
lineStarts.add(stringOffset + 1);
|
|
||||||
file.lineStarts = lineStarts;
|
|
||||||
}
|
|
||||||
|
|
||||||
return firstToken();
|
return firstToken();
|
||||||
}
|
}
|
||||||
|
@ -635,7 +623,6 @@ abstract class AbstractScanner implements Scanner {
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int tokenizeHexOrNumber(int next) {
|
int tokenizeHexOrNumber(int next) {
|
||||||
|
@ -665,7 +652,6 @@ abstract class AbstractScanner implements Scanner {
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int tokenizeDotsOrNumber(int next) {
|
int tokenizeDotsOrNumber(int next) {
|
||||||
|
@ -761,7 +747,6 @@ abstract class AbstractScanner implements Scanner {
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int tokenizeMultiLineComment(int next, int start) {
|
int tokenizeMultiLineComment(int next, int start) {
|
||||||
|
|
|
@ -2,24 +2,43 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
library dart2js.scanner.array_based;
|
library fasta.scanner.array_based_scanner;
|
||||||
|
|
||||||
import '../io/source_file.dart' show SourceFile;
|
import 'keyword.dart' show
|
||||||
import '../tokens/keyword.dart' show Keyword;
|
Keyword;
|
||||||
import '../tokens/precedence.dart' show PrecedenceInfo;
|
|
||||||
import '../tokens/precedence_constants.dart' as Precedence
|
import 'precedence.dart' show
|
||||||
show COMMENT_INFO, EOF_INFO;
|
COMMENT_INFO,
|
||||||
import '../tokens/token.dart'
|
EOF_INFO,
|
||||||
show BeginGroupToken, ErrorToken, KeywordToken, SymbolToken, Token;
|
PrecedenceInfo;
|
||||||
import '../tokens/token_constants.dart' as Tokens
|
|
||||||
show LT_TOKEN, OPEN_CURLY_BRACKET_TOKEN, STRING_INTERPOLATION_TOKEN;
|
import 'token.dart' show
|
||||||
import '../util/characters.dart' show $LF, $STX;
|
BeginGroupToken,
|
||||||
import '../util/util.dart' show Link;
|
ErrorToken,
|
||||||
import 'scanner.dart' show AbstractScanner;
|
KeywordToken,
|
||||||
|
SymbolToken,
|
||||||
|
Token;
|
||||||
|
|
||||||
|
import 'token_constants.dart' show
|
||||||
|
LT_TOKEN,
|
||||||
|
OPEN_CURLY_BRACKET_TOKEN,
|
||||||
|
STRING_INTERPOLATION_TOKEN;
|
||||||
|
|
||||||
|
import 'characters.dart' show
|
||||||
|
$LF,
|
||||||
|
$STX;
|
||||||
|
|
||||||
|
import 'abstract_scanner.dart' show
|
||||||
|
AbstractScanner;
|
||||||
|
|
||||||
|
import 'package:front_end/src/fasta/util/link.dart' show
|
||||||
|
Link;
|
||||||
|
|
||||||
abstract class ArrayBasedScanner extends AbstractScanner {
|
abstract class ArrayBasedScanner extends AbstractScanner {
|
||||||
ArrayBasedScanner(SourceFile file, bool includeComments)
|
bool hasErrors = false;
|
||||||
: super(file, includeComments);
|
|
||||||
|
ArrayBasedScanner(bool includeComments)
|
||||||
|
: super(includeComments);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The stack of open groups, e.g [: { ... ( .. :]
|
* The stack of open groups, e.g [: { ... ( .. :]
|
||||||
|
@ -77,7 +96,7 @@ abstract class ArrayBasedScanner extends AbstractScanner {
|
||||||
unmatchedBeginGroup(groupingStack.head);
|
unmatchedBeginGroup(groupingStack.head);
|
||||||
groupingStack = groupingStack.tail;
|
groupingStack = groupingStack.tail;
|
||||||
}
|
}
|
||||||
tail.next = new SymbolToken(Precedence.EOF_INFO, tokenStart);
|
tail.next = new SymbolToken(EOF_INFO, tokenStart);
|
||||||
tail = tail.next;
|
tail = tail.next;
|
||||||
// EOF points to itself so there's always infinite look-ahead.
|
// EOF points to itself so there's always infinite look-ahead.
|
||||||
tail.next = tail;
|
tail.next = tail;
|
||||||
|
@ -91,7 +110,7 @@ abstract class ArrayBasedScanner extends AbstractScanner {
|
||||||
* [lineStarts] map.
|
* [lineStarts] map.
|
||||||
*/
|
*/
|
||||||
void appendWhiteSpace(int next) {
|
void appendWhiteSpace(int next) {
|
||||||
if (next == $LF && file != null) {
|
if (next == $LF) {
|
||||||
lineStarts.add(stringOffset + 1); // +1, the line starts after the $LF.
|
lineStarts.add(stringOffset + 1); // +1, the line starts after the $LF.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,9 +122,7 @@ abstract class ArrayBasedScanner extends AbstractScanner {
|
||||||
* [lineStarts] map.
|
* [lineStarts] map.
|
||||||
*/
|
*/
|
||||||
void lineFeedInMultiline() {
|
void lineFeedInMultiline() {
|
||||||
if (file != null) {
|
lineStarts.add(stringOffset + 1);
|
||||||
lineStarts.add(stringOffset + 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,7 +135,7 @@ abstract class ArrayBasedScanner extends AbstractScanner {
|
||||||
tail = tail.next;
|
tail = tail.next;
|
||||||
|
|
||||||
// { ( [ ${ cannot appear inside a type parameters / arguments.
|
// { ( [ ${ cannot appear inside a type parameters / arguments.
|
||||||
if (!identical(info.kind, Tokens.LT_TOKEN)) discardOpenLt();
|
if (!identical(info.kind, LT_TOKEN)) discardOpenLt();
|
||||||
groupingStack = groupingStack.prepend(token);
|
groupingStack = groupingStack.prepend(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +145,7 @@ abstract class ArrayBasedScanner extends AbstractScanner {
|
||||||
* '>>' are handled separately bo [appendGt] and [appendGtGt].
|
* '>>' are handled separately bo [appendGt] and [appendGtGt].
|
||||||
*/
|
*/
|
||||||
int appendEndGroup(PrecedenceInfo info, int openKind) {
|
int appendEndGroup(PrecedenceInfo info, int openKind) {
|
||||||
assert(!identical(openKind, Tokens.LT_TOKEN)); // openKind is < for > and >>
|
assert(!identical(openKind, LT_TOKEN)); // openKind is < for > and >>
|
||||||
discardBeginGroupUntil(openKind);
|
discardBeginGroupUntil(openKind);
|
||||||
appendPrecedenceToken(info);
|
appendPrecedenceToken(info);
|
||||||
Token close = tail;
|
Token close = tail;
|
||||||
|
@ -137,8 +154,8 @@ abstract class ArrayBasedScanner extends AbstractScanner {
|
||||||
}
|
}
|
||||||
BeginGroupToken begin = groupingStack.head;
|
BeginGroupToken begin = groupingStack.head;
|
||||||
if (!identical(begin.kind, openKind)) {
|
if (!identical(begin.kind, openKind)) {
|
||||||
assert(begin.kind == Tokens.STRING_INTERPOLATION_TOKEN &&
|
assert(begin.kind == STRING_INTERPOLATION_TOKEN &&
|
||||||
openKind == Tokens.OPEN_CURLY_BRACKET_TOKEN);
|
openKind == OPEN_CURLY_BRACKET_TOKEN);
|
||||||
// We're ending an interpolated expression.
|
// We're ending an interpolated expression.
|
||||||
begin.endGroup = close;
|
begin.endGroup = close;
|
||||||
groupingStack = groupingStack.tail;
|
groupingStack = groupingStack.tail;
|
||||||
|
@ -162,8 +179,8 @@ abstract class ArrayBasedScanner extends AbstractScanner {
|
||||||
if (groupingStack.isEmpty) return;
|
if (groupingStack.isEmpty) return;
|
||||||
BeginGroupToken begin = groupingStack.head;
|
BeginGroupToken begin = groupingStack.head;
|
||||||
if (openKind == begin.kind) return;
|
if (openKind == begin.kind) return;
|
||||||
if (openKind == Tokens.OPEN_CURLY_BRACKET_TOKEN &&
|
if (openKind == OPEN_CURLY_BRACKET_TOKEN &&
|
||||||
begin.kind == Tokens.STRING_INTERPOLATION_TOKEN) return;
|
begin.kind == STRING_INTERPOLATION_TOKEN) return;
|
||||||
unmatchedBeginGroup(begin);
|
unmatchedBeginGroup(begin);
|
||||||
groupingStack = groupingStack.tail;
|
groupingStack = groupingStack.tail;
|
||||||
}
|
}
|
||||||
|
@ -177,7 +194,7 @@ abstract class ArrayBasedScanner extends AbstractScanner {
|
||||||
void appendGt(PrecedenceInfo info) {
|
void appendGt(PrecedenceInfo info) {
|
||||||
appendPrecedenceToken(info);
|
appendPrecedenceToken(info);
|
||||||
if (groupingStack.isEmpty) return;
|
if (groupingStack.isEmpty) return;
|
||||||
if (identical(groupingStack.head.kind, Tokens.LT_TOKEN)) {
|
if (identical(groupingStack.head.kind, LT_TOKEN)) {
|
||||||
groupingStack.head.endGroup = tail;
|
groupingStack.head.endGroup = tail;
|
||||||
groupingStack = groupingStack.tail;
|
groupingStack = groupingStack.tail;
|
||||||
}
|
}
|
||||||
|
@ -191,13 +208,13 @@ abstract class ArrayBasedScanner extends AbstractScanner {
|
||||||
void appendGtGt(PrecedenceInfo info) {
|
void appendGtGt(PrecedenceInfo info) {
|
||||||
appendPrecedenceToken(info);
|
appendPrecedenceToken(info);
|
||||||
if (groupingStack.isEmpty) return;
|
if (groupingStack.isEmpty) return;
|
||||||
if (identical(groupingStack.head.kind, Tokens.LT_TOKEN)) {
|
if (identical(groupingStack.head.kind, LT_TOKEN)) {
|
||||||
// Don't assign endGroup: in "T<U<V>>", the '>>' token closes the outer
|
// Don't assign endGroup: in "T<U<V>>", the '>>' token closes the outer
|
||||||
// '<', the inner '<' is left without endGroup.
|
// '<', the inner '<' is left without endGroup.
|
||||||
groupingStack = groupingStack.tail;
|
groupingStack = groupingStack.tail;
|
||||||
}
|
}
|
||||||
if (groupingStack.isEmpty) return;
|
if (groupingStack.isEmpty) return;
|
||||||
if (identical(groupingStack.head.kind, Tokens.LT_TOKEN)) {
|
if (identical(groupingStack.head.kind, LT_TOKEN)) {
|
||||||
groupingStack.head.endGroup = tail;
|
groupingStack.head.endGroup = tail;
|
||||||
groupingStack = groupingStack.tail;
|
groupingStack = groupingStack.tail;
|
||||||
}
|
}
|
||||||
|
@ -205,10 +222,11 @@ abstract class ArrayBasedScanner extends AbstractScanner {
|
||||||
|
|
||||||
void appendComment(start, bool asciiOnly) {
|
void appendComment(start, bool asciiOnly) {
|
||||||
if (!includeComments) return;
|
if (!includeComments) return;
|
||||||
appendSubstringToken(Precedence.COMMENT_INFO, start, asciiOnly);
|
appendSubstringToken(COMMENT_INFO, start, asciiOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
void appendErrorToken(ErrorToken token) {
|
void appendErrorToken(ErrorToken token) {
|
||||||
|
hasErrors = true;
|
||||||
tail.next = token;
|
tail.next = token;
|
||||||
tail = token;
|
tail = token;
|
||||||
}
|
}
|
||||||
|
@ -226,7 +244,7 @@ abstract class ArrayBasedScanner extends AbstractScanner {
|
||||||
*/
|
*/
|
||||||
void discardOpenLt() {
|
void discardOpenLt() {
|
||||||
while (!groupingStack.isEmpty &&
|
while (!groupingStack.isEmpty &&
|
||||||
identical(groupingStack.head.kind, Tokens.LT_TOKEN)) {
|
identical(groupingStack.head.kind, LT_TOKEN)) {
|
||||||
groupingStack = groupingStack.tail;
|
groupingStack = groupingStack.tail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
7
pkg/front_end/lib/src/fasta/scanner/bin/scanner.dart
Normal file
7
pkg/front_end/lib/src/fasta/scanner/bin/scanner.dart
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// Copyright (c) 2016, 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.md file.
|
||||||
|
|
||||||
|
import 'package:front_end/src/fasta/scanner/main.dart' as dart_scanner;
|
||||||
|
|
||||||
|
main(List<String> arguments) => dart_scanner.main(arguments);
|
|
@ -2,7 +2,7 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
library characters;
|
library fasta.scanner.characters;
|
||||||
|
|
||||||
const int $EOF = 0;
|
const int $EOF = 0;
|
||||||
const int $STX = 2;
|
const int $STX = 2;
|
||||||
|
|
|
@ -1,408 +1,46 @@
|
||||||
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// BSD-style license that can be found in the LICENSE.md file.
|
||||||
|
|
||||||
library source_file_provider;
|
library fasta.scanner.io;
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async' show
|
||||||
import 'dart:convert';
|
Future;
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:math' as math;
|
|
||||||
import 'dart:typed_data';
|
|
||||||
|
|
||||||
import '../compiler.dart' as api show Diagnostic;
|
import 'dart:io' show
|
||||||
import '../compiler_new.dart' as api;
|
File,
|
||||||
import '../compiler_new.dart';
|
RandomAccessFile;
|
||||||
import 'colors.dart' as colors;
|
|
||||||
import 'dart2js.dart' show AbortLeg;
|
|
||||||
import 'filenames.dart';
|
|
||||||
import 'io/source_file.dart';
|
|
||||||
import 'util/uri_extras.dart';
|
|
||||||
|
|
||||||
abstract class SourceFileProvider implements CompilerInput {
|
import 'dart:typed_data' show
|
||||||
bool isWindows = (Platform.operatingSystem == 'windows');
|
Uint8List;
|
||||||
Uri cwd = currentDirectory;
|
|
||||||
Map<Uri, SourceFile> sourceFiles = <Uri, SourceFile>{};
|
|
||||||
int dartCharactersRead = 0;
|
|
||||||
|
|
||||||
Future<String> readStringFromUri(Uri resourceUri) {
|
List<int> readBytesFromFileSync(Uri uri) {
|
||||||
return readUtf8BytesFromUri(resourceUri).then(UTF8.decode);
|
RandomAccessFile file = new File.fromUri(uri).openSync();
|
||||||
}
|
Uint8List list;
|
||||||
|
try {
|
||||||
Future<List<int>> readUtf8BytesFromUri(Uri resourceUri) {
|
int length = file.lengthSync();
|
||||||
if (resourceUri.scheme == 'file') {
|
// +1 to have a 0 terminated list, see [Scanner].
|
||||||
return _readFromFile(resourceUri);
|
list = new Uint8List(length + 1);
|
||||||
} else if (resourceUri.scheme == 'http' || resourceUri.scheme == 'https') {
|
file.readIntoSync(list, 0, length);
|
||||||
return _readFromHttp(resourceUri);
|
} finally {
|
||||||
} else {
|
file.closeSync();
|
||||||
throw new ArgumentError("Unknown scheme in uri '$resourceUri'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<List<int>> _readFromFile(Uri resourceUri) {
|
|
||||||
assert(resourceUri.scheme == 'file');
|
|
||||||
List<int> source;
|
|
||||||
try {
|
|
||||||
source = readAll(resourceUri.toFilePath());
|
|
||||||
} on FileSystemException catch (ex) {
|
|
||||||
String message = ex.osError?.message;
|
|
||||||
String detail = message != null ? ' ($message)' : '';
|
|
||||||
return new Future.error(
|
|
||||||
"Error reading '${relativizeUri(resourceUri)}' $detail");
|
|
||||||
}
|
|
||||||
dartCharactersRead += source.length;
|
|
||||||
sourceFiles[resourceUri] = new CachingUtf8BytesSourceFile(
|
|
||||||
resourceUri, relativizeUri(resourceUri), source);
|
|
||||||
return new Future.value(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<List<int>> _readFromHttp(Uri resourceUri) {
|
|
||||||
assert(resourceUri.scheme == 'http');
|
|
||||||
HttpClient client = new HttpClient();
|
|
||||||
return client
|
|
||||||
.getUrl(resourceUri)
|
|
||||||
.then((HttpClientRequest request) => request.close())
|
|
||||||
.then((HttpClientResponse response) {
|
|
||||||
if (response.statusCode != HttpStatus.OK) {
|
|
||||||
String msg = 'Failure getting $resourceUri: '
|
|
||||||
'${response.statusCode} ${response.reasonPhrase}';
|
|
||||||
throw msg;
|
|
||||||
}
|
|
||||||
return response.toList();
|
|
||||||
}).then((List<List<int>> splitContent) {
|
|
||||||
int totalLength = splitContent.fold(0, (int old, List list) {
|
|
||||||
return old + list.length;
|
|
||||||
});
|
|
||||||
Uint8List result = new Uint8List(totalLength);
|
|
||||||
int offset = 0;
|
|
||||||
for (List<int> contentPart in splitContent) {
|
|
||||||
result.setRange(offset, offset + contentPart.length, contentPart);
|
|
||||||
offset += contentPart.length;
|
|
||||||
}
|
|
||||||
dartCharactersRead += totalLength;
|
|
||||||
sourceFiles[resourceUri] = new CachingUtf8BytesSourceFile(
|
|
||||||
resourceUri, resourceUri.toString(), result);
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(johnniwinther): Remove this when no longer needed for the old compiler
|
|
||||||
// API.
|
|
||||||
Future/*<List<int> | String>*/ call(Uri resourceUri) => throw "unimplemented";
|
|
||||||
|
|
||||||
relativizeUri(Uri uri) => relativize(cwd, uri, isWindows);
|
|
||||||
|
|
||||||
SourceFile getSourceFile(Uri resourceUri) {
|
|
||||||
return sourceFiles[resourceUri];
|
|
||||||
}
|
}
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<int> readAll(String filename) {
|
Future<List<int>> readBytesFromFile(Uri uri) async {
|
||||||
var file = (new File(filename)).openSync();
|
RandomAccessFile file = await new File.fromUri(uri).open();
|
||||||
var length = file.lengthSync();
|
Uint8List list;
|
||||||
// +1 to have a 0 terminated list, see [Scanner].
|
try {
|
||||||
var buffer = new Uint8List(length + 1);
|
int length = await file.length();
|
||||||
file.readIntoSync(buffer, 0, length);
|
// +1 to have a 0 terminated list, see [Scanner].
|
||||||
file.closeSync();
|
list = new Uint8List(length + 1);
|
||||||
return buffer;
|
int read = await file.readInto(list);
|
||||||
}
|
if (read != length) {
|
||||||
|
throw "Error reading file: ${uri}";
|
||||||
class CompilerSourceFileProvider extends SourceFileProvider {
|
}
|
||||||
// TODO(johnniwinther): Remove this when no longer needed for the old compiler
|
} finally {
|
||||||
// API.
|
await file.close();
|
||||||
Future<List<int>> call(Uri resourceUri) => readFromUri(resourceUri);
|
}
|
||||||
|
return list;
|
||||||
@override
|
|
||||||
Future readFromUri(Uri uri) => readUtf8BytesFromUri(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
class FormattingDiagnosticHandler implements CompilerDiagnostics {
|
|
||||||
final SourceFileProvider provider;
|
|
||||||
bool showWarnings = true;
|
|
||||||
bool showHints = true;
|
|
||||||
bool verbose = false;
|
|
||||||
bool isAborting = false;
|
|
||||||
bool enableColors = false;
|
|
||||||
bool throwOnError = false;
|
|
||||||
int throwOnErrorCount = 0;
|
|
||||||
api.Diagnostic lastKind = null;
|
|
||||||
int fatalCount = 0;
|
|
||||||
|
|
||||||
final int FATAL = api.Diagnostic.CRASH.ordinal | api.Diagnostic.ERROR.ordinal;
|
|
||||||
final int INFO =
|
|
||||||
api.Diagnostic.INFO.ordinal | api.Diagnostic.VERBOSE_INFO.ordinal;
|
|
||||||
|
|
||||||
FormattingDiagnosticHandler([SourceFileProvider provider])
|
|
||||||
: this.provider =
|
|
||||||
(provider == null) ? new CompilerSourceFileProvider() : provider;
|
|
||||||
|
|
||||||
void info(var message, [api.Diagnostic kind = api.Diagnostic.VERBOSE_INFO]) {
|
|
||||||
if (!verbose && kind == api.Diagnostic.VERBOSE_INFO) return;
|
|
||||||
if (enableColors) {
|
|
||||||
print('${colors.green("Info:")} $message');
|
|
||||||
} else {
|
|
||||||
print('Info: $message');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds [kind] specific prefix to [message].
|
|
||||||
String prefixMessage(String message, api.Diagnostic kind) {
|
|
||||||
switch (kind) {
|
|
||||||
case api.Diagnostic.ERROR:
|
|
||||||
return 'Error: $message';
|
|
||||||
case api.Diagnostic.WARNING:
|
|
||||||
return 'Warning: $message';
|
|
||||||
case api.Diagnostic.HINT:
|
|
||||||
return 'Hint: $message';
|
|
||||||
case api.Diagnostic.CRASH:
|
|
||||||
return 'Internal Error: $message';
|
|
||||||
case api.Diagnostic.INFO:
|
|
||||||
case api.Diagnostic.VERBOSE_INFO:
|
|
||||||
return 'Info: $message';
|
|
||||||
}
|
|
||||||
throw 'Unexpected diagnostic kind: $kind (${kind.ordinal})';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void report(var code, Uri uri, int begin, int end, String message,
|
|
||||||
api.Diagnostic kind) {
|
|
||||||
if (isAborting) return;
|
|
||||||
isAborting = (kind == api.Diagnostic.CRASH);
|
|
||||||
|
|
||||||
bool fatal = (kind.ordinal & FATAL) != 0;
|
|
||||||
bool isInfo = (kind.ordinal & INFO) != 0;
|
|
||||||
if (isInfo && uri == null && kind != api.Diagnostic.INFO) {
|
|
||||||
info(message, kind);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
message = prefixMessage(message, kind);
|
|
||||||
|
|
||||||
// [lastKind] records the previous non-INFO kind we saw.
|
|
||||||
// This is used to suppress info about a warning when warnings are
|
|
||||||
// suppressed, and similar for hints.
|
|
||||||
if (kind != api.Diagnostic.INFO) {
|
|
||||||
lastKind = kind;
|
|
||||||
}
|
|
||||||
var color;
|
|
||||||
if (kind == api.Diagnostic.ERROR) {
|
|
||||||
color = colors.red;
|
|
||||||
} else if (kind == api.Diagnostic.WARNING) {
|
|
||||||
if (!showWarnings) return;
|
|
||||||
color = colors.magenta;
|
|
||||||
} else if (kind == api.Diagnostic.HINT) {
|
|
||||||
if (!showHints) return;
|
|
||||||
color = colors.cyan;
|
|
||||||
} else if (kind == api.Diagnostic.CRASH) {
|
|
||||||
color = colors.red;
|
|
||||||
} else if (kind == api.Diagnostic.INFO) {
|
|
||||||
if (lastKind == api.Diagnostic.WARNING && !showWarnings) return;
|
|
||||||
if (lastKind == api.Diagnostic.HINT && !showHints) return;
|
|
||||||
color = colors.green;
|
|
||||||
} else {
|
|
||||||
throw 'Unknown kind: $kind (${kind.ordinal})';
|
|
||||||
}
|
|
||||||
if (!enableColors) {
|
|
||||||
color = (x) => x;
|
|
||||||
}
|
|
||||||
if (uri == null) {
|
|
||||||
print('${color(message)}');
|
|
||||||
} else {
|
|
||||||
SourceFile file = provider.sourceFiles[uri];
|
|
||||||
if (file != null) {
|
|
||||||
print(file.getLocationMessage(color(message), begin, end,
|
|
||||||
colorize: color));
|
|
||||||
} else {
|
|
||||||
String position = end - begin > 0 ? '@$begin+${end - begin}' : '';
|
|
||||||
print('${provider.relativizeUri(uri)}$position:\n'
|
|
||||||
'${color(message)}');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fatal && ++fatalCount >= throwOnErrorCount && throwOnError) {
|
|
||||||
isAborting = true;
|
|
||||||
throw new AbortLeg(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(johnniwinther): Remove this when no longer needed for the old compiler
|
|
||||||
// API.
|
|
||||||
void call(Uri uri, int begin, int end, String message, api.Diagnostic kind) {
|
|
||||||
return report(null, uri, begin, end, message, kind);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef void MessageCallback(String message);
|
|
||||||
|
|
||||||
class RandomAccessFileOutputProvider implements CompilerOutput {
|
|
||||||
final Uri out;
|
|
||||||
final Uri sourceMapOut;
|
|
||||||
final Uri resolutionOutput;
|
|
||||||
final MessageCallback onInfo;
|
|
||||||
final MessageCallback onFailure;
|
|
||||||
|
|
||||||
int totalCharactersWritten = 0;
|
|
||||||
List<String> allOutputFiles = new List<String>();
|
|
||||||
|
|
||||||
RandomAccessFileOutputProvider(this.out, this.sourceMapOut,
|
|
||||||
{this.onInfo, this.onFailure, this.resolutionOutput});
|
|
||||||
|
|
||||||
static Uri computePrecompiledUri(Uri out) {
|
|
||||||
String extension = 'precompiled.js';
|
|
||||||
String outPath = out.path;
|
|
||||||
if (outPath.endsWith('.js')) {
|
|
||||||
outPath = outPath.substring(0, outPath.length - 3);
|
|
||||||
return out.resolve('$outPath.$extension');
|
|
||||||
} else {
|
|
||||||
return out.resolve(extension);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EventSink<String> call(String name, String extension) {
|
|
||||||
return createEventSink(name, extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
EventSink<String> createEventSink(String name, String extension) {
|
|
||||||
Uri uri;
|
|
||||||
bool isPrimaryOutput = false;
|
|
||||||
// TODO (johnniwinther, sigurdm): Make a better interface for
|
|
||||||
// output-providers.
|
|
||||||
if (extension == "deferred_map") {
|
|
||||||
uri = out.resolve(name);
|
|
||||||
} else if (name == '') {
|
|
||||||
if (extension == 'js' || extension == 'dart') {
|
|
||||||
isPrimaryOutput = true;
|
|
||||||
uri = out;
|
|
||||||
} else if (extension == 'precompiled.js') {
|
|
||||||
uri = computePrecompiledUri(out);
|
|
||||||
onInfo("File ($uri) is compatible with header"
|
|
||||||
" \"Content-Security-Policy: script-src 'self'\"");
|
|
||||||
} else if (extension == 'js.map' || extension == 'dart.map') {
|
|
||||||
uri = sourceMapOut;
|
|
||||||
} else if (extension == 'info.json') {
|
|
||||||
String outName = out.path.substring(out.path.lastIndexOf('/') + 1);
|
|
||||||
uri = out.resolve('$outName.$extension');
|
|
||||||
} else if (extension == 'data') {
|
|
||||||
if (resolutionOutput == null) {
|
|
||||||
onFailure('Serialization target unspecified.');
|
|
||||||
}
|
|
||||||
uri = resolutionOutput;
|
|
||||||
} else {
|
|
||||||
onFailure('Unknown extension: $extension');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
uri = out.resolve('$name.$extension');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uri.scheme != 'file') {
|
|
||||||
onFailure('Unhandled scheme ${uri.scheme} in $uri.');
|
|
||||||
}
|
|
||||||
|
|
||||||
RandomAccessFile output;
|
|
||||||
try {
|
|
||||||
output = new File(uri.toFilePath()).openSync(mode: FileMode.WRITE);
|
|
||||||
} on FileSystemException catch (e) {
|
|
||||||
onFailure('$e');
|
|
||||||
}
|
|
||||||
|
|
||||||
allOutputFiles.add(relativize(currentDirectory, uri, Platform.isWindows));
|
|
||||||
|
|
||||||
int charactersWritten = 0;
|
|
||||||
|
|
||||||
writeStringSync(String data) {
|
|
||||||
// Write the data in chunks of 8kb, otherwise we risk running OOM.
|
|
||||||
int chunkSize = 8 * 1024;
|
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
while (offset < data.length) {
|
|
||||||
output.writeStringSync(
|
|
||||||
data.substring(offset, math.min(offset + chunkSize, data.length)));
|
|
||||||
offset += chunkSize;
|
|
||||||
}
|
|
||||||
charactersWritten += data.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
onDone() {
|
|
||||||
output.closeSync();
|
|
||||||
if (isPrimaryOutput) {
|
|
||||||
totalCharactersWritten += charactersWritten;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new _EventSinkWrapper(writeStringSync, onDone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _EventSinkWrapper extends EventSink<String> {
|
|
||||||
var onAdd, onClose;
|
|
||||||
|
|
||||||
_EventSinkWrapper(this.onAdd, this.onClose);
|
|
||||||
|
|
||||||
void add(String data) => onAdd(data);
|
|
||||||
|
|
||||||
void addError(error, [StackTrace stackTrace]) => throw error;
|
|
||||||
|
|
||||||
void close() => onClose();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adapter to integrate dart2js in bazel.
|
|
||||||
///
|
|
||||||
/// To handle bazel's special layout:
|
|
||||||
///
|
|
||||||
/// * We specify a .packages configuration file that expands packages to their
|
|
||||||
/// corresponding bazel location. This way there is no need to create a pub
|
|
||||||
/// cache prior to invoking dart2js.
|
|
||||||
///
|
|
||||||
/// * We provide an implicit mapping that can make all urls relative to the
|
|
||||||
/// bazel root.
|
|
||||||
/// To the compiler, URIs look like:
|
|
||||||
/// file:///bazel-root/a/b/c.dart
|
|
||||||
///
|
|
||||||
/// even though in the file system the file is located at:
|
|
||||||
/// file:///path/to/the/actual/bazel/root/a/b/c.dart
|
|
||||||
///
|
|
||||||
/// This mapping serves two purposes:
|
|
||||||
/// - It makes compiler results independent of the machine layout, which
|
|
||||||
/// enables us to share results across bazel runs and across machines.
|
|
||||||
///
|
|
||||||
/// - It hides the distinction between generated and source files. That way
|
|
||||||
/// we can use the standard package-resolution mechanism and ignore the
|
|
||||||
/// internals of how files are organized within bazel.
|
|
||||||
///
|
|
||||||
/// When invoking the compiler, bazel will use `package:` and
|
|
||||||
/// `file:///bazel-root/` URIs to specify entrypoints.
|
|
||||||
///
|
|
||||||
/// The mapping is specified using search paths relative to the current
|
|
||||||
/// directory. When this provider looks up a file, the bazel-root folder is
|
|
||||||
/// replaced by the first directory in the search path containing the file, if
|
|
||||||
/// any. For example, given the search path ".,bazel-bin/", and a URL
|
|
||||||
/// of the form `file:///bazel-root/a/b.dart`, this provider will check if the
|
|
||||||
/// file exists under "./a/b.dart", then check under "bazel-bin/a/b.dart". If
|
|
||||||
/// none of the paths matches, it will attempt to load the file from
|
|
||||||
/// `/bazel-root/a/b.dart` which will likely fail.
|
|
||||||
class BazelInputProvider extends SourceFileProvider {
|
|
||||||
final List<Uri> dirs;
|
|
||||||
|
|
||||||
BazelInputProvider(List<String> searchPaths)
|
|
||||||
: dirs = searchPaths.map(_resolve).toList();
|
|
||||||
|
|
||||||
static _resolve(String path) => currentDirectory.resolve(path);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future readFromUri(Uri uri) async {
|
|
||||||
var resolvedUri = uri;
|
|
||||||
var path = uri.path;
|
|
||||||
if (path.startsWith('/bazel-root')) {
|
|
||||||
path = path.substring('/bazel-root/'.length);
|
|
||||||
for (var dir in dirs) {
|
|
||||||
var file = dir.resolve(path);
|
|
||||||
if (await new File.fromUri(file).exists()) {
|
|
||||||
resolvedUri = file;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var result = await readUtf8BytesFromUri(resolvedUri);
|
|
||||||
sourceFiles[uri] = sourceFiles[resolvedUri];
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,18 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
library dart2js.tokens.keywords;
|
library fasta.scanner.keywords;
|
||||||
|
|
||||||
import '../util/characters.dart' as Characters show $a;
|
import 'characters.dart' show
|
||||||
import 'precedence.dart' show PrecedenceInfo;
|
$a;
|
||||||
import 'precedence_constants.dart' as Precedence
|
|
||||||
show AS_INFO, IS_INFO, KEYWORD_INFO;
|
import 'precedence.dart' show
|
||||||
|
PrecedenceInfo;
|
||||||
|
|
||||||
|
import 'precedence.dart' show
|
||||||
|
AS_INFO,
|
||||||
|
IS_INFO,
|
||||||
|
KEYWORD_INFO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A keyword in the Dart programming language.
|
* A keyword in the Dart programming language.
|
||||||
|
@ -49,10 +55,10 @@ class Keyword {
|
||||||
|
|
||||||
// TODO(ahe): Don't think this is a reserved word.
|
// TODO(ahe): Don't think this is a reserved word.
|
||||||
// See: http://dartbug.com/5579
|
// See: http://dartbug.com/5579
|
||||||
const Keyword("is", info: Precedence.IS_INFO),
|
const Keyword("is", info: IS_INFO),
|
||||||
|
|
||||||
const Keyword("abstract", isBuiltIn: true),
|
const Keyword("abstract", isBuiltIn: true),
|
||||||
const Keyword("as", info: Precedence.AS_INFO, isBuiltIn: true),
|
const Keyword("as", info: AS_INFO, isBuiltIn: true),
|
||||||
const Keyword("covariant", isBuiltIn: true),
|
const Keyword("covariant", isBuiltIn: true),
|
||||||
const Keyword("dynamic", isBuiltIn: true),
|
const Keyword("dynamic", isBuiltIn: true),
|
||||||
const Keyword("export", isBuiltIn: true),
|
const Keyword("export", isBuiltIn: true),
|
||||||
|
@ -97,7 +103,7 @@ class Keyword {
|
||||||
const Keyword(this.syntax,
|
const Keyword(this.syntax,
|
||||||
{this.isPseudo: false,
|
{this.isPseudo: false,
|
||||||
this.isBuiltIn: false,
|
this.isBuiltIn: false,
|
||||||
this.info: Precedence.KEYWORD_INFO});
|
this.info: KEYWORD_INFO});
|
||||||
|
|
||||||
static Map<String, Keyword> computeKeywordMap() {
|
static Map<String, Keyword> computeKeywordMap() {
|
||||||
Map<String, Keyword> result = new Map<String, Keyword>();
|
Map<String, Keyword> result = new Map<String, Keyword>();
|
||||||
|
@ -147,8 +153,8 @@ abstract class KeywordState {
|
||||||
int c = strings[i].codeUnitAt(start);
|
int c = strings[i].codeUnitAt(start);
|
||||||
if (chunk != c) {
|
if (chunk != c) {
|
||||||
if (chunkStart != -1) {
|
if (chunkStart != -1) {
|
||||||
assert(result[chunk - Characters.$a] == null);
|
assert(result[chunk - $a] == null);
|
||||||
result[chunk - Characters.$a] = computeKeywordStateTable(
|
result[chunk - $a] = computeKeywordStateTable(
|
||||||
start + 1, strings, chunkStart, i - chunkStart);
|
start + 1, strings, chunkStart, i - chunkStart);
|
||||||
}
|
}
|
||||||
chunkStart = i;
|
chunkStart = i;
|
||||||
|
@ -157,8 +163,8 @@ abstract class KeywordState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chunkStart != -1) {
|
if (chunkStart != -1) {
|
||||||
assert(result[chunk - Characters.$a] == null);
|
assert(result[chunk - $a] == null);
|
||||||
result[chunk - Characters.$a] = computeKeywordStateTable(
|
result[chunk - $a] = computeKeywordStateTable(
|
||||||
start + 1, strings, chunkStart, offset + length - chunkStart);
|
start + 1, strings, chunkStart, offset + length - chunkStart);
|
||||||
} else {
|
} else {
|
||||||
assert(length == 1);
|
assert(length == 1);
|
||||||
|
@ -181,7 +187,7 @@ class ArrayKeywordState extends KeywordState {
|
||||||
ArrayKeywordState(List<KeywordState> this.table, String syntax)
|
ArrayKeywordState(List<KeywordState> this.table, String syntax)
|
||||||
: super((syntax == null) ? null : Keyword.keywords[syntax]);
|
: super((syntax == null) ? null : Keyword.keywords[syntax]);
|
||||||
|
|
||||||
KeywordState next(int c) => table[c - Characters.$a];
|
KeywordState next(int c) => table[c - $a];
|
||||||
|
|
||||||
String toString() {
|
String toString() {
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
|
@ -194,7 +200,7 @@ class ArrayKeywordState extends KeywordState {
|
||||||
List<KeywordState> foo = table;
|
List<KeywordState> foo = table;
|
||||||
for (int i = 0; i < foo.length; i++) {
|
for (int i = 0; i < foo.length; i++) {
|
||||||
if (foo[i] != null) {
|
if (foo[i] != null) {
|
||||||
sb.write("${new String.fromCharCodes([i + Characters.$a])}: "
|
sb.write("${new String.fromCharCodes([i + $a])}: "
|
||||||
"${foo[i]}; ");
|
"${foo[i]}; ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
36
pkg/front_end/lib/src/fasta/scanner/main.dart
Normal file
36
pkg/front_end/lib/src/fasta/scanner/main.dart
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// Copyright (c) 2016, 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.md file.
|
||||||
|
|
||||||
|
library fasta.scanner.main;
|
||||||
|
|
||||||
|
import 'io.dart' show
|
||||||
|
readBytesFromFileSync;
|
||||||
|
|
||||||
|
import '../scanner.dart' show
|
||||||
|
scan;
|
||||||
|
|
||||||
|
scanAll(Map<Uri, List<int>> files) {
|
||||||
|
Stopwatch sw = new Stopwatch()..start();
|
||||||
|
int byteCount = 0;
|
||||||
|
files.forEach((Uri uri, List<int> bytes) {
|
||||||
|
scan(bytes);
|
||||||
|
byteCount += bytes.length - 1;
|
||||||
|
});
|
||||||
|
sw.stop();
|
||||||
|
print("Scanning files took: ${sw.elapsed}");
|
||||||
|
print("Bytes/ms: ${byteCount/sw.elapsedMilliseconds}");
|
||||||
|
}
|
||||||
|
|
||||||
|
main(List<String> arguments) {
|
||||||
|
Map<Uri, List<int>> files = <Uri, List<int>>{};
|
||||||
|
Stopwatch sw = new Stopwatch()..start();
|
||||||
|
for (String name in arguments) {
|
||||||
|
Uri uri = Uri.base.resolve(name);
|
||||||
|
List<int> bytes = readBytesFromFileSync(uri);
|
||||||
|
files[uri] = bytes;
|
||||||
|
}
|
||||||
|
sw.stop();
|
||||||
|
print("Reading files took: ${sw.elapsed}");
|
||||||
|
scanAll(files);
|
||||||
|
}
|
|
@ -2,11 +2,20 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
library dart2js.tokens.precedence.constants;
|
library fasta.scanner.precedence;
|
||||||
|
|
||||||
import 'precedence.dart' show PrecedenceInfo;
|
|
||||||
import 'token_constants.dart';
|
import 'token_constants.dart';
|
||||||
|
|
||||||
|
class PrecedenceInfo {
|
||||||
|
final String value;
|
||||||
|
final int precedence;
|
||||||
|
final int kind;
|
||||||
|
|
||||||
|
const PrecedenceInfo(this.value, this.precedence, this.kind);
|
||||||
|
|
||||||
|
toString() => 'PrecedenceInfo($value, $precedence, $kind)';
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(ahe): The following are not tokens in Dart.
|
// TODO(ahe): The following are not tokens in Dart.
|
||||||
const PrecedenceInfo BACKPING_INFO =
|
const PrecedenceInfo BACKPING_INFO =
|
||||||
const PrecedenceInfo('`', 0, BACKPING_TOKEN);
|
const PrecedenceInfo('`', 0, BACKPING_TOKEN);
|
||||||
|
|
29
pkg/front_end/lib/src/fasta/scanner/recover.dart
Normal file
29
pkg/front_end/lib/src/fasta/scanner/recover.dart
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright (c) 2017, 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 licenset hat can be found in the LICENSE file.
|
||||||
|
|
||||||
|
library fasta.scanner.recover;
|
||||||
|
|
||||||
|
import 'token.dart' show
|
||||||
|
Token;
|
||||||
|
|
||||||
|
/// Recover from errors in [tokens]. The original sources are provided as
|
||||||
|
/// [bytes]. [lineStarts] are the beginning character offsets of lines, and
|
||||||
|
/// must be updated if recovery is performed rewriting the original source
|
||||||
|
/// code.
|
||||||
|
Token defaultRecoveryStrategy(
|
||||||
|
List<int> bytes, Token tokens, List<int> lineStarts) {
|
||||||
|
// See [Parser.reportErrorToken](package:front_end/src/fasta/parser/src/parser.dart) for how
|
||||||
|
// it currently handles lexical errors. In addition, notice how the parser
|
||||||
|
// calls [handleInvalidExpression], [handleInvalidFunctionBody], and
|
||||||
|
// [handleInvalidTypeReference] to allow the listener to recover its internal
|
||||||
|
// state. See [package:compiler/src/parser/element_listener.dart] for an
|
||||||
|
// example of how these events are used.
|
||||||
|
//
|
||||||
|
// In addition, the scanner will attempt a bit of recovery when braces don't
|
||||||
|
// match up during brace grouping. See
|
||||||
|
// [ArrayBasedScanner.discardBeginGroupUntil](array_based_scanner.dart). For
|
||||||
|
// more details on brace grouping see
|
||||||
|
// [AbstractScanner.unmatchedBeginGroup](abstract_scanner.dart).
|
||||||
|
return tokens;
|
||||||
|
}
|
|
@ -2,12 +2,17 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
library dart2js.scanner.string;
|
library dart2js.scanner.string_scanner;
|
||||||
|
|
||||||
import '../io/source_file.dart' show SourceFile;
|
import 'array_based_scanner.dart' show
|
||||||
import '../tokens/precedence.dart' show PrecedenceInfo;
|
ArrayBasedScanner;
|
||||||
import '../tokens/token.dart' show StringToken, Token;
|
|
||||||
import 'array_based_scanner.dart' show ArrayBasedScanner;
|
import 'precedence.dart' show
|
||||||
|
PrecedenceInfo;
|
||||||
|
|
||||||
|
import 'token.dart' show
|
||||||
|
StringToken,
|
||||||
|
Token;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scanner that reads from a String and creates tokens that points to
|
* Scanner that reads from a String and creates tokens that points to
|
||||||
|
@ -20,22 +25,15 @@ class StringScanner extends ArrayBasedScanner {
|
||||||
/** The current offset in [string]. */
|
/** The current offset in [string]. */
|
||||||
int scanOffset = -1;
|
int scanOffset = -1;
|
||||||
|
|
||||||
StringScanner(SourceFile file, {bool includeComments: false})
|
StringScanner(String string, {bool includeComments: false})
|
||||||
: string = file.slowText(),
|
: string = ensureZeroTermination(string),
|
||||||
super(file, includeComments) {
|
super(includeComments);
|
||||||
ensureZeroTermination();
|
|
||||||
}
|
|
||||||
|
|
||||||
StringScanner.fromString(this.string, {bool includeComments: false})
|
static String ensureZeroTermination(String string) {
|
||||||
: super(null, includeComments) {
|
return (string.isEmpty || string.codeUnitAt(string.length - 1) != 0)
|
||||||
ensureZeroTermination();
|
// TODO(lry): abort instead of copying the array, or warn?
|
||||||
}
|
? string + '\x00'
|
||||||
|
: string;
|
||||||
void ensureZeroTermination() {
|
|
||||||
if (string.isEmpty || string.codeUnitAt(string.length - 1) != 0) {
|
|
||||||
// TODO(lry): abort instead of copying the array, or warn?
|
|
||||||
string = string + '\x00';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int advance() => string.codeUnitAt(++scanOffset);
|
int advance() => string.codeUnitAt(++scanOffset);
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
// Copyright (c) 2016, 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.md file.
|
||||||
|
|
||||||
|
library fasta.scanner.testing.scanner_chain;
|
||||||
|
|
||||||
|
import 'package:testing/testing.dart';
|
||||||
|
|
||||||
|
import 'package:front_end/src/fasta/scanner.dart';
|
||||||
|
|
||||||
|
import 'package:front_end/src/fasta/scanner/io.dart';
|
||||||
|
|
||||||
|
class Read extends Step<TestDescription, List<int>, ChainContext> {
|
||||||
|
const Read();
|
||||||
|
|
||||||
|
String get name => "read";
|
||||||
|
|
||||||
|
Future<Result<List<int>>> run(
|
||||||
|
TestDescription input, ChainContext context) async {
|
||||||
|
return pass(await readBytesFromFile(input.uri));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Scan extends Step<List<int>, ScannerResult, ChainContext> {
|
||||||
|
const Scan();
|
||||||
|
|
||||||
|
String get name => "scan";
|
||||||
|
|
||||||
|
Future<Result<ScannerResult>> run(
|
||||||
|
List<int> bytes, ChainContext context) async {
|
||||||
|
return pass(scan(bytes));
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,22 +2,28 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
library dart2js.tokens;
|
library fasta.scanner.token;
|
||||||
|
|
||||||
import 'dart:collection' show HashSet;
|
import 'dart:collection' show
|
||||||
import 'dart:convert' show UTF8;
|
HashSet;
|
||||||
|
|
||||||
import '../common.dart';
|
import 'dart:convert' show
|
||||||
import '../util/util.dart' show computeHashCode;
|
UTF8;
|
||||||
import 'keyword.dart' show Keyword;
|
|
||||||
import 'precedence.dart' show PrecedenceInfo;
|
import 'keyword.dart' show
|
||||||
import 'precedence_constants.dart' as Precedence show BAD_INPUT_INFO;
|
Keyword;
|
||||||
import 'token_constants.dart' as Tokens show IDENTIFIER_TOKEN;
|
|
||||||
|
import 'precedence.dart' show
|
||||||
|
BAD_INPUT_INFO,
|
||||||
|
PrecedenceInfo;
|
||||||
|
|
||||||
|
import 'token_constants.dart' show
|
||||||
|
IDENTIFIER_TOKEN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A token that doubles as a linked list.
|
* A token that doubles as a linked list.
|
||||||
*/
|
*/
|
||||||
abstract class Token implements Spannable {
|
abstract class Token {
|
||||||
/**
|
/**
|
||||||
* The character offset of the start of this token within the source text.
|
* The character offset of the start of this token within the source text.
|
||||||
*/
|
*/
|
||||||
|
@ -95,7 +101,7 @@ abstract class Token implements Spannable {
|
||||||
* The number of characters parsed by this token.
|
* The number of characters parsed by this token.
|
||||||
*/
|
*/
|
||||||
int get charCount {
|
int get charCount {
|
||||||
if (info == Precedence.BAD_INPUT_INFO) {
|
if (info == BAD_INPUT_INFO) {
|
||||||
// This is a token that wraps around an error message. Return 1
|
// This is a token that wraps around an error message. Return 1
|
||||||
// instead of the size of the length of the error message.
|
// instead of the size of the length of the error message.
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -106,17 +112,6 @@ abstract class Token implements Spannable {
|
||||||
|
|
||||||
/// The character offset of the end of this token within the source text.
|
/// The character offset of the end of this token within the source text.
|
||||||
int get charEnd => charOffset + charCount;
|
int get charEnd => charOffset + charCount;
|
||||||
|
|
||||||
int get hashCode => computeHashCode(charOffset, info, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A pair of tokens marking the beginning and the end of a span. Use for error
|
|
||||||
/// reporting.
|
|
||||||
class TokenPair implements Spannable {
|
|
||||||
final Token begin;
|
|
||||||
final Token end;
|
|
||||||
|
|
||||||
TokenPair(this.begin, this.end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -172,10 +167,10 @@ class KeywordToken extends Token {
|
||||||
abstract class ErrorToken extends Token {
|
abstract class ErrorToken extends Token {
|
||||||
ErrorToken(int charOffset) : super(charOffset);
|
ErrorToken(int charOffset) : super(charOffset);
|
||||||
|
|
||||||
PrecedenceInfo get info => Precedence.BAD_INPUT_INFO;
|
PrecedenceInfo get info => BAD_INPUT_INFO;
|
||||||
|
|
||||||
String get value {
|
String get value {
|
||||||
throw new SpannableAssertionFailure(this, assertionMessage);
|
throw assertionMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
String get stringValue => null;
|
String get stringValue => null;
|
||||||
|
@ -307,7 +302,7 @@ class StringToken extends Token {
|
||||||
/// See [Token.stringValue] for an explanation.
|
/// See [Token.stringValue] for an explanation.
|
||||||
String get stringValue => null;
|
String get stringValue => null;
|
||||||
|
|
||||||
bool isIdentifier() => identical(kind, Tokens.IDENTIFIER_TOKEN);
|
bool isIdentifier() => identical(kind, IDENTIFIER_TOKEN);
|
||||||
|
|
||||||
String toString() => "StringToken($value)";
|
String toString() => "StringToken($value)";
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// 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.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
library dart2js.tokens.constants;
|
library fasta.scanner.token_constants;
|
||||||
|
|
||||||
import '../util/characters.dart';
|
import 'characters.dart';
|
||||||
|
|
||||||
const int EOF_TOKEN = 0;
|
const int EOF_TOKEN = 0;
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue