blob: 55a4f34e91e24fb8b2857b97e9152e37817a7917 [file] [log] [blame]
// 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 parser_helper;
import 'package:expect/expect.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/id_generator.dart';
import 'package:compiler/src/tree/tree.dart';
import 'package:compiler/src/parser/element_listener.dart';
import 'package:compiler/src/parser/node_listener.dart';
import 'package:compiler/src/parser/diet_parser_task.dart';
import 'package:front_end/src/fasta/parser.dart' hide parse;
import 'package:front_end/src/fasta/scanner.dart' hide scan;
import 'package:compiler/src/io/source_file.dart';
import 'package:compiler/src/util/util.dart';
import 'package:compiler/src/elements/modelx.dart'
show CompilationUnitElementX, ElementX, LibraryElementX;
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/options.dart';
import 'package:compiler/src/diagnostics/source_span.dart';
import 'package:compiler/src/diagnostics/spannable.dart';
import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
import 'package:compiler/src/diagnostics/messages.dart';
import 'package:compiler/src/script.dart';
import 'options_helper.dart';
export 'package:front_end/src/fasta/parser.dart' hide parse;
export 'package:front_end/src/fasta/scanner.dart' hide scan;
export 'package:compiler/src/diagnostics/diagnostic_listener.dart';
export 'package:compiler/src/parser/node_listener.dart';
export 'package:compiler/src/parser/diet_parser_task.dart';
export 'package:front_end/src/fasta/scanner/token_constants.dart';
import 'mock_compiler.dart';
class LoggerCanceler extends DiagnosticReporter {
DiagnosticOptions get options => const MockDiagnosticOptions();
void log(message) {
print(message);
}
void internalError(Spannable node, message) {
log(message);
}
SourceSpan spanFromSpannable(node) {
throw 'unsupported operation';
}
SourceSpan spanFromToken(token) => null;
void reportError(DiagnosticMessage message,
[List<DiagnosticMessage> infos = const <DiagnosticMessage>[]]) {
log(message);
infos.forEach(log);
}
void reportWarning(DiagnosticMessage message,
[List<DiagnosticMessage> infos = const <DiagnosticMessage>[]]) {
log(message);
infos.forEach(log);
}
void reportInfo(Spannable node, MessageKind errorCode,
[Map arguments = const {}]) {
log(new Message(MessageTemplate.TEMPLATES[errorCode], arguments, false));
}
void reportHint(DiagnosticMessage message,
[List<DiagnosticMessage> infos = const <DiagnosticMessage>[]]) {
log(message);
infos.forEach(log);
}
withCurrentElement(Entity element, f()) => f();
@override
DiagnosticMessage createMessage(Spannable spannable, MessageKind messageKind,
[Map arguments = const {}]) {
return new DiagnosticMessage(null, spannable,
new Message(MessageTemplate.TEMPLATES[messageKind], arguments, false));
}
@override
bool get hasReportedError => false;
}
Token scan(String text) => new StringScanner(text).tokenize();
Node parseBodyCode(String text, Function parseMethod,
{DiagnosticReporter reporter}) {
Token tokens = scan(text);
if (reporter == null) reporter = new LoggerCanceler();
Uri uri = new Uri(scheme: "source");
Script script = new Script(uri, uri, new MockFile(text));
LibraryElement library = new LibraryElementX(script);
NodeListener listener = new NodeListener(
new ScannerOptions(canUseNative: true),
reporter,
library.entryCompilationUnit);
Parser parser = new Parser(listener);
Token endToken = parseMethod(parser, tokens).next;
assert(endToken.kind == EOF_TOKEN);
Node node = listener.popNode();
Expect.isNotNull(node);
Expect.isTrue(listener.nodes.isEmpty, 'Not empty: ${listener.nodes}');
return node;
}
Node parseStatement(String text) => parseBodyCode(
text,
(parser, tokens) =>
parser.parseStatement(parser.syntheticPreviousToken(tokens)));
Node parseFunction(String text, MockCompiler compiler) {
ElementX element = parseUnit(text, compiler, compiler.mainApp).head;
Expect.isNotNull(element);
Expect.equals(ElementKind.FUNCTION, element.kind);
return element.parseNode(compiler.parsingContext);
}
Node parseMember(String text, {DiagnosticReporter reporter}) {
return parseBodyCode(
text, (parser, tokens) => parser.parseClassMember(tokens),
reporter: reporter);
}
class MockFile extends StringSourceFile {
MockFile(text) : super.fromName('<string>', text);
}
var sourceCounter = 0;
Link<Element> parseUnit(String text, Compiler compiler, LibraryElement library,
[void registerSource(Uri uri, String source)]) {
Token tokens = scan(text);
Uri uri = new Uri(scheme: "source", path: '${++sourceCounter}');
if (registerSource != null) {
registerSource(uri, text);
}
var script = new Script(uri, uri, new MockFile(text));
var unit = new CompilationUnitElementX(script, library);
DiagnosticReporter reporter = compiler.reporter;
ElementListener listener = new ElementListener(
compiler.parsingContext.getScannerOptionsFor(library),
reporter,
unit,
new IdGenerator());
PartialParser parser = new PartialParser(listener);
reporter.withCurrentElement(unit, () => parser.parseUnit(tokens));
return unit.localMembers;
}
NodeList fullParseUnit(String source, {DiagnosticReporter reporter}) {
return parseBodyCode(source, (parser, tokens) => parser.parseUnit(tokens),
reporter: reporter);
}