1
0
mirror of https://github.com/dart-lang/sdk synced 2024-07-08 20:16:39 +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:
Peter von der Ahé 2017-01-31 12:44:23 +01:00 committed by Peter von der Ahé
parent 2a4bc2c7e5
commit d0d27c1c38
118 changed files with 5012 additions and 1825 deletions

3
.gitignore vendored
View File

@ -75,3 +75,6 @@ editor/util/testing/mac/CodeLab.suite/Results
editor/util/testing/mac/DartEditor.suite/Results
editor/util/testing/mac/Samples.suite/Results
.test-outcome.log
/outline.dill
/generated/
/crash_logs/

View File

@ -28,7 +28,6 @@ compiler_unsupported:pkg/compiler/lib
convert:third_party/pkg/convert/lib
crypto:third_party/pkg/crypto/lib
csslib:third_party/pkg/csslib/lib
dart2js_incremental:pkg/dart2js_incremental/lib
dart2js_info:third_party/pkg/dart2js_info/lib
dart_messages:pkg/dart_messages/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
string_scanner:third_party/pkg/string_scanner/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
typed_data:third_party/pkg/typed_data/lib
typed_mock:pkg/typed_mock/lib

View File

@ -18,7 +18,7 @@ import 'elements/modelx.dart'
import 'elements/visitor.dart' show ElementVisitor;
import 'js_backend/js_backend.dart' show JavaScriptBackend;
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 'util/util.dart';
import 'world.dart' show ClosedWorldRefiner;

View File

@ -17,7 +17,6 @@ import '../elements/elements.dart'
FunctionElement,
LocalFunctionElement,
ResolvedAst;
import '../enqueue.dart' show Enqueuer;
import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse;
import '../universe/world_impact.dart'
show WorldImpact, WorldImpactBuilderImpl, WorldImpactVisitor;

View File

