rbs 4.1.0.pre.2-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.clang-format +75 -0
- data/.clangd +2 -0
- data/.github/dependabot.yml +24 -0
- data/.github/workflows/bundle-update.yml +63 -0
- data/.github/workflows/c-check.yml +61 -0
- data/.github/workflows/comments.yml +37 -0
- data/.github/workflows/dependabot.yml +30 -0
- data/.github/workflows/jruby.yml +67 -0
- data/.github/workflows/milestone.yml +83 -0
- data/.github/workflows/ruby.yml +158 -0
- data/.github/workflows/rust.yml +184 -0
- data/.github/workflows/truffleruby.yml +54 -0
- data/.github/workflows/typecheck.yml +39 -0
- data/.github/workflows/wasm.yml +53 -0
- data/.github/workflows/windows.yml +49 -0
- data/.gitignore +38 -0
- data/.rubocop.yml +72 -0
- data/BSDL +22 -0
- data/CHANGELOG.md +2292 -0
- data/COPYING +56 -0
- data/README.md +240 -0
- data/Rakefile +869 -0
- data/Steepfile +53 -0
- data/config.yml +913 -0
- data/core/array.rbs +4142 -0
- data/core/basic_object.rbs +376 -0
- data/core/binding.rbs +148 -0
- data/core/builtin.rbs +278 -0
- data/core/class.rbs +223 -0
- data/core/comparable.rbs +192 -0
- data/core/complex.rbs +812 -0
- data/core/constants.rbs +96 -0
- data/core/data.rbs +415 -0
- data/core/dir.rbs +993 -0
- data/core/encoding.rbs +1368 -0
- data/core/enumerable.rbs +2506 -0
- data/core/enumerator/arithmetic_sequence.rbs +70 -0
- data/core/enumerator/product.rbs +92 -0
- data/core/enumerator.rbs +705 -0
- data/core/env.rbs +6 -0
- data/core/errno.rbs +682 -0
- data/core/errors.rbs +789 -0
- data/core/exception.rbs +485 -0
- data/core/false_class.rbs +82 -0
- data/core/fiber.rbs +570 -0
- data/core/fiber_error.rbs +11 -0
- data/core/file.rbs +2045 -0
- data/core/file_constants.rbs +463 -0
- data/core/file_stat.rbs +534 -0
- data/core/file_test.rbs +331 -0
- data/core/float.rbs +1316 -0
- data/core/gc.rbs +788 -0
- data/core/global_variables.rbs +184 -0
- data/core/hash.rbs +2183 -0
- data/core/integer.rbs +1374 -0
- data/core/io/buffer.rbs +995 -0
- data/core/io/wait.rbs +48 -0
- data/core/io.rbs +3472 -0
- data/core/kernel.rbs +3172 -0
- data/core/marshal.rbs +207 -0
- data/core/match_data.rbs +637 -0
- data/core/math.rbs +770 -0
- data/core/method.rbs +422 -0
- data/core/module.rbs +1856 -0
- data/core/nil_class.rbs +210 -0
- data/core/numeric.rbs +832 -0
- data/core/object.rbs +108 -0
- data/core/object_space/weak_key_map.rbs +166 -0
- data/core/object_space.rbs +197 -0
- data/core/pathname.rbs +1322 -0
- data/core/proc.rbs +905 -0
- data/core/process.rbs +2316 -0
- data/core/ractor.rbs +924 -0
- data/core/random.rbs +255 -0
- data/core/range.rbs +1209 -0
- data/core/rational.rbs +502 -0
- data/core/rb_config.rbs +88 -0
- data/core/rbs/ops.rbs +154 -0
- data/core/rbs/unnamed/argf.rbs +1236 -0
- data/core/rbs/unnamed/env_class.rbs +1214 -0
- data/core/rbs/unnamed/main_class.rbs +123 -0
- data/core/rbs/unnamed/random.rbs +186 -0
- data/core/refinement.rbs +59 -0
- data/core/regexp.rbs +1974 -0
- data/core/ruby.rbs +53 -0
- data/core/ruby_vm.rbs +809 -0
- data/core/rubygems/basic_specification.rbs +6 -0
- data/core/rubygems/config_file.rbs +38 -0
- data/core/rubygems/dependency_installer.rbs +6 -0
- data/core/rubygems/errors.rbs +109 -0
- data/core/rubygems/installer.rbs +15 -0
- data/core/rubygems/path_support.rbs +6 -0
- data/core/rubygems/platform.rbs +7 -0
- data/core/rubygems/request_set.rbs +49 -0
- data/core/rubygems/requirement.rbs +148 -0
- data/core/rubygems/rubygems.rbs +1105 -0
- data/core/rubygems/source_list.rbs +15 -0
- data/core/rubygems/specification.rbs +23 -0
- data/core/rubygems/stream_ui.rbs +5 -0
- data/core/rubygems/uninstaller.rbs +10 -0
- data/core/rubygems/version.rbs +293 -0
- data/core/set.rbs +751 -0
- data/core/signal.rbs +110 -0
- data/core/string.rbs +5532 -0
- data/core/struct.rbs +668 -0
- data/core/symbol.rbs +482 -0
- data/core/thread.rbs +1826 -0
- data/core/thread_group.rbs +79 -0
- data/core/time.rbs +1793 -0
- data/core/trace_point.rbs +483 -0
- data/core/true_class.rbs +98 -0
- data/core/unbound_method.rbs +337 -0
- data/core/warning.rbs +87 -0
- data/docs/CONTRIBUTING.md +107 -0
- data/docs/aliases.md +79 -0
- data/docs/architecture.md +110 -0
- data/docs/collection.md +192 -0
- data/docs/config.md +171 -0
- data/docs/data_and_struct.md +86 -0
- data/docs/encoding.md +56 -0
- data/docs/gem.md +56 -0
- data/docs/inline.md +634 -0
- data/docs/rbs_by_example.md +309 -0
- data/docs/repo.md +125 -0
- data/docs/rust.md +96 -0
- data/docs/sigs.md +167 -0
- data/docs/stdlib.md +147 -0
- data/docs/syntax.md +940 -0
- data/docs/tools.md +17 -0
- data/docs/type_fingerprint.md +21 -0
- data/docs/wasm_serialization.md +80 -0
- data/exe/rbs +7 -0
- data/ext/rbs_extension/ast_translation.c +1855 -0
- data/ext/rbs_extension/ast_translation.h +41 -0
- data/ext/rbs_extension/class_constants.c +187 -0
- data/ext/rbs_extension/class_constants.h +104 -0
- data/ext/rbs_extension/compat.h +10 -0
- data/ext/rbs_extension/extconf.rb +40 -0
- data/ext/rbs_extension/legacy_location.c +294 -0
- data/ext/rbs_extension/legacy_location.h +82 -0
- data/ext/rbs_extension/main.c +613 -0
- data/ext/rbs_extension/rbs_extension.h +16 -0
- data/ext/rbs_extension/rbs_string_bridging.c +9 -0
- data/ext/rbs_extension/rbs_string_bridging.h +24 -0
- data/goodcheck.yml +91 -0
- data/include/rbs/ast.h +1047 -0
- data/include/rbs/defines.h +99 -0
- data/include/rbs/lexer.h +207 -0
- data/include/rbs/location.h +40 -0
- data/include/rbs/parser.h +153 -0
- data/include/rbs/serialize.h +39 -0
- data/include/rbs/string.h +47 -0
- data/include/rbs/util/rbs_allocator.h +59 -0
- data/include/rbs/util/rbs_assert.h +20 -0
- data/include/rbs/util/rbs_buffer.h +83 -0
- data/include/rbs/util/rbs_constant_pool.h +155 -0
- data/include/rbs/util/rbs_encoding.h +282 -0
- data/include/rbs/util/rbs_unescape.h +24 -0
- data/include/rbs.h +14 -0
- data/lib/rbs/ancestor_graph.rb +92 -0
- data/lib/rbs/annotate/annotations.rb +199 -0
- data/lib/rbs/annotate/formatter.rb +82 -0
- data/lib/rbs/annotate/rdoc_annotator.rb +398 -0
- data/lib/rbs/annotate/rdoc_source.rb +131 -0
- data/lib/rbs/annotate.rb +8 -0
- data/lib/rbs/ast/annotation.rb +29 -0
- data/lib/rbs/ast/comment.rb +29 -0
- data/lib/rbs/ast/declarations.rb +472 -0
- data/lib/rbs/ast/directives.rb +49 -0
- data/lib/rbs/ast/members.rb +451 -0
- data/lib/rbs/ast/ruby/annotations.rb +451 -0
- data/lib/rbs/ast/ruby/comment_block.rb +247 -0
- data/lib/rbs/ast/ruby/declarations.rb +291 -0
- data/lib/rbs/ast/ruby/helpers/constant_helper.rb +28 -0
- data/lib/rbs/ast/ruby/helpers/location_helper.rb +15 -0
- data/lib/rbs/ast/ruby/members.rb +762 -0
- data/lib/rbs/ast/type_param.rb +235 -0
- data/lib/rbs/ast/visitor.rb +137 -0
- data/lib/rbs/buffer.rb +189 -0
- data/lib/rbs/builtin_names.rb +58 -0
- data/lib/rbs/cli/colored_io.rb +48 -0
- data/lib/rbs/cli/diff.rb +84 -0
- data/lib/rbs/cli/validate.rb +294 -0
- data/lib/rbs/cli.rb +1253 -0
- data/lib/rbs/collection/cleaner.rb +38 -0
- data/lib/rbs/collection/config/lockfile.rb +92 -0
- data/lib/rbs/collection/config/lockfile_generator.rb +269 -0
- data/lib/rbs/collection/config.rb +81 -0
- data/lib/rbs/collection/installer.rb +32 -0
- data/lib/rbs/collection/sources/base.rb +14 -0
- data/lib/rbs/collection/sources/git.rb +265 -0
- data/lib/rbs/collection/sources/local.rb +81 -0
- data/lib/rbs/collection/sources/rubygems.rb +48 -0
- data/lib/rbs/collection/sources/stdlib.rb +50 -0
- data/lib/rbs/collection/sources.rb +38 -0
- data/lib/rbs/collection.rb +16 -0
- data/lib/rbs/constant.rb +28 -0
- data/lib/rbs/definition.rb +415 -0
- data/lib/rbs/definition_builder/ancestor_builder.rb +678 -0
- data/lib/rbs/definition_builder/method_builder.rb +295 -0
- data/lib/rbs/definition_builder.rb +1054 -0
- data/lib/rbs/diff.rb +131 -0
- data/lib/rbs/environment/class_entry.rb +69 -0
- data/lib/rbs/environment/module_entry.rb +66 -0
- data/lib/rbs/environment/use_map.rb +77 -0
- data/lib/rbs/environment.rb +1028 -0
- data/lib/rbs/environment_loader.rb +167 -0
- data/lib/rbs/environment_walker.rb +155 -0
- data/lib/rbs/errors.rb +634 -0
- data/lib/rbs/factory.rb +18 -0
- data/lib/rbs/file_finder.rb +28 -0
- data/lib/rbs/inline_parser/comment_association.rb +117 -0
- data/lib/rbs/inline_parser.rb +568 -0
- data/lib/rbs/location_aux.rb +170 -0
- data/lib/rbs/locator.rb +247 -0
- data/lib/rbs/method_type.rb +145 -0
- data/lib/rbs/namespace.rb +154 -0
- data/lib/rbs/parser/lex_result.rb +15 -0
- data/lib/rbs/parser/token.rb +23 -0
- data/lib/rbs/parser_aux.rb +142 -0
- data/lib/rbs/prototype/helpers.rb +197 -0
- data/lib/rbs/prototype/node_usage.rb +99 -0
- data/lib/rbs/prototype/rb.rb +816 -0
- data/lib/rbs/prototype/rbi.rb +625 -0
- data/lib/rbs/prototype/runtime/helpers.rb +59 -0
- data/lib/rbs/prototype/runtime/reflection.rb +19 -0
- data/lib/rbs/prototype/runtime/value_object_generator.rb +279 -0
- data/lib/rbs/prototype/runtime.rb +680 -0
- data/lib/rbs/repository.rb +127 -0
- data/lib/rbs/resolver/constant_resolver.rb +219 -0
- data/lib/rbs/resolver/type_name_resolver.rb +167 -0
- data/lib/rbs/rewriter.rb +70 -0
- data/lib/rbs/sorter.rb +198 -0
- data/lib/rbs/source.rb +99 -0
- data/lib/rbs/substitution.rb +83 -0
- data/lib/rbs/subtractor.rb +204 -0
- data/lib/rbs/test/errors.rb +80 -0
- data/lib/rbs/test/guaranteed.rb +30 -0
- data/lib/rbs/test/hook.rb +212 -0
- data/lib/rbs/test/observer.rb +19 -0
- data/lib/rbs/test/setup.rb +84 -0
- data/lib/rbs/test/setup_helper.rb +50 -0
- data/lib/rbs/test/tester.rb +167 -0
- data/lib/rbs/test/type_check.rb +457 -0
- data/lib/rbs/test.rb +112 -0
- data/lib/rbs/type_alias_dependency.rb +100 -0
- data/lib/rbs/type_alias_regularity.rb +126 -0
- data/lib/rbs/type_name.rb +122 -0
- data/lib/rbs/types.rb +1604 -0
- data/lib/rbs/unit_test/convertibles.rb +177 -0
- data/lib/rbs/unit_test/spy.rb +138 -0
- data/lib/rbs/unit_test/type_assertions.rb +383 -0
- data/lib/rbs/unit_test/with_aliases.rb +145 -0
- data/lib/rbs/unit_test.rb +6 -0
- data/lib/rbs/validator.rb +186 -0
- data/lib/rbs/variance_calculator.rb +189 -0
- data/lib/rbs/vendorer.rb +71 -0
- data/lib/rbs/version.rb +5 -0
- data/lib/rbs/wasm/deserializer.rb +213 -0
- data/lib/rbs/wasm/jars/asm-analysis.jar +0 -0
- data/lib/rbs/wasm/jars/asm-commons.jar +0 -0
- data/lib/rbs/wasm/jars/asm-tree.jar +0 -0
- data/lib/rbs/wasm/jars/asm-util.jar +0 -0
- data/lib/rbs/wasm/jars/asm.jar +0 -0
- data/lib/rbs/wasm/jars/compiler.jar +0 -0
- data/lib/rbs/wasm/jars/log.jar +0 -0
- data/lib/rbs/wasm/jars/runtime.jar +0 -0
- data/lib/rbs/wasm/jars/wasi.jar +0 -0
- data/lib/rbs/wasm/jars/wasm.jar +0 -0
- data/lib/rbs/wasm/location.rb +61 -0
- data/lib/rbs/wasm/parser.rb +137 -0
- data/lib/rbs/wasm/rbs_parser.wasm +0 -0
- data/lib/rbs/wasm/runtime.rb +217 -0
- data/lib/rbs/wasm/serialization_schema.rb +110 -0
- data/lib/rbs/writer.rb +424 -0
- data/lib/rbs.rb +117 -0
- data/lib/rdoc/discover.rb +20 -0
- data/lib/rdoc_plugin/parser.rb +163 -0
- data/rbs.gemspec +68 -0
- data/schema/annotation.json +14 -0
- data/schema/comment.json +26 -0
- data/schema/decls.json +326 -0
- data/schema/function.json +87 -0
- data/schema/location.json +56 -0
- data/schema/members.json +266 -0
- data/schema/methodType.json +50 -0
- data/schema/typeParam.json +52 -0
- data/schema/types.json +317 -0
- data/sig/ancestor_builder.rbs +163 -0
- data/sig/ancestor_graph.rbs +60 -0
- data/sig/annotate/annotations.rbs +102 -0
- data/sig/annotate/formatter.rbs +24 -0
- data/sig/annotate/rdoc_annotater.rbs +85 -0
- data/sig/annotate/rdoc_source.rbs +32 -0
- data/sig/annotation.rbs +27 -0
- data/sig/ast/ruby/annotations.rbs +470 -0
- data/sig/ast/ruby/comment_block.rbs +127 -0
- data/sig/ast/ruby/declarations.rbs +158 -0
- data/sig/ast/ruby/helpers/constant_helper.rbs +11 -0
- data/sig/ast/ruby/helpers/location_helper.rbs +15 -0
- data/sig/ast/ruby/members.rbs +198 -0
- data/sig/buffer.rbs +108 -0
- data/sig/builtin_names.rbs +44 -0
- data/sig/cli/colored_io.rbs +15 -0
- data/sig/cli/diff.rbs +15 -0
- data/sig/cli/validate.rbs +47 -0
- data/sig/cli.rbs +89 -0
- data/sig/collection/cleaner.rbs +13 -0
- data/sig/collection/config/lockfile.rbs +74 -0
- data/sig/collection/config/lockfile_generator.rbs +68 -0
- data/sig/collection/config.rbs +46 -0
- data/sig/collection/installer.rbs +17 -0
- data/sig/collection/sources.rbs +214 -0
- data/sig/collection.rbs +4 -0
- data/sig/comment.rbs +26 -0
- data/sig/constant.rbs +21 -0
- data/sig/declarations.rbs +274 -0
- data/sig/definition.rbs +232 -0
- data/sig/definition_builder.rbs +181 -0
- data/sig/diff.rbs +28 -0
- data/sig/directives.rbs +77 -0
- data/sig/environment/class_entry.rbs +50 -0
- data/sig/environment/module_entry.rbs +50 -0
- data/sig/environment.rbs +286 -0
- data/sig/environment_loader.rbs +111 -0
- data/sig/environment_walker.rbs +65 -0
- data/sig/errors.rbs +408 -0
- data/sig/factory.rbs +5 -0
- data/sig/file_finder.rbs +28 -0
- data/sig/inline_parser/comment_association.rbs +71 -0
- data/sig/inline_parser.rbs +126 -0
- data/sig/location.rbs +135 -0
- data/sig/locator.rbs +56 -0
- data/sig/manifest.yaml +5 -0
- data/sig/members.rbs +258 -0
- data/sig/method_builder.rbs +89 -0
- data/sig/method_types.rbs +58 -0
- data/sig/namespace.rbs +161 -0
- data/sig/parser.rbs +164 -0
- data/sig/prototype/helpers.rbs +29 -0
- data/sig/prototype/node_usage.rbs +20 -0
- data/sig/prototype/rb.rbs +96 -0
- data/sig/prototype/rbi.rbs +75 -0
- data/sig/prototype/runtime.rbs +182 -0
- data/sig/rbs.rbs +21 -0
- data/sig/rdoc/rbs.rbs +67 -0
- data/sig/repository.rbs +85 -0
- data/sig/resolver/constant_resolver.rbs +92 -0
- data/sig/resolver/context.rbs +34 -0
- data/sig/resolver/type_name_resolver.rbs +61 -0
- data/sig/rewriter.rbs +45 -0
- data/sig/shims/bundler.rbs +38 -0
- data/sig/shims/enumerable.rbs +5 -0
- data/sig/shims/rubygems.rbs +19 -0
- data/sig/sorter.rbs +41 -0
- data/sig/source.rbs +48 -0
- data/sig/substitution.rbs +48 -0
- data/sig/subtractor.rbs +37 -0
- data/sig/test/errors.rbs +52 -0
- data/sig/test/guranteed.rbs +9 -0
- data/sig/test/type_check.rbs +19 -0
- data/sig/test.rbs +82 -0
- data/sig/type_alias_dependency.rbs +53 -0
- data/sig/type_alias_regularity.rbs +98 -0
- data/sig/type_param.rbs +115 -0
- data/sig/typename.rbs +89 -0
- data/sig/types.rbs +578 -0
- data/sig/unit_test/convertibles.rbs +154 -0
- data/sig/unit_test/spy.rbs +22 -0
- data/sig/unit_test/type_assertions.rbs +211 -0
- data/sig/unit_test/with_aliases.rbs +136 -0
- data/sig/use_map.rbs +35 -0
- data/sig/util.rbs +9 -0
- data/sig/validator.rbs +63 -0
- data/sig/variance_calculator.rbs +87 -0
- data/sig/vendorer.rbs +51 -0
- data/sig/version.rbs +3 -0
- data/sig/visitor.rbs +47 -0
- data/sig/wasm/deserializer.rbs +66 -0
- data/sig/wasm/serialization_schema.rbs +13 -0
- data/sig/writer.rbs +127 -0
- data/src/ast.c +1628 -0
- data/src/lexer.c +3217 -0
- data/src/lexer.re +155 -0
- data/src/lexstate.c +217 -0
- data/src/location.c +31 -0
- data/src/parser.c +4255 -0
- data/src/serialize.c +958 -0
- data/src/string.c +41 -0
- data/src/util/rbs_allocator.c +162 -0
- data/src/util/rbs_assert.c +19 -0
- data/src/util/rbs_buffer.c +54 -0
- data/src/util/rbs_constant_pool.c +268 -0
- data/src/util/rbs_encoding.c +21308 -0
- data/src/util/rbs_unescape.c +167 -0
- data/stdlib/abbrev/0/abbrev.rbs +66 -0
- data/stdlib/abbrev/0/array.rbs +26 -0
- data/stdlib/base64/0/base64.rbs +355 -0
- data/stdlib/benchmark/0/benchmark.rbs +452 -0
- data/stdlib/bigdecimal/0/big_decimal.rbs +1647 -0
- data/stdlib/bigdecimal-math/0/big_math.rbs +280 -0
- data/stdlib/bigdecimal-math/0/manifest.yaml +2 -0
- data/stdlib/cgi/0/core.rbs +911 -0
- data/stdlib/cgi/0/manifest.yaml +4 -0
- data/stdlib/cgi-escape/0/escape.rbs +171 -0
- data/stdlib/coverage/0/coverage.rbs +266 -0
- data/stdlib/csv/0/csv.rbs +3776 -0
- data/stdlib/csv/0/manifest.yaml +3 -0
- data/stdlib/date/0/date.rbs +1598 -0
- data/stdlib/date/0/date_time.rbs +617 -0
- data/stdlib/date/0/time.rbs +26 -0
- data/stdlib/dbm/0/dbm.rbs +421 -0
- data/stdlib/delegate/0/delegator.rbs +187 -0
- data/stdlib/delegate/0/kernel.rbs +47 -0
- data/stdlib/delegate/0/simple_delegator.rbs +96 -0
- data/stdlib/did_you_mean/0/did_you_mean.rbs +344 -0
- data/stdlib/digest/0/digest.rbs +687 -0
- data/stdlib/erb/0/erb.rbs +933 -0
- data/stdlib/etc/0/etc.rbs +884 -0
- data/stdlib/fileutils/0/fileutils.rbs +1753 -0
- data/stdlib/find/0/find.rbs +49 -0
- data/stdlib/forwardable/0/forwardable.rbs +271 -0
- data/stdlib/io-console/0/io-console.rbs +414 -0
- data/stdlib/ipaddr/0/ipaddr.rbs +436 -0
- data/stdlib/json/0/json.rbs +1963 -0
- data/stdlib/kconv/0/kconv.rbs +166 -0
- data/stdlib/logger/0/formatter.rbs +45 -0
- data/stdlib/logger/0/log_device.rbs +100 -0
- data/stdlib/logger/0/logger.rbs +796 -0
- data/stdlib/logger/0/manifest.yaml +2 -0
- data/stdlib/logger/0/period.rbs +17 -0
- data/stdlib/logger/0/severity.rbs +34 -0
- data/stdlib/minitest/0/kernel.rbs +42 -0
- data/stdlib/minitest/0/minitest/abstract_reporter.rbs +52 -0
- data/stdlib/minitest/0/minitest/assertion.rbs +17 -0
- data/stdlib/minitest/0/minitest/assertions.rbs +590 -0
- data/stdlib/minitest/0/minitest/backtrace_filter.rbs +23 -0
- data/stdlib/minitest/0/minitest/bench_spec.rbs +102 -0
- data/stdlib/minitest/0/minitest/benchmark.rbs +259 -0
- data/stdlib/minitest/0/minitest/composite_reporter.rbs +25 -0
- data/stdlib/minitest/0/minitest/compress.rbs +13 -0
- data/stdlib/minitest/0/minitest/error_on_warning.rbs +3 -0
- data/stdlib/minitest/0/minitest/expectation.rbs +2 -0
- data/stdlib/minitest/0/minitest/expectations.rbs +21 -0
- data/stdlib/minitest/0/minitest/guard.rbs +64 -0
- data/stdlib/minitest/0/minitest/mock.rbs +64 -0
- data/stdlib/minitest/0/minitest/parallel/executor.rbs +46 -0
- data/stdlib/minitest/0/minitest/parallel/test/class_methods.rbs +5 -0
- data/stdlib/minitest/0/minitest/parallel/test.rbs +3 -0
- data/stdlib/minitest/0/minitest/parallel.rbs +2 -0
- data/stdlib/minitest/0/minitest/pride_io.rbs +62 -0
- data/stdlib/minitest/0/minitest/pride_lol.rbs +19 -0
- data/stdlib/minitest/0/minitest/progress_reporter.rbs +11 -0
- data/stdlib/minitest/0/minitest/reportable.rbs +53 -0
- data/stdlib/minitest/0/minitest/reporter.rbs +5 -0
- data/stdlib/minitest/0/minitest/result.rbs +28 -0
- data/stdlib/minitest/0/minitest/runnable.rbs +163 -0
- data/stdlib/minitest/0/minitest/skip.rbs +6 -0
- data/stdlib/minitest/0/minitest/spec/dsl/instance_methods.rbs +48 -0
- data/stdlib/minitest/0/minitest/spec/dsl.rbs +129 -0
- data/stdlib/minitest/0/minitest/spec.rbs +11 -0
- data/stdlib/minitest/0/minitest/statistics_reporter.rbs +81 -0
- data/stdlib/minitest/0/minitest/summary_reporter.rbs +18 -0
- data/stdlib/minitest/0/minitest/test/lifecycle_hooks.rbs +92 -0
- data/stdlib/minitest/0/minitest/test.rbs +69 -0
- data/stdlib/minitest/0/minitest/unexpected_error.rbs +12 -0
- data/stdlib/minitest/0/minitest/unexpected_warning.rbs +6 -0
- data/stdlib/minitest/0/minitest/unit/test_case.rbs +3 -0
- data/stdlib/minitest/0/minitest/unit.rbs +4 -0
- data/stdlib/minitest/0/minitest.rbs +115 -0
- data/stdlib/monitor/0/monitor.rbs +363 -0
- data/stdlib/mutex_m/0/mutex_m.rbs +104 -0
- data/stdlib/net-http/0/manifest.yaml +3 -0
- data/stdlib/net-http/0/net-http.rbs +5580 -0
- data/stdlib/net-protocol/0/manifest.yaml +2 -0
- data/stdlib/net-protocol/0/net-protocol.rbs +56 -0
- data/stdlib/net-smtp/0/manifest.yaml +2 -0
- data/stdlib/net-smtp/0/net-smtp.rbs +55 -0
- data/stdlib/nkf/0/nkf.rbs +402 -0
- data/stdlib/objspace/0/objspace.rbs +470 -0
- data/stdlib/observable/0/observable.rbs +217 -0
- data/stdlib/open-uri/0/manifest.yaml +4 -0
- data/stdlib/open-uri/0/open-uri.rbs +433 -0
- data/stdlib/open3/0/open3.rbs +606 -0
- data/stdlib/openssl/0/manifest.yaml +3 -0
- data/stdlib/openssl/0/openssl.rbs +12231 -0
- data/stdlib/optparse/0/optparse.rbs +1734 -0
- data/stdlib/pathname/0/pathname.rbs +36 -0
- data/stdlib/pp/0/manifest.yaml +2 -0
- data/stdlib/pp/0/pp.rbs +301 -0
- data/stdlib/prettyprint/0/prettyprint.rbs +383 -0
- data/stdlib/pstore/0/pstore.rbs +608 -0
- data/stdlib/psych/0/core_ext.rbs +12 -0
- data/stdlib/psych/0/dbm.rbs +237 -0
- data/stdlib/psych/0/manifest.yaml +3 -0
- data/stdlib/psych/0/psych.rbs +455 -0
- data/stdlib/psych/0/store.rbs +57 -0
- data/stdlib/pty/0/pty.rbs +240 -0
- data/stdlib/random-formatter/0/random-formatter.rbs +277 -0
- data/stdlib/rdoc/0/code_object.rbs +52 -0
- data/stdlib/rdoc/0/comment.rbs +61 -0
- data/stdlib/rdoc/0/context.rbs +153 -0
- data/stdlib/rdoc/0/markup.rbs +117 -0
- data/stdlib/rdoc/0/options.rbs +76 -0
- data/stdlib/rdoc/0/parser.rbs +56 -0
- data/stdlib/rdoc/0/rdoc.rbs +393 -0
- data/stdlib/rdoc/0/ri.rbs +17 -0
- data/stdlib/rdoc/0/store.rbs +48 -0
- data/stdlib/rdoc/0/top_level.rbs +97 -0
- data/stdlib/resolv/0/manifest.yaml +3 -0
- data/stdlib/resolv/0/resolv.rbs +1787 -0
- data/stdlib/ripper/0/ripper.rbs +1654 -0
- data/stdlib/securerandom/0/manifest.yaml +2 -0
- data/stdlib/securerandom/0/securerandom.rbs +49 -0
- data/stdlib/shellwords/0/shellwords.rbs +229 -0
- data/stdlib/singleton/0/singleton.rbs +134 -0
- data/stdlib/socket/0/addrinfo.rbs +666 -0
- data/stdlib/socket/0/basic_socket.rbs +590 -0
- data/stdlib/socket/0/constants.rbs +2295 -0
- data/stdlib/socket/0/ip_socket.rbs +94 -0
- data/stdlib/socket/0/socket.rbs +4170 -0
- data/stdlib/socket/0/socket_error.rbs +5 -0
- data/stdlib/socket/0/tcp_server.rbs +192 -0
- data/stdlib/socket/0/tcp_socket.rbs +87 -0
- data/stdlib/socket/0/udp_socket.rbs +133 -0
- data/stdlib/socket/0/unix_server.rbs +169 -0
- data/stdlib/socket/0/unix_socket.rbs +172 -0
- data/stdlib/stringio/0/stringio.rbs +1681 -0
- data/stdlib/strscan/0/string_scanner.rbs +1648 -0
- data/stdlib/tempfile/0/tempfile.rbs +483 -0
- data/stdlib/time/0/time.rbs +434 -0
- data/stdlib/timeout/0/timeout.rbs +137 -0
- data/stdlib/tmpdir/0/tmpdir.rbs +69 -0
- data/stdlib/tsort/0/cyclic.rbs +8 -0
- data/stdlib/tsort/0/interfaces.rbs +20 -0
- data/stdlib/tsort/0/tsort.rbs +410 -0
- data/stdlib/uri/0/common.rbs +621 -0
- data/stdlib/uri/0/file.rbs +118 -0
- data/stdlib/uri/0/ftp.rbs +13 -0
- data/stdlib/uri/0/generic.rbs +1116 -0
- data/stdlib/uri/0/http.rbs +104 -0
- data/stdlib/uri/0/https.rbs +14 -0
- data/stdlib/uri/0/ldap.rbs +230 -0
- data/stdlib/uri/0/ldaps.rbs +14 -0
- data/stdlib/uri/0/mailto.rbs +92 -0
- data/stdlib/uri/0/rfc2396_parser.rbs +189 -0
- data/stdlib/uri/0/rfc3986_parser.rbs +2 -0
- data/stdlib/uri/0/ws.rbs +13 -0
- data/stdlib/uri/0/wss.rbs +9 -0
- data/stdlib/yaml/0/manifest.yaml +2 -0
- data/stdlib/yaml/0/yaml.rbs +1 -0
- data/stdlib/zlib/0/buf_error.rbs +10 -0
- data/stdlib/zlib/0/data_error.rbs +10 -0
- data/stdlib/zlib/0/deflate.rbs +211 -0
- data/stdlib/zlib/0/error.rbs +20 -0
- data/stdlib/zlib/0/gzip_file/crc_error.rbs +12 -0
- data/stdlib/zlib/0/gzip_file/error.rbs +23 -0
- data/stdlib/zlib/0/gzip_file/length_error.rbs +12 -0
- data/stdlib/zlib/0/gzip_file/no_footer.rbs +11 -0
- data/stdlib/zlib/0/gzip_file.rbs +156 -0
- data/stdlib/zlib/0/gzip_reader.rbs +293 -0
- data/stdlib/zlib/0/gzip_writer.rbs +168 -0
- data/stdlib/zlib/0/inflate.rbs +180 -0
- data/stdlib/zlib/0/mem_error.rbs +10 -0
- data/stdlib/zlib/0/need_dict.rbs +13 -0
- data/stdlib/zlib/0/stream_end.rbs +11 -0
- data/stdlib/zlib/0/stream_error.rbs +11 -0
- data/stdlib/zlib/0/version_error.rbs +11 -0
- data/stdlib/zlib/0/zlib.rbs +449 -0
- data/stdlib/zlib/0/zstream.rbs +201 -0
- data/wasm/README.md +59 -0
- data/wasm/rbs_wasm.c +411 -0
- metadata +660 -0
data/src/parser.c
ADDED
|
@@ -0,0 +1,4255 @@
|
|
|
1
|
+
#include "rbs/parser.h"
|
|
2
|
+
|
|
3
|
+
#include <stdlib.h>
|
|
4
|
+
#include <stdarg.h>
|
|
5
|
+
#include <stdio.h>
|
|
6
|
+
#include <ctype.h>
|
|
7
|
+
#include <string.h>
|
|
8
|
+
|
|
9
|
+
#include "rbs/ast.h"
|
|
10
|
+
#include "rbs/defines.h"
|
|
11
|
+
#include "rbs/lexer.h"
|
|
12
|
+
#include "rbs/location.h"
|
|
13
|
+
#include "rbs/string.h"
|
|
14
|
+
#include "rbs/util/rbs_unescape.h"
|
|
15
|
+
#include "rbs/util/rbs_buffer.h"
|
|
16
|
+
#include "rbs/util/rbs_assert.h"
|
|
17
|
+
|
|
18
|
+
#define INTERN_TOKEN(parser, tok) \
|
|
19
|
+
rbs_constant_pool_insert_shared_with_encoding( \
|
|
20
|
+
&parser->constant_pool, \
|
|
21
|
+
(const uint8_t *) rbs_peek_token(parser->lexer, tok), \
|
|
22
|
+
rbs_token_bytes(tok), \
|
|
23
|
+
parser->lexer->encoding \
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
#define KEYWORD_CASES \
|
|
27
|
+
case kBOOL: \
|
|
28
|
+
case kBOT: \
|
|
29
|
+
case kCLASS: \
|
|
30
|
+
case kFALSE: \
|
|
31
|
+
case kINSTANCE: \
|
|
32
|
+
case kINTERFACE: \
|
|
33
|
+
case kNIL: \
|
|
34
|
+
case kSELF: \
|
|
35
|
+
case kSINGLETON: \
|
|
36
|
+
case kTOP: \
|
|
37
|
+
case kTRUE: \
|
|
38
|
+
case kVOID: \
|
|
39
|
+
case kTYPE: \
|
|
40
|
+
case kUNCHECKED: \
|
|
41
|
+
case kIN: \
|
|
42
|
+
case kOUT: \
|
|
43
|
+
case kEND: \
|
|
44
|
+
case kDEF: \
|
|
45
|
+
case kINCLUDE: \
|
|
46
|
+
case kEXTEND: \
|
|
47
|
+
case kPREPEND: \
|
|
48
|
+
case kALIAS: \
|
|
49
|
+
case kMODULE: \
|
|
50
|
+
case kATTRREADER: \
|
|
51
|
+
case kATTRWRITER: \
|
|
52
|
+
case kATTRACCESSOR: \
|
|
53
|
+
case kPUBLIC: \
|
|
54
|
+
case kPRIVATE: \
|
|
55
|
+
case kUNTYPED: \
|
|
56
|
+
case kUSE: \
|
|
57
|
+
case kAS: \
|
|
58
|
+
case k__TODO__: \
|
|
59
|
+
case kSKIP: \
|
|
60
|
+
case kRETURN: \
|
|
61
|
+
/* nop */
|
|
62
|
+
|
|
63
|
+
#define PARAM_NAME_CASES \
|
|
64
|
+
case kBOOL: \
|
|
65
|
+
case kBOT: \
|
|
66
|
+
case kCLASS: \
|
|
67
|
+
case kFALSE: \
|
|
68
|
+
case kINSTANCE: \
|
|
69
|
+
case kINTERFACE: \
|
|
70
|
+
case kNIL: \
|
|
71
|
+
case kSELF: \
|
|
72
|
+
case kSINGLETON: \
|
|
73
|
+
case kTOP: \
|
|
74
|
+
case kTRUE: \
|
|
75
|
+
case kVOID: \
|
|
76
|
+
case kTYPE: \
|
|
77
|
+
case kUNCHECKED: \
|
|
78
|
+
case kIN: \
|
|
79
|
+
case kOUT: \
|
|
80
|
+
case kEND: \
|
|
81
|
+
case kDEF: \
|
|
82
|
+
case kINCLUDE: \
|
|
83
|
+
case kEXTEND: \
|
|
84
|
+
case kPREPEND: \
|
|
85
|
+
case kALIAS: \
|
|
86
|
+
case kMODULE: \
|
|
87
|
+
case kATTRREADER: \
|
|
88
|
+
case kATTRWRITER: \
|
|
89
|
+
case kATTRACCESSOR: \
|
|
90
|
+
case kPUBLIC: \
|
|
91
|
+
case kPRIVATE: \
|
|
92
|
+
case kUNTYPED: \
|
|
93
|
+
case kUSE: \
|
|
94
|
+
case kAS: \
|
|
95
|
+
case k__TODO__: \
|
|
96
|
+
/* nop */
|
|
97
|
+
|
|
98
|
+
#define CHECK_PARSE(call) \
|
|
99
|
+
if (!call) { \
|
|
100
|
+
return false; \
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
#define ASSERT_TOKEN(parser, expected_type) \
|
|
104
|
+
if (parser->current_token.type != expected_type) { \
|
|
105
|
+
rbs_parser_set_error(parser, parser->current_token, true, "expected a token `%s`", rbs_token_type_str(expected_type)); \
|
|
106
|
+
return false; \
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
#define ADVANCE_ASSERT(parser, expected_type) \
|
|
110
|
+
do { \
|
|
111
|
+
rbs_parser_advance(parser); \
|
|
112
|
+
ASSERT_TOKEN(parser, expected_type) \
|
|
113
|
+
} while (0);
|
|
114
|
+
|
|
115
|
+
#define RESET_TABLE_P(table) (table->size == 0)
|
|
116
|
+
|
|
117
|
+
#define ALLOCATOR() parser->allocator
|
|
118
|
+
|
|
119
|
+
typedef struct {
|
|
120
|
+
rbs_node_list_t *required_positionals;
|
|
121
|
+
rbs_node_list_t *optional_positionals;
|
|
122
|
+
rbs_node_t *rest_positionals;
|
|
123
|
+
rbs_node_list_t *trailing_positionals;
|
|
124
|
+
rbs_hash_t *required_keywords;
|
|
125
|
+
rbs_hash_t *optional_keywords;
|
|
126
|
+
rbs_node_t *rest_keywords;
|
|
127
|
+
} method_params;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* id_table represents a set of RBS constant IDs.
|
|
131
|
+
* This is used to manage the set of bound variables.
|
|
132
|
+
* */
|
|
133
|
+
typedef struct id_table {
|
|
134
|
+
size_t size;
|
|
135
|
+
size_t count;
|
|
136
|
+
rbs_constant_id_t *ids;
|
|
137
|
+
struct id_table *next;
|
|
138
|
+
} id_table;
|
|
139
|
+
|
|
140
|
+
static bool rbs_is_untyped_params(method_params *params) {
|
|
141
|
+
return params->required_positionals == NULL;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
static rbs_location_range rbs_location_range_current_token(rbs_parser_t *parser) {
|
|
145
|
+
return RBS_RANGE_LEX2AST(parser->current_token.range);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
static bool parse_optional(rbs_parser_t *parser, rbs_node_t **optional, bool void_allowed, bool self_allowed, bool classish_allowed);
|
|
149
|
+
static bool parse_simple(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed, bool self_allowed, bool classish_allowed);
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* @returns A borrowed copy of the current token, which does *not* need to be freed.
|
|
153
|
+
*/
|
|
154
|
+
static rbs_string_t rbs_parser_peek_current_token(rbs_parser_t *parser) {
|
|
155
|
+
rbs_range_t rg = parser->current_token.range;
|
|
156
|
+
|
|
157
|
+
const char *start = parser->lexer->string.start + rg.start.byte_pos;
|
|
158
|
+
size_t length = rg.end.byte_pos - rg.start.byte_pos;
|
|
159
|
+
|
|
160
|
+
return rbs_string_new(start, start + length);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
static rbs_constant_id_t rbs_constant_pool_insert_string(rbs_constant_pool_t *self, rbs_string_t string) {
|
|
164
|
+
return rbs_constant_pool_insert_shared(self, (const uint8_t *) string.start, rbs_string_len(string));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
typedef enum {
|
|
168
|
+
CLASS_NAME = 1,
|
|
169
|
+
INTERFACE_NAME = 2,
|
|
170
|
+
ALIAS_NAME = 4
|
|
171
|
+
} TypeNameKind;
|
|
172
|
+
|
|
173
|
+
static void parser_advance_no_gap(rbs_parser_t *parser) {
|
|
174
|
+
if (parser->current_token.range.end.byte_pos == parser->next_token.range.start.byte_pos) {
|
|
175
|
+
rbs_parser_advance(parser);
|
|
176
|
+
} else {
|
|
177
|
+
rbs_parser_set_error(parser, parser->next_token, true, "unexpected token");
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/*
|
|
182
|
+
type_name ::= {`::`} (tUIDENT `::`)* <tXIDENT>
|
|
183
|
+
| {(tUIDENT `::`)*} <tXIDENT>
|
|
184
|
+
| {<tXIDENT>}
|
|
185
|
+
*/
|
|
186
|
+
NODISCARD
|
|
187
|
+
static bool parse_type_name(rbs_parser_t *parser, TypeNameKind kind, rbs_range_t *rg, rbs_type_name_t **type_name) {
|
|
188
|
+
bool absolute = false;
|
|
189
|
+
|
|
190
|
+
if (rg) {
|
|
191
|
+
rg->start = parser->current_token.range.start;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (parser->current_token.type == pCOLON2) {
|
|
195
|
+
absolute = true;
|
|
196
|
+
parser_advance_no_gap(parser);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
rbs_node_list_t *path = rbs_node_list_new(ALLOCATOR());
|
|
200
|
+
|
|
201
|
+
while (
|
|
202
|
+
parser->current_token.type == tUIDENT && parser->next_token.type == pCOLON2 && parser->current_token.range.end.byte_pos == parser->next_token.range.start.byte_pos && parser->next_token.range.end.byte_pos == parser->next_token2.range.start.byte_pos
|
|
203
|
+
) {
|
|
204
|
+
rbs_constant_id_t symbol_value = INTERN_TOKEN(parser, parser->current_token);
|
|
205
|
+
rbs_location_range symbol_range = RBS_RANGE_LEX2AST(parser->next_token.range);
|
|
206
|
+
rbs_ast_symbol_t *symbol = rbs_ast_symbol_new(ALLOCATOR(), symbol_range, &parser->constant_pool, symbol_value);
|
|
207
|
+
rbs_node_list_append(path, (rbs_node_t *) symbol);
|
|
208
|
+
|
|
209
|
+
rbs_parser_advance(parser);
|
|
210
|
+
rbs_parser_advance(parser);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
rbs_range_t namespace_range = {
|
|
214
|
+
.start = rg->start,
|
|
215
|
+
.end = parser->current_token.range.end
|
|
216
|
+
};
|
|
217
|
+
rbs_namespace_t *ns = rbs_namespace_new(ALLOCATOR(), RBS_RANGE_LEX2AST(namespace_range), path, absolute);
|
|
218
|
+
|
|
219
|
+
switch (parser->current_token.type) {
|
|
220
|
+
case tLIDENT:
|
|
221
|
+
case kSKIP:
|
|
222
|
+
case kRETURN:
|
|
223
|
+
if (kind & ALIAS_NAME) goto success;
|
|
224
|
+
goto error_handling;
|
|
225
|
+
case tULIDENT:
|
|
226
|
+
if (kind & INTERFACE_NAME) goto success;
|
|
227
|
+
goto error_handling;
|
|
228
|
+
case tUIDENT:
|
|
229
|
+
if (kind & CLASS_NAME) goto success;
|
|
230
|
+
goto error_handling;
|
|
231
|
+
default:
|
|
232
|
+
goto error_handling;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
success: {
|
|
236
|
+
if (rg) {
|
|
237
|
+
rg->end = parser->current_token.range.end;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
rbs_location_range symbol_range = rbs_location_range_current_token(parser);
|
|
241
|
+
rbs_constant_id_t name = INTERN_TOKEN(parser, parser->current_token);
|
|
242
|
+
rbs_ast_symbol_t *symbol = rbs_ast_symbol_new(ALLOCATOR(), symbol_range, &parser->constant_pool, name);
|
|
243
|
+
*type_name = rbs_type_name_new(ALLOCATOR(), RBS_RANGE_LEX2AST(*rg), ns, symbol);
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
error_handling: {
|
|
248
|
+
const char *ids = NULL;
|
|
249
|
+
if (kind & ALIAS_NAME) {
|
|
250
|
+
ids = "alias name";
|
|
251
|
+
}
|
|
252
|
+
if (kind & INTERFACE_NAME) {
|
|
253
|
+
ids = "interface name";
|
|
254
|
+
}
|
|
255
|
+
if (kind & CLASS_NAME) {
|
|
256
|
+
ids = "class/module/constant name";
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
RBS_ASSERT(ids != NULL, "Unknown kind of type: %i", kind);
|
|
260
|
+
|
|
261
|
+
rbs_parser_set_error(parser, parser->current_token, true, "expected one of %s", ids);
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/*
|
|
267
|
+
type_list ::= {} type `,` ... <`,`> eol
|
|
268
|
+
| {} type `,` ... `,` <type> eol
|
|
269
|
+
*/
|
|
270
|
+
NODISCARD
|
|
271
|
+
static bool parse_type_list(rbs_parser_t *parser, enum RBSTokenType eol, rbs_node_list_t *types, bool void_allowed, bool self_allowed, bool classish_allowed) {
|
|
272
|
+
while (true) {
|
|
273
|
+
rbs_node_t *type;
|
|
274
|
+
CHECK_PARSE(rbs_parse_type(parser, &type, void_allowed, self_allowed, classish_allowed));
|
|
275
|
+
rbs_node_list_append(types, type);
|
|
276
|
+
|
|
277
|
+
if (parser->next_token.type == pCOMMA) {
|
|
278
|
+
rbs_parser_advance(parser);
|
|
279
|
+
|
|
280
|
+
if (parser->next_token.type == eol) {
|
|
281
|
+
break;
|
|
282
|
+
}
|
|
283
|
+
} else {
|
|
284
|
+
if (parser->next_token.type == eol) {
|
|
285
|
+
break;
|
|
286
|
+
} else {
|
|
287
|
+
rbs_parser_set_error(parser, parser->next_token, true, "comma delimited type list is expected");
|
|
288
|
+
return false;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return true;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/*
|
|
297
|
+
type_list_with_commas ::= {} type `,` ... <`,`> eol
|
|
298
|
+
| {} type `,` ... `,` <type> eol
|
|
299
|
+
*/
|
|
300
|
+
NODISCARD
|
|
301
|
+
static bool parse_type_list_with_commas(rbs_parser_t *parser, enum RBSTokenType eol, rbs_node_list_t *types, rbs_location_range_list_t *comma_locations, bool void_allowed, bool self_allowed, bool classish_allowed) {
|
|
302
|
+
while (true) {
|
|
303
|
+
rbs_node_t *type;
|
|
304
|
+
CHECK_PARSE(rbs_parse_type(parser, &type, void_allowed, self_allowed, classish_allowed));
|
|
305
|
+
rbs_node_list_append(types, type);
|
|
306
|
+
|
|
307
|
+
if (parser->next_token.type == pCOMMA) {
|
|
308
|
+
rbs_location_range comma_loc = RBS_RANGE_LEX2AST(parser->next_token.range);
|
|
309
|
+
rbs_location_range_list_append(comma_locations, comma_loc);
|
|
310
|
+
rbs_parser_advance(parser);
|
|
311
|
+
|
|
312
|
+
if (parser->next_token.type == eol) {
|
|
313
|
+
// Handle trailing comma - for type applications, this is an error
|
|
314
|
+
if (eol == pRBRACKET) {
|
|
315
|
+
rbs_parser_set_error(parser, parser->next_token, true, "unexpected trailing comma");
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
} else {
|
|
321
|
+
if (parser->next_token.type == eol) {
|
|
322
|
+
break;
|
|
323
|
+
} else {
|
|
324
|
+
rbs_parser_set_error(parser, parser->next_token, true, "comma delimited type list is expected");
|
|
325
|
+
return false;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
return true;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
static bool is_keyword_token(enum RBSTokenType type) {
|
|
334
|
+
switch (type) {
|
|
335
|
+
case tLIDENT:
|
|
336
|
+
case tUIDENT:
|
|
337
|
+
case tULIDENT:
|
|
338
|
+
case tULLIDENT:
|
|
339
|
+
case tQIDENT:
|
|
340
|
+
case tBANGIDENT:
|
|
341
|
+
KEYWORD_CASES
|
|
342
|
+
return true;
|
|
343
|
+
default:
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/*
|
|
349
|
+
function_param ::= {} <type>
|
|
350
|
+
| {} type <param>
|
|
351
|
+
*/
|
|
352
|
+
NODISCARD
|
|
353
|
+
static bool parse_function_param(rbs_parser_t *parser, rbs_types_function_param_t **function_param, bool self_allowed, bool classish_allowed) {
|
|
354
|
+
rbs_range_t type_range;
|
|
355
|
+
type_range.start = parser->next_token.range.start;
|
|
356
|
+
rbs_node_t *type;
|
|
357
|
+
CHECK_PARSE(rbs_parse_type(parser, &type, false, self_allowed, classish_allowed));
|
|
358
|
+
type_range.end = parser->current_token.range.end;
|
|
359
|
+
|
|
360
|
+
if (parser->next_token.type == pCOMMA || parser->next_token.type == pRPAREN) {
|
|
361
|
+
rbs_range_t param_range = type_range;
|
|
362
|
+
|
|
363
|
+
*function_param = rbs_types_function_param_new(ALLOCATOR(), RBS_RANGE_LEX2AST(param_range), type, NULL);
|
|
364
|
+
return true;
|
|
365
|
+
} else {
|
|
366
|
+
rbs_range_t name_range = parser->next_token.range;
|
|
367
|
+
|
|
368
|
+
rbs_parser_advance(parser);
|
|
369
|
+
|
|
370
|
+
rbs_range_t param_range = {
|
|
371
|
+
.start = type_range.start,
|
|
372
|
+
.end = name_range.end,
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
if (!is_keyword_token(parser->current_token.type)) {
|
|
376
|
+
rbs_parser_set_error(parser, parser->current_token, true, "unexpected token for function parameter name");
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
rbs_string_t unquoted_str = rbs_unquote_string(ALLOCATOR(), rbs_parser_peek_current_token(parser), parser->lexer->encoding);
|
|
381
|
+
rbs_location_range symbol_range = rbs_location_range_current_token(parser);
|
|
382
|
+
rbs_constant_id_t constant_id = rbs_constant_pool_insert_string(&parser->constant_pool, unquoted_str);
|
|
383
|
+
rbs_ast_symbol_t *name = rbs_ast_symbol_new(ALLOCATOR(), symbol_range, &parser->constant_pool, constant_id);
|
|
384
|
+
|
|
385
|
+
*function_param = rbs_types_function_param_new(ALLOCATOR(), RBS_RANGE_LEX2AST(param_range), type, name);
|
|
386
|
+
(*function_param)->name_range = RBS_RANGE_LEX2AST(name_range);
|
|
387
|
+
return true;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
static rbs_constant_id_t intern_token_start_end(rbs_parser_t *parser, rbs_token_t start_token, rbs_token_t end_token) {
|
|
392
|
+
return rbs_constant_pool_insert_shared_with_encoding(
|
|
393
|
+
&parser->constant_pool,
|
|
394
|
+
(const uint8_t *) rbs_peek_token(parser->lexer, start_token),
|
|
395
|
+
end_token.range.end.byte_pos - start_token.range.start.byte_pos,
|
|
396
|
+
parser->lexer->encoding
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/*
|
|
401
|
+
keyword_key ::= {} <keyword> `:`
|
|
402
|
+
| {} keyword <`?`> `:`
|
|
403
|
+
*/
|
|
404
|
+
NODISCARD
|
|
405
|
+
static bool parse_keyword_key(rbs_parser_t *parser, rbs_ast_symbol_t **key) {
|
|
406
|
+
rbs_parser_advance(parser);
|
|
407
|
+
|
|
408
|
+
rbs_location_range symbol_range = rbs_location_range_current_token(parser);
|
|
409
|
+
|
|
410
|
+
if (parser->next_token.type == pQUESTION) {
|
|
411
|
+
*key = rbs_ast_symbol_new(
|
|
412
|
+
ALLOCATOR(),
|
|
413
|
+
symbol_range,
|
|
414
|
+
&parser->constant_pool,
|
|
415
|
+
intern_token_start_end(parser, parser->current_token, parser->next_token)
|
|
416
|
+
);
|
|
417
|
+
rbs_parser_advance(parser);
|
|
418
|
+
} else {
|
|
419
|
+
*key = rbs_ast_symbol_new(ALLOCATOR(), symbol_range, &parser->constant_pool, INTERN_TOKEN(parser, parser->current_token));
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
return true;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/*
|
|
426
|
+
keyword ::= {} keyword `:` <function_param>
|
|
427
|
+
*/
|
|
428
|
+
NODISCARD
|
|
429
|
+
static bool parse_keyword(rbs_parser_t *parser, rbs_hash_t *keywords, rbs_hash_t *memo, bool self_allowed, bool classish_allowed) {
|
|
430
|
+
rbs_ast_symbol_t *key = NULL;
|
|
431
|
+
CHECK_PARSE(parse_keyword_key(parser, &key));
|
|
432
|
+
|
|
433
|
+
if (rbs_hash_find(memo, (rbs_node_t *) key)) {
|
|
434
|
+
rbs_parser_set_error(parser, parser->current_token, true, "duplicated keyword argument");
|
|
435
|
+
return false;
|
|
436
|
+
} else {
|
|
437
|
+
rbs_location_range symbol_range = rbs_location_range_current_token(parser);
|
|
438
|
+
rbs_hash_set(memo, (rbs_node_t *) key, (rbs_node_t *) rbs_ast_bool_new(ALLOCATOR(), symbol_range, true));
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
ADVANCE_ASSERT(parser, pCOLON);
|
|
442
|
+
rbs_types_function_param_t *param = NULL;
|
|
443
|
+
CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed, classish_allowed));
|
|
444
|
+
|
|
445
|
+
rbs_hash_set(keywords, (rbs_node_t *) key, (rbs_node_t *) param);
|
|
446
|
+
|
|
447
|
+
return true;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/*
|
|
451
|
+
Returns true if keyword is given.
|
|
452
|
+
|
|
453
|
+
is_keyword === {} KEYWORD `:`
|
|
454
|
+
*/
|
|
455
|
+
static bool is_keyword(rbs_parser_t *parser) {
|
|
456
|
+
if (is_keyword_token(parser->next_token.type)) {
|
|
457
|
+
if (parser->next_token2.type == pCOLON && parser->next_token.range.end.byte_pos == parser->next_token2.range.start.byte_pos) {
|
|
458
|
+
return true;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
if (parser->next_token2.type == pQUESTION && parser->next_token3.type == pCOLON && parser->next_token.range.end.byte_pos == parser->next_token2.range.start.byte_pos && parser->next_token2.range.end.byte_pos == parser->next_token3.range.start.byte_pos) {
|
|
462
|
+
return true;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
return false;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Advance token if _next_ token is `type`.
|
|
471
|
+
* Ensures one token advance and `parser->current_token.type == type`, or current token not changed.
|
|
472
|
+
*
|
|
473
|
+
* @returns true if token advances, false otherwise.
|
|
474
|
+
**/
|
|
475
|
+
static bool parser_advance_if(rbs_parser_t *parser, enum RBSTokenType type) {
|
|
476
|
+
if (parser->next_token.type == type) {
|
|
477
|
+
rbs_parser_advance(parser);
|
|
478
|
+
return true;
|
|
479
|
+
} else {
|
|
480
|
+
return false;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/*
|
|
485
|
+
params ::= {} `)`
|
|
486
|
+
| {} `?` `)` -- Untyped function params (assign params.required = nil)
|
|
487
|
+
| <required_params> `)`
|
|
488
|
+
| <required_params> `,` `)`
|
|
489
|
+
|
|
490
|
+
required_params ::= {} function_param `,` <required_params>
|
|
491
|
+
| {} <function_param>
|
|
492
|
+
| {} <optional_params>
|
|
493
|
+
|
|
494
|
+
optional_params ::= {} `?` function_param `,` <optional_params>
|
|
495
|
+
| {} `?` <function_param>
|
|
496
|
+
| {} <rest_params>
|
|
497
|
+
|
|
498
|
+
rest_params ::= {} `*` function_param `,` <trailing_params>
|
|
499
|
+
| {} `*` <function_param>
|
|
500
|
+
| {} <trailing_params>
|
|
501
|
+
|
|
502
|
+
trailing_params ::= {} function_param `,` <trailing_params>
|
|
503
|
+
| {} <function_param>
|
|
504
|
+
| {} <keywords>
|
|
505
|
+
|
|
506
|
+
keywords ::= {} required_keyword `,` <keywords>
|
|
507
|
+
| {} `?` optional_keyword `,` <keywords>
|
|
508
|
+
| {} `**` function_param `,` <keywords>
|
|
509
|
+
| {} <required_keyword>
|
|
510
|
+
| {} `?` <optional_keyword>
|
|
511
|
+
| {} `**` <function_param>
|
|
512
|
+
*/
|
|
513
|
+
NODISCARD
|
|
514
|
+
static bool parse_params(rbs_parser_t *parser, method_params *params, bool self_allowed, bool classish_allowed) {
|
|
515
|
+
if (parser->next_token.type == pQUESTION && parser->next_token2.type == pRPAREN) {
|
|
516
|
+
params->required_positionals = NULL;
|
|
517
|
+
rbs_parser_advance(parser);
|
|
518
|
+
return true;
|
|
519
|
+
}
|
|
520
|
+
if (parser->next_token.type == pRPAREN) {
|
|
521
|
+
return true;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
rbs_hash_t *memo = rbs_hash_new(ALLOCATOR());
|
|
525
|
+
|
|
526
|
+
while (true) {
|
|
527
|
+
switch (parser->next_token.type) {
|
|
528
|
+
case pQUESTION:
|
|
529
|
+
goto PARSE_OPTIONAL_PARAMS;
|
|
530
|
+
case pSTAR:
|
|
531
|
+
goto PARSE_REST_PARAM;
|
|
532
|
+
case pSTAR2:
|
|
533
|
+
goto PARSE_KEYWORDS;
|
|
534
|
+
case pRPAREN:
|
|
535
|
+
goto EOP;
|
|
536
|
+
|
|
537
|
+
default:
|
|
538
|
+
if (is_keyword(parser)) {
|
|
539
|
+
goto PARSE_KEYWORDS;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
rbs_types_function_param_t *param = NULL;
|
|
543
|
+
CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed, classish_allowed));
|
|
544
|
+
rbs_node_list_append(params->required_positionals, (rbs_node_t *) param);
|
|
545
|
+
|
|
546
|
+
break;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
if (!parser_advance_if(parser, pCOMMA)) {
|
|
550
|
+
goto EOP;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
PARSE_OPTIONAL_PARAMS:
|
|
555
|
+
while (true) {
|
|
556
|
+
switch (parser->next_token.type) {
|
|
557
|
+
case pQUESTION: {
|
|
558
|
+
rbs_parser_advance(parser);
|
|
559
|
+
|
|
560
|
+
if (is_keyword(parser)) {
|
|
561
|
+
CHECK_PARSE(parse_keyword(parser, params->optional_keywords, memo, self_allowed, classish_allowed));
|
|
562
|
+
parser_advance_if(parser, pCOMMA);
|
|
563
|
+
goto PARSE_KEYWORDS;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
rbs_types_function_param_t *param = NULL;
|
|
567
|
+
CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed, classish_allowed));
|
|
568
|
+
rbs_node_list_append(params->optional_positionals, (rbs_node_t *) param);
|
|
569
|
+
|
|
570
|
+
break;
|
|
571
|
+
}
|
|
572
|
+
default:
|
|
573
|
+
goto PARSE_REST_PARAM;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
if (!parser_advance_if(parser, pCOMMA)) {
|
|
577
|
+
goto EOP;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
PARSE_REST_PARAM:
|
|
582
|
+
if (parser->next_token.type == pSTAR) {
|
|
583
|
+
rbs_parser_advance(parser);
|
|
584
|
+
rbs_types_function_param_t *param = NULL;
|
|
585
|
+
CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed, classish_allowed));
|
|
586
|
+
params->rest_positionals = (rbs_node_t *) param;
|
|
587
|
+
|
|
588
|
+
if (!parser_advance_if(parser, pCOMMA)) {
|
|
589
|
+
goto EOP;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
goto PARSE_TRAILING_PARAMS;
|
|
593
|
+
|
|
594
|
+
PARSE_TRAILING_PARAMS:
|
|
595
|
+
while (true) {
|
|
596
|
+
switch (parser->next_token.type) {
|
|
597
|
+
case pQUESTION:
|
|
598
|
+
goto PARSE_KEYWORDS;
|
|
599
|
+
case pSTAR:
|
|
600
|
+
goto EOP;
|
|
601
|
+
case pSTAR2:
|
|
602
|
+
goto PARSE_KEYWORDS;
|
|
603
|
+
case pRPAREN:
|
|
604
|
+
goto EOP;
|
|
605
|
+
|
|
606
|
+
default:
|
|
607
|
+
if (is_keyword(parser)) {
|
|
608
|
+
goto PARSE_KEYWORDS;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
rbs_types_function_param_t *param = NULL;
|
|
612
|
+
CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed, classish_allowed));
|
|
613
|
+
rbs_node_list_append(params->trailing_positionals, (rbs_node_t *) param);
|
|
614
|
+
|
|
615
|
+
break;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
if (!parser_advance_if(parser, pCOMMA)) {
|
|
619
|
+
goto EOP;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
PARSE_KEYWORDS:
|
|
624
|
+
while (true) {
|
|
625
|
+
switch (parser->next_token.type) {
|
|
626
|
+
case pQUESTION:
|
|
627
|
+
rbs_parser_advance(parser);
|
|
628
|
+
if (is_keyword(parser)) {
|
|
629
|
+
CHECK_PARSE(parse_keyword(parser, params->optional_keywords, memo, self_allowed, classish_allowed));
|
|
630
|
+
} else {
|
|
631
|
+
rbs_parser_set_error(parser, parser->next_token, true, "optional keyword argument type is expected");
|
|
632
|
+
return false;
|
|
633
|
+
}
|
|
634
|
+
break;
|
|
635
|
+
|
|
636
|
+
case pSTAR2: {
|
|
637
|
+
rbs_parser_advance(parser);
|
|
638
|
+
rbs_types_function_param_t *param = NULL;
|
|
639
|
+
CHECK_PARSE(parse_function_param(parser, ¶m, self_allowed, classish_allowed));
|
|
640
|
+
params->rest_keywords = (rbs_node_t *) param;
|
|
641
|
+
break;
|
|
642
|
+
}
|
|
643
|
+
case tUIDENT:
|
|
644
|
+
case tLIDENT:
|
|
645
|
+
case tQIDENT:
|
|
646
|
+
case tULIDENT:
|
|
647
|
+
case tULLIDENT:
|
|
648
|
+
case tBANGIDENT:
|
|
649
|
+
KEYWORD_CASES
|
|
650
|
+
if (is_keyword(parser)) {
|
|
651
|
+
CHECK_PARSE(parse_keyword(parser, params->required_keywords, memo, self_allowed, classish_allowed));
|
|
652
|
+
} else {
|
|
653
|
+
rbs_parser_set_error(parser, parser->next_token, true, "required keyword argument type is expected");
|
|
654
|
+
return false;
|
|
655
|
+
}
|
|
656
|
+
break;
|
|
657
|
+
|
|
658
|
+
default:
|
|
659
|
+
goto EOP;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
if (!parser_advance_if(parser, pCOMMA)) {
|
|
663
|
+
goto EOP;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
EOP:
|
|
668
|
+
if (parser->next_token.type != pRPAREN) {
|
|
669
|
+
rbs_parser_set_error(parser, parser->next_token, true, "unexpected token for method type parameters");
|
|
670
|
+
return false;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
return true;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/*
|
|
677
|
+
optional ::= {} <simple_type>
|
|
678
|
+
| {} simple_type <`?`>
|
|
679
|
+
*/
|
|
680
|
+
NODISCARD
|
|
681
|
+
static bool parse_optional(rbs_parser_t *parser, rbs_node_t **optional, bool void_allowed, bool self_allowed, bool classish_allowed) {
|
|
682
|
+
rbs_range_t rg;
|
|
683
|
+
rg.start = parser->next_token.range.start;
|
|
684
|
+
|
|
685
|
+
rbs_node_t *type = NULL;
|
|
686
|
+
CHECK_PARSE(parse_simple(parser, &type, void_allowed, self_allowed, classish_allowed));
|
|
687
|
+
|
|
688
|
+
if (parser->next_token.type == pQUESTION) {
|
|
689
|
+
if (void_allowed && type->type == RBS_TYPES_BASES_VOID) {
|
|
690
|
+
rbs_parser_set_error(parser, parser->current_token, true, "void type is not allowed here");
|
|
691
|
+
return false;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
rbs_parser_advance(parser);
|
|
695
|
+
rg.end = parser->current_token.range.end;
|
|
696
|
+
*optional = (rbs_node_t *) rbs_types_optional_new(ALLOCATOR(), RBS_RANGE_LEX2AST(rg), type);
|
|
697
|
+
} else {
|
|
698
|
+
*optional = type;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
return true;
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
static void initialize_method_params(method_params *params, rbs_allocator_t *allocator) {
|
|
705
|
+
*params = (method_params) {
|
|
706
|
+
.required_positionals = rbs_node_list_new(allocator),
|
|
707
|
+
.optional_positionals = rbs_node_list_new(allocator),
|
|
708
|
+
.rest_positionals = NULL,
|
|
709
|
+
.trailing_positionals = rbs_node_list_new(allocator),
|
|
710
|
+
.required_keywords = rbs_hash_new(allocator),
|
|
711
|
+
.optional_keywords = rbs_hash_new(allocator),
|
|
712
|
+
.rest_keywords = NULL,
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
/*
|
|
717
|
+
self_type_binding ::= {} <>
|
|
718
|
+
| {} `[` `self` `:` type <`]`>
|
|
719
|
+
*/
|
|
720
|
+
NODISCARD
|
|
721
|
+
static bool parse_self_type_binding(rbs_parser_t *parser, rbs_node_t **self_type, bool self_allowed, bool classish_allowed) {
|
|
722
|
+
if (parser->next_token.type == pLBRACKET) {
|
|
723
|
+
rbs_parser_advance(parser);
|
|
724
|
+
ADVANCE_ASSERT(parser, kSELF);
|
|
725
|
+
ADVANCE_ASSERT(parser, pCOLON);
|
|
726
|
+
rbs_node_t *type;
|
|
727
|
+
CHECK_PARSE(rbs_parse_type(parser, &type, false, self_allowed, classish_allowed));
|
|
728
|
+
ADVANCE_ASSERT(parser, pRBRACKET);
|
|
729
|
+
*self_type = type;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
return true;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
typedef struct {
|
|
736
|
+
rbs_node_t *function;
|
|
737
|
+
rbs_types_block_t *block;
|
|
738
|
+
rbs_node_t *function_self_type;
|
|
739
|
+
} parse_function_result;
|
|
740
|
+
|
|
741
|
+
/*
|
|
742
|
+
function ::= {} `(` params `)` self_type_binding? `{` `(` params `)` self_type_binding? `->` optional `}` `->` <optional>
|
|
743
|
+
| {} `(` params `)` self_type_binding? `->` <optional>
|
|
744
|
+
| {} self_type_binding? `{` `(` params `)` self_type_binding? `->` optional `}` `->` <optional>
|
|
745
|
+
| {} self_type_binding? `{` self_type_binding `->` optional `}` `->` <optional>
|
|
746
|
+
| {} self_type_binding? `->` <optional>
|
|
747
|
+
*/
|
|
748
|
+
NODISCARD
|
|
749
|
+
static bool parse_function(rbs_parser_t *parser, bool accept_type_binding, bool block_allowed, parse_function_result **result, bool self_allowed, bool classish_allowed) {
|
|
750
|
+
rbs_node_t *function = NULL;
|
|
751
|
+
rbs_types_block_t *block = NULL;
|
|
752
|
+
rbs_node_t *function_self_type = NULL;
|
|
753
|
+
rbs_range_t function_range;
|
|
754
|
+
function_range.start = parser->current_token.range.start;
|
|
755
|
+
|
|
756
|
+
method_params params;
|
|
757
|
+
initialize_method_params(¶ms, ALLOCATOR());
|
|
758
|
+
|
|
759
|
+
if (parser->next_token.type == pLPAREN) {
|
|
760
|
+
rbs_parser_advance(parser);
|
|
761
|
+
CHECK_PARSE(parse_params(parser, ¶ms, self_allowed, classish_allowed));
|
|
762
|
+
ADVANCE_ASSERT(parser, pRPAREN);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
// Passing NULL to function_self_type means the function itself doesn't accept self type binding. (== method type)
|
|
766
|
+
if (accept_type_binding) {
|
|
767
|
+
CHECK_PARSE(parse_self_type_binding(parser, &function_self_type, self_allowed, classish_allowed));
|
|
768
|
+
} else {
|
|
769
|
+
if (rbs_is_untyped_params(¶ms)) {
|
|
770
|
+
if (parser->next_token.type != pARROW) {
|
|
771
|
+
rbs_parser_set_error(parser, parser->next_token2, true, "A method type with untyped method parameter cannot have block");
|
|
772
|
+
return false;
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
bool required = true;
|
|
778
|
+
rbs_range_t block_range;
|
|
779
|
+
|
|
780
|
+
if (!block_allowed && (parser->next_token.type == pLBRACE || (parser->next_token.type == pQUESTION && parser->next_token2.type == pLBRACE))) {
|
|
781
|
+
rbs_parser_set_error(parser, parser->next_token, true, "block is not allowed in this context");
|
|
782
|
+
return false;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
if (parser->next_token.type == pQUESTION && parser->next_token2.type == pLBRACE) {
|
|
786
|
+
// Optional block
|
|
787
|
+
block_range.start = parser->next_token.range.start;
|
|
788
|
+
required = false;
|
|
789
|
+
rbs_parser_advance(parser);
|
|
790
|
+
} else if (parser->next_token.type == pLBRACE) {
|
|
791
|
+
block_range.start = parser->next_token.range.start;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
if (parser->next_token.type == pLBRACE) {
|
|
795
|
+
rbs_parser_advance(parser);
|
|
796
|
+
|
|
797
|
+
method_params block_params;
|
|
798
|
+
initialize_method_params(&block_params, ALLOCATOR());
|
|
799
|
+
|
|
800
|
+
if (parser->next_token.type == pLPAREN) {
|
|
801
|
+
rbs_parser_advance(parser);
|
|
802
|
+
CHECK_PARSE(parse_params(parser, &block_params, self_allowed, classish_allowed));
|
|
803
|
+
ADVANCE_ASSERT(parser, pRPAREN);
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
rbs_node_t *self_type = NULL;
|
|
807
|
+
CHECK_PARSE(parse_self_type_binding(parser, &self_type, self_allowed, classish_allowed));
|
|
808
|
+
|
|
809
|
+
ADVANCE_ASSERT(parser, pARROW);
|
|
810
|
+
rbs_node_t *block_return_type = NULL;
|
|
811
|
+
CHECK_PARSE(parse_optional(parser, &block_return_type, true, self_allowed, classish_allowed));
|
|
812
|
+
|
|
813
|
+
ADVANCE_ASSERT(parser, pRBRACE);
|
|
814
|
+
|
|
815
|
+
block_range.end = parser->current_token.range.end;
|
|
816
|
+
|
|
817
|
+
rbs_node_t *block_function = NULL;
|
|
818
|
+
if (rbs_is_untyped_params(&block_params)) {
|
|
819
|
+
block_function = (rbs_node_t *) rbs_types_untyped_function_new(ALLOCATOR(), RBS_RANGE_LEX2AST(block_range), block_return_type);
|
|
820
|
+
} else {
|
|
821
|
+
block_function = (rbs_node_t *) rbs_types_function_new(
|
|
822
|
+
ALLOCATOR(),
|
|
823
|
+
RBS_RANGE_LEX2AST(block_range),
|
|
824
|
+
block_params.required_positionals,
|
|
825
|
+
block_params.optional_positionals,
|
|
826
|
+
block_params.rest_positionals,
|
|
827
|
+
block_params.trailing_positionals,
|
|
828
|
+
block_params.required_keywords,
|
|
829
|
+
block_params.optional_keywords,
|
|
830
|
+
block_params.rest_keywords,
|
|
831
|
+
block_return_type
|
|
832
|
+
);
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
block = rbs_types_block_new(ALLOCATOR(), RBS_RANGE_LEX2AST(block_range), block_function, required, self_type);
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
ADVANCE_ASSERT(parser, pARROW);
|
|
839
|
+
rbs_node_t *type = NULL;
|
|
840
|
+
CHECK_PARSE(parse_optional(parser, &type, true, self_allowed, classish_allowed));
|
|
841
|
+
|
|
842
|
+
function_range.end = parser->current_token.range.end;
|
|
843
|
+
if (rbs_is_untyped_params(¶ms)) {
|
|
844
|
+
function = (rbs_node_t *) rbs_types_untyped_function_new(ALLOCATOR(), RBS_RANGE_LEX2AST(function_range), type);
|
|
845
|
+
} else {
|
|
846
|
+
function = (rbs_node_t *) rbs_types_function_new(
|
|
847
|
+
ALLOCATOR(),
|
|
848
|
+
RBS_RANGE_LEX2AST(function_range),
|
|
849
|
+
params.required_positionals,
|
|
850
|
+
params.optional_positionals,
|
|
851
|
+
params.rest_positionals,
|
|
852
|
+
params.trailing_positionals,
|
|
853
|
+
params.required_keywords,
|
|
854
|
+
params.optional_keywords,
|
|
855
|
+
params.rest_keywords,
|
|
856
|
+
type
|
|
857
|
+
);
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
(*result)->function = function;
|
|
861
|
+
(*result)->block = block;
|
|
862
|
+
(*result)->function_self_type = function_self_type;
|
|
863
|
+
return true;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
/*
|
|
867
|
+
proc_type ::= {`^`} <function>
|
|
868
|
+
*/
|
|
869
|
+
NODISCARD
|
|
870
|
+
static bool parse_proc_type(rbs_parser_t *parser, rbs_types_proc_t **proc, bool self_allowed, bool classish_allowed) {
|
|
871
|
+
rbs_position_t start = parser->current_token.range.start;
|
|
872
|
+
parse_function_result *result = rbs_allocator_alloc(ALLOCATOR(), parse_function_result);
|
|
873
|
+
CHECK_PARSE(parse_function(parser, true, true, &result, self_allowed, classish_allowed));
|
|
874
|
+
|
|
875
|
+
rbs_position_t end = parser->current_token.range.end;
|
|
876
|
+
rbs_location_range range = { .start_char = start.char_pos, .start_byte = start.byte_pos, .end_char = end.char_pos, .end_byte = end.byte_pos };
|
|
877
|
+
*proc = rbs_types_proc_new(ALLOCATOR(), range, result->function, result->block, result->function_self_type);
|
|
878
|
+
return true;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
static void check_key_duplication(rbs_parser_t *parser, rbs_hash_t *fields, rbs_node_t *key) {
|
|
882
|
+
if (rbs_hash_find(fields, ((rbs_node_t *) key))) {
|
|
883
|
+
rbs_parser_set_error(parser, parser->current_token, true, "duplicated record key");
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
/**
|
|
888
|
+
* ... `{` ... `}` ...
|
|
889
|
+
* > >
|
|
890
|
+
* */
|
|
891
|
+
/*
|
|
892
|
+
record_attributes ::= {`{`} record_attribute... <record_attribute> `}`
|
|
893
|
+
|
|
894
|
+
record_attribute ::= {} keyword_token `:` <type>
|
|
895
|
+
| {} literal_type `=>` <type>
|
|
896
|
+
*/
|
|
897
|
+
NODISCARD
|
|
898
|
+
static bool parse_record_attributes(rbs_parser_t *parser, rbs_hash_t **fields, bool self_allowed, bool classish_allowed) {
|
|
899
|
+
*fields = rbs_hash_new(ALLOCATOR());
|
|
900
|
+
|
|
901
|
+
if (parser->next_token.type == pRBRACE) return true;
|
|
902
|
+
|
|
903
|
+
while (true) {
|
|
904
|
+
rbs_ast_symbol_t *key = NULL;
|
|
905
|
+
bool required = true;
|
|
906
|
+
|
|
907
|
+
if (parser->next_token.type == pQUESTION) {
|
|
908
|
+
// { ?foo: type } syntax
|
|
909
|
+
required = false;
|
|
910
|
+
rbs_parser_advance(parser);
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
if (is_keyword(parser)) {
|
|
914
|
+
// { foo: type } syntax
|
|
915
|
+
CHECK_PARSE(parse_keyword_key(parser, &key));
|
|
916
|
+
|
|
917
|
+
check_key_duplication(parser, *fields, (rbs_node_t *) key);
|
|
918
|
+
ADVANCE_ASSERT(parser, pCOLON);
|
|
919
|
+
} else {
|
|
920
|
+
// { key => type } syntax
|
|
921
|
+
switch (parser->next_token.type) {
|
|
922
|
+
case tSYMBOL:
|
|
923
|
+
case tSQSYMBOL:
|
|
924
|
+
case tDQSYMBOL:
|
|
925
|
+
case tSQSTRING:
|
|
926
|
+
case tDQSTRING:
|
|
927
|
+
case tINTEGER:
|
|
928
|
+
case kTRUE:
|
|
929
|
+
case kFALSE: {
|
|
930
|
+
rbs_node_t *type = NULL;
|
|
931
|
+
CHECK_PARSE(parse_simple(parser, &type, false, self_allowed, classish_allowed));
|
|
932
|
+
|
|
933
|
+
key = (rbs_ast_symbol_t *) ((rbs_types_literal_t *) type)->literal;
|
|
934
|
+
break;
|
|
935
|
+
}
|
|
936
|
+
default:
|
|
937
|
+
rbs_parser_set_error(parser, parser->next_token, true, "unexpected record key token");
|
|
938
|
+
return false;
|
|
939
|
+
}
|
|
940
|
+
check_key_duplication(parser, *fields, (rbs_node_t *) key);
|
|
941
|
+
ADVANCE_ASSERT(parser, pFATARROW);
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
rbs_range_t field_range;
|
|
945
|
+
field_range.start = parser->current_token.range.end;
|
|
946
|
+
|
|
947
|
+
rbs_node_t *type;
|
|
948
|
+
CHECK_PARSE(rbs_parse_type(parser, &type, false, self_allowed, classish_allowed));
|
|
949
|
+
|
|
950
|
+
field_range.end = parser->current_token.range.end;
|
|
951
|
+
rbs_hash_set(*fields, (rbs_node_t *) key, (rbs_node_t *) rbs_types_record_field_type_new(ALLOCATOR(), RBS_RANGE_LEX2AST(field_range), type, required));
|
|
952
|
+
|
|
953
|
+
if (parser_advance_if(parser, pCOMMA)) {
|
|
954
|
+
if (parser->next_token.type == pRBRACE) {
|
|
955
|
+
break;
|
|
956
|
+
}
|
|
957
|
+
} else {
|
|
958
|
+
break;
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
return true;
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
/*
|
|
965
|
+
symbol ::= {<tSYMBOL>}
|
|
966
|
+
*/
|
|
967
|
+
NODISCARD
|
|
968
|
+
static bool parse_symbol(rbs_parser_t *parser, rbs_location_range location, rbs_types_literal_t **symbol) {
|
|
969
|
+
size_t offset_bytes = parser->lexer->encoding->char_width((const uint8_t *) ":", (size_t) 1);
|
|
970
|
+
size_t bytes = rbs_token_bytes(parser->current_token) - offset_bytes;
|
|
971
|
+
|
|
972
|
+
rbs_ast_symbol_t *literal;
|
|
973
|
+
|
|
974
|
+
switch (parser->current_token.type) {
|
|
975
|
+
case tSYMBOL: {
|
|
976
|
+
rbs_location_range symbol_range = rbs_location_range_current_token(parser);
|
|
977
|
+
|
|
978
|
+
char *buffer = rbs_peek_token(parser->lexer, parser->current_token);
|
|
979
|
+
rbs_constant_id_t constant_id = rbs_constant_pool_insert_shared(
|
|
980
|
+
&parser->constant_pool,
|
|
981
|
+
(const uint8_t *) buffer + offset_bytes,
|
|
982
|
+
bytes
|
|
983
|
+
);
|
|
984
|
+
literal = rbs_ast_symbol_new(ALLOCATOR(), symbol_range, &parser->constant_pool, constant_id);
|
|
985
|
+
break;
|
|
986
|
+
}
|
|
987
|
+
case tDQSYMBOL:
|
|
988
|
+
case tSQSYMBOL: {
|
|
989
|
+
rbs_location_range symbol_range = rbs_location_range_current_token(parser);
|
|
990
|
+
rbs_string_t current_token = rbs_parser_peek_current_token(parser);
|
|
991
|
+
|
|
992
|
+
rbs_string_t symbol = rbs_string_new(current_token.start + offset_bytes, current_token.end);
|
|
993
|
+
|
|
994
|
+
rbs_string_t unquoted_symbol = rbs_unquote_string(ALLOCATOR(), symbol, parser->lexer->encoding);
|
|
995
|
+
|
|
996
|
+
rbs_constant_id_t constant_id = rbs_constant_pool_insert_string(&parser->constant_pool, unquoted_symbol);
|
|
997
|
+
|
|
998
|
+
literal = rbs_ast_symbol_new(ALLOCATOR(), symbol_range, &parser->constant_pool, constant_id);
|
|
999
|
+
break;
|
|
1000
|
+
}
|
|
1001
|
+
default:
|
|
1002
|
+
rbs_parser_set_error(parser, parser->current_token, false, "Unexpected error");
|
|
1003
|
+
return false;
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
*symbol = rbs_types_literal_new(ALLOCATOR(), location, (rbs_node_t *) literal);
|
|
1007
|
+
return true;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
/*
|
|
1011
|
+
instance_type ::= {type_name} <type_args>
|
|
1012
|
+
|
|
1013
|
+
type_args ::= {} <> /empty/
|
|
1014
|
+
| {} `[` type_list <`]`>
|
|
1015
|
+
*/
|
|
1016
|
+
NODISCARD
|
|
1017
|
+
static bool parse_instance_type(rbs_parser_t *parser, bool parse_alias, rbs_node_t **type) {
|
|
1018
|
+
TypeNameKind expected_kind = (TypeNameKind) (INTERFACE_NAME | CLASS_NAME);
|
|
1019
|
+
if (parse_alias) {
|
|
1020
|
+
expected_kind = (TypeNameKind) (expected_kind | ALIAS_NAME);
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
rbs_range_t name_range;
|
|
1024
|
+
rbs_type_name_t *type_name = NULL;
|
|
1025
|
+
CHECK_PARSE(parse_type_name(parser, expected_kind, &name_range, &type_name));
|
|
1026
|
+
|
|
1027
|
+
rbs_node_list_t *types = rbs_node_list_new(ALLOCATOR());
|
|
1028
|
+
|
|
1029
|
+
TypeNameKind kind;
|
|
1030
|
+
switch (parser->current_token.type) {
|
|
1031
|
+
case tUIDENT: {
|
|
1032
|
+
kind = CLASS_NAME;
|
|
1033
|
+
break;
|
|
1034
|
+
}
|
|
1035
|
+
case tULIDENT: {
|
|
1036
|
+
kind = INTERFACE_NAME;
|
|
1037
|
+
break;
|
|
1038
|
+
}
|
|
1039
|
+
case kSKIP:
|
|
1040
|
+
case kRETURN:
|
|
1041
|
+
case tLIDENT: {
|
|
1042
|
+
kind = ALIAS_NAME;
|
|
1043
|
+
break;
|
|
1044
|
+
}
|
|
1045
|
+
default:
|
|
1046
|
+
rbs_parser_set_error(parser, parser->current_token, false, "unexpected token for type name");
|
|
1047
|
+
return false;
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
rbs_range_t args_range;
|
|
1051
|
+
if (parser->next_token.type == pLBRACKET) {
|
|
1052
|
+
rbs_parser_advance(parser);
|
|
1053
|
+
args_range.start = parser->current_token.range.start;
|
|
1054
|
+
CHECK_PARSE(parse_type_list(parser, pRBRACKET, types, true, true, true));
|
|
1055
|
+
ADVANCE_ASSERT(parser, pRBRACKET);
|
|
1056
|
+
args_range.end = parser->current_token.range.end;
|
|
1057
|
+
} else {
|
|
1058
|
+
args_range = NULL_RANGE;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
rbs_range_t type_range = {
|
|
1062
|
+
.start = name_range.start,
|
|
1063
|
+
.end = rbs_nonnull_pos_or(args_range.end, name_range.end),
|
|
1064
|
+
};
|
|
1065
|
+
|
|
1066
|
+
rbs_location_range loc = RBS_RANGE_LEX2AST(type_range);
|
|
1067
|
+
|
|
1068
|
+
if (kind == CLASS_NAME) {
|
|
1069
|
+
rbs_types_class_instance_t *instance_type = rbs_types_class_instance_new(ALLOCATOR(), loc, type_name, types, RBS_RANGE_LEX2AST(name_range));
|
|
1070
|
+
instance_type->args_range = RBS_RANGE_LEX2AST(args_range);
|
|
1071
|
+
*type = (rbs_node_t *) instance_type;
|
|
1072
|
+
} else if (kind == INTERFACE_NAME) {
|
|
1073
|
+
rbs_types_interface_t *interface_type = rbs_types_interface_new(ALLOCATOR(), loc, type_name, types, RBS_RANGE_LEX2AST(name_range));
|
|
1074
|
+
interface_type->args_range = RBS_RANGE_LEX2AST(args_range);
|
|
1075
|
+
*type = (rbs_node_t *) interface_type;
|
|
1076
|
+
} else if (kind == ALIAS_NAME) {
|
|
1077
|
+
rbs_types_alias_t *type_alias = rbs_types_alias_new(ALLOCATOR(), loc, type_name, types, RBS_RANGE_LEX2AST(name_range));
|
|
1078
|
+
type_alias->args_range = RBS_RANGE_LEX2AST(args_range);
|
|
1079
|
+
*type = (rbs_node_t *) type_alias;
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
return true;
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
/*
|
|
1086
|
+
singleton_type ::= {`singleton`} `(` type_name <`)`> type_args?
|
|
1087
|
+
*/
|
|
1088
|
+
NODISCARD
|
|
1089
|
+
static bool parse_singleton_type(rbs_parser_t *parser, rbs_types_class_singleton_t **singleton, bool self_allowed, bool classish_allowed) {
|
|
1090
|
+
ASSERT_TOKEN(parser, kSINGLETON);
|
|
1091
|
+
|
|
1092
|
+
rbs_range_t type_range;
|
|
1093
|
+
type_range.start = parser->current_token.range.start;
|
|
1094
|
+
ADVANCE_ASSERT(parser, pLPAREN);
|
|
1095
|
+
rbs_parser_advance(parser);
|
|
1096
|
+
|
|
1097
|
+
rbs_range_t name_range;
|
|
1098
|
+
rbs_type_name_t *type_name = NULL;
|
|
1099
|
+
CHECK_PARSE(parse_type_name(parser, CLASS_NAME, &name_range, &type_name));
|
|
1100
|
+
|
|
1101
|
+
ADVANCE_ASSERT(parser, pRPAREN);
|
|
1102
|
+
|
|
1103
|
+
rbs_node_list_t *types = rbs_node_list_new(ALLOCATOR());
|
|
1104
|
+
|
|
1105
|
+
rbs_location_range args_range = RBS_LOCATION_NULL_RANGE;
|
|
1106
|
+
if (parser->next_token.type == pLBRACKET) {
|
|
1107
|
+
rbs_parser_advance(parser);
|
|
1108
|
+
args_range.start_byte = parser->current_token.range.start.byte_pos;
|
|
1109
|
+
args_range.start_char = parser->current_token.range.start.char_pos;
|
|
1110
|
+
CHECK_PARSE(parse_type_list(parser, pRBRACKET, types, true, self_allowed, classish_allowed));
|
|
1111
|
+
ADVANCE_ASSERT(parser, pRBRACKET);
|
|
1112
|
+
args_range.end_byte = parser->current_token.range.end.byte_pos;
|
|
1113
|
+
args_range.end_char = parser->current_token.range.end.char_pos;
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
type_range.end = parser->current_token.range.end;
|
|
1117
|
+
rbs_location_range loc = RBS_RANGE_LEX2AST(type_range);
|
|
1118
|
+
|
|
1119
|
+
*singleton = rbs_types_class_singleton_new(ALLOCATOR(), loc, type_name, types, RBS_RANGE_LEX2AST(name_range));
|
|
1120
|
+
(*singleton)->args_range = args_range;
|
|
1121
|
+
|
|
1122
|
+
return true;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
/**
|
|
1126
|
+
* Returns true if given type variable is recorded in the table.
|
|
1127
|
+
* If not found, it goes one table up, if it's not a reset table.
|
|
1128
|
+
* Or returns false, if it's a reset table.
|
|
1129
|
+
* */
|
|
1130
|
+
static bool parser_typevar_member(rbs_parser_t *parser, rbs_constant_id_t id) {
|
|
1131
|
+
id_table *table = parser->vars;
|
|
1132
|
+
|
|
1133
|
+
while (table && !RESET_TABLE_P(table)) {
|
|
1134
|
+
for (size_t i = 0; i < table->count; i++) {
|
|
1135
|
+
if (table->ids[i] == id) {
|
|
1136
|
+
return true;
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
table = table->next;
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
return false;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
/*
|
|
1147
|
+
simple ::= {} `(` type <`)`>
|
|
1148
|
+
| {} <base type>
|
|
1149
|
+
| {} <type_name>
|
|
1150
|
+
| {} class_instance `[` type_list <`]`>
|
|
1151
|
+
| {} `singleton` `(` type_name <`)`>
|
|
1152
|
+
| {} `[` type_list <`]`>
|
|
1153
|
+
| {} `{` record_attributes <`}`>
|
|
1154
|
+
| {} `^` <function>
|
|
1155
|
+
*/
|
|
1156
|
+
NODISCARD
|
|
1157
|
+
static bool parse_simple(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed, bool self_allowed, bool classish_allowed) {
|
|
1158
|
+
rbs_parser_advance(parser);
|
|
1159
|
+
|
|
1160
|
+
switch (parser->current_token.type) {
|
|
1161
|
+
case pLPAREN: {
|
|
1162
|
+
rbs_node_t *lparen_type;
|
|
1163
|
+
CHECK_PARSE(rbs_parse_type(parser, &lparen_type, void_allowed, self_allowed, classish_allowed));
|
|
1164
|
+
ADVANCE_ASSERT(parser, pRPAREN);
|
|
1165
|
+
*type = lparen_type;
|
|
1166
|
+
return true;
|
|
1167
|
+
}
|
|
1168
|
+
case kBOOL: {
|
|
1169
|
+
rbs_location_range loc = rbs_location_range_current_token(parser);
|
|
1170
|
+
*type = (rbs_node_t *) rbs_types_bases_bool_new(ALLOCATOR(), loc);
|
|
1171
|
+
return true;
|
|
1172
|
+
}
|
|
1173
|
+
case kBOT: {
|
|
1174
|
+
rbs_location_range loc = rbs_location_range_current_token(parser);
|
|
1175
|
+
*type = (rbs_node_t *) rbs_types_bases_bottom_new(ALLOCATOR(), loc);
|
|
1176
|
+
return true;
|
|
1177
|
+
}
|
|
1178
|
+
case kCLASS: {
|
|
1179
|
+
if (!classish_allowed) {
|
|
1180
|
+
rbs_parser_set_error(parser, parser->current_token, true, "class type is not allowed here");
|
|
1181
|
+
return false;
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
rbs_location_range loc = rbs_location_range_current_token(parser);
|
|
1185
|
+
*type = (rbs_node_t *) rbs_types_bases_class_new(ALLOCATOR(), loc);
|
|
1186
|
+
return true;
|
|
1187
|
+
}
|
|
1188
|
+
case kINSTANCE: {
|
|
1189
|
+
if (!classish_allowed) {
|
|
1190
|
+
rbs_parser_set_error(parser, parser->current_token, true, "instance type is not allowed here");
|
|
1191
|
+
return false;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
rbs_location_range loc = rbs_location_range_current_token(parser);
|
|
1195
|
+
*type = (rbs_node_t *) rbs_types_bases_instance_new(ALLOCATOR(), loc);
|
|
1196
|
+
return true;
|
|
1197
|
+
}
|
|
1198
|
+
case kNIL: {
|
|
1199
|
+
rbs_location_range loc = rbs_location_range_current_token(parser);
|
|
1200
|
+
*type = (rbs_node_t *) rbs_types_bases_nil_new(ALLOCATOR(), loc);
|
|
1201
|
+
return true;
|
|
1202
|
+
}
|
|
1203
|
+
case kSELF: {
|
|
1204
|
+
if (!self_allowed) {
|
|
1205
|
+
rbs_parser_set_error(parser, parser->current_token, true, "self type is not allowed here");
|
|
1206
|
+
return false;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
rbs_location_range loc = rbs_location_range_current_token(parser);
|
|
1210
|
+
*type = (rbs_node_t *) rbs_types_bases_self_new(ALLOCATOR(), loc);
|
|
1211
|
+
return true;
|
|
1212
|
+
}
|
|
1213
|
+
case kTOP: {
|
|
1214
|
+
rbs_location_range loc = rbs_location_range_current_token(parser);
|
|
1215
|
+
*type = (rbs_node_t *) rbs_types_bases_top_new(ALLOCATOR(), loc);
|
|
1216
|
+
return true;
|
|
1217
|
+
}
|
|
1218
|
+
case kVOID: {
|
|
1219
|
+
if (!void_allowed) {
|
|
1220
|
+
rbs_parser_set_error(parser, parser->current_token, true, "void type is not allowed here");
|
|
1221
|
+
return false;
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
rbs_location_range loc = rbs_location_range_current_token(parser);
|
|
1225
|
+
*type = (rbs_node_t *) rbs_types_bases_void_new(ALLOCATOR(), loc);
|
|
1226
|
+
return true;
|
|
1227
|
+
}
|
|
1228
|
+
case kUNTYPED: {
|
|
1229
|
+
rbs_location_range loc = rbs_location_range_current_token(parser);
|
|
1230
|
+
*type = (rbs_node_t *) rbs_types_bases_any_new(ALLOCATOR(), loc, false);
|
|
1231
|
+
return true;
|
|
1232
|
+
}
|
|
1233
|
+
case k__TODO__: {
|
|
1234
|
+
rbs_location_range loc = rbs_location_range_current_token(parser);
|
|
1235
|
+
*type = (rbs_node_t *) rbs_types_bases_any_new(ALLOCATOR(), loc, true);
|
|
1236
|
+
return true;
|
|
1237
|
+
}
|
|
1238
|
+
case tINTEGER: {
|
|
1239
|
+
rbs_location_range loc = rbs_location_range_current_token(parser);
|
|
1240
|
+
|
|
1241
|
+
rbs_string_t string = rbs_parser_peek_current_token(parser);
|
|
1242
|
+
rbs_string_t stripped_string = rbs_string_strip_whitespace(&string);
|
|
1243
|
+
|
|
1244
|
+
rbs_node_t *literal = (rbs_node_t *) rbs_ast_integer_new(ALLOCATOR(), loc, stripped_string);
|
|
1245
|
+
*type = (rbs_node_t *) rbs_types_literal_new(ALLOCATOR(), loc, literal);
|
|
1246
|
+
return true;
|
|
1247
|
+
}
|
|
1248
|
+
case kTRUE: {
|
|
1249
|
+
rbs_location_range loc = rbs_location_range_current_token(parser);
|
|
1250
|
+
*type = (rbs_node_t *) rbs_types_literal_new(ALLOCATOR(), loc, (rbs_node_t *) rbs_ast_bool_new(ALLOCATOR(), loc, true));
|
|
1251
|
+
return true;
|
|
1252
|
+
}
|
|
1253
|
+
case kFALSE: {
|
|
1254
|
+
rbs_location_range loc = rbs_location_range_current_token(parser);
|
|
1255
|
+
*type = (rbs_node_t *) rbs_types_literal_new(ALLOCATOR(), loc, (rbs_node_t *) rbs_ast_bool_new(ALLOCATOR(), loc, false));
|
|
1256
|
+
return true;
|
|
1257
|
+
}
|
|
1258
|
+
case tSQSTRING:
|
|
1259
|
+
case tDQSTRING: {
|
|
1260
|
+
rbs_location_range loc = rbs_location_range_current_token(parser);
|
|
1261
|
+
|
|
1262
|
+
rbs_string_t unquoted_str = rbs_unquote_string(ALLOCATOR(), rbs_parser_peek_current_token(parser), parser->lexer->encoding);
|
|
1263
|
+
rbs_node_t *literal = (rbs_node_t *) rbs_ast_string_new(ALLOCATOR(), loc, unquoted_str);
|
|
1264
|
+
*type = (rbs_node_t *) rbs_types_literal_new(ALLOCATOR(), loc, literal);
|
|
1265
|
+
return true;
|
|
1266
|
+
}
|
|
1267
|
+
case tSYMBOL:
|
|
1268
|
+
case tSQSYMBOL:
|
|
1269
|
+
case tDQSYMBOL: {
|
|
1270
|
+
rbs_location_range loc = rbs_location_range_current_token(parser);
|
|
1271
|
+
rbs_types_literal_t *literal = NULL;
|
|
1272
|
+
CHECK_PARSE(parse_symbol(parser, loc, &literal));
|
|
1273
|
+
*type = (rbs_node_t *) literal;
|
|
1274
|
+
return true;
|
|
1275
|
+
}
|
|
1276
|
+
case tUIDENT: {
|
|
1277
|
+
const char *name_str = rbs_peek_token(parser->lexer, parser->current_token);
|
|
1278
|
+
size_t name_len = rbs_token_bytes(parser->current_token);
|
|
1279
|
+
|
|
1280
|
+
rbs_constant_id_t name = rbs_constant_pool_find(&parser->constant_pool, (const uint8_t *) name_str, name_len);
|
|
1281
|
+
|
|
1282
|
+
if (parser_typevar_member(parser, name)) {
|
|
1283
|
+
rbs_location_range loc = rbs_location_range_current_token(parser);
|
|
1284
|
+
rbs_ast_symbol_t *symbol = rbs_ast_symbol_new(ALLOCATOR(), loc, &parser->constant_pool, name);
|
|
1285
|
+
*type = (rbs_node_t *) rbs_types_variable_new(ALLOCATOR(), loc, symbol);
|
|
1286
|
+
return true;
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
RBS_FALLTHROUGH // for type name
|
|
1290
|
+
}
|
|
1291
|
+
case tULIDENT:
|
|
1292
|
+
case tLIDENT:
|
|
1293
|
+
case kSKIP:
|
|
1294
|
+
case kRETURN:
|
|
1295
|
+
case pCOLON2: {
|
|
1296
|
+
rbs_node_t *instance_type = NULL;
|
|
1297
|
+
CHECK_PARSE(parse_instance_type(parser, true, &instance_type));
|
|
1298
|
+
*type = instance_type;
|
|
1299
|
+
return true;
|
|
1300
|
+
}
|
|
1301
|
+
case kSINGLETON: {
|
|
1302
|
+
rbs_types_class_singleton_t *singleton = NULL;
|
|
1303
|
+
CHECK_PARSE(parse_singleton_type(parser, &singleton, self_allowed, classish_allowed));
|
|
1304
|
+
*type = (rbs_node_t *) singleton;
|
|
1305
|
+
return true;
|
|
1306
|
+
}
|
|
1307
|
+
case pLBRACKET: {
|
|
1308
|
+
rbs_range_t rg;
|
|
1309
|
+
rg.start = parser->current_token.range.start;
|
|
1310
|
+
rbs_node_list_t *types = rbs_node_list_new(ALLOCATOR());
|
|
1311
|
+
if (parser->next_token.type != pRBRACKET) {
|
|
1312
|
+
CHECK_PARSE(parse_type_list(parser, pRBRACKET, types, false, self_allowed, classish_allowed));
|
|
1313
|
+
}
|
|
1314
|
+
ADVANCE_ASSERT(parser, pRBRACKET);
|
|
1315
|
+
rg.end = parser->current_token.range.end;
|
|
1316
|
+
|
|
1317
|
+
*type = (rbs_node_t *) rbs_types_tuple_new(ALLOCATOR(), RBS_RANGE_LEX2AST(rg), types);
|
|
1318
|
+
return true;
|
|
1319
|
+
}
|
|
1320
|
+
case pAREF_OPR: {
|
|
1321
|
+
rbs_location_range loc = rbs_location_range_current_token(parser);
|
|
1322
|
+
rbs_node_list_t *types = rbs_node_list_new(ALLOCATOR());
|
|
1323
|
+
*type = (rbs_node_t *) rbs_types_tuple_new(ALLOCATOR(), loc, types);
|
|
1324
|
+
return true;
|
|
1325
|
+
}
|
|
1326
|
+
case pLBRACE: {
|
|
1327
|
+
rbs_position_t start = parser->current_token.range.start;
|
|
1328
|
+
rbs_hash_t *fields = NULL;
|
|
1329
|
+
CHECK_PARSE(parse_record_attributes(parser, &fields, self_allowed, classish_allowed));
|
|
1330
|
+
ADVANCE_ASSERT(parser, pRBRACE);
|
|
1331
|
+
rbs_position_t end = parser->current_token.range.end;
|
|
1332
|
+
rbs_location_range loc = { .start_char = start.char_pos, .start_byte = start.byte_pos, .end_char = end.char_pos, .end_byte = end.byte_pos };
|
|
1333
|
+
*type = (rbs_node_t *) rbs_types_record_new(ALLOCATOR(), loc, fields);
|
|
1334
|
+
return true;
|
|
1335
|
+
}
|
|
1336
|
+
case pHAT: {
|
|
1337
|
+
rbs_types_proc_t *value = NULL;
|
|
1338
|
+
CHECK_PARSE(parse_proc_type(parser, &value, self_allowed, classish_allowed));
|
|
1339
|
+
*type = (rbs_node_t *) value;
|
|
1340
|
+
return true;
|
|
1341
|
+
}
|
|
1342
|
+
default:
|
|
1343
|
+
rbs_parser_set_error(parser, parser->current_token, true, "unexpected token for simple type");
|
|
1344
|
+
return false;
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
/*
|
|
1349
|
+
intersection ::= {} optional `&` ... '&' <optional>
|
|
1350
|
+
| {} <optional>
|
|
1351
|
+
*/
|
|
1352
|
+
NODISCARD
|
|
1353
|
+
static bool parse_intersection(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed, bool self_allowed, bool classish_allowed) {
|
|
1354
|
+
rbs_range_t rg;
|
|
1355
|
+
rg.start = parser->next_token.range.start;
|
|
1356
|
+
|
|
1357
|
+
rbs_node_t *optional = NULL;
|
|
1358
|
+
CHECK_PARSE(parse_optional(parser, &optional, void_allowed, self_allowed, classish_allowed));
|
|
1359
|
+
*type = optional;
|
|
1360
|
+
|
|
1361
|
+
rbs_node_list_t *intersection_types = rbs_node_list_new(ALLOCATOR());
|
|
1362
|
+
|
|
1363
|
+
rbs_node_list_append(intersection_types, optional);
|
|
1364
|
+
while (parser->next_token.type == pAMP) {
|
|
1365
|
+
if (void_allowed && (*type)->type == RBS_TYPES_BASES_VOID) {
|
|
1366
|
+
rbs_parser_set_error(parser, parser->current_token, true, "void type is not allowed here");
|
|
1367
|
+
return false;
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
rbs_parser_advance(parser);
|
|
1371
|
+
rbs_node_t *type = NULL;
|
|
1372
|
+
CHECK_PARSE(parse_optional(parser, &type, false, self_allowed, classish_allowed));
|
|
1373
|
+
rbs_node_list_append(intersection_types, type);
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
rg.end = parser->current_token.range.end;
|
|
1377
|
+
|
|
1378
|
+
if (intersection_types->length > 1) {
|
|
1379
|
+
*type = (rbs_node_t *) rbs_types_intersection_new(ALLOCATOR(), RBS_RANGE_LEX2AST(rg), intersection_types);
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
return true;
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
/*
|
|
1386
|
+
union ::= {} intersection '|' ... '|' <intersection>
|
|
1387
|
+
| {} <intersection>
|
|
1388
|
+
*/
|
|
1389
|
+
bool rbs_parse_type(rbs_parser_t *parser, rbs_node_t **type, bool void_allowed, bool self_allowed, bool classish_allowed) {
|
|
1390
|
+
rbs_range_t rg;
|
|
1391
|
+
rg.start = parser->next_token.range.start;
|
|
1392
|
+
rbs_node_list_t *union_types = rbs_node_list_new(ALLOCATOR());
|
|
1393
|
+
|
|
1394
|
+
CHECK_PARSE(parse_intersection(parser, type, void_allowed, self_allowed, classish_allowed));
|
|
1395
|
+
|
|
1396
|
+
rbs_node_list_append(union_types, *type);
|
|
1397
|
+
|
|
1398
|
+
while (parser->next_token.type == pBAR) {
|
|
1399
|
+
if (void_allowed && (*type)->type == RBS_TYPES_BASES_VOID) {
|
|
1400
|
+
rbs_parser_set_error(parser, parser->current_token, true, "void type is not allowed here");
|
|
1401
|
+
return false;
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
rbs_parser_advance(parser);
|
|
1405
|
+
rbs_node_t *intersection = NULL;
|
|
1406
|
+
CHECK_PARSE(parse_intersection(parser, &intersection, false, self_allowed, classish_allowed));
|
|
1407
|
+
rbs_node_list_append(union_types, intersection);
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
rg.end = parser->current_token.range.end;
|
|
1411
|
+
|
|
1412
|
+
if (union_types->length > 1) {
|
|
1413
|
+
*type = (rbs_node_t *) rbs_types_union_new(ALLOCATOR(), RBS_RANGE_LEX2AST(rg), union_types);
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
return true;
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
/*
|
|
1420
|
+
type_params ::= {} `[` type_param `,` ... <`]`>
|
|
1421
|
+
| {<>}
|
|
1422
|
+
|
|
1423
|
+
type_param ::= kUNCHECKED? (kIN|kOUT|) tUIDENT upper_bound? lower_bound? default_type? (module_type_params == true)
|
|
1424
|
+
|
|
1425
|
+
type_param ::= tUIDENT upper_bound? lower_bound? default_type? (module_type_params == false)
|
|
1426
|
+
*/
|
|
1427
|
+
NODISCARD
|
|
1428
|
+
static bool parse_type_params(rbs_parser_t *parser, rbs_range_t *rg, bool module_type_params, rbs_node_list_t **params) {
|
|
1429
|
+
*params = rbs_node_list_new(ALLOCATOR());
|
|
1430
|
+
|
|
1431
|
+
bool required_param_allowed = true;
|
|
1432
|
+
|
|
1433
|
+
if (parser->next_token.type == pLBRACKET) {
|
|
1434
|
+
rbs_parser_advance(parser);
|
|
1435
|
+
|
|
1436
|
+
rg->start = parser->current_token.range.start;
|
|
1437
|
+
|
|
1438
|
+
while (true) {
|
|
1439
|
+
bool unchecked = false;
|
|
1440
|
+
enum rbs_type_param_variance variance = RBS_TYPE_PARAM_VARIANCE_INVARIANT;
|
|
1441
|
+
rbs_node_t *upper_bound = NULL;
|
|
1442
|
+
rbs_node_t *lower_bound = NULL;
|
|
1443
|
+
rbs_node_t *default_type = NULL;
|
|
1444
|
+
|
|
1445
|
+
rbs_range_t param_range;
|
|
1446
|
+
param_range.start = parser->next_token.range.start;
|
|
1447
|
+
|
|
1448
|
+
rbs_range_t unchecked_range = NULL_RANGE;
|
|
1449
|
+
rbs_range_t variance_range = NULL_RANGE;
|
|
1450
|
+
if (module_type_params) {
|
|
1451
|
+
if (parser->next_token.type == kUNCHECKED) {
|
|
1452
|
+
unchecked = true;
|
|
1453
|
+
rbs_parser_advance(parser);
|
|
1454
|
+
unchecked_range = parser->current_token.range;
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
if (parser->next_token.type == kIN || parser->next_token.type == kOUT) {
|
|
1458
|
+
switch (parser->next_token.type) {
|
|
1459
|
+
case kIN:
|
|
1460
|
+
variance = RBS_TYPE_PARAM_VARIANCE_CONTRAVARIANT;
|
|
1461
|
+
break;
|
|
1462
|
+
case kOUT:
|
|
1463
|
+
variance = RBS_TYPE_PARAM_VARIANCE_COVARIANT;
|
|
1464
|
+
break;
|
|
1465
|
+
default:
|
|
1466
|
+
rbs_parser_set_error(parser, parser->current_token, false, "Unexpected error");
|
|
1467
|
+
return false;
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
rbs_parser_advance(parser);
|
|
1471
|
+
variance_range = parser->current_token.range;
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
ADVANCE_ASSERT(parser, tUIDENT);
|
|
1476
|
+
rbs_range_t name_range = parser->current_token.range;
|
|
1477
|
+
|
|
1478
|
+
rbs_string_t string = rbs_parser_peek_current_token(parser);
|
|
1479
|
+
rbs_location_range name_symbol_range = rbs_location_range_current_token(parser);
|
|
1480
|
+
rbs_constant_id_t id = rbs_constant_pool_insert_string(&parser->constant_pool, string);
|
|
1481
|
+
rbs_ast_symbol_t *name = rbs_ast_symbol_new(ALLOCATOR(), name_symbol_range, &parser->constant_pool, id);
|
|
1482
|
+
|
|
1483
|
+
CHECK_PARSE(rbs_parser_insert_typevar(parser, id));
|
|
1484
|
+
|
|
1485
|
+
rbs_range_t upper_bound_range = NULL_RANGE;
|
|
1486
|
+
rbs_range_t lower_bound_range = NULL_RANGE;
|
|
1487
|
+
|
|
1488
|
+
for (int bound_parse_attempt = 0; bound_parse_attempt < 2; bound_parse_attempt++) {
|
|
1489
|
+
switch (parser->next_token.type) {
|
|
1490
|
+
case pLT:
|
|
1491
|
+
if (upper_bound != NULL) {
|
|
1492
|
+
rbs_parser_set_error(parser, parser->next_token, true, "duplicate upper bound ('<') for type parameter");
|
|
1493
|
+
return false;
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
rbs_parser_advance(parser);
|
|
1497
|
+
upper_bound_range.start = parser->current_token.range.start;
|
|
1498
|
+
CHECK_PARSE(rbs_parse_type(parser, &upper_bound, false, false, false));
|
|
1499
|
+
upper_bound_range.end = parser->current_token.range.end;
|
|
1500
|
+
break;
|
|
1501
|
+
|
|
1502
|
+
case pGT:
|
|
1503
|
+
if (lower_bound != NULL) {
|
|
1504
|
+
rbs_parser_set_error(parser, parser->next_token, true, "duplicate lower bound ('>') for type parameter");
|
|
1505
|
+
return false;
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
rbs_parser_advance(parser);
|
|
1509
|
+
lower_bound_range.start = parser->current_token.range.start;
|
|
1510
|
+
CHECK_PARSE(rbs_parse_type(parser, &lower_bound, false, false, false));
|
|
1511
|
+
lower_bound_range.end = parser->current_token.range.end;
|
|
1512
|
+
break;
|
|
1513
|
+
|
|
1514
|
+
default:
|
|
1515
|
+
break;
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
rbs_range_t default_type_range = NULL_RANGE;
|
|
1520
|
+
if (module_type_params) {
|
|
1521
|
+
if (parser->next_token.type == pEQ) {
|
|
1522
|
+
rbs_parser_advance(parser);
|
|
1523
|
+
|
|
1524
|
+
default_type_range.start = parser->current_token.range.start;
|
|
1525
|
+
CHECK_PARSE(rbs_parse_type(parser, &default_type, true, false, false));
|
|
1526
|
+
default_type_range.end = parser->current_token.range.end;
|
|
1527
|
+
|
|
1528
|
+
required_param_allowed = false;
|
|
1529
|
+
} else {
|
|
1530
|
+
if (!required_param_allowed) {
|
|
1531
|
+
rbs_parser_set_error(parser, parser->current_token, true, "required type parameter is not allowed after optional type parameter");
|
|
1532
|
+
return false;
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
param_range.end = parser->current_token.range.end;
|
|
1538
|
+
|
|
1539
|
+
rbs_ast_type_param_t *param = rbs_ast_type_param_new(ALLOCATOR(), RBS_RANGE_LEX2AST(param_range), name, variance, upper_bound, lower_bound, default_type, unchecked, RBS_RANGE_LEX2AST(name_range));
|
|
1540
|
+
param->variance_range = RBS_RANGE_LEX2AST(variance_range);
|
|
1541
|
+
param->unchecked_range = RBS_RANGE_LEX2AST(unchecked_range);
|
|
1542
|
+
param->upper_bound_range = RBS_RANGE_LEX2AST(upper_bound_range);
|
|
1543
|
+
param->lower_bound_range = RBS_RANGE_LEX2AST(lower_bound_range);
|
|
1544
|
+
param->default_range = RBS_RANGE_LEX2AST(default_type_range);
|
|
1545
|
+
|
|
1546
|
+
rbs_node_list_append(*params, (rbs_node_t *) param);
|
|
1547
|
+
|
|
1548
|
+
if (parser->next_token.type == pCOMMA) {
|
|
1549
|
+
rbs_parser_advance(parser);
|
|
1550
|
+
} else if (parser->next_token.type == pRBRACKET) {
|
|
1551
|
+
break;
|
|
1552
|
+
} else {
|
|
1553
|
+
rbs_parser_set_error(parser, parser->next_token, true, "expected ',' or ']' after type parameter, got %s", rbs_token_type_str(parser->next_token.type));
|
|
1554
|
+
return false;
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
|
|
1558
|
+
ADVANCE_ASSERT(parser, pRBRACKET);
|
|
1559
|
+
rg->end = parser->current_token.range.end;
|
|
1560
|
+
} else {
|
|
1561
|
+
*rg = NULL_RANGE;
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
return true;
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
NODISCARD
|
|
1568
|
+
static bool parser_pop_typevar_table(rbs_parser_t *parser) {
|
|
1569
|
+
id_table *table;
|
|
1570
|
+
|
|
1571
|
+
if (parser->vars) {
|
|
1572
|
+
table = parser->vars;
|
|
1573
|
+
parser->vars = table->next;
|
|
1574
|
+
} else {
|
|
1575
|
+
rbs_parser_set_error(parser, parser->current_token, false, "Cannot pop empty table");
|
|
1576
|
+
return false;
|
|
1577
|
+
}
|
|
1578
|
+
|
|
1579
|
+
if (parser->vars && RESET_TABLE_P(parser->vars)) {
|
|
1580
|
+
table = parser->vars;
|
|
1581
|
+
parser->vars = table->next;
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
return true;
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
/*
|
|
1588
|
+
method_type ::= {} type_params <function>
|
|
1589
|
+
*/
|
|
1590
|
+
// TODO: Should this be NODISCARD?
|
|
1591
|
+
bool rbs_parse_method_type(rbs_parser_t *parser, rbs_method_type_t **method_type, bool require_eof, bool classish_allowed) {
|
|
1592
|
+
rbs_parser_push_typevar_table(parser, false);
|
|
1593
|
+
|
|
1594
|
+
rbs_range_t rg;
|
|
1595
|
+
rg.start = parser->next_token.range.start;
|
|
1596
|
+
|
|
1597
|
+
rbs_range_t params_range = NULL_RANGE;
|
|
1598
|
+
rbs_node_list_t *type_params;
|
|
1599
|
+
CHECK_PARSE(parse_type_params(parser, ¶ms_range, false, &type_params));
|
|
1600
|
+
|
|
1601
|
+
rbs_range_t type_range;
|
|
1602
|
+
type_range.start = parser->next_token.range.start;
|
|
1603
|
+
|
|
1604
|
+
parse_function_result *result = rbs_allocator_alloc(ALLOCATOR(), parse_function_result);
|
|
1605
|
+
CHECK_PARSE(parse_function(parser, false, true, &result, true, classish_allowed));
|
|
1606
|
+
|
|
1607
|
+
CHECK_PARSE(parser_pop_typevar_table(parser));
|
|
1608
|
+
|
|
1609
|
+
rg.end = parser->current_token.range.end;
|
|
1610
|
+
type_range.end = rg.end;
|
|
1611
|
+
|
|
1612
|
+
if (require_eof) {
|
|
1613
|
+
rbs_parser_advance(parser);
|
|
1614
|
+
if (parser->current_token.type != pEOF) {
|
|
1615
|
+
rbs_parser_set_error(parser, parser->current_token, true, "expected a token `%s`", rbs_token_type_str(pEOF));
|
|
1616
|
+
return false;
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1620
|
+
*method_type = rbs_method_type_new(ALLOCATOR(), RBS_RANGE_LEX2AST(rg), type_params, result->function, result->block, RBS_RANGE_LEX2AST(type_range));
|
|
1621
|
+
(*method_type)->type_params_range = RBS_RANGE_LEX2AST(params_range);
|
|
1622
|
+
|
|
1623
|
+
return true;
|
|
1624
|
+
}
|
|
1625
|
+
|
|
1626
|
+
/*
|
|
1627
|
+
global_decl ::= {tGIDENT} `:` <type>
|
|
1628
|
+
*/
|
|
1629
|
+
NODISCARD
|
|
1630
|
+
static bool parse_global_decl(rbs_parser_t *parser, rbs_node_list_t *annotations, rbs_ast_declarations_global_t **global) {
|
|
1631
|
+
rbs_range_t decl_range;
|
|
1632
|
+
decl_range.start = parser->current_token.range.start;
|
|
1633
|
+
|
|
1634
|
+
rbs_ast_comment_t *comment = rbs_parser_get_comment(parser, decl_range.start.line);
|
|
1635
|
+
|
|
1636
|
+
rbs_range_t name_range = parser->current_token.range;
|
|
1637
|
+
|
|
1638
|
+
rbs_ast_symbol_t *type_name = rbs_ast_symbol_new(ALLOCATOR(), RBS_RANGE_LEX2AST(name_range), &parser->constant_pool, INTERN_TOKEN(parser, parser->current_token));
|
|
1639
|
+
|
|
1640
|
+
ADVANCE_ASSERT(parser, pCOLON);
|
|
1641
|
+
rbs_range_t colon_range = parser->current_token.range;
|
|
1642
|
+
|
|
1643
|
+
rbs_node_t *type;
|
|
1644
|
+
CHECK_PARSE(rbs_parse_type(parser, &type, false, false, false));
|
|
1645
|
+
decl_range.end = parser->current_token.range.end;
|
|
1646
|
+
|
|
1647
|
+
*global = rbs_ast_declarations_global_new(ALLOCATOR(), RBS_RANGE_LEX2AST(decl_range), type_name, type, comment, annotations, RBS_RANGE_LEX2AST(name_range), RBS_RANGE_LEX2AST(colon_range));
|
|
1648
|
+
return true;
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
/*
|
|
1652
|
+
const_decl ::= {const_name} `:` <type>
|
|
1653
|
+
*/
|
|
1654
|
+
NODISCARD
|
|
1655
|
+
static bool parse_const_decl(rbs_parser_t *parser, rbs_node_list_t *annotations, rbs_ast_declarations_constant_t **constant) {
|
|
1656
|
+
rbs_range_t decl_range;
|
|
1657
|
+
|
|
1658
|
+
decl_range.start = parser->current_token.range.start;
|
|
1659
|
+
rbs_ast_comment_t *comment = rbs_parser_get_comment(parser, decl_range.start.line);
|
|
1660
|
+
|
|
1661
|
+
rbs_range_t name_range;
|
|
1662
|
+
rbs_type_name_t *type_name = NULL;
|
|
1663
|
+
CHECK_PARSE(parse_type_name(parser, CLASS_NAME, &name_range, &type_name));
|
|
1664
|
+
|
|
1665
|
+
ADVANCE_ASSERT(parser, pCOLON);
|
|
1666
|
+
rbs_range_t colon_range = parser->current_token.range;
|
|
1667
|
+
|
|
1668
|
+
rbs_node_t *type;
|
|
1669
|
+
CHECK_PARSE(rbs_parse_type(parser, &type, false, false, false));
|
|
1670
|
+
|
|
1671
|
+
decl_range.end = parser->current_token.range.end;
|
|
1672
|
+
|
|
1673
|
+
*constant = rbs_ast_declarations_constant_new(ALLOCATOR(), RBS_RANGE_LEX2AST(decl_range), type_name, type, comment, annotations, RBS_RANGE_LEX2AST(name_range), RBS_RANGE_LEX2AST(colon_range));
|
|
1674
|
+
return true;
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
/*
|
|
1678
|
+
type_decl ::= {kTYPE} alias_name `=` <type>
|
|
1679
|
+
*/
|
|
1680
|
+
NODISCARD
|
|
1681
|
+
static bool parse_type_decl(rbs_parser_t *parser, rbs_position_t comment_pos, rbs_node_list_t *annotations, rbs_ast_declarations_type_alias_t **typealias) {
|
|
1682
|
+
rbs_parser_push_typevar_table(parser, true);
|
|
1683
|
+
|
|
1684
|
+
rbs_range_t decl_range;
|
|
1685
|
+
decl_range.start = parser->current_token.range.start;
|
|
1686
|
+
comment_pos = rbs_nonnull_pos_or(comment_pos, decl_range.start);
|
|
1687
|
+
|
|
1688
|
+
rbs_range_t keyword_range = parser->current_token.range;
|
|
1689
|
+
|
|
1690
|
+
rbs_parser_advance(parser);
|
|
1691
|
+
|
|
1692
|
+
rbs_range_t name_range;
|
|
1693
|
+
rbs_type_name_t *type_name = NULL;
|
|
1694
|
+
CHECK_PARSE(parse_type_name(parser, ALIAS_NAME, &name_range, &type_name));
|
|
1695
|
+
|
|
1696
|
+
rbs_range_t params_range;
|
|
1697
|
+
rbs_node_list_t *type_params;
|
|
1698
|
+
CHECK_PARSE(parse_type_params(parser, ¶ms_range, true, &type_params));
|
|
1699
|
+
|
|
1700
|
+
ADVANCE_ASSERT(parser, pEQ);
|
|
1701
|
+
rbs_range_t eq_range = parser->current_token.range;
|
|
1702
|
+
|
|
1703
|
+
rbs_node_t *type;
|
|
1704
|
+
CHECK_PARSE(rbs_parse_type(parser, &type, false, false, false));
|
|
1705
|
+
|
|
1706
|
+
decl_range.end = parser->current_token.range.end;
|
|
1707
|
+
|
|
1708
|
+
CHECK_PARSE(parser_pop_typevar_table(parser));
|
|
1709
|
+
|
|
1710
|
+
rbs_ast_comment_t *comment = rbs_parser_get_comment(parser, comment_pos.line);
|
|
1711
|
+
|
|
1712
|
+
*typealias = rbs_ast_declarations_type_alias_new(ALLOCATOR(), RBS_RANGE_LEX2AST(decl_range), type_name, type_params, type, annotations, comment, RBS_RANGE_LEX2AST(keyword_range), RBS_RANGE_LEX2AST(name_range), RBS_RANGE_LEX2AST(eq_range));
|
|
1713
|
+
(*typealias)->type_params_range = RBS_RANGE_LEX2AST(params_range);
|
|
1714
|
+
return true;
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
/*
|
|
1718
|
+
annotation ::= {<tANNOTATION>}
|
|
1719
|
+
*/
|
|
1720
|
+
NODISCARD
|
|
1721
|
+
static bool parse_annotation(rbs_parser_t *parser, rbs_ast_annotation_t **annotation) {
|
|
1722
|
+
rbs_range_t rg = parser->current_token.range;
|
|
1723
|
+
|
|
1724
|
+
size_t offset_bytes =
|
|
1725
|
+
parser->lexer->encoding->char_width((const uint8_t *) "%", (size_t) 1) +
|
|
1726
|
+
parser->lexer->encoding->char_width((const uint8_t *) "a", (size_t) 1);
|
|
1727
|
+
|
|
1728
|
+
rbs_string_t str = rbs_string_new(
|
|
1729
|
+
parser->lexer->string.start + rg.start.byte_pos + offset_bytes,
|
|
1730
|
+
parser->lexer->string.end
|
|
1731
|
+
);
|
|
1732
|
+
|
|
1733
|
+
// Assumes the input is ASCII compatible
|
|
1734
|
+
unsigned int open_char = str.start[0];
|
|
1735
|
+
|
|
1736
|
+
unsigned int close_char;
|
|
1737
|
+
|
|
1738
|
+
switch (open_char) {
|
|
1739
|
+
case '{':
|
|
1740
|
+
close_char = '}';
|
|
1741
|
+
break;
|
|
1742
|
+
case '(':
|
|
1743
|
+
close_char = ')';
|
|
1744
|
+
break;
|
|
1745
|
+
case '[':
|
|
1746
|
+
close_char = ']';
|
|
1747
|
+
break;
|
|
1748
|
+
case '<':
|
|
1749
|
+
close_char = '>';
|
|
1750
|
+
break;
|
|
1751
|
+
case '|':
|
|
1752
|
+
close_char = '|';
|
|
1753
|
+
break;
|
|
1754
|
+
default:
|
|
1755
|
+
rbs_parser_set_error(parser, parser->current_token, false, "Unexpected error");
|
|
1756
|
+
return false;
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1759
|
+
size_t open_bytes = parser->lexer->encoding->char_width((const uint8_t *) &open_char, (size_t) 1);
|
|
1760
|
+
size_t close_bytes = parser->lexer->encoding->char_width((const uint8_t *) &close_char, (size_t) 1);
|
|
1761
|
+
|
|
1762
|
+
rbs_string_t current_token = rbs_parser_peek_current_token(parser);
|
|
1763
|
+
size_t total_offset = offset_bytes + open_bytes;
|
|
1764
|
+
|
|
1765
|
+
rbs_string_t annotation_str = rbs_string_new(
|
|
1766
|
+
current_token.start + total_offset,
|
|
1767
|
+
current_token.end - close_bytes
|
|
1768
|
+
);
|
|
1769
|
+
|
|
1770
|
+
rbs_string_t stripped_annotation_str = rbs_string_strip_whitespace(&annotation_str);
|
|
1771
|
+
|
|
1772
|
+
*annotation = rbs_ast_annotation_new(ALLOCATOR(), RBS_RANGE_LEX2AST(rg), stripped_annotation_str);
|
|
1773
|
+
return true;
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
/*
|
|
1777
|
+
annotations ::= {} annotation ... <annotation>
|
|
1778
|
+
| {<>}
|
|
1779
|
+
*/
|
|
1780
|
+
NODISCARD
|
|
1781
|
+
static bool parse_annotations(rbs_parser_t *parser, rbs_node_list_t *annotations, rbs_position_t *annot_pos) {
|
|
1782
|
+
*annot_pos = NullPosition;
|
|
1783
|
+
|
|
1784
|
+
while (true) {
|
|
1785
|
+
if (parser->next_token.type == tANNOTATION) {
|
|
1786
|
+
rbs_parser_advance(parser);
|
|
1787
|
+
|
|
1788
|
+
if (rbs_null_position_p((*annot_pos))) {
|
|
1789
|
+
*annot_pos = parser->current_token.range.start;
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1792
|
+
rbs_ast_annotation_t *annotation = NULL;
|
|
1793
|
+
CHECK_PARSE(parse_annotation(parser, &annotation));
|
|
1794
|
+
rbs_node_list_append(annotations, (rbs_node_t *) annotation);
|
|
1795
|
+
} else {
|
|
1796
|
+
break;
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
return true;
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
/*
|
|
1804
|
+
method_name ::= {} <IDENT | keyword>
|
|
1805
|
+
| {} (IDENT | keyword)~<`?`>
|
|
1806
|
+
*/
|
|
1807
|
+
NODISCARD
|
|
1808
|
+
static bool parse_method_name(rbs_parser_t *parser, rbs_range_t *range, rbs_ast_symbol_t **symbol) {
|
|
1809
|
+
rbs_parser_advance(parser);
|
|
1810
|
+
|
|
1811
|
+
switch (parser->current_token.type) {
|
|
1812
|
+
case tUIDENT:
|
|
1813
|
+
case tLIDENT:
|
|
1814
|
+
case tULIDENT:
|
|
1815
|
+
case tULLIDENT:
|
|
1816
|
+
KEYWORD_CASES
|
|
1817
|
+
if (parser->next_token.type == pQUESTION && parser->current_token.range.end.byte_pos == parser->next_token.range.start.byte_pos) {
|
|
1818
|
+
range->start = parser->current_token.range.start;
|
|
1819
|
+
range->end = parser->next_token.range.end;
|
|
1820
|
+
rbs_parser_advance(parser);
|
|
1821
|
+
|
|
1822
|
+
rbs_constant_id_t constant_id = rbs_constant_pool_insert_shared_with_encoding(
|
|
1823
|
+
&parser->constant_pool,
|
|
1824
|
+
(const uint8_t *) parser->lexer->string.start + range->start.byte_pos,
|
|
1825
|
+
range->end.byte_pos - range->start.byte_pos,
|
|
1826
|
+
parser->lexer->encoding
|
|
1827
|
+
);
|
|
1828
|
+
|
|
1829
|
+
*symbol = rbs_ast_symbol_new(ALLOCATOR(), RBS_RANGE_LEX2AST(*range), &parser->constant_pool, constant_id);
|
|
1830
|
+
} else {
|
|
1831
|
+
*range = parser->current_token.range;
|
|
1832
|
+
*symbol = rbs_ast_symbol_new(ALLOCATOR(), RBS_RANGE_LEX2AST(*range), &parser->constant_pool, INTERN_TOKEN(parser, parser->current_token));
|
|
1833
|
+
}
|
|
1834
|
+
return true;
|
|
1835
|
+
|
|
1836
|
+
case tBANGIDENT:
|
|
1837
|
+
case tEQIDENT: {
|
|
1838
|
+
*range = parser->current_token.range;
|
|
1839
|
+
*symbol = rbs_ast_symbol_new(ALLOCATOR(), RBS_RANGE_LEX2AST(*range), &parser->constant_pool, INTERN_TOKEN(parser, parser->current_token));
|
|
1840
|
+
return true;
|
|
1841
|
+
}
|
|
1842
|
+
case tQIDENT: {
|
|
1843
|
+
rbs_string_t string = rbs_parser_peek_current_token(parser);
|
|
1844
|
+
rbs_string_t unquoted_str = rbs_unquote_string(ALLOCATOR(), string, parser->lexer->encoding);
|
|
1845
|
+
rbs_constant_id_t constant_id = rbs_constant_pool_insert_string(&parser->constant_pool, unquoted_str);
|
|
1846
|
+
*symbol = rbs_ast_symbol_new(ALLOCATOR(), rbs_location_range_current_token(parser), &parser->constant_pool, constant_id);
|
|
1847
|
+
return true;
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
case pBAR:
|
|
1851
|
+
case pHAT:
|
|
1852
|
+
case pAMP:
|
|
1853
|
+
case pSTAR:
|
|
1854
|
+
case pSTAR2:
|
|
1855
|
+
case pLT:
|
|
1856
|
+
case pGT:
|
|
1857
|
+
case pAREF_OPR:
|
|
1858
|
+
case tOPERATOR: {
|
|
1859
|
+
*range = parser->current_token.range;
|
|
1860
|
+
*symbol = rbs_ast_symbol_new(ALLOCATOR(), RBS_RANGE_LEX2AST(*range), &parser->constant_pool, INTERN_TOKEN(parser, parser->current_token));
|
|
1861
|
+
return true;
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1864
|
+
default:
|
|
1865
|
+
rbs_parser_set_error(parser, parser->current_token, true, "unexpected token for method name");
|
|
1866
|
+
return false;
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
|
|
1870
|
+
typedef enum {
|
|
1871
|
+
INSTANCE_KIND,
|
|
1872
|
+
SINGLETON_KIND,
|
|
1873
|
+
INSTANCE_SINGLETON_KIND
|
|
1874
|
+
} InstanceSingletonKind;
|
|
1875
|
+
|
|
1876
|
+
/*
|
|
1877
|
+
instance_singleton_kind ::= {<>}
|
|
1878
|
+
| {} kSELF <`.`>
|
|
1879
|
+
| {} kSELF~`?` <`.`>
|
|
1880
|
+
|
|
1881
|
+
@param allow_selfq `true` to accept `self?` kind.
|
|
1882
|
+
*/
|
|
1883
|
+
static InstanceSingletonKind parse_instance_singleton_kind(rbs_parser_t *parser, bool allow_selfq, rbs_range_t *rg) {
|
|
1884
|
+
InstanceSingletonKind kind = INSTANCE_KIND;
|
|
1885
|
+
|
|
1886
|
+
if (parser->next_token.type == kSELF) {
|
|
1887
|
+
rbs_range_t self_range = parser->next_token.range;
|
|
1888
|
+
|
|
1889
|
+
if (parser->next_token2.type == pDOT) {
|
|
1890
|
+
rbs_parser_advance(parser);
|
|
1891
|
+
rbs_parser_advance(parser);
|
|
1892
|
+
kind = SINGLETON_KIND;
|
|
1893
|
+
} else if (
|
|
1894
|
+
parser->next_token2.type == pQUESTION && parser->next_token.range.end.char_pos == parser->next_token2.range.start.char_pos && parser->next_token3.type == pDOT && allow_selfq
|
|
1895
|
+
) {
|
|
1896
|
+
rbs_parser_advance(parser);
|
|
1897
|
+
rbs_parser_advance(parser);
|
|
1898
|
+
rbs_parser_advance(parser);
|
|
1899
|
+
kind = INSTANCE_SINGLETON_KIND;
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1902
|
+
*rg = (rbs_range_t) {
|
|
1903
|
+
.start = self_range.start,
|
|
1904
|
+
.end = parser->current_token.range.end,
|
|
1905
|
+
};
|
|
1906
|
+
} else {
|
|
1907
|
+
*rg = NULL_RANGE;
|
|
1908
|
+
}
|
|
1909
|
+
|
|
1910
|
+
return kind;
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1913
|
+
/**
|
|
1914
|
+
* def_member ::= {kDEF} method_name `:` <method_types>
|
|
1915
|
+
* | {kPRIVATE} kDEF method_name `:` <method_types>
|
|
1916
|
+
* | {kPUBLIC} kDEF method_name `:` <method_types>
|
|
1917
|
+
*
|
|
1918
|
+
* method_types ::= {} <method_type>
|
|
1919
|
+
* | {} <`...`>
|
|
1920
|
+
* | {} method_type `|` <method_types>
|
|
1921
|
+
*
|
|
1922
|
+
* @param instance_only `true` to reject singleton method definition.
|
|
1923
|
+
* @param accept_overload `true` to accept overloading (...) definition.
|
|
1924
|
+
* */
|
|
1925
|
+
NODISCARD
|
|
1926
|
+
static bool parse_member_def(rbs_parser_t *parser, bool instance_only, bool accept_overload, rbs_position_t comment_pos, rbs_node_list_t *annotations, rbs_ast_members_method_definition_t **method_definition) {
|
|
1927
|
+
rbs_range_t member_range;
|
|
1928
|
+
member_range.start = parser->current_token.range.start;
|
|
1929
|
+
comment_pos = rbs_nonnull_pos_or(comment_pos, member_range.start);
|
|
1930
|
+
|
|
1931
|
+
rbs_ast_comment_t *comment = rbs_parser_get_comment(parser, comment_pos.line);
|
|
1932
|
+
|
|
1933
|
+
rbs_range_t visibility_range;
|
|
1934
|
+
enum rbs_method_definition_visibility visibility;
|
|
1935
|
+
switch (parser->current_token.type) {
|
|
1936
|
+
case kPRIVATE: {
|
|
1937
|
+
visibility_range = parser->current_token.range;
|
|
1938
|
+
visibility = RBS_METHOD_DEFINITION_VISIBILITY_PRIVATE;
|
|
1939
|
+
member_range.start = visibility_range.start;
|
|
1940
|
+
rbs_parser_advance(parser);
|
|
1941
|
+
break;
|
|
1942
|
+
}
|
|
1943
|
+
case kPUBLIC: {
|
|
1944
|
+
visibility_range = parser->current_token.range;
|
|
1945
|
+
visibility = RBS_METHOD_DEFINITION_VISIBILITY_PUBLIC;
|
|
1946
|
+
member_range.start = visibility_range.start;
|
|
1947
|
+
rbs_parser_advance(parser);
|
|
1948
|
+
break;
|
|
1949
|
+
}
|
|
1950
|
+
default:
|
|
1951
|
+
visibility_range = NULL_RANGE;
|
|
1952
|
+
visibility = RBS_METHOD_DEFINITION_VISIBILITY_UNSPECIFIED;
|
|
1953
|
+
break;
|
|
1954
|
+
}
|
|
1955
|
+
|
|
1956
|
+
rbs_range_t keyword_range = parser->current_token.range;
|
|
1957
|
+
|
|
1958
|
+
rbs_range_t kind_range;
|
|
1959
|
+
InstanceSingletonKind kind;
|
|
1960
|
+
if (instance_only) {
|
|
1961
|
+
kind_range = NULL_RANGE;
|
|
1962
|
+
kind = INSTANCE_KIND;
|
|
1963
|
+
} else {
|
|
1964
|
+
kind = parse_instance_singleton_kind(parser, visibility == RBS_METHOD_DEFINITION_VISIBILITY_UNSPECIFIED, &kind_range);
|
|
1965
|
+
}
|
|
1966
|
+
|
|
1967
|
+
rbs_range_t name_range;
|
|
1968
|
+
rbs_ast_symbol_t *name = NULL;
|
|
1969
|
+
CHECK_PARSE(parse_method_name(parser, &name_range, &name));
|
|
1970
|
+
|
|
1971
|
+
#define SELF_ID rbs_constant_pool_insert_constant(&parser->constant_pool, (const unsigned char *) "self?", strlen("self?"))
|
|
1972
|
+
|
|
1973
|
+
if (parser->next_token.type == pDOT && name->constant_id == SELF_ID) {
|
|
1974
|
+
rbs_parser_set_error(parser, parser->next_token, true, "`self?` method cannot have visibility");
|
|
1975
|
+
return false;
|
|
1976
|
+
} else {
|
|
1977
|
+
ADVANCE_ASSERT(parser, pCOLON);
|
|
1978
|
+
}
|
|
1979
|
+
|
|
1980
|
+
rbs_parser_push_typevar_table(parser, kind != INSTANCE_KIND);
|
|
1981
|
+
|
|
1982
|
+
rbs_node_list_t *overloads = rbs_node_list_new(ALLOCATOR());
|
|
1983
|
+
bool overloading = false;
|
|
1984
|
+
rbs_range_t overloading_range = NULL_RANGE;
|
|
1985
|
+
bool loop = true;
|
|
1986
|
+
while (loop) {
|
|
1987
|
+
rbs_node_list_t *annotations = rbs_node_list_new(ALLOCATOR());
|
|
1988
|
+
rbs_position_t overload_annot_pos = NullPosition;
|
|
1989
|
+
|
|
1990
|
+
rbs_range_t overload_range;
|
|
1991
|
+
overload_range.start = parser->current_token.range.start;
|
|
1992
|
+
|
|
1993
|
+
if (parser->next_token.type == tANNOTATION) {
|
|
1994
|
+
CHECK_PARSE(parse_annotations(parser, annotations, &overload_annot_pos));
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1997
|
+
switch (parser->next_token.type) {
|
|
1998
|
+
case pLPAREN:
|
|
1999
|
+
case pARROW:
|
|
2000
|
+
case pLBRACE:
|
|
2001
|
+
case pLBRACKET:
|
|
2002
|
+
case pQUESTION: {
|
|
2003
|
+
rbs_method_type_t *method_type = NULL;
|
|
2004
|
+
CHECK_PARSE(rbs_parse_method_type(parser, &method_type, false, !instance_only));
|
|
2005
|
+
|
|
2006
|
+
overload_range.end = parser->current_token.range.end;
|
|
2007
|
+
rbs_node_t *overload = (rbs_node_t *) rbs_ast_members_method_definition_overload_new(ALLOCATOR(), RBS_RANGE_LEX2AST(overload_range), annotations, (rbs_node_t *) method_type);
|
|
2008
|
+
rbs_node_list_append(overloads, overload);
|
|
2009
|
+
member_range.end = parser->current_token.range.end;
|
|
2010
|
+
break;
|
|
2011
|
+
}
|
|
2012
|
+
|
|
2013
|
+
case pDOT3:
|
|
2014
|
+
if (accept_overload) {
|
|
2015
|
+
overloading = true;
|
|
2016
|
+
rbs_parser_advance(parser);
|
|
2017
|
+
loop = false;
|
|
2018
|
+
overloading_range = parser->current_token.range;
|
|
2019
|
+
member_range.end = overloading_range.end;
|
|
2020
|
+
break;
|
|
2021
|
+
} else {
|
|
2022
|
+
rbs_parser_set_error(parser, parser->next_token, true, "unexpected overloading method definition");
|
|
2023
|
+
return false;
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
default:
|
|
2027
|
+
rbs_parser_set_error(parser, parser->next_token, true, "unexpected token for method type");
|
|
2028
|
+
return false;
|
|
2029
|
+
}
|
|
2030
|
+
|
|
2031
|
+
if (parser->next_token.type == pBAR) {
|
|
2032
|
+
rbs_parser_advance(parser);
|
|
2033
|
+
} else {
|
|
2034
|
+
loop = false;
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
2037
|
+
|
|
2038
|
+
CHECK_PARSE(parser_pop_typevar_table(parser));
|
|
2039
|
+
|
|
2040
|
+
enum rbs_method_definition_kind k;
|
|
2041
|
+
switch (kind) {
|
|
2042
|
+
case INSTANCE_KIND: {
|
|
2043
|
+
k = RBS_METHOD_DEFINITION_KIND_INSTANCE;
|
|
2044
|
+
break;
|
|
2045
|
+
}
|
|
2046
|
+
case SINGLETON_KIND: {
|
|
2047
|
+
k = RBS_METHOD_DEFINITION_KIND_SINGLETON;
|
|
2048
|
+
break;
|
|
2049
|
+
}
|
|
2050
|
+
case INSTANCE_SINGLETON_KIND: {
|
|
2051
|
+
k = RBS_METHOD_DEFINITION_KIND_SINGLETON_INSTANCE;
|
|
2052
|
+
break;
|
|
2053
|
+
}
|
|
2054
|
+
default:
|
|
2055
|
+
rbs_parser_set_error(parser, parser->current_token, false, "Unexpected error");
|
|
2056
|
+
return false;
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
*method_definition = rbs_ast_members_method_definition_new(ALLOCATOR(), RBS_RANGE_LEX2AST(member_range), name, k, overloads, annotations, comment, overloading, visibility, RBS_RANGE_LEX2AST(keyword_range), RBS_RANGE_LEX2AST(name_range));
|
|
2060
|
+
(*method_definition)->kind_range = RBS_RANGE_LEX2AST(kind_range);
|
|
2061
|
+
(*method_definition)->overloading_range = RBS_RANGE_LEX2AST(overloading_range);
|
|
2062
|
+
(*method_definition)->visibility_range = RBS_RANGE_LEX2AST(visibility_range);
|
|
2063
|
+
|
|
2064
|
+
return true;
|
|
2065
|
+
}
|
|
2066
|
+
|
|
2067
|
+
/**
|
|
2068
|
+
* class_instance_name ::= {} <class_name>
|
|
2069
|
+
* | {} class_name `[` type args <`]`>
|
|
2070
|
+
*
|
|
2071
|
+
* @param kind
|
|
2072
|
+
* */
|
|
2073
|
+
NODISCARD
|
|
2074
|
+
static bool class_instance_name(rbs_parser_t *parser, TypeNameKind kind, rbs_node_list_t *args, rbs_range_t *name_range, rbs_range_t *args_range, rbs_type_name_t **name, bool classish_allowed) {
|
|
2075
|
+
rbs_parser_advance(parser);
|
|
2076
|
+
|
|
2077
|
+
rbs_type_name_t *type_name = NULL;
|
|
2078
|
+
CHECK_PARSE(parse_type_name(parser, kind, name_range, &type_name));
|
|
2079
|
+
*name = type_name;
|
|
2080
|
+
|
|
2081
|
+
if (parser->next_token.type == pLBRACKET) {
|
|
2082
|
+
rbs_parser_advance(parser);
|
|
2083
|
+
args_range->start = parser->current_token.range.start;
|
|
2084
|
+
CHECK_PARSE(parse_type_list(parser, pRBRACKET, args, true, false, classish_allowed));
|
|
2085
|
+
ADVANCE_ASSERT(parser, pRBRACKET);
|
|
2086
|
+
args_range->end = parser->current_token.range.end;
|
|
2087
|
+
} else {
|
|
2088
|
+
*args_range = NULL_RANGE;
|
|
2089
|
+
}
|
|
2090
|
+
|
|
2091
|
+
return true;
|
|
2092
|
+
}
|
|
2093
|
+
|
|
2094
|
+
/**
|
|
2095
|
+
* mixin_member ::= {kINCLUDE} <class_instance_name>
|
|
2096
|
+
* | {kPREPEND} <class_instance_name>
|
|
2097
|
+
* | {kEXTEND} <class_instance_name>
|
|
2098
|
+
*
|
|
2099
|
+
* @param from_interface `true` when the member is in an interface.
|
|
2100
|
+
* */
|
|
2101
|
+
NODISCARD
|
|
2102
|
+
static bool parse_mixin_member(rbs_parser_t *parser, bool from_interface, rbs_position_t comment_pos, rbs_node_list_t *annotations, rbs_node_t **mixin_member) {
|
|
2103
|
+
rbs_range_t member_range;
|
|
2104
|
+
member_range.start = parser->current_token.range.start;
|
|
2105
|
+
comment_pos = rbs_nonnull_pos_or(comment_pos, member_range.start);
|
|
2106
|
+
|
|
2107
|
+
enum RBSTokenType type = parser->current_token.type;
|
|
2108
|
+
rbs_range_t keyword_range = parser->current_token.range;
|
|
2109
|
+
|
|
2110
|
+
bool reset_typevar_scope;
|
|
2111
|
+
switch (type) {
|
|
2112
|
+
case kINCLUDE:
|
|
2113
|
+
reset_typevar_scope = false;
|
|
2114
|
+
break;
|
|
2115
|
+
case kEXTEND:
|
|
2116
|
+
reset_typevar_scope = true;
|
|
2117
|
+
break;
|
|
2118
|
+
case kPREPEND:
|
|
2119
|
+
reset_typevar_scope = false;
|
|
2120
|
+
break;
|
|
2121
|
+
default:
|
|
2122
|
+
rbs_parser_set_error(parser, parser->current_token, false, "Unexpected error");
|
|
2123
|
+
return false;
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2126
|
+
if (from_interface) {
|
|
2127
|
+
if (parser->current_token.type != kINCLUDE) {
|
|
2128
|
+
rbs_parser_set_error(parser, parser->current_token, true, "unexpected mixin in interface declaration");
|
|
2129
|
+
return false;
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
|
|
2133
|
+
rbs_parser_push_typevar_table(parser, reset_typevar_scope);
|
|
2134
|
+
|
|
2135
|
+
rbs_node_list_t *args = rbs_node_list_new(ALLOCATOR());
|
|
2136
|
+
rbs_range_t name_range;
|
|
2137
|
+
rbs_range_t args_range = NULL_RANGE;
|
|
2138
|
+
rbs_type_name_t *name = NULL;
|
|
2139
|
+
CHECK_PARSE(class_instance_name(
|
|
2140
|
+
parser,
|
|
2141
|
+
from_interface ? INTERFACE_NAME : (TypeNameKind) (INTERFACE_NAME | CLASS_NAME),
|
|
2142
|
+
args,
|
|
2143
|
+
&name_range,
|
|
2144
|
+
&args_range,
|
|
2145
|
+
&name,
|
|
2146
|
+
!from_interface
|
|
2147
|
+
));
|
|
2148
|
+
|
|
2149
|
+
CHECK_PARSE(parser_pop_typevar_table(parser));
|
|
2150
|
+
|
|
2151
|
+
member_range.end = parser->current_token.range.end;
|
|
2152
|
+
|
|
2153
|
+
rbs_location_range loc = RBS_RANGE_LEX2AST(member_range);
|
|
2154
|
+
rbs_location_range name_rg = RBS_RANGE_LEX2AST(name_range);
|
|
2155
|
+
rbs_location_range keyword_rg = RBS_RANGE_LEX2AST(keyword_range);
|
|
2156
|
+
rbs_location_range args_rg = RBS_RANGE_LEX2AST(args_range);
|
|
2157
|
+
|
|
2158
|
+
rbs_ast_comment_t *comment = rbs_parser_get_comment(parser, comment_pos.line);
|
|
2159
|
+
switch (type) {
|
|
2160
|
+
case kINCLUDE: {
|
|
2161
|
+
rbs_ast_members_include_t *include_member = rbs_ast_members_include_new(ALLOCATOR(), loc, name, args, annotations, comment, name_rg, keyword_rg);
|
|
2162
|
+
include_member->args_range = args_rg;
|
|
2163
|
+
*mixin_member = (rbs_node_t *) include_member;
|
|
2164
|
+
return true;
|
|
2165
|
+
}
|
|
2166
|
+
case kEXTEND: {
|
|
2167
|
+
rbs_ast_members_extend_t *extend_member = rbs_ast_members_extend_new(ALLOCATOR(), loc, name, args, annotations, comment, name_rg, keyword_rg);
|
|
2168
|
+
extend_member->args_range = args_rg;
|
|
2169
|
+
*mixin_member = (rbs_node_t *) extend_member;
|
|
2170
|
+
return true;
|
|
2171
|
+
}
|
|
2172
|
+
case kPREPEND: {
|
|
2173
|
+
rbs_ast_members_prepend_t *prepend_member = rbs_ast_members_prepend_new(ALLOCATOR(), loc, name, args, annotations, comment, name_rg, keyword_rg);
|
|
2174
|
+
prepend_member->args_range = args_rg;
|
|
2175
|
+
*mixin_member = (rbs_node_t *) prepend_member;
|
|
2176
|
+
return true;
|
|
2177
|
+
}
|
|
2178
|
+
default:
|
|
2179
|
+
rbs_parser_set_error(parser, parser->current_token, false, "Unexpected error");
|
|
2180
|
+
return false;
|
|
2181
|
+
}
|
|
2182
|
+
}
|
|
2183
|
+
|
|
2184
|
+
/**
|
|
2185
|
+
* @code
|
|
2186
|
+
* alias_member ::= {kALIAS} method_name <method_name>
|
|
2187
|
+
* | {kALIAS} kSELF `.` method_name kSELF `.` <method_name>
|
|
2188
|
+
* @endcode
|
|
2189
|
+
*
|
|
2190
|
+
* @param[in] instance_only `true` to reject `self.` alias.
|
|
2191
|
+
* */
|
|
2192
|
+
NODISCARD
|
|
2193
|
+
static bool parse_alias_member(rbs_parser_t *parser, bool instance_only, rbs_position_t comment_pos, rbs_node_list_t *annotations, rbs_ast_members_alias_t **alias_member) {
|
|
2194
|
+
rbs_range_t member_range;
|
|
2195
|
+
member_range.start = parser->current_token.range.start;
|
|
2196
|
+
rbs_range_t keyword_range = parser->current_token.range;
|
|
2197
|
+
|
|
2198
|
+
comment_pos = rbs_nonnull_pos_or(comment_pos, member_range.start);
|
|
2199
|
+
rbs_ast_comment_t *comment = rbs_parser_get_comment(parser, comment_pos.line);
|
|
2200
|
+
|
|
2201
|
+
enum rbs_alias_kind kind;
|
|
2202
|
+
rbs_ast_symbol_t *new_name, *old_name;
|
|
2203
|
+
rbs_range_t new_kind_range, old_kind_range, new_name_range, old_name_range;
|
|
2204
|
+
|
|
2205
|
+
if (!instance_only && parser->next_token.type == kSELF) {
|
|
2206
|
+
kind = RBS_ALIAS_KIND_SINGLETON;
|
|
2207
|
+
|
|
2208
|
+
new_kind_range.start = parser->next_token.range.start;
|
|
2209
|
+
new_kind_range.end = parser->next_token2.range.end;
|
|
2210
|
+
ADVANCE_ASSERT(parser, kSELF);
|
|
2211
|
+
ADVANCE_ASSERT(parser, pDOT);
|
|
2212
|
+
CHECK_PARSE(parse_method_name(parser, &new_name_range, &new_name));
|
|
2213
|
+
|
|
2214
|
+
old_kind_range.start = parser->next_token.range.start;
|
|
2215
|
+
old_kind_range.end = parser->next_token2.range.end;
|
|
2216
|
+
ADVANCE_ASSERT(parser, kSELF);
|
|
2217
|
+
ADVANCE_ASSERT(parser, pDOT);
|
|
2218
|
+
CHECK_PARSE(parse_method_name(parser, &old_name_range, &old_name));
|
|
2219
|
+
} else {
|
|
2220
|
+
kind = RBS_ALIAS_KIND_INSTANCE;
|
|
2221
|
+
CHECK_PARSE(parse_method_name(parser, &new_name_range, &new_name));
|
|
2222
|
+
CHECK_PARSE(parse_method_name(parser, &old_name_range, &old_name));
|
|
2223
|
+
new_kind_range = NULL_RANGE;
|
|
2224
|
+
old_kind_range = NULL_RANGE;
|
|
2225
|
+
}
|
|
2226
|
+
|
|
2227
|
+
member_range.end = parser->current_token.range.end;
|
|
2228
|
+
|
|
2229
|
+
rbs_location_range loc = RBS_RANGE_LEX2AST(member_range);
|
|
2230
|
+
|
|
2231
|
+
*alias_member = rbs_ast_members_alias_new(ALLOCATOR(), loc, new_name, old_name, kind, annotations, comment, RBS_RANGE_LEX2AST(keyword_range), RBS_RANGE_LEX2AST(new_name_range), RBS_RANGE_LEX2AST(old_name_range));
|
|
2232
|
+
(*alias_member)->new_kind_range = RBS_RANGE_LEX2AST(new_kind_range);
|
|
2233
|
+
(*alias_member)->old_kind_range = RBS_RANGE_LEX2AST(old_kind_range);
|
|
2234
|
+
|
|
2235
|
+
return true;
|
|
2236
|
+
}
|
|
2237
|
+
|
|
2238
|
+
/*
|
|
2239
|
+
variable_member ::= {tAIDENT} `:` <type>
|
|
2240
|
+
| {kSELF} `.` tAIDENT `:` <type>
|
|
2241
|
+
| {tA2IDENT} `:` <type>
|
|
2242
|
+
*/
|
|
2243
|
+
NODISCARD
|
|
2244
|
+
static bool parse_variable_member(rbs_parser_t *parser, rbs_position_t comment_pos, rbs_node_list_t *annotations, rbs_node_t **variable_member) {
|
|
2245
|
+
if (annotations->length > 0) {
|
|
2246
|
+
rbs_parser_set_error(parser, parser->current_token, true, "annotation cannot be given to variable members");
|
|
2247
|
+
return false;
|
|
2248
|
+
}
|
|
2249
|
+
|
|
2250
|
+
rbs_range_t member_range;
|
|
2251
|
+
member_range.start = parser->current_token.range.start;
|
|
2252
|
+
comment_pos = rbs_nonnull_pos_or(comment_pos, member_range.start);
|
|
2253
|
+
rbs_ast_comment_t *comment = rbs_parser_get_comment(parser, comment_pos.line);
|
|
2254
|
+
|
|
2255
|
+
switch (parser->current_token.type) {
|
|
2256
|
+
case tAIDENT:
|
|
2257
|
+
case kATRBS: {
|
|
2258
|
+
rbs_range_t name_range = parser->current_token.range;
|
|
2259
|
+
rbs_location_range symbolLoc = RBS_RANGE_LEX2AST(name_range);
|
|
2260
|
+
rbs_ast_symbol_t *name = rbs_ast_symbol_new(ALLOCATOR(), symbolLoc, &parser->constant_pool, INTERN_TOKEN(parser, parser->current_token));
|
|
2261
|
+
|
|
2262
|
+
ADVANCE_ASSERT(parser, pCOLON);
|
|
2263
|
+
rbs_range_t colon_range = parser->current_token.range;
|
|
2264
|
+
|
|
2265
|
+
rbs_node_t *type;
|
|
2266
|
+
CHECK_PARSE(rbs_parse_type(parser, &type, false, true, true));
|
|
2267
|
+
member_range.end = parser->current_token.range.end;
|
|
2268
|
+
|
|
2269
|
+
rbs_location_range loc = RBS_RANGE_LEX2AST(member_range);
|
|
2270
|
+
|
|
2271
|
+
*variable_member = (rbs_node_t *) rbs_ast_members_instance_variable_new(ALLOCATOR(), loc, name, type, comment, RBS_RANGE_LEX2AST(name_range), RBS_RANGE_LEX2AST(colon_range));
|
|
2272
|
+
|
|
2273
|
+
return true;
|
|
2274
|
+
}
|
|
2275
|
+
case tA2IDENT: {
|
|
2276
|
+
rbs_range_t name_range = parser->current_token.range;
|
|
2277
|
+
rbs_location_range symbol_loc = RBS_RANGE_LEX2AST(name_range);
|
|
2278
|
+
rbs_ast_symbol_t *name = rbs_ast_symbol_new(ALLOCATOR(), symbol_loc, &parser->constant_pool, INTERN_TOKEN(parser, parser->current_token));
|
|
2279
|
+
|
|
2280
|
+
ADVANCE_ASSERT(parser, pCOLON);
|
|
2281
|
+
rbs_range_t colon_range = parser->current_token.range;
|
|
2282
|
+
|
|
2283
|
+
rbs_parser_push_typevar_table(parser, true);
|
|
2284
|
+
|
|
2285
|
+
rbs_node_t *type;
|
|
2286
|
+
CHECK_PARSE(rbs_parse_type(parser, &type, false, false, true));
|
|
2287
|
+
|
|
2288
|
+
CHECK_PARSE(parser_pop_typevar_table(parser));
|
|
2289
|
+
|
|
2290
|
+
member_range.end = parser->current_token.range.end;
|
|
2291
|
+
|
|
2292
|
+
rbs_location_range loc = RBS_RANGE_LEX2AST(member_range);
|
|
2293
|
+
|
|
2294
|
+
*variable_member = (rbs_node_t *) rbs_ast_members_class_variable_new(ALLOCATOR(), loc, name, type, comment, RBS_RANGE_LEX2AST(name_range), RBS_RANGE_LEX2AST(colon_range));
|
|
2295
|
+
|
|
2296
|
+
return true;
|
|
2297
|
+
}
|
|
2298
|
+
case kSELF: {
|
|
2299
|
+
rbs_range_t kind_range = {
|
|
2300
|
+
.start = parser->current_token.range.start,
|
|
2301
|
+
.end = parser->next_token.range.end
|
|
2302
|
+
};
|
|
2303
|
+
|
|
2304
|
+
ADVANCE_ASSERT(parser, pDOT);
|
|
2305
|
+
if (parser->next_token.type == tAIDENT || parser->next_token.type == kATRBS) {
|
|
2306
|
+
rbs_parser_advance(parser);
|
|
2307
|
+
} else {
|
|
2308
|
+
rbs_parser_set_error(parser, parser->current_token, false, "Unexpected error");
|
|
2309
|
+
return false;
|
|
2310
|
+
}
|
|
2311
|
+
|
|
2312
|
+
rbs_range_t name_range = parser->current_token.range;
|
|
2313
|
+
rbs_location_range symbol_loc = RBS_RANGE_LEX2AST(name_range);
|
|
2314
|
+
rbs_ast_symbol_t *name = rbs_ast_symbol_new(ALLOCATOR(), symbol_loc, &parser->constant_pool, INTERN_TOKEN(parser, parser->current_token));
|
|
2315
|
+
|
|
2316
|
+
ADVANCE_ASSERT(parser, pCOLON);
|
|
2317
|
+
rbs_range_t colon_range = parser->current_token.range;
|
|
2318
|
+
|
|
2319
|
+
rbs_parser_push_typevar_table(parser, true);
|
|
2320
|
+
|
|
2321
|
+
rbs_node_t *type;
|
|
2322
|
+
CHECK_PARSE(rbs_parse_type(parser, &type, false, true, true));
|
|
2323
|
+
|
|
2324
|
+
CHECK_PARSE(parser_pop_typevar_table(parser));
|
|
2325
|
+
|
|
2326
|
+
member_range.end = parser->current_token.range.end;
|
|
2327
|
+
|
|
2328
|
+
rbs_location_range loc = RBS_RANGE_LEX2AST(member_range);
|
|
2329
|
+
|
|
2330
|
+
rbs_ast_members_class_instance_variable_t *class_ivar_member = rbs_ast_members_class_instance_variable_new(ALLOCATOR(), loc, name, type, comment, RBS_RANGE_LEX2AST(name_range), RBS_RANGE_LEX2AST(colon_range));
|
|
2331
|
+
class_ivar_member->kind_range = RBS_RANGE_LEX2AST(kind_range);
|
|
2332
|
+
|
|
2333
|
+
*variable_member = (rbs_node_t *) class_ivar_member;
|
|
2334
|
+
|
|
2335
|
+
return true;
|
|
2336
|
+
}
|
|
2337
|
+
default:
|
|
2338
|
+
rbs_parser_set_error(parser, parser->current_token, false, "Unexpected error");
|
|
2339
|
+
return false;
|
|
2340
|
+
}
|
|
2341
|
+
}
|
|
2342
|
+
|
|
2343
|
+
/*
|
|
2344
|
+
visibility_member ::= {<`public`>}
|
|
2345
|
+
| {<`private`>}
|
|
2346
|
+
*/
|
|
2347
|
+
NODISCARD
|
|
2348
|
+
static bool parse_visibility_member(rbs_parser_t *parser, rbs_node_list_t *annotations, rbs_node_t **visibility_member) {
|
|
2349
|
+
if (annotations->length > 0) {
|
|
2350
|
+
rbs_parser_set_error(parser, parser->current_token, true, "annotation cannot be given to visibility members");
|
|
2351
|
+
return false;
|
|
2352
|
+
}
|
|
2353
|
+
|
|
2354
|
+
rbs_location_range location = rbs_location_range_current_token(parser);
|
|
2355
|
+
|
|
2356
|
+
switch (parser->current_token.type) {
|
|
2357
|
+
case kPUBLIC: {
|
|
2358
|
+
*visibility_member = (rbs_node_t *) rbs_ast_members_public_new(ALLOCATOR(), location);
|
|
2359
|
+
return true;
|
|
2360
|
+
}
|
|
2361
|
+
case kPRIVATE: {
|
|
2362
|
+
*visibility_member = (rbs_node_t *) rbs_ast_members_private_new(ALLOCATOR(), location);
|
|
2363
|
+
return true;
|
|
2364
|
+
}
|
|
2365
|
+
default:
|
|
2366
|
+
rbs_parser_set_error(parser, parser->current_token, false, "Unexpected error");
|
|
2367
|
+
return false;
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
|
|
2371
|
+
/*
|
|
2372
|
+
attribute_member ::= {attr_keyword} attr_name attr_var `:` <type>
|
|
2373
|
+
| {visibility} attr_keyword attr_name attr_var `:` <type>
|
|
2374
|
+
| {attr_keyword} `self` `.` attr_name attr_var `:` <type>
|
|
2375
|
+
| {visibility} attr_keyword `self` `.` attr_name attr_var `:` <type>
|
|
2376
|
+
|
|
2377
|
+
attr_keyword ::= `attr_reader` | `attr_writer` | `attr_accessor`
|
|
2378
|
+
|
|
2379
|
+
visibility ::= `public` | `private`
|
|
2380
|
+
|
|
2381
|
+
attr_var ::= # empty
|
|
2382
|
+
| `(` tAIDENT `)` # Ivar name
|
|
2383
|
+
| `(` `)` # No variable
|
|
2384
|
+
*/
|
|
2385
|
+
NODISCARD
|
|
2386
|
+
static bool parse_attribute_member(rbs_parser_t *parser, rbs_position_t comment_pos, rbs_node_list_t *annotations, rbs_node_t **attribute_member) {
|
|
2387
|
+
rbs_range_t member_range;
|
|
2388
|
+
|
|
2389
|
+
member_range.start = parser->current_token.range.start;
|
|
2390
|
+
comment_pos = rbs_nonnull_pos_or(comment_pos, member_range.start);
|
|
2391
|
+
rbs_ast_comment_t *comment = rbs_parser_get_comment(parser, comment_pos.line);
|
|
2392
|
+
|
|
2393
|
+
rbs_range_t visibility_range;
|
|
2394
|
+
enum rbs_attribute_visibility visibility;
|
|
2395
|
+
|
|
2396
|
+
switch (parser->current_token.type) {
|
|
2397
|
+
case kPRIVATE: {
|
|
2398
|
+
visibility_range = parser->current_token.range;
|
|
2399
|
+
visibility = RBS_ATTRIBUTE_VISIBILITY_PRIVATE;
|
|
2400
|
+
rbs_parser_advance(parser);
|
|
2401
|
+
break;
|
|
2402
|
+
}
|
|
2403
|
+
case kPUBLIC: {
|
|
2404
|
+
visibility_range = parser->current_token.range;
|
|
2405
|
+
visibility = RBS_ATTRIBUTE_VISIBILITY_PUBLIC;
|
|
2406
|
+
rbs_parser_advance(parser);
|
|
2407
|
+
break;
|
|
2408
|
+
}
|
|
2409
|
+
default:
|
|
2410
|
+
visibility = RBS_ATTRIBUTE_VISIBILITY_UNSPECIFIED;
|
|
2411
|
+
visibility_range = NULL_RANGE;
|
|
2412
|
+
break;
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
enum RBSTokenType attr_type = parser->current_token.type;
|
|
2416
|
+
rbs_range_t keyword_range = parser->current_token.range;
|
|
2417
|
+
|
|
2418
|
+
rbs_range_t kind_range;
|
|
2419
|
+
InstanceSingletonKind is_kind = parse_instance_singleton_kind(parser, false, &kind_range);
|
|
2420
|
+
|
|
2421
|
+
enum rbs_attribute_kind kind = (is_kind == INSTANCE_KIND) ? RBS_ATTRIBUTE_KIND_INSTANCE : RBS_ATTRIBUTE_KIND_SINGLETON;
|
|
2422
|
+
|
|
2423
|
+
rbs_range_t name_range;
|
|
2424
|
+
rbs_ast_symbol_t *attr_name;
|
|
2425
|
+
CHECK_PARSE(parse_method_name(parser, &name_range, &attr_name));
|
|
2426
|
+
|
|
2427
|
+
rbs_attr_ivar_name_t ivar_name = { .tag = RBS_ATTR_IVAR_NAME_TAG_UNSPECIFIED };
|
|
2428
|
+
rbs_location_range ivar_range = RBS_LOCATION_NULL_RANGE;
|
|
2429
|
+
rbs_location_range ivar_name_range = RBS_LOCATION_NULL_RANGE;
|
|
2430
|
+
if (parser->next_token.type == pLPAREN) {
|
|
2431
|
+
ADVANCE_ASSERT(parser, pLPAREN);
|
|
2432
|
+
ivar_range.start_char = parser->current_token.range.start.char_pos;
|
|
2433
|
+
ivar_range.start_byte = parser->current_token.range.start.byte_pos;
|
|
2434
|
+
|
|
2435
|
+
ivar_name.tag = RBS_ATTR_IVAR_NAME_TAG_EMPTY;
|
|
2436
|
+
|
|
2437
|
+
if (parser_advance_if(parser, tAIDENT) || parser_advance_if(parser, kATRBS)) {
|
|
2438
|
+
ivar_name.tag = RBS_ATTR_IVAR_NAME_TAG_NAME;
|
|
2439
|
+
ivar_name.name = INTERN_TOKEN(parser, parser->current_token);
|
|
2440
|
+
ivar_name_range = rbs_location_range_current_token(parser);
|
|
2441
|
+
}
|
|
2442
|
+
|
|
2443
|
+
ADVANCE_ASSERT(parser, pRPAREN);
|
|
2444
|
+
ivar_range.end_char = parser->current_token.range.end.char_pos;
|
|
2445
|
+
ivar_range.end_byte = parser->current_token.range.end.byte_pos;
|
|
2446
|
+
}
|
|
2447
|
+
|
|
2448
|
+
ADVANCE_ASSERT(parser, pCOLON);
|
|
2449
|
+
rbs_range_t colon_range = parser->current_token.range;
|
|
2450
|
+
|
|
2451
|
+
rbs_parser_push_typevar_table(parser, is_kind == SINGLETON_KIND);
|
|
2452
|
+
|
|
2453
|
+
rbs_node_t *type;
|
|
2454
|
+
CHECK_PARSE(rbs_parse_type(parser, &type, false, true, true));
|
|
2455
|
+
|
|
2456
|
+
CHECK_PARSE(parser_pop_typevar_table(parser));
|
|
2457
|
+
|
|
2458
|
+
member_range.end = parser->current_token.range.end;
|
|
2459
|
+
|
|
2460
|
+
rbs_location_range loc = RBS_RANGE_LEX2AST(member_range);
|
|
2461
|
+
rbs_location_range keyword_rg = RBS_RANGE_LEX2AST(keyword_range);
|
|
2462
|
+
rbs_location_range name_rg = RBS_RANGE_LEX2AST(name_range);
|
|
2463
|
+
rbs_location_range colon_rg = RBS_RANGE_LEX2AST(colon_range);
|
|
2464
|
+
rbs_location_range kind_rg = RBS_RANGE_LEX2AST(kind_range);
|
|
2465
|
+
rbs_location_range visibility_rg = RBS_RANGE_LEX2AST(visibility_range);
|
|
2466
|
+
|
|
2467
|
+
switch (attr_type) {
|
|
2468
|
+
case kATTRREADER: {
|
|
2469
|
+
rbs_ast_members_attr_reader_t *attr_reader = rbs_ast_members_attr_reader_new(ALLOCATOR(), loc, attr_name, type, ivar_name, kind, annotations, comment, visibility, keyword_rg, name_rg, colon_rg);
|
|
2470
|
+
attr_reader->kind_range = kind_rg;
|
|
2471
|
+
attr_reader->ivar_range = ivar_range;
|
|
2472
|
+
attr_reader->ivar_name_range = ivar_name_range;
|
|
2473
|
+
attr_reader->visibility_range = visibility_rg;
|
|
2474
|
+
|
|
2475
|
+
*attribute_member = (rbs_node_t *) attr_reader;
|
|
2476
|
+
|
|
2477
|
+
return true;
|
|
2478
|
+
}
|
|
2479
|
+
case kATTRWRITER: {
|
|
2480
|
+
rbs_ast_members_attr_writer_t *attr_writer = rbs_ast_members_attr_writer_new(ALLOCATOR(), loc, attr_name, type, ivar_name, kind, annotations, comment, visibility, keyword_rg, name_rg, colon_rg);
|
|
2481
|
+
attr_writer->kind_range = kind_rg;
|
|
2482
|
+
attr_writer->ivar_range = ivar_range;
|
|
2483
|
+
attr_writer->ivar_name_range = ivar_name_range;
|
|
2484
|
+
attr_writer->visibility_range = visibility_rg;
|
|
2485
|
+
|
|
2486
|
+
*attribute_member = (rbs_node_t *) attr_writer;
|
|
2487
|
+
|
|
2488
|
+
return true;
|
|
2489
|
+
}
|
|
2490
|
+
case kATTRACCESSOR: {
|
|
2491
|
+
rbs_ast_members_attr_accessor_t *attr_accessor = rbs_ast_members_attr_accessor_new(ALLOCATOR(), loc, attr_name, type, ivar_name, kind, annotations, comment, visibility, keyword_rg, name_rg, colon_rg);
|
|
2492
|
+
attr_accessor->kind_range = kind_rg;
|
|
2493
|
+
attr_accessor->ivar_range = ivar_range;
|
|
2494
|
+
attr_accessor->ivar_name_range = ivar_name_range;
|
|
2495
|
+
attr_accessor->visibility_range = visibility_rg;
|
|
2496
|
+
|
|
2497
|
+
*attribute_member = (rbs_node_t *) attr_accessor;
|
|
2498
|
+
|
|
2499
|
+
return true;
|
|
2500
|
+
}
|
|
2501
|
+
default:
|
|
2502
|
+
rbs_parser_set_error(parser, parser->current_token, false, "Unexpected error");
|
|
2503
|
+
return false;
|
|
2504
|
+
}
|
|
2505
|
+
}
|
|
2506
|
+
|
|
2507
|
+
/*
|
|
2508
|
+
interface_members ::= {} ...<interface_member> kEND
|
|
2509
|
+
|
|
2510
|
+
interface_member ::= def_member (instance method only && no overloading)
|
|
2511
|
+
| mixin_member (interface only)
|
|
2512
|
+
| alias_member (instance only)
|
|
2513
|
+
*/
|
|
2514
|
+
NODISCARD
|
|
2515
|
+
static bool parse_interface_members(rbs_parser_t *parser, rbs_node_list_t **members) {
|
|
2516
|
+
*members = rbs_node_list_new(ALLOCATOR());
|
|
2517
|
+
|
|
2518
|
+
while (parser->next_token.type != kEND) {
|
|
2519
|
+
rbs_node_list_t *annotations = rbs_node_list_new(ALLOCATOR());
|
|
2520
|
+
rbs_position_t annot_pos = NullPosition;
|
|
2521
|
+
|
|
2522
|
+
CHECK_PARSE(parse_annotations(parser, annotations, &annot_pos));
|
|
2523
|
+
rbs_parser_advance(parser);
|
|
2524
|
+
|
|
2525
|
+
rbs_node_t *member;
|
|
2526
|
+
switch (parser->current_token.type) {
|
|
2527
|
+
case kDEF: {
|
|
2528
|
+
rbs_ast_members_method_definition_t *method_definition = NULL;
|
|
2529
|
+
CHECK_PARSE(parse_member_def(parser, true, true, annot_pos, annotations, &method_definition));
|
|
2530
|
+
member = (rbs_node_t *) method_definition;
|
|
2531
|
+
break;
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2534
|
+
case kINCLUDE:
|
|
2535
|
+
case kEXTEND:
|
|
2536
|
+
case kPREPEND: {
|
|
2537
|
+
CHECK_PARSE(parse_mixin_member(parser, true, annot_pos, annotations, &member));
|
|
2538
|
+
break;
|
|
2539
|
+
}
|
|
2540
|
+
|
|
2541
|
+
case kALIAS: {
|
|
2542
|
+
rbs_ast_members_alias_t *alias_member = NULL;
|
|
2543
|
+
CHECK_PARSE(parse_alias_member(parser, true, annot_pos, annotations, &alias_member));
|
|
2544
|
+
member = (rbs_node_t *) alias_member;
|
|
2545
|
+
break;
|
|
2546
|
+
}
|
|
2547
|
+
|
|
2548
|
+
default:
|
|
2549
|
+
rbs_parser_set_error(parser, parser->current_token, true, "unexpected token for interface declaration member");
|
|
2550
|
+
return false;
|
|
2551
|
+
}
|
|
2552
|
+
|
|
2553
|
+
rbs_node_list_append(*members, member);
|
|
2554
|
+
}
|
|
2555
|
+
|
|
2556
|
+
return true;
|
|
2557
|
+
}
|
|
2558
|
+
|
|
2559
|
+
/*
|
|
2560
|
+
interface_decl ::= {`interface`} interface_name module_type_params interface_members <kEND>
|
|
2561
|
+
*/
|
|
2562
|
+
NODISCARD
|
|
2563
|
+
static bool parse_interface_decl(rbs_parser_t *parser, rbs_position_t comment_pos, rbs_node_list_t *annotations, rbs_ast_declarations_interface_t **interface_decl) {
|
|
2564
|
+
rbs_parser_push_typevar_table(parser, true);
|
|
2565
|
+
|
|
2566
|
+
rbs_range_t member_range;
|
|
2567
|
+
member_range.start = parser->current_token.range.start;
|
|
2568
|
+
comment_pos = rbs_nonnull_pos_or(comment_pos, member_range.start);
|
|
2569
|
+
|
|
2570
|
+
rbs_range_t keyword_range = parser->current_token.range;
|
|
2571
|
+
|
|
2572
|
+
rbs_parser_advance(parser);
|
|
2573
|
+
|
|
2574
|
+
rbs_range_t name_range;
|
|
2575
|
+
rbs_type_name_t *name = NULL;
|
|
2576
|
+
CHECK_PARSE(parse_type_name(parser, INTERFACE_NAME, &name_range, &name));
|
|
2577
|
+
|
|
2578
|
+
rbs_range_t type_params_range;
|
|
2579
|
+
rbs_node_list_t *type_params;
|
|
2580
|
+
CHECK_PARSE(parse_type_params(parser, &type_params_range, true, &type_params));
|
|
2581
|
+
|
|
2582
|
+
rbs_node_list_t *members = NULL;
|
|
2583
|
+
CHECK_PARSE(parse_interface_members(parser, &members));
|
|
2584
|
+
|
|
2585
|
+
ADVANCE_ASSERT(parser, kEND);
|
|
2586
|
+
rbs_range_t end_range = parser->current_token.range;
|
|
2587
|
+
member_range.end = end_range.end;
|
|
2588
|
+
|
|
2589
|
+
CHECK_PARSE(parser_pop_typevar_table(parser));
|
|
2590
|
+
|
|
2591
|
+
rbs_location_range loc = RBS_RANGE_LEX2AST(member_range);
|
|
2592
|
+
rbs_ast_comment_t *comment = rbs_parser_get_comment(parser, comment_pos.line);
|
|
2593
|
+
|
|
2594
|
+
*interface_decl = rbs_ast_declarations_interface_new(ALLOCATOR(), loc, name, type_params, members, annotations, comment, RBS_RANGE_LEX2AST(keyword_range), RBS_RANGE_LEX2AST(name_range), RBS_RANGE_LEX2AST(end_range));
|
|
2595
|
+
(*interface_decl)->type_params_range = RBS_RANGE_LEX2AST(type_params_range);
|
|
2596
|
+
|
|
2597
|
+
return true;
|
|
2598
|
+
}
|
|
2599
|
+
|
|
2600
|
+
/*
|
|
2601
|
+
module_self_types ::= {`:`} module_self_type `,` ... `,` <module_self_type>
|
|
2602
|
+
|
|
2603
|
+
module_self_type ::= <module_name>
|
|
2604
|
+
| module_name `[` type_list <`]`>
|
|
2605
|
+
*/
|
|
2606
|
+
NODISCARD
|
|
2607
|
+
static bool parse_module_self_types(rbs_parser_t *parser, rbs_node_list_t *array) {
|
|
2608
|
+
while (true) {
|
|
2609
|
+
rbs_parser_advance(parser);
|
|
2610
|
+
|
|
2611
|
+
rbs_range_t self_range;
|
|
2612
|
+
self_range.start = parser->current_token.range.start;
|
|
2613
|
+
|
|
2614
|
+
rbs_range_t name_range;
|
|
2615
|
+
rbs_type_name_t *module_name = NULL;
|
|
2616
|
+
CHECK_PARSE(parse_type_name(parser, (TypeNameKind) (CLASS_NAME | INTERFACE_NAME), &name_range, &module_name));
|
|
2617
|
+
self_range.end = name_range.end;
|
|
2618
|
+
|
|
2619
|
+
rbs_node_list_t *args = rbs_node_list_new(ALLOCATOR());
|
|
2620
|
+
rbs_range_t args_range = NULL_RANGE;
|
|
2621
|
+
if (parser->next_token.type == pLBRACKET) {
|
|
2622
|
+
rbs_parser_advance(parser);
|
|
2623
|
+
args_range.start = parser->current_token.range.start;
|
|
2624
|
+
CHECK_PARSE(parse_type_list(parser, pRBRACKET, args, true, false, false));
|
|
2625
|
+
rbs_parser_advance(parser);
|
|
2626
|
+
self_range.end = args_range.end = parser->current_token.range.end;
|
|
2627
|
+
}
|
|
2628
|
+
|
|
2629
|
+
rbs_location_range loc = RBS_RANGE_LEX2AST(self_range);
|
|
2630
|
+
|
|
2631
|
+
rbs_ast_declarations_module_self_t *self_type = rbs_ast_declarations_module_self_new(ALLOCATOR(), loc, module_name, args, RBS_RANGE_LEX2AST(name_range));
|
|
2632
|
+
self_type->args_range = RBS_RANGE_LEX2AST(args_range);
|
|
2633
|
+
rbs_node_list_append(array, (rbs_node_t *) self_type);
|
|
2634
|
+
|
|
2635
|
+
if (parser->next_token.type == pCOMMA) {
|
|
2636
|
+
rbs_parser_advance(parser);
|
|
2637
|
+
} else {
|
|
2638
|
+
break;
|
|
2639
|
+
}
|
|
2640
|
+
}
|
|
2641
|
+
|
|
2642
|
+
return true;
|
|
2643
|
+
}
|
|
2644
|
+
|
|
2645
|
+
NODISCARD
|
|
2646
|
+
static bool parse_nested_decl(rbs_parser_t *parser, const char *nested_in, rbs_position_t annot_pos, rbs_node_list_t *annotations, rbs_node_t **decl);
|
|
2647
|
+
|
|
2648
|
+
/*
|
|
2649
|
+
module_members ::= {} ...<module_member> kEND
|
|
2650
|
+
|
|
2651
|
+
module_member ::= def_member
|
|
2652
|
+
| variable_member
|
|
2653
|
+
| mixin_member
|
|
2654
|
+
| alias_member
|
|
2655
|
+
| attribute_member
|
|
2656
|
+
| `public`
|
|
2657
|
+
| `private`
|
|
2658
|
+
*/
|
|
2659
|
+
NODISCARD
|
|
2660
|
+
static bool parse_module_members(rbs_parser_t *parser, rbs_node_list_t **members) {
|
|
2661
|
+
*members = rbs_node_list_new(ALLOCATOR());
|
|
2662
|
+
|
|
2663
|
+
while (parser->next_token.type != kEND) {
|
|
2664
|
+
rbs_node_list_t *annotations = rbs_node_list_new(ALLOCATOR());
|
|
2665
|
+
rbs_position_t annot_pos;
|
|
2666
|
+
CHECK_PARSE(parse_annotations(parser, annotations, &annot_pos));
|
|
2667
|
+
|
|
2668
|
+
rbs_parser_advance(parser);
|
|
2669
|
+
|
|
2670
|
+
rbs_node_t *member;
|
|
2671
|
+
switch (parser->current_token.type) {
|
|
2672
|
+
case kDEF: {
|
|
2673
|
+
rbs_ast_members_method_definition_t *method_definition;
|
|
2674
|
+
CHECK_PARSE(parse_member_def(parser, false, true, annot_pos, annotations, &method_definition));
|
|
2675
|
+
member = (rbs_node_t *) method_definition;
|
|
2676
|
+
break;
|
|
2677
|
+
}
|
|
2678
|
+
|
|
2679
|
+
case kINCLUDE:
|
|
2680
|
+
case kEXTEND:
|
|
2681
|
+
case kPREPEND: {
|
|
2682
|
+
CHECK_PARSE(parse_mixin_member(parser, false, annot_pos, annotations, &member));
|
|
2683
|
+
break;
|
|
2684
|
+
}
|
|
2685
|
+
case kALIAS: {
|
|
2686
|
+
rbs_ast_members_alias_t *alias_member = NULL;
|
|
2687
|
+
CHECK_PARSE(parse_alias_member(parser, false, annot_pos, annotations, &alias_member));
|
|
2688
|
+
member = (rbs_node_t *) alias_member;
|
|
2689
|
+
break;
|
|
2690
|
+
}
|
|
2691
|
+
case tAIDENT:
|
|
2692
|
+
case tA2IDENT:
|
|
2693
|
+
case kATRBS:
|
|
2694
|
+
case kSELF: {
|
|
2695
|
+
CHECK_PARSE(parse_variable_member(parser, annot_pos, annotations, &member));
|
|
2696
|
+
break;
|
|
2697
|
+
}
|
|
2698
|
+
|
|
2699
|
+
case kATTRREADER:
|
|
2700
|
+
case kATTRWRITER:
|
|
2701
|
+
case kATTRACCESSOR: {
|
|
2702
|
+
CHECK_PARSE(parse_attribute_member(parser, annot_pos, annotations, &member));
|
|
2703
|
+
break;
|
|
2704
|
+
}
|
|
2705
|
+
|
|
2706
|
+
case kPUBLIC:
|
|
2707
|
+
case kPRIVATE:
|
|
2708
|
+
if (parser->next_token.range.start.line == parser->current_token.range.start.line) {
|
|
2709
|
+
switch (parser->next_token.type) {
|
|
2710
|
+
case kDEF: {
|
|
2711
|
+
rbs_ast_members_method_definition_t *method_definition = NULL;
|
|
2712
|
+
CHECK_PARSE(parse_member_def(parser, false, true, annot_pos, annotations, &method_definition));
|
|
2713
|
+
member = (rbs_node_t *) method_definition;
|
|
2714
|
+
break;
|
|
2715
|
+
}
|
|
2716
|
+
case kATTRREADER:
|
|
2717
|
+
case kATTRWRITER:
|
|
2718
|
+
case kATTRACCESSOR: {
|
|
2719
|
+
CHECK_PARSE(parse_attribute_member(parser, annot_pos, annotations, &member));
|
|
2720
|
+
break;
|
|
2721
|
+
}
|
|
2722
|
+
default:
|
|
2723
|
+
rbs_parser_set_error(parser, parser->next_token, true, "method or attribute definition is expected after visibility modifier");
|
|
2724
|
+
return false;
|
|
2725
|
+
}
|
|
2726
|
+
} else {
|
|
2727
|
+
CHECK_PARSE(parse_visibility_member(parser, annotations, &member));
|
|
2728
|
+
}
|
|
2729
|
+
break;
|
|
2730
|
+
|
|
2731
|
+
default:
|
|
2732
|
+
CHECK_PARSE(parse_nested_decl(parser, "module", annot_pos, annotations, &member));
|
|
2733
|
+
break;
|
|
2734
|
+
}
|
|
2735
|
+
|
|
2736
|
+
rbs_node_list_append(*members, member);
|
|
2737
|
+
}
|
|
2738
|
+
|
|
2739
|
+
return true;
|
|
2740
|
+
}
|
|
2741
|
+
|
|
2742
|
+
/*
|
|
2743
|
+
module_decl ::= {module_name} module_type_params module_members <kEND>
|
|
2744
|
+
| {module_name} module_name module_type_params `:` module_self_types module_members <kEND>
|
|
2745
|
+
*/
|
|
2746
|
+
NODISCARD
|
|
2747
|
+
static bool parse_module_decl0(rbs_parser_t *parser, rbs_range_t keyword_range, rbs_type_name_t *module_name, rbs_range_t name_range, rbs_ast_comment_t *comment, rbs_node_list_t *annotations, rbs_ast_declarations_module_t **module_decl) {
|
|
2748
|
+
rbs_parser_push_typevar_table(parser, true);
|
|
2749
|
+
|
|
2750
|
+
rbs_range_t decl_range;
|
|
2751
|
+
decl_range.start = keyword_range.start;
|
|
2752
|
+
|
|
2753
|
+
rbs_range_t type_params_range;
|
|
2754
|
+
rbs_node_list_t *type_params;
|
|
2755
|
+
CHECK_PARSE(parse_type_params(parser, &type_params_range, true, &type_params));
|
|
2756
|
+
|
|
2757
|
+
rbs_node_list_t *self_types = rbs_node_list_new(ALLOCATOR());
|
|
2758
|
+
rbs_range_t colon_range;
|
|
2759
|
+
rbs_range_t self_types_range;
|
|
2760
|
+
if (parser->next_token.type == pCOLON) {
|
|
2761
|
+
rbs_parser_advance(parser);
|
|
2762
|
+
colon_range = parser->current_token.range;
|
|
2763
|
+
self_types_range.start = parser->next_token.range.start;
|
|
2764
|
+
CHECK_PARSE(parse_module_self_types(parser, self_types));
|
|
2765
|
+
self_types_range.end = parser->current_token.range.end;
|
|
2766
|
+
} else {
|
|
2767
|
+
colon_range = NULL_RANGE;
|
|
2768
|
+
self_types_range = NULL_RANGE;
|
|
2769
|
+
}
|
|
2770
|
+
|
|
2771
|
+
rbs_node_list_t *members = NULL;
|
|
2772
|
+
CHECK_PARSE(parse_module_members(parser, &members));
|
|
2773
|
+
|
|
2774
|
+
ADVANCE_ASSERT(parser, kEND);
|
|
2775
|
+
rbs_range_t end_range = parser->current_token.range;
|
|
2776
|
+
decl_range.end = parser->current_token.range.end;
|
|
2777
|
+
|
|
2778
|
+
CHECK_PARSE(parser_pop_typevar_table(parser));
|
|
2779
|
+
|
|
2780
|
+
rbs_location_range loc = RBS_RANGE_LEX2AST(decl_range);
|
|
2781
|
+
|
|
2782
|
+
*module_decl = rbs_ast_declarations_module_new(ALLOCATOR(), loc, module_name, type_params, self_types, members, annotations, comment, RBS_RANGE_LEX2AST(keyword_range), RBS_RANGE_LEX2AST(name_range), RBS_RANGE_LEX2AST(end_range));
|
|
2783
|
+
(*module_decl)->type_params_range = RBS_RANGE_LEX2AST(type_params_range);
|
|
2784
|
+
(*module_decl)->colon_range = RBS_RANGE_LEX2AST(colon_range);
|
|
2785
|
+
(*module_decl)->self_types_range = RBS_RANGE_LEX2AST(self_types_range);
|
|
2786
|
+
return true;
|
|
2787
|
+
}
|
|
2788
|
+
|
|
2789
|
+
/*
|
|
2790
|
+
module_decl ::= {`module`} module_name `=` old_module_name <kEND>
|
|
2791
|
+
| {`module`} module_name module_decl0 <kEND>
|
|
2792
|
+
|
|
2793
|
+
*/
|
|
2794
|
+
NODISCARD
|
|
2795
|
+
static bool parse_module_decl(rbs_parser_t *parser, rbs_position_t comment_pos, rbs_node_list_t *annotations, rbs_node_t **module_decl) {
|
|
2796
|
+
rbs_range_t keyword_range = parser->current_token.range;
|
|
2797
|
+
|
|
2798
|
+
comment_pos = rbs_nonnull_pos_or(comment_pos, parser->current_token.range.start);
|
|
2799
|
+
rbs_ast_comment_t *comment = rbs_parser_get_comment(parser, comment_pos.line);
|
|
2800
|
+
|
|
2801
|
+
rbs_parser_advance(parser);
|
|
2802
|
+
|
|
2803
|
+
rbs_range_t module_name_range;
|
|
2804
|
+
rbs_type_name_t *module_name;
|
|
2805
|
+
CHECK_PARSE(parse_type_name(parser, CLASS_NAME, &module_name_range, &module_name));
|
|
2806
|
+
|
|
2807
|
+
if (parser->next_token.type == pEQ) {
|
|
2808
|
+
rbs_range_t eq_range = parser->next_token.range;
|
|
2809
|
+
rbs_parser_advance(parser);
|
|
2810
|
+
rbs_parser_advance(parser);
|
|
2811
|
+
|
|
2812
|
+
rbs_range_t old_name_range;
|
|
2813
|
+
rbs_type_name_t *old_name = NULL;
|
|
2814
|
+
CHECK_PARSE(parse_type_name(parser, CLASS_NAME, &old_name_range, &old_name));
|
|
2815
|
+
|
|
2816
|
+
rbs_range_t decl_range = {
|
|
2817
|
+
.start = keyword_range.start,
|
|
2818
|
+
.end = old_name_range.end
|
|
2819
|
+
};
|
|
2820
|
+
|
|
2821
|
+
rbs_location_range loc = RBS_RANGE_LEX2AST(decl_range);
|
|
2822
|
+
|
|
2823
|
+
*module_decl = (rbs_node_t *) rbs_ast_declarations_module_alias_new(ALLOCATOR(), loc, module_name, old_name, comment, annotations, RBS_RANGE_LEX2AST(keyword_range), RBS_RANGE_LEX2AST(module_name_range), RBS_RANGE_LEX2AST(eq_range), RBS_RANGE_LEX2AST(old_name_range));
|
|
2824
|
+
} else {
|
|
2825
|
+
rbs_ast_declarations_module_t *module_decl0 = NULL;
|
|
2826
|
+
CHECK_PARSE(parse_module_decl0(parser, keyword_range, module_name, module_name_range, comment, annotations, &module_decl0));
|
|
2827
|
+
*module_decl = (rbs_node_t *) module_decl0;
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
return true;
|
|
2831
|
+
}
|
|
2832
|
+
|
|
2833
|
+
/*
|
|
2834
|
+
class_decl_super ::= {} `<` <class_instance_name>
|
|
2835
|
+
| {<>}
|
|
2836
|
+
*/
|
|
2837
|
+
NODISCARD
|
|
2838
|
+
static bool parse_class_decl_super(rbs_parser_t *parser, rbs_range_t *lt_range, rbs_ast_declarations_class_super_t **super) {
|
|
2839
|
+
if (parser_advance_if(parser, pLT)) {
|
|
2840
|
+
*lt_range = parser->current_token.range;
|
|
2841
|
+
|
|
2842
|
+
rbs_range_t super_range;
|
|
2843
|
+
super_range.start = parser->next_token.range.start;
|
|
2844
|
+
|
|
2845
|
+
rbs_node_list_t *args = rbs_node_list_new(ALLOCATOR());
|
|
2846
|
+
rbs_type_name_t *name = NULL;
|
|
2847
|
+
rbs_range_t name_range, args_range;
|
|
2848
|
+
CHECK_PARSE(class_instance_name(parser, CLASS_NAME, args, &name_range, &args_range, &name, false));
|
|
2849
|
+
|
|
2850
|
+
super_range.end = parser->current_token.range.end;
|
|
2851
|
+
|
|
2852
|
+
rbs_location_range loc = RBS_RANGE_LEX2AST(super_range);
|
|
2853
|
+
*super = rbs_ast_declarations_class_super_new(ALLOCATOR(), loc, name, args, RBS_RANGE_LEX2AST(name_range));
|
|
2854
|
+
(*super)->args_range = RBS_RANGE_LEX2AST(args_range);
|
|
2855
|
+
} else {
|
|
2856
|
+
*lt_range = NULL_RANGE;
|
|
2857
|
+
}
|
|
2858
|
+
|
|
2859
|
+
return true;
|
|
2860
|
+
}
|
|
2861
|
+
|
|
2862
|
+
/*
|
|
2863
|
+
class_decl ::= {class_name} type_params class_decl_super class_members <`end`>
|
|
2864
|
+
*/
|
|
2865
|
+
NODISCARD
|
|
2866
|
+
static bool parse_class_decl0(rbs_parser_t *parser, rbs_range_t keyword_range, rbs_type_name_t *name, rbs_range_t name_range, rbs_ast_comment_t *comment, rbs_node_list_t *annotations, rbs_ast_declarations_class_t **class_decl) {
|
|
2867
|
+
rbs_parser_push_typevar_table(parser, true);
|
|
2868
|
+
|
|
2869
|
+
rbs_range_t decl_range;
|
|
2870
|
+
decl_range.start = keyword_range.start;
|
|
2871
|
+
|
|
2872
|
+
rbs_range_t type_params_range;
|
|
2873
|
+
rbs_node_list_t *type_params;
|
|
2874
|
+
CHECK_PARSE(parse_type_params(parser, &type_params_range, true, &type_params));
|
|
2875
|
+
|
|
2876
|
+
rbs_range_t lt_range;
|
|
2877
|
+
rbs_ast_declarations_class_super_t *super = NULL;
|
|
2878
|
+
CHECK_PARSE(parse_class_decl_super(parser, <_range, &super));
|
|
2879
|
+
|
|
2880
|
+
rbs_node_list_t *members = NULL;
|
|
2881
|
+
CHECK_PARSE(parse_module_members(parser, &members));
|
|
2882
|
+
|
|
2883
|
+
ADVANCE_ASSERT(parser, kEND);
|
|
2884
|
+
|
|
2885
|
+
rbs_range_t end_range = parser->current_token.range;
|
|
2886
|
+
|
|
2887
|
+
decl_range.end = end_range.end;
|
|
2888
|
+
|
|
2889
|
+
CHECK_PARSE(parser_pop_typevar_table(parser));
|
|
2890
|
+
|
|
2891
|
+
rbs_location_range loc = RBS_RANGE_LEX2AST(decl_range);
|
|
2892
|
+
|
|
2893
|
+
*class_decl = rbs_ast_declarations_class_new(ALLOCATOR(), loc, name, type_params, super, members, annotations, comment, RBS_RANGE_LEX2AST(keyword_range), RBS_RANGE_LEX2AST(name_range), RBS_RANGE_LEX2AST(end_range));
|
|
2894
|
+
(*class_decl)->type_params_range = RBS_RANGE_LEX2AST(type_params_range);
|
|
2895
|
+
(*class_decl)->lt_range = RBS_RANGE_LEX2AST(lt_range);
|
|
2896
|
+
|
|
2897
|
+
return true;
|
|
2898
|
+
}
|
|
2899
|
+
|
|
2900
|
+
/*
|
|
2901
|
+
class_decl ::= {`class`} class_name `=` <class_name>
|
|
2902
|
+
| {`class`} class_name <class_decl0>
|
|
2903
|
+
*/
|
|
2904
|
+
NODISCARD
|
|
2905
|
+
static bool parse_class_decl(rbs_parser_t *parser, rbs_position_t comment_pos, rbs_node_list_t *annotations, rbs_node_t **class_decl) {
|
|
2906
|
+
rbs_range_t keyword_range = parser->current_token.range;
|
|
2907
|
+
|
|
2908
|
+
comment_pos = rbs_nonnull_pos_or(comment_pos, parser->current_token.range.start);
|
|
2909
|
+
rbs_ast_comment_t *comment = rbs_parser_get_comment(parser, comment_pos.line);
|
|
2910
|
+
|
|
2911
|
+
rbs_parser_advance(parser);
|
|
2912
|
+
rbs_range_t class_name_range;
|
|
2913
|
+
rbs_type_name_t *class_name = NULL;
|
|
2914
|
+
CHECK_PARSE(parse_type_name(parser, CLASS_NAME, &class_name_range, &class_name));
|
|
2915
|
+
|
|
2916
|
+
if (parser->next_token.type == pEQ) {
|
|
2917
|
+
rbs_range_t eq_range = parser->next_token.range;
|
|
2918
|
+
rbs_parser_advance(parser);
|
|
2919
|
+
rbs_parser_advance(parser);
|
|
2920
|
+
|
|
2921
|
+
rbs_range_t old_name_range;
|
|
2922
|
+
rbs_type_name_t *old_name = NULL;
|
|
2923
|
+
CHECK_PARSE(parse_type_name(parser, CLASS_NAME, &old_name_range, &old_name));
|
|
2924
|
+
|
|
2925
|
+
rbs_range_t decl_range = {
|
|
2926
|
+
.start = keyword_range.start,
|
|
2927
|
+
.end = old_name_range.end,
|
|
2928
|
+
};
|
|
2929
|
+
|
|
2930
|
+
rbs_location_range loc = RBS_RANGE_LEX2AST(decl_range);
|
|
2931
|
+
|
|
2932
|
+
*class_decl = (rbs_node_t *) rbs_ast_declarations_class_alias_new(ALLOCATOR(), loc, class_name, old_name, comment, annotations, RBS_RANGE_LEX2AST(keyword_range), RBS_RANGE_LEX2AST(class_name_range), RBS_RANGE_LEX2AST(eq_range), RBS_RANGE_LEX2AST(old_name_range));
|
|
2933
|
+
} else {
|
|
2934
|
+
rbs_ast_declarations_class_t *class_decl0 = NULL;
|
|
2935
|
+
CHECK_PARSE(parse_class_decl0(parser, keyword_range, class_name, class_name_range, comment, annotations, &class_decl0));
|
|
2936
|
+
*class_decl = (rbs_node_t *) class_decl0;
|
|
2937
|
+
}
|
|
2938
|
+
|
|
2939
|
+
return true;
|
|
2940
|
+
}
|
|
2941
|
+
|
|
2942
|
+
/*
|
|
2943
|
+
nested_decl ::= {<const_decl>}
|
|
2944
|
+
| {<class_decl>}
|
|
2945
|
+
| {<interface_decl>}
|
|
2946
|
+
| {<module_decl>}
|
|
2947
|
+
| {<class_decl>}
|
|
2948
|
+
*/
|
|
2949
|
+
NODISCARD
|
|
2950
|
+
static bool parse_nested_decl(rbs_parser_t *parser, const char *nested_in, rbs_position_t annot_pos, rbs_node_list_t *annotations, rbs_node_t **decl) {
|
|
2951
|
+
rbs_parser_push_typevar_table(parser, true);
|
|
2952
|
+
|
|
2953
|
+
switch (parser->current_token.type) {
|
|
2954
|
+
case tUIDENT:
|
|
2955
|
+
case pCOLON2: {
|
|
2956
|
+
rbs_ast_declarations_constant_t *constant = NULL;
|
|
2957
|
+
CHECK_PARSE(parse_const_decl(parser, annotations, &constant));
|
|
2958
|
+
*decl = (rbs_node_t *) constant;
|
|
2959
|
+
break;
|
|
2960
|
+
}
|
|
2961
|
+
case tGIDENT: {
|
|
2962
|
+
rbs_ast_declarations_global_t *global = NULL;
|
|
2963
|
+
CHECK_PARSE(parse_global_decl(parser, annotations, &global));
|
|
2964
|
+
*decl = (rbs_node_t *) global;
|
|
2965
|
+
break;
|
|
2966
|
+
}
|
|
2967
|
+
case kTYPE: {
|
|
2968
|
+
rbs_ast_declarations_type_alias_t *typealias = NULL;
|
|
2969
|
+
CHECK_PARSE(parse_type_decl(parser, annot_pos, annotations, &typealias));
|
|
2970
|
+
*decl = (rbs_node_t *) typealias;
|
|
2971
|
+
break;
|
|
2972
|
+
}
|
|
2973
|
+
case kINTERFACE: {
|
|
2974
|
+
rbs_ast_declarations_interface_t *interface_decl = NULL;
|
|
2975
|
+
CHECK_PARSE(parse_interface_decl(parser, annot_pos, annotations, &interface_decl));
|
|
2976
|
+
*decl = (rbs_node_t *) interface_decl;
|
|
2977
|
+
break;
|
|
2978
|
+
}
|
|
2979
|
+
case kMODULE: {
|
|
2980
|
+
rbs_node_t *module_decl = NULL;
|
|
2981
|
+
CHECK_PARSE(parse_module_decl(parser, annot_pos, annotations, &module_decl));
|
|
2982
|
+
*decl = module_decl;
|
|
2983
|
+
break;
|
|
2984
|
+
}
|
|
2985
|
+
case kCLASS: {
|
|
2986
|
+
rbs_node_t *class_decl = NULL;
|
|
2987
|
+
CHECK_PARSE(parse_class_decl(parser, annot_pos, annotations, &class_decl));
|
|
2988
|
+
*decl = class_decl;
|
|
2989
|
+
break;
|
|
2990
|
+
}
|
|
2991
|
+
default:
|
|
2992
|
+
rbs_parser_set_error(parser, parser->current_token, true, "unexpected token for class/module declaration member");
|
|
2993
|
+
return false;
|
|
2994
|
+
}
|
|
2995
|
+
|
|
2996
|
+
CHECK_PARSE(parser_pop_typevar_table(parser));
|
|
2997
|
+
|
|
2998
|
+
return true;
|
|
2999
|
+
}
|
|
3000
|
+
|
|
3001
|
+
NODISCARD
|
|
3002
|
+
static bool parse_decl(rbs_parser_t *parser, rbs_node_t **decl) {
|
|
3003
|
+
rbs_node_list_t *annotations = rbs_node_list_new(ALLOCATOR());
|
|
3004
|
+
rbs_position_t annot_pos = NullPosition;
|
|
3005
|
+
|
|
3006
|
+
CHECK_PARSE(parse_annotations(parser, annotations, &annot_pos));
|
|
3007
|
+
rbs_parser_advance(parser);
|
|
3008
|
+
|
|
3009
|
+
switch (parser->current_token.type) {
|
|
3010
|
+
case tUIDENT:
|
|
3011
|
+
case pCOLON2: {
|
|
3012
|
+
rbs_ast_declarations_constant_t *constant = NULL;
|
|
3013
|
+
CHECK_PARSE(parse_const_decl(parser, annotations, &constant));
|
|
3014
|
+
*decl = (rbs_node_t *) constant;
|
|
3015
|
+
return true;
|
|
3016
|
+
}
|
|
3017
|
+
case tGIDENT: {
|
|
3018
|
+
rbs_ast_declarations_global_t *global = NULL;
|
|
3019
|
+
CHECK_PARSE(parse_global_decl(parser, annotations, &global));
|
|
3020
|
+
*decl = (rbs_node_t *) global;
|
|
3021
|
+
return true;
|
|
3022
|
+
}
|
|
3023
|
+
case kTYPE: {
|
|
3024
|
+
rbs_ast_declarations_type_alias_t *typealias = NULL;
|
|
3025
|
+
CHECK_PARSE(parse_type_decl(parser, annot_pos, annotations, &typealias));
|
|
3026
|
+
*decl = (rbs_node_t *) typealias;
|
|
3027
|
+
return true;
|
|
3028
|
+
}
|
|
3029
|
+
case kINTERFACE: {
|
|
3030
|
+
rbs_ast_declarations_interface_t *interface_decl = NULL;
|
|
3031
|
+
CHECK_PARSE(parse_interface_decl(parser, annot_pos, annotations, &interface_decl));
|
|
3032
|
+
*decl = (rbs_node_t *) interface_decl;
|
|
3033
|
+
return true;
|
|
3034
|
+
}
|
|
3035
|
+
case kMODULE: {
|
|
3036
|
+
rbs_node_t *module_decl = NULL;
|
|
3037
|
+
CHECK_PARSE(parse_module_decl(parser, annot_pos, annotations, &module_decl));
|
|
3038
|
+
*decl = module_decl;
|
|
3039
|
+
return true;
|
|
3040
|
+
}
|
|
3041
|
+
case kCLASS: {
|
|
3042
|
+
rbs_node_t *class_decl = NULL;
|
|
3043
|
+
CHECK_PARSE(parse_class_decl(parser, annot_pos, annotations, &class_decl));
|
|
3044
|
+
*decl = class_decl;
|
|
3045
|
+
return true;
|
|
3046
|
+
}
|
|
3047
|
+
default:
|
|
3048
|
+
rbs_parser_set_error(parser, parser->current_token, true, "cannot start a declaration");
|
|
3049
|
+
return false;
|
|
3050
|
+
}
|
|
3051
|
+
}
|
|
3052
|
+
|
|
3053
|
+
/*
|
|
3054
|
+
namespace ::= {} (`::`)? (`tUIDENT` `::`)* `tUIDENT` <`::`>
|
|
3055
|
+
| {} <> (empty -- returns empty namespace)
|
|
3056
|
+
*/
|
|
3057
|
+
NODISCARD
|
|
3058
|
+
static bool parse_namespace(rbs_parser_t *parser, rbs_range_t *rg, rbs_namespace_t **out_ns) {
|
|
3059
|
+
bool is_absolute = false;
|
|
3060
|
+
|
|
3061
|
+
if (parser->next_token.type == pCOLON2) {
|
|
3062
|
+
*rg = (rbs_range_t) {
|
|
3063
|
+
.start = parser->next_token.range.start,
|
|
3064
|
+
.end = parser->next_token.range.end,
|
|
3065
|
+
};
|
|
3066
|
+
is_absolute = true;
|
|
3067
|
+
|
|
3068
|
+
rbs_parser_advance(parser);
|
|
3069
|
+
}
|
|
3070
|
+
|
|
3071
|
+
rbs_node_list_t *path = rbs_node_list_new(ALLOCATOR());
|
|
3072
|
+
|
|
3073
|
+
while (true) {
|
|
3074
|
+
if (parser->next_token.type == tUIDENT && parser->next_token2.type == pCOLON2) {
|
|
3075
|
+
rbs_location_range symbol_loc = RBS_RANGE_LEX2AST(parser->next_token.range);
|
|
3076
|
+
rbs_ast_symbol_t *symbol = rbs_ast_symbol_new(ALLOCATOR(), symbol_loc, &parser->constant_pool, INTERN_TOKEN(parser, parser->next_token));
|
|
3077
|
+
rbs_node_list_append(path, (rbs_node_t *) symbol);
|
|
3078
|
+
if (rbs_null_position_p(rg->start)) {
|
|
3079
|
+
rg->start = parser->next_token.range.start;
|
|
3080
|
+
}
|
|
3081
|
+
rg->end = parser->next_token2.range.end;
|
|
3082
|
+
rbs_parser_advance(parser);
|
|
3083
|
+
rbs_parser_advance(parser);
|
|
3084
|
+
} else {
|
|
3085
|
+
break;
|
|
3086
|
+
}
|
|
3087
|
+
}
|
|
3088
|
+
|
|
3089
|
+
*out_ns = rbs_namespace_new(ALLOCATOR(), RBS_RANGE_LEX2AST(*rg), path, is_absolute);
|
|
3090
|
+
return true;
|
|
3091
|
+
}
|
|
3092
|
+
|
|
3093
|
+
/*
|
|
3094
|
+
use_clauses ::= {} use_clause `,` ... `,` <use_clause>
|
|
3095
|
+
|
|
3096
|
+
use_clause ::= {} namespace <tUIDENT>
|
|
3097
|
+
| {} namespace tUIDENT `as` <tUIDENT>
|
|
3098
|
+
| {} namespace <tSTAR>
|
|
3099
|
+
*/
|
|
3100
|
+
NODISCARD
|
|
3101
|
+
static bool parse_use_clauses(rbs_parser_t *parser, rbs_node_list_t *clauses) {
|
|
3102
|
+
while (true) {
|
|
3103
|
+
rbs_range_t namespace_range = NULL_RANGE;
|
|
3104
|
+
rbs_namespace_t *ns = NULL;
|
|
3105
|
+
CHECK_PARSE(parse_namespace(parser, &namespace_range, &ns));
|
|
3106
|
+
|
|
3107
|
+
switch (parser->next_token.type) {
|
|
3108
|
+
case tLIDENT:
|
|
3109
|
+
case tULIDENT:
|
|
3110
|
+
case tUIDENT: {
|
|
3111
|
+
rbs_parser_advance(parser);
|
|
3112
|
+
|
|
3113
|
+
enum RBSTokenType ident_type = parser->current_token.type;
|
|
3114
|
+
|
|
3115
|
+
rbs_range_t type_name_range = rbs_null_range_p(namespace_range) ? parser->current_token.range : (rbs_range_t) { .start = namespace_range.start, .end = parser->current_token.range.end };
|
|
3116
|
+
|
|
3117
|
+
rbs_location_range symbol_loc = rbs_location_range_current_token(parser);
|
|
3118
|
+
rbs_ast_symbol_t *symbol = rbs_ast_symbol_new(ALLOCATOR(), symbol_loc, &parser->constant_pool, INTERN_TOKEN(parser, parser->current_token));
|
|
3119
|
+
rbs_type_name_t *type_name = rbs_type_name_new(ALLOCATOR(), RBS_RANGE_LEX2AST(type_name_range), ns, symbol);
|
|
3120
|
+
|
|
3121
|
+
rbs_range_t keyword_range = NULL_RANGE;
|
|
3122
|
+
rbs_range_t new_name_range = NULL_RANGE;
|
|
3123
|
+
rbs_ast_symbol_t *new_name = NULL;
|
|
3124
|
+
rbs_range_t clause_range = type_name_range;
|
|
3125
|
+
if (parser->next_token.type == kAS) {
|
|
3126
|
+
rbs_parser_advance(parser);
|
|
3127
|
+
keyword_range = parser->current_token.range;
|
|
3128
|
+
|
|
3129
|
+
if (ident_type == tUIDENT) ADVANCE_ASSERT(parser, tUIDENT);
|
|
3130
|
+
if (ident_type == tLIDENT) ADVANCE_ASSERT(parser, tLIDENT);
|
|
3131
|
+
if (ident_type == tULIDENT) ADVANCE_ASSERT(parser, tULIDENT);
|
|
3132
|
+
|
|
3133
|
+
rbs_location_range symbol_loc = RBS_RANGE_LEX2AST(new_name_range);
|
|
3134
|
+
new_name = rbs_ast_symbol_new(ALLOCATOR(), symbol_loc, &parser->constant_pool, INTERN_TOKEN(parser, parser->current_token));
|
|
3135
|
+
new_name_range = parser->current_token.range;
|
|
3136
|
+
clause_range.end = new_name_range.end;
|
|
3137
|
+
}
|
|
3138
|
+
|
|
3139
|
+
rbs_location_range loc = RBS_RANGE_LEX2AST(clause_range);
|
|
3140
|
+
|
|
3141
|
+
rbs_ast_directives_use_single_clause_t *clause = rbs_ast_directives_use_single_clause_new(ALLOCATOR(), loc, type_name, new_name, RBS_RANGE_LEX2AST(type_name_range));
|
|
3142
|
+
clause->keyword_range = RBS_RANGE_LEX2AST(keyword_range);
|
|
3143
|
+
clause->new_name_range = RBS_RANGE_LEX2AST(new_name_range);
|
|
3144
|
+
|
|
3145
|
+
rbs_node_list_append(clauses, (rbs_node_t *) clause);
|
|
3146
|
+
|
|
3147
|
+
break;
|
|
3148
|
+
}
|
|
3149
|
+
case pSTAR: {
|
|
3150
|
+
rbs_range_t clause_range = namespace_range;
|
|
3151
|
+
rbs_parser_advance(parser);
|
|
3152
|
+
|
|
3153
|
+
rbs_range_t star_range = parser->current_token.range;
|
|
3154
|
+
clause_range.end = star_range.end;
|
|
3155
|
+
|
|
3156
|
+
rbs_location_range loc = RBS_RANGE_LEX2AST(clause_range);
|
|
3157
|
+
|
|
3158
|
+
rbs_ast_directives_use_wildcard_clause_t *clause = rbs_ast_directives_use_wildcard_clause_new(ALLOCATOR(), loc, ns, RBS_RANGE_LEX2AST(namespace_range), RBS_RANGE_LEX2AST(star_range));
|
|
3159
|
+
rbs_node_list_append(clauses, (rbs_node_t *) clause);
|
|
3160
|
+
|
|
3161
|
+
break;
|
|
3162
|
+
}
|
|
3163
|
+
default:
|
|
3164
|
+
rbs_parser_set_error(parser, parser->next_token, true, "use clause is expected");
|
|
3165
|
+
return false;
|
|
3166
|
+
}
|
|
3167
|
+
|
|
3168
|
+
if (parser->next_token.type == pCOMMA) {
|
|
3169
|
+
rbs_parser_advance(parser);
|
|
3170
|
+
} else {
|
|
3171
|
+
break;
|
|
3172
|
+
}
|
|
3173
|
+
}
|
|
3174
|
+
|
|
3175
|
+
return true;
|
|
3176
|
+
}
|
|
3177
|
+
|
|
3178
|
+
/*
|
|
3179
|
+
use_directive ::= {} `use` <clauses>
|
|
3180
|
+
*/
|
|
3181
|
+
NODISCARD
|
|
3182
|
+
static bool parse_use_directive(rbs_parser_t *parser, rbs_ast_directives_use_t **use_directive) {
|
|
3183
|
+
if (parser->next_token.type == kUSE) {
|
|
3184
|
+
rbs_parser_advance(parser);
|
|
3185
|
+
|
|
3186
|
+
rbs_range_t keyword_range = parser->current_token.range;
|
|
3187
|
+
|
|
3188
|
+
rbs_node_list_t *clauses = rbs_node_list_new(ALLOCATOR());
|
|
3189
|
+
CHECK_PARSE(parse_use_clauses(parser, clauses));
|
|
3190
|
+
|
|
3191
|
+
rbs_range_t directive_range = keyword_range;
|
|
3192
|
+
directive_range.end = parser->current_token.range.end;
|
|
3193
|
+
|
|
3194
|
+
rbs_location_range loc = RBS_RANGE_LEX2AST(directive_range);
|
|
3195
|
+
|
|
3196
|
+
*use_directive = rbs_ast_directives_use_new(ALLOCATOR(), loc, clauses, RBS_RANGE_LEX2AST(keyword_range));
|
|
3197
|
+
}
|
|
3198
|
+
|
|
3199
|
+
return true;
|
|
3200
|
+
}
|
|
3201
|
+
|
|
3202
|
+
static rbs_ast_comment_t *parse_comment_lines(rbs_parser_t *parser, rbs_comment_t *com) {
|
|
3203
|
+
size_t hash_bytes = parser->lexer->encoding->char_width((const uint8_t *) "#", (size_t) 1);
|
|
3204
|
+
size_t space_bytes = parser->lexer->encoding->char_width((const uint8_t *) " ", (size_t) 1);
|
|
3205
|
+
|
|
3206
|
+
rbs_buffer_t rbs_buffer;
|
|
3207
|
+
rbs_buffer_init(ALLOCATOR(), &rbs_buffer);
|
|
3208
|
+
|
|
3209
|
+
for (size_t i = 0; i < com->line_tokens_count; i++) {
|
|
3210
|
+
rbs_token_t tok = com->line_tokens[i];
|
|
3211
|
+
|
|
3212
|
+
const char *comment_start = parser->lexer->string.start + tok.range.start.byte_pos + hash_bytes;
|
|
3213
|
+
size_t comment_bytes = RBS_RANGE_BYTES(tok.range) - hash_bytes;
|
|
3214
|
+
|
|
3215
|
+
rbs_string_t str = rbs_string_new(
|
|
3216
|
+
comment_start,
|
|
3217
|
+
parser->lexer->string.end
|
|
3218
|
+
);
|
|
3219
|
+
|
|
3220
|
+
// Assumes the input is ASCII compatible
|
|
3221
|
+
unsigned char c = str.start[0];
|
|
3222
|
+
|
|
3223
|
+
if (c == ' ') {
|
|
3224
|
+
comment_start += space_bytes;
|
|
3225
|
+
comment_bytes -= space_bytes;
|
|
3226
|
+
}
|
|
3227
|
+
|
|
3228
|
+
rbs_buffer_append_string(ALLOCATOR(), &rbs_buffer, comment_start, comment_bytes);
|
|
3229
|
+
rbs_buffer_append_cstr(ALLOCATOR(), &rbs_buffer, "\n");
|
|
3230
|
+
}
|
|
3231
|
+
|
|
3232
|
+
return rbs_ast_comment_new(
|
|
3233
|
+
ALLOCATOR(),
|
|
3234
|
+
(rbs_location_range) {
|
|
3235
|
+
.start_char = com->start.char_pos,
|
|
3236
|
+
.start_byte = com->start.byte_pos,
|
|
3237
|
+
.end_char = com->end.char_pos,
|
|
3238
|
+
.end_byte = com->end.byte_pos,
|
|
3239
|
+
},
|
|
3240
|
+
rbs_buffer_to_string(&rbs_buffer)
|
|
3241
|
+
);
|
|
3242
|
+
}
|
|
3243
|
+
|
|
3244
|
+
static rbs_comment_t *comment_get_comment(rbs_comment_t *com, int line) {
|
|
3245
|
+
if (com == NULL) {
|
|
3246
|
+
return NULL;
|
|
3247
|
+
}
|
|
3248
|
+
|
|
3249
|
+
if (com->end.line < line) {
|
|
3250
|
+
return NULL;
|
|
3251
|
+
}
|
|
3252
|
+
|
|
3253
|
+
if (com->end.line == line) {
|
|
3254
|
+
return com;
|
|
3255
|
+
}
|
|
3256
|
+
|
|
3257
|
+
return comment_get_comment(com->next_comment, line);
|
|
3258
|
+
}
|
|
3259
|
+
|
|
3260
|
+
static void comment_insert_new_line(rbs_allocator_t *allocator, rbs_comment_t *com, rbs_token_t comment_token) {
|
|
3261
|
+
if (com->line_tokens_count == com->line_tokens_capacity) {
|
|
3262
|
+
size_t old_size = com->line_tokens_capacity;
|
|
3263
|
+
size_t new_size = old_size * 2;
|
|
3264
|
+
com->line_tokens_capacity = new_size;
|
|
3265
|
+
|
|
3266
|
+
com->line_tokens = rbs_allocator_realloc(
|
|
3267
|
+
allocator,
|
|
3268
|
+
com->line_tokens,
|
|
3269
|
+
sizeof(rbs_token_t) * old_size,
|
|
3270
|
+
sizeof(rbs_token_t) * new_size,
|
|
3271
|
+
rbs_token_t
|
|
3272
|
+
);
|
|
3273
|
+
}
|
|
3274
|
+
|
|
3275
|
+
com->line_tokens[com->line_tokens_count++] = comment_token;
|
|
3276
|
+
com->end = comment_token.range.end;
|
|
3277
|
+
}
|
|
3278
|
+
|
|
3279
|
+
static rbs_comment_t *alloc_comment(rbs_allocator_t *allocator, rbs_token_t comment_token, rbs_comment_t *last_comment) {
|
|
3280
|
+
rbs_comment_t *new_comment = rbs_allocator_alloc(allocator, rbs_comment_t);
|
|
3281
|
+
|
|
3282
|
+
size_t initial_line_capacity = 10;
|
|
3283
|
+
|
|
3284
|
+
rbs_token_t *tokens = rbs_allocator_calloc(allocator, initial_line_capacity, rbs_token_t);
|
|
3285
|
+
tokens[0] = comment_token;
|
|
3286
|
+
|
|
3287
|
+
*new_comment = (rbs_comment_t) {
|
|
3288
|
+
.start = comment_token.range.start,
|
|
3289
|
+
.end = comment_token.range.end,
|
|
3290
|
+
|
|
3291
|
+
.line_tokens_capacity = initial_line_capacity,
|
|
3292
|
+
.line_tokens_count = 1,
|
|
3293
|
+
.line_tokens = tokens,
|
|
3294
|
+
|
|
3295
|
+
.next_comment = last_comment,
|
|
3296
|
+
};
|
|
3297
|
+
|
|
3298
|
+
return new_comment;
|
|
3299
|
+
}
|
|
3300
|
+
|
|
3301
|
+
/**
|
|
3302
|
+
* Insert new comment line token.
|
|
3303
|
+
* */
|
|
3304
|
+
static void insert_comment_line(rbs_parser_t *parser, rbs_token_t tok) {
|
|
3305
|
+
int prev_line = tok.range.start.line - 1;
|
|
3306
|
+
|
|
3307
|
+
rbs_comment_t *com = comment_get_comment(parser->last_comment, prev_line);
|
|
3308
|
+
|
|
3309
|
+
if (com) {
|
|
3310
|
+
comment_insert_new_line(ALLOCATOR(), com, tok);
|
|
3311
|
+
} else {
|
|
3312
|
+
parser->last_comment = alloc_comment(ALLOCATOR(), tok, parser->last_comment);
|
|
3313
|
+
}
|
|
3314
|
+
}
|
|
3315
|
+
|
|
3316
|
+
bool rbs_parse_signature(rbs_parser_t *parser, rbs_signature_t **signature) {
|
|
3317
|
+
rbs_range_t signature_range;
|
|
3318
|
+
signature_range.start = parser->current_token.range.start;
|
|
3319
|
+
|
|
3320
|
+
rbs_node_list_t *dirs = rbs_node_list_new(ALLOCATOR());
|
|
3321
|
+
rbs_node_list_t *decls = rbs_node_list_new(ALLOCATOR());
|
|
3322
|
+
|
|
3323
|
+
while (parser->next_token.type == kUSE) {
|
|
3324
|
+
rbs_ast_directives_use_t *use_node;
|
|
3325
|
+
CHECK_PARSE(parse_use_directive(parser, &use_node));
|
|
3326
|
+
|
|
3327
|
+
rbs_node_list_append(dirs, (rbs_node_t *) use_node);
|
|
3328
|
+
}
|
|
3329
|
+
|
|
3330
|
+
while (parser->next_token.type != pEOF) {
|
|
3331
|
+
rbs_node_t *decl = NULL;
|
|
3332
|
+
CHECK_PARSE(parse_decl(parser, &decl));
|
|
3333
|
+
rbs_node_list_append(decls, decl);
|
|
3334
|
+
}
|
|
3335
|
+
|
|
3336
|
+
signature_range.end = parser->current_token.range.end;
|
|
3337
|
+
*signature = rbs_signature_new(ALLOCATOR(), RBS_RANGE_LEX2AST(signature_range), dirs, decls);
|
|
3338
|
+
return true;
|
|
3339
|
+
}
|
|
3340
|
+
|
|
3341
|
+
bool rbs_parse_type_params(rbs_parser_t *parser, bool module_type_params, rbs_node_list_t **params) {
|
|
3342
|
+
if (parser->next_token.type != pLBRACKET) {
|
|
3343
|
+
rbs_parser_set_error(parser, parser->next_token, true, "expected a token `pLBRACKET`");
|
|
3344
|
+
return false;
|
|
3345
|
+
}
|
|
3346
|
+
|
|
3347
|
+
rbs_range_t rg = NULL_RANGE;
|
|
3348
|
+
rbs_parser_push_typevar_table(parser, true);
|
|
3349
|
+
bool res = parse_type_params(parser, &rg, module_type_params, params);
|
|
3350
|
+
rbs_parser_push_typevar_table(parser, false);
|
|
3351
|
+
|
|
3352
|
+
rbs_parser_advance(parser);
|
|
3353
|
+
if (parser->current_token.type != pEOF) {
|
|
3354
|
+
rbs_parser_set_error(parser, parser->current_token, true, "expected a token `%s`", rbs_token_type_str(pEOF));
|
|
3355
|
+
return false;
|
|
3356
|
+
}
|
|
3357
|
+
|
|
3358
|
+
return res;
|
|
3359
|
+
}
|
|
3360
|
+
|
|
3361
|
+
id_table *alloc_empty_table(rbs_allocator_t *allocator) {
|
|
3362
|
+
id_table *table = rbs_allocator_alloc(allocator, id_table);
|
|
3363
|
+
|
|
3364
|
+
*table = (id_table) {
|
|
3365
|
+
.size = 10,
|
|
3366
|
+
.count = 0,
|
|
3367
|
+
.ids = rbs_allocator_calloc(allocator, 10, rbs_constant_id_t),
|
|
3368
|
+
.next = NULL,
|
|
3369
|
+
};
|
|
3370
|
+
|
|
3371
|
+
return table;
|
|
3372
|
+
}
|
|
3373
|
+
|
|
3374
|
+
id_table *alloc_reset_table(rbs_allocator_t *allocator) {
|
|
3375
|
+
id_table *table = rbs_allocator_alloc(allocator, id_table);
|
|
3376
|
+
|
|
3377
|
+
*table = (id_table) {
|
|
3378
|
+
.size = 0,
|
|
3379
|
+
.count = 0,
|
|
3380
|
+
.ids = NULL,
|
|
3381
|
+
.next = NULL,
|
|
3382
|
+
};
|
|
3383
|
+
|
|
3384
|
+
return table;
|
|
3385
|
+
}
|
|
3386
|
+
|
|
3387
|
+
void rbs_parser_push_typevar_table(rbs_parser_t *parser, bool reset) {
|
|
3388
|
+
if (reset) {
|
|
3389
|
+
id_table *table = alloc_reset_table(ALLOCATOR());
|
|
3390
|
+
table->next = parser->vars;
|
|
3391
|
+
parser->vars = table;
|
|
3392
|
+
}
|
|
3393
|
+
|
|
3394
|
+
id_table *table = alloc_empty_table(ALLOCATOR());
|
|
3395
|
+
table->next = parser->vars;
|
|
3396
|
+
parser->vars = table;
|
|
3397
|
+
}
|
|
3398
|
+
|
|
3399
|
+
NODISCARD
|
|
3400
|
+
bool rbs_parser_insert_typevar(rbs_parser_t *parser, rbs_constant_id_t id) {
|
|
3401
|
+
id_table *table = parser->vars;
|
|
3402
|
+
|
|
3403
|
+
if (RESET_TABLE_P(table)) {
|
|
3404
|
+
rbs_parser_set_error(parser, parser->current_token, false, "Cannot insert to reset table");
|
|
3405
|
+
return false;
|
|
3406
|
+
}
|
|
3407
|
+
|
|
3408
|
+
if (table->size == table->count) {
|
|
3409
|
+
// expand
|
|
3410
|
+
rbs_constant_id_t *ptr = table->ids;
|
|
3411
|
+
table->size += 10;
|
|
3412
|
+
table->ids = rbs_allocator_calloc(ALLOCATOR(), table->size, rbs_constant_id_t);
|
|
3413
|
+
memcpy(table->ids, ptr, sizeof(rbs_constant_id_t) * table->count);
|
|
3414
|
+
}
|
|
3415
|
+
|
|
3416
|
+
table->ids[table->count++] = id;
|
|
3417
|
+
|
|
3418
|
+
return true;
|
|
3419
|
+
}
|
|
3420
|
+
|
|
3421
|
+
void rbs_parser_print(rbs_parser_t *parser) {
|
|
3422
|
+
printf(" current_token = %s (%d...%d)\n", rbs_token_type_str(parser->current_token.type), parser->current_token.range.start.char_pos, parser->current_token.range.end.char_pos);
|
|
3423
|
+
printf(" next_token = %s (%d...%d)\n", rbs_token_type_str(parser->next_token.type), parser->next_token.range.start.char_pos, parser->next_token.range.end.char_pos);
|
|
3424
|
+
printf(" next_token2 = %s (%d...%d)\n", rbs_token_type_str(parser->next_token2.type), parser->next_token2.range.start.char_pos, parser->next_token2.range.end.char_pos);
|
|
3425
|
+
printf(" next_token3 = %s (%d...%d)\n", rbs_token_type_str(parser->next_token3.type), parser->next_token3.range.start.char_pos, parser->next_token3.range.end.char_pos);
|
|
3426
|
+
}
|
|
3427
|
+
|
|
3428
|
+
void rbs_parser_advance(rbs_parser_t *parser) {
|
|
3429
|
+
parser->current_token = parser->next_token;
|
|
3430
|
+
parser->next_token = parser->next_token2;
|
|
3431
|
+
parser->next_token2 = parser->next_token3;
|
|
3432
|
+
|
|
3433
|
+
while (true) {
|
|
3434
|
+
if (parser->next_token3.type == pEOF) {
|
|
3435
|
+
break;
|
|
3436
|
+
}
|
|
3437
|
+
|
|
3438
|
+
parser->next_token3 = rbs_lexer_next_token(parser->lexer);
|
|
3439
|
+
|
|
3440
|
+
if (parser->next_token3.type == tCOMMENT) {
|
|
3441
|
+
// skip
|
|
3442
|
+
} else if (parser->next_token3.type == tLINECOMMENT) {
|
|
3443
|
+
insert_comment_line(parser, parser->next_token3);
|
|
3444
|
+
} else if (parser->next_token3.type == tTRIVIA) {
|
|
3445
|
+
//skip
|
|
3446
|
+
} else {
|
|
3447
|
+
break;
|
|
3448
|
+
}
|
|
3449
|
+
}
|
|
3450
|
+
}
|
|
3451
|
+
|
|
3452
|
+
void rbs_print_token(rbs_token_t tok) {
|
|
3453
|
+
printf(
|
|
3454
|
+
"%s char=%d...%d\n",
|
|
3455
|
+
rbs_token_type_str(tok.type),
|
|
3456
|
+
tok.range.start.char_pos,
|
|
3457
|
+
tok.range.end.char_pos
|
|
3458
|
+
);
|
|
3459
|
+
}
|
|
3460
|
+
|
|
3461
|
+
void rbs_print_lexer(rbs_lexer_t *lexer) {
|
|
3462
|
+
printf("Lexer: (range = %d...%d, encoding = %s\n", lexer->start_pos, lexer->end_pos, lexer->encoding->name);
|
|
3463
|
+
printf(" start = { char_pos = %d, byte_pos = %d }\n", lexer->start.char_pos, lexer->start.byte_pos);
|
|
3464
|
+
printf(" current = { char_pos = %d, byte_pos = %d }\n", lexer->current.char_pos, lexer->current.byte_pos);
|
|
3465
|
+
printf(" character = { code_point = %d (%c), bytes = %zu }\n", lexer->current_code_point, lexer->current_code_point < 256 ? lexer->current_code_point : '?', lexer->current_character_bytes);
|
|
3466
|
+
printf(" first_token_of_line = %s\n", lexer->first_token_of_line ? "true" : "false");
|
|
3467
|
+
}
|
|
3468
|
+
|
|
3469
|
+
rbs_ast_comment_t *rbs_parser_get_comment(rbs_parser_t *parser, int subject_line) {
|
|
3470
|
+
int comment_line = subject_line - 1;
|
|
3471
|
+
|
|
3472
|
+
rbs_comment_t *com = comment_get_comment(parser->last_comment, comment_line);
|
|
3473
|
+
|
|
3474
|
+
if (com) {
|
|
3475
|
+
return parse_comment_lines(parser, com);
|
|
3476
|
+
} else {
|
|
3477
|
+
return NULL;
|
|
3478
|
+
}
|
|
3479
|
+
}
|
|
3480
|
+
|
|
3481
|
+
rbs_lexer_t *rbs_lexer_new(rbs_allocator_t *allocator, rbs_string_t string, const rbs_encoding_t *encoding, int start_pos, int end_pos) {
|
|
3482
|
+
rbs_lexer_t *lexer = rbs_allocator_alloc(allocator, rbs_lexer_t);
|
|
3483
|
+
|
|
3484
|
+
rbs_position_t start_position = (rbs_position_t) {
|
|
3485
|
+
.byte_pos = 0,
|
|
3486
|
+
.char_pos = 0,
|
|
3487
|
+
.line = 1,
|
|
3488
|
+
.column = 0,
|
|
3489
|
+
};
|
|
3490
|
+
|
|
3491
|
+
*lexer = (rbs_lexer_t) {
|
|
3492
|
+
.string = string,
|
|
3493
|
+
.start_pos = start_pos,
|
|
3494
|
+
.end_pos = end_pos,
|
|
3495
|
+
.current = start_position,
|
|
3496
|
+
.start = { 0 },
|
|
3497
|
+
.first_token_of_line = true,
|
|
3498
|
+
.current_character_bytes = 0,
|
|
3499
|
+
.current_code_point = '\0',
|
|
3500
|
+
.encoding = encoding,
|
|
3501
|
+
};
|
|
3502
|
+
|
|
3503
|
+
unsigned int codepoint;
|
|
3504
|
+
size_t bytes;
|
|
3505
|
+
|
|
3506
|
+
if (rbs_next_char(lexer, &codepoint, &bytes)) {
|
|
3507
|
+
lexer->current_code_point = codepoint;
|
|
3508
|
+
lexer->current_character_bytes = bytes;
|
|
3509
|
+
} else {
|
|
3510
|
+
lexer->current_code_point = '\0';
|
|
3511
|
+
lexer->current_character_bytes = 1;
|
|
3512
|
+
}
|
|
3513
|
+
|
|
3514
|
+
if (start_pos > 0) {
|
|
3515
|
+
while (lexer->current.byte_pos < start_pos) {
|
|
3516
|
+
rbs_skip(lexer);
|
|
3517
|
+
}
|
|
3518
|
+
}
|
|
3519
|
+
|
|
3520
|
+
lexer->start = lexer->current;
|
|
3521
|
+
|
|
3522
|
+
return lexer;
|
|
3523
|
+
}
|
|
3524
|
+
|
|
3525
|
+
rbs_parser_t *rbs_parser_new(rbs_string_t string, const rbs_encoding_t *encoding, int start_pos, int end_pos) {
|
|
3526
|
+
rbs_allocator_t *allocator = rbs_allocator_init();
|
|
3527
|
+
|
|
3528
|
+
rbs_lexer_t *lexer = rbs_lexer_new(allocator, string, encoding, start_pos, end_pos);
|
|
3529
|
+
rbs_parser_t *parser = rbs_allocator_alloc(allocator, rbs_parser_t);
|
|
3530
|
+
|
|
3531
|
+
*parser = (rbs_parser_t) {
|
|
3532
|
+
.lexer = lexer,
|
|
3533
|
+
|
|
3534
|
+
.current_token = NullToken,
|
|
3535
|
+
.next_token = NullToken,
|
|
3536
|
+
.next_token2 = NullToken,
|
|
3537
|
+
.next_token3 = NullToken,
|
|
3538
|
+
|
|
3539
|
+
.vars = NULL,
|
|
3540
|
+
.last_comment = NULL,
|
|
3541
|
+
|
|
3542
|
+
.constant_pool = { 0 },
|
|
3543
|
+
.allocator = allocator,
|
|
3544
|
+
.error = NULL,
|
|
3545
|
+
};
|
|
3546
|
+
|
|
3547
|
+
// The parser's constant pool is mainly used for storing the names of type variables, which usually aren't many.
|
|
3548
|
+
// Below are some statistics gathered from the current test suite. We can see that 56% of parsers never add to their
|
|
3549
|
+
// constant pool at all. The initial capacity needs to be a power of 2. Picking 2 means that we won't need to realloc
|
|
3550
|
+
// in 85% of cases.
|
|
3551
|
+
//
|
|
3552
|
+
// TODO: recalculate these statistics based on a real world codebase, rather than the test suite.
|
|
3553
|
+
//
|
|
3554
|
+
// | Size | Count | Cumulative | % Coverage |
|
|
3555
|
+
// |------|-------|------------|------------|
|
|
3556
|
+
// | 0 | 7,862 | 7,862 | 56% |
|
|
3557
|
+
// | 1 | 3,196 | 11,058 | 79% |
|
|
3558
|
+
// | 2 | 778 | 12,719 | 85% |
|
|
3559
|
+
// | 3 | 883 | 11,941 | 91% |
|
|
3560
|
+
// | 4 | 478 | 13,197 | 95% |
|
|
3561
|
+
// | 5 | 316 | 13,513 | 97% |
|
|
3562
|
+
// | 6 | 288 | 13,801 | 99% |
|
|
3563
|
+
// | 7 | 144 | 13,945 | 100% |
|
|
3564
|
+
const size_t initial_pool_capacity = 2;
|
|
3565
|
+
rbs_constant_pool_init(&parser->constant_pool, initial_pool_capacity);
|
|
3566
|
+
|
|
3567
|
+
rbs_parser_advance(parser);
|
|
3568
|
+
rbs_parser_advance(parser);
|
|
3569
|
+
rbs_parser_advance(parser);
|
|
3570
|
+
|
|
3571
|
+
return parser;
|
|
3572
|
+
}
|
|
3573
|
+
|
|
3574
|
+
void rbs_parser_free(rbs_parser_t *parser) {
|
|
3575
|
+
rbs_constant_pool_free(&parser->constant_pool);
|
|
3576
|
+
rbs_allocator_free(ALLOCATOR());
|
|
3577
|
+
}
|
|
3578
|
+
|
|
3579
|
+
void rbs_parser_set_error(rbs_parser_t *parser, rbs_token_t tok, bool syntax_error, const char *fmt, ...) {
|
|
3580
|
+
if (parser->error) {
|
|
3581
|
+
return;
|
|
3582
|
+
}
|
|
3583
|
+
|
|
3584
|
+
va_list args;
|
|
3585
|
+
|
|
3586
|
+
va_start(args, fmt);
|
|
3587
|
+
int length = vsnprintf(NULL, 0, fmt, args);
|
|
3588
|
+
va_end(args);
|
|
3589
|
+
|
|
3590
|
+
char *message = rbs_allocator_alloc_many(ALLOCATOR(), length + 1, char);
|
|
3591
|
+
|
|
3592
|
+
va_start(args, fmt);
|
|
3593
|
+
vsnprintf(message, length + 1, fmt, args);
|
|
3594
|
+
va_end(args);
|
|
3595
|
+
|
|
3596
|
+
parser->error = rbs_allocator_alloc(ALLOCATOR(), rbs_error_t);
|
|
3597
|
+
parser->error->token = tok;
|
|
3598
|
+
parser->error->message = message;
|
|
3599
|
+
parser->error->syntax_error = syntax_error;
|
|
3600
|
+
}
|
|
3601
|
+
|
|
3602
|
+
/*
|
|
3603
|
+
parse_method_overload ::= {} annotations <method_type>
|
|
3604
|
+
*/
|
|
3605
|
+
NODISCARD
|
|
3606
|
+
static bool parse_method_overload(rbs_parser_t *parser, rbs_node_list_t *annotations, rbs_method_type_t **method_type) {
|
|
3607
|
+
rbs_position_t pos = NullPosition;
|
|
3608
|
+
|
|
3609
|
+
if (!parse_annotations(parser, annotations, &pos)) {
|
|
3610
|
+
return false;
|
|
3611
|
+
}
|
|
3612
|
+
|
|
3613
|
+
return rbs_parse_method_type(parser, method_type, false, true);
|
|
3614
|
+
}
|
|
3615
|
+
|
|
3616
|
+
/*
|
|
3617
|
+
inline_method_overloads ::= {} <overload> -- returns true
|
|
3618
|
+
| {} overload `|` ... `|` overload -- returns true
|
|
3619
|
+
| {} overload `|` ... `|` `...` -- returns true (dot3_location is set)
|
|
3620
|
+
| {<>} -- returns false
|
|
3621
|
+
*/
|
|
3622
|
+
NODISCARD
|
|
3623
|
+
static bool parse_inline_method_overloads(rbs_parser_t *parser, rbs_node_list_t *overloads, rbs_location_range_list_t *bar_locations, rbs_location_range *dot3_location) {
|
|
3624
|
+
while (true) {
|
|
3625
|
+
rbs_node_list_t *annotations = rbs_node_list_new(ALLOCATOR());
|
|
3626
|
+
rbs_method_type_t *method_type = NULL;
|
|
3627
|
+
|
|
3628
|
+
if (!parse_method_overload(parser, annotations, &method_type)) {
|
|
3629
|
+
return false;
|
|
3630
|
+
}
|
|
3631
|
+
|
|
3632
|
+
rbs_location_range location = rbs_location_range_current_token(parser);
|
|
3633
|
+
rbs_ast_members_method_definition_overload_t *overload = rbs_ast_members_method_definition_overload_new(
|
|
3634
|
+
ALLOCATOR(),
|
|
3635
|
+
location,
|
|
3636
|
+
annotations,
|
|
3637
|
+
(rbs_node_t *) method_type
|
|
3638
|
+
);
|
|
3639
|
+
rbs_node_list_append(overloads, (rbs_node_t *) overload);
|
|
3640
|
+
|
|
3641
|
+
if (parser->next_token.type == pBAR) {
|
|
3642
|
+
rbs_location_range bar_range = RBS_RANGE_LEX2AST(parser->next_token.range);
|
|
3643
|
+
|
|
3644
|
+
rbs_parser_advance(parser);
|
|
3645
|
+
|
|
3646
|
+
rbs_location_range_list_append(bar_locations, bar_range);
|
|
3647
|
+
|
|
3648
|
+
if (parser->next_token.type == pDOT3) {
|
|
3649
|
+
*dot3_location = RBS_RANGE_LEX2AST(parser->next_token.range);
|
|
3650
|
+
rbs_parser_advance(parser);
|
|
3651
|
+
return true;
|
|
3652
|
+
}
|
|
3653
|
+
|
|
3654
|
+
continue;
|
|
3655
|
+
}
|
|
3656
|
+
|
|
3657
|
+
return true;
|
|
3658
|
+
}
|
|
3659
|
+
}
|
|
3660
|
+
|
|
3661
|
+
NODISCARD
|
|
3662
|
+
static bool parse_inline_comment(rbs_parser_t *parser, rbs_location_range *comment_range) {
|
|
3663
|
+
if (parser->next_token.type != tINLINECOMMENT) {
|
|
3664
|
+
*comment_range = RBS_LOCATION_NULL_RANGE;
|
|
3665
|
+
return true;
|
|
3666
|
+
}
|
|
3667
|
+
|
|
3668
|
+
*comment_range = RBS_RANGE_LEX2AST(parser->next_token.range);
|
|
3669
|
+
rbs_parser_advance(parser);
|
|
3670
|
+
|
|
3671
|
+
return true;
|
|
3672
|
+
}
|
|
3673
|
+
|
|
3674
|
+
NODISCARD
|
|
3675
|
+
static bool parse_inline_param_type_annotation(rbs_parser_t *parser, rbs_ast_ruby_annotations_t **annotation, rbs_range_t rbs_range) {
|
|
3676
|
+
rbs_parser_advance(parser);
|
|
3677
|
+
|
|
3678
|
+
rbs_location_range name_loc = rbs_location_range_current_token(parser);
|
|
3679
|
+
|
|
3680
|
+
ADVANCE_ASSERT(parser, pCOLON);
|
|
3681
|
+
|
|
3682
|
+
rbs_location_range colon_loc = rbs_location_range_current_token(parser);
|
|
3683
|
+
|
|
3684
|
+
rbs_node_t *param_type = NULL;
|
|
3685
|
+
if (!rbs_parse_type(parser, ¶m_type, false, true, true)) {
|
|
3686
|
+
return false;
|
|
3687
|
+
}
|
|
3688
|
+
|
|
3689
|
+
rbs_location_range comment_loc = RBS_LOCATION_NULL_RANGE;
|
|
3690
|
+
if (!parse_inline_comment(parser, &comment_loc)) {
|
|
3691
|
+
return false;
|
|
3692
|
+
}
|
|
3693
|
+
|
|
3694
|
+
rbs_location_range full_loc = {
|
|
3695
|
+
.start_char = rbs_range.start.char_pos,
|
|
3696
|
+
.start_byte = rbs_range.start.byte_pos,
|
|
3697
|
+
.end_char = parser->current_token.range.end.char_pos,
|
|
3698
|
+
.end_byte = parser->current_token.range.end.byte_pos,
|
|
3699
|
+
};
|
|
3700
|
+
|
|
3701
|
+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_param_type_annotation_new(
|
|
3702
|
+
ALLOCATOR(),
|
|
3703
|
+
full_loc,
|
|
3704
|
+
RBS_RANGE_LEX2AST(rbs_range),
|
|
3705
|
+
name_loc,
|
|
3706
|
+
colon_loc,
|
|
3707
|
+
param_type,
|
|
3708
|
+
comment_loc
|
|
3709
|
+
);
|
|
3710
|
+
|
|
3711
|
+
return true;
|
|
3712
|
+
}
|
|
3713
|
+
|
|
3714
|
+
NODISCARD
|
|
3715
|
+
static bool parse_inline_leading_annotation(rbs_parser_t *parser, rbs_ast_ruby_annotations_t **annotation) {
|
|
3716
|
+
switch (parser->next_token.type) {
|
|
3717
|
+
case pCOLON: {
|
|
3718
|
+
rbs_range_t colon_range = parser->next_token.range;
|
|
3719
|
+
rbs_parser_advance(parser);
|
|
3720
|
+
|
|
3721
|
+
rbs_node_list_t *annotations = rbs_node_list_new(ALLOCATOR());
|
|
3722
|
+
rbs_method_type_t *method_type = NULL;
|
|
3723
|
+
|
|
3724
|
+
if (!parse_method_overload(parser, annotations, &method_type)) {
|
|
3725
|
+
return false;
|
|
3726
|
+
}
|
|
3727
|
+
|
|
3728
|
+
rbs_range_t full_range = {
|
|
3729
|
+
.start = colon_range.start,
|
|
3730
|
+
.end = parser->current_token.range.end
|
|
3731
|
+
};
|
|
3732
|
+
|
|
3733
|
+
rbs_location_range full_loc = RBS_RANGE_LEX2AST(full_range);
|
|
3734
|
+
|
|
3735
|
+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_colon_method_type_annotation_new(
|
|
3736
|
+
ALLOCATOR(),
|
|
3737
|
+
full_loc,
|
|
3738
|
+
RBS_RANGE_LEX2AST(colon_range),
|
|
3739
|
+
annotations,
|
|
3740
|
+
(rbs_node_t *) method_type
|
|
3741
|
+
);
|
|
3742
|
+
return true;
|
|
3743
|
+
}
|
|
3744
|
+
case kATRBS: {
|
|
3745
|
+
rbs_range_t rbs_range = parser->next_token.range;
|
|
3746
|
+
rbs_parser_advance(parser);
|
|
3747
|
+
|
|
3748
|
+
switch (parser->next_token.type) {
|
|
3749
|
+
case pDOT3: {
|
|
3750
|
+
rbs_location_range dot3_range = RBS_RANGE_LEX2AST(parser->next_token.range);
|
|
3751
|
+
rbs_parser_advance(parser);
|
|
3752
|
+
|
|
3753
|
+
rbs_node_list_t *overloads = rbs_node_list_new(ALLOCATOR());
|
|
3754
|
+
rbs_location_range_list_t *bar_locations = rbs_location_range_list_new(ALLOCATOR());
|
|
3755
|
+
|
|
3756
|
+
rbs_range_t full_range = {
|
|
3757
|
+
.start = rbs_range.start,
|
|
3758
|
+
.end = parser->current_token.range.end
|
|
3759
|
+
};
|
|
3760
|
+
|
|
3761
|
+
rbs_location_range full_loc = RBS_RANGE_LEX2AST(full_range);
|
|
3762
|
+
|
|
3763
|
+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_method_types_annotation_new(
|
|
3764
|
+
ALLOCATOR(),
|
|
3765
|
+
full_loc,
|
|
3766
|
+
RBS_RANGE_LEX2AST(rbs_range),
|
|
3767
|
+
overloads,
|
|
3768
|
+
bar_locations,
|
|
3769
|
+
dot3_range
|
|
3770
|
+
);
|
|
3771
|
+
return true;
|
|
3772
|
+
}
|
|
3773
|
+
case pLPAREN:
|
|
3774
|
+
case pLBRACKET:
|
|
3775
|
+
case pLBRACE:
|
|
3776
|
+
case tANNOTATION: {
|
|
3777
|
+
rbs_node_list_t *overloads = rbs_node_list_new(ALLOCATOR());
|
|
3778
|
+
rbs_location_range_list_t *bar_locations = rbs_location_range_list_new(ALLOCATOR());
|
|
3779
|
+
rbs_location_range dot3_location = RBS_LOCATION_NULL_RANGE;
|
|
3780
|
+
|
|
3781
|
+
if (!parse_inline_method_overloads(parser, overloads, bar_locations, &dot3_location)) {
|
|
3782
|
+
return false;
|
|
3783
|
+
}
|
|
3784
|
+
|
|
3785
|
+
rbs_range_t full_range = {
|
|
3786
|
+
.start = rbs_range.start,
|
|
3787
|
+
.end = parser->current_token.range.end
|
|
3788
|
+
};
|
|
3789
|
+
|
|
3790
|
+
rbs_location_range full_loc = RBS_RANGE_LEX2AST(full_range);
|
|
3791
|
+
|
|
3792
|
+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_method_types_annotation_new(
|
|
3793
|
+
ALLOCATOR(),
|
|
3794
|
+
full_loc,
|
|
3795
|
+
RBS_RANGE_LEX2AST(rbs_range),
|
|
3796
|
+
overloads,
|
|
3797
|
+
bar_locations,
|
|
3798
|
+
dot3_location
|
|
3799
|
+
);
|
|
3800
|
+
return true;
|
|
3801
|
+
}
|
|
3802
|
+
case kSKIP: {
|
|
3803
|
+
if (parser->next_token2.type == pCOLON) {
|
|
3804
|
+
return parse_inline_param_type_annotation(parser, annotation, rbs_range);
|
|
3805
|
+
} else {
|
|
3806
|
+
rbs_parser_advance(parser);
|
|
3807
|
+
|
|
3808
|
+
rbs_range_t skip_range = parser->current_token.range;
|
|
3809
|
+
|
|
3810
|
+
rbs_location_range comment_loc = RBS_LOCATION_NULL_RANGE;
|
|
3811
|
+
if (!parse_inline_comment(parser, &comment_loc)) {
|
|
3812
|
+
return false;
|
|
3813
|
+
}
|
|
3814
|
+
|
|
3815
|
+
rbs_range_t full_range = {
|
|
3816
|
+
.start = rbs_range.start,
|
|
3817
|
+
.end = parser->current_token.range.end
|
|
3818
|
+
};
|
|
3819
|
+
|
|
3820
|
+
rbs_location_range full_loc = RBS_RANGE_LEX2AST(full_range);
|
|
3821
|
+
|
|
3822
|
+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_skip_annotation_new(
|
|
3823
|
+
ALLOCATOR(),
|
|
3824
|
+
full_loc,
|
|
3825
|
+
RBS_RANGE_LEX2AST(rbs_range),
|
|
3826
|
+
RBS_RANGE_LEX2AST(skip_range),
|
|
3827
|
+
comment_loc
|
|
3828
|
+
);
|
|
3829
|
+
return true;
|
|
3830
|
+
}
|
|
3831
|
+
}
|
|
3832
|
+
case kRETURN: {
|
|
3833
|
+
rbs_parser_advance(parser);
|
|
3834
|
+
|
|
3835
|
+
rbs_range_t return_range = parser->current_token.range;
|
|
3836
|
+
|
|
3837
|
+
ADVANCE_ASSERT(parser, pCOLON);
|
|
3838
|
+
|
|
3839
|
+
rbs_range_t colon_range = parser->current_token.range;
|
|
3840
|
+
|
|
3841
|
+
rbs_node_t *return_type = NULL;
|
|
3842
|
+
if (!rbs_parse_type(parser, &return_type, true, true, true)) {
|
|
3843
|
+
return false;
|
|
3844
|
+
}
|
|
3845
|
+
|
|
3846
|
+
rbs_location_range comment_loc = RBS_LOCATION_NULL_RANGE;
|
|
3847
|
+
if (!parse_inline_comment(parser, &comment_loc)) {
|
|
3848
|
+
return false;
|
|
3849
|
+
}
|
|
3850
|
+
|
|
3851
|
+
rbs_range_t full_range = {
|
|
3852
|
+
.start = rbs_range.start,
|
|
3853
|
+
.end = parser->current_token.range.end
|
|
3854
|
+
};
|
|
3855
|
+
|
|
3856
|
+
rbs_location_range full_loc = RBS_RANGE_LEX2AST(full_range);
|
|
3857
|
+
|
|
3858
|
+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_return_type_annotation_new(
|
|
3859
|
+
ALLOCATOR(),
|
|
3860
|
+
full_loc,
|
|
3861
|
+
RBS_RANGE_LEX2AST(rbs_range),
|
|
3862
|
+
RBS_RANGE_LEX2AST(return_range),
|
|
3863
|
+
RBS_RANGE_LEX2AST(colon_range),
|
|
3864
|
+
return_type,
|
|
3865
|
+
comment_loc
|
|
3866
|
+
);
|
|
3867
|
+
return true;
|
|
3868
|
+
}
|
|
3869
|
+
case tAIDENT: {
|
|
3870
|
+
// Parse instance variable annotation: @rbs @name: Type
|
|
3871
|
+
rbs_parser_advance(parser);
|
|
3872
|
+
|
|
3873
|
+
rbs_range_t ivar_name_range = parser->current_token.range;
|
|
3874
|
+
rbs_location_range ivar_name_loc = RBS_RANGE_LEX2AST(ivar_name_range);
|
|
3875
|
+
|
|
3876
|
+
// Extract the instance variable name as a symbol
|
|
3877
|
+
rbs_string_t ivar_string = rbs_parser_peek_current_token(parser);
|
|
3878
|
+
rbs_constant_id_t ivar_id = rbs_constant_pool_insert_string(&parser->constant_pool, ivar_string);
|
|
3879
|
+
rbs_ast_symbol_t *ivar_name = rbs_ast_symbol_new(ALLOCATOR(), ivar_name_loc, &parser->constant_pool, ivar_id);
|
|
3880
|
+
|
|
3881
|
+
ADVANCE_ASSERT(parser, pCOLON);
|
|
3882
|
+
|
|
3883
|
+
rbs_range_t colon_range = parser->current_token.range;
|
|
3884
|
+
|
|
3885
|
+
rbs_node_t *type = NULL;
|
|
3886
|
+
if (!rbs_parse_type(parser, &type, false, true, true)) {
|
|
3887
|
+
return false;
|
|
3888
|
+
}
|
|
3889
|
+
|
|
3890
|
+
rbs_location_range comment_loc = RBS_LOCATION_NULL_RANGE;
|
|
3891
|
+
if (!parse_inline_comment(parser, &comment_loc)) {
|
|
3892
|
+
return false;
|
|
3893
|
+
}
|
|
3894
|
+
|
|
3895
|
+
rbs_range_t full_range = {
|
|
3896
|
+
.start = rbs_range.start,
|
|
3897
|
+
.end = parser->current_token.range.end
|
|
3898
|
+
};
|
|
3899
|
+
|
|
3900
|
+
rbs_location_range full_loc = RBS_RANGE_LEX2AST(full_range);
|
|
3901
|
+
|
|
3902
|
+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_instance_variable_annotation_new(
|
|
3903
|
+
ALLOCATOR(),
|
|
3904
|
+
full_loc,
|
|
3905
|
+
RBS_RANGE_LEX2AST(rbs_range),
|
|
3906
|
+
ivar_name,
|
|
3907
|
+
RBS_RANGE_LEX2AST(ivar_name_range),
|
|
3908
|
+
RBS_RANGE_LEX2AST(colon_range),
|
|
3909
|
+
type,
|
|
3910
|
+
comment_loc
|
|
3911
|
+
);
|
|
3912
|
+
return true;
|
|
3913
|
+
}
|
|
3914
|
+
case tLIDENT:
|
|
3915
|
+
PARAM_NAME_CASES {
|
|
3916
|
+
return parse_inline_param_type_annotation(parser, annotation, rbs_range);
|
|
3917
|
+
}
|
|
3918
|
+
case pSTAR: {
|
|
3919
|
+
rbs_parser_advance(parser);
|
|
3920
|
+
rbs_location_range star_loc = rbs_location_range_current_token(parser);
|
|
3921
|
+
|
|
3922
|
+
rbs_location_range name_loc = RBS_LOCATION_NULL_RANGE;
|
|
3923
|
+
if (parser->next_token.type == tLIDENT) {
|
|
3924
|
+
rbs_parser_advance(parser);
|
|
3925
|
+
name_loc = rbs_location_range_current_token(parser);
|
|
3926
|
+
}
|
|
3927
|
+
|
|
3928
|
+
ADVANCE_ASSERT(parser, pCOLON);
|
|
3929
|
+
rbs_location_range colon_loc = rbs_location_range_current_token(parser);
|
|
3930
|
+
|
|
3931
|
+
rbs_node_t *param_type = NULL;
|
|
3932
|
+
if (!rbs_parse_type(parser, ¶m_type, false, true, true)) {
|
|
3933
|
+
return false;
|
|
3934
|
+
}
|
|
3935
|
+
|
|
3936
|
+
rbs_location_range comment_loc = RBS_LOCATION_NULL_RANGE;
|
|
3937
|
+
if (!parse_inline_comment(parser, &comment_loc)) {
|
|
3938
|
+
return false;
|
|
3939
|
+
}
|
|
3940
|
+
|
|
3941
|
+
rbs_range_t full_range = {
|
|
3942
|
+
.start = rbs_range.start,
|
|
3943
|
+
.end = parser->current_token.range.end
|
|
3944
|
+
};
|
|
3945
|
+
|
|
3946
|
+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_splat_param_type_annotation_new(
|
|
3947
|
+
ALLOCATOR(),
|
|
3948
|
+
RBS_RANGE_LEX2AST(full_range),
|
|
3949
|
+
RBS_RANGE_LEX2AST(rbs_range),
|
|
3950
|
+
star_loc,
|
|
3951
|
+
name_loc,
|
|
3952
|
+
colon_loc,
|
|
3953
|
+
param_type,
|
|
3954
|
+
comment_loc
|
|
3955
|
+
);
|
|
3956
|
+
return true;
|
|
3957
|
+
}
|
|
3958
|
+
case pSTAR2: {
|
|
3959
|
+
rbs_parser_advance(parser);
|
|
3960
|
+
rbs_location_range star2_loc = rbs_location_range_current_token(parser);
|
|
3961
|
+
|
|
3962
|
+
rbs_location_range name_loc = RBS_LOCATION_NULL_RANGE;
|
|
3963
|
+
if (parser->next_token.type == tLIDENT) {
|
|
3964
|
+
rbs_parser_advance(parser);
|
|
3965
|
+
name_loc = rbs_location_range_current_token(parser);
|
|
3966
|
+
}
|
|
3967
|
+
|
|
3968
|
+
ADVANCE_ASSERT(parser, pCOLON);
|
|
3969
|
+
rbs_location_range colon_loc = rbs_location_range_current_token(parser);
|
|
3970
|
+
|
|
3971
|
+
rbs_node_t *param_type = NULL;
|
|
3972
|
+
if (!rbs_parse_type(parser, ¶m_type, false, true, true)) {
|
|
3973
|
+
return false;
|
|
3974
|
+
}
|
|
3975
|
+
|
|
3976
|
+
rbs_location_range comment_loc = RBS_LOCATION_NULL_RANGE;
|
|
3977
|
+
if (!parse_inline_comment(parser, &comment_loc)) {
|
|
3978
|
+
return false;
|
|
3979
|
+
}
|
|
3980
|
+
|
|
3981
|
+
rbs_range_t full_range = {
|
|
3982
|
+
.start = rbs_range.start,
|
|
3983
|
+
.end = parser->current_token.range.end
|
|
3984
|
+
};
|
|
3985
|
+
|
|
3986
|
+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_double_splat_param_type_annotation_new(
|
|
3987
|
+
ALLOCATOR(),
|
|
3988
|
+
RBS_RANGE_LEX2AST(full_range),
|
|
3989
|
+
RBS_RANGE_LEX2AST(rbs_range),
|
|
3990
|
+
star2_loc,
|
|
3991
|
+
name_loc,
|
|
3992
|
+
colon_loc,
|
|
3993
|
+
param_type,
|
|
3994
|
+
comment_loc
|
|
3995
|
+
);
|
|
3996
|
+
return true;
|
|
3997
|
+
}
|
|
3998
|
+
case pAMP: {
|
|
3999
|
+
rbs_parser_advance(parser);
|
|
4000
|
+
rbs_location_range ampersand_loc = rbs_location_range_current_token(parser);
|
|
4001
|
+
|
|
4002
|
+
rbs_location_range name_loc = RBS_LOCATION_NULL_RANGE;
|
|
4003
|
+
if (parser->next_token.type == tLIDENT) {
|
|
4004
|
+
rbs_parser_advance(parser);
|
|
4005
|
+
name_loc = rbs_location_range_current_token(parser);
|
|
4006
|
+
}
|
|
4007
|
+
|
|
4008
|
+
ADVANCE_ASSERT(parser, pCOLON);
|
|
4009
|
+
rbs_location_range colon_loc = rbs_location_range_current_token(parser);
|
|
4010
|
+
|
|
4011
|
+
rbs_location_range question_loc = RBS_LOCATION_NULL_RANGE;
|
|
4012
|
+
if (parser->next_token.type == pQUESTION) {
|
|
4013
|
+
rbs_parser_advance(parser);
|
|
4014
|
+
question_loc = rbs_location_range_current_token(parser);
|
|
4015
|
+
}
|
|
4016
|
+
|
|
4017
|
+
rbs_range_t type_range;
|
|
4018
|
+
type_range.start = parser->next_token.range.start;
|
|
4019
|
+
|
|
4020
|
+
parse_function_result *result = rbs_allocator_alloc(ALLOCATOR(), parse_function_result);
|
|
4021
|
+
if (!parse_function(parser, true, false, &result, true, true)) {
|
|
4022
|
+
return false;
|
|
4023
|
+
}
|
|
4024
|
+
|
|
4025
|
+
type_range.end = parser->current_token.range.end;
|
|
4026
|
+
|
|
4027
|
+
rbs_location_range comment_loc = RBS_LOCATION_NULL_RANGE;
|
|
4028
|
+
if (!parse_inline_comment(parser, &comment_loc)) {
|
|
4029
|
+
return false;
|
|
4030
|
+
}
|
|
4031
|
+
|
|
4032
|
+
rbs_range_t full_range = {
|
|
4033
|
+
.start = rbs_range.start,
|
|
4034
|
+
.end = parser->current_token.range.end
|
|
4035
|
+
};
|
|
4036
|
+
|
|
4037
|
+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_block_param_type_annotation_new(
|
|
4038
|
+
ALLOCATOR(),
|
|
4039
|
+
RBS_RANGE_LEX2AST(full_range),
|
|
4040
|
+
RBS_RANGE_LEX2AST(rbs_range),
|
|
4041
|
+
ampersand_loc,
|
|
4042
|
+
name_loc,
|
|
4043
|
+
colon_loc,
|
|
4044
|
+
question_loc,
|
|
4045
|
+
RBS_RANGE_LEX2AST(type_range),
|
|
4046
|
+
result->function,
|
|
4047
|
+
comment_loc
|
|
4048
|
+
);
|
|
4049
|
+
return true;
|
|
4050
|
+
}
|
|
4051
|
+
case kMODULESELF: {
|
|
4052
|
+
rbs_parser_advance(parser);
|
|
4053
|
+
rbs_range_t keyword_range = parser->current_token.range;
|
|
4054
|
+
|
|
4055
|
+
ADVANCE_ASSERT(parser, pCOLON);
|
|
4056
|
+
rbs_range_t colon_range = parser->current_token.range;
|
|
4057
|
+
|
|
4058
|
+
rbs_parser_advance(parser);
|
|
4059
|
+
|
|
4060
|
+
rbs_range_t name_range;
|
|
4061
|
+
rbs_type_name_t *type_name = NULL;
|
|
4062
|
+
if (!parse_type_name(parser, (TypeNameKind) (CLASS_NAME | INTERFACE_NAME), &name_range, &type_name)) {
|
|
4063
|
+
return false;
|
|
4064
|
+
}
|
|
4065
|
+
|
|
4066
|
+
rbs_node_list_t *args = rbs_node_list_new(ALLOCATOR());
|
|
4067
|
+
rbs_location_range open_bracket_loc = RBS_LOCATION_NULL_RANGE;
|
|
4068
|
+
rbs_location_range close_bracket_loc = RBS_LOCATION_NULL_RANGE;
|
|
4069
|
+
rbs_location_range_list_t *args_comma_locations = rbs_location_range_list_new(ALLOCATOR());
|
|
4070
|
+
if (parser->next_token.type == pLBRACKET) {
|
|
4071
|
+
rbs_parser_advance(parser);
|
|
4072
|
+
open_bracket_loc = RBS_RANGE_LEX2AST(parser->current_token.range);
|
|
4073
|
+
CHECK_PARSE(parse_type_list_with_commas(parser, pRBRACKET, args, args_comma_locations, true, false, false));
|
|
4074
|
+
rbs_parser_advance(parser);
|
|
4075
|
+
close_bracket_loc = RBS_RANGE_LEX2AST(parser->current_token.range);
|
|
4076
|
+
}
|
|
4077
|
+
|
|
4078
|
+
rbs_location_range comment_loc = RBS_LOCATION_NULL_RANGE;
|
|
4079
|
+
if (!parse_inline_comment(parser, &comment_loc)) {
|
|
4080
|
+
return false;
|
|
4081
|
+
}
|
|
4082
|
+
|
|
4083
|
+
rbs_range_t full_range = {
|
|
4084
|
+
.start = rbs_range.start,
|
|
4085
|
+
.end = parser->current_token.range.end
|
|
4086
|
+
};
|
|
4087
|
+
|
|
4088
|
+
rbs_location_range full_loc = RBS_RANGE_LEX2AST(full_range);
|
|
4089
|
+
|
|
4090
|
+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_module_self_annotation_new(
|
|
4091
|
+
ALLOCATOR(),
|
|
4092
|
+
full_loc,
|
|
4093
|
+
RBS_RANGE_LEX2AST(rbs_range),
|
|
4094
|
+
RBS_RANGE_LEX2AST(keyword_range),
|
|
4095
|
+
RBS_RANGE_LEX2AST(colon_range),
|
|
4096
|
+
type_name,
|
|
4097
|
+
args,
|
|
4098
|
+
open_bracket_loc,
|
|
4099
|
+
close_bracket_loc,
|
|
4100
|
+
args_comma_locations,
|
|
4101
|
+
comment_loc
|
|
4102
|
+
);
|
|
4103
|
+
return true;
|
|
4104
|
+
}
|
|
4105
|
+
default: {
|
|
4106
|
+
rbs_parser_set_error(parser, parser->next_token, true, "unexpected token for @rbs annotation");
|
|
4107
|
+
return false;
|
|
4108
|
+
}
|
|
4109
|
+
}
|
|
4110
|
+
}
|
|
4111
|
+
default: {
|
|
4112
|
+
rbs_parser_set_error(parser, parser->next_token, true, "unexpected token for inline leading annotation");
|
|
4113
|
+
return false;
|
|
4114
|
+
}
|
|
4115
|
+
}
|
|
4116
|
+
}
|
|
4117
|
+
|
|
4118
|
+
NODISCARD
|
|
4119
|
+
static bool parse_inline_trailing_annotation(rbs_parser_t *parser, rbs_ast_ruby_annotations_t **annotation) {
|
|
4120
|
+
rbs_range_t prefix_range = parser->next_token.range;
|
|
4121
|
+
|
|
4122
|
+
switch (parser->next_token.type) {
|
|
4123
|
+
case pCOLON: {
|
|
4124
|
+
rbs_parser_advance(parser);
|
|
4125
|
+
|
|
4126
|
+
// Check for class-alias or module-alias keywords
|
|
4127
|
+
if (parser->next_token.type == kCLASSALIAS || parser->next_token.type == kMODULEALIAS) {
|
|
4128
|
+
bool is_class_alias = (parser->next_token.type == kCLASSALIAS);
|
|
4129
|
+
rbs_range_t keyword_range = parser->next_token.range;
|
|
4130
|
+
rbs_parser_advance(parser);
|
|
4131
|
+
|
|
4132
|
+
rbs_type_name_t *type_name = NULL;
|
|
4133
|
+
rbs_location_range type_name_loc = RBS_LOCATION_NULL_RANGE;
|
|
4134
|
+
rbs_range_t full_range;
|
|
4135
|
+
|
|
4136
|
+
// Check if a type name is provided
|
|
4137
|
+
if (parser->next_token.type == tUIDENT || parser->next_token.type == pCOLON2) {
|
|
4138
|
+
rbs_parser_advance(parser);
|
|
4139
|
+
|
|
4140
|
+
rbs_range_t type_name_range;
|
|
4141
|
+
if (!parse_type_name(parser, CLASS_NAME, &type_name_range, &type_name)) {
|
|
4142
|
+
return false;
|
|
4143
|
+
}
|
|
4144
|
+
// parse_type_name leaves current_token at the last identifier, don't advance
|
|
4145
|
+
type_name_loc = RBS_RANGE_LEX2AST(type_name_range);
|
|
4146
|
+
full_range.start = prefix_range.start;
|
|
4147
|
+
full_range.end = type_name_range.end;
|
|
4148
|
+
} else {
|
|
4149
|
+
// No type name provided - will be inferred
|
|
4150
|
+
full_range.start = prefix_range.start;
|
|
4151
|
+
full_range.end = keyword_range.end;
|
|
4152
|
+
}
|
|
4153
|
+
|
|
4154
|
+
rbs_location_range full_loc = RBS_RANGE_LEX2AST(full_range);
|
|
4155
|
+
|
|
4156
|
+
if (is_class_alias) {
|
|
4157
|
+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_class_alias_annotation_new(
|
|
4158
|
+
ALLOCATOR(),
|
|
4159
|
+
full_loc,
|
|
4160
|
+
RBS_RANGE_LEX2AST(prefix_range),
|
|
4161
|
+
RBS_RANGE_LEX2AST(keyword_range),
|
|
4162
|
+
type_name,
|
|
4163
|
+
type_name_loc
|
|
4164
|
+
);
|
|
4165
|
+
} else {
|
|
4166
|
+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_module_alias_annotation_new(
|
|
4167
|
+
ALLOCATOR(),
|
|
4168
|
+
full_loc,
|
|
4169
|
+
RBS_RANGE_LEX2AST(prefix_range),
|
|
4170
|
+
RBS_RANGE_LEX2AST(keyword_range),
|
|
4171
|
+
type_name,
|
|
4172
|
+
type_name_loc
|
|
4173
|
+
);
|
|
4174
|
+
}
|
|
4175
|
+
return true;
|
|
4176
|
+
}
|
|
4177
|
+
|
|
4178
|
+
// Otherwise, parse as regular type assertion
|
|
4179
|
+
rbs_node_t *type = NULL;
|
|
4180
|
+
if (!rbs_parse_type(parser, &type, true, true, true)) {
|
|
4181
|
+
return false;
|
|
4182
|
+
}
|
|
4183
|
+
|
|
4184
|
+
rbs_range_t full_range = {
|
|
4185
|
+
.start = prefix_range.start,
|
|
4186
|
+
.end = parser->current_token.range.end
|
|
4187
|
+
};
|
|
4188
|
+
|
|
4189
|
+
rbs_location_range full_loc = RBS_RANGE_LEX2AST(full_range);
|
|
4190
|
+
|
|
4191
|
+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_node_type_assertion_new(
|
|
4192
|
+
ALLOCATOR(),
|
|
4193
|
+
full_loc,
|
|
4194
|
+
RBS_RANGE_LEX2AST(prefix_range),
|
|
4195
|
+
type
|
|
4196
|
+
);
|
|
4197
|
+
return true;
|
|
4198
|
+
}
|
|
4199
|
+
case pLBRACKET: {
|
|
4200
|
+
rbs_parser_advance(parser);
|
|
4201
|
+
|
|
4202
|
+
rbs_node_list_t *type_args = rbs_node_list_new(ALLOCATOR());
|
|
4203
|
+
rbs_location_range_list_t *comma_locations = rbs_location_range_list_new(ALLOCATOR());
|
|
4204
|
+
|
|
4205
|
+
// Check for empty type args
|
|
4206
|
+
if (parser->next_token.type == pRBRACKET) {
|
|
4207
|
+
rbs_parser_set_error(parser, parser->next_token, true, "type application cannot be empty");
|
|
4208
|
+
return false;
|
|
4209
|
+
}
|
|
4210
|
+
|
|
4211
|
+
// Parse type list with comma tracking
|
|
4212
|
+
CHECK_PARSE(parse_type_list_with_commas(parser, pRBRACKET, type_args, comma_locations, true, true, false));
|
|
4213
|
+
|
|
4214
|
+
rbs_range_t close_bracket_range = parser->next_token.range;
|
|
4215
|
+
rbs_parser_advance(parser); // consume ]
|
|
4216
|
+
|
|
4217
|
+
rbs_range_t full_range = {
|
|
4218
|
+
.start = prefix_range.start,
|
|
4219
|
+
.end = close_bracket_range.end
|
|
4220
|
+
};
|
|
4221
|
+
|
|
4222
|
+
rbs_location_range full_loc = RBS_RANGE_LEX2AST(full_range);
|
|
4223
|
+
|
|
4224
|
+
*annotation = (rbs_ast_ruby_annotations_t *) rbs_ast_ruby_annotations_type_application_annotation_new(
|
|
4225
|
+
ALLOCATOR(),
|
|
4226
|
+
full_loc,
|
|
4227
|
+
RBS_RANGE_LEX2AST(prefix_range),
|
|
4228
|
+
type_args,
|
|
4229
|
+
RBS_RANGE_LEX2AST(close_bracket_range),
|
|
4230
|
+
comma_locations
|
|
4231
|
+
);
|
|
4232
|
+
return true;
|
|
4233
|
+
}
|
|
4234
|
+
default: {
|
|
4235
|
+
rbs_parser_set_error(parser, parser->next_token, true, "unexpected token for inline trailing annotation");
|
|
4236
|
+
return false;
|
|
4237
|
+
}
|
|
4238
|
+
}
|
|
4239
|
+
}
|
|
4240
|
+
|
|
4241
|
+
bool rbs_parse_inline_leading_annotation(rbs_parser_t *parser, rbs_ast_ruby_annotations_t **annotation) {
|
|
4242
|
+
bool success = parse_inline_leading_annotation(parser, annotation);
|
|
4243
|
+
|
|
4244
|
+
ADVANCE_ASSERT(parser, pEOF);
|
|
4245
|
+
|
|
4246
|
+
return success;
|
|
4247
|
+
}
|
|
4248
|
+
|
|
4249
|
+
bool rbs_parse_inline_trailing_annotation(rbs_parser_t *parser, rbs_ast_ruby_annotations_t **annotation) {
|
|
4250
|
+
bool success = parse_inline_trailing_annotation(parser, annotation);
|
|
4251
|
+
|
|
4252
|
+
ADVANCE_ASSERT(parser, pEOF);
|
|
4253
|
+
|
|
4254
|
+
return success;
|
|
4255
|
+
}
|