integrating fasta parser

* start integrating fasta parser into analyzer
* extract new Scanner.fasta factory

R=paulberry@google.com

Review-Url: https://codereview.chromium.org/2948473002 .
This commit is contained in:
Dan Rubel 2017-06-20 12:24:07 -04:00
parent 97d188418a
commit 966d1a4701
5 changed files with 148 additions and 8 deletions

View file

@ -48,10 +48,16 @@ class Scanner extends fe.Scanner {
factory Scanner(Source source, CharacterReader reader,
AnalysisErrorListener errorListener) =>
fe.Scanner.useFasta
? new _Scanner2(
source, reader.getContents(), reader.offset, errorListener)
? new Scanner.fasta(source, errorListener,
contents: reader.getContents(), offset: reader.offset)
: new Scanner._(source, reader, errorListener);
factory Scanner.fasta(Source source, AnalysisErrorListener errorListener,
{String contents, int offset: 0}) {
return new _Scanner2(
source, contents ?? source.contents.data, offset, errorListener);
}
Scanner._(this.source, CharacterReader reader, this._errorListener)
: super.create(reader);

View file

@ -2,6 +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.
library analyzer.parser;
import 'dart:collection';
import "dart:math" as math;
@ -16,15 +18,22 @@ import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/fasta/ast_builder.dart';
import 'package:analyzer/src/fasta/element_store.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:front_end/src/fasta/kernel/kernel_builder.dart';
import 'package:front_end/src/fasta/kernel/kernel_library_builder.dart';
import 'package:front_end/src/fasta/parser/parser.dart' as fasta;
export 'package:analyzer/src/dart/ast/utilities.dart' show ResolutionCopier;
export 'package:analyzer/src/dart/error/syntactic_errors.dart';
part 'parser_fasta.dart';
/**
* A simple data-holder for a method that needs to return multiple values.
*/
@ -260,11 +269,26 @@ class Parser {
*/
bool parseGenericMethodComments = false;
/**
* A flag indicating whether the analyzer [Parser] factory method
* will return a fasta based parser or an analyzer based parser.
*/
static bool useFasta = const bool.fromEnvironment("useFastaParser");
/**
* Initialize a newly created parser to parse tokens in the given [_source]
* and to report any errors that are found to the given [_errorListener].
*/
Parser(this._source, this._errorListener);
factory Parser(Source source, AnalysisErrorListener errorListener,
{bool useFasta}) {
if (useFasta ?? Parser.useFasta) {
return new _Parser2(source, errorListener);
} else {
return new Parser._(source, errorListener);
}
}
Parser._(this._source, this._errorListener);
/**
* Return the current token.

View file

@ -0,0 +1,94 @@
// 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 license that can be found in the LICENSE file.
part of analyzer.parser;
class _Builder implements Builder {
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class _ElementStore implements ElementStore {
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class _KernelLibraryBuilder implements KernelLibraryBuilder {
@override
final uri;
_KernelLibraryBuilder(this.uri);
@override
Uri get fileUri => uri;
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
/**
* Replacement parser based on Fasta.
*/
class _Parser2 implements Parser {
@override
Token currentToken;
/**
* The builder which creates the analyzer AST data structures
* based on the Fasta parser.
*/
final AstBuilder _astBuilder;
/**
* The error listener that will be informed of any errors that are found
* during the parse.
*/
final AnalysisErrorListener _errorListener;
/**
* The fasta parser being wrapped.
*/
final fasta.Parser _fastaParser;
/**
* The source being parsed.
*/
final Source _source;
factory _Parser2(Source source, AnalysisErrorListener errorListener) {
var errorReporter = new ErrorReporter(errorListener, source);
var library = new _KernelLibraryBuilder(source.uri);
var member = new _Builder();
var elementStore = new _ElementStore();
var scope = new Scope.top(isModifiable: true);
AstBuilder astBuilder = new AstBuilder(
errorReporter, library, member, elementStore, scope, true);
fasta.Parser fastaParser = new fasta.Parser(astBuilder);
astBuilder.parser = fastaParser;
return new _Parser2._(source, errorListener, fastaParser, astBuilder);
}
_Parser2._(
this._source, this._errorListener, this._fastaParser, this._astBuilder);
@override
bool get parseGenericMethodComments => _astBuilder.parseGenericMethodComments;
@override
set parseGenericMethodComments(bool value) {
_astBuilder.parseGenericMethodComments = value;
}
@override
CompilationUnit parseCompilationUnit(Token token) {
currentToken = token;
return parseCompilationUnit2();
}
@override
CompilationUnit parseCompilationUnit2() {
currentToken = _fastaParser.parseUnit(currentToken);
return _astBuilder.pop();
}
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

View file

@ -6,10 +6,12 @@ import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart' as analyzer;
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/fasta/ast_builder.dart';
import 'package:analyzer/src/fasta/element_store.dart';
import 'package:analyzer/src/generated/parser.dart' as analyzer;
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/string_source.dart';
import 'package:front_end/src/fasta/kernel/kernel_builder.dart';
import 'package:front_end/src/fasta/kernel/kernel_library_builder.dart';
import 'package:front_end/src/fasta/parser/identifier_context.dart'
@ -21,6 +23,7 @@ import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'parser_test.dart';
import 'test_support.dart';
main() {
defineReflectiveSuite(() {
@ -387,10 +390,23 @@ class FastaParserTestCase extends Object
}
@override
CompilationUnit parseCompilationUnit(String source,
[List<ErrorCode> errorCodes = const <ErrorCode>[]]) {
return _runParser(source, (parser) => parser.parseUnit, errorCodes)
as CompilationUnit;
CompilationUnit parseCompilationUnit(String content,
[List<ErrorCode> expectedErrorCodes = const <ErrorCode>[]]) {
// Scan tokens
var source = new StringSource(content, 'parser_test_StringSource.dart');
GatheringErrorListener listener = new GatheringErrorListener();
var scanner = new Scanner.fasta(source, listener);
scanner.scanGenericMethodComments = enableGenericMethodComments;
_fastaTokens = scanner.tokenize();
// Run parser
analyzer.Parser parser =
new analyzer.Parser(source, listener, useFasta: true);
CompilationUnit unit = parser.parseCompilationUnit(_fastaTokens);
// Assert and return result
listener.assertErrorsWithCodes(expectedErrorCodes);
return unit;
}
@override

View file

@ -126,7 +126,7 @@ class KeywordState {
*/
abstract class Scanner {
/**
* A flag indicating whether the [Scanner] factory method
* A flag indicating whether the analyzer [Scanner] factory method
* will return a fasta based scanner or an analyzer based scanner.
*/
static bool useFasta = const bool.fromEnvironment("useFastaScanner");