rbs-relaxed 3.9.0.1
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/.github/dependabot.yml +22 -0
- data/.github/workflows/comments.yml +35 -0
- data/.github/workflows/dependabot.yml +30 -0
- data/.github/workflows/ruby.yml +82 -0
- data/.github/workflows/typecheck.yml +38 -0
- data/.github/workflows/windows.yml +43 -0
- data/.gitignore +23 -0
- data/.rubocop.yml +68 -0
- data/BSDL +22 -0
- data/CHANGELOG.md +1868 -0
- data/COPYING +56 -0
- data/README.md +203 -0
- data/Rakefile +417 -0
- data/Steepfile +44 -0
- data/config.yml +313 -0
- data/core/array.rbs +4062 -0
- data/core/basic_object.rbs +375 -0
- data/core/binding.rbs +150 -0
- data/core/builtin.rbs +277 -0
- data/core/class.rbs +220 -0
- data/core/comparable.rbs +171 -0
- data/core/complex.rbs +786 -0
- data/core/constants.rbs +96 -0
- data/core/data.rbs +415 -0
- data/core/dir.rbs +981 -0
- data/core/encoding.rbs +1371 -0
- data/core/enumerable.rbs +2405 -0
- data/core/enumerator/product.rbs +92 -0
- data/core/enumerator.rbs +630 -0
- data/core/env.rbs +6 -0
- data/core/errno.rbs +673 -0
- data/core/errors.rbs +760 -0
- data/core/exception.rbs +485 -0
- data/core/false_class.rbs +82 -0
- data/core/fiber.rbs +550 -0
- data/core/fiber_error.rbs +11 -0
- data/core/file.rbs +2936 -0
- data/core/file_test.rbs +331 -0
- data/core/float.rbs +1151 -0
- data/core/gc.rbs +644 -0
- data/core/global_variables.rbs +184 -0
- data/core/hash.rbs +1861 -0
- data/core/integer.rbs +1413 -0
- data/core/io/buffer.rbs +984 -0
- data/core/io/wait.rbs +70 -0
- data/core/io.rbs +3406 -0
- data/core/kernel.rbs +3096 -0
- data/core/marshal.rbs +207 -0
- data/core/match_data.rbs +635 -0
- data/core/math.rbs +729 -0
- data/core/method.rbs +386 -0
- data/core/module.rbs +1704 -0
- data/core/nil_class.rbs +209 -0
- data/core/numeric.rbs +818 -0
- data/core/object.rbs +110 -0
- data/core/object_space/weak_key_map.rbs +166 -0
- data/core/object_space.rbs +190 -0
- data/core/proc.rbs +868 -0
- data/core/process.rbs +2296 -0
- data/core/ractor.rbs +1068 -0
- data/core/random.rbs +237 -0
- data/core/range.rbs +1107 -0
- data/core/rational.rbs +531 -0
- data/core/rb_config.rbs +88 -0
- data/core/rbs/unnamed/argf.rbs +1229 -0
- data/core/rbs/unnamed/env_class.rbs +1209 -0
- data/core/rbs/unnamed/random.rbs +293 -0
- data/core/refinement.rbs +59 -0
- data/core/regexp.rbs +1930 -0
- data/core/ruby_vm.rbs +765 -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 +176 -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 +1171 -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 +294 -0
- data/core/set.rbs +621 -0
- data/core/signal.rbs +100 -0
- data/core/string.rbs +3583 -0
- data/core/struct.rbs +667 -0
- data/core/symbol.rbs +475 -0
- data/core/thread.rbs +1765 -0
- data/core/thread_group.rbs +79 -0
- data/core/time.rbs +1762 -0
- data/core/trace_point.rbs +477 -0
- data/core/true_class.rbs +98 -0
- data/core/unbound_method.rbs +329 -0
- data/core/warning.rbs +87 -0
- data/docs/CONTRIBUTING.md +106 -0
- data/docs/architecture.md +110 -0
- data/docs/collection.md +192 -0
- data/docs/data_and_struct.md +86 -0
- data/docs/gem.md +57 -0
- data/docs/rbs_by_example.md +309 -0
- data/docs/repo.md +125 -0
- data/docs/sigs.md +167 -0
- data/docs/stdlib.md +147 -0
- data/docs/syntax.md +910 -0
- data/docs/tools.md +17 -0
- data/exe/rbs +7 -0
- data/ext/rbs_extension/extconf.rb +15 -0
- data/ext/rbs_extension/lexer.c +2728 -0
- data/ext/rbs_extension/lexer.h +179 -0
- data/ext/rbs_extension/lexer.re +147 -0
- data/ext/rbs_extension/lexstate.c +175 -0
- data/ext/rbs_extension/location.c +325 -0
- data/ext/rbs_extension/location.h +85 -0
- data/ext/rbs_extension/main.c +33 -0
- data/ext/rbs_extension/parser.c +2973 -0
- data/ext/rbs_extension/parser.h +18 -0
- data/ext/rbs_extension/parserstate.c +397 -0
- data/ext/rbs_extension/parserstate.h +163 -0
- data/ext/rbs_extension/rbs_extension.h +31 -0
- data/ext/rbs_extension/unescape.c +32 -0
- data/goodcheck.yml +91 -0
- data/include/rbs/constants.h +82 -0
- data/include/rbs/ruby_objs.h +72 -0
- data/include/rbs/util/rbs_constant_pool.h +219 -0
- data/include/rbs.h +7 -0
- data/lib/rbs/ancestor_graph.rb +92 -0
- data/lib/rbs/annotate/annotations.rb +199 -0
- data/lib/rbs/annotate/formatter.rb +92 -0
- data/lib/rbs/annotate/rdoc_annotator.rb +400 -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 +467 -0
- data/lib/rbs/ast/directives.rb +49 -0
- data/lib/rbs/ast/members.rb +451 -0
- data/lib/rbs/ast/type_param.rb +225 -0
- data/lib/rbs/ast/visitor.rb +137 -0
- data/lib/rbs/buffer.rb +67 -0
- data/lib/rbs/builtin_names.rb +58 -0
- data/lib/rbs/cli/colored_io.rb +48 -0
- data/lib/rbs/cli/diff.rb +83 -0
- data/lib/rbs/cli/validate.rb +357 -0
- data/lib/rbs/cli.rb +1223 -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 +218 -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 +258 -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 +401 -0
- data/lib/rbs/definition_builder/ancestor_builder.rb +620 -0
- data/lib/rbs/definition_builder/method_builder.rb +254 -0
- data/lib/rbs/definition_builder.rb +845 -0
- data/lib/rbs/diff.rb +125 -0
- data/lib/rbs/environment/use_map.rb +77 -0
- data/lib/rbs/environment.rb +829 -0
- data/lib/rbs/environment_loader.rb +173 -0
- data/lib/rbs/environment_walker.rb +155 -0
- data/lib/rbs/errors.rb +645 -0
- data/lib/rbs/factory.rb +18 -0
- data/lib/rbs/file_finder.rb +28 -0
- data/lib/rbs/location_aux.rb +138 -0
- data/lib/rbs/locator.rb +243 -0
- data/lib/rbs/method_type.rb +143 -0
- data/lib/rbs/namespace.rb +125 -0
- data/lib/rbs/parser/lex_result.rb +15 -0
- data/lib/rbs/parser/token.rb +23 -0
- data/lib/rbs/parser_aux.rb +114 -0
- data/lib/rbs/prototype/helpers.rb +140 -0
- data/lib/rbs/prototype/node_usage.rb +99 -0
- data/lib/rbs/prototype/rb.rb +840 -0
- data/lib/rbs/prototype/rbi.rb +641 -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 +667 -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 +91 -0
- data/lib/rbs/sorter.rb +198 -0
- data/lib/rbs/substitution.rb +83 -0
- data/lib/rbs/subtractor.rb +201 -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 +435 -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 +109 -0
- data/lib/rbs/types.rb +1596 -0
- data/lib/rbs/unit_test/convertibles.rb +176 -0
- data/lib/rbs/unit_test/spy.rb +138 -0
- data/lib/rbs/unit_test/type_assertions.rb +347 -0
- data/lib/rbs/unit_test/with_aliases.rb +143 -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/writer.rb +424 -0
- data/lib/rbs.rb +94 -0
- data/lib/rdoc/discover.rb +20 -0
- data/lib/rdoc_plugin/parser.rb +163 -0
- data/rbs-relaxed.gemspec +48 -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 +36 -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 +82 -0
- data/sig/annotate/rdoc_source.rbs +30 -0
- data/sig/annotation.rbs +27 -0
- data/sig/buffer.rbs +32 -0
- data/sig/builtin_names.rbs +44 -0
- data/sig/cli/colored_io.rbs +15 -0
- data/sig/cli/diff.rbs +21 -0
- data/sig/cli/validate.rbs +43 -0
- data/sig/cli.rbs +87 -0
- data/sig/collection/cleaner.rbs +13 -0
- data/sig/collection/config/lockfile.rbs +74 -0
- data/sig/collection/config/lockfile_generator.rbs +66 -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 +267 -0
- data/sig/definition.rbs +173 -0
- data/sig/definition_builder.rbs +165 -0
- data/sig/diff.rbs +28 -0
- data/sig/directives.rbs +77 -0
- data/sig/environment.rbs +279 -0
- data/sig/environment_loader.rbs +111 -0
- data/sig/environment_walker.rbs +65 -0
- data/sig/errors.rbs +405 -0
- data/sig/factory.rbs +5 -0
- data/sig/file_finder.rbs +28 -0
- data/sig/location.rbs +110 -0
- data/sig/locator.rbs +58 -0
- data/sig/manifest.yaml +7 -0
- data/sig/members.rbs +258 -0
- data/sig/method_builder.rbs +84 -0
- data/sig/method_types.rbs +58 -0
- data/sig/namespace.rbs +146 -0
- data/sig/parser.rbs +100 -0
- data/sig/prototype/helpers.rbs +27 -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 +35 -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/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 +110 -0
- data/sig/typename.rbs +79 -0
- data/sig/types.rbs +579 -0
- data/sig/unit_test/convertibles.rbs +154 -0
- data/sig/unit_test/spy.rbs +30 -0
- data/sig/unit_test/type_assertions.rbs +196 -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/writer.rbs +127 -0
- data/src/constants.c +153 -0
- data/src/ruby_objs.c +795 -0
- data/src/util/rbs_constant_pool.c +342 -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 +1629 -0
- data/stdlib/bigdecimal-math/0/big_math.rbs +119 -0
- data/stdlib/bigdecimal-math/0/manifest.yaml +2 -0
- data/stdlib/cgi/0/core.rbs +1285 -0
- data/stdlib/cgi/0/manifest.yaml +3 -0
- data/stdlib/coverage/0/coverage.rbs +263 -0
- data/stdlib/csv/0/csv.rbs +3776 -0
- data/stdlib/csv/0/manifest.yaml +3 -0
- data/stdlib/date/0/date.rbs +1585 -0
- data/stdlib/date/0/date_time.rbs +616 -0
- data/stdlib/date/0/time.rbs +26 -0
- data/stdlib/dbm/0/dbm.rbs +421 -0
- data/stdlib/delegate/0/delegator.rbs +184 -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 +343 -0
- data/stdlib/digest/0/digest.rbs +577 -0
- data/stdlib/erb/0/erb.rbs +532 -0
- data/stdlib/etc/0/etc.rbs +865 -0
- data/stdlib/fileutils/0/fileutils.rbs +1734 -0
- data/stdlib/find/0/find.rbs +49 -0
- data/stdlib/forwardable/0/forwardable.rbs +268 -0
- data/stdlib/io-console/0/io-console.rbs +414 -0
- data/stdlib/ipaddr/0/ipaddr.rbs +428 -0
- data/stdlib/json/0/json.rbs +1916 -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 +5552 -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 +487 -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 +393 -0
- data/stdlib/open3/0/open3.rbs +147 -0
- data/stdlib/openssl/0/manifest.yaml +3 -0
- data/stdlib/openssl/0/openssl.rbs +12113 -0
- data/stdlib/optparse/0/optparse.rbs +1725 -0
- data/stdlib/pathname/0/pathname.rbs +1406 -0
- data/stdlib/pp/0/manifest.yaml +2 -0
- data/stdlib/pp/0/pp.rbs +300 -0
- data/stdlib/prettyprint/0/prettyprint.rbs +383 -0
- data/stdlib/pstore/0/pstore.rbs +603 -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 +402 -0
- data/stdlib/psych/0/store.rbs +59 -0
- data/stdlib/pty/0/pty.rbs +237 -0
- data/stdlib/rdoc/0/code_object.rbs +51 -0
- data/stdlib/rdoc/0/comment.rbs +59 -0
- data/stdlib/rdoc/0/context.rbs +153 -0
- data/stdlib/rdoc/0/markup.rbs +117 -0
- data/stdlib/rdoc/0/parser.rbs +56 -0
- data/stdlib/rdoc/0/rdoc.rbs +391 -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 +1830 -0
- data/stdlib/ripper/0/ripper.rbs +1648 -0
- data/stdlib/securerandom/0/securerandom.rbs +62 -0
- data/stdlib/shellwords/0/shellwords.rbs +229 -0
- data/stdlib/singleton/0/singleton.rbs +131 -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 +92 -0
- data/stdlib/socket/0/socket.rbs +4157 -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 +79 -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 +567 -0
- data/stdlib/strscan/0/string_scanner.rbs +1627 -0
- data/stdlib/tempfile/0/tempfile.rbs +479 -0
- data/stdlib/time/0/time.rbs +432 -0
- data/stdlib/timeout/0/timeout.rbs +81 -0
- data/stdlib/tmpdir/0/tmpdir.rbs +69 -0
- data/stdlib/tsort/0/cyclic.rbs +5 -0
- data/stdlib/tsort/0/interfaces.rbs +20 -0
- data/stdlib/tsort/0/tsort.rbs +409 -0
- data/stdlib/uri/0/common.rbs +582 -0
- data/stdlib/uri/0/file.rbs +118 -0
- data/stdlib/uri/0/ftp.rbs +13 -0
- data/stdlib/uri/0/generic.rbs +1108 -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 +210 -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 +166 -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 +200 -0
- metadata +532 -0
@@ -0,0 +1,2973 @@
|
|
1
|
+
#include "rbs_extension.h"
|
2
|
+
#include "rbs/util/rbs_constant_pool.h"
|
3
|
+
|
4
|
+
#define INTERN(str) \
|
5
|
+
rbs_constant_pool_insert_constant( \
|
6
|
+
RBS_GLOBAL_CONSTANT_POOL, \
|
7
|
+
(const uint8_t *) str, \
|
8
|
+
strlen(str) \
|
9
|
+
)
|
10
|
+
|
11
|
+
#define INTERN_TOKEN(parserstate, tok) \
|
12
|
+
rb_intern3(\
|
13
|
+
peek_token(parserstate->lexstate, tok),\
|
14
|
+
token_bytes(tok),\
|
15
|
+
rb_enc_get(parserstate->lexstate->string)\
|
16
|
+
)
|
17
|
+
|
18
|
+
#define KEYWORD_CASES \
|
19
|
+
case kBOOL:\
|
20
|
+
case kBOT: \
|
21
|
+
case kCLASS: \
|
22
|
+
case kFALSE: \
|
23
|
+
case kINSTANCE: \
|
24
|
+
case kINTERFACE: \
|
25
|
+
case kNIL: \
|
26
|
+
case kSELF: \
|
27
|
+
case kSINGLETON: \
|
28
|
+
case kTOP: \
|
29
|
+
case kTRUE: \
|
30
|
+
case kVOID: \
|
31
|
+
case kTYPE: \
|
32
|
+
case kUNCHECKED: \
|
33
|
+
case kIN: \
|
34
|
+
case kOUT: \
|
35
|
+
case kEND: \
|
36
|
+
case kDEF: \
|
37
|
+
case kINCLUDE: \
|
38
|
+
case kEXTEND: \
|
39
|
+
case kPREPEND: \
|
40
|
+
case kALIAS: \
|
41
|
+
case kMODULE: \
|
42
|
+
case kATTRREADER: \
|
43
|
+
case kATTRWRITER: \
|
44
|
+
case kATTRACCESSOR: \
|
45
|
+
case kPUBLIC: \
|
46
|
+
case kPRIVATE: \
|
47
|
+
case kUNTYPED: \
|
48
|
+
case kUSE: \
|
49
|
+
case kAS: \
|
50
|
+
case k__TODO__: \
|
51
|
+
/* nop */
|
52
|
+
|
53
|
+
typedef struct {
|
54
|
+
VALUE required_positionals;
|
55
|
+
VALUE optional_positionals;
|
56
|
+
VALUE rest_positionals;
|
57
|
+
VALUE trailing_positionals;
|
58
|
+
VALUE required_keywords;
|
59
|
+
VALUE optional_keywords;
|
60
|
+
VALUE rest_keywords;
|
61
|
+
} method_params;
|
62
|
+
|
63
|
+
static VALUE EMPTY_ARRAY;
|
64
|
+
|
65
|
+
static inline void melt_array(VALUE *array) {
|
66
|
+
if (*array == EMPTY_ARRAY) {
|
67
|
+
*array = rb_ary_new();
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
static bool rbs_is_untyped_params(method_params *params) {
|
72
|
+
return NIL_P(params->required_positionals);
|
73
|
+
}
|
74
|
+
|
75
|
+
// /**
|
76
|
+
// * Returns RBS::Location object of `current_token` of a parser state.
|
77
|
+
// *
|
78
|
+
// * @param state
|
79
|
+
// * @return New RBS::Location object.
|
80
|
+
// * */
|
81
|
+
static VALUE rbs_location_current_token(parserstate *state) {
|
82
|
+
return rbs_location_pp(
|
83
|
+
state->buffer,
|
84
|
+
&state->current_token.range.start,
|
85
|
+
&state->current_token.range.end
|
86
|
+
);
|
87
|
+
}
|
88
|
+
|
89
|
+
static VALUE parse_optional(parserstate *state);
|
90
|
+
static VALUE parse_simple(parserstate *state);
|
91
|
+
|
92
|
+
static VALUE string_of_loc(parserstate *state, position start, position end) {
|
93
|
+
return rb_enc_str_new(
|
94
|
+
RSTRING_PTR(state->lexstate->string) + start.byte_pos,
|
95
|
+
end.byte_pos - start.byte_pos,
|
96
|
+
rb_enc_get(state->lexstate->string)
|
97
|
+
);
|
98
|
+
}
|
99
|
+
|
100
|
+
/**
|
101
|
+
* Raises RuntimeError with "Unexpected error " message.
|
102
|
+
* */
|
103
|
+
static NORETURN(void) rbs_abort(void) {
|
104
|
+
rb_raise(
|
105
|
+
rb_eRuntimeError,
|
106
|
+
"Unexpected error"
|
107
|
+
);
|
108
|
+
}
|
109
|
+
|
110
|
+
NORETURN(void) raise_syntax_error(parserstate *state, token tok, const char *fmt, ...) {
|
111
|
+
va_list args;
|
112
|
+
va_start(args, fmt);
|
113
|
+
VALUE message = rb_vsprintf(fmt, args);
|
114
|
+
va_end(args);
|
115
|
+
|
116
|
+
VALUE location = rbs_new_location(state->buffer, tok.range);
|
117
|
+
VALUE type = rb_str_new_cstr(token_type_str(tok.type));
|
118
|
+
|
119
|
+
VALUE error = rb_funcall(
|
120
|
+
RBS_ParsingError,
|
121
|
+
rb_intern("new"),
|
122
|
+
3,
|
123
|
+
location,
|
124
|
+
message,
|
125
|
+
type
|
126
|
+
);
|
127
|
+
|
128
|
+
rb_exc_raise(error);
|
129
|
+
}
|
130
|
+
|
131
|
+
typedef enum {
|
132
|
+
CLASS_NAME = 1,
|
133
|
+
INTERFACE_NAME = 2,
|
134
|
+
ALIAS_NAME = 4
|
135
|
+
} TypeNameKind;
|
136
|
+
|
137
|
+
void parser_advance_no_gap(parserstate *state) {
|
138
|
+
if (state->current_token.range.end.byte_pos == state->next_token.range.start.byte_pos) {
|
139
|
+
parser_advance(state);
|
140
|
+
} else {
|
141
|
+
raise_syntax_error(
|
142
|
+
state,
|
143
|
+
state->next_token,
|
144
|
+
"unexpected token"
|
145
|
+
);
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
/*
|
150
|
+
type_name ::= {`::`} (tUIDENT `::`)* <tXIDENT>
|
151
|
+
| {(tUIDENT `::`)*} <tXIDENT>
|
152
|
+
| {<tXIDENT>}
|
153
|
+
*/
|
154
|
+
static VALUE parse_type_name(parserstate *state, TypeNameKind kind, range *rg) {
|
155
|
+
VALUE absolute = Qfalse;
|
156
|
+
VALUE path = EMPTY_ARRAY;
|
157
|
+
|
158
|
+
if (rg) {
|
159
|
+
rg->start = state->current_token.range.start;
|
160
|
+
}
|
161
|
+
|
162
|
+
if (state->current_token.type == pCOLON2) {
|
163
|
+
absolute = Qtrue;
|
164
|
+
parser_advance_no_gap(state);
|
165
|
+
}
|
166
|
+
|
167
|
+
while (
|
168
|
+
state->current_token.type == tUIDENT
|
169
|
+
&& state->next_token.type == pCOLON2
|
170
|
+
&& state->current_token.range.end.byte_pos == state->next_token.range.start.byte_pos
|
171
|
+
&& state->next_token.range.end.byte_pos == state->next_token2.range.start.byte_pos
|
172
|
+
) {
|
173
|
+
melt_array(&path);
|
174
|
+
rb_ary_push(path, ID2SYM(INTERN_TOKEN(state, state->current_token)));
|
175
|
+
|
176
|
+
parser_advance(state);
|
177
|
+
parser_advance(state);
|
178
|
+
}
|
179
|
+
|
180
|
+
VALUE namespace = rbs_namespace(path, absolute);
|
181
|
+
|
182
|
+
switch (state->current_token.type) {
|
183
|
+
case tLIDENT:
|
184
|
+
if (kind & ALIAS_NAME) goto success;
|
185
|
+
goto error;
|
186
|
+
case tULIDENT:
|
187
|
+
if (kind & INTERFACE_NAME) goto success;
|
188
|
+
goto error;
|
189
|
+
case tUIDENT:
|
190
|
+
if (kind & CLASS_NAME) goto success;
|
191
|
+
goto error;
|
192
|
+
default:
|
193
|
+
goto error;
|
194
|
+
}
|
195
|
+
|
196
|
+
success: {
|
197
|
+
if (rg) {
|
198
|
+
rg->end = state->current_token.range.end;
|
199
|
+
}
|
200
|
+
|
201
|
+
return rbs_type_name(namespace, ID2SYM(INTERN_TOKEN(state, state->current_token)));
|
202
|
+
}
|
203
|
+
|
204
|
+
error: {
|
205
|
+
VALUE ids = rb_ary_new();
|
206
|
+
if (kind & ALIAS_NAME) {
|
207
|
+
rb_ary_push(ids, rb_str_new_literal("alias name"));
|
208
|
+
}
|
209
|
+
if (kind & INTERFACE_NAME) {
|
210
|
+
rb_ary_push(ids, rb_str_new_literal("interface name"));
|
211
|
+
}
|
212
|
+
if (kind & CLASS_NAME) {
|
213
|
+
rb_ary_push(ids, rb_str_new_literal("class/module/constant name"));
|
214
|
+
}
|
215
|
+
|
216
|
+
VALUE string = rb_funcall(ids, rb_intern("join"), 1, rb_str_new_cstr(", "));
|
217
|
+
|
218
|
+
raise_syntax_error(
|
219
|
+
state,
|
220
|
+
state->current_token,
|
221
|
+
"expected one of %"PRIsVALUE,
|
222
|
+
string
|
223
|
+
);
|
224
|
+
}
|
225
|
+
}
|
226
|
+
|
227
|
+
/*
|
228
|
+
type_list ::= {} type `,` ... <`,`> eol
|
229
|
+
| {} type `,` ... `,` <type> eol
|
230
|
+
*/
|
231
|
+
static void parse_type_list(parserstate *state, enum TokenType eol, VALUE *types) {
|
232
|
+
while (true) {
|
233
|
+
melt_array(types);
|
234
|
+
rb_ary_push(*types, parse_type(state));
|
235
|
+
|
236
|
+
if (state->next_token.type == pCOMMA) {
|
237
|
+
parser_advance(state);
|
238
|
+
|
239
|
+
if (state->next_token.type == eol) {
|
240
|
+
break;
|
241
|
+
}
|
242
|
+
} else {
|
243
|
+
if (state->next_token.type == eol) {
|
244
|
+
break;
|
245
|
+
} else {
|
246
|
+
raise_syntax_error(
|
247
|
+
state,
|
248
|
+
state->next_token,
|
249
|
+
"comma delimited type list is expected"
|
250
|
+
);
|
251
|
+
}
|
252
|
+
}
|
253
|
+
}
|
254
|
+
}
|
255
|
+
|
256
|
+
static bool is_keyword_token(enum TokenType type) {
|
257
|
+
switch (type)
|
258
|
+
{
|
259
|
+
case tLIDENT:
|
260
|
+
case tUIDENT:
|
261
|
+
case tULIDENT:
|
262
|
+
case tULLIDENT:
|
263
|
+
case tQIDENT:
|
264
|
+
case tBANGIDENT:
|
265
|
+
KEYWORD_CASES
|
266
|
+
return true;
|
267
|
+
default:
|
268
|
+
return false;
|
269
|
+
}
|
270
|
+
}
|
271
|
+
|
272
|
+
/*
|
273
|
+
function_param ::= {} <type>
|
274
|
+
| {} type <param>
|
275
|
+
*/
|
276
|
+
static VALUE parse_function_param(parserstate *state) {
|
277
|
+
range type_range;
|
278
|
+
type_range.start = state->next_token.range.start;
|
279
|
+
VALUE type = parse_type(state);
|
280
|
+
type_range.end = state->current_token.range.end;
|
281
|
+
|
282
|
+
if (state->next_token.type == pCOMMA || state->next_token.type == pRPAREN) {
|
283
|
+
range param_range = type_range;
|
284
|
+
|
285
|
+
VALUE location = rbs_new_location(state->buffer, param_range);
|
286
|
+
rbs_loc *loc = rbs_check_location(location);
|
287
|
+
rbs_loc_alloc_children(loc, 1);
|
288
|
+
rbs_loc_add_optional_child(loc, INTERN("name"), NULL_RANGE);
|
289
|
+
|
290
|
+
return rbs_function_param(type, Qnil, location);
|
291
|
+
} else {
|
292
|
+
range name_range = state->next_token.range;
|
293
|
+
|
294
|
+
parser_advance(state);
|
295
|
+
|
296
|
+
range param_range = {
|
297
|
+
.start = type_range.start,
|
298
|
+
.end = name_range.end,
|
299
|
+
};
|
300
|
+
|
301
|
+
if (!is_keyword_token(state->current_token.type)) {
|
302
|
+
raise_syntax_error(
|
303
|
+
state,
|
304
|
+
state->current_token,
|
305
|
+
"unexpected token for function parameter name"
|
306
|
+
);
|
307
|
+
}
|
308
|
+
|
309
|
+
VALUE name = rb_to_symbol(rbs_unquote_string(state, state->current_token.range, 0));
|
310
|
+
VALUE location = rbs_new_location(state->buffer, param_range);
|
311
|
+
rbs_loc *loc = rbs_check_location(location);
|
312
|
+
rbs_loc_alloc_children(loc, 1);
|
313
|
+
rbs_loc_add_optional_child(loc, INTERN("name"), name_range);
|
314
|
+
|
315
|
+
return rbs_function_param(type, name, location);
|
316
|
+
}
|
317
|
+
}
|
318
|
+
|
319
|
+
static ID intern_token_start_end(parserstate *state, token start_token, token end_token) {
|
320
|
+
return rb_intern3(
|
321
|
+
peek_token(state->lexstate, start_token),
|
322
|
+
end_token.range.end.byte_pos - start_token.range.start.byte_pos,
|
323
|
+
rb_enc_get(state->lexstate->string)
|
324
|
+
);
|
325
|
+
}
|
326
|
+
|
327
|
+
/*
|
328
|
+
keyword_key ::= {} <keyword> `:`
|
329
|
+
| {} keyword <`?`> `:`
|
330
|
+
*/
|
331
|
+
static VALUE parse_keyword_key(parserstate *state) {
|
332
|
+
parser_advance(state);
|
333
|
+
|
334
|
+
if (state->next_token.type == pQUESTION) {
|
335
|
+
VALUE key = ID2SYM(intern_token_start_end(state, state->current_token, state->next_token));
|
336
|
+
parser_advance(state);
|
337
|
+
return key;
|
338
|
+
} else {
|
339
|
+
return ID2SYM(INTERN_TOKEN(state, state->current_token));
|
340
|
+
}
|
341
|
+
}
|
342
|
+
|
343
|
+
/*
|
344
|
+
keyword ::= {} keyword `:` <function_param>
|
345
|
+
*/
|
346
|
+
static void parse_keyword(parserstate *state, VALUE keywords, VALUE memo) {
|
347
|
+
VALUE key = parse_keyword_key(state);
|
348
|
+
|
349
|
+
if (!NIL_P(rb_hash_aref(memo, key))) {
|
350
|
+
raise_syntax_error(
|
351
|
+
state,
|
352
|
+
state->current_token,
|
353
|
+
"duplicated keyword argument"
|
354
|
+
);
|
355
|
+
} else {
|
356
|
+
rb_hash_aset(memo, key, Qtrue);
|
357
|
+
}
|
358
|
+
|
359
|
+
parser_advance_assert(state, pCOLON);
|
360
|
+
VALUE param = parse_function_param(state);
|
361
|
+
|
362
|
+
rb_hash_aset(keywords, key, param);
|
363
|
+
|
364
|
+
return;
|
365
|
+
}
|
366
|
+
|
367
|
+
/*
|
368
|
+
Returns true if keyword is given.
|
369
|
+
|
370
|
+
is_keyword === {} KEYWORD `:`
|
371
|
+
*/
|
372
|
+
static bool is_keyword(parserstate *state) {
|
373
|
+
if (is_keyword_token(state->next_token.type)) {
|
374
|
+
if (state->next_token2.type == pCOLON && state->next_token.range.end.byte_pos == state->next_token2.range.start.byte_pos) {
|
375
|
+
return true;
|
376
|
+
}
|
377
|
+
|
378
|
+
if (state->next_token2.type == pQUESTION
|
379
|
+
&& state->next_token3.type == pCOLON
|
380
|
+
&& state->next_token.range.end.byte_pos == state->next_token2.range.start.byte_pos
|
381
|
+
&& state->next_token2.range.end.byte_pos == state->next_token3.range.start.byte_pos) {
|
382
|
+
return true;
|
383
|
+
}
|
384
|
+
}
|
385
|
+
|
386
|
+
return false;
|
387
|
+
}
|
388
|
+
|
389
|
+
/*
|
390
|
+
params ::= {} `)`
|
391
|
+
| {} `?` `)` -- Untyped function params (assign params.required = nil)
|
392
|
+
| <required_params> `)`
|
393
|
+
| <required_params> `,` `)`
|
394
|
+
|
395
|
+
required_params ::= {} function_param `,` <required_params>
|
396
|
+
| {} <function_param>
|
397
|
+
| {} <optional_params>
|
398
|
+
|
399
|
+
optional_params ::= {} `?` function_param `,` <optional_params>
|
400
|
+
| {} `?` <function_param>
|
401
|
+
| {} <rest_params>
|
402
|
+
|
403
|
+
rest_params ::= {} `*` function_param `,` <trailing_params>
|
404
|
+
| {} `*` <function_param>
|
405
|
+
| {} <trailing_params>
|
406
|
+
|
407
|
+
trailing_params ::= {} function_param `,` <trailing_params>
|
408
|
+
| {} <function_param>
|
409
|
+
| {} <keywords>
|
410
|
+
|
411
|
+
keywords ::= {} required_keyword `,` <keywords>
|
412
|
+
| {} `?` optional_keyword `,` <keywords>
|
413
|
+
| {} `**` function_param `,` <keywords>
|
414
|
+
| {} <required_keyword>
|
415
|
+
| {} `?` <optional_keyword>
|
416
|
+
| {} `**` <function_param>
|
417
|
+
*/
|
418
|
+
static void parse_params(parserstate *state, method_params *params) {
|
419
|
+
if (state->next_token.type == pQUESTION && state->next_token2.type == pRPAREN) {
|
420
|
+
params->required_positionals = Qnil;
|
421
|
+
parser_advance(state);
|
422
|
+
return;
|
423
|
+
}
|
424
|
+
if (state->next_token.type == pRPAREN) {
|
425
|
+
return;
|
426
|
+
}
|
427
|
+
|
428
|
+
VALUE memo = rb_hash_new();
|
429
|
+
|
430
|
+
while (true) {
|
431
|
+
VALUE param;
|
432
|
+
|
433
|
+
switch (state->next_token.type) {
|
434
|
+
case pQUESTION:
|
435
|
+
goto PARSE_OPTIONAL_PARAMS;
|
436
|
+
case pSTAR:
|
437
|
+
goto PARSE_REST_PARAM;
|
438
|
+
case pSTAR2:
|
439
|
+
goto PARSE_KEYWORDS;
|
440
|
+
case pRPAREN:
|
441
|
+
goto EOP;
|
442
|
+
|
443
|
+
default:
|
444
|
+
if (is_keyword(state)) {
|
445
|
+
goto PARSE_KEYWORDS;
|
446
|
+
}
|
447
|
+
|
448
|
+
param = parse_function_param(state);
|
449
|
+
melt_array(¶ms->required_positionals);
|
450
|
+
rb_ary_push(params->required_positionals, param);
|
451
|
+
|
452
|
+
break;
|
453
|
+
}
|
454
|
+
|
455
|
+
if (!parser_advance_if(state, pCOMMA)) {
|
456
|
+
goto EOP;
|
457
|
+
}
|
458
|
+
}
|
459
|
+
|
460
|
+
PARSE_OPTIONAL_PARAMS:
|
461
|
+
while (true) {
|
462
|
+
VALUE param;
|
463
|
+
|
464
|
+
switch (state->next_token.type) {
|
465
|
+
case pQUESTION:
|
466
|
+
parser_advance(state);
|
467
|
+
|
468
|
+
if (is_keyword(state)) {
|
469
|
+
parse_keyword(state, params->optional_keywords, memo);
|
470
|
+
parser_advance_if(state, pCOMMA);
|
471
|
+
goto PARSE_KEYWORDS;
|
472
|
+
}
|
473
|
+
|
474
|
+
param = parse_function_param(state);
|
475
|
+
melt_array(¶ms->optional_positionals);
|
476
|
+
rb_ary_push(params->optional_positionals, param);
|
477
|
+
|
478
|
+
break;
|
479
|
+
default:
|
480
|
+
goto PARSE_REST_PARAM;
|
481
|
+
}
|
482
|
+
|
483
|
+
if (!parser_advance_if(state, pCOMMA)) {
|
484
|
+
goto EOP;
|
485
|
+
}
|
486
|
+
}
|
487
|
+
|
488
|
+
PARSE_REST_PARAM:
|
489
|
+
if (state->next_token.type == pSTAR) {
|
490
|
+
parser_advance(state);
|
491
|
+
params->rest_positionals = parse_function_param(state);
|
492
|
+
|
493
|
+
if (!parser_advance_if(state, pCOMMA)) {
|
494
|
+
goto EOP;
|
495
|
+
}
|
496
|
+
}
|
497
|
+
goto PARSE_TRAILING_PARAMS;
|
498
|
+
|
499
|
+
PARSE_TRAILING_PARAMS:
|
500
|
+
while (true) {
|
501
|
+
VALUE param;
|
502
|
+
|
503
|
+
switch (state->next_token.type) {
|
504
|
+
case pQUESTION:
|
505
|
+
goto PARSE_KEYWORDS;
|
506
|
+
case pSTAR:
|
507
|
+
goto EOP;
|
508
|
+
case pSTAR2:
|
509
|
+
goto PARSE_KEYWORDS;
|
510
|
+
case pRPAREN:
|
511
|
+
goto EOP;
|
512
|
+
|
513
|
+
default:
|
514
|
+
if (is_keyword(state)) {
|
515
|
+
goto PARSE_KEYWORDS;
|
516
|
+
}
|
517
|
+
|
518
|
+
param = parse_function_param(state);
|
519
|
+
melt_array(¶ms->trailing_positionals);
|
520
|
+
rb_ary_push(params->trailing_positionals, param);
|
521
|
+
|
522
|
+
break;
|
523
|
+
}
|
524
|
+
|
525
|
+
if (!parser_advance_if(state, pCOMMA)) {
|
526
|
+
goto EOP;
|
527
|
+
}
|
528
|
+
}
|
529
|
+
|
530
|
+
PARSE_KEYWORDS:
|
531
|
+
while (true) {
|
532
|
+
switch (state->next_token.type) {
|
533
|
+
case pQUESTION:
|
534
|
+
parser_advance(state);
|
535
|
+
if (is_keyword(state)) {
|
536
|
+
parse_keyword(state, params->optional_keywords, memo);
|
537
|
+
} else {
|
538
|
+
raise_syntax_error(
|
539
|
+
state,
|
540
|
+
state->next_token,
|
541
|
+
"optional keyword argument type is expected"
|
542
|
+
);
|
543
|
+
}
|
544
|
+
break;
|
545
|
+
|
546
|
+
case pSTAR2:
|
547
|
+
parser_advance(state);
|
548
|
+
params->rest_keywords = parse_function_param(state);
|
549
|
+
break;
|
550
|
+
|
551
|
+
case tUIDENT:
|
552
|
+
case tLIDENT:
|
553
|
+
case tQIDENT:
|
554
|
+
case tULIDENT:
|
555
|
+
case tULLIDENT:
|
556
|
+
case tBANGIDENT:
|
557
|
+
KEYWORD_CASES
|
558
|
+
if (is_keyword(state)) {
|
559
|
+
parse_keyword(state, params->required_keywords, memo);
|
560
|
+
} else {
|
561
|
+
raise_syntax_error(
|
562
|
+
state,
|
563
|
+
state->next_token,
|
564
|
+
"required keyword argument type is expected"
|
565
|
+
);
|
566
|
+
}
|
567
|
+
break;
|
568
|
+
|
569
|
+
default:
|
570
|
+
goto EOP;
|
571
|
+
}
|
572
|
+
|
573
|
+
if (!parser_advance_if(state, pCOMMA)) {
|
574
|
+
goto EOP;
|
575
|
+
}
|
576
|
+
}
|
577
|
+
|
578
|
+
EOP:
|
579
|
+
if (state->next_token.type != pRPAREN) {
|
580
|
+
raise_syntax_error(
|
581
|
+
state,
|
582
|
+
state->next_token,
|
583
|
+
"unexpected token for method type parameters"
|
584
|
+
);
|
585
|
+
}
|
586
|
+
|
587
|
+
return;
|
588
|
+
}
|
589
|
+
|
590
|
+
/*
|
591
|
+
optional ::= {} <simple_type>
|
592
|
+
| {} simple_type <`?`>
|
593
|
+
*/
|
594
|
+
static VALUE parse_optional(parserstate *state) {
|
595
|
+
range rg;
|
596
|
+
rg.start = state->next_token.range.start;
|
597
|
+
|
598
|
+
VALUE type = parse_simple(state);
|
599
|
+
|
600
|
+
if (state->next_token.type == pQUESTION) {
|
601
|
+
parser_advance(state);
|
602
|
+
rg.end = state->current_token.range.end;
|
603
|
+
VALUE location = rbs_new_location(state->buffer, rg);
|
604
|
+
return rbs_optional(type, location);
|
605
|
+
} else {
|
606
|
+
return type;
|
607
|
+
}
|
608
|
+
}
|
609
|
+
|
610
|
+
static void initialize_method_params(method_params *params){
|
611
|
+
*params = (method_params) {
|
612
|
+
.required_positionals = EMPTY_ARRAY,
|
613
|
+
.optional_positionals = EMPTY_ARRAY,
|
614
|
+
.rest_positionals = Qnil,
|
615
|
+
.trailing_positionals = EMPTY_ARRAY,
|
616
|
+
.required_keywords = rb_hash_new(),
|
617
|
+
.optional_keywords = rb_hash_new(),
|
618
|
+
.rest_keywords = Qnil,
|
619
|
+
};
|
620
|
+
}
|
621
|
+
|
622
|
+
/*
|
623
|
+
self_type_binding ::= {} <>
|
624
|
+
| {} `[` `self` `:` type <`]`>
|
625
|
+
*/
|
626
|
+
static VALUE parse_self_type_binding(parserstate *state) {
|
627
|
+
if (state->next_token.type == pLBRACKET) {
|
628
|
+
parser_advance(state);
|
629
|
+
parser_advance_assert(state, kSELF);
|
630
|
+
parser_advance_assert(state, pCOLON);
|
631
|
+
VALUE type = parse_type(state);
|
632
|
+
parser_advance_assert(state, pRBRACKET);
|
633
|
+
return type;
|
634
|
+
} else {
|
635
|
+
return Qnil;
|
636
|
+
}
|
637
|
+
}
|
638
|
+
|
639
|
+
/*
|
640
|
+
function ::= {} `(` params `)` self_type_binding? `{` `(` params `)` self_type_binding? `->` optional `}` `->` <optional>
|
641
|
+
| {} `(` params `)` self_type_binding? `->` <optional>
|
642
|
+
| {} self_type_binding? `{` `(` params `)` self_type_binding? `->` optional `}` `->` <optional>
|
643
|
+
| {} self_type_binding? `{` self_type_binding `->` optional `}` `->` <optional>
|
644
|
+
| {} self_type_binding? `->` <optional>
|
645
|
+
*/
|
646
|
+
static void parse_function(parserstate *state, VALUE *function, VALUE *block, VALUE *function_self_type) {
|
647
|
+
method_params params;
|
648
|
+
initialize_method_params(¶ms);
|
649
|
+
|
650
|
+
if (state->next_token.type == pLPAREN) {
|
651
|
+
parser_advance(state);
|
652
|
+
parse_params(state, ¶ms);
|
653
|
+
parser_advance_assert(state, pRPAREN);
|
654
|
+
}
|
655
|
+
|
656
|
+
// Untyped method parameter means it cannot have block
|
657
|
+
if (rbs_is_untyped_params(¶ms)) {
|
658
|
+
if (state->next_token.type != pARROW) {
|
659
|
+
raise_syntax_error(state, state->next_token2, "A method type with untyped method parameter cannot have block");
|
660
|
+
}
|
661
|
+
}
|
662
|
+
|
663
|
+
// Passing NULL to function_self_type means the function itself doesn't accept self type binding. (== method type)
|
664
|
+
if (function_self_type) {
|
665
|
+
*function_self_type = parse_self_type_binding(state);
|
666
|
+
}
|
667
|
+
|
668
|
+
VALUE required = Qtrue;
|
669
|
+
if (state->next_token.type == pQUESTION && state->next_token2.type == pLBRACE) {
|
670
|
+
// Optional block
|
671
|
+
required = Qfalse;
|
672
|
+
parser_advance(state);
|
673
|
+
}
|
674
|
+
if (state->next_token.type == pLBRACE) {
|
675
|
+
parser_advance(state);
|
676
|
+
|
677
|
+
method_params block_params;
|
678
|
+
initialize_method_params(&block_params);
|
679
|
+
|
680
|
+
if (state->next_token.type == pLPAREN) {
|
681
|
+
parser_advance(state);
|
682
|
+
parse_params(state, &block_params);
|
683
|
+
parser_advance_assert(state, pRPAREN);
|
684
|
+
}
|
685
|
+
|
686
|
+
VALUE block_self_type = parse_self_type_binding(state);
|
687
|
+
|
688
|
+
parser_advance_assert(state, pARROW);
|
689
|
+
VALUE block_return_type = parse_optional(state);
|
690
|
+
|
691
|
+
VALUE block_function = Qnil;
|
692
|
+
if (rbs_is_untyped_params(&block_params)) {
|
693
|
+
block_function = rbs_untyped_function(block_return_type);
|
694
|
+
} else {
|
695
|
+
block_function = rbs_function(
|
696
|
+
block_params.required_positionals,
|
697
|
+
block_params.optional_positionals,
|
698
|
+
block_params.rest_positionals,
|
699
|
+
block_params.trailing_positionals,
|
700
|
+
block_params.required_keywords,
|
701
|
+
block_params.optional_keywords,
|
702
|
+
block_params.rest_keywords,
|
703
|
+
block_return_type
|
704
|
+
);
|
705
|
+
}
|
706
|
+
|
707
|
+
*block = rbs_block(block_function, required, block_self_type);
|
708
|
+
|
709
|
+
parser_advance_assert(state, pRBRACE);
|
710
|
+
}
|
711
|
+
|
712
|
+
parser_advance_assert(state, pARROW);
|
713
|
+
VALUE type = parse_optional(state);
|
714
|
+
|
715
|
+
if (rbs_is_untyped_params(¶ms)) {
|
716
|
+
*function = rbs_untyped_function(type);
|
717
|
+
} else {
|
718
|
+
*function = rbs_function(
|
719
|
+
params.required_positionals,
|
720
|
+
params.optional_positionals,
|
721
|
+
params.rest_positionals,
|
722
|
+
params.trailing_positionals,
|
723
|
+
params.required_keywords,
|
724
|
+
params.optional_keywords,
|
725
|
+
params.rest_keywords,
|
726
|
+
type
|
727
|
+
);
|
728
|
+
}
|
729
|
+
}
|
730
|
+
|
731
|
+
/*
|
732
|
+
proc_type ::= {`^`} <function>
|
733
|
+
*/
|
734
|
+
static VALUE parse_proc_type(parserstate *state) {
|
735
|
+
position start = state->current_token.range.start;
|
736
|
+
VALUE function = Qnil;
|
737
|
+
VALUE block = Qnil;
|
738
|
+
VALUE proc_self = Qnil;
|
739
|
+
parse_function(state, &function, &block, &proc_self);
|
740
|
+
position end = state->current_token.range.end;
|
741
|
+
VALUE loc = rbs_location_pp(state->buffer, &start, &end);
|
742
|
+
|
743
|
+
return rbs_proc(function, block, loc, proc_self);
|
744
|
+
}
|
745
|
+
|
746
|
+
static void check_key_duplication(parserstate *state, VALUE fields, VALUE key) {
|
747
|
+
if (!NIL_P(rb_hash_aref(fields, key))) {
|
748
|
+
raise_syntax_error(
|
749
|
+
state,
|
750
|
+
state->current_token,
|
751
|
+
"duplicated record key"
|
752
|
+
);
|
753
|
+
}
|
754
|
+
}
|
755
|
+
|
756
|
+
/**
|
757
|
+
* ... `{` ... `}` ...
|
758
|
+
* > >
|
759
|
+
* */
|
760
|
+
/*
|
761
|
+
record_attributes ::= {`{`} record_attribute... <record_attribute> `}`
|
762
|
+
|
763
|
+
record_attribute ::= {} keyword_token `:` <type>
|
764
|
+
| {} literal_type `=>` <type>
|
765
|
+
*/
|
766
|
+
static VALUE parse_record_attributes(parserstate *state) {
|
767
|
+
VALUE fields = rb_hash_new();
|
768
|
+
|
769
|
+
if (state->next_token.type == pRBRACE) {
|
770
|
+
return fields;
|
771
|
+
}
|
772
|
+
|
773
|
+
while (true) {
|
774
|
+
VALUE key, type,
|
775
|
+
value = rb_ary_new(),
|
776
|
+
required = Qtrue;
|
777
|
+
|
778
|
+
if (state->next_token.type == pQUESTION) {
|
779
|
+
// { ?foo: type } syntax
|
780
|
+
required = Qfalse;
|
781
|
+
parser_advance(state);
|
782
|
+
}
|
783
|
+
|
784
|
+
if (is_keyword(state)) {
|
785
|
+
// { foo: type } syntax
|
786
|
+
key = parse_keyword_key(state);
|
787
|
+
check_key_duplication(state, fields, key);
|
788
|
+
parser_advance_assert(state, pCOLON);
|
789
|
+
} else {
|
790
|
+
// { key => type } syntax
|
791
|
+
switch (state->next_token.type) {
|
792
|
+
case tSYMBOL:
|
793
|
+
case tSQSYMBOL:
|
794
|
+
case tDQSYMBOL:
|
795
|
+
case tSQSTRING:
|
796
|
+
case tDQSTRING:
|
797
|
+
case tINTEGER:
|
798
|
+
case kTRUE:
|
799
|
+
case kFALSE: {
|
800
|
+
key = rb_funcall(parse_simple(state), rb_intern("literal"), 0);
|
801
|
+
break;
|
802
|
+
}
|
803
|
+
default:
|
804
|
+
raise_syntax_error(
|
805
|
+
state,
|
806
|
+
state->next_token,
|
807
|
+
"unexpected record key token"
|
808
|
+
);
|
809
|
+
}
|
810
|
+
check_key_duplication(state, fields, key);
|
811
|
+
parser_advance_assert(state, pFATARROW);
|
812
|
+
}
|
813
|
+
type = parse_type(state);
|
814
|
+
rb_ary_push(value, type);
|
815
|
+
rb_ary_push(value, required);
|
816
|
+
rb_hash_aset(fields, key, value);
|
817
|
+
|
818
|
+
if (parser_advance_if(state, pCOMMA)) {
|
819
|
+
if (state->next_token.type == pRBRACE) {
|
820
|
+
break;
|
821
|
+
}
|
822
|
+
} else {
|
823
|
+
break;
|
824
|
+
}
|
825
|
+
}
|
826
|
+
return fields;
|
827
|
+
}
|
828
|
+
|
829
|
+
/*
|
830
|
+
symbol ::= {<tSYMBOL>}
|
831
|
+
*/
|
832
|
+
static VALUE parse_symbol(parserstate *state) {
|
833
|
+
VALUE string = state->lexstate->string;
|
834
|
+
rb_encoding *enc = rb_enc_get(string);
|
835
|
+
|
836
|
+
int offset_bytes = rb_enc_codelen(':', enc);
|
837
|
+
int bytes = token_bytes(state->current_token) - offset_bytes;
|
838
|
+
|
839
|
+
VALUE literal;
|
840
|
+
|
841
|
+
switch (state->current_token.type)
|
842
|
+
{
|
843
|
+
case tSYMBOL: {
|
844
|
+
char *buffer = peek_token(state->lexstate, state->current_token);
|
845
|
+
literal = ID2SYM(rb_intern3(buffer+offset_bytes, bytes, enc));
|
846
|
+
break;
|
847
|
+
}
|
848
|
+
case tDQSYMBOL:
|
849
|
+
case tSQSYMBOL: {
|
850
|
+
literal = rb_funcall(
|
851
|
+
rbs_unquote_string(state, state->current_token.range, offset_bytes),
|
852
|
+
rb_intern("to_sym"),
|
853
|
+
0
|
854
|
+
);
|
855
|
+
break;
|
856
|
+
}
|
857
|
+
default:
|
858
|
+
rbs_abort();
|
859
|
+
}
|
860
|
+
|
861
|
+
return rbs_literal(
|
862
|
+
literal,
|
863
|
+
rbs_location_current_token(state)
|
864
|
+
);
|
865
|
+
}
|
866
|
+
|
867
|
+
/*
|
868
|
+
instance_type ::= {type_name} <type_args>
|
869
|
+
|
870
|
+
type_args ::= {} <> /empty/
|
871
|
+
| {} `[` type_list <`]`>
|
872
|
+
*/
|
873
|
+
static VALUE parse_instance_type(parserstate *state, bool parse_alias) {
|
874
|
+
TypeNameKind expected_kind = INTERFACE_NAME | CLASS_NAME;
|
875
|
+
if (parse_alias) {
|
876
|
+
expected_kind |= ALIAS_NAME;
|
877
|
+
}
|
878
|
+
|
879
|
+
range name_range;
|
880
|
+
VALUE typename = parse_type_name(state, expected_kind, &name_range);
|
881
|
+
VALUE types = EMPTY_ARRAY;
|
882
|
+
|
883
|
+
TypeNameKind kind;
|
884
|
+
if (state->current_token.type == tUIDENT) {
|
885
|
+
kind = CLASS_NAME;
|
886
|
+
} else if (state->current_token.type == tULIDENT) {
|
887
|
+
kind = INTERFACE_NAME;
|
888
|
+
} else if (state->current_token.type == tLIDENT) {
|
889
|
+
kind = ALIAS_NAME;
|
890
|
+
} else {
|
891
|
+
rbs_abort();
|
892
|
+
}
|
893
|
+
|
894
|
+
range args_range;
|
895
|
+
if (state->next_token.type == pLBRACKET) {
|
896
|
+
parser_advance(state);
|
897
|
+
args_range.start = state->current_token.range.start;
|
898
|
+
parse_type_list(state, pRBRACKET, &types);
|
899
|
+
parser_advance_assert(state, pRBRACKET);
|
900
|
+
args_range.end = state->current_token.range.end;
|
901
|
+
} else {
|
902
|
+
args_range = NULL_RANGE;
|
903
|
+
}
|
904
|
+
|
905
|
+
range type_range = {
|
906
|
+
.start = name_range.start,
|
907
|
+
.end = nonnull_pos_or(args_range.end, name_range.end),
|
908
|
+
};
|
909
|
+
|
910
|
+
VALUE location = rbs_new_location(state->buffer, type_range);
|
911
|
+
rbs_loc *loc = rbs_check_location(location);
|
912
|
+
rbs_loc_alloc_children(loc, 2);
|
913
|
+
rbs_loc_add_required_child(loc, INTERN("name"), name_range);
|
914
|
+
rbs_loc_add_optional_child(loc, INTERN("args"), args_range);
|
915
|
+
|
916
|
+
if (kind == CLASS_NAME) {
|
917
|
+
return rbs_class_instance(typename, types, location);
|
918
|
+
} else if (kind == INTERFACE_NAME) {
|
919
|
+
return rbs_interface(typename, types, location);
|
920
|
+
} else if (kind == ALIAS_NAME) {
|
921
|
+
return rbs_alias(typename, types, location);
|
922
|
+
} else {
|
923
|
+
return Qnil;
|
924
|
+
}
|
925
|
+
}
|
926
|
+
|
927
|
+
/*
|
928
|
+
singleton_type ::= {`singleton`} `(` type_name <`)`>
|
929
|
+
*/
|
930
|
+
static VALUE parse_singleton_type(parserstate *state) {
|
931
|
+
parser_assert(state, kSINGLETON);
|
932
|
+
|
933
|
+
range type_range;
|
934
|
+
type_range.start = state->current_token.range.start;
|
935
|
+
parser_advance_assert(state, pLPAREN);
|
936
|
+
parser_advance(state);
|
937
|
+
|
938
|
+
range name_range;
|
939
|
+
VALUE typename = parse_type_name(state, CLASS_NAME, &name_range);
|
940
|
+
|
941
|
+
parser_advance_assert(state, pRPAREN);
|
942
|
+
type_range.end = state->current_token.range.end;
|
943
|
+
|
944
|
+
VALUE location = rbs_new_location(state->buffer, type_range);
|
945
|
+
rbs_loc *loc = rbs_check_location(location);
|
946
|
+
rbs_loc_alloc_children(loc, 1);
|
947
|
+
rbs_loc_add_required_child(loc, INTERN("name"), name_range);
|
948
|
+
|
949
|
+
return rbs_class_singleton(typename, location);
|
950
|
+
}
|
951
|
+
|
952
|
+
/*
|
953
|
+
simple ::= {} `(` type <`)`>
|
954
|
+
| {} <base type>
|
955
|
+
| {} <type_name>
|
956
|
+
| {} class_instance `[` type_list <`]`>
|
957
|
+
| {} `singleton` `(` type_name <`)`>
|
958
|
+
| {} `[` type_list <`]`>
|
959
|
+
| {} `{` record_attributes <`}`>
|
960
|
+
| {} `^` <function>
|
961
|
+
*/
|
962
|
+
static VALUE parse_simple(parserstate *state) {
|
963
|
+
parser_advance(state);
|
964
|
+
|
965
|
+
switch (state->current_token.type) {
|
966
|
+
case pLPAREN: {
|
967
|
+
VALUE type = parse_type(state);
|
968
|
+
parser_advance_assert(state, pRPAREN);
|
969
|
+
return type;
|
970
|
+
}
|
971
|
+
case kBOOL: {
|
972
|
+
return rbs_bases_bool(rbs_location_current_token(state));
|
973
|
+
}
|
974
|
+
case kBOT: {
|
975
|
+
return rbs_bases_bottom(rbs_location_current_token(state));
|
976
|
+
}
|
977
|
+
case kCLASS: {
|
978
|
+
return rbs_bases_class(rbs_location_current_token(state));
|
979
|
+
}
|
980
|
+
case kINSTANCE: {
|
981
|
+
return rbs_bases_instance(rbs_location_current_token(state));
|
982
|
+
}
|
983
|
+
case kNIL: {
|
984
|
+
return rbs_bases_nil(rbs_location_current_token(state));
|
985
|
+
}
|
986
|
+
case kSELF: {
|
987
|
+
return rbs_bases_self(rbs_location_current_token(state));
|
988
|
+
}
|
989
|
+
case kTOP: {
|
990
|
+
return rbs_bases_top(rbs_location_current_token(state));
|
991
|
+
}
|
992
|
+
case kVOID: {
|
993
|
+
return rbs_bases_void(rbs_location_current_token(state));
|
994
|
+
}
|
995
|
+
case kUNTYPED: {
|
996
|
+
return rbs_bases_any(false, rbs_location_current_token(state));
|
997
|
+
}
|
998
|
+
case k__TODO__: {
|
999
|
+
return rbs_bases_any(true, rbs_location_current_token(state));
|
1000
|
+
}
|
1001
|
+
case tINTEGER: {
|
1002
|
+
VALUE literal = rb_funcall(
|
1003
|
+
string_of_loc(state, state->current_token.range.start, state->current_token.range.end),
|
1004
|
+
rb_intern("to_i"),
|
1005
|
+
0
|
1006
|
+
);
|
1007
|
+
return rbs_literal(
|
1008
|
+
literal,
|
1009
|
+
rbs_location_current_token(state)
|
1010
|
+
);
|
1011
|
+
}
|
1012
|
+
case kTRUE: {
|
1013
|
+
return rbs_literal(Qtrue, rbs_location_current_token(state));
|
1014
|
+
}
|
1015
|
+
case kFALSE: {
|
1016
|
+
return rbs_literal(Qfalse, rbs_location_current_token(state));
|
1017
|
+
}
|
1018
|
+
case tSQSTRING:
|
1019
|
+
case tDQSTRING: {
|
1020
|
+
VALUE literal = rbs_unquote_string(state, state->current_token.range, 0);
|
1021
|
+
return rbs_literal(
|
1022
|
+
literal,
|
1023
|
+
rbs_location_current_token(state)
|
1024
|
+
);
|
1025
|
+
}
|
1026
|
+
case tSYMBOL:
|
1027
|
+
case tSQSYMBOL:
|
1028
|
+
case tDQSYMBOL: {
|
1029
|
+
return parse_symbol(state);
|
1030
|
+
}
|
1031
|
+
case tUIDENT: {
|
1032
|
+
const char *name_str = peek_token(state->lexstate, state->current_token);
|
1033
|
+
size_t name_len = token_bytes(state->current_token);
|
1034
|
+
|
1035
|
+
rbs_constant_id_t name = rbs_constant_pool_find(&state->constant_pool, (const uint8_t *) name_str, name_len);
|
1036
|
+
|
1037
|
+
if (parser_typevar_member(state, name)) {
|
1038
|
+
ID name = rb_intern3(name_str, name_len, rb_enc_get(state->lexstate->string));
|
1039
|
+
return rbs_variable(ID2SYM(name), rbs_location_current_token(state));
|
1040
|
+
}
|
1041
|
+
// fallthrough for type name
|
1042
|
+
}
|
1043
|
+
case tULIDENT: // fallthrough
|
1044
|
+
case tLIDENT: // fallthrough
|
1045
|
+
case pCOLON2: {
|
1046
|
+
return parse_instance_type(state, true);
|
1047
|
+
}
|
1048
|
+
case kSINGLETON: {
|
1049
|
+
return parse_singleton_type(state);
|
1050
|
+
}
|
1051
|
+
case pLBRACKET: {
|
1052
|
+
range rg;
|
1053
|
+
rg.start = state->current_token.range.start;
|
1054
|
+
VALUE types = EMPTY_ARRAY;
|
1055
|
+
if (state->next_token.type != pRBRACKET) {
|
1056
|
+
parse_type_list(state, pRBRACKET, &types);
|
1057
|
+
}
|
1058
|
+
parser_advance_assert(state, pRBRACKET);
|
1059
|
+
rg.end = state->current_token.range.end;
|
1060
|
+
|
1061
|
+
return rbs_tuple(types, rbs_new_location(state->buffer, rg));
|
1062
|
+
}
|
1063
|
+
case pAREF_OPR: {
|
1064
|
+
return rbs_tuple(EMPTY_ARRAY, rbs_new_location(state->buffer, state->current_token.range));
|
1065
|
+
}
|
1066
|
+
case pLBRACE: {
|
1067
|
+
position start = state->current_token.range.start;
|
1068
|
+
VALUE fields = parse_record_attributes(state);
|
1069
|
+
parser_advance_assert(state, pRBRACE);
|
1070
|
+
position end = state->current_token.range.end;
|
1071
|
+
VALUE location = rbs_location_pp(state->buffer, &start, &end);
|
1072
|
+
return rbs_record(fields, location);
|
1073
|
+
}
|
1074
|
+
case pHAT: {
|
1075
|
+
return parse_proc_type(state);
|
1076
|
+
}
|
1077
|
+
default:
|
1078
|
+
raise_syntax_error(
|
1079
|
+
state,
|
1080
|
+
state->current_token,
|
1081
|
+
"unexpected token for simple type"
|
1082
|
+
);
|
1083
|
+
}
|
1084
|
+
}
|
1085
|
+
|
1086
|
+
/*
|
1087
|
+
intersection ::= {} optional `&` ... '&' <optional>
|
1088
|
+
| {} <optional>
|
1089
|
+
*/
|
1090
|
+
static VALUE parse_intersection(parserstate *state) {
|
1091
|
+
range rg;
|
1092
|
+
rg.start = state->next_token.range.start;
|
1093
|
+
|
1094
|
+
VALUE type = parse_optional(state);
|
1095
|
+
VALUE intersection_types = rb_ary_new();
|
1096
|
+
|
1097
|
+
rb_ary_push(intersection_types, type);
|
1098
|
+
while (state->next_token.type == pAMP) {
|
1099
|
+
parser_advance(state);
|
1100
|
+
rb_ary_push(intersection_types, parse_optional(state));
|
1101
|
+
}
|
1102
|
+
|
1103
|
+
rg.end = state->current_token.range.end;
|
1104
|
+
|
1105
|
+
if (rb_array_len(intersection_types) > 1) {
|
1106
|
+
VALUE location = rbs_new_location(state->buffer, rg);
|
1107
|
+
type = rbs_intersection(intersection_types, location);
|
1108
|
+
}
|
1109
|
+
|
1110
|
+
return type;
|
1111
|
+
}
|
1112
|
+
|
1113
|
+
/*
|
1114
|
+
union ::= {} intersection '|' ... '|' <intersection>
|
1115
|
+
| {} <intersection>
|
1116
|
+
*/
|
1117
|
+
VALUE parse_type(parserstate *state) {
|
1118
|
+
range rg;
|
1119
|
+
rg.start = state->next_token.range.start;
|
1120
|
+
|
1121
|
+
VALUE type = parse_intersection(state);
|
1122
|
+
VALUE union_types = rb_ary_new();
|
1123
|
+
|
1124
|
+
rb_ary_push(union_types, type);
|
1125
|
+
while (state->next_token.type == pBAR) {
|
1126
|
+
parser_advance(state);
|
1127
|
+
rb_ary_push(union_types, parse_intersection(state));
|
1128
|
+
}
|
1129
|
+
|
1130
|
+
rg.end = state->current_token.range.end;
|
1131
|
+
|
1132
|
+
if (rb_array_len(union_types) > 1) {
|
1133
|
+
VALUE location = rbs_new_location(state->buffer, rg);
|
1134
|
+
type = rbs_union(union_types, location);
|
1135
|
+
}
|
1136
|
+
|
1137
|
+
return type;
|
1138
|
+
}
|
1139
|
+
|
1140
|
+
/*
|
1141
|
+
type_params ::= {} `[` type_param `,` ... <`]`>
|
1142
|
+
| {<>}
|
1143
|
+
|
1144
|
+
type_param ::= kUNCHECKED? (kIN|kOUT|) tUIDENT upper_bound? default_type? (module_type_params == true)
|
1145
|
+
|
1146
|
+
type_param ::= tUIDENT upper_bound? default_type? (module_type_params == false)
|
1147
|
+
*/
|
1148
|
+
static VALUE parse_type_params(parserstate *state, range *rg, bool module_type_params) {
|
1149
|
+
VALUE params = EMPTY_ARRAY;
|
1150
|
+
|
1151
|
+
bool required_param_allowed = true;
|
1152
|
+
|
1153
|
+
if (state->next_token.type == pLBRACKET) {
|
1154
|
+
parser_advance(state);
|
1155
|
+
|
1156
|
+
rg->start = state->current_token.range.start;
|
1157
|
+
|
1158
|
+
while (true) {
|
1159
|
+
VALUE unchecked = Qfalse;
|
1160
|
+
VALUE variance = ID2SYM(rb_intern("invariant"));
|
1161
|
+
VALUE upper_bound = Qnil;
|
1162
|
+
VALUE default_type = Qnil;
|
1163
|
+
|
1164
|
+
range param_range;
|
1165
|
+
param_range.start = state->next_token.range.start;
|
1166
|
+
|
1167
|
+
range variance_range = NULL_RANGE;
|
1168
|
+
range unchecked_range = NULL_RANGE;
|
1169
|
+
if (module_type_params) {
|
1170
|
+
if (state->next_token.type == kUNCHECKED) {
|
1171
|
+
unchecked = Qtrue;
|
1172
|
+
parser_advance(state);
|
1173
|
+
unchecked_range = state->current_token.range;
|
1174
|
+
}
|
1175
|
+
|
1176
|
+
if (state->next_token.type == kIN || state->next_token.type == kOUT) {
|
1177
|
+
switch (state->next_token.type) {
|
1178
|
+
case kIN:
|
1179
|
+
variance = ID2SYM(rb_intern("contravariant"));
|
1180
|
+
break;
|
1181
|
+
case kOUT:
|
1182
|
+
variance = ID2SYM(rb_intern("covariant"));
|
1183
|
+
break;
|
1184
|
+
default:
|
1185
|
+
rbs_abort();
|
1186
|
+
}
|
1187
|
+
|
1188
|
+
parser_advance(state);
|
1189
|
+
variance_range = state->current_token.range;
|
1190
|
+
}
|
1191
|
+
}
|
1192
|
+
|
1193
|
+
parser_advance_assert(state, tUIDENT);
|
1194
|
+
range name_range = state->current_token.range;
|
1195
|
+
|
1196
|
+
rbs_constant_id_t id = rbs_constant_pool_insert_shared(
|
1197
|
+
&state->constant_pool,
|
1198
|
+
(const uint8_t *) peek_token(state->lexstate, state->current_token),
|
1199
|
+
token_bytes(state->current_token)
|
1200
|
+
);
|
1201
|
+
|
1202
|
+
VALUE name = ID2SYM(INTERN_TOKEN(state, state->current_token));
|
1203
|
+
|
1204
|
+
parser_insert_typevar(state, id);
|
1205
|
+
|
1206
|
+
range upper_bound_range = NULL_RANGE;
|
1207
|
+
if (state->next_token.type == pLT) {
|
1208
|
+
parser_advance(state);
|
1209
|
+
upper_bound_range.start = state->current_token.range.start;
|
1210
|
+
upper_bound = parse_type(state);
|
1211
|
+
upper_bound_range.end = state->current_token.range.end;
|
1212
|
+
}
|
1213
|
+
|
1214
|
+
range default_type_range = NULL_RANGE;
|
1215
|
+
if (module_type_params) {
|
1216
|
+
if (state->next_token.type == pEQ) {
|
1217
|
+
parser_advance(state);
|
1218
|
+
|
1219
|
+
default_type_range.start = state->current_token.range.start;
|
1220
|
+
default_type = parse_type(state);
|
1221
|
+
default_type_range.end = state->current_token.range.end;
|
1222
|
+
|
1223
|
+
required_param_allowed = false;
|
1224
|
+
} else {
|
1225
|
+
if (!required_param_allowed) {
|
1226
|
+
raise_syntax_error(
|
1227
|
+
state,
|
1228
|
+
state->current_token,
|
1229
|
+
"required type parameter is not allowed after optional type parameter"
|
1230
|
+
);
|
1231
|
+
}
|
1232
|
+
}
|
1233
|
+
}
|
1234
|
+
|
1235
|
+
param_range.end = state->current_token.range.end;
|
1236
|
+
|
1237
|
+
VALUE location = rbs_new_location(state->buffer, param_range);
|
1238
|
+
rbs_loc *loc = rbs_check_location(location);
|
1239
|
+
rbs_loc_alloc_children(loc, 5);
|
1240
|
+
rbs_loc_add_required_child(loc, INTERN("name"), name_range);
|
1241
|
+
rbs_loc_add_optional_child(loc, INTERN("variance"), variance_range);
|
1242
|
+
rbs_loc_add_optional_child(loc, INTERN("unchecked"), unchecked_range);
|
1243
|
+
rbs_loc_add_optional_child(loc, INTERN("upper_bound"), upper_bound_range);
|
1244
|
+
rbs_loc_add_optional_child(loc, INTERN("default"), default_type_range);
|
1245
|
+
|
1246
|
+
VALUE param = rbs_ast_type_param(name, variance, upper_bound, default_type, unchecked, location);
|
1247
|
+
|
1248
|
+
melt_array(¶ms);
|
1249
|
+
rb_ary_push(params, param);
|
1250
|
+
|
1251
|
+
if (state->next_token.type == pCOMMA) {
|
1252
|
+
parser_advance(state);
|
1253
|
+
}
|
1254
|
+
|
1255
|
+
if (state->next_token.type == pRBRACKET) {
|
1256
|
+
break;
|
1257
|
+
}
|
1258
|
+
}
|
1259
|
+
|
1260
|
+
parser_advance_assert(state, pRBRACKET);
|
1261
|
+
rg->end = state->current_token.range.end;
|
1262
|
+
} else {
|
1263
|
+
*rg = NULL_RANGE;
|
1264
|
+
}
|
1265
|
+
|
1266
|
+
rb_funcall(
|
1267
|
+
RBS_AST_TypeParam,
|
1268
|
+
rb_intern("resolve_variables"),
|
1269
|
+
1,
|
1270
|
+
params
|
1271
|
+
);
|
1272
|
+
|
1273
|
+
return params;
|
1274
|
+
}
|
1275
|
+
|
1276
|
+
/*
|
1277
|
+
method_type ::= {} type_params <function>
|
1278
|
+
*/
|
1279
|
+
VALUE parse_method_type(parserstate *state) {
|
1280
|
+
parser_push_typevar_table(state, false);
|
1281
|
+
|
1282
|
+
range rg;
|
1283
|
+
rg.start = state->next_token.range.start;
|
1284
|
+
|
1285
|
+
range params_range = NULL_RANGE;
|
1286
|
+
VALUE type_params = parse_type_params(state, ¶ms_range, false);
|
1287
|
+
|
1288
|
+
range type_range;
|
1289
|
+
type_range.start = state->next_token.range.start;
|
1290
|
+
|
1291
|
+
VALUE function = Qnil;
|
1292
|
+
VALUE block = Qnil;
|
1293
|
+
parse_function(state, &function, &block, NULL);
|
1294
|
+
|
1295
|
+
rg.end = state->current_token.range.end;
|
1296
|
+
type_range.end = rg.end;
|
1297
|
+
|
1298
|
+
parser_pop_typevar_table(state);
|
1299
|
+
|
1300
|
+
VALUE location = rbs_new_location(state->buffer, rg);
|
1301
|
+
rbs_loc *loc = rbs_check_location(location);
|
1302
|
+
rbs_loc_alloc_children(loc, 2);
|
1303
|
+
rbs_loc_add_required_child(loc, INTERN("type"), type_range);
|
1304
|
+
rbs_loc_add_optional_child(loc, INTERN("type_params"), params_range);
|
1305
|
+
|
1306
|
+
return rbs_method_type(
|
1307
|
+
type_params,
|
1308
|
+
function,
|
1309
|
+
block,
|
1310
|
+
location
|
1311
|
+
);
|
1312
|
+
}
|
1313
|
+
|
1314
|
+
/*
|
1315
|
+
global_decl ::= {tGIDENT} `:` <type>
|
1316
|
+
*/
|
1317
|
+
static VALUE parse_global_decl(parserstate *state) {
|
1318
|
+
range decl_range;
|
1319
|
+
decl_range.start = state->current_token.range.start;
|
1320
|
+
|
1321
|
+
VALUE comment = get_comment(state, decl_range.start.line);
|
1322
|
+
range name_range = state->current_token.range;
|
1323
|
+
VALUE typename = ID2SYM(INTERN_TOKEN(state, state->current_token));
|
1324
|
+
|
1325
|
+
parser_advance_assert(state, pCOLON);
|
1326
|
+
range colon_range = state->current_token.range;
|
1327
|
+
|
1328
|
+
VALUE type = parse_type(state);
|
1329
|
+
decl_range.end = state->current_token.range.end;
|
1330
|
+
|
1331
|
+
VALUE location = rbs_new_location(state->buffer, decl_range);
|
1332
|
+
rbs_loc *loc = rbs_check_location(location);
|
1333
|
+
rbs_loc_alloc_children(loc, 2);
|
1334
|
+
rbs_loc_add_required_child(loc, INTERN("name"), name_range);
|
1335
|
+
rbs_loc_add_required_child(loc, INTERN("colon"), colon_range);
|
1336
|
+
|
1337
|
+
return rbs_ast_decl_global(typename, type, location, comment);
|
1338
|
+
}
|
1339
|
+
|
1340
|
+
/*
|
1341
|
+
const_decl ::= {const_name} `:` <type>
|
1342
|
+
*/
|
1343
|
+
static VALUE parse_const_decl(parserstate *state) {
|
1344
|
+
range decl_range;
|
1345
|
+
|
1346
|
+
decl_range.start = state->current_token.range.start;
|
1347
|
+
VALUE comment = get_comment(state, decl_range.start.line);
|
1348
|
+
|
1349
|
+
range name_range;
|
1350
|
+
VALUE typename = parse_type_name(state, CLASS_NAME, &name_range);
|
1351
|
+
|
1352
|
+
parser_advance_assert(state, pCOLON);
|
1353
|
+
range colon_range = state->current_token.range;
|
1354
|
+
|
1355
|
+
VALUE type = parse_type(state);
|
1356
|
+
decl_range.end = state->current_token.range.end;
|
1357
|
+
|
1358
|
+
VALUE location = rbs_new_location(state->buffer, decl_range);
|
1359
|
+
rbs_loc *loc = rbs_check_location(location);
|
1360
|
+
rbs_loc_alloc_children(loc, 2);
|
1361
|
+
rbs_loc_add_required_child(loc, INTERN("name"), name_range);
|
1362
|
+
rbs_loc_add_required_child(loc, INTERN("colon"), colon_range);
|
1363
|
+
|
1364
|
+
return rbs_ast_decl_constant(typename, type, location, comment);
|
1365
|
+
}
|
1366
|
+
|
1367
|
+
/*
|
1368
|
+
type_decl ::= {kTYPE} alias_name `=` <type>
|
1369
|
+
*/
|
1370
|
+
static VALUE parse_type_decl(parserstate *state, position comment_pos, VALUE annotations) {
|
1371
|
+
parser_push_typevar_table(state, true);
|
1372
|
+
|
1373
|
+
range decl_range;
|
1374
|
+
decl_range.start = state->current_token.range.start;
|
1375
|
+
comment_pos = nonnull_pos_or(comment_pos, decl_range.start);
|
1376
|
+
|
1377
|
+
range keyword_range = state->current_token.range;
|
1378
|
+
|
1379
|
+
parser_advance(state);
|
1380
|
+
|
1381
|
+
range name_range;
|
1382
|
+
VALUE typename = parse_type_name(state, ALIAS_NAME, &name_range);
|
1383
|
+
|
1384
|
+
range params_range;
|
1385
|
+
VALUE type_params = parse_type_params(state, ¶ms_range, true);
|
1386
|
+
|
1387
|
+
parser_advance_assert(state, pEQ);
|
1388
|
+
range eq_range = state->current_token.range;
|
1389
|
+
|
1390
|
+
VALUE type = parse_type(state);
|
1391
|
+
decl_range.end = state->current_token.range.end;
|
1392
|
+
|
1393
|
+
VALUE location = rbs_new_location(state->buffer, decl_range);
|
1394
|
+
rbs_loc *loc = rbs_check_location(location);
|
1395
|
+
rbs_loc_alloc_children(loc, 4);
|
1396
|
+
rbs_loc_add_required_child(loc, INTERN("keyword"), keyword_range);
|
1397
|
+
rbs_loc_add_required_child(loc, INTERN("name"), name_range);
|
1398
|
+
rbs_loc_add_optional_child(loc, INTERN("type_params"), params_range);
|
1399
|
+
rbs_loc_add_required_child(loc, INTERN("eq"), eq_range);
|
1400
|
+
|
1401
|
+
parser_pop_typevar_table(state);
|
1402
|
+
|
1403
|
+
return rbs_ast_decl_type_alias(
|
1404
|
+
typename,
|
1405
|
+
type_params,
|
1406
|
+
type,
|
1407
|
+
annotations,
|
1408
|
+
location,
|
1409
|
+
get_comment(state, comment_pos.line)
|
1410
|
+
);
|
1411
|
+
}
|
1412
|
+
|
1413
|
+
/*
|
1414
|
+
annotation ::= {<tANNOTATION>}
|
1415
|
+
*/
|
1416
|
+
static VALUE parse_annotation(parserstate *state) {
|
1417
|
+
VALUE content = rb_funcall(state->buffer, rb_intern("content"), 0);
|
1418
|
+
rb_encoding *enc = rb_enc_get(content);
|
1419
|
+
|
1420
|
+
range rg = state->current_token.range;
|
1421
|
+
|
1422
|
+
int offset_bytes = rb_enc_codelen('%', enc) + rb_enc_codelen('a', enc);
|
1423
|
+
|
1424
|
+
unsigned int open_char = rb_enc_mbc_to_codepoint(
|
1425
|
+
RSTRING_PTR(state->lexstate->string) + rg.start.byte_pos + offset_bytes,
|
1426
|
+
RSTRING_END(state->lexstate->string),
|
1427
|
+
enc
|
1428
|
+
);
|
1429
|
+
|
1430
|
+
unsigned int close_char;
|
1431
|
+
|
1432
|
+
switch (open_char) {
|
1433
|
+
case '{':
|
1434
|
+
close_char = '}';
|
1435
|
+
break;
|
1436
|
+
case '(':
|
1437
|
+
close_char = ')';
|
1438
|
+
break;
|
1439
|
+
case '[':
|
1440
|
+
close_char = ']';
|
1441
|
+
break;
|
1442
|
+
case '<':
|
1443
|
+
close_char = '>';
|
1444
|
+
break;
|
1445
|
+
case '|':
|
1446
|
+
close_char = '|';
|
1447
|
+
break;
|
1448
|
+
default:
|
1449
|
+
rbs_abort();
|
1450
|
+
}
|
1451
|
+
|
1452
|
+
int open_bytes = rb_enc_codelen(open_char, enc);
|
1453
|
+
int close_bytes = rb_enc_codelen(close_char, enc);
|
1454
|
+
|
1455
|
+
char *buffer = RSTRING_PTR(state->lexstate->string) + rg.start.byte_pos + offset_bytes + open_bytes;
|
1456
|
+
VALUE string = rb_enc_str_new(
|
1457
|
+
buffer,
|
1458
|
+
rg.end.byte_pos - rg.start.byte_pos - offset_bytes - open_bytes - close_bytes,
|
1459
|
+
enc
|
1460
|
+
);
|
1461
|
+
rb_funcall(string, rb_intern("strip!"), 0);
|
1462
|
+
|
1463
|
+
VALUE location = rbs_location_current_token(state);
|
1464
|
+
|
1465
|
+
return rbs_ast_annotation(string, location);
|
1466
|
+
}
|
1467
|
+
|
1468
|
+
/*
|
1469
|
+
annotations ::= {} annotation ... <annotation>
|
1470
|
+
| {<>}
|
1471
|
+
*/
|
1472
|
+
static void parse_annotations(parserstate *state, VALUE *annotations, position *annot_pos) {
|
1473
|
+
*annot_pos = NullPosition;
|
1474
|
+
|
1475
|
+
while (true) {
|
1476
|
+
if (state->next_token.type == tANNOTATION) {
|
1477
|
+
parser_advance(state);
|
1478
|
+
|
1479
|
+
if (null_position_p((*annot_pos))) {
|
1480
|
+
*annot_pos = state->current_token.range.start;
|
1481
|
+
}
|
1482
|
+
|
1483
|
+
melt_array(annotations);
|
1484
|
+
rb_ary_push(*annotations, parse_annotation(state));
|
1485
|
+
} else {
|
1486
|
+
break;
|
1487
|
+
}
|
1488
|
+
}
|
1489
|
+
}
|
1490
|
+
|
1491
|
+
/*
|
1492
|
+
method_name ::= {} <IDENT | keyword>
|
1493
|
+
| {} (IDENT | keyword)~<`?`>
|
1494
|
+
*/
|
1495
|
+
static VALUE parse_method_name(parserstate *state, range *range) {
|
1496
|
+
parser_advance(state);
|
1497
|
+
|
1498
|
+
switch (state->current_token.type)
|
1499
|
+
{
|
1500
|
+
case tUIDENT:
|
1501
|
+
case tLIDENT:
|
1502
|
+
case tULIDENT:
|
1503
|
+
case tULLIDENT:
|
1504
|
+
KEYWORD_CASES
|
1505
|
+
if (state->next_token.type == pQUESTION && state->current_token.range.end.byte_pos == state->next_token.range.start.byte_pos) {
|
1506
|
+
range->start = state->current_token.range.start;
|
1507
|
+
range->end = state->next_token.range.end;
|
1508
|
+
parser_advance(state);
|
1509
|
+
|
1510
|
+
ID id = rb_intern3(
|
1511
|
+
RSTRING_PTR(state->lexstate->string) + range->start.byte_pos,
|
1512
|
+
range->end.byte_pos - range->start.byte_pos,
|
1513
|
+
rb_enc_get(state->lexstate->string)
|
1514
|
+
);
|
1515
|
+
|
1516
|
+
return ID2SYM(id);
|
1517
|
+
} else {
|
1518
|
+
*range = state->current_token.range;
|
1519
|
+
return ID2SYM(INTERN_TOKEN(state, state->current_token));
|
1520
|
+
}
|
1521
|
+
|
1522
|
+
case tBANGIDENT:
|
1523
|
+
case tEQIDENT:
|
1524
|
+
*range = state->current_token.range;
|
1525
|
+
return ID2SYM(INTERN_TOKEN(state, state->current_token));
|
1526
|
+
|
1527
|
+
case tQIDENT: {
|
1528
|
+
return rb_to_symbol(rbs_unquote_string(state, state->current_token.range, 0));
|
1529
|
+
}
|
1530
|
+
|
1531
|
+
case pBAR:
|
1532
|
+
case pHAT:
|
1533
|
+
case pAMP:
|
1534
|
+
case pSTAR:
|
1535
|
+
case pSTAR2:
|
1536
|
+
case pLT:
|
1537
|
+
case pAREF_OPR:
|
1538
|
+
case tOPERATOR:
|
1539
|
+
*range = state->current_token.range;
|
1540
|
+
return ID2SYM(INTERN_TOKEN(state, state->current_token));
|
1541
|
+
|
1542
|
+
default:
|
1543
|
+
raise_syntax_error(
|
1544
|
+
state,
|
1545
|
+
state->current_token,
|
1546
|
+
"unexpected token for method name"
|
1547
|
+
);
|
1548
|
+
}
|
1549
|
+
}
|
1550
|
+
|
1551
|
+
typedef enum {
|
1552
|
+
INSTANCE_KIND,
|
1553
|
+
SINGLETON_KIND,
|
1554
|
+
INSTANCE_SINGLETON_KIND
|
1555
|
+
} InstanceSingletonKind;
|
1556
|
+
|
1557
|
+
/*
|
1558
|
+
instance_singleton_kind ::= {<>}
|
1559
|
+
| {} kSELF <`.`>
|
1560
|
+
| {} kSELF~`?` <`.`>
|
1561
|
+
|
1562
|
+
@param allow_selfq `true` to accept `self?` kind.
|
1563
|
+
*/
|
1564
|
+
static InstanceSingletonKind parse_instance_singleton_kind(parserstate *state, bool allow_selfq, range *rg) {
|
1565
|
+
InstanceSingletonKind kind = INSTANCE_KIND;
|
1566
|
+
|
1567
|
+
if (state->next_token.type == kSELF) {
|
1568
|
+
range self_range = state->next_token.range;
|
1569
|
+
|
1570
|
+
if (state->next_token2.type == pDOT) {
|
1571
|
+
parser_advance(state);
|
1572
|
+
parser_advance(state);
|
1573
|
+
kind = SINGLETON_KIND;
|
1574
|
+
} else if (
|
1575
|
+
state->next_token2.type == pQUESTION
|
1576
|
+
&& state->next_token.range.end.char_pos == state->next_token2.range.start.char_pos
|
1577
|
+
&& state->next_token3.type == pDOT
|
1578
|
+
&& allow_selfq) {
|
1579
|
+
parser_advance(state);
|
1580
|
+
parser_advance(state);
|
1581
|
+
parser_advance(state);
|
1582
|
+
kind = INSTANCE_SINGLETON_KIND;
|
1583
|
+
}
|
1584
|
+
|
1585
|
+
*rg = (range) {
|
1586
|
+
.start = self_range.start,
|
1587
|
+
.end = state->current_token.range.end,
|
1588
|
+
};
|
1589
|
+
} else {
|
1590
|
+
*rg = NULL_RANGE;
|
1591
|
+
}
|
1592
|
+
|
1593
|
+
return kind;
|
1594
|
+
}
|
1595
|
+
|
1596
|
+
/**
|
1597
|
+
* def_member ::= {kDEF} method_name `:` <method_types>
|
1598
|
+
* | {kPRIVATE} kDEF method_name `:` <method_types>
|
1599
|
+
* | {kPUBLIC} kDEF method_name `:` <method_types>
|
1600
|
+
*
|
1601
|
+
* method_types ::= {} <method_type>
|
1602
|
+
* | {} <`...`>
|
1603
|
+
* | {} method_type `|` <method_types>
|
1604
|
+
*
|
1605
|
+
* @param instance_only `true` to reject singleton method definition.
|
1606
|
+
* @param accept_overload `true` to accept overloading (...) definition.
|
1607
|
+
* */
|
1608
|
+
static VALUE parse_member_def(parserstate *state, bool instance_only, bool accept_overload, position comment_pos, VALUE annotations) {
|
1609
|
+
range member_range;
|
1610
|
+
member_range.start = state->current_token.range.start;
|
1611
|
+
comment_pos = nonnull_pos_or(comment_pos, member_range.start);
|
1612
|
+
|
1613
|
+
VALUE comment = get_comment(state, comment_pos.line);
|
1614
|
+
|
1615
|
+
range visibility_range;
|
1616
|
+
VALUE visibility;
|
1617
|
+
switch (state->current_token.type)
|
1618
|
+
{
|
1619
|
+
case kPRIVATE: {
|
1620
|
+
visibility_range = state->current_token.range;
|
1621
|
+
visibility = ID2SYM(rb_intern("private"));
|
1622
|
+
member_range.start = visibility_range.start;
|
1623
|
+
parser_advance(state);
|
1624
|
+
break;
|
1625
|
+
}
|
1626
|
+
case kPUBLIC: {
|
1627
|
+
visibility_range = state->current_token.range;
|
1628
|
+
visibility = ID2SYM(rb_intern("public"));
|
1629
|
+
member_range.start = visibility_range.start;
|
1630
|
+
parser_advance(state);
|
1631
|
+
break;
|
1632
|
+
}
|
1633
|
+
default:
|
1634
|
+
visibility_range = NULL_RANGE;
|
1635
|
+
visibility = Qnil;
|
1636
|
+
break;
|
1637
|
+
}
|
1638
|
+
|
1639
|
+
range keyword_range = state->current_token.range;
|
1640
|
+
|
1641
|
+
range kind_range;
|
1642
|
+
InstanceSingletonKind kind;
|
1643
|
+
if (instance_only) {
|
1644
|
+
kind_range = NULL_RANGE;
|
1645
|
+
kind = INSTANCE_KIND;
|
1646
|
+
} else {
|
1647
|
+
kind = parse_instance_singleton_kind(state, NIL_P(visibility), &kind_range);
|
1648
|
+
}
|
1649
|
+
|
1650
|
+
range name_range;
|
1651
|
+
VALUE name = parse_method_name(state, &name_range);
|
1652
|
+
VALUE overloads = rb_ary_new();
|
1653
|
+
VALUE overloading = Qfalse;
|
1654
|
+
|
1655
|
+
if (state->next_token.type == pDOT && RB_SYM2ID(name) == rb_intern("self?")) {
|
1656
|
+
raise_syntax_error(
|
1657
|
+
state,
|
1658
|
+
state->next_token,
|
1659
|
+
"`self?` method cannot have visibility"
|
1660
|
+
);
|
1661
|
+
} else {
|
1662
|
+
parser_advance_assert(state, pCOLON);
|
1663
|
+
}
|
1664
|
+
|
1665
|
+
parser_push_typevar_table(state, kind != INSTANCE_KIND);
|
1666
|
+
|
1667
|
+
range overloading_range = NULL_RANGE;
|
1668
|
+
bool loop = true;
|
1669
|
+
while (loop) {
|
1670
|
+
VALUE annotations = EMPTY_ARRAY;
|
1671
|
+
position overload_annot_pos = NullPosition;
|
1672
|
+
|
1673
|
+
if (state->next_token.type == tANNOTATION) {
|
1674
|
+
parse_annotations(state, &annotations, &overload_annot_pos);
|
1675
|
+
}
|
1676
|
+
|
1677
|
+
switch (state->next_token.type) {
|
1678
|
+
case pLPAREN:
|
1679
|
+
case pARROW:
|
1680
|
+
case pLBRACE:
|
1681
|
+
case pLBRACKET:
|
1682
|
+
case pQUESTION:
|
1683
|
+
{
|
1684
|
+
VALUE method_type = parse_method_type(state);
|
1685
|
+
rb_ary_push(overloads, rbs_ast_members_method_definition_overload(annotations, method_type));
|
1686
|
+
member_range.end = state->current_token.range.end;
|
1687
|
+
break;
|
1688
|
+
}
|
1689
|
+
|
1690
|
+
case pDOT3:
|
1691
|
+
if (accept_overload) {
|
1692
|
+
overloading = Qtrue;
|
1693
|
+
parser_advance(state);
|
1694
|
+
loop = false;
|
1695
|
+
overloading_range = state->current_token.range;
|
1696
|
+
member_range.end = overloading_range.end;
|
1697
|
+
break;
|
1698
|
+
} else {
|
1699
|
+
raise_syntax_error(
|
1700
|
+
state,
|
1701
|
+
state->next_token,
|
1702
|
+
"unexpected overloading method definition"
|
1703
|
+
);
|
1704
|
+
}
|
1705
|
+
|
1706
|
+
default:
|
1707
|
+
raise_syntax_error(
|
1708
|
+
state,
|
1709
|
+
state->next_token,
|
1710
|
+
"unexpected token for method type"
|
1711
|
+
);
|
1712
|
+
}
|
1713
|
+
|
1714
|
+
if (state->next_token.type == pBAR) {
|
1715
|
+
parser_advance(state);
|
1716
|
+
} else {
|
1717
|
+
loop = false;
|
1718
|
+
}
|
1719
|
+
}
|
1720
|
+
|
1721
|
+
parser_pop_typevar_table(state);
|
1722
|
+
|
1723
|
+
VALUE k;
|
1724
|
+
switch (kind) {
|
1725
|
+
case INSTANCE_KIND:
|
1726
|
+
k = ID2SYM(rb_intern("instance"));
|
1727
|
+
break;
|
1728
|
+
case SINGLETON_KIND:
|
1729
|
+
k = ID2SYM(rb_intern("singleton"));
|
1730
|
+
break;
|
1731
|
+
case INSTANCE_SINGLETON_KIND:
|
1732
|
+
k = ID2SYM(rb_intern("singleton_instance"));
|
1733
|
+
break;
|
1734
|
+
default:
|
1735
|
+
rbs_abort();
|
1736
|
+
}
|
1737
|
+
|
1738
|
+
VALUE location = rbs_new_location(state->buffer, member_range);
|
1739
|
+
rbs_loc *loc = rbs_check_location(location);
|
1740
|
+
rbs_loc_alloc_children(loc, 5);
|
1741
|
+
rbs_loc_add_required_child(loc, INTERN("keyword"), keyword_range);
|
1742
|
+
rbs_loc_add_required_child(loc, INTERN("name"), name_range);
|
1743
|
+
rbs_loc_add_optional_child(loc, INTERN("kind"), kind_range);
|
1744
|
+
rbs_loc_add_optional_child(loc, INTERN("overloading"), overloading_range);
|
1745
|
+
rbs_loc_add_optional_child(loc, INTERN("visibility"), visibility_range);
|
1746
|
+
|
1747
|
+
return rbs_ast_members_method_definition(
|
1748
|
+
name,
|
1749
|
+
k,
|
1750
|
+
overloads,
|
1751
|
+
annotations,
|
1752
|
+
location,
|
1753
|
+
comment,
|
1754
|
+
overloading,
|
1755
|
+
visibility
|
1756
|
+
);
|
1757
|
+
}
|
1758
|
+
|
1759
|
+
/**
|
1760
|
+
* class_instance_name ::= {} <class_name>
|
1761
|
+
* | {} class_name `[` type args <`]`>
|
1762
|
+
*
|
1763
|
+
* @param kind
|
1764
|
+
* */
|
1765
|
+
void class_instance_name(parserstate *state, TypeNameKind kind, VALUE *name, VALUE *args, range *name_range, range *args_range) {
|
1766
|
+
parser_advance(state);
|
1767
|
+
|
1768
|
+
*name = parse_type_name(state, kind, name_range);
|
1769
|
+
|
1770
|
+
if (state->next_token.type == pLBRACKET) {
|
1771
|
+
parser_advance(state);
|
1772
|
+
args_range->start = state->current_token.range.start;
|
1773
|
+
parse_type_list(state, pRBRACKET, args);
|
1774
|
+
parser_advance_assert(state, pRBRACKET);
|
1775
|
+
args_range->end = state->current_token.range.end;
|
1776
|
+
} else {
|
1777
|
+
*args_range = NULL_RANGE;
|
1778
|
+
}
|
1779
|
+
}
|
1780
|
+
|
1781
|
+
/**
|
1782
|
+
* mixin_member ::= {kINCLUDE} <class_instance_name>
|
1783
|
+
* | {kPREPEND} <class_instance_name>
|
1784
|
+
* | {kEXTEND} <class_instance_name>
|
1785
|
+
*
|
1786
|
+
* @param from_interface `true` when the member is in an interface.
|
1787
|
+
* */
|
1788
|
+
static VALUE parse_mixin_member(parserstate *state, bool from_interface, position comment_pos, VALUE annotations) {
|
1789
|
+
range member_range;
|
1790
|
+
member_range.start = state->current_token.range.start;
|
1791
|
+
comment_pos = nonnull_pos_or(comment_pos, member_range.start);
|
1792
|
+
|
1793
|
+
enum TokenType type = state->current_token.type;
|
1794
|
+
range keyword_range = state->current_token.range;
|
1795
|
+
|
1796
|
+
bool reset_typevar_scope;
|
1797
|
+
switch (type)
|
1798
|
+
{
|
1799
|
+
case kINCLUDE:
|
1800
|
+
reset_typevar_scope = false;
|
1801
|
+
break;
|
1802
|
+
case kEXTEND:
|
1803
|
+
reset_typevar_scope = true;
|
1804
|
+
break;
|
1805
|
+
case kPREPEND:
|
1806
|
+
reset_typevar_scope = false;
|
1807
|
+
break;
|
1808
|
+
default:
|
1809
|
+
rbs_abort();
|
1810
|
+
}
|
1811
|
+
|
1812
|
+
if (from_interface) {
|
1813
|
+
if (state->current_token.type != kINCLUDE) {
|
1814
|
+
raise_syntax_error(
|
1815
|
+
state,
|
1816
|
+
state->current_token,
|
1817
|
+
"unexpected mixin in interface declaration"
|
1818
|
+
);
|
1819
|
+
}
|
1820
|
+
}
|
1821
|
+
|
1822
|
+
parser_push_typevar_table(state, reset_typevar_scope);
|
1823
|
+
|
1824
|
+
VALUE name;
|
1825
|
+
VALUE args = EMPTY_ARRAY;
|
1826
|
+
range name_range;
|
1827
|
+
range args_range = NULL_RANGE;
|
1828
|
+
class_instance_name(
|
1829
|
+
state,
|
1830
|
+
from_interface ? INTERFACE_NAME : (INTERFACE_NAME | CLASS_NAME),
|
1831
|
+
&name, &args, &name_range, &args_range
|
1832
|
+
);
|
1833
|
+
|
1834
|
+
parser_pop_typevar_table(state);
|
1835
|
+
|
1836
|
+
member_range.end = state->current_token.range.end;
|
1837
|
+
|
1838
|
+
VALUE location = rbs_new_location(state->buffer, member_range);
|
1839
|
+
rbs_loc *loc = rbs_check_location(location);
|
1840
|
+
rbs_loc_alloc_children(loc, 3);
|
1841
|
+
rbs_loc_add_required_child(loc, INTERN("name"), name_range);
|
1842
|
+
rbs_loc_add_required_child(loc, INTERN("keyword"), keyword_range);
|
1843
|
+
rbs_loc_add_optional_child(loc, INTERN("args"), args_range);
|
1844
|
+
|
1845
|
+
VALUE comment = get_comment(state, comment_pos.line);
|
1846
|
+
switch (type)
|
1847
|
+
{
|
1848
|
+
case kINCLUDE:
|
1849
|
+
return rbs_ast_members_include(name, args, annotations, location, comment);
|
1850
|
+
case kEXTEND:
|
1851
|
+
return rbs_ast_members_extend(name, args, annotations, location, comment);
|
1852
|
+
case kPREPEND:
|
1853
|
+
return rbs_ast_members_prepend(name, args, annotations, location, comment);
|
1854
|
+
default:
|
1855
|
+
rbs_abort();
|
1856
|
+
}
|
1857
|
+
}
|
1858
|
+
|
1859
|
+
/**
|
1860
|
+
* @code
|
1861
|
+
* alias_member ::= {kALIAS} method_name <method_name>
|
1862
|
+
* | {kALIAS} kSELF `.` method_name kSELF `.` <method_name>
|
1863
|
+
* @endcode
|
1864
|
+
*
|
1865
|
+
* @param[in] instance_only `true` to reject `self.` alias.
|
1866
|
+
* */
|
1867
|
+
static VALUE parse_alias_member(parserstate *state, bool instance_only, position comment_pos, VALUE annotations) {
|
1868
|
+
range member_range;
|
1869
|
+
member_range.start = state->current_token.range.start;
|
1870
|
+
range keyword_range = state->current_token.range;
|
1871
|
+
|
1872
|
+
comment_pos = nonnull_pos_or(comment_pos, member_range.start);
|
1873
|
+
VALUE comment = get_comment(state, comment_pos.line);
|
1874
|
+
|
1875
|
+
VALUE kind, new_name, old_name;
|
1876
|
+
range new_kind_range, old_kind_range, new_name_range, old_name_range;
|
1877
|
+
if (!instance_only && state->next_token.type == kSELF) {
|
1878
|
+
kind = ID2SYM(rb_intern("singleton"));
|
1879
|
+
|
1880
|
+
new_kind_range.start = state->next_token.range.start;
|
1881
|
+
new_kind_range.end = state->next_token2.range.end;
|
1882
|
+
parser_advance_assert(state, kSELF);
|
1883
|
+
parser_advance_assert(state, pDOT);
|
1884
|
+
new_name = parse_method_name(state, &new_name_range);
|
1885
|
+
|
1886
|
+
old_kind_range.start = state->next_token.range.start;
|
1887
|
+
old_kind_range.end = state->next_token2.range.end;
|
1888
|
+
parser_advance_assert(state, kSELF);
|
1889
|
+
parser_advance_assert(state, pDOT);
|
1890
|
+
old_name = parse_method_name(state, &old_name_range);
|
1891
|
+
} else {
|
1892
|
+
kind = ID2SYM(rb_intern("instance"));
|
1893
|
+
new_name = parse_method_name(state, &new_name_range);
|
1894
|
+
old_name = parse_method_name(state, &old_name_range);
|
1895
|
+
|
1896
|
+
new_kind_range = NULL_RANGE;
|
1897
|
+
old_kind_range = NULL_RANGE;
|
1898
|
+
}
|
1899
|
+
|
1900
|
+
member_range.end = state->current_token.range.end;
|
1901
|
+
VALUE location = rbs_new_location(state->buffer, member_range);
|
1902
|
+
rbs_loc *loc = rbs_check_location(location);
|
1903
|
+
rbs_loc_alloc_children(loc, 5);
|
1904
|
+
rbs_loc_add_required_child(loc, INTERN("keyword"), keyword_range);
|
1905
|
+
rbs_loc_add_required_child(loc, INTERN("new_name"), new_name_range);
|
1906
|
+
rbs_loc_add_required_child(loc, INTERN("old_name"), old_name_range);
|
1907
|
+
rbs_loc_add_optional_child(loc, INTERN("new_kind"), new_kind_range);
|
1908
|
+
rbs_loc_add_optional_child(loc, INTERN("old_kind"), old_kind_range);
|
1909
|
+
|
1910
|
+
return rbs_ast_members_alias(
|
1911
|
+
new_name,
|
1912
|
+
old_name,
|
1913
|
+
kind,
|
1914
|
+
annotations,
|
1915
|
+
location,
|
1916
|
+
comment
|
1917
|
+
);
|
1918
|
+
}
|
1919
|
+
|
1920
|
+
/*
|
1921
|
+
variable_member ::= {tAIDENT} `:` <type>
|
1922
|
+
| {kSELF} `.` tAIDENT `:` <type>
|
1923
|
+
| {tA2IDENT} `:` <type>
|
1924
|
+
*/
|
1925
|
+
static VALUE parse_variable_member(parserstate *state, position comment_pos, VALUE annotations) {
|
1926
|
+
if (rb_array_len(annotations) > 0) {
|
1927
|
+
raise_syntax_error(
|
1928
|
+
state,
|
1929
|
+
state->current_token,
|
1930
|
+
"annotation cannot be given to variable members"
|
1931
|
+
);
|
1932
|
+
}
|
1933
|
+
|
1934
|
+
range member_range;
|
1935
|
+
member_range.start = state->current_token.range.start;
|
1936
|
+
comment_pos = nonnull_pos_or(comment_pos, member_range.start);
|
1937
|
+
VALUE comment = get_comment(state, comment_pos.line);
|
1938
|
+
|
1939
|
+
switch (state->current_token.type)
|
1940
|
+
{
|
1941
|
+
case tAIDENT: {
|
1942
|
+
range name_range = state->current_token.range;
|
1943
|
+
VALUE name = ID2SYM(INTERN_TOKEN(state, state->current_token));
|
1944
|
+
|
1945
|
+
parser_advance_assert(state, pCOLON);
|
1946
|
+
range colon_range = state->current_token.range;
|
1947
|
+
|
1948
|
+
VALUE type = parse_type(state);
|
1949
|
+
member_range.end = state->current_token.range.end;
|
1950
|
+
|
1951
|
+
VALUE location = rbs_new_location(state->buffer, member_range);
|
1952
|
+
rbs_loc *loc = rbs_check_location(location);
|
1953
|
+
rbs_loc_alloc_children(loc, 3);
|
1954
|
+
rbs_loc_add_required_child(loc, INTERN("name"), name_range);
|
1955
|
+
rbs_loc_add_required_child(loc, INTERN("colon"), colon_range);
|
1956
|
+
rbs_loc_add_optional_child(loc, INTERN("kind"), NULL_RANGE);
|
1957
|
+
|
1958
|
+
return rbs_ast_members_instance_variable(name, type, location, comment);
|
1959
|
+
}
|
1960
|
+
case tA2IDENT: {
|
1961
|
+
range name_range = state->current_token.range;
|
1962
|
+
VALUE name = ID2SYM(INTERN_TOKEN(state, state->current_token));
|
1963
|
+
|
1964
|
+
parser_advance_assert(state, pCOLON);
|
1965
|
+
range colon_range = state->current_token.range;
|
1966
|
+
|
1967
|
+
parser_push_typevar_table(state, true);
|
1968
|
+
VALUE type = parse_type(state);
|
1969
|
+
parser_pop_typevar_table(state);
|
1970
|
+
member_range.end = state->current_token.range.end;
|
1971
|
+
|
1972
|
+
VALUE location = rbs_new_location(state->buffer, member_range);
|
1973
|
+
rbs_loc *loc = rbs_check_location(location);
|
1974
|
+
rbs_loc_alloc_children(loc, 3);
|
1975
|
+
rbs_loc_add_required_child(loc, INTERN("name"), name_range);
|
1976
|
+
rbs_loc_add_required_child(loc, INTERN("colon"), colon_range);
|
1977
|
+
rbs_loc_add_optional_child(loc, INTERN("kind"), NULL_RANGE);
|
1978
|
+
|
1979
|
+
return rbs_ast_members_class_variable(name, type, location, comment);
|
1980
|
+
}
|
1981
|
+
case kSELF: {
|
1982
|
+
range kind_range = {
|
1983
|
+
.start = state->current_token.range.start,
|
1984
|
+
.end = state->next_token.range.end
|
1985
|
+
};
|
1986
|
+
|
1987
|
+
parser_advance_assert(state, pDOT);
|
1988
|
+
parser_advance_assert(state, tAIDENT);
|
1989
|
+
|
1990
|
+
range name_range = state->current_token.range;
|
1991
|
+
VALUE name = ID2SYM(INTERN_TOKEN(state, state->current_token));
|
1992
|
+
|
1993
|
+
parser_advance_assert(state, pCOLON);
|
1994
|
+
range colon_range = state->current_token.range;
|
1995
|
+
|
1996
|
+
parser_push_typevar_table(state, true);
|
1997
|
+
VALUE type = parse_type(state);
|
1998
|
+
parser_pop_typevar_table(state);
|
1999
|
+
member_range.end = state->current_token.range.end;
|
2000
|
+
|
2001
|
+
VALUE location = rbs_new_location(state->buffer, member_range);
|
2002
|
+
rbs_loc *loc = rbs_check_location(location);
|
2003
|
+
rbs_loc_alloc_children(loc, 3);
|
2004
|
+
rbs_loc_add_required_child(loc, INTERN("name"), name_range);
|
2005
|
+
rbs_loc_add_required_child(loc, INTERN("colon"), colon_range);
|
2006
|
+
rbs_loc_add_optional_child(loc, INTERN("kind"), kind_range);
|
2007
|
+
|
2008
|
+
return rbs_ast_members_class_instance_variable(name, type, location, comment);
|
2009
|
+
}
|
2010
|
+
default:
|
2011
|
+
rbs_abort();
|
2012
|
+
}
|
2013
|
+
}
|
2014
|
+
|
2015
|
+
/*
|
2016
|
+
visibility_member ::= {<`public`>}
|
2017
|
+
| {<`private`>}
|
2018
|
+
*/
|
2019
|
+
static VALUE parse_visibility_member(parserstate *state, VALUE annotations) {
|
2020
|
+
if (rb_array_len(annotations) > 0) {
|
2021
|
+
raise_syntax_error(
|
2022
|
+
state,
|
2023
|
+
state->current_token,
|
2024
|
+
"annotation cannot be given to visibility members"
|
2025
|
+
);
|
2026
|
+
}
|
2027
|
+
|
2028
|
+
VALUE location = rbs_new_location(state->buffer, state->current_token.range);
|
2029
|
+
|
2030
|
+
switch (state->current_token.type)
|
2031
|
+
{
|
2032
|
+
case kPUBLIC:
|
2033
|
+
return rbs_ast_members_public(location);
|
2034
|
+
case kPRIVATE:
|
2035
|
+
return rbs_ast_members_private(location);
|
2036
|
+
default:
|
2037
|
+
rbs_abort();
|
2038
|
+
}
|
2039
|
+
}
|
2040
|
+
|
2041
|
+
/*
|
2042
|
+
attribute_member ::= {attr_keyword} attr_name attr_var `:` <type>
|
2043
|
+
| {visibility} attr_keyword attr_name attr_var `:` <type>
|
2044
|
+
| {attr_keyword} `self` `.` attr_name attr_var `:` <type>
|
2045
|
+
| {visibility} attr_keyword `self` `.` attr_name attr_var `:` <type>
|
2046
|
+
|
2047
|
+
attr_keyword ::= `attr_reader` | `attr_writer` | `attr_accessor`
|
2048
|
+
|
2049
|
+
visibility ::= `public` | `private`
|
2050
|
+
|
2051
|
+
attr_var ::= # empty
|
2052
|
+
| `(` tAIDENT `)` # Ivar name
|
2053
|
+
| `(` `)` # No variable
|
2054
|
+
*/
|
2055
|
+
static VALUE parse_attribute_member(parserstate *state, position comment_pos, VALUE annotations) {
|
2056
|
+
range member_range;
|
2057
|
+
member_range.start = state->current_token.range.start;
|
2058
|
+
comment_pos = nonnull_pos_or(comment_pos, member_range.start);
|
2059
|
+
VALUE comment = get_comment(state, comment_pos.line);
|
2060
|
+
|
2061
|
+
VALUE visibility;
|
2062
|
+
range visibility_range;
|
2063
|
+
switch (state->current_token.type)
|
2064
|
+
{
|
2065
|
+
case kPRIVATE:
|
2066
|
+
visibility = ID2SYM(rb_intern("private"));
|
2067
|
+
visibility_range = state->current_token.range;
|
2068
|
+
parser_advance(state);
|
2069
|
+
break;
|
2070
|
+
case kPUBLIC:
|
2071
|
+
visibility = ID2SYM(rb_intern("public"));
|
2072
|
+
visibility_range = state->current_token.range;
|
2073
|
+
parser_advance(state);
|
2074
|
+
break;
|
2075
|
+
default:
|
2076
|
+
visibility = Qnil;
|
2077
|
+
visibility_range = NULL_RANGE;
|
2078
|
+
break;
|
2079
|
+
}
|
2080
|
+
|
2081
|
+
enum TokenType attr_type = state->current_token.type;
|
2082
|
+
range keyword_range = state->current_token.range;
|
2083
|
+
|
2084
|
+
range kind_range;
|
2085
|
+
InstanceSingletonKind is_kind = parse_instance_singleton_kind(state, false, &kind_range);
|
2086
|
+
VALUE kind = ID2SYM(rb_intern((is_kind == INSTANCE_KIND) ? "instance" : "singleton"));
|
2087
|
+
|
2088
|
+
range name_range;
|
2089
|
+
VALUE attr_name = parse_method_name(state, &name_range);
|
2090
|
+
|
2091
|
+
VALUE ivar_name;
|
2092
|
+
range ivar_range, ivar_name_range;
|
2093
|
+
if (state->next_token.type == pLPAREN) {
|
2094
|
+
parser_advance_assert(state, pLPAREN);
|
2095
|
+
ivar_range.start = state->current_token.range.start;
|
2096
|
+
|
2097
|
+
if (parser_advance_if(state, tAIDENT)) {
|
2098
|
+
ivar_name = ID2SYM(INTERN_TOKEN(state, state->current_token));
|
2099
|
+
ivar_name_range = state->current_token.range;
|
2100
|
+
} else {
|
2101
|
+
ivar_name = Qfalse;
|
2102
|
+
ivar_name_range = NULL_RANGE;
|
2103
|
+
}
|
2104
|
+
|
2105
|
+
parser_advance_assert(state, pRPAREN);
|
2106
|
+
ivar_range.end = state->current_token.range.end;
|
2107
|
+
} else {
|
2108
|
+
ivar_range = NULL_RANGE;
|
2109
|
+
ivar_name = Qnil;
|
2110
|
+
ivar_name_range = NULL_RANGE;
|
2111
|
+
}
|
2112
|
+
|
2113
|
+
parser_advance_assert(state, pCOLON);
|
2114
|
+
range colon_range = state->current_token.range;
|
2115
|
+
|
2116
|
+
parser_push_typevar_table(state, is_kind == SINGLETON_KIND);
|
2117
|
+
VALUE type = parse_type(state);
|
2118
|
+
parser_pop_typevar_table(state);
|
2119
|
+
member_range.end = state->current_token.range.end;
|
2120
|
+
|
2121
|
+
VALUE location = rbs_new_location(state->buffer, member_range);
|
2122
|
+
rbs_loc *loc = rbs_check_location(location);
|
2123
|
+
rbs_loc_alloc_children(loc, 7);
|
2124
|
+
rbs_loc_add_required_child(loc, INTERN("keyword"), keyword_range);
|
2125
|
+
rbs_loc_add_required_child(loc, INTERN("name"), name_range);
|
2126
|
+
rbs_loc_add_required_child(loc, INTERN("colon"), colon_range);
|
2127
|
+
rbs_loc_add_optional_child(loc, INTERN("kind"), kind_range);
|
2128
|
+
rbs_loc_add_optional_child(loc, INTERN("ivar"), ivar_range);
|
2129
|
+
rbs_loc_add_optional_child(loc, INTERN("ivar_name"), ivar_name_range);
|
2130
|
+
rbs_loc_add_optional_child(loc, INTERN("visibility"), visibility_range);
|
2131
|
+
|
2132
|
+
switch (attr_type)
|
2133
|
+
{
|
2134
|
+
case kATTRREADER:
|
2135
|
+
return rbs_ast_members_attr_reader(attr_name, type, ivar_name, kind, annotations, location, comment, visibility);
|
2136
|
+
case kATTRWRITER:
|
2137
|
+
return rbs_ast_members_attr_writer(attr_name, type, ivar_name, kind, annotations, location, comment, visibility);
|
2138
|
+
case kATTRACCESSOR:
|
2139
|
+
return rbs_ast_members_attr_accessor(attr_name, type, ivar_name, kind, annotations, location, comment, visibility);
|
2140
|
+
default:
|
2141
|
+
rbs_abort();
|
2142
|
+
}
|
2143
|
+
}
|
2144
|
+
|
2145
|
+
/*
|
2146
|
+
interface_members ::= {} ...<interface_member> kEND
|
2147
|
+
|
2148
|
+
interface_member ::= def_member (instance method only && no overloading)
|
2149
|
+
| mixin_member (interface only)
|
2150
|
+
| alias_member (instance only)
|
2151
|
+
*/
|
2152
|
+
static VALUE parse_interface_members(parserstate *state) {
|
2153
|
+
VALUE members = EMPTY_ARRAY;
|
2154
|
+
|
2155
|
+
while (state->next_token.type != kEND) {
|
2156
|
+
VALUE annotations = EMPTY_ARRAY;
|
2157
|
+
position annot_pos = NullPosition;
|
2158
|
+
|
2159
|
+
parse_annotations(state, &annotations, &annot_pos);
|
2160
|
+
|
2161
|
+
parser_advance(state);
|
2162
|
+
|
2163
|
+
VALUE member;
|
2164
|
+
switch (state->current_token.type) {
|
2165
|
+
case kDEF: {
|
2166
|
+
member = parse_member_def(state, true, true, annot_pos, annotations);
|
2167
|
+
break;
|
2168
|
+
}
|
2169
|
+
|
2170
|
+
case kINCLUDE:
|
2171
|
+
case kEXTEND:
|
2172
|
+
case kPREPEND: {
|
2173
|
+
member = parse_mixin_member(state, true, annot_pos, annotations);
|
2174
|
+
break;
|
2175
|
+
}
|
2176
|
+
|
2177
|
+
case kALIAS: {
|
2178
|
+
member = parse_alias_member(state, true, annot_pos, annotations);
|
2179
|
+
break;
|
2180
|
+
}
|
2181
|
+
|
2182
|
+
default:
|
2183
|
+
raise_syntax_error(
|
2184
|
+
state,
|
2185
|
+
state->current_token,
|
2186
|
+
"unexpected token for interface declaration member"
|
2187
|
+
);
|
2188
|
+
}
|
2189
|
+
|
2190
|
+
melt_array(&members);
|
2191
|
+
rb_ary_push(members, member);
|
2192
|
+
}
|
2193
|
+
|
2194
|
+
return members;
|
2195
|
+
}
|
2196
|
+
|
2197
|
+
/*
|
2198
|
+
interface_decl ::= {`interface`} interface_name module_type_params interface_members <kEND>
|
2199
|
+
*/
|
2200
|
+
static VALUE parse_interface_decl(parserstate *state, position comment_pos, VALUE annotations) {
|
2201
|
+
parser_push_typevar_table(state, true);
|
2202
|
+
|
2203
|
+
range member_range;
|
2204
|
+
member_range.start = state->current_token.range.start;
|
2205
|
+
comment_pos = nonnull_pos_or(comment_pos, member_range.start);
|
2206
|
+
|
2207
|
+
range keyword_range = state->current_token.range;
|
2208
|
+
|
2209
|
+
parser_advance(state);
|
2210
|
+
|
2211
|
+
range name_range;
|
2212
|
+
VALUE name = parse_type_name(state, INTERFACE_NAME, &name_range);
|
2213
|
+
range type_params_range;
|
2214
|
+
VALUE params = parse_type_params(state, &type_params_range, true);
|
2215
|
+
VALUE members = parse_interface_members(state);
|
2216
|
+
|
2217
|
+
parser_advance_assert(state, kEND);
|
2218
|
+
range end_range = state->current_token.range;
|
2219
|
+
member_range.end = end_range.end;
|
2220
|
+
|
2221
|
+
parser_pop_typevar_table(state);
|
2222
|
+
|
2223
|
+
VALUE location = rbs_new_location(state->buffer, member_range);
|
2224
|
+
rbs_loc *loc = rbs_check_location(location);
|
2225
|
+
rbs_loc_alloc_children(loc, 4);
|
2226
|
+
rbs_loc_add_required_child(loc, INTERN("keyword"), keyword_range);
|
2227
|
+
rbs_loc_add_required_child(loc, INTERN("name"), name_range);
|
2228
|
+
rbs_loc_add_required_child(loc, INTERN("end"), end_range);
|
2229
|
+
rbs_loc_add_optional_child(loc, INTERN("type_params"), type_params_range);
|
2230
|
+
|
2231
|
+
return rbs_ast_decl_interface(
|
2232
|
+
name,
|
2233
|
+
params,
|
2234
|
+
members,
|
2235
|
+
annotations,
|
2236
|
+
location,
|
2237
|
+
get_comment(state, comment_pos.line)
|
2238
|
+
);
|
2239
|
+
}
|
2240
|
+
|
2241
|
+
/*
|
2242
|
+
module_self_types ::= {`:`} module_self_type `,` ... `,` <module_self_type>
|
2243
|
+
|
2244
|
+
module_self_type ::= <module_name>
|
2245
|
+
| module_name `[` type_list <`]`>
|
2246
|
+
*/
|
2247
|
+
static void parse_module_self_types(parserstate *state, VALUE *array) {
|
2248
|
+
while (true) {
|
2249
|
+
parser_advance(state);
|
2250
|
+
|
2251
|
+
range self_range;
|
2252
|
+
self_range.start = state->current_token.range.start;
|
2253
|
+
range name_range;
|
2254
|
+
VALUE module_name = parse_type_name(state, CLASS_NAME | INTERFACE_NAME, &name_range);
|
2255
|
+
self_range.end = name_range.end;
|
2256
|
+
|
2257
|
+
VALUE args = EMPTY_ARRAY;
|
2258
|
+
range args_range = NULL_RANGE;
|
2259
|
+
if (state->next_token.type == pLBRACKET) {
|
2260
|
+
parser_advance(state);
|
2261
|
+
args_range.start = state->current_token.range.start;
|
2262
|
+
parse_type_list(state, pRBRACKET, &args);
|
2263
|
+
parser_advance(state);
|
2264
|
+
self_range.end = args_range.end = state->current_token.range.end;
|
2265
|
+
}
|
2266
|
+
|
2267
|
+
VALUE location = rbs_new_location(state->buffer, self_range);
|
2268
|
+
rbs_loc *loc = rbs_check_location(location);
|
2269
|
+
rbs_loc_alloc_children(loc, 2);
|
2270
|
+
rbs_loc_add_required_child(loc, INTERN("name"), name_range);
|
2271
|
+
rbs_loc_add_optional_child(loc, INTERN("args"), args_range);
|
2272
|
+
|
2273
|
+
VALUE self_type = rbs_ast_decl_module_self(module_name, args, location);
|
2274
|
+
melt_array(array);
|
2275
|
+
rb_ary_push(*array, self_type);
|
2276
|
+
|
2277
|
+
if (state->next_token.type == pCOMMA) {
|
2278
|
+
parser_advance(state);
|
2279
|
+
} else {
|
2280
|
+
break;
|
2281
|
+
}
|
2282
|
+
}
|
2283
|
+
}
|
2284
|
+
|
2285
|
+
static VALUE parse_nested_decl(parserstate *state, const char *nested_in, position annot_pos, VALUE annotations);
|
2286
|
+
|
2287
|
+
/*
|
2288
|
+
module_members ::= {} ...<module_member> kEND
|
2289
|
+
|
2290
|
+
module_member ::= def_member
|
2291
|
+
| variable_member
|
2292
|
+
| mixin_member
|
2293
|
+
| alias_member
|
2294
|
+
| attribute_member
|
2295
|
+
| `public`
|
2296
|
+
| `private`
|
2297
|
+
*/
|
2298
|
+
static VALUE parse_module_members(parserstate *state) {
|
2299
|
+
VALUE members = EMPTY_ARRAY;
|
2300
|
+
|
2301
|
+
while (state->next_token.type != kEND) {
|
2302
|
+
VALUE annotations = EMPTY_ARRAY;
|
2303
|
+
position annot_pos = NullPosition;
|
2304
|
+
parse_annotations(state, &annotations, &annot_pos);
|
2305
|
+
|
2306
|
+
parser_advance(state);
|
2307
|
+
|
2308
|
+
VALUE member;
|
2309
|
+
switch (state->current_token.type)
|
2310
|
+
{
|
2311
|
+
case kDEF: {
|
2312
|
+
member = parse_member_def(state, false, true, annot_pos, annotations);
|
2313
|
+
break;
|
2314
|
+
}
|
2315
|
+
|
2316
|
+
case kINCLUDE:
|
2317
|
+
case kEXTEND:
|
2318
|
+
case kPREPEND: {
|
2319
|
+
member = parse_mixin_member(state, false, annot_pos, annotations);
|
2320
|
+
break;
|
2321
|
+
}
|
2322
|
+
|
2323
|
+
case kALIAS: {
|
2324
|
+
member = parse_alias_member(state, false, annot_pos, annotations);
|
2325
|
+
break;
|
2326
|
+
}
|
2327
|
+
|
2328
|
+
case tAIDENT:
|
2329
|
+
case tA2IDENT:
|
2330
|
+
case kSELF: {
|
2331
|
+
member = parse_variable_member(state, annot_pos, annotations);
|
2332
|
+
break;
|
2333
|
+
}
|
2334
|
+
|
2335
|
+
case kATTRREADER:
|
2336
|
+
case kATTRWRITER:
|
2337
|
+
case kATTRACCESSOR: {
|
2338
|
+
member = parse_attribute_member(state, annot_pos, annotations);
|
2339
|
+
break;
|
2340
|
+
}
|
2341
|
+
|
2342
|
+
case kPUBLIC:
|
2343
|
+
case kPRIVATE:
|
2344
|
+
if (state->next_token.range.start.line == state->current_token.range.start.line) {
|
2345
|
+
switch (state->next_token.type)
|
2346
|
+
{
|
2347
|
+
case kDEF: {
|
2348
|
+
member = parse_member_def(state, false, true, annot_pos, annotations);
|
2349
|
+
break;
|
2350
|
+
}
|
2351
|
+
case kATTRREADER:
|
2352
|
+
case kATTRWRITER:
|
2353
|
+
case kATTRACCESSOR: {
|
2354
|
+
member = parse_attribute_member(state, annot_pos, annotations);
|
2355
|
+
break;
|
2356
|
+
}
|
2357
|
+
default:
|
2358
|
+
raise_syntax_error(state, state->next_token, "method or attribute definition is expected after visibility modifier");
|
2359
|
+
}
|
2360
|
+
} else {
|
2361
|
+
member = parse_visibility_member(state, annotations);
|
2362
|
+
}
|
2363
|
+
break;
|
2364
|
+
|
2365
|
+
default:
|
2366
|
+
member = parse_nested_decl(state, "module", annot_pos, annotations);
|
2367
|
+
break;
|
2368
|
+
}
|
2369
|
+
|
2370
|
+
melt_array(&members);
|
2371
|
+
rb_ary_push(members, member);
|
2372
|
+
}
|
2373
|
+
|
2374
|
+
return members;
|
2375
|
+
}
|
2376
|
+
|
2377
|
+
/*
|
2378
|
+
module_decl ::= {module_name} module_type_params module_members <kEND>
|
2379
|
+
| {module_name} module_name module_type_params `:` module_self_types module_members <kEND>
|
2380
|
+
*/
|
2381
|
+
static VALUE parse_module_decl0(parserstate *state, range keyword_range, VALUE module_name, range name_range, VALUE comment, VALUE annotations) {
|
2382
|
+
parser_push_typevar_table(state, true);
|
2383
|
+
|
2384
|
+
range decl_range;
|
2385
|
+
decl_range.start = keyword_range.start;
|
2386
|
+
range type_params_range;
|
2387
|
+
VALUE type_params = parse_type_params(state, &type_params_range, true);
|
2388
|
+
|
2389
|
+
VALUE self_types = EMPTY_ARRAY;
|
2390
|
+
range colon_range;
|
2391
|
+
range self_types_range;
|
2392
|
+
if (state->next_token.type == pCOLON) {
|
2393
|
+
parser_advance(state);
|
2394
|
+
colon_range = state->current_token.range;
|
2395
|
+
self_types_range.start = state->next_token.range.start;
|
2396
|
+
parse_module_self_types(state, &self_types);
|
2397
|
+
self_types_range.end = state->current_token.range.end;
|
2398
|
+
} else {
|
2399
|
+
colon_range = NULL_RANGE;
|
2400
|
+
self_types_range = NULL_RANGE;
|
2401
|
+
}
|
2402
|
+
|
2403
|
+
VALUE members = parse_module_members(state);
|
2404
|
+
|
2405
|
+
parser_advance_assert(state, kEND);
|
2406
|
+
range end_range = state->current_token.range;
|
2407
|
+
decl_range.end = state->current_token.range.end;
|
2408
|
+
|
2409
|
+
VALUE location = rbs_new_location(state->buffer, decl_range);
|
2410
|
+
rbs_loc *loc = rbs_check_location(location);
|
2411
|
+
rbs_loc_alloc_children(loc, 6);
|
2412
|
+
rbs_loc_add_required_child(loc, INTERN("keyword"), keyword_range);
|
2413
|
+
rbs_loc_add_required_child(loc, INTERN("name"), name_range);
|
2414
|
+
rbs_loc_add_required_child(loc, INTERN("end"), end_range);
|
2415
|
+
rbs_loc_add_optional_child(loc, INTERN("type_params"), type_params_range);
|
2416
|
+
rbs_loc_add_optional_child(loc, INTERN("colon"), colon_range);
|
2417
|
+
rbs_loc_add_optional_child(loc, INTERN("self_types"), self_types_range);
|
2418
|
+
|
2419
|
+
parser_pop_typevar_table(state);
|
2420
|
+
|
2421
|
+
return rbs_ast_decl_module(
|
2422
|
+
module_name,
|
2423
|
+
type_params,
|
2424
|
+
self_types,
|
2425
|
+
members,
|
2426
|
+
annotations,
|
2427
|
+
location,
|
2428
|
+
comment
|
2429
|
+
);
|
2430
|
+
}
|
2431
|
+
|
2432
|
+
/*
|
2433
|
+
module_decl ::= {`module`} module_name `=` old_module_name <kEND>
|
2434
|
+
| {`module`} module_name module_decl0 <kEND>
|
2435
|
+
|
2436
|
+
*/
|
2437
|
+
static VALUE parse_module_decl(parserstate *state, position comment_pos, VALUE annotations) {
|
2438
|
+
range keyword_range = state->current_token.range;
|
2439
|
+
|
2440
|
+
comment_pos = nonnull_pos_or(comment_pos, state->current_token.range.start);
|
2441
|
+
VALUE comment = get_comment(state, comment_pos.line);
|
2442
|
+
|
2443
|
+
parser_advance(state);
|
2444
|
+
range module_name_range;
|
2445
|
+
VALUE module_name = parse_type_name(state, CLASS_NAME, &module_name_range);
|
2446
|
+
|
2447
|
+
if (state->next_token.type == pEQ) {
|
2448
|
+
range eq_range = state->next_token.range;
|
2449
|
+
parser_advance(state);
|
2450
|
+
parser_advance(state);
|
2451
|
+
|
2452
|
+
range old_name_range;
|
2453
|
+
VALUE old_name = parse_type_name(state, CLASS_NAME, &old_name_range);
|
2454
|
+
|
2455
|
+
range decl_range = {
|
2456
|
+
.start = keyword_range.start,
|
2457
|
+
.end = old_name_range.end
|
2458
|
+
};
|
2459
|
+
|
2460
|
+
VALUE location = rbs_new_location(state->buffer, decl_range);
|
2461
|
+
rbs_loc *loc = rbs_check_location(location);
|
2462
|
+
rbs_loc_alloc_children(loc, 4);
|
2463
|
+
rbs_loc_add_required_child(loc, INTERN("keyword"), keyword_range);
|
2464
|
+
rbs_loc_add_required_child(loc, INTERN("new_name"), module_name_range);
|
2465
|
+
rbs_loc_add_required_child(loc, INTERN("eq"), eq_range);
|
2466
|
+
rbs_loc_add_optional_child(loc, INTERN("old_name"), old_name_range);
|
2467
|
+
|
2468
|
+
return rbs_ast_decl_module_alias(module_name, old_name, location, comment);
|
2469
|
+
} else {
|
2470
|
+
return parse_module_decl0(state, keyword_range, module_name, module_name_range, comment, annotations);
|
2471
|
+
}
|
2472
|
+
}
|
2473
|
+
|
2474
|
+
/*
|
2475
|
+
class_decl_super ::= {} `<` <class_instance_name>
|
2476
|
+
| {<>}
|
2477
|
+
*/
|
2478
|
+
static VALUE parse_class_decl_super(parserstate *state, range *lt_range) {
|
2479
|
+
if (parser_advance_if(state, pLT)) {
|
2480
|
+
*lt_range = state->current_token.range;
|
2481
|
+
|
2482
|
+
range super_range;
|
2483
|
+
super_range.start = state->next_token.range.start;
|
2484
|
+
|
2485
|
+
VALUE name;
|
2486
|
+
VALUE args = EMPTY_ARRAY;
|
2487
|
+
range name_range, args_range;
|
2488
|
+
class_instance_name(state, CLASS_NAME, &name, &args, &name_range, &args_range);
|
2489
|
+
|
2490
|
+
super_range.end = state->current_token.range.end;
|
2491
|
+
|
2492
|
+
VALUE location = rbs_new_location(state->buffer, super_range);
|
2493
|
+
rbs_loc *loc = rbs_check_location(location);
|
2494
|
+
rbs_loc_alloc_children(loc, 2);
|
2495
|
+
rbs_loc_add_required_child(loc, INTERN("name"), name_range);
|
2496
|
+
rbs_loc_add_optional_child(loc, INTERN("args"), args_range);
|
2497
|
+
|
2498
|
+
return rbs_ast_decl_class_super(name, args, location);
|
2499
|
+
} else {
|
2500
|
+
*lt_range = NULL_RANGE;
|
2501
|
+
return Qnil;
|
2502
|
+
}
|
2503
|
+
}
|
2504
|
+
|
2505
|
+
/*
|
2506
|
+
class_decl ::= {class_name} type_params class_decl_super class_members <`end`>
|
2507
|
+
*/
|
2508
|
+
static VALUE parse_class_decl0(parserstate *state, range keyword_range, VALUE name, range name_range, VALUE comment, VALUE annotations) {
|
2509
|
+
parser_push_typevar_table(state, true);
|
2510
|
+
|
2511
|
+
range decl_range;
|
2512
|
+
decl_range.start = keyword_range.start;
|
2513
|
+
|
2514
|
+
range type_params_range;
|
2515
|
+
VALUE type_params = parse_type_params(state, &type_params_range, true);
|
2516
|
+
|
2517
|
+
range lt_range;
|
2518
|
+
VALUE super = parse_class_decl_super(state, <_range);
|
2519
|
+
|
2520
|
+
VALUE members = parse_module_members(state);
|
2521
|
+
|
2522
|
+
parser_advance_assert(state, kEND);
|
2523
|
+
|
2524
|
+
range end_range = state->current_token.range;
|
2525
|
+
|
2526
|
+
decl_range.end = end_range.end;
|
2527
|
+
|
2528
|
+
parser_pop_typevar_table(state);
|
2529
|
+
|
2530
|
+
VALUE location = rbs_new_location(state->buffer, decl_range);
|
2531
|
+
rbs_loc *loc = rbs_check_location(location);
|
2532
|
+
rbs_loc_alloc_children(loc, 5);
|
2533
|
+
rbs_loc_add_required_child(loc, INTERN("keyword"), keyword_range);
|
2534
|
+
rbs_loc_add_required_child(loc, INTERN("name"), name_range);
|
2535
|
+
rbs_loc_add_required_child(loc, INTERN("end"), end_range);
|
2536
|
+
rbs_loc_add_optional_child(loc, INTERN("type_params"), type_params_range);
|
2537
|
+
rbs_loc_add_optional_child(loc, INTERN("lt"), lt_range);
|
2538
|
+
|
2539
|
+
return rbs_ast_decl_class(
|
2540
|
+
name,
|
2541
|
+
type_params,
|
2542
|
+
super,
|
2543
|
+
members,
|
2544
|
+
annotations,
|
2545
|
+
location,
|
2546
|
+
comment
|
2547
|
+
);
|
2548
|
+
}
|
2549
|
+
|
2550
|
+
/*
|
2551
|
+
class_decl ::= {`class`} class_name `=` <class_name>
|
2552
|
+
| {`class`} class_name <class_decl0>
|
2553
|
+
*/
|
2554
|
+
static VALUE parse_class_decl(parserstate *state, position comment_pos, VALUE annotations) {
|
2555
|
+
range keyword_range = state->current_token.range;
|
2556
|
+
|
2557
|
+
comment_pos = nonnull_pos_or(comment_pos, state->current_token.range.start);
|
2558
|
+
VALUE comment = get_comment(state, comment_pos.line);
|
2559
|
+
|
2560
|
+
parser_advance(state);
|
2561
|
+
range class_name_range;
|
2562
|
+
VALUE class_name = parse_type_name(state, CLASS_NAME, &class_name_range);
|
2563
|
+
|
2564
|
+
if (state->next_token.type == pEQ) {
|
2565
|
+
range eq_range = state->next_token.range;
|
2566
|
+
parser_advance(state);
|
2567
|
+
parser_advance(state);
|
2568
|
+
|
2569
|
+
range old_name_range;
|
2570
|
+
VALUE old_name = parse_type_name(state, CLASS_NAME, &old_name_range);
|
2571
|
+
|
2572
|
+
range decl_range = {
|
2573
|
+
.start = keyword_range.start,
|
2574
|
+
.end = old_name_range.end,
|
2575
|
+
};
|
2576
|
+
|
2577
|
+
VALUE location = rbs_new_location(state->buffer, decl_range);
|
2578
|
+
rbs_loc *loc = rbs_check_location(location);
|
2579
|
+
rbs_loc_alloc_children(loc, 4);
|
2580
|
+
rbs_loc_add_required_child(loc, INTERN("keyword"), keyword_range);
|
2581
|
+
rbs_loc_add_required_child(loc, INTERN("new_name"), class_name_range);
|
2582
|
+
rbs_loc_add_required_child(loc, INTERN("eq"), eq_range);
|
2583
|
+
rbs_loc_add_optional_child(loc, INTERN("old_name"), old_name_range);
|
2584
|
+
|
2585
|
+
return rbs_ast_decl_class_alias(class_name, old_name, location, comment);
|
2586
|
+
} else {
|
2587
|
+
return parse_class_decl0(state, keyword_range, class_name, class_name_range, comment, annotations);
|
2588
|
+
}
|
2589
|
+
}
|
2590
|
+
|
2591
|
+
/*
|
2592
|
+
nested_decl ::= {<const_decl>}
|
2593
|
+
| {<class_decl>}
|
2594
|
+
| {<interface_decl>}
|
2595
|
+
| {<module_decl>}
|
2596
|
+
| {<class_decl>}
|
2597
|
+
*/
|
2598
|
+
static VALUE parse_nested_decl(parserstate *state, const char *nested_in, position annot_pos, VALUE annotations) {
|
2599
|
+
parser_push_typevar_table(state, true);
|
2600
|
+
|
2601
|
+
VALUE decl;
|
2602
|
+
switch (state->current_token.type) {
|
2603
|
+
case tUIDENT:
|
2604
|
+
case pCOLON2: {
|
2605
|
+
decl = parse_const_decl(state);
|
2606
|
+
break;
|
2607
|
+
}
|
2608
|
+
case tGIDENT: {
|
2609
|
+
decl = parse_global_decl(state);
|
2610
|
+
break;
|
2611
|
+
}
|
2612
|
+
case kTYPE: {
|
2613
|
+
decl = parse_type_decl(state, annot_pos, annotations);
|
2614
|
+
break;
|
2615
|
+
}
|
2616
|
+
case kINTERFACE: {
|
2617
|
+
decl = parse_interface_decl(state, annot_pos, annotations);
|
2618
|
+
break;
|
2619
|
+
}
|
2620
|
+
case kMODULE: {
|
2621
|
+
decl = parse_module_decl(state, annot_pos, annotations);
|
2622
|
+
break;
|
2623
|
+
}
|
2624
|
+
case kCLASS: {
|
2625
|
+
decl = parse_class_decl(state, annot_pos, annotations);
|
2626
|
+
break;
|
2627
|
+
}
|
2628
|
+
default:
|
2629
|
+
raise_syntax_error(
|
2630
|
+
state,
|
2631
|
+
state->current_token,
|
2632
|
+
"unexpected token for class/module declaration member"
|
2633
|
+
);
|
2634
|
+
}
|
2635
|
+
|
2636
|
+
parser_pop_typevar_table(state);
|
2637
|
+
|
2638
|
+
return decl;
|
2639
|
+
}
|
2640
|
+
|
2641
|
+
static VALUE parse_decl(parserstate *state) {
|
2642
|
+
VALUE annotations = EMPTY_ARRAY;
|
2643
|
+
position annot_pos = NullPosition;
|
2644
|
+
|
2645
|
+
parse_annotations(state, &annotations, &annot_pos);
|
2646
|
+
|
2647
|
+
parser_advance(state);
|
2648
|
+
switch (state->current_token.type) {
|
2649
|
+
case tUIDENT:
|
2650
|
+
case pCOLON2: {
|
2651
|
+
return parse_const_decl(state);
|
2652
|
+
}
|
2653
|
+
case tGIDENT: {
|
2654
|
+
return parse_global_decl(state);
|
2655
|
+
}
|
2656
|
+
case kTYPE: {
|
2657
|
+
return parse_type_decl(state, annot_pos, annotations);
|
2658
|
+
}
|
2659
|
+
case kINTERFACE: {
|
2660
|
+
return parse_interface_decl(state, annot_pos, annotations);
|
2661
|
+
}
|
2662
|
+
case kMODULE: {
|
2663
|
+
return parse_module_decl(state, annot_pos, annotations);
|
2664
|
+
}
|
2665
|
+
case kCLASS: {
|
2666
|
+
return parse_class_decl(state, annot_pos, annotations);
|
2667
|
+
}
|
2668
|
+
default:
|
2669
|
+
raise_syntax_error(
|
2670
|
+
state,
|
2671
|
+
state->current_token,
|
2672
|
+
"cannot start a declaration"
|
2673
|
+
);
|
2674
|
+
}
|
2675
|
+
}
|
2676
|
+
|
2677
|
+
/*
|
2678
|
+
namespace ::= {} (`::`)? (`tUIDENT` `::`)* `tUIDENT` <`::`>
|
2679
|
+
| {} <> (empty -- returns empty namespace)
|
2680
|
+
*/
|
2681
|
+
static VALUE parse_namespace(parserstate *state, range *rg) {
|
2682
|
+
bool is_absolute = false;
|
2683
|
+
|
2684
|
+
if (state->next_token.type == pCOLON2) {
|
2685
|
+
*rg = (range) {
|
2686
|
+
.start = state->next_token.range.start,
|
2687
|
+
.end = state->next_token.range.end,
|
2688
|
+
};
|
2689
|
+
is_absolute = true;
|
2690
|
+
|
2691
|
+
parser_advance(state);
|
2692
|
+
}
|
2693
|
+
|
2694
|
+
VALUE path = EMPTY_ARRAY;
|
2695
|
+
|
2696
|
+
while (true) {
|
2697
|
+
if (state->next_token.type == tUIDENT && state->next_token2.type == pCOLON2) {
|
2698
|
+
melt_array(&path);
|
2699
|
+
rb_ary_push(path, ID2SYM(INTERN_TOKEN(state, state->next_token)));
|
2700
|
+
if (null_position_p(rg->start)) {
|
2701
|
+
rg->start = state->next_token.range.start;
|
2702
|
+
}
|
2703
|
+
rg->end = state->next_token2.range.end;
|
2704
|
+
parser_advance(state);
|
2705
|
+
parser_advance(state);
|
2706
|
+
} else {
|
2707
|
+
break;
|
2708
|
+
}
|
2709
|
+
}
|
2710
|
+
|
2711
|
+
return rbs_namespace(path, is_absolute ? Qtrue : Qfalse);
|
2712
|
+
}
|
2713
|
+
|
2714
|
+
/*
|
2715
|
+
use_clauses ::= {} use_clause `,` ... `,` <use_clause>
|
2716
|
+
|
2717
|
+
use_clause ::= {} namespace <tUIDENT>
|
2718
|
+
| {} namespace tUIDENT `as` <tUIDENT>
|
2719
|
+
| {} namespace <tSTAR>
|
2720
|
+
*/
|
2721
|
+
static void parse_use_clauses(parserstate *state, VALUE clauses) {
|
2722
|
+
while (true) {
|
2723
|
+
range namespace_range = NULL_RANGE;
|
2724
|
+
VALUE namespace = parse_namespace(state, &namespace_range);
|
2725
|
+
|
2726
|
+
switch (state->next_token.type)
|
2727
|
+
{
|
2728
|
+
case tLIDENT:
|
2729
|
+
case tULIDENT:
|
2730
|
+
case tUIDENT: {
|
2731
|
+
parser_advance(state);
|
2732
|
+
|
2733
|
+
enum TokenType ident_type = state->current_token.type;
|
2734
|
+
|
2735
|
+
range type_name_range = null_range_p(namespace_range)
|
2736
|
+
? state->current_token.range
|
2737
|
+
: (range) { .start = namespace_range.start, .end = state->current_token.range.end };
|
2738
|
+
|
2739
|
+
VALUE type_name = rbs_type_name(namespace, ID2SYM(INTERN_TOKEN(state, state->current_token)));
|
2740
|
+
|
2741
|
+
range keyword_range = NULL_RANGE;
|
2742
|
+
range new_name_range = NULL_RANGE;
|
2743
|
+
|
2744
|
+
VALUE new_name = Qnil;
|
2745
|
+
range clause_range = type_name_range;
|
2746
|
+
if (state->next_token.type == kAS) {
|
2747
|
+
parser_advance(state);
|
2748
|
+
keyword_range = state->current_token.range;
|
2749
|
+
|
2750
|
+
if (ident_type == tUIDENT) parser_advance_assert(state, tUIDENT);
|
2751
|
+
if (ident_type == tLIDENT) parser_advance_assert(state, tLIDENT);
|
2752
|
+
if (ident_type == tULIDENT) parser_advance_assert(state, tULIDENT);
|
2753
|
+
|
2754
|
+
new_name = ID2SYM(INTERN_TOKEN(state, state->current_token));
|
2755
|
+
new_name_range = state->current_token.range;
|
2756
|
+
clause_range.end = new_name_range.end;
|
2757
|
+
}
|
2758
|
+
|
2759
|
+
VALUE location = rbs_new_location(state->buffer, clause_range);
|
2760
|
+
rbs_loc *loc = rbs_check_location(location);
|
2761
|
+
rbs_loc_alloc_children(loc, 3);
|
2762
|
+
rbs_loc_add_required_child(loc, INTERN("type_name"), type_name_range);
|
2763
|
+
rbs_loc_add_optional_child(loc, INTERN("keyword"), keyword_range);
|
2764
|
+
rbs_loc_add_optional_child(loc, INTERN("new_name"), new_name_range);
|
2765
|
+
|
2766
|
+
rb_ary_push(clauses, rbs_ast_directives_use_single_clause(type_name, new_name, location));
|
2767
|
+
|
2768
|
+
break;
|
2769
|
+
}
|
2770
|
+
case pSTAR:
|
2771
|
+
{
|
2772
|
+
range clause_range = namespace_range;
|
2773
|
+
parser_advance(state);
|
2774
|
+
|
2775
|
+
range star_range = state->current_token.range;
|
2776
|
+
clause_range.end = star_range.end;
|
2777
|
+
|
2778
|
+
VALUE location = rbs_new_location(state->buffer, clause_range);
|
2779
|
+
rbs_loc *loc = rbs_check_location(location);
|
2780
|
+
rbs_loc_alloc_children(loc, 2);
|
2781
|
+
rbs_loc_add_required_child(loc, INTERN("namespace"), namespace_range);
|
2782
|
+
rbs_loc_add_required_child(loc, INTERN("star"), star_range);
|
2783
|
+
|
2784
|
+
rb_ary_push(clauses, rbs_ast_directives_use_wildcard_clause(namespace, location));
|
2785
|
+
|
2786
|
+
break;
|
2787
|
+
}
|
2788
|
+
default:
|
2789
|
+
raise_syntax_error(
|
2790
|
+
state,
|
2791
|
+
state->next_token,
|
2792
|
+
"use clause is expected"
|
2793
|
+
);
|
2794
|
+
}
|
2795
|
+
|
2796
|
+
if (state->next_token.type == pCOMMA) {
|
2797
|
+
parser_advance(state);
|
2798
|
+
} else {
|
2799
|
+
break;
|
2800
|
+
}
|
2801
|
+
}
|
2802
|
+
|
2803
|
+
return;
|
2804
|
+
}
|
2805
|
+
|
2806
|
+
/*
|
2807
|
+
use_directive ::= {} `use` <clauses>
|
2808
|
+
*/
|
2809
|
+
static VALUE parse_use_directive(parserstate *state) {
|
2810
|
+
if (state->next_token.type == kUSE) {
|
2811
|
+
parser_advance(state);
|
2812
|
+
|
2813
|
+
range keyword_range = state->current_token.range;
|
2814
|
+
|
2815
|
+
VALUE clauses = rb_ary_new();
|
2816
|
+
parse_use_clauses(state, clauses);
|
2817
|
+
|
2818
|
+
range directive_range = keyword_range;
|
2819
|
+
directive_range.end = state->current_token.range.end;
|
2820
|
+
|
2821
|
+
VALUE location = rbs_new_location(state->buffer, directive_range);
|
2822
|
+
rbs_loc *loc = rbs_check_location(location);
|
2823
|
+
rbs_loc_alloc_children(loc, 1);
|
2824
|
+
rbs_loc_add_required_child(loc, INTERN("keyword"), keyword_range);
|
2825
|
+
|
2826
|
+
return rbs_ast_directives_use(clauses, location);
|
2827
|
+
} else {
|
2828
|
+
return Qnil;
|
2829
|
+
}
|
2830
|
+
}
|
2831
|
+
|
2832
|
+
VALUE parse_signature(parserstate *state) {
|
2833
|
+
VALUE dirs = EMPTY_ARRAY;
|
2834
|
+
VALUE decls = EMPTY_ARRAY;
|
2835
|
+
|
2836
|
+
while (state->next_token.type == kUSE) {
|
2837
|
+
melt_array(&dirs);
|
2838
|
+
rb_ary_push(dirs, parse_use_directive(state));
|
2839
|
+
}
|
2840
|
+
|
2841
|
+
while (state->next_token.type != pEOF) {
|
2842
|
+
melt_array(&decls);
|
2843
|
+
rb_ary_push(decls, parse_decl(state));
|
2844
|
+
}
|
2845
|
+
|
2846
|
+
VALUE ret = rb_ary_new();
|
2847
|
+
rb_ary_push(ret, dirs);
|
2848
|
+
rb_ary_push(ret, decls);
|
2849
|
+
return ret;
|
2850
|
+
}
|
2851
|
+
|
2852
|
+
struct parse_type_arg {
|
2853
|
+
parserstate *parser;
|
2854
|
+
VALUE require_eof;
|
2855
|
+
};
|
2856
|
+
|
2857
|
+
static VALUE
|
2858
|
+
ensure_free_parser(VALUE parser) {
|
2859
|
+
free_parser((parserstate *)parser);
|
2860
|
+
return Qnil;
|
2861
|
+
}
|
2862
|
+
|
2863
|
+
static VALUE
|
2864
|
+
parse_type_try(VALUE a) {
|
2865
|
+
struct parse_type_arg *arg = (struct parse_type_arg *)a;
|
2866
|
+
|
2867
|
+
if (arg->parser->next_token.type == pEOF) {
|
2868
|
+
return Qnil;
|
2869
|
+
}
|
2870
|
+
|
2871
|
+
VALUE type = parse_type(arg->parser);
|
2872
|
+
|
2873
|
+
if (RB_TEST(arg->require_eof)) {
|
2874
|
+
parser_advance_assert(arg->parser, pEOF);
|
2875
|
+
}
|
2876
|
+
|
2877
|
+
return type;
|
2878
|
+
}
|
2879
|
+
|
2880
|
+
static VALUE
|
2881
|
+
rbsparser_parse_type(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE variables, VALUE require_eof)
|
2882
|
+
{
|
2883
|
+
VALUE string = rb_funcall(buffer, rb_intern("content"), 0);
|
2884
|
+
StringValue(string);
|
2885
|
+
lexstate *lexer = alloc_lexer(string, FIX2INT(start_pos), FIX2INT(end_pos));
|
2886
|
+
parserstate *parser = alloc_parser(buffer, lexer, FIX2INT(start_pos), FIX2INT(end_pos), variables);
|
2887
|
+
struct parse_type_arg arg = {
|
2888
|
+
parser,
|
2889
|
+
require_eof
|
2890
|
+
};
|
2891
|
+
return rb_ensure(parse_type_try, (VALUE)&arg, ensure_free_parser, (VALUE)parser);
|
2892
|
+
}
|
2893
|
+
|
2894
|
+
static VALUE
|
2895
|
+
parse_method_type_try(VALUE a) {
|
2896
|
+
struct parse_type_arg *arg = (struct parse_type_arg *)a;
|
2897
|
+
|
2898
|
+
if (arg->parser->next_token.type == pEOF) {
|
2899
|
+
return Qnil;
|
2900
|
+
}
|
2901
|
+
|
2902
|
+
VALUE method_type = parse_method_type(arg->parser);
|
2903
|
+
|
2904
|
+
if (RB_TEST(arg->require_eof)) {
|
2905
|
+
parser_advance_assert(arg->parser, pEOF);
|
2906
|
+
}
|
2907
|
+
|
2908
|
+
return method_type;
|
2909
|
+
}
|
2910
|
+
|
2911
|
+
static VALUE
|
2912
|
+
rbsparser_parse_method_type(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos, VALUE variables, VALUE require_eof)
|
2913
|
+
{
|
2914
|
+
VALUE string = rb_funcall(buffer, rb_intern("content"), 0);
|
2915
|
+
StringValue(string);
|
2916
|
+
lexstate *lexer = alloc_lexer(string, FIX2INT(start_pos), FIX2INT(end_pos));
|
2917
|
+
parserstate *parser = alloc_parser(buffer, lexer, FIX2INT(start_pos), FIX2INT(end_pos), variables);
|
2918
|
+
struct parse_type_arg arg = {
|
2919
|
+
parser,
|
2920
|
+
require_eof
|
2921
|
+
};
|
2922
|
+
return rb_ensure(parse_method_type_try, (VALUE)&arg, ensure_free_parser, (VALUE)parser);
|
2923
|
+
}
|
2924
|
+
|
2925
|
+
static VALUE
|
2926
|
+
parse_signature_try(VALUE a) {
|
2927
|
+
parserstate *parser = (parserstate *)a;
|
2928
|
+
return parse_signature(parser);
|
2929
|
+
}
|
2930
|
+
|
2931
|
+
static VALUE
|
2932
|
+
rbsparser_parse_signature(VALUE self, VALUE buffer, VALUE start_pos, VALUE end_pos)
|
2933
|
+
{
|
2934
|
+
VALUE string = rb_funcall(buffer, rb_intern("content"), 0);
|
2935
|
+
StringValue(string);
|
2936
|
+
lexstate *lexer = alloc_lexer(string, FIX2INT(start_pos), FIX2INT(end_pos));
|
2937
|
+
parserstate *parser = alloc_parser(buffer, lexer, FIX2INT(start_pos), FIX2INT(end_pos), Qnil);
|
2938
|
+
return rb_ensure(parse_signature_try, (VALUE)parser, ensure_free_parser, (VALUE)parser);
|
2939
|
+
}
|
2940
|
+
|
2941
|
+
static VALUE
|
2942
|
+
rbsparser_lex(VALUE self, VALUE buffer, VALUE end_pos) {
|
2943
|
+
VALUE string = rb_funcall(buffer, rb_intern("content"), 0);
|
2944
|
+
StringValue(string);
|
2945
|
+
lexstate *lexer = alloc_lexer(string, 0, FIX2INT(end_pos));
|
2946
|
+
VALUE results = rb_ary_new();
|
2947
|
+
|
2948
|
+
token token = NullToken;
|
2949
|
+
while (token.type != pEOF) {
|
2950
|
+
token = rbsparser_next_token(lexer);
|
2951
|
+
VALUE type = ID2SYM(rb_intern(token_type_str(token.type)));
|
2952
|
+
VALUE location = rbs_new_location(buffer, token.range);
|
2953
|
+
VALUE pair = rb_ary_new3(2, type, location);
|
2954
|
+
rb_ary_push(results, pair);
|
2955
|
+
}
|
2956
|
+
|
2957
|
+
free(lexer);
|
2958
|
+
|
2959
|
+
return results;
|
2960
|
+
}
|
2961
|
+
|
2962
|
+
void rbs__init_parser(void) {
|
2963
|
+
RBS_Parser = rb_define_class_under(RBS, "Parser", rb_cObject);
|
2964
|
+
rb_gc_register_mark_object(RBS_Parser);
|
2965
|
+
VALUE empty_array = rb_obj_freeze(rb_ary_new());
|
2966
|
+
rb_gc_register_mark_object(empty_array);
|
2967
|
+
EMPTY_ARRAY = empty_array;
|
2968
|
+
|
2969
|
+
rb_define_singleton_method(RBS_Parser, "_parse_type", rbsparser_parse_type, 5);
|
2970
|
+
rb_define_singleton_method(RBS_Parser, "_parse_method_type", rbsparser_parse_method_type, 5);
|
2971
|
+
rb_define_singleton_method(RBS_Parser, "_parse_signature", rbsparser_parse_signature, 3);
|
2972
|
+
rb_define_singleton_method(RBS_Parser, "_lex", rbsparser_lex, 2);
|
2973
|
+
}
|