@ -30,6 +30,7 @@ import '../mirrors_used.dart';
import '../options.dart' show CompilerOptions;
import '../parser/element_listener.dart' show ScannerOptions;
import '../parser/parser_task.dart';
import '../scanner/scanner_task.dart';
import '../patch_parser.dart';
import '../resolution/resolution.dart';
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.
abstract class ParsingContext {
factory ParsingContext(DiagnosticReporter reporter, ParserTask parser,
PatchParserTask patchParser, Backend backend) = _ParsingContext;
ScannerTask scanner, PatchParserTask patchParser, Backend backend)
= _ParsingContext;
DiagnosticReporter get reporter;
ParserTask get parser;
ScannerTask get scanner;
PatchParserTask get patchParser;
/// Use [patchParser] directly instead.
@ -236,10 +239,12 @@ abstract class ParsingContext {
class _ParsingContext implements ParsingContext {
final DiagnosticReporter reporter;
final ParserTask parser;
final ScannerTask scanner;
final PatchParserTask patchParser;
final Backend backend;
_ParsingContext(this.reporter, this.parser, this.patchParser, this.backend);
_ParsingContext(this.reporter, this.parser, this.scanner, this.patchParser,
this.backend);
@override
measure(f()) => parser.measure(f);

View File

@ -5,9 +5,7 @@
library dart2js.common.work;
import '../common.dart';
import '../compiler.dart' show Compiler;
import '../elements/elements.dart' show AstElement;
import '../enqueue.dart' show Enqueuer;
import '../universe/world_impact.dart' show WorldImpact;
abstract class WorkItem {

View File

@ -1294,7 +1294,7 @@ class ConstructorEvaluator extends CompileTimeConstantEvaluator {
Function compileArgument = (element) => definitions[element];
Function compileConstant = handler.compileConstant;
FunctionElement target = constructor.definingConstructor.implementation;
Elements.addForwardingElementArgumentsToList<AstConstant>(constructor,
Elements.addForwardingElementArgumentsToList(constructor,
compiledArguments, target, compileArgument, compileConstant);
CallStructure callStructure = new CallStructure(
target.functionSignature.parameterCount, target.type.namedParameters);

View File

@ -66,9 +66,9 @@ import 'scanner/scanner_task.dart' show ScannerTask;
import 'script.dart' show Script;
import 'serialization/task.dart' show SerializationTask;
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 'tracer.dart' show Tracer;
import 'tree/tree.dart' show Node, TypeAnnotation;
import 'typechecker.dart' show TypeCheckerTask;
import 'types/types.dart' show GlobalTypeInferenceTask;
@ -80,7 +80,6 @@ import 'universe/world_impact.dart'
show
ImpactStrategy,
WorldImpact,
WorldImpactBuilder,
WorldImpactBuilderImpl;
import 'util/util.dart' show Link, Setlet;
import 'world.dart' show ClosedWorld, ClosedWorldRefiner, ClosedWorldImpl;
@ -266,7 +265,7 @@ abstract class Compiler implements LibraryLoaderListener {
}
_parsingContext =
new ParsingContext(reporter, parser, patchParser, backend);
new ParsingContext(reporter, parser, scanner, patchParser, backend);
tasks.addAll(backend.tasks);
}
@ -1214,9 +1213,6 @@ class _CompilerCommonElements extends CommonElementsMixin {
return _findLibraryMember(library, name, required: required);
}
Element _findRequired(LibraryElement library, String name) =>
_findLibraryMember(library, name);
Element _findLibraryMember(LibraryElement library, String name,
{bool required: true}) {
// If the script of the library is synthesized, the library does not exist
@ -1398,6 +1394,9 @@ class CompilerDiagnosticReporter extends DiagnosticReporter {
api.Diagnostic.CRASH);
}
@override
SourceSpan spanFromToken(Token token) => spanFromTokens(token, token);
SourceSpan spanFromTokens(Token begin, Token end, [Uri uri]) {
if (begin == null || end == null) {
// TODO(ahe): We can almost always do better. Often it is only
@ -1546,10 +1545,6 @@ class CompilerDiagnosticReporter extends DiagnosticReporter {
return node;
} else if (node is 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) {
return spanFromHInstruction(node);
} else if (node is Element) {
@ -1715,7 +1710,6 @@ class CompilerResolution implements Resolution {
MirrorUsageAnalyzerTask get mirrorUsageAnalyzerTask =>
_compiler.mirrorUsageAnalyzerTask;
@override
LibraryElement get coreLibrary => _compiler._commonElements.coreLibrary;
@override

View File

@ -122,7 +122,6 @@ Future<api.CompilationResult> compile(List<String> argv) {
Uri resolutionOutput = currentDirectory.resolve('out.data');
bool allowNativeExtensions = false;
bool trustTypeAnnotations = false;
bool trustJSInteropTypeAnnotations = false;
bool checkedMode = false;
List<String> hints = <String>[];
bool verbose;
@ -243,7 +242,6 @@ Future<api.CompilationResult> compile(List<String> argv) {
}
void setTrustJSInteropTypeAnnotations(String argument) {
trustJSInteropTypeAnnotations = true;
implyCompilation(argument);
}

View File

@ -40,7 +40,7 @@ import 'universe/world_impact.dart'
show ImpactUseCase, WorldImpact, WorldImpactVisitorImpl;
import 'util/setlet.dart' show Setlet;
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]
/// are loaded.

View File

@ -4,6 +4,7 @@
library dart2js.diagnostic_listener;
import 'package:front_end/src/fasta/scanner.dart' show Token;
import '../elements/elements.dart' show Element;
import '../options.dart' show DiagnosticOptions;
import 'messages.dart';
@ -21,11 +22,16 @@ abstract class DiagnosticReporter {
/// 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
/// corresponding tokens can be found within the tokens of the current
/// element.
/// If [node] is a [Node] we assert in checked mode that the corresponding
/// tokens can be found within the tokens of the current element.
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,
[Map arguments = const {}]) {
reportError(createMessage(spannable, messageKind, arguments));

View File

@ -62,7 +62,8 @@
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 'invariant.dart' show invariant;
import 'spannable.dart' show CURRENT_ELEMENT_SPANNABLE;
@ -3090,7 +3091,9 @@ main() => r\"\"\"
examples: const [
"main(",
"main(){",
"main(){]}",
"main(){[}",
// TODO(ahe): https://github.com/dart-lang/sdk/issues/28495
// "main(){]}",
]),
MessageKind.UNTERMINATED_TOKEN: const MessageTemplate(

View File

@ -4,7 +4,7 @@
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 'spannable.dart' show Spannable;

View File

@ -13,11 +13,11 @@ import '../ordered_typeset.dart' show OrderedTypeSet;
import '../resolution/scope.dart' show Scope;
import '../resolution/tree_elements.dart' show TreeElements;
import '../script.dart';
import '../tokens/token.dart'
import 'package:front_end/src/fasta/scanner.dart'
show Token, isUserDefinableOperator, isMinusOperator;
import '../tree/tree.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 '../world.dart' show ClosedWorld;
import 'entities.dart';

View File

@ -20,8 +20,10 @@ import '../resolution/scope.dart'
import '../resolution/tree_elements.dart' show TreeElements;
import '../resolution/typedefs.dart' show TypedefCyclicVisitor;
import '../script.dart';
import '../tokens/token.dart' show ErrorToken, Token;
import '../tokens/token_constants.dart' as Tokens show EOF_TOKEN;
import 'package:front_end/src/fasta/scanner.dart'
show ErrorToken, Token;
import 'package:front_end/src/fasta/scanner.dart' as Tokens
show EOF_TOKEN;
import '../tree/tree.dart';
import '../util/util.dart';
import 'common.dart';
@ -314,7 +316,6 @@ class ErroneousConstructorElementX extends ErroneousElementX
@override
bool isRedirectingGenerativeInternal;
@override
void set isRedirectingGenerative(_) {
throw new UnsupportedError("isRedirectingGenerative");
}

View File

@ -78,7 +78,6 @@ int _rotl32(int val, int shift) {
// functions.
abstract class _HashBase implements Hash {
final int _chunkSizeInWords;
final int _digestSizeInWords;
final bool _bigEndianWords;
final List<int> _currentChunk;
final List<int> _h;
@ -91,8 +90,7 @@ abstract class _HashBase implements Hash {
: _pendingData = [],
_currentChunk = new List(chunkSizeInWords),
_h = new List(digestSizeInWords),
_chunkSizeInWords = chunkSizeInWords,
_digestSizeInWords = digestSizeInWords;
_chunkSizeInWords = chunkSizeInWords;
// Update the hasher with more data.
void add(List<int> data) {

View File

@ -102,7 +102,6 @@ StackTraceLines stackTrace({int offset: 1, int limit: null}) {
rangeEnd: rangeEnd,
filePrefix: stackTraceFilePrefix);
}
return null;
}
/// A stack trace as a sequence of [StackTraceLine]s.

View File

@ -1215,7 +1215,6 @@ class ElementGraphBuilder extends ast.Visitor<TypeInformation>
(element != null && element.isInstanceMember);
}
@override
TypeInformation handleSendSet(ast.SendSet node) {
Element element = elements[node];
if (!Elements.isUnresolved(element) && element.impliesType) {
@ -2280,7 +2279,6 @@ class ElementGraphBuilder extends ast.Visitor<TypeInformation>
return inferrer.registerAwait(node, futureType);
}
@override
TypeInformation handleTypeLiteralInvoke(ast.NodeList arguments) {
// 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

View File

@ -6,7 +6,6 @@ library type_graph_inferrer;
import 'dart:collection' show Queue;
import '../common.dart';
import '../compiler.dart' show Compiler;
import '../elements/elements.dart';
import '../tree/tree.dart' as ast show Node;

View File

@ -12,7 +12,7 @@ import '../diagnostics/messages.dart' show MessageTemplate;
import '../elements/elements.dart' show ResolvedAst, ResolvedAstKind;
import '../js/js.dart' as js;
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 'source_file.dart';
import 'source_information.dart';

View File

@ -129,7 +129,6 @@ abstract class ReferenceCountedAstNode implements Node {
/// This is used when generated code needs to be represented as a string,
/// for example by the lazy emitter or when generating code generators.
class UnparsedNode extends DeferredString implements AstContainer {
@override
final Node tree;
final Compiler _compiler;
final bool _protectForEval;

View File

@ -905,7 +905,8 @@ class JavaScriptBackend extends Backend {
if (elements.isEmpty) return false;
return elements.any((element) {
return selector.applies(element) &&
(mask == null || mask.canHit(element, selector, _closedWorld));
(mask == null ||
mask.canHit(element as MemberElement, selector, _closedWorld));
});
}

View File

@ -206,8 +206,6 @@ class BackendHelpers {
// TODO(johnniwinther): Split into _findHelperFunction and _findHelperClass
// and add a check that the element has the expected kind.
Element _findHelper(String name) => _find(jsHelperLibrary, name);
FunctionElement _findHelperFunction(String name) =>
_find(jsHelperLibrary, name);
Element _findAsyncHelper(String name) => _find(asyncLibrary, name);
Element _findInterceptor(String name) => _find(interceptorsLibrary, name);
Element _find(LibraryElement library, String name) {

View File

@ -12,7 +12,6 @@ import '../elements/elements.dart' show ClassElement, Element;
import '../universe/selector.dart';
import '../util/enumset.dart';
import 'backend_helpers.dart';
import 'constant_system_javascript.dart';
import 'js_backend.dart';
/// Backend specific features required by a backend impact.

View File

@ -6,7 +6,6 @@ import '../compiler.dart' show Compiler;
import '../constants/values.dart';
import '../elements/resolution_types.dart';
import '../elements/elements.dart';
import '../enqueue.dart' show Enqueuer;
import '../universe/use.dart' show StaticUse;
import '../universe/world_impact.dart'
show WorldImpact, StagedWorldImpactBuilder;

View File

@ -17,7 +17,6 @@ import '../constants/values.dart'
NullConstantValue,
StringConstantValue,
TypeConstantValue;
import '../elements/resolution_types.dart' show ResolutionDartType;
import '../elements/resolution_types.dart' show ResolutionInterfaceType;
import '../elements/elements.dart'
show ClassElement, FieldElement, LibraryElement, VariableElement;

View File

@ -317,25 +317,20 @@ class _ConstructorBodyNamingScope {
int get numberOfConstructors => _constructors.length;
_ConstructorBodyNamingScope _superScope;
_ConstructorBodyNamingScope.rootScope(ClassElement cls)
: _superScope = null,
_startIndex = 0,
: _startIndex = 0,
_constructors = cls.constructors.toList(growable: false);
_ConstructorBodyNamingScope.forClass(
ClassElement cls, _ConstructorBodyNamingScope superScope)
: _superScope = superScope,
_startIndex = superScope._startIndex + superScope.numberOfConstructors,
: _startIndex = superScope._startIndex + superScope.numberOfConstructors,
_constructors = cls.constructors.toList(growable: false);
// Mixin Applications have constructors but we never generate code for them,
// so they do not count in the inheritance chain.
_ConstructorBodyNamingScope.forMixinApplication(
ClassElement cls, _ConstructorBodyNamingScope superScope)
: _superScope = superScope,
_startIndex = superScope._startIndex + superScope.numberOfConstructors,
: _startIndex = superScope._startIndex + superScope.numberOfConstructors,
_constructors = const [];
factory _ConstructorBodyNamingScope(ClassElement cls,

View File

@ -11,7 +11,6 @@ import 'package:js_runtime/shared/embedded_names.dart' show JsGetName;
import '../closure.dart';
import '../common.dart';
import '../common/names.dart' show Identifiers, Selectors;
import '../compiler.dart' show Compiler;
import '../constants/values.dart';
import '../core_types.dart' show CommonElements;
import '../elements/resolution_types.dart';
@ -24,7 +23,7 @@ import '../tree/tree.dart';
import '../universe/call_structure.dart' show CallStructure;
import '../universe/selector.dart' show Selector, SelectorKind;
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 '../world.dart' show ClosedWorld;
import 'backend.dart';

View File

@ -589,7 +589,6 @@ class _RuntimeTypes implements RuntimeTypes {
class _RuntimeTypesEncoder implements RuntimeTypesEncoder {
final Compiler compiler;
@override
final TypeRepresentationGenerator representationGenerator;
_RuntimeTypesEncoder(Compiler compiler)

View File

@ -8,12 +8,10 @@ import '../constants/expressions.dart';
import '../constants/values.dart';
import '../elements/resolution_types.dart';
import '../elements/elements.dart';
import '../enqueue.dart' show Enqueuer;
import '../js/js.dart' as jsAst;
import '../js_emitter/js_emitter.dart'
show CodeEmitterTask, MetadataCollector, Placeholder;
import '../universe/call_structure.dart' show CallStructure;
import '../universe/use.dart' show StaticUse;
import '../universe/world_impact.dart';
import '../util/util.dart';
import 'backend.dart';
@ -101,7 +99,6 @@ class TypeVariableHandler {
// Do not process classes twice.
if (_typeVariables.containsKey(cls)) return;
ResolutionInterfaceType typeVariableType = _typeVariableClass.thisType;
List<jsAst.Expression> constants = <jsAst.Expression>[];
for (ResolutionTypeVariableType currentTypeVariable in cls.typeVariables) {
@ -111,8 +108,6 @@ class TypeVariableHandler {
_metadataCollector.reifyType(typeVariableElement.bound);
ConstantValue boundValue = new SyntheticConstantValue(
SyntheticConstantKind.TYPEVARIABLE_REFERENCE, boundIndex);
ConstantExpression boundExpression =
new SyntheticConstantExpression(boundValue);
ConstantExpression constant = new ConstructedConstantExpression(
_typeVariableConstructor.enclosingClass.thisType,
_typeVariableConstructor,

View File

@ -9,7 +9,8 @@ import '../../js/js.dart' as jsAst;
import '../../js/js.dart' show js;
import '../../js_backend/js_backend.dart' show GetterName, SetterName;
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 '../js_emitter.dart' hide Emitter, EmitterFactory;
import '../model.dart';

View File

@ -281,7 +281,6 @@ class Collector {
}
void computeNeededStaticNonFinalFields() {
JavaScriptConstantCompiler handler = backend.constants;
addToOutputUnit(Element element) {
List<VariableElement> list = outputStaticNonFinalFieldLists.putIfAbsent(
compiler.deferredLoadTask.outputUnitForElement(element),

View File

@ -183,7 +183,7 @@ class ProgramBuilder {
List<js.TokenFinalizer> finalizers = [_task.metadataCollector];
if (backend.namer is js.TokenFinalizer) {
var namingFinalizer = backend.namer;
finalizers.add(namingFinalizer);
finalizers.add(namingFinalizer as js.TokenFinalizer);
}
return new Program(fragments, holders, _buildLoadMap(), _symbolsMap,

View File

@ -1037,11 +1037,8 @@ class KernelVisitor extends Object
}
ir.SwitchCase irCase = casesIterator.current;
List<ir.Statement> statements = <ir.Statement>[];
bool hasVariableDeclaration = false;
for (Statement statement in caseNode.statements.nodes) {
if (buildStatement(statement, statements)) {
hasVariableDeclaration = true;
}
buildStatement(statement, statements);
}
if (statements.isEmpty || fallsThrough(statements.last)) {
if (isLastCase) {
@ -2116,7 +2113,6 @@ class KernelVisitor extends Object
// [body] must be `null`.
} else if (function.isConstructor) {
// TODO(johnniwinther): Clean this up pending kernel issue #28.
ConstructorElement constructor = function;
if (bodyNode == null || bodyNode.asEmptyStatement() != null) {
body = new ir.EmptyStatement();
} else {

View File

@ -2,8 +2,6 @@
// 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 'dart:collection' show Queue;
import '../common.dart';
import '../common/backend_api.dart' show ForeignResolver;
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/js_backend.dart';
import '../js_emitter/js_emitter.dart' show CodeEmitterTask, NativeEmitter;
import '../tokens/token.dart' show BeginGroupToken, Token;
import '../tokens/token_constants.dart' as Tokens show EOF_TOKEN;
import 'package:front_end/src/fasta/scanner.dart'
show BeginGroupToken, Token;
import 'package:front_end/src/fasta/scanner.dart' as Tokens
show EOF_TOKEN;
import '../tree/tree.dart';
import '../universe/use.dart' show StaticUse, TypeUse;
import '../universe/world_impact.dart'

View File

@ -4,12 +4,14 @@
import '../common.dart';
import '../parser/element_listener.dart' show ElementListener;
import '../tokens/token.dart' show BeginGroupToken, Token;
import '../tokens/token_constants.dart' as Tokens show STRING_TOKEN;
import 'package:front_end/src/fasta/scanner.dart'
show BeginGroupToken, Token;
import 'package:front_end/src/fasta/scanner/token_constants.dart' as Tokens
show STRING_TOKEN;
void checkAllowedLibrary(ElementListener listener, Token token) {
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) {

View File

@ -9,7 +9,8 @@ import 'elements/resolution_types.dart';
import 'diagnostics/diagnostic_listener.dart' show DiagnosticReporter;
import 'elements/elements.dart' show ClassElement;
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

View File

@ -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);
}

View File

@ -9,10 +9,17 @@ import '../common/backend_api.dart' show Backend;
import '../common/tasks.dart' show CompilerTask, Measurer;
import '../elements/elements.dart' show CompilationUnitElement;
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 'listener.dart' show ParserError;
import 'partial_parser.dart' show PartialParser;
import 'package:front_end/src/fasta/parser.dart'
show Listener, ParserError, TopLevelParser;
class PartialParser extends TopLevelParser {
PartialParser(Listener listener)
: super(listener);
Token parseFormalParameters(Token token) => skipFormalParameters(token);
}
class DietParserTask extends CompilerTask {
final IdGenerator _idGenerator;

View File

@ -22,14 +22,16 @@ import '../elements/modelx.dart'
import '../id_generator.dart';
import '../native/native.dart' as native;
import '../string_validator.dart' show StringValidator;
import '../tokens/keyword.dart' show Keyword;
import '../tokens/precedence_constants.dart' as Precedence show BAD_INPUT_INFO;
import '../tokens/token.dart'
show BeginGroupToken, ErrorToken, KeywordToken, Token;
import '../tokens/token_constants.dart' as Tokens show EOF_TOKEN;
import 'package:front_end/src/fasta/scanner.dart'
show Keyword, BeginGroupToken, ErrorToken, KeywordToken, StringToken, Token;
import 'package:front_end/src/fasta/scanner.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 '../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'
show
PartialClassElement,
@ -39,6 +41,8 @@ import 'partial_elements.dart'
PartialMetadataAnnotation,
PartialTypedefElement;
const bool VERBOSE = false;
/// Options used for scanning.
///
/// Use this to conditionally support special tokens.
@ -82,6 +86,10 @@ class ElementListener extends Listener {
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,
this.compilationUnitElement, this.idGenerator)
: this.reporter = reporter,
@ -121,12 +129,14 @@ class ElementListener extends Listener {
library.entryCompilationUnit == compilationUnitElement;
}
@override
void endLibraryName(Token libraryKeyword, Token semicolon) {
Expression name = popNode();
addLibraryTag(new LibraryName(
libraryKeyword, name, popMetadata(compilationUnitElement)));
}
@override
void endImport(Token importKeyword, Token deferredKeyword, Token asKeyword,
Token semicolon) {
NodeList combinators = popNode();
@ -142,11 +152,13 @@ class ElementListener extends Listener {
isDeferred: isDeferred));
}
@override
void endDottedName(int count, Token token) {
NodeList identifiers = makeNodeList(count, null, null, '.');
pushNode(new DottedName(token, identifiers));
}
@override
void endConditionalUris(int count) {
if (count == 0) {
pushNode(null);
@ -155,6 +167,7 @@ class ElementListener extends Listener {
}
}
@override
void endConditionalUri(Token ifToken, Token equalSign) {
StringNode uri = popNode();
LiteralString conditionValue = (equalSign != null) ? popNode() : null;
@ -162,6 +175,7 @@ class ElementListener extends Listener {
pushNode(new ConditionalUri(ifToken, identifier, conditionValue, uri));
}
@override
void endEnum(Token enumKeyword, Token endBrace, int count) {
NodeList names = makeNodeList(count, enumKeyword.next.next, endBrace, ",");
Identifier name = popNode();
@ -173,6 +187,7 @@ class ElementListener extends Listener {
rejectBuiltInIdentifier(name);
}
@override
void endExport(Token exportKeyword, Token semicolon) {
NodeList combinators = popNode();
NodeList conditionalUris = popNode();
@ -181,6 +196,7 @@ class ElementListener extends Listener {
popMetadata(compilationUnitElement)));
}
@override
void endCombinators(int count) {
if (0 == count) {
pushNode(null);
@ -189,8 +205,10 @@ class ElementListener extends Listener {
}
}
@override
void endHide(Token hideKeyword) => pushCombinator(hideKeyword);
@override
void endShow(Token showKeyword) => pushCombinator(showKeyword);
void pushCombinator(Token keywordToken) {
@ -198,20 +216,24 @@ class ElementListener extends Listener {
pushNode(new Combinator(identifiers, keywordToken));
}
@override
void endIdentifierList(int count) {
pushNode(makeNodeList(count, null, null, ","));
}
@override
void endTypeList(int count) {
pushNode(makeNodeList(count, null, null, ","));
}
@override
void endPart(Token partKeyword, Token semicolon) {
StringNode uri = popLiteralString();
addLibraryTag(
new Part(partKeyword, uri, popMetadata(compilationUnitElement)));
}
@override
void endPartOf(Token partKeyword, Token semicolon) {
Expression name = popNode();
addPartOfTag(
@ -222,6 +244,7 @@ class ElementListener extends Listener {
compilationUnitElement.setPartOf(tag, reporter);
}
@override
void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
if (periodBeforeName != null) {
popNode(); // Discard name.
@ -230,14 +253,17 @@ class ElementListener extends Listener {
pushMetadata(new PartialMetadataAnnotation(beginToken, endToken));
}
@override
void endTopLevelDeclaration(Token token) {
if (!metadata.isEmpty) {
MetadataAnnotationX first = metadata.first;
recoverableError(first.beginToken, 'Metadata not supported here.');
recoverableError(reporter.spanFromToken(first.beginToken),
'Metadata not supported here.');
metadata.clear();
}
}
@override
void endClassDeclaration(int interfacesCount, Token beginToken,
Token extendsKeyword, Token implementsKeyword, Token endToken) {
makeNodeList(interfacesCount, implementsKeyword, null, ","); // interfaces
@ -260,6 +286,7 @@ class ElementListener extends Listener {
}
}
@override
void endFunctionTypeAlias(Token typedefKeyword, Token endToken) {
popNode(); // TODO(karlklose): do not throw away typeVariables.
Identifier name = popNode();
@ -269,6 +296,7 @@ class ElementListener extends Listener {
rejectBuiltInIdentifier(name);
}
@override
void endNamedMixinApplication(
Token classKeyword, Token implementsKeyword, Token endToken) {
NodeList interfaces = (implementsKeyword != null) ? popNode() : null;
@ -292,16 +320,19 @@ class ElementListener extends Listener {
rejectBuiltInIdentifier(name);
}
@override
void endMixinApplication() {
NodeList mixins = popNode();
TypeAnnotation superclass = popNode();
pushNode(new MixinApplication(superclass, mixins));
}
@override
void handleVoidKeyword(Token token) {
pushNode(new TypeAnnotation(new Identifier(token), null));
}
@override
void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
bool hasParseError = currentMemberHasParseError;
memberErrors = memberErrors.tail;
@ -315,6 +346,7 @@ class ElementListener extends Listener {
pushElement(element);
}
@override
void endTopLevelFields(int count, Token beginToken, Token endToken) {
bool hasParseError = currentMemberHasParseError;
memberErrors = memberErrors.tail;
@ -351,20 +383,24 @@ class ElementListener extends Listener {
}
}
@override
void handleIdentifier(Token token) {
pushNode(new Identifier(token));
}
@override
void handleQualified(Token period) {
Identifier last = popNode();
Expression first = popNode();
pushNode(new Send(first, last));
}
@override
void handleNoType(Token token) {
pushNode(null);
}
@override
void endTypeVariable(Token token, Token extendsOrSuper) {
TypeAnnotation bound = popNode();
Identifier name = popNode();
@ -372,37 +408,45 @@ class ElementListener extends Listener {
rejectBuiltInIdentifier(name);
}
@override
void endTypeVariables(int count, Token beginToken, Token endToken) {
pushNode(makeNodeList(count, beginToken, endToken, ','));
}
@override
void handleNoTypeVariables(Token token) {
pushNode(null);
}
@override
void endTypeArguments(int count, Token beginToken, Token endToken) {
pushNode(makeNodeList(count, beginToken, endToken, ','));
}
@override
void handleNoTypeArguments(Token token) {
pushNode(null);
}
@override
void endType(Token beginToken, Token endToken) {
NodeList typeArguments = popNode();
Expression typeName = popNode();
pushNode(new TypeAnnotation(typeName, typeArguments));
}
@override
void handleParenthesizedExpression(BeginGroupToken token) {
Expression expression = popNode();
pushNode(new ParenthesizedExpression(expression, token));
}
@override
void handleModifier(Token token) {
pushNode(new Identifier(token));
}
@override
void handleModifiers(int count) {
if (count == 0) {
pushNode(Modifiers.EMPTY);
@ -412,29 +456,234 @@ class ElementListener extends Listener {
}
}
Token expected(String string, Token token) {
if (token is ErrorToken) {
reportErrorToken(token);
} else if (identical(';', string)) {
// 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) {
reportError(
token, MessageKind.MISSING_TOKEN_BEFORE_THIS, {'token': string});
} else {
reportError(
preceding, MessageKind.MISSING_TOKEN_AFTER_THIS, {'token': string});
}
return token;
@override
Token handleUnrecoverableError(Token token, ErrorKind kind, Map arguments) {
Token next = handleError(token, kind, arguments);
if (next == null &&
kind != ErrorKind.UnterminatedComment &&
kind != ErrorKind.UnterminatedString) {
throw new ParserError.fromTokens(token, token, kind, arguments);
} else {
reportFatalError(
token,
MessageTemplate.TEMPLATES[MessageKind.MISSING_TOKEN_BEFORE_THIS]
.message({'token': string}, true).toString());
return next;
}
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
@ -494,113 +743,13 @@ class ElementListener extends Listener {
return null;
}
Token expectedIdentifier(Token token) {
if (token is KeywordToken) {
reportError(token, MessageKind.EXPECTED_IDENTIFIER_NOT_RESERVED_WORD,
{'keyword': token.value});
} else if (token is ErrorToken) {
reportErrorToken(token);
return synthesizeIdentifier(token);
} 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;
/// Finds the preceding token via the begin token of the last AST node pushed
/// on the [nodes] stack.
Token synthesizeIdentifier(Token token) {
Token synthesizedToken = new StringToken.fromString(
Precedence.IDENTIFIER_INFO, '?', token.charOffset);
synthesizedToken.next = token.next;
return synthesizedToken;
}
void recoverableError(Spannable node, String message) {
@ -663,6 +812,7 @@ class ElementListener extends Listener {
return new NodeList(beginToken, poppedNodes, endToken, delimiter);
}
@override
void beginLiteralString(Token token) {
String source = token.value;
StringQuoting quoting = StringValidator.quotingFromString(source);
@ -672,12 +822,14 @@ class ElementListener extends Listener {
pushNode(new LiteralString(token, null));
}
@override
void handleStringPart(Token token) {
// Just push an unvalidated token now, and replace it when we know the
// end of the interpolation.
pushNode(new LiteralString(token, null));
}
@override
void endLiteralString(int count) {
StringQuoting quoting = popQuoting();
@ -711,6 +863,7 @@ class ElementListener extends Listener {
}
}
@override
void handleStringJuxtaposition(int stringCount) {
assert(stringCount != 0);
Expression accumulator = popNode();
@ -723,14 +876,17 @@ class ElementListener extends Listener {
pushNode(accumulator);
}
@override
void beginMember(Token token) {
memberErrors = memberErrors.prepend(false);
}
@override
void beginTopLevelMember(Token token) {
beginMember(token);
}
@override
void endMember() {
memberErrors = memberErrors.tail;
}
@ -740,11 +896,12 @@ class ElementListener extends Listener {
void reportFatalError(Spannable spannable, String message) {
reportError(spannable, MessageKind.GENERIC, {'text': message});
// 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 reportErrorHelper(Spannable spannable, MessageKind errorCode,
void reportError(Spannable spannable, MessageKind errorCode,
[Map arguments = const {}]) {
if (currentMemberHasParseError) return; // Error already reported.
if (suppressParseErrors) return;
@ -753,4 +910,9 @@ class ElementListener extends Listener {
}
reporter.reportErrorMessage(spannable, errorCode, arguments);
}
void reportErrorFromToken(Token token, MessageKind errorCode,
[Map arguments = const {}]) {
reportError(reporter.spanFromToken(token), errorCode, arguments);
}
}

View File

@ -8,7 +8,7 @@ import '../common.dart';
import '../elements/elements.dart' show Element, ElementKind, Elements;
import '../elements/modelx.dart'
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 'element_listener.dart' show ScannerOptions;
import 'node_listener.dart' show NodeListener;
@ -67,6 +67,7 @@ class MemberListener extends NodeListener {
}
}
@override
void endMethod(Token getOrSet, Token beginToken, Token endToken) {
super.endMethod(getOrSet, beginToken, endToken);
FunctionExpression method = popNode();
@ -76,7 +77,7 @@ class MemberListener extends NodeListener {
Element memberElement;
if (isConstructor) {
if (getOrSet != null) {
recoverableError(getOrSet, 'illegal modifier');
recoverableError(reporter.spanFromToken(getOrSet), 'illegal modifier');
}
memberElement = new PartialConstructorElement(name, beginToken, endToken,
ElementKind.GENERATIVE_CONSTRUCTOR, method.modifiers, enclosingClass);
@ -88,6 +89,7 @@ class MemberListener extends NodeListener {
addMember(memberElement);
}
@override
void endFactoryMethod(Token beginToken, Token endToken) {
super.endFactoryMethod(beginToken, endToken);
FunctionExpression method = popNode();
@ -112,6 +114,7 @@ class MemberListener extends NodeListener {
addMember(memberElement);
}
@override
void endFields(int count, Token beginToken, Token endToken) {
bool hasParseError = memberErrors.head;
super.endFields(count, beginToken, endToken);
@ -127,12 +130,14 @@ class MemberListener extends NodeListener {
enclosingClass, buildFieldElement, beginToken, endToken, hasParseError);
}
void endInitializer(Token assignmentOperator) {
@override
void endFieldInitializer(Token assignmentOperator) {
pushNode(null); // Super expects an expression, but
// ClassElementParser just skips expressions.
super.endInitializer(assignmentOperator);
super.endFieldInitializer(assignmentOperator);
}
@override
void endInitializers(int count, Token beginToken, Token endToken) {
pushNode(null);
}
@ -146,6 +151,7 @@ class MemberListener extends NodeListener {
enclosingClass.addMember(memberElement, reporter);
}
@override
void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
super.endMetadata(beginToken, periodBeforeName, endToken);
pushMetadata(new PartialMetadataAnnotation(beginToken, endToken));

View File

@ -6,27 +6,30 @@ library dart2js.parser.node_listener;
import '../common.dart';
import '../elements/elements.dart' show CompilationUnitElement;
import '../native/native.dart' as native;
import '../tokens/precedence_constants.dart' as Precedence show INDEX_INFO;
import '../tokens/token.dart' show ErrorToken, StringToken, Token;
import 'package:front_end/src/fasta/scanner/precedence.dart' as Precedence show
INDEX_INFO;
import 'package:front_end/src/fasta/scanner.dart' show
StringToken, Token;
import '../tree/tree.dart';
import '../util/util.dart' show Link;
import 'element_listener.dart' show ElementListener, ScannerOptions;
import 'partial_elements.dart' show PartialFunctionElement;
class NodeListener extends ElementListener {
NodeListener(ScannerOptions scannerOptions, DiagnosticReporter reporter,
CompilationUnitElement element)
: super(scannerOptions, reporter, element, null);
@override
void addLibraryTag(LibraryTag tag) {
pushNode(tag);
}
@override
void addPartOfTag(PartOf tag) {
pushNode(tag);
}
@override
void endLibraryName(Token libraryKeyword, Token semicolon) {
Expression name = popNode();
pushNode(new LibraryName(
@ -37,6 +40,7 @@ class NodeListener extends ElementListener {
null));
}
@override
void endImport(Token importKeyword, Token deferredKeyword, Token asKeyword,
Token semicolon) {
NodeList combinators = popNode();
@ -55,6 +59,7 @@ class NodeListener extends ElementListener {
isDeferred: deferredKeyword != null));
}
@override
void endExport(Token exportKeyword, Token semicolon) {
NodeList combinators = popNode();
NodeList conditionalUris = popNode();
@ -69,6 +74,7 @@ class NodeListener extends ElementListener {
null));
}
@override
void endPart(Token partKeyword, Token semicolon) {
StringNode uri = popLiteralString();
pushNode(new Part(
@ -79,6 +85,7 @@ class NodeListener extends ElementListener {
null));
}
@override
void endPartOf(Token partKeyword, Token semicolon) {
Expression name = popNode(); // name
pushNode(new PartOf(
@ -89,6 +96,7 @@ class NodeListener extends ElementListener {
null));
}
@override
void endClassDeclaration(int interfacesCount, Token beginToken,
Token extendsKeyword, Token implementsKeyword, Token endToken) {
NodeList body = popNode();
@ -102,6 +110,7 @@ class NodeListener extends ElementListener {
interfaces, beginToken, extendsKeyword, body, endToken));
}
@override
void endTopLevelDeclaration(Token token) {
// TODO(sigmund): consider moving metadata into each declaration
// element instead.
@ -111,10 +120,12 @@ class NodeListener extends ElementListener {
super.endTopLevelDeclaration(token);
}
@override
void endCompilationUnit(int count, Token token) {
pushNode(makeNodeList(count, null, null, '\n'));
}
@override
void endFunctionTypeAlias(Token typedefKeyword, Token endToken) {
NodeList formals = popNode();
NodeList typeParameters = popNode();
@ -124,6 +135,7 @@ class NodeListener extends ElementListener {
returnType, name, typeParameters, formals, typedefKeyword, endToken));
}
@override
void endNamedMixinApplication(
Token classKeyword, Token implementsKeyword, Token endToken) {
NodeList interfaces = (implementsKeyword != null) ? popNode() : null;
@ -135,16 +147,19 @@ class NodeListener extends ElementListener {
mixinApplication, interfaces, classKeyword, endToken));
}
@override
void endEnum(Token enumKeyword, Token endBrace, int count) {
NodeList names = makeNodeList(count, enumKeyword.next.next, endBrace, ",");
Identifier name = popNode();
pushNode(new Enum(enumKeyword, name, names));
}
@override
void endClassBody(int memberCount, Token beginToken, Token endToken) {
pushNode(makeNodeList(memberCount, beginToken, endToken, null));
}
@override
void endTopLevelFields(int count, Token beginToken, Token endToken) {
NodeList variables = makeNodeList(count, null, endToken, ",");
TypeAnnotation type = popNode();
@ -152,6 +167,7 @@ class NodeListener extends ElementListener {
pushNode(new VariableDefinitions(type, modifiers, variables));
}
@override
void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
Statement body = popNode();
AsyncModifier asyncModifier = popNode();
@ -164,6 +180,7 @@ class NodeListener extends ElementListener {
modifiers, null, getOrSet, asyncModifier));
}
@override
void endFormalParameter(Token thisKeyword) {
Expression name = popNode();
if (thisKeyword != null) {
@ -181,22 +198,27 @@ class NodeListener extends ElementListener {
metadata, type, modifiers, new NodeList.singleton(name)));
}
@override
void endFormalParameters(int count, Token beginToken, Token endToken) {
pushNode(makeNodeList(count, beginToken, endToken, ","));
}
@override
void handleNoFormalParameters(Token token) {
pushNode(null);
}
@override
void endArguments(int count, Token beginToken, Token endToken) {
pushNode(makeNodeList(count, beginToken, endToken, ","));
}
@override
void handleNoArguments(Token token) {
pushNode(null);
}
@override
void endConstructorReference(
Token start, Token periodBeforeName, Token endToken) {
Identifier name = null;
@ -228,74 +250,61 @@ class NodeListener extends ElementListener {
pushNode(constructor);
}
@override
void endRedirectingFactoryBody(Token beginToken, Token endToken) {
pushNode(new RedirectingFactoryBody(beginToken, endToken, popNode()));
}
@override
void endReturnStatement(
bool hasExpression, Token beginToken, Token endToken) {
Expression expression = hasExpression ? popNode() : null;
pushNode(new Return(beginToken, endToken, expression));
}
@override
void endYieldStatement(Token yieldToken, Token starToken, Token endToken) {
Expression expression = popNode();
pushNode(new Yield(yieldToken, starToken, expression, endToken));
}
@override
void endExpressionStatement(Token token) {
pushNode(new ExpressionStatement(popNode(), token));
}
void handleOnError(Token token, var errorInformation) {
reporter.internalError(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);
}
reporter.internalError(reporter.spanFromToken(token),
"'${token.value}': ${errorInformation}");
}
@override
void handleLiteralInt(Token token) {
pushNode(new LiteralInt(token, (t, e) => handleOnError(t, e)));
}
@override
void handleLiteralDouble(Token token) {
pushNode(new LiteralDouble(token, (t, e) => handleOnError(t, e)));
}
@override
void handleLiteralBool(Token token) {
pushNode(new LiteralBool(token, (t, e) => handleOnError(t, e)));
}
@override
void handleLiteralNull(Token token) {
pushNode(new LiteralNull(token));
}
@override
void endLiteralSymbol(Token hashToken, int identifierCount) {
NodeList identifiers = makeNodeList(identifierCount, null, null, '.');
pushNode(new LiteralSymbol(hashToken, identifiers));
}
@override
void handleBinaryExpression(Token token) {
Node argument = popNode();
Node receiver = popNode();
@ -307,7 +316,8 @@ class NodeListener extends ElementListener {
if (argumentSend == null) {
// TODO(ahe): The parser should diagnose this problem, not
// this listener.
reportFatalError(argument, 'Expected an identifier.');
reportFatalError(reporter.spanFromSpannable(argument),
"Expected an identifier.");
}
if (argumentSend.receiver != null) 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));
}
if (identical(tokenString, '===')) {
reporter.reportErrorMessage(token, MessageKind.UNSUPPORTED_EQ_EQ_EQ,
{'lhs': receiver, 'rhs': argument});
reporter.reportErrorMessage(reporter.spanFromToken(token),
MessageKind.UNSUPPORTED_EQ_EQ_EQ, {'lhs': receiver, 'rhs': argument});
}
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});
}
}
@override
void beginCascade(Token token) {
pushNode(new CascadeReceiver(popNode(), token));
}
@override
void endCascade() {
pushNode(new Cascade(popNode()));
}
@override
void handleAsOperator(Token operator, Token endToken) {
TypeAnnotation type = popNode();
Expression expression = popNode();
@ -343,6 +357,7 @@ class NodeListener extends ElementListener {
pushNode(new Send(expression, new Operator(operator), arguments));
}
@override
void handleAssignmentExpression(Token token) {
Node arg = popNode();
Node node = popNode();
@ -367,9 +382,10 @@ class NodeListener extends ElementListener {
void reportNotAssignable(Node node) {
// TODO(ahe): The parser should diagnose this problem, not this
// listener.
reportFatalError(node, 'Not assignable.');
reportFatalError(reporter.spanFromSpannable(node), "Not assignable.");
}
@override
void handleConditionalExpression(Token question, Token colon) {
Node elseExpression = popNode();
Node thenExpression = popNode();
@ -378,6 +394,7 @@ class NodeListener extends ElementListener {
condition, thenExpression, elseExpression, question, colon));
}
@override
void endSend(Token token) {
NodeList arguments = popNode();
NodeList typeArguments = popNode();
@ -386,6 +403,7 @@ class NodeListener extends ElementListener {
pushNode(new Send(null, selector, arguments, typeArguments));
}
@override
void endFunctionBody(int count, Token beginToken, Token endToken) {
if (count == 0 && beginToken == null) {
pushNode(new EmptyStatement(endToken));
@ -394,6 +412,7 @@ class NodeListener extends ElementListener {
}
}
@override
void handleAsyncModifier(Token asyncToken, Token starToken) {
if (asyncToken != null) {
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()));
}
@override
void handleNoFunctionBody(Token token) {
pushNode(new EmptyStatement(token));
}
@override
void endFunction(Token getOrSet, Token endToken) {
Statement body = popNode();
AsyncModifier asyncModifier = popNode();
@ -424,10 +446,12 @@ class NodeListener extends ElementListener {
modifiers, initializers, getOrSet, asyncModifier));
}
@override
void endFunctionDeclaration(Token endToken) {
pushNode(new FunctionDeclaration(popNode()));
}
@override
void endVariablesDeclaration(int count, Token endToken) {
// TODO(ahe): Pick one name for this concept, either
// VariablesDeclaration or VariableDefinitions.
@ -437,7 +461,8 @@ class NodeListener extends ElementListener {
pushNode(new VariableDefinitions(type, modifiers, variables));
}
void endInitializer(Token assignmentOperator) {
@override
void endVariableInitializer(Token assignmentOperator) {
Expression initializer = popNode();
NodeList arguments =
initializer == null ? null : new NodeList.singleton(initializer);
@ -446,6 +471,12 @@ class NodeListener extends ElementListener {
pushNode(new SendSet(null, name, op, arguments));
}
@override
void endFieldInitializer(Token assignmentOperator) {
endVariableInitializer(assignmentOperator);
}
@override
void endIfStatement(Token ifToken, Token elseToken) {
Statement elsePart = (elseToken == null) ? null : popNode();
Statement thenPart = popNode();
@ -453,6 +484,7 @@ class NodeListener extends ElementListener {
pushNode(new If(condition, thenPart, elsePart, ifToken, elseToken));
}
@override
void endForStatement(
int updateExpressionCount, Token beginToken, Token endToken) {
Statement body = popNode();
@ -462,10 +494,12 @@ class NodeListener extends ElementListener {
pushNode(new For(initializer, condition, updates, body, beginToken));
}
@override
void handleNoExpression(Token token) {
pushNode(null);
}
@override
void endDoWhileStatement(
Token doKeyword, Token whileKeyword, Token endToken) {
Expression condition = popNode();
@ -473,42 +507,51 @@ class NodeListener extends ElementListener {
pushNode(new DoWhile(body, condition, doKeyword, whileKeyword, endToken));
}
@override
void endWhileStatement(Token whileKeyword, Token endToken) {
Statement body = popNode();
Expression condition = popNode();
pushNode(new While(condition, body, whileKeyword));
}
@override
void endBlock(int count, Token beginToken, Token endToken) {
pushNode(new Block(makeNodeList(count, beginToken, endToken, null)));
}
@override
void endThrowExpression(Token throwToken, Token endToken) {
Expression expression = popNode();
pushNode(new Throw(expression, throwToken, endToken));
}
@override
void endAwaitExpression(Token awaitToken, Token endToken) {
Expression expression = popNode();
pushNode(new Await(awaitToken, expression));
}
@override
void endRethrowStatement(Token throwToken, Token endToken) {
pushNode(new Rethrow(throwToken, endToken));
if (identical(throwToken.stringValue, 'throw')) {
reporter.reportErrorMessage(
throwToken, MessageKind.MISSING_EXPRESSION_IN_THROW);
reporter.spanFromToken(throwToken),
MessageKind.MISSING_EXPRESSION_IN_THROW);
}
}
@override
void handleUnaryPrefixExpression(Token token) {
pushNode(new Send.prefix(popNode(), new Operator(token)));
}
@override
void handleSuperExpression(Token token) {
pushNode(new Identifier(token));
}
@override
void handleThisExpression(Token token) {
pushNode(new Identifier(token));
}
@ -536,22 +579,27 @@ class NodeListener extends ElementListener {
}
}
@override
void handleUnaryPostfixAssignmentExpression(Token token) {
handleUnaryAssignmentExpression(token, false);
}
@override
void handleUnaryPrefixAssignmentExpression(Token token) {
handleUnaryAssignmentExpression(token, true);
}
@override
void endInitializers(int count, Token beginToken, Token endToken) {
pushNode(makeNodeList(count, beginToken, null, ','));
}
@override
void handleNoInitializers() {
pushNode(null);
}
@override
void endMember() {
// TODO(sigmund): consider moving metadata into each declaration
// element instead.
@ -561,6 +609,7 @@ class NodeListener extends ElementListener {
super.endMember();
}
@override
void endFields(int count, Token beginToken, Token endToken) {
NodeList variables = makeNodeList(count, null, endToken, ",");
TypeAnnotation type = popNode();
@ -568,6 +617,7 @@ class NodeListener extends ElementListener {
pushNode(new VariableDefinitions(type, modifiers, variables));
}
@override
void endMethod(Token getOrSet, Token beginToken, Token endToken) {
Statement body = popNode();
AsyncModifier asyncModifier = popNode();
@ -581,6 +631,7 @@ class NodeListener extends ElementListener {
returnType, modifiers, initializers, getOrSet, asyncModifier));
}
@override
void handleLiteralMap(
int count, Token beginToken, Token constKeyword, Token endToken) {
NodeList entries = makeNodeList(count, beginToken, endToken, ',');
@ -588,18 +639,21 @@ class NodeListener extends ElementListener {
pushNode(new LiteralMap(typeArguments, entries, constKeyword));
}
@override
void endLiteralMapEntry(Token colon, Token endToken) {
Expression value = popNode();
Expression key = popNode();
pushNode(new LiteralMapEntry(key, colon, value));
}
@override
void handleLiteralList(
int count, Token beginToken, Token constKeyword, Token endToken) {
NodeList elements = makeNodeList(count, beginToken, endToken, ',');
pushNode(new LiteralList(popNode(), elements, constKeyword));
}
@override
void handleIndexedExpression(
Token openSquareBracket, Token closeSquareBracket) {
NodeList arguments =
@ -611,38 +665,45 @@ class NodeListener extends ElementListener {
pushNode(new Send(receiver, selector, arguments));
}
@override
void handleNewExpression(Token token) {
NodeList arguments = popNode();
Node name = popNode();
pushNode(new NewExpression(token, new Send(null, name, arguments)));
}
@override
void handleConstExpression(Token token) {
// [token] carries the 'const' information.
handleNewExpression(token);
}
@override
void handleOperator(Token token) {
pushNode(new Operator(token));
}
@override
void handleOperatorName(Token operatorKeyword, Token token) {
Operator op = new Operator(token);
pushNode(new Send(new Identifier(operatorKeyword), op, null));
}
@override
void handleNamedArgument(Token colon) {
Expression expression = popNode();
Identifier name = popNode();
pushNode(new NamedArgument(name, colon, expression));
}
@override
void endOptionalFormalParameters(
int count, Token beginToken, Token endToken) {
pushNode(makeNodeList(count, beginToken, endToken, ','));
}
void handleFunctionTypedFormalParameter(Token endToken) {
@override
void endFunctionTypedFormalParameter(Token endToken) {
NodeList formals = popNode();
NodeList typeVariables = popNode();
Identifier name = popNode();
@ -652,6 +713,7 @@ class NodeListener extends ElementListener {
returnType, Modifiers.EMPTY, null, null, null));
}
@override
void handleValuedFormalParameter(Token equals, Token token) {
Expression defaultValue = popNode();
Expression parameterName = popNode();
@ -659,6 +721,7 @@ class NodeListener extends ElementListener {
new NodeList.singleton(defaultValue)));
}
@override
void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
Block finallyBlock = null;
if (finallyKeyword != null) {
@ -670,10 +733,12 @@ class NodeListener extends ElementListener {
tryBlock, catchBlocks, finallyBlock, tryKeyword, finallyKeyword));
}
@override
void handleCaseMatch(Token caseKeyword, Token colon) {
pushNode(new CaseMatch(caseKeyword, popNode(), colon));
}
@override
void handleCatchBlock(Token onKeyword, Token catchKeyword) {
Block block = popNode();
NodeList formals = catchKeyword != null ? popNode() : null;
@ -681,12 +746,14 @@ class NodeListener extends ElementListener {
pushNode(new CatchBlock(type, formals, block, onKeyword, catchKeyword));
}
@override
void endSwitchStatement(Token switchKeyword, Token endToken) {
NodeList cases = popNode();
ParenthesizedExpression expression = popNode();
pushNode(new SwitchStatement(expression, cases, switchKeyword));
}
@override
void endSwitchBlock(int caseCount, Token beginToken, Token endToken) {
Link<Node> caseNodes = const Link<Node>();
while (caseCount > 0) {
@ -697,6 +764,7 @@ class NodeListener extends ElementListener {
pushNode(new NodeList(beginToken, caseNodes, endToken, null));
}
@override
void handleSwitchCase(int labelCount, int caseCount, Token defaultKeyword,
int statementCount, Token firstToken, Token endToken) {
NodeList statements = makeNodeList(statementCount, null, null, null);
@ -706,6 +774,7 @@ class NodeListener extends ElementListener {
new SwitchCase(labelsAndCases, defaultKeyword, statements, firstToken));
}
@override
void handleBreakStatement(
bool hasTarget, Token breakKeyword, Token endToken) {
Identifier target = null;
@ -715,6 +784,7 @@ class NodeListener extends ElementListener {
pushNode(new BreakStatement(target, breakKeyword, endToken));
}
@override
void handleContinueStatement(
bool hasTarget, Token continueKeyword, Token endToken) {
Identifier target = null;
@ -724,10 +794,12 @@ class NodeListener extends ElementListener {
pushNode(new ContinueStatement(target, continueKeyword, endToken));
}
@override
void handleEmptyStatement(Token token) {
pushNode(new EmptyStatement(token));
}
@override
void endFactoryMethod(Token beginToken, Token endToken) {
super.endFactoryMethod(beginToken, endToken);
Statement body = popNode();
@ -758,6 +830,7 @@ class NodeListener extends ElementListener {
name, null, formals, body, null, modifiers, null, null, asyncModifier));
}
@override
void endForIn(
Token awaitToken, Token forToken, Token inKeyword, Token endToken) {
Statement body = popNode();
@ -772,6 +845,7 @@ class NodeListener extends ElementListener {
}
}
@override
void endMetadataStar(int count, bool forParameter) {
if (0 == count) {
pushNode(null);
@ -780,6 +854,7 @@ class NodeListener extends ElementListener {
}
}
@override
void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
NodeList arguments = popNode();
if (arguments == null) {
@ -816,6 +891,7 @@ class NodeListener extends ElementListener {
}
}
@override
void handleAssertStatement(
Token assertKeyword, Token commaToken, Token semicolonToken) {
Node message;
@ -827,6 +903,7 @@ class NodeListener extends ElementListener {
pushNode(new Assert(assertKeyword, condition, message, semicolonToken));
}
@override
void endUnnamedFunction(Token token) {
Statement body = popNode();
AsyncModifier asyncModifier = popNode();
@ -836,6 +913,7 @@ class NodeListener extends ElementListener {
Modifiers.EMPTY, null, null, asyncModifier));
}
@override
void handleIsOperator(Token operator, Token not, Token endToken) {
TypeAnnotation type = popNode();
Expression expression = popNode();
@ -850,21 +928,32 @@ class NodeListener extends ElementListener {
pushNode(new Send(expression, new Operator(operator), arguments));
}
@override
void handleLabel(Token colon) {
Identifier name = popNode();
pushNode(new Label(name, colon));
}
@override
void endLabeledStatement(int labelCount) {
Statement statement = popNode();
NodeList labels = makeNodeList(labelCount, null, null, null);
pushNode(new LabeledStatement(labels, statement));
}
@override
void log(message) {
reporter.log(message);
}
@override
void handleInvalidFunctionBody(Token token) {
if (!lastErrorWasNativeFunctionBody) {
pushNode(null);
}
lastErrorWasNativeFunctionBody = false;
}
void internalError({Token token, Node node}) {
// TODO(ahe): This should call reporter.internalError.
Spannable spannable = (token == null) ? node : token;

View File

@ -8,12 +8,11 @@ import '../common.dart';
import '../common/tasks.dart' show CompilerTask;
import '../compiler.dart' show Compiler;
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 '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 'parser.dart' show Parser;
class ParserTask extends CompilerTask {
final Compiler compiler;
@ -36,7 +35,8 @@ class ParserTask extends CompilerTask {
try {
parser.parseUnit(token);
} on ParserError catch (_) {
assert(invariant(token, compiler.compilationFailed));
assert(invariant(compiler.reporter.spanFromToken(token),
compiler.compilationFailed));
return listener.makeNodeList(0, null, null, '\n');
}
Node result = listener.popNode();

View File

@ -31,14 +31,20 @@ import '../elements/modelx.dart'
TypedefElementX,
VariableList;
import '../elements/visitor.dart' show ElementVisitor;
import '../tokens/token.dart' show Token;
import '../tokens/token_constants.dart' as Tokens show EOF_TOKEN;
import 'package:front_end/src/fasta/scanner.dart' show Token;
import 'package:front_end/src/fasta/scanner.dart' as Tokens show EOF_TOKEN;
import '../tree/tree.dart';
import 'class_element_parser.dart' show ClassElementParser;
import 'listener.dart' show ParserError;
import 'package:front_end/src/fasta/parser.dart'
show ClassMemberParser, Listener, Parser, ParserError;
import 'member_listener.dart' show MemberListener;
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 {
Token beginToken;
@ -379,8 +385,9 @@ class PartialClassElement extends ClassElementX with PartialElement {
Token token = parser.parseTopLevelDeclaration(beginToken);
assert(identical(token, endToken.next));
cachedNode = listener.popNode();
assert(invariant(beginToken, listener.nodes.isEmpty,
message: "Non-empty listener stack: ${listener.nodes}"));
assert(invariant(reporter.spanFromToken(beginToken),
listener.nodes.isEmpty,
message: "Non-empty listener stack: ${listener.nodes}"));
} on ParserError {
// TODO(ahe): Often, a ParserError is thrown while parsing the class
// 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));
} on ParserError catch (e) {
partial.hasParseError = true;
return new ErrorNode(element.position, e.reason);
return new ErrorNode(element.position, e.kind, e.arguments);
}
Node node = listener.popNode();
assert(listener.nodes.isEmpty);

View File

@ -134,14 +134,14 @@ import 'id_generator.dart';
import 'js_backend/js_backend.dart' show JavaScriptBackend;
import 'library_loader.dart' show LibraryLoader;
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/parser.dart' show Parser;
import 'parser/partial_elements.dart' show PartialClassElement;
import 'parser/partial_parser.dart' show PartialParser;
import 'scanner/scanner.dart' show Scanner;
import 'parser/partial_elements.dart'
show ClassElementParser, PartialClassElement;
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 {
final String name = "Patching Parser";
@ -178,7 +178,7 @@ class PatchParserTask extends CompilerTask {
measure(() {
// TODO(johnniwinther): Test that parts and exports are handled correctly.
Script script = compilationUnit.script;
Token tokens = new Scanner(script.file).tokenize();
Token tokens = compiler.scanner.scanFile(script.file);
Listener patchListener = new PatchElementListener(
compiler, compilationUnit, compiler.idGenerator);
try {
@ -199,7 +199,7 @@ class PatchParserTask extends CompilerTask {
measure(() => reporter.withCurrentElement(cls, () {
MemberListener listener = new PatchMemberListener(compiler, cls);
Parser parser = new PatchClassElementParser(listener);
Parser parser = new ClassElementParser(listener);
try {
Token token = parser.parseTopLevelDeclaration(cls.beginToken);
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.
*/

View File

@ -9,10 +9,9 @@ import '../core_types.dart' show CommonElements;
import '../elements/resolution_types.dart';
import '../elements/elements.dart';
import '../elements/modelx.dart';
import '../tokens/keyword.dart' show Keyword;
import '../tokens/precedence.dart';
import '../tokens/precedence_constants.dart' as Precedence;
import '../tokens/token.dart';
import 'package:front_end/src/fasta/scanner.dart';
import 'package:front_end/src/fasta/scanner/precedence.dart';
import 'package:front_end/src/fasta/scanner/precedence.dart' as Precedence;
import '../tree/tree.dart';
import '../util/util.dart';

View File

@ -27,7 +27,7 @@ import '../elements/modelx.dart'
VariableElementX,
VariableList;
import '../options.dart';
import '../tokens/token.dart' show isUserDefinableOperator;
import 'package:front_end/src/fasta/scanner.dart' show isUserDefinableOperator;
import '../tree/tree.dart';
import '../universe/call_structure.dart' show CallStructure;
import '../universe/feature.dart' show Feature;
@ -2841,7 +2841,7 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
} else if (member.isFunction) {
// `a = b`, `a++` or `a += b` where `a` is a function.
MethodElement method = member;
ErroneousElement error = reportAndCreateErroneousElement(
reportAndCreateErroneousElement(
node.selector, name.text, MessageKind.ASSIGNING_METHOD, const {});
registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
if (node.isComplex) {
@ -2860,7 +2860,7 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
registry.registerStaticUse(new StaticUse.staticGet(member));
}
if (member.isFinal || member.isConst) {
ErroneousElement error = reportAndCreateErroneousElement(
reportAndCreateErroneousElement(
node.selector,
name.text,
MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER,
@ -3613,7 +3613,8 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
ResolutionResult visitYield(Yield node) {
if (!resolution.target.supportsAsyncAwait) {
reporter.reportErrorMessage(
node.yieldToken, MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
reporter.spanFromToken(node.yieldToken),
MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
} else {
if (!currentAsyncMarker.isYielding) {
reporter.reportErrorMessage(node, MessageKind.INVALID_YIELD);
@ -3754,7 +3755,8 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
ResolutionResult visitAwait(Await node) {
if (!resolution.target.supportsAsyncAwait) {
reporter.reportErrorMessage(
node.awaitToken, MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
reporter.spanFromToken(node.awaitToken),
MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
} else {
if (!currentAsyncMarker.isAsync) {
reporter.reportErrorMessage(node, MessageKind.INVALID_AWAIT);
@ -4017,7 +4019,8 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
if (resolution.commonElements.isSymbolConstructor(constructor) &&
!resolution.mirrorUsageAnalyzerTask
.hasMirrorUsage(enclosingElement)) {
reporter.reportHintMessage(node.newToken, MessageKind.NON_CONST_BLOAT,
reporter.reportHintMessage(reporter.spanFromToken(node.newToken),
MessageKind.NON_CONST_BLOAT,
{'name': commonElements.symbolClass.name});
}
registry.registerNewStructure(
@ -4289,11 +4292,13 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
ResolutionResult visitAsyncForIn(AsyncForIn node) {
if (!resolution.target.supportsAsyncAwait) {
reporter.reportErrorMessage(
node.awaitToken, MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
reporter.spanFromToken(node.awaitToken),
MessageKind.ASYNC_AWAIT_NOT_SUPPORTED);
} else {
if (!currentAsyncMarker.isAsync) {
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.registerDynamicUse(new DynamicUse(Selectors.current, null));
@ -4693,7 +4698,8 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
visit(node.tryBlock);
if (node.catchBlocks.isEmpty && node.finallyBlock == null) {
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.finallyBlock);

View File

@ -37,7 +37,7 @@ import '../elements/modelx.dart'
TypedefElementX;
import '../enqueue.dart';
import '../options.dart';
import '../tokens/token.dart'
import 'package:front_end/src/fasta/scanner.dart'
show
isBinaryOperator,
isMinusOperator,
@ -47,7 +47,7 @@ import '../tokens/token.dart'
import '../tree/tree.dart';
import '../universe/call_structure.dart' show CallStructure;
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 '../util/util.dart' show Link, Setlet;
import '../world.dart';
@ -518,7 +518,6 @@ class ResolverTask extends CompilerTask {
ResolvedAst resolvedAst = factory.resolvedAst;
assert(invariant(node, resolvedAst != null,
message: 'No ResolvedAst for $factory.'));
FunctionExpression functionNode = resolvedAst.node;
RedirectingFactoryBody redirectionNode = resolvedAst.body;
ResolutionDartType factoryType =
resolvedAst.elements.getType(redirectionNode);

View File

@ -18,7 +18,6 @@ import '../elements/modelx.dart'
LocalParameterElementX,
TypeVariableElementX;
import '../tree/tree.dart';
import '../universe/use.dart' show TypeUse;
import '../util/util.dart' show Link, LinkBuilder;
import 'members.dart' show ResolverVisitor;
import 'registry.dart' show ResolutionRegistry;

View File

@ -8,7 +8,6 @@ import '../common.dart';
import '../common/resolution.dart';
import '../elements/modelx.dart' show LocalVariableElementX, VariableList;
import '../tree/tree.dart';
import '../universe/use.dart' show TypeUse;
import '../universe/feature.dart';
import '../util/util.dart' show Link;
import 'members.dart' show ResolverVisitor;

View File

@ -9,11 +9,12 @@ import '../diagnostics/diagnostic_listener.dart' show DiagnosticReporter;
import '../elements/elements.dart' show CompilationUnitElement, LibraryElement;
import '../parser/diet_parser_task.dart' show DietParserTask;
import '../script.dart' show Script;
import '../tokens/token.dart' show Token;
import '../tokens/token_constants.dart' as Tokens show COMMENT_TOKEN, EOF_TOKEN;
import 'package:front_end/src/fasta/scanner.dart'
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 'scanner.dart' show Scanner;
import 'string_scanner.dart' show StringScanner;
import '../io/source_file.dart';
class ScannerTask extends CompilerTask {
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) {
Script script = compilationUnit.script;
Token tokens =
new Scanner(script.file, includeComments: _preserveComments).tokenize();
Token tokens = scanFile(script.file, includeComments: _preserveComments);
if (_preserveComments) {
tokens = processAndStripComments(tokens);
}
@ -71,8 +79,7 @@ class ScannerTask extends CompilerTask {
*/
Token tokenize(String source) {
return measure(() {
return new StringScanner.fromString(source, includeComments: false)
.tokenize();
return new StringScanner(source, includeComments: false).tokenize();
});
}

View File

@ -21,7 +21,7 @@ import '../native/native.dart' show NativeBehavior;
import '../resolution/access_semantics.dart';
import '../resolution/send_structure.dart';
import '../resolution/tree_elements.dart';
import '../tokens/token.dart';
import 'package:front_end/src/fasta/scanner.dart';
import '../tree/nodes.dart';
import '../universe/selector.dart';
import '../universe/feature.dart';
@ -1437,7 +1437,10 @@ class NodeEquivalenceVisitor implements Visitor1<bool, Node> {
(Token t1, Token t2) {
if (t1 == t2) return true;
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);
});
}

View File

@ -25,7 +25,7 @@ import '../resolution/scope.dart' show Scope;
import '../resolution/tree_elements.dart' show TreeElements;
import '../script.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 '../util/util.dart' show Link, LinkBuilder;
import 'keys.dart';
@ -1572,7 +1572,6 @@ abstract class MemberElementMixin
@override
bool get isInjected => _decoder.getBool(Key.IS_INJECTED);
@override
void forgetElement() {
nestedClosures.clear();
}

View File

@ -11,16 +11,14 @@ import '../elements/resolution_types.dart';
import '../diagnostics/diagnostic_listener.dart';
import '../elements/elements.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/parser.dart' show Parser;
import '../resolution/enum_creator.dart';
import '../resolution/send_structure.dart';
import '../resolution/tree_elements.dart';
import '../tokens/token.dart';
import 'package:front_end/src/fasta/scanner.dart';
import '../tree/tree.dart';
import '../universe/selector.dart';
import '../util/util.dart';
import 'keys.dart';
import 'modelz.dart';
import 'serialization.dart';
@ -374,7 +372,6 @@ class ResolvedAstDeserializer {
ParsingContext parsing,
Token getBeginToken(Uri uri, int charOffset),
DeserializerPlugin nativeDataDeserializer) {
CompilationUnitElement compilationUnit = element.compilationUnit;
DiagnosticReporter reporter = parsing.reporter;
Uri uri = objectDecoder.getUri(Key.URI);
@ -395,7 +392,6 @@ class ResolvedAstDeserializer {
Node doParse(parse(Parser parser)) {
return parsing.measure(() {
return reporter.withCurrentElement(element, () {
CompilationUnitElement unit = element.compilationUnit;
NodeListener listener = new NodeListener(
parsing.getScannerOptionsFor(element), reporter, null);
listener.memberErrors = listener.memberErrors.prepend(false);
@ -424,7 +420,6 @@ class ResolvedAstDeserializer {
case AstKind.ENUM_VALUES_FIELD:
EnumClassElement enumClass = element.enclosingClass;
AstBuilder builder = new AstBuilder(element.sourcePosition.begin);
List<FieldElement> enumValues = <FieldElement>[];
List<Node> valueReferences = <Node>[];
for (EnumConstantElement enumConstant in enumClass.enumValues) {
AstBuilder valueBuilder =
@ -532,7 +527,6 @@ class ResolvedAstDeserializer {
Node root = computeNode(kind);
TreeElementMapping elements = new TreeElementMapping(element);
AstIndexComputer indexComputer = new AstIndexComputer();
Map<Node, int> nodeIndices = indexComputer.nodeIndices;
List<Node> nodeList = indexComputer.nodeList;
root.accept(indexComputer);
elements.containsTryStatement = objectDecoder.getBool(Key.CONTAINS_TRY);

View File

@ -659,7 +659,6 @@ bool includeAllElements(Element element) => true;
class Serializer {
List<SerializerPlugin> plugins = <SerializerPlugin>[];
Map<Uri, dynamic> _dependencyMap = <Uri, dynamic>{};
Map<Element, DataObject> _elementMap = <Element, DataObject>{};
Map<ConstantExpression, DataObject> _constantMap =
<ConstantExpression, DataObject>{};

View File

@ -52,9 +52,6 @@ Selector deserializeSelector(ObjectDecoder decoder) {
int argumentCount = decoder.getInt(Key.ARGUMENTS);
List<String> namedArguments =
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),
new CallStructure(argumentCount, namedArguments));
}

View File

@ -11,10 +11,9 @@ import '../common/resolution.dart';
import '../compiler.dart';
import '../elements/resolution_types.dart';
import '../elements/elements.dart';
import '../scanner/scanner.dart';
import '../script.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/use.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 ')}');
}
if (script.isSynthesized) return null;
return new Scanner(script.file).tokenize();
return parsingContext.scanner.scanFile(script.file);
});
if (beginToken == null) return null;
return ResolvedAstDeserializer.findTokenInStream(beginToken, offset);

View File

@ -10,7 +10,6 @@ import '../common/resolution.dart' show ResolutionImpact, ResolutionWorkItem;
import '../common/tasks.dart' show CompilerTask;
import '../compiler.dart' show Compiler;
import '../elements/elements.dart';
import '../enqueue.dart' show ResolutionEnqueuer;
import '../universe/world_impact.dart' show WorldImpact;
import 'json_serializer.dart';
import 'serialization.dart';

View File

@ -1140,7 +1140,6 @@ class SsaBuilder extends ast.Visitor
if (compiler.elementHasCompileTimeError(member)) return;
reporter.withCurrentElement(member, () {
ResolvedAst fieldResolvedAst = member.resolvedAst;
ast.Node node = fieldResolvedAst.node;
ast.Expression initializer = fieldResolvedAst.body;
if (initializer == null) {
// Unassigned fields of native classes are not initialized to

View File

@ -26,7 +26,7 @@ import '../kernel/kernel.dart';
import '../native/native.dart' as native;
import '../resolution/tree_elements.dart';
import '../tree/dartstring.dart';
import '../tree/nodes.dart' show Node, BreakStatement;
import '../tree/nodes.dart' show Node;
import '../types/masks.dart';
import '../universe/call_structure.dart' show CallStructure;
import '../universe/selector.dart';
@ -663,7 +663,6 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
returnStatement.expression.accept(this);
value = pop();
if (_targetFunction.asyncMarker == ir.AsyncMarker.Async) {
var returnType = astAdapter.getDartType(_targetFunction.returnType);
if (compiler.options.enableTypeAssertions &&
!isValidAsyncReturnType(_targetFunction.returnType)) {
generateTypeError(
@ -1309,12 +1308,12 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder {
int switchIndex = 1;
bool hasDefault = false;
for (ir.SwitchCase switchCase in switchStatement.cases) {
if (_isDefaultCase(switchCase)) {
hasDefault = true;
}
if (SwitchContinueAnalysis.containsContinue(switchCase.body)) {
hasContinue = true;
}
if (switchCase.isDefault) {
hasDefault = true;
}
caseIndex[switchCase] = switchIndex;
switchIndex++;
}

View File

@ -2,11 +2,10 @@
// 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 '../common.dart';
import '../common/codegen.dart' show CodegenRegistry;
import '../compiler.dart';
import '../elements/elements.dart';
import '../elements/entities.dart';
import '../elements/entities.dart' show Entity, Local;
import '../elements/resolution_types.dart';
import '../js_backend/js_backend.dart';
import '../resolution/tree_elements.dart';

View File

@ -6,7 +6,6 @@ import '../common.dart';
import '../elements/elements.dart';
import '../tree/tree.dart' as ast;
import 'builder.dart';
import 'graph_builder.dart';
import 'locals_handler.dart';
import 'nodes.dart';

View File

@ -6,7 +6,6 @@ import 'package:js_runtime/shared/embedded_names.dart';
import 'package:kernel/ast.dart' as ir;
import '../common.dart';
import '../common/names.dart';
import '../compiler.dart';
import '../constants/expressions.dart';
import '../constants/values.dart';
@ -17,7 +16,6 @@ import '../elements/entities.dart';
import '../elements/modelx.dart';
import '../elements/types.dart';
import '../js/js.dart' as js;
import '../js_backend/backend_helpers.dart';
import '../js_backend/js_backend.dart';
import '../kernel/element_adapter.dart';
import '../kernel/kernel.dart';
@ -766,7 +764,7 @@ class Constantifier extends ir.ExpressionVisitor<ConstantExpression> {
ConstantExpression visitStaticGet(ir.StaticGet node) {
Element element = astAdapter.getMember(node.target);
if (element.isField) {
return new VariableConstantExpression(element);
return new VariableConstantExpression(element as VariableElement);
}
astAdapter.reporter.internalError(
CURRENT_ELEMENT_SPANNABLE, "Unexpected constant target: $element.");

View File

@ -487,7 +487,6 @@ class LocalsHandler {
Map<Local, HInstruction> savedDirectLocals =
new Map<Local, HInstruction>.from(directLocals);
JavaScriptBackend backend = _compiler.backend;
// Create phis for all elements in the definitions environment.
savedDirectLocals.forEach((Local local, HInstruction instruction) {
if (isAccessedDirectly(local)) {

View File

@ -4,7 +4,6 @@
import '../compiler.dart';
import '../io/source_information.dart';
import '../js_backend/js_backend.dart';
import '../tree/tree.dart' as ast;
import 'graph_builder.dart';

View File

@ -9,10 +9,10 @@ library stringvalidator;
import 'dart:collection';
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/nodes.dart' show StringQuoting;
import 'util/characters.dart';
import 'package:front_end/src/fasta/scanner/characters.dart';
class StringValidator {
final DiagnosticReporter reporter;
@ -100,7 +100,8 @@ class StringValidator {
void stringParseError(String message, Token token, int offset) {
reporter.reportErrorMessage(
token, MessageKind.GENERIC, {'text': "$message @ $offset"});
reporter.spanFromToken(token), MessageKind.GENERIC,
{'text': "$message @ $offset"});
}
/**

View File

@ -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);
}

View File

@ -4,7 +4,7 @@
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

View File

@ -4,7 +4,7 @@
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

View File

@ -8,14 +8,17 @@ import '../common.dart';
import '../elements/elements.dart' show MetadataAnnotation;
import '../resolution/secret_tree_element.dart'
show NullTreeElementMixin, StoredTreeElementMixin;
import '../tokens/precedence_constants.dart' as Precedence show FUNCTION_INFO;
import '../tokens/token.dart' show BeginGroupToken, Token;
import '../tokens/token_constants.dart' as Tokens show PLUS_TOKEN;
import '../util/characters.dart';
import 'package:front_end/src/fasta/scanner/precedence.dart' as Precedence
show FUNCTION_INFO;
import 'package:front_end/src/fasta/scanner.dart' show BeginGroupToken, Token;
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 'dartstring.dart';
import 'prettyprint.dart';
import 'unparser.dart';
import 'package:front_end/src/fasta/parser.dart' show ErrorKind;
abstract class Visitor<R> {
const Visitor();
@ -478,7 +481,7 @@ class ClassNode extends Node {
if (token == null) {
token = name.getEndToken();
}
assert(invariant(beginToken, token != null));
assert(token != null);
return token;
}
@ -3086,17 +3089,19 @@ class IsInterpolationVisitor extends Visitor<bool> {
class ErrorNode extends Node
implements FunctionExpression, VariableDefinitions, Typedef {
final Token token;
final String reason;
final ErrorKind kind;
final Map arguments;
final Identifier name;
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);
NodeList definitions =
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;

View File

@ -2,7 +2,7 @@
// 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 '../tokens/token.dart' show Token;
import 'package:front_end/src/fasta/scanner.dart' show Token;
import '../util/util.dart';
import 'nodes.dart';

View File

@ -2,8 +2,8 @@
// 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 '../tokens/token.dart' show Token;
import '../tokens/token_constants.dart' as Tokens
import 'package:front_end/src/fasta/scanner.dart' show Token;
import 'package:front_end/src/fasta/scanner/token_constants.dart' as Tokens
show IDENTIFIER_TOKEN, KEYWORD_TOKEN, PLUS_TOKEN;
import '../util/util.dart';
import 'nodes.dart';

View File

@ -5,11 +5,8 @@
library types.constants;
import '../common.dart';
import '../constants/constant_system.dart' show ConstantSystem;
import '../compiler.dart' show Compiler;
import '../constants/values.dart';
import '../js_backend/js_backend.dart'
show JavaScriptBackend, SyntheticConstantKind;
import '../js_backend/js_backend.dart' show SyntheticConstantKind;
import '../world.dart' show ClosedWorld;
import 'masks.dart';

View File

@ -4,7 +4,6 @@
library dart2js.call_structure;
import '../common.dart';
import '../common/names.dart' show Names;
import '../elements/types.dart' show FunctionType;
import '../util/util.dart';

View File

@ -6,7 +6,6 @@ library dart2js.world.class_set;
import 'dart:collection' show IterableBase;
import '../common.dart';
import '../elements/elements.dart' show ClassElement;
import '../util/enumset.dart' show EnumSet;
import '../util/util.dart' show Link;

View File

@ -22,7 +22,6 @@ import '../universe/function_set.dart' show FunctionSetBuilder;
import '../util/enumset.dart';
import '../util/util.dart';
import '../world.dart' show World, ClosedWorld, ClosedWorldImpl, OpenWorld;
import 'call_structure.dart' show CallStructure;
import 'selector.dart' show Selector;
import 'use.dart' show DynamicUse, DynamicUseKind, StaticUse, StaticUseKind;

View File

@ -4,7 +4,6 @@
library dart2js.universe.world_impact;
import '../elements/elements.dart' show Element;
import '../util/util.dart' show Setlet;
import 'use.dart' show DynamicUse, StaticUse, TypeUse;

View File

@ -4,15 +4,15 @@
library dart2js.util;
import 'characters.dart';
import 'util_implementation.dart';
import 'package:front_end/src/fasta/scanner/characters.dart';
import 'package:front_end/src/fasta/util/link.dart';
export 'emptyset.dart';
export 'maplet.dart';
export 'setlet.dart';
export 'package:front_end/src/fasta/util/link.dart';
part 'indentation.dart';
part 'link.dart';
/// Helper functions for creating hash codes.
class Hashing {

View 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;
}

View 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);

View File

@ -2,174 +2,32 @@
// 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.partial;
library fasta.parser.class_member_parser;
import '../common.dart';
import '../tokens/token.dart' show BeginGroupToken, ErrorToken, 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;
import 'package:front_end/src/fasta/scanner/token.dart' show
Token;
class PartialParser extends Parser {
PartialParser(Listener listener) : super(listener);
import 'listener.dart' show
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 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;
}
// 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).
Token parseArgumentsOpt(Token token) => skipArgumentsOpt(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;
return skipFunctionBody(token, isExpression, allowAbstract);
}
}

View 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

View 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

View File

@ -2,174 +2,22 @@
// 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.partial;
library fasta.parser.top_level_parser;
import '../common.dart';
import '../tokens/token.dart' show BeginGroupToken, ErrorToken, 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;
import 'package:front_end/src/fasta/scanner/token.dart' show
Token;
class PartialParser extends Parser {
PartialParser(Listener listener) : super(listener);
import 'listener.dart' show
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 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;
}
}

View 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);
}

View File

@ -2,33 +2,32 @@
// 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.scanner;
library fasta.scanner.abstract_scanner;
import '../io/source_file.dart' show SourceFile, Utf8BytesSourceFile;
import '../tokens/keyword.dart' show Keyword, KeywordState;
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;
import '../scanner.dart' show
Scanner;
abstract class Scanner {
Token tokenize();
import 'keyword.dart' show
KeywordState,
Keyword;
factory Scanner(SourceFile file, {bool includeComments: false}) {
if (file is Utf8BytesSourceFile) {
return new Utf8BytesScanner(file, includeComments: includeComments);
} else {
return new StringScanner(file, includeComments: includeComments);
}
}
}
import 'precedence.dart';
import 'token.dart' show
BadInputToken,
BeginGroupToken,
ErrorToken,
KeywordToken,
SymbolToken,
Token,
UnmatchedToken,
UnterminatedToken;
import 'token_constants.dart';
import 'characters.dart';
abstract class AbstractScanner implements Scanner {
// TODO(ahe): Move this class to implementation.
final bool includeComments;
/**
@ -54,16 +53,9 @@ abstract class AbstractScanner implements Scanner {
*/
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];
AbstractScanner(this.file, this.includeComments) {
AbstractScanner(this.includeComments) {
this.tail = this.tokens;
}
@ -214,12 +206,8 @@ abstract class AbstractScanner implements Scanner {
}
}
if (file != null) {
file.length = stringOffset;
// One additional line start at the end, see [SourceFile.lineStarts].
lineStarts.add(stringOffset + 1);
file.lineStarts = lineStarts;
}
// Always pretend that there's a line at the end of the file.
lineStarts.add(stringOffset + 1);
return firstToken();
}
@ -635,7 +623,6 @@ abstract class AbstractScanner implements Scanner {
return next;
}
}
return null;
}
int tokenizeHexOrNumber(int next) {
@ -665,7 +652,6 @@ abstract class AbstractScanner implements Scanner {
return next;
}
}
return null;
}
int tokenizeDotsOrNumber(int next) {
@ -761,7 +747,6 @@ abstract class AbstractScanner implements Scanner {
return next;
}
}
return null;
}
int tokenizeMultiLineComment(int next, int start) {

View File

@ -2,24 +2,43 @@
// 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.scanner.array_based;
library fasta.scanner.array_based_scanner;
import '../io/source_file.dart' show SourceFile;
import '../tokens/keyword.dart' show Keyword;
import '../tokens/precedence.dart' show PrecedenceInfo;
import '../tokens/precedence_constants.dart' as Precedence
show COMMENT_INFO, EOF_INFO;
import '../tokens/token.dart'
show BeginGroupToken, ErrorToken, KeywordToken, SymbolToken, Token;
import '../tokens/token_constants.dart' as Tokens
show LT_TOKEN, OPEN_CURLY_BRACKET_TOKEN, STRING_INTERPOLATION_TOKEN;
import '../util/characters.dart' show $LF, $STX;
import '../util/util.dart' show Link;
import 'scanner.dart' show AbstractScanner;
import 'keyword.dart' show
Keyword;
import 'precedence.dart' show
COMMENT_INFO,
EOF_INFO,
PrecedenceInfo;
import 'token.dart' show
BeginGroupToken,
ErrorToken,
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 {
ArrayBasedScanner(SourceFile file, bool includeComments)
: super(file, includeComments);
bool hasErrors = false;
ArrayBasedScanner(bool includeComments)
: super(includeComments);
/**
* The stack of open groups, e.g [: { ... ( .. :]
@ -77,7 +96,7 @@ abstract class ArrayBasedScanner extends AbstractScanner {
unmatchedBeginGroup(groupingStack.head);
groupingStack = groupingStack.tail;
}
tail.next = new SymbolToken(Precedence.EOF_INFO, tokenStart);
tail.next = new SymbolToken(EOF_INFO, tokenStart);
tail = tail.next;
// EOF points to itself so there's always infinite look-ahead.
tail.next = tail;
@ -91,7 +110,7 @@ abstract class ArrayBasedScanner extends AbstractScanner {
* [lineStarts] map.
*/
void appendWhiteSpace(int next) {
if (next == $LF && file != null) {
if (next == $LF) {
lineStarts.add(stringOffset + 1); // +1, the line starts after the $LF.
}
}
@ -103,9 +122,7 @@ abstract class ArrayBasedScanner extends AbstractScanner {
* [lineStarts] map.
*/
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;
// { ( [ ${ 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);
}
@ -128,7 +145,7 @@ abstract class ArrayBasedScanner extends AbstractScanner {
* '>>' are handled separately bo [appendGt] and [appendGtGt].
*/
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);
appendPrecedenceToken(info);
Token close = tail;
@ -137,8 +154,8 @@ abstract class ArrayBasedScanner extends AbstractScanner {
}
BeginGroupToken begin = groupingStack.head;
if (!identical(begin.kind, openKind)) {
assert(begin.kind == Tokens.STRING_INTERPOLATION_TOKEN &&
openKind == Tokens.OPEN_CURLY_BRACKET_TOKEN);
assert(begin.kind == STRING_INTERPOLATION_TOKEN &&
openKind == OPEN_CURLY_BRACKET_TOKEN);
// We're ending an interpolated expression.
begin.endGroup = close;
groupingStack = groupingStack.tail;
@ -162,8 +179,8 @@ abstract class ArrayBasedScanner extends AbstractScanner {
if (groupingStack.isEmpty) return;
BeginGroupToken begin = groupingStack.head;
if (openKind == begin.kind) return;
if (openKind == Tokens.OPEN_CURLY_BRACKET_TOKEN &&
begin.kind == Tokens.STRING_INTERPOLATION_TOKEN) return;
if (openKind == OPEN_CURLY_BRACKET_TOKEN &&
begin.kind == STRING_INTERPOLATION_TOKEN) return;
unmatchedBeginGroup(begin);
groupingStack = groupingStack.tail;
}
@ -177,7 +194,7 @@ abstract class ArrayBasedScanner extends AbstractScanner {
void appendGt(PrecedenceInfo info) {
appendPrecedenceToken(info);
if (groupingStack.isEmpty) return;
if (identical(groupingStack.head.kind, Tokens.LT_TOKEN)) {
if (identical(groupingStack.head.kind, LT_TOKEN)) {
groupingStack.head.endGroup = tail;
groupingStack = groupingStack.tail;
}
@ -191,13 +208,13 @@ abstract class ArrayBasedScanner extends AbstractScanner {
void appendGtGt(PrecedenceInfo info) {
appendPrecedenceToken(info);
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
// '<', the inner '<' is left without endGroup.
groupingStack = groupingStack.tail;
}
if (groupingStack.isEmpty) return;
if (identical(groupingStack.head.kind, Tokens.LT_TOKEN)) {
if (identical(groupingStack.head.kind, LT_TOKEN)) {
groupingStack.head.endGroup = tail;
groupingStack = groupingStack.tail;
}
@ -205,10 +222,11 @@ abstract class ArrayBasedScanner extends AbstractScanner {
void appendComment(start, bool asciiOnly) {
if (!includeComments) return;
appendSubstringToken(Precedence.COMMENT_INFO, start, asciiOnly);
appendSubstringToken(COMMENT_INFO, start, asciiOnly);
}
void appendErrorToken(ErrorToken token) {
hasErrors = true;
tail.next = token;
tail = token;
}
@ -226,7 +244,7 @@ abstract class ArrayBasedScanner extends AbstractScanner {
*/
void discardOpenLt() {
while (!groupingStack.isEmpty &&
identical(groupingStack.head.kind, Tokens.LT_TOKEN)) {
identical(groupingStack.head.kind, LT_TOKEN)) {
groupingStack = groupingStack.tail;
}
}

View 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);

View File

@ -2,7 +2,7 @@
// 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 characters;
library fasta.scanner.characters;
const int $EOF = 0;
const int $STX = 2;

View File

@ -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
// 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:convert';
import 'dart:io';
import 'dart:math' as math;
import 'dart:typed_data';
import 'dart:async' show
Future;
import '../compiler.dart' as api show Diagnostic;
import '../compiler_new.dart' as api;
import '../compiler_new.dart';
import 'colors.dart' as colors;
import 'dart2js.dart' show AbortLeg;
import 'filenames.dart';
import 'io/source_file.dart';
import 'util/uri_extras.dart';
import 'dart:io' show
File,
RandomAccessFile;
abstract class SourceFileProvider implements CompilerInput {
bool isWindows = (Platform.operatingSystem == 'windows');
Uri cwd = currentDirectory;
Map<Uri, SourceFile> sourceFiles = <Uri, SourceFile>{};
int dartCharactersRead = 0;
import 'dart:typed_data' show
Uint8List;
Future<String> readStringFromUri(Uri resourceUri) {
return readUtf8BytesFromUri(resourceUri).then(UTF8.decode);
}
Future<List<int>> readUtf8BytesFromUri(Uri resourceUri) {
if (resourceUri.scheme == 'file') {
return _readFromFile(resourceUri);
} else if (resourceUri.scheme == 'http' || resourceUri.scheme == 'https') {
return _readFromHttp(resourceUri);
} else {
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];
List<int> readBytesFromFileSync(Uri uri) {
RandomAccessFile file = new File.fromUri(uri).openSync();
Uint8List list;
try {
int length = file.lengthSync();
// +1 to have a 0 terminated list, see [Scanner].
list = new Uint8List(length + 1);
file.readIntoSync(list, 0, length);
} finally {
file.closeSync();
}
return list;
}
List<int> readAll(String filename) {
var file = (new File(filename)).openSync();
var length = file.lengthSync();
// +1 to have a 0 terminated list, see [Scanner].
var buffer = new Uint8List(length + 1);
file.readIntoSync(buffer, 0, length);
file.closeSync();
return buffer;
}
class CompilerSourceFileProvider extends SourceFileProvider {
// TODO(johnniwinther): Remove this when no longer needed for the old compiler
// API.
Future<List<int>> call(Uri resourceUri) => readFromUri(resourceUri);
@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;
}
Future<List<int>> readBytesFromFile(Uri uri) async {
RandomAccessFile file = await new File.fromUri(uri).open();
Uint8List list;
try {
int length = await file.length();
// +1 to have a 0 terminated list, see [Scanner].
list = new Uint8List(length + 1);
int read = await file.readInto(list);
if (read != length) {
throw "Error reading file: ${uri}";
}
} finally {
await file.close();
}
return list;
}

View File

@ -2,12 +2,18 @@
// 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.keywords;
library fasta.scanner.keywords;
import '../util/characters.dart' as Characters show $a;
import 'precedence.dart' show PrecedenceInfo;
import 'precedence_constants.dart' as Precedence
show AS_INFO, IS_INFO, KEYWORD_INFO;
import 'characters.dart' show
$a;
import 'precedence.dart' show
PrecedenceInfo;
import 'precedence.dart' show
AS_INFO,
IS_INFO,
KEYWORD_INFO;
/**
* A keyword in the Dart programming language.
@ -49,10 +55,10 @@ class Keyword {
// TODO(ahe): Don't think this is a reserved word.
// 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("as", info: Precedence.AS_INFO, isBuiltIn: true),
const Keyword("as", info: AS_INFO, isBuiltIn: true),
const Keyword("covariant", isBuiltIn: true),
const Keyword("dynamic", isBuiltIn: true),
const Keyword("export", isBuiltIn: true),
@ -97,7 +103,7 @@ class Keyword {
const Keyword(this.syntax,
{this.isPseudo: false,
this.isBuiltIn: false,
this.info: Precedence.KEYWORD_INFO});
this.info: KEYWORD_INFO});
static Map<String, Keyword> computeKeywordMap() {
Map<String, Keyword> result = new Map<String, Keyword>();
@ -147,8 +153,8 @@ abstract class KeywordState {
int c = strings[i].codeUnitAt(start);
if (chunk != c) {
if (chunkStart != -1) {
assert(result[chunk - Characters.$a] == null);
result[chunk - Characters.$a] = computeKeywordStateTable(
assert(result[chunk - $a] == null);
result[chunk - $a] = computeKeywordStateTable(
start + 1, strings, chunkStart, i - chunkStart);
}
chunkStart = i;
@ -157,8 +163,8 @@ abstract class KeywordState {
}
}
if (chunkStart != -1) {
assert(result[chunk - Characters.$a] == null);
result[chunk - Characters.$a] = computeKeywordStateTable(
assert(result[chunk - $a] == null);
result[chunk - $a] = computeKeywordStateTable(
start + 1, strings, chunkStart, offset + length - chunkStart);
} else {
assert(length == 1);
@ -181,7 +187,7 @@ class ArrayKeywordState extends KeywordState {
ArrayKeywordState(List<KeywordState> this.table, String 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() {
StringBuffer sb = new StringBuffer();
@ -194,7 +200,7 @@ class ArrayKeywordState extends KeywordState {
List<KeywordState> foo = table;
for (int i = 0; i < foo.length; i++) {
if (foo[i] != null) {
sb.write("${new String.fromCharCodes([i + Characters.$a])}: "
sb.write("${new String.fromCharCodes([i + $a])}: "
"${foo[i]}; ");
}
}

View 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);
}

View File

@ -2,11 +2,20 @@
// 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.constants;
library fasta.scanner.precedence;
import 'precedence.dart' show PrecedenceInfo;
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.
const PrecedenceInfo BACKPING_INFO =
const PrecedenceInfo('`', 0, BACKPING_TOKEN);

View 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;
}

View File

@ -2,12 +2,17 @@
// 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.scanner.string;
library dart2js.scanner.string_scanner;
import '../io/source_file.dart' show SourceFile;
import '../tokens/precedence.dart' show PrecedenceInfo;
import '../tokens/token.dart' show StringToken, Token;
import 'array_based_scanner.dart' show ArrayBasedScanner;
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
@ -20,22 +25,15 @@ class StringScanner extends ArrayBasedScanner {
/** The current offset in [string]. */
int scanOffset = -1;
StringScanner(SourceFile file, {bool includeComments: false})
: string = file.slowText(),
super(file, includeComments) {
ensureZeroTermination();
}
StringScanner(String string, {bool includeComments: false})
: string = ensureZeroTermination(string),
super(includeComments);
StringScanner.fromString(this.string, {bool includeComments: false})
: super(null, includeComments) {
ensureZeroTermination();
}
void ensureZeroTermination() {
if (string.isEmpty || string.codeUnitAt(string.length - 1) != 0) {
// TODO(lry): abort instead of copying the array, or warn?
string = string + '\x00';
}
static String ensureZeroTermination(String string) {
return (string.isEmpty || string.codeUnitAt(string.length - 1) != 0)
// TODO(lry): abort instead of copying the array, or warn?
? string + '\x00'
: string;
}
int advance() => string.codeUnitAt(++scanOffset);

View File

@ -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));
}
}

View File

@ -2,22 +2,28 @@
// 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;
library fasta.scanner.token;
import 'dart:collection' show HashSet;
import 'dart:convert' show UTF8;
import 'dart:collection' show
HashSet;
import '../common.dart';
import '../util/util.dart' show computeHashCode;
import 'keyword.dart' show Keyword;
import 'precedence.dart' show PrecedenceInfo;
import 'precedence_constants.dart' as Precedence show BAD_INPUT_INFO;
import 'token_constants.dart' as Tokens show IDENTIFIER_TOKEN;
import 'dart:convert' show
UTF8;
import 'keyword.dart' show
Keyword;
import 'precedence.dart' show
BAD_INPUT_INFO,
PrecedenceInfo;
import 'token_constants.dart' show
IDENTIFIER_TOKEN;
/**
* 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.
*/
@ -95,7 +101,7 @@ abstract class Token implements Spannable {
* The number of characters parsed by this token.
*/
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
// instead of the size of the length of the error message.
return 1;
@ -106,17 +112,6 @@ abstract class Token implements Spannable {
/// The character offset of the end of this token within the source text.
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 {
ErrorToken(int charOffset) : super(charOffset);
PrecedenceInfo get info => Precedence.BAD_INPUT_INFO;
PrecedenceInfo get info => BAD_INPUT_INFO;
String get value {
throw new SpannableAssertionFailure(this, assertionMessage);
throw assertionMessage;
}
String get stringValue => null;
@ -307,7 +302,7 @@ class StringToken extends Token {
/// See [Token.stringValue] for an explanation.
String get stringValue => null;
bool isIdentifier() => identical(kind, Tokens.IDENTIFIER_TOKEN);
bool isIdentifier() => identical(kind, IDENTIFIER_TOKEN);
String toString() => "StringToken($value)";

View File

@ -2,9 +2,9 @@
// 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.constants;
library fasta.scanner.token_constants;
import '../util/characters.dart';
import 'characters.dart';
const int EOF_TOKEN = 0;

Some files were not shown because too many files have changed in this diff Show More