Adding a New Keyword to the Dart Language
I'm attempting to add the keyword: foobar which will translate to a literal int 5.
Steps:
- Modified lib/src/scanner/token.dart to add "foobar" keyword
- Looking at where the Keyword TRUE is used
- parser_impl.dart
- keyword_contributor.dart
- ast_test_factory.dart
- tokens_context.dart
- tokens_writer.dart
- unlinked_token_type.dart
- lax_json.dart
- <various tests>
- Likely need to update: https://github.com/dart-lang/sdk/blob/master/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart#L5362 in order to produce correct AST.
- Compiling dart program with "foobar" expecting error...
SDK diff:
# compiling sdk
ninja -C out/ios_debug_sim_unopt
ninja: Entering directory `out/ios_debug_sim_unopt'
[1/1] Regenerating ninja files
[50/50] STAMP obj/default.stamp
# running on simulator
flutter run --local-engine-src-path='../flojure-engine/src' --local-engine=ios_debug_sim_unopt
It did not throw an error compiling instead complained that variable was not defined.
dart bin/starter.dart --sdk-root='../../out/ios_debug_sim_unopt/flutter_patched_sdk' --target=flutter tmp/hello.dart [ruby-2.6.3p62]
result 8b200e8d-fbf3-4de7-8376-56ccd7e8b320
tmp/hello.dart:3:13: Error: 'foobar' can't be used as an identifier because it's a keyword.
Try renaming this to be an identifier that isn't a keyword.
final x = foobar;
^^^^^^
tmp/hello.dart:3:13: Error: Getter not found: 'foobar'.
final x = foobar;
^^^^^^
8b200e8d-fbf3-4de7-8376-56ccd7e8b320
+file:///Users/johnmcconnell/dev/github.com/johnmcconnell/flojure-engine/src/flutter/flutter_frontend_server/tmp/hello.dart
8b200e8d-fbf3-4de7-8376-56ccd7e8b320 tmp/hello.dart.dill 2
Compiling from frontend server doesn't require recompiling.
Compiling the program:
void main() {
final x = foobar;
print('hello world!: $x');
}
$ dart bin/starter.dart --sdk-root='../../out/ios_debug_sim_unopt/flutter_patched_sdk' --target=flutter tmp/hello.dart
result df088500-2afb-4488-9013-a23f2c1a5ae8
df088500-2afb-4488-9013-a23f2c1a5ae8
+file:///Users/johnmcconnell/dev/github.com/johnmcconnell/flojure-engine/src/flutter/flutter_frontend_server/tmp/hello.dart
df088500-2afb-4488-9013-a23f2c1a5ae8 tmp/hello.dart.dill 0
$ dart run tmp/hello.dart.dill
hello world!: 5
It worked. However, using flutter and setting the local engine path doesn't seem to work.
Code diff:
diff --git i/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart w/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
index 93d7a7b9671..b943bd90600 100644
--- i/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ w/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -5289,6 +5275,11 @@ class Parser {
return parseLiteralBool(token);
} else if (identical(value, "null")) {
return parseLiteralNull(token);
+ } else if (identical(value, "foobar")) {
+ final t = StringToken(TokenType.INT, "5", token.next!.charOffset);
+ t.setNext(token.next!.next!);
+ listener.handleLiteralInt(t);
+ return t;
} else if (identical(value, "this")) {
return parseThisExpression(token, context);
} else if (identical(value, "super")) {
diff --git i/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart w/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
index 4cc7473c8c7..b2e014533a2 100644
--- i/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
+++ w/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
@@ -340,6 +340,9 @@ class Keyword extends TokenType {
static const Keyword YIELD =
const Keyword("yield", "YIELD", KeywordStyle.pseudo);
+ static const Keyword FOOBAR =
+ const Keyword("foobar", "FOOBAR", KeywordStyle.reserved);
+
static const List<Keyword> values = const <Keyword>[
ABSTRACT,
AS,
@@ -368,6 +371,7 @@ class Keyword extends TokenType {
FINAL,
FINALLY,
FOR,
+ FOOBAR,
FUNCTION,
GET,
HIDE,
Finish for now.
Error with running from flutter (vs the dart command):
/Users/johnmcconnell/dev/github.com/johnmcconnell/flojure-example-app/.dart_tool/flutter_build/a5b6813f1f6085abf8595dcd34b5ad4f/kernel_snapshot.d package:flojure_example_app/main.dart
[+2644 ms] lib/main.dart:11:15: Error: The getter 'foobar' isn't defined for the class 'MyApp'.
[ +1 ms] - 'MyApp' is from 'package:flojure_example_app/main.dart' ('lib/main.dart').
[ ] Try correcting the name to the name of an existing getter, or defining a getter or field named 'foobar'.
[ ] final x = foobar;
[ ] ^^^^^^
[+6619 ms] Persisting file store
[ +4 ms] Done persisting file store
[ +3 ms] Target kernel_snapshot failed: Exception
#0 KernelSnapshot.build (package:flutter_tools/src/build_system/targets/common.dart:291:7)
<asynchronous suspension>
#1 _BuildInstance._invokeInternal (package:flutter_tools/src/build_system/build_system.dart:828:9)
<asynchronous suspension>
#2 Future.wait.<anonymous closure> (dart:async/future.dart)
<asynchronous suspension>
#3 _BuildInstance.invokeTarget (package:flutter_tools/src/build_system/build_system.dart:766:32)
<asynchronous suspension>
#4 FlutterBuildSystem.build (package:flutter_tools/src/build_system/build_system.dart:595:16)
<asynchronous suspension>
#5 AssembleCommand.runCommand (package:flutter_tools/src/commands/assemble.dart:318:32)
<asynchronous suspension>
#6 FlutterCommand.run.<anonymous closure> (package:flutter_tools/src/runner/flutter_command.dart:1043:27)
<asynchronous suspension>
#7 AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
<asynchronous suspension>
#8 CommandRunner.runCommand (package:args/command_runner.dart:196:13)
<asynchronous suspension>
#9 FlutterCommandRunner.runCommand.<anonymous closure> (package:flutter_tools/src/runner/flutter_command_runner.dart:284:9)
<asynchronous suspension>
#10 AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
<asynchronous suspension>
#11 FlutterCommandRunner.runCommand (package:flutter_tools/src/runner/flutter_command_runner.dart:232:5)
<asynchronous suspension>
#12 run.<anonymous closure>.<anonymous closure> (package:flutter_tools/runner.dart:62:9)
<asynchronous suspension>
#13 AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
<asynchronous suspension>
#14 main (package:flutter_tools/executable.dart:91:3)
<asynchronous suspension>
[ +13 ms] "flutter assemble" took 16,412ms.
[ +4 ms]
#0 throwToolExit (package:flutter_tools/src/base/common.dart:10:3)
#1 AssembleCommand.runCommand (package:flutter_tools/src/commands/assemble.dart:335:7)
<asynchronous suspension>
#2 FlutterCommand.run.<anonymous closure> (package:flutter_tools/src/runner/flutter_command.dart:1043:27)
<asynchronous suspension>
#3 AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
<asynchronous suspension>
#4 CommandRunner.runCommand (package:args/command_runner.dart:196:13)
<asynchronous suspension>
#5 FlutterCommandRunner.runCommand.<anonymous closure> (package:flutter_tools/src/runner/flutter_command_runner.dart:284:9)
<asynchronous suspension>
#6 AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
<asynchronous suspension>
#7 FlutterCommandRunner.runCommand (package:flutter_tools/src/runner/flutter_command_runner.dart:232:5)
<asynchronous suspension>
#8 run.<anonymous closure>.<anonymous closure> (package:flutter_tools/runner.dart:62:9)
<asynchronous suspension>
#9 AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
<asynchronous suspension>
#10 main (package:flutter_tools/executable.dart:91:3)
<asynchronous suspension>
Error occurs running this assemble command:
$ ../flojure-engine/src/out/host_debug_unopt/dart-sdk/bin/dart \
--disable-dart-dev ../flojure-engine/src/out/host_debug_unopt/gen/frontend_server.dart.snapshot \
--sdk-root ../flojure-engine/src/out/ios_debug_sim_unopt/flutter_patched_sdk/ \
--target=flutter --no-print-incremental-dependencies -DFLUTTER_WEB_AUTO_DETECT=true \
-Ddart.vm.profile=false -Ddart.vm.product=false --enable-asserts --track-widget-creation \
--no-link-platform \
--packages /Users/johnmcconnell/dev/github.com/johnmcconnell/flojure-example-app/.dart_tool/package_config.json \
--output-dill /Users/johnmcconnell/dev/github.com/johnmcconnell/flojure-example-app/.dart_tool/flutter_build/a5b6813f1f6085abf8595dcd34b5ad4f/app.dill \
--depfile /Users/johnmcconnell/dev/github.com/johnmcconnell/flojure-example-app/.dart_tool/flutter_build/a5b6813f1f6085abf8595dcd34b5ad4f/kernel_snapshot.d package:flojure_example_app/main.dart
However, it is still able to create an app.dill which can be run via:
dart run .dart_tool/flutter_build/a5b6813f1f6085abf8595dcd34b5ad4f/app.dill
Unhandled exception:
'package:flojure_example_app/main.dart': error: lib/main.dart:4:13: Error: Getter not found: 'foobar'.
final x = foobar;
^^^^^^
#0 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:283:19)
#1 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
So it looks like both compilation and runtime fail.
The assemble command is using the host_debug_unopt sdk . Rebuilding the host_debug_unopt sdk with latest language modifications worked as expected:
import 'package:flutter/material.dart';
void main() {
final x = foobar;
print('hello world!: $x');
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
final x = foobar;
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page: $x'),
);
}
}
Comments
Post a Comment