blob: 3fde7d03f7488183e0987e899073c8665302d50f [file] [log] [blame]
// Copyright (c) 2020, 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.
// @dart=2.9
import 'dart:io';
import 'dart:typed_data';
import 'package:_fe_analyzer_shared/src/parser/parser.dart';
import 'package:_fe_analyzer_shared/src/parser/formal_parameter_kind.dart';
import 'package:_fe_analyzer_shared/src/parser/listener.dart';
import 'package:_fe_analyzer_shared/src/parser/member_kind.dart';
import 'package:_fe_analyzer_shared/src/scanner/utf8_bytes_scanner.dart';
import 'package:_fe_analyzer_shared/src/scanner/token.dart';
import 'package:dart_style/dart_style.dart' show DartFormatter;
StringSink out;
main(List<String> args) {
if (args.contains("--stdout")) {
out = stdout;
} else {
out = new StringBuffer();
}
File f = new File.fromUri(Platform.script
.resolve("../../../_fe_analyzer_shared/lib/src/parser/listener.dart"));
List<int> rawBytes = f.readAsBytesSync();
Uint8List bytes = new Uint8List(rawBytes.length + 1);
bytes.setRange(0, rawBytes.length, rawBytes);
Utf8BytesScanner scanner = new Utf8BytesScanner(bytes, includeComments: true);
Token firstToken = scanner.tokenize();
out.write(r"""
// Copyright (c) 2020, 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:_fe_analyzer_shared/src/parser/assert.dart';
import 'package:_fe_analyzer_shared/src/parser/block_kind.dart';
import 'package:_fe_analyzer_shared/src/parser/declaration_kind.dart';
import 'package:_fe_analyzer_shared/src/parser/formal_parameter_kind.dart';
import 'package:_fe_analyzer_shared/src/parser/identifier_context.dart';
import 'package:_fe_analyzer_shared/src/parser/listener.dart';
import 'package:_fe_analyzer_shared/src/parser/member_kind.dart';
import 'package:_fe_analyzer_shared/src/scanner/error_token.dart';
import 'package:_fe_analyzer_shared/src/scanner/token.dart';
import 'package:front_end/src/fasta/messages.dart';
// ignore_for_file: lines_longer_than_80_chars
// THIS FILE IS AUTO GENERATED BY
// 'tool/_fasta/direct_parser_ast_helper_creator.dart'
// Run e.g.
/*
out/ReleaseX64/dart \
pkg/front_end/tool/_fasta/direct_parser_ast_helper_creator.dart \
> pkg/front_end/lib/src/fasta/util/direct_parser_ast_helper.dart
*/
abstract class DirectParserASTContent {
final String what;
final DirectParserASTType type;
Map<String, Object> get deprecatedArguments;
List<DirectParserASTContent> children;
DirectParserASTContent(this.what, this.type);
// TODO(jensj): Compare two ASTs.
}
enum DirectParserASTType { BEGIN, END, HANDLE }
abstract class AbstractDirectParserASTListener implements Listener {
List<DirectParserASTContent> data = [];
void seen(DirectParserASTContent entry);
""");
ParserCreatorListener listener = new ParserCreatorListener();
ClassMemberParser parser = new ClassMemberParser(listener);
parser.parseUnit(firstToken);
out.writeln("}");
out.writeln("");
out.write(listener.newClasses.toString());
if (out is StringBuffer) {
String text = new DartFormatter().format("$out");
if (args.isNotEmpty) {
new File(args.first).writeAsStringSync(text);
} else {
stdout.write(text);
}
}
}
class ParserCreatorListener extends Listener {
bool insideListenerClass = false;
String currentMethodName;
String latestSeenParameterTypeToken;
List<String> parameters = <String>[];
List<String> parameterTypes = <String>[];
StringBuffer newClasses = new StringBuffer();
void beginClassDeclaration(Token begin, Token abstractToken, Token name) {
if (name.lexeme == "Listener") insideListenerClass = true;
}
void endClassDeclaration(Token beginToken, Token endToken) {
insideListenerClass = false;
}
void beginMethod(Token externalToken, Token staticToken, Token covariantToken,
Token varFinalOrConst, Token getOrSet, Token name) {
currentMethodName = name.lexeme;
}
void endClassMethod(Token getOrSet, Token beginToken, Token beginParam,
Token beginInitializers, Token endToken) {
void end() {
parameters.clear();
parameterTypes.clear();
currentMethodName = null;
}
if (insideListenerClass &&
(currentMethodName.startsWith("begin") ||
currentMethodName.startsWith("end") ||
currentMethodName.startsWith("handle"))) {
StringBuffer sb = new StringBuffer();
sb.write(" ");
Token token = beginToken;
Token latestToken;
while (true) {
if (latestToken != null && latestToken.charEnd < token.charOffset) {
sb.write(" ");
}
sb.write(token.lexeme);
if ((token is BeginToken &&
token.type == TokenType.OPEN_CURLY_BRACKET) ||
token is SimpleToken && token.type == TokenType.FUNCTION) {
break;
}
if (token == endToken) {
throw token.runtimeType;
}
latestToken = token;
token = token.next;
}
if (token is SimpleToken && token.type == TokenType.FUNCTION) {
return end();
} else {
sb.write("\n ");
String typeString;
String typeStringCamel;
String name;
if (currentMethodName.startsWith("begin")) {
typeString = "BEGIN";
typeStringCamel = "Begin";
name = currentMethodName.substring("begin".length);
} else if (currentMethodName.startsWith("end")) {
typeString = "END";
typeStringCamel = "End";
name = currentMethodName.substring("end".length);
} else if (currentMethodName.startsWith("handle")) {
typeString = "HANDLE";
typeStringCamel = "Handle";
name = currentMethodName.substring("handle".length);
} else {
throw "Unexpected.";
}
String className = "DirectParserASTContent${name}${typeStringCamel}";
sb.write("$className data = new $className(");
sb.write("DirectParserASTType.");
sb.write(typeString);
for (int i = 0; i < parameters.length; i++) {
sb.write(', ');
sb.write(parameters[i]);
sb.write(': ');
sb.write(parameters[i]);
}
sb.write(");");
sb.write("\n ");
sb.write("seen(data);");
sb.write("\n ");
newClasses
.write("class DirectParserASTContent${name}${typeStringCamel} "
"extends DirectParserASTContent {\n");
for (int i = 0; i < parameters.length; i++) {
newClasses.write(" final ");
newClasses.write(parameterTypes[i]);
newClasses.write(' ');
newClasses.write(parameters[i]);
newClasses.write(';\n');
}
newClasses.write('\n');
newClasses.write(" DirectParserASTContent${name}${typeStringCamel}"
"(DirectParserASTType type");
String separator = ", {";
for (int i = 0; i < parameters.length; i++) {
newClasses.write(separator);
newClasses.write('this.');
newClasses.write(parameters[i]);
separator = ", ";
}
if (parameters.isNotEmpty) {
newClasses.write('}');
}
newClasses.write(') : super("$name", type);\n\n');
newClasses.write("Map<String, Object> get deprecatedArguments => {");
for (int i = 0; i < parameters.length; i++) {
newClasses.write('"');
newClasses.write(parameters[i]);
newClasses.write('": ');
newClasses.write(parameters[i]);
newClasses.write(',');
}
newClasses.write("};\n");
newClasses.write("}\n");
}
sb.write("}");
sb.write("\n\n");
out.write(sb.toString());
}
end();
}
@override
void handleNoType(Token lastConsumed) {
latestSeenParameterTypeToken = null;
}
void handleType(Token beginToken, Token questionMark) {
latestSeenParameterTypeToken = beginToken.lexeme;
}
void endFormalParameter(
Token thisKeyword,
Token periodAfterThis,
Token nameToken,
Token initializerStart,
Token initializerEnd,
FormalParameterKind kind,
MemberKind memberKind) {
parameters.add(nameToken.lexeme);
parameterTypes.add(latestSeenParameterTypeToken);
}
}