solargraph-dragonruby 0.2.0

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.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +56 -0
  3. data/CODE_OF_CONDUCT.md +10 -0
  4. data/LICENSE.txt +21 -0
  5. data/NOTICE +8 -0
  6. data/README.md +185 -0
  7. data/Rakefile +13 -0
  8. data/lib/solargraph/dragonruby/convention.rb +43 -0
  9. data/lib/solargraph/dragonruby/macro_node.rb +44 -0
  10. data/lib/solargraph/dragonruby/version.rb +7 -0
  11. data/lib/solargraph/dragonruby.rb +15 -0
  12. data/lib/solargraph-dragonruby.rb +5 -0
  13. data/sig/solargraph/dragonruby.rbs +19 -0
  14. data/stubs/extensions/README.md +20 -0
  15. data/stubs/extensions/args.rb +91 -0
  16. data/stubs/extensions/array.rb +25 -0
  17. data/stubs/extensions/attr.rb +249 -0
  18. data/stubs/extensions/easing.rb +90 -0
  19. data/stubs/extensions/entity.rb +63 -0
  20. data/stubs/extensions/geometry.rb +528 -0
  21. data/stubs/extensions/grid.rb +247 -0
  22. data/stubs/extensions/inputs.rb +678 -0
  23. data/stubs/extensions/layout.rb +175 -0
  24. data/stubs/extensions/log.rb +158 -0
  25. data/stubs/extensions/main.rb +63 -0
  26. data/stubs/extensions/numeric.rb +395 -0
  27. data/stubs/extensions/outputs.rb +132 -0
  28. data/stubs/extensions/runtime.rb +436 -0
  29. data/stubs/extensions/string.rb +85 -0
  30. data/stubs/extensions/typing.rb +193 -0
  31. data/stubs/extensions/zlib.rb +24 -0
  32. data/stubs/upstream/LICENSE.txt +21 -0
  33. data/stubs/upstream/UPSTREAM +2 -0
  34. data/stubs/upstream/args.rb +61 -0
  35. data/stubs/upstream/constants.rb +8 -0
  36. data/stubs/upstream/controller.rb +90 -0
  37. data/stubs/upstream/easing.rb +119 -0
  38. data/stubs/upstream/geometry.rb +430 -0
  39. data/stubs/upstream/globals.rb +17 -0
  40. data/stubs/upstream/gtk.rb +476 -0
  41. data/stubs/upstream/inputs.rb +286 -0
  42. data/stubs/upstream/kernel.rb +7 -0
  43. data/stubs/upstream/keyboard.rb +38 -0
  44. data/stubs/upstream/layout.rb +32 -0
  45. data/stubs/upstream/numeric.rb +82 -0
  46. data/stubs/upstream/outputs.rb +55 -0
  47. data/stubs/upstream/outputs_array.rb +4 -0
  48. data/stubs/upstream/phantom_types.rb +25 -0
  49. data/stubs/upstream/toplevel.rb +13 -0
  50. metadata +107 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 69f9b6b80173020c3d7aec40a6f782716dfd0b42da4894216b0d380e7115bf27
4
+ data.tar.gz: 885052b696f737c49425ee95b57114c9e40ff211f5c358050e8bc56cb8a02830
5
+ SHA512:
6
+ metadata.gz: 43ecc336e05490e0e9edaa820964a514a2f449cb60b363703afbbbe76a0b3609f4d39af11d21a66015e55243d3b6383d1b160d0f10c868dcce940652b6db6f6e
7
+ data.tar.gz: a5beca5b99d1f3e00427364b187d83c9f19b71a86e7e5e4927dd1b60e6deaa3f6343032e306b438279f4b79538503e57fe9f97ed34624967edbb38bb1a96525c
data/CHANGELOG.md ADDED
@@ -0,0 +1,56 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.2.0] - 2026-10-08
4
+
5
+ - Adds `module Main` support: the `boot`/`start`/`tick`/`reset`/`did_reset`/`shutdown` hooks type `args` as
6
+ `GTK::Args` when they take it, and `args`, `inputs`, `outputs`, `state` (a `Hash`), `events` and `audio`
7
+ complete as bare calls inside `Main`.
8
+ - Adds the `attr_dr`/`attr_gtk`, `attr_sprite`, `attr_rect`, `attr_label` and `attr_line` class macros: a call in a
9
+ class body (or instance method) is treated as including `AttrDR`, `AttrSprite`, `AttrRect`, `AttrLabel` or `AttrLine`,
10
+ so their methods complete on `self` and on instances.
11
+ - Adds documented APIs that were missing:
12
+ - Inputs: mouse `key_down`/`key_held`/`key_up`, `rect`/`point` (with `offset:`), the combined keyboard or controller
13
+ `args.inputs.key_down`/`key_held`/`key_up`, `left_right_dpad`/`left_right_perc_dpad`/`up_down_arrow` and the other
14
+ top-level aliases, `Keyboard#directional_vector`/`directional_angle`, and `args.inputs.touch` values (`FingerTouch`)
15
+ - Keyboard keys: `f1`–`f12`, the numpad, `home`/`end`/`page_up`/`page_down`/`insert`, `caps_lock`, and more symbols
16
+ - `Easing.spline`, `Numeric.compose_blendmode` and the `BLENDFACTOR_*`/`BLENDOPERATION_*` constants,
17
+ `Numeric#mid?`/`between?`/`min`/`max` and `Numeric.mid`, `args.audio.volume`, and `Zlib`
18
+ - Fixes the signatures of `Easing.smooth_start`/`smooth_stop`/`smooth_step` (keyword arguments) and `Numeric#mid`.
19
+ - Adds undocumented APIs that the runtime and sample apps use:
20
+ - Numeric: `randomize`, `rand_sign`, `half`, `to_vector`, `towards`, `from_right`/`from_left`/`from_bottom`,
21
+ `sin`/`cos`/`tan` (and `_d`/`_r`), `ease`/`ease_spline`, `to_sf(decimal_places:, include_sign:)`, ...
22
+ - `Grid.x`/`y`/`center`/`w_half`/`h_half`, `origin_center?`, `letterbox?`, `hd?` and more pixel-category properties
23
+ - `Layout.rect_group`, `rects`, `point`, `rect_center`, `font_size_*`, `safe_rect`, ...
24
+ - `Geometry.line_slope`, `line_length`, `line_rect`, `rect_to_line`, `cubic_bezier`, `circle?`, ...
25
+ - Inputs: `directional_vector`/`directional_angle` (on inputs, keyboard key states and controllers), more mouse
26
+ properties (`position`, `held`, `left`, `click_at`, `key_down?`, ...), `finger_one`/`finger_two`, `pinch_zoom`
27
+ - `String#wrapped_lines`, `String.line_anchors`, `trim`, ..., and the global `log_info`/`log_warn`/`log_once`/... functions
28
+ - `DR.pause!`, `serialize_state`/`deserialize_state`, `set_rng`, `notify`, `http_head`/`http_put`, `platform`, ...,
29
+ `outputs.render_target_state`, `outputs.a11y`, `watch_fps`, and `File.append`
30
+ - Fixes the `Layout.rect` signature (keyword arguments).
31
+ - Types the Hashes DragonRuby returns, so their fields complete (`Geometry.vec2_add(a, b).x`,
32
+ `Layout.rect(...).center.x`, `DR.http_get(url).response_data`, ...): adds phantom `Typing::PointHash`, `RectHash`,
33
+ `RectPropsHash`, `LineHash`, `CircleHash`, `ColorHash`, `SizeHash`, and record types for `Numeric#frame`, http
34
+ responses, `DR.stat_file`, `keyboard.keys` and render target state. Shape parameters are documented as
35
+ `[Typing::Rect, Object]` (and `Point`, `Line`, `Circle`), which still accepts any value.
36
+ - Types `MouseButton#click`/`down`/`held`/`up` as `MousePoint`, `Easing.ease` definitions as `Array<Symbol, Proc>`, and
37
+ makes `Layout.rect_group`/`point` and `Numeric#to_layout_*` take keyword arguments.
38
+ - Fixes upstream Geometry docs: `line_intersect`/`ray_intersect` return types, mismatched parameter names, and the
39
+ signatures of `inside_rect?`, `point_inside_circle?`, `rotate_point`, `rect_navigate`, `zoom_rect`, `line_to_points`, ...
40
+
41
+ ## [0.1.0] - 2026-10-07
42
+
43
+ - Initial release: Solargraph plugin (`plugins: [solargraph-dragonruby]`) that adds DragonRuby API pins.
44
+ - Vendors the YARD stubs from owenbutler/dragonruby-yard-doc @ 06cc3d1 (`rake stubs:sync` to update).
45
+ - Adds coverage for `args.state`/entities, `Grid`, `DR`, events, pixel arrays, keyboard/controller/mouse
46
+ details, `vec2_*` and other Geometry functions, the Geometry mixin on Hash/Array, and Numeric/Array/Layout helpers.
47
+ - Adds Indie/Pro APIs: `outputs.shader`, `DR.get_dlopen_path`, `DR.start_text_input`/`stop_text_input`,
48
+ `args.inputs.http_requests` (with `HTTPRequest#respond`/`reject`), and `Layout.allscreen_rect`.
49
+ - Notes the required license tier in the docs of Indie/Pro APIs, including upstream's `dlopen` and HD functions
50
+ and `Grid`'s all-screen, pixel-category and scale properties.
51
+ - Types `buffered_click`/`buffered_held` as `MousePoint` (DragonRuby 7.22), adds them on `Mouse` along with
52
+ `MousePoint#x`/`#y`, and types `args.inputs.text` as `Array<String>`.
53
+ - Requires Solargraph 0.61.x.
54
+
55
+ [Unreleased]: https://github.com/asimmons91/solargraph-dragonruby/compare/v0.2.0...HEAD
56
+ [0.2.0]: https://github.com/asimmons91/solargraph-dragonruby/compare/v0.1.0...v0.2.0
@@ -0,0 +1,10 @@
1
+ # Code of Conduct
2
+
3
+ "solargraph-dragonruby" follows [The Ruby Community Conduct Guideline](https://www.ruby-lang.org/en/conduct) in all "collaborative space", which is defined as community communications channels (such as mailing lists, submitted patches, commit comments, etc.):
4
+
5
+ * Participants will be tolerant of opposing views.
6
+ * Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks.
7
+ * When interpreting the words and actions of others, participants should always assume good intentions.
8
+ * Behaviour which can be reasonably considered harassment will not be tolerated.
9
+
10
+ If you have any concerns about behaviour within this project, please contact us at ["austin_simmons@fastmail.com"](mailto:"austin_simmons@fastmail.com").
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2026 Austin Simmons
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/NOTICE ADDED
@@ -0,0 +1,8 @@
1
+ solargraph-dragonruby
2
+ Copyright (c) 2026 Austin Simmons. MIT License, see LICENSE.txt.
3
+
4
+ This project includes third-party files:
5
+
6
+ stubs/upstream/
7
+ Vendored from https://github.com/owenbutler/dragonruby-yard-doc
8
+ Copyright (c) 2024 Owen Butler. MIT License, see stubs/upstream/LICENSE.txt.
data/README.md ADDED
@@ -0,0 +1,185 @@
1
+ # solargraph-dragonruby
2
+
3
+ A [Solargraph](https://solargraph.org) plugin that gives LSP editors autocomplete,
4
+ hover docs and go-to-definition for the [DragonRuby Game Toolkit](https://dragonruby.org) API:
5
+ `args.outputs`, `args.inputs`, `args.state`, `$gtk`/`DR`, `Grid`, `Geometry`, `Layout`, `Easing`, and more.
6
+
7
+ ```ruby
8
+ def tick args # args is typed as GTK::Args automatically
9
+ args.outputs.sprites << { ... } # completes outputs, inputs, state, grid, events, ...
10
+ if args.inputs.keyboard.key_down.space
11
+ DR.notify! "jump"
12
+ end
13
+ end
14
+ ```
15
+
16
+ The `module Main` entry point works too:
17
+
18
+ ```ruby
19
+ module Main
20
+ def start # boot, start, tick, reset, ... with or without args
21
+ state.score = 0 # state is a Hash in Main
22
+ end
23
+
24
+ def tick
25
+ outputs.labels << { ... } # args, inputs, outputs, state, events and audio complete bare
26
+ end
27
+ end
28
+ ```
29
+
30
+ So do DragonRuby's class macros:
31
+
32
+ ```ruby
33
+ class Ship
34
+ attr_sprite # x, y, w, h, path, angle, ... plus top, right, intersect_rect?, ...
35
+ end
36
+
37
+ class Game
38
+ attr_dr # or attr_gtk: args, state, inputs, outputs, grid, ... on self
39
+ end
40
+ ```
41
+
42
+ The API definitions are YARD stubs. Most of them come from
43
+ [owenbutler/dragonruby-yard-doc](https://github.com/owenbutler/dragonruby-yard-doc),
44
+ with extra coverage added here (see [What's covered](#whats-covered)).
45
+
46
+ ## Requirements
47
+
48
+ - A CRuby install. DragonRuby doesn't need one, but Solargraph does.
49
+ - Solargraph 0.61.x: `gem install solargraph -v '~> 0.61.0'`
50
+ - An editor configured to use the Solargraph language server (see [Editor setup](#editor-setup))
51
+
52
+ ## Installation
53
+
54
+ Install the gem into the same Ruby that runs `solargraph`:
55
+
56
+ ```sh
57
+ gem install solargraph-dragonruby
58
+ ```
59
+
60
+ Then create a `.solargraph.yml` in your game's root directory (`solargraph config` generates
61
+ a default one) and add the plugin:
62
+
63
+ ```yml
64
+ include:
65
+ - "mygame/app/**/*.rb"
66
+ plugins:
67
+ - solargraph-dragonruby
68
+ ```
69
+
70
+ Restart your editor's language server.
71
+
72
+ ### Migrating from a dragonruby-yard-doc checkout
73
+
74
+ If your `.solargraph.yml` includes a cloned copy of the stubs (for example
75
+ `../dragonruby-yard-doc/*.rb`), remove that line. Otherwise every definition is
76
+ indexed twice.
77
+
78
+ ## What's covered
79
+
80
+ - **From dragonruby-yard-doc** (`stubs/upstream`): `GTK::Args`, `GTK::Runtime` (`$gtk`, `$dr`),
81
+ outputs, inputs (keyboard, mouse, controllers), `Geometry`, `Easing`, `Layout`, `Numeric`
82
+ extensions, `Kernel.tick_count`, and the `tick`/`boot`/`reset` hooks.
83
+ - **Added here** (`stubs/extensions`), checked against the DragonRuby 7.22 docs, sample apps and open-source runtime:
84
+ - `module Main`: the `boot`/`start`/`tick`/`reset`/`did_reset`/`shutdown` hooks (with or without `args`) and bare
85
+ `args`/`inputs`/`outputs`/`state`/`events`/`audio`, with `state` typed as `Hash`
86
+ - `args.state` (entities, `new_entity`, `new_entity_strict`), `args.grid`, `args.events`, `args.pixel_array(s)`
87
+ - The `DR` and `Grid` constants, plus the `$grid` and `$state` globals
88
+ - `Grid` orientation/origin, all-screen and pixel-category properties
89
+ - More `DR` functions: save data, env vars, window size/position, `on_tick_count`, `benchmark`, `reset_and_replay`, ...
90
+ - Keyboard key states (`key_down.space`, `key_held.truthy_keys`, `key_down?(:enter)`), WASD/arrow helpers
91
+ - Controller dpad and directional vectors, `accept`/`cancel`, and face button aliases (`south`, `east`, ...)
92
+ - `args.inputs.mouse.buttons.left.buffered_click` and the other mouse button properties, `mouse.key_down.left`,
93
+ `mouse.rect(offset:)`, and touch points (`args.inputs.touch`)
94
+ - The shared keyboard-or-controller `args.inputs.key_down.left` and the other key-state directions
95
+ - Function, numpad and navigation keys (`key_down.f1`, `kp_enter`, `page_down`, ...)
96
+ - `vec2_*` and other `Geometry` functions, and the Geometry mixin on `Hash`/`Array` (`rect.intersect_rect?(other)`)
97
+ - `Numeric#frame_index`, `elapsed_time`, `to_sf`, `mid?`, ..., plus `Array#map_2d`, `include_any?`, and `Layout.row_count`, ...
98
+ - `Easing.spline` and keyword `smooth_start`/`smooth_stop`/`smooth_step`, `Numeric.compose_blendmode` with the
99
+ `BLENDFACTOR_*`/`BLENDOPERATION_*` constants, `args.audio.volume`, and `Zlib`
100
+ - Undocumented APIs used by the sample apps: `10.randomize(:ratio, :sign)`, `Grid.center`, `Layout.rect_group`,
101
+ `Geometry.line_slope`, `String#wrapped_lines`, `log_info`, `DR.serialize_state`, `outputs.render_target_state`, ...
102
+ - `outputs.watch`/`outputs.debug.watch`, `outputs.sounds`, `did_reset`/`shutdown`, `Kernel.global_tick_count`
103
+ - The `attr_dr`/`attr_gtk`, `attr_sprite`, `attr_rect`, `attr_label` and `attr_line` class macros: calling one in a
104
+ class (or in one of its instance methods) completes the methods it adds
105
+ - **Indie and Pro APIs** are included. Their hover docs say which license tier they need:
106
+ - Shaders: `outputs.shader = { path:, uniforms:, textures: }` (Indie/Pro)
107
+ - C Extensions: `DR.dlopen`, `DR.get_dlopen_path` (Indie/Pro)
108
+ - HD and All Screen: `DR.set_hd_max_scale`, `set_hd_letterbox`, `toggle_hd_letterbox`, `Layout.allscreen_rect`,
109
+ and `Grid`'s all-screen, pixel-category and scale properties (Pro)
110
+ - `DR.start_text_input`/`stop_text_input`, `args.inputs.http_requests` (Pro)
111
+
112
+ Completions don't depend on your license, so check the hover note before relying on one of these.
113
+
114
+ Hashes that DragonRuby returns are typed by their shape, so their keys complete like methods:
115
+ `Geometry.vec2_add(a, b).x`, `Layout.rect(row: 0, col: 0).center.y`, `DR.http_get(url).response_data`. These
116
+ `Typing::*Hash` types are phantom types: they exist only in the stubs.
117
+
118
+ ## Editor setup
119
+
120
+ ### VS Code
121
+
122
+ Install the [Solargraph extension](https://marketplace.visualstudio.com/items?itemName=castwide.solargraph).
123
+
124
+ ### Vim/Neovim
125
+
126
+ Install the Solargraph LSP with [Mason](https://github.com/williamboman/mason.nvim), or point
127
+ your LSP client at `solargraph stdio`.
128
+
129
+ ### Sublime Text
130
+
131
+ Install the [LSP](https://lsp.sublimetext.io/) package, then add Solargraph under
132
+ `Settings > Package Settings > LSP > Settings`:
133
+
134
+ ```json
135
+ {
136
+ "clients": {
137
+ "solargraph": {
138
+ "enabled": true,
139
+ "command": ["solargraph", "stdio"],
140
+ "selector": "source.ruby",
141
+ "initializationOptions": { "diagnostics": true }
142
+ }
143
+ }
144
+ }
145
+ ```
146
+
147
+ ## Development
148
+
149
+ ```sh
150
+ bin/setup # install dependencies
151
+ bundle exec rake # tests + standardrb
152
+ bundle exec rake stubs:sync # re-vendor upstream stubs from main
153
+ bundle exec rake stubs:sync[<ref>] # ...or from a specific branch/tag
154
+ ```
155
+
156
+ - `stubs/upstream/` is vendored verbatim; `UPSTREAM` records the source commit. Don't edit it by hand.
157
+ - `stubs/extensions/` holds our additions. When an extension re-declares an upstream
158
+ method (for example to add a return type), the upstream definition is dropped.
159
+ - The Solargraph dependency is pinned to `~> 0.61.0`, because its plugin internals
160
+ change between minor releases. Re-run the tests before widening it.
161
+
162
+ ### Releasing
163
+
164
+ Add changes to the `## [Unreleased]` section of `CHANGELOG.md` as you go. To release:
165
+
166
+ ```sh
167
+ bundle exec rake release:prepare[minor] # or major, patch, or an explicit version like 1.2.3
168
+ git push origin main v0.2.0 # the command it prints
169
+ ```
170
+
171
+ `release:prepare` runs the tests, bumps `version.rb` and `Gemfile.lock`, moves the Unreleased notes under a
172
+ dated heading, and commits and tags the release. Pushing the tag runs `.github/workflows/release.yml`, which checks
173
+ that the tag, version and changelog agree, publishes the gem to RubyGems.org with
174
+ [Trusted Publishing](https://guides.rubygems.org/trusted-publishing/), and creates the GitHub release from that
175
+ version's changelog notes.
176
+
177
+ One-time setup: on RubyGems.org, add a trusted publisher for this repository with the workflow `release.yml` and
178
+ the environment `release` (use a "pending" trusted publisher if the gem has never been pushed).
179
+
180
+ ## Credits and license
181
+
182
+ The gem is available under the [MIT License](LICENSE.txt). The vendored stubs in
183
+ `stubs/upstream` come from [owenbutler/dragonruby-yard-doc](https://github.com/owenbutler/dragonruby-yard-doc)
184
+ and are by Owen Butler and contributors, also MIT licensed (see
185
+ [stubs/upstream/LICENSE.txt](stubs/upstream/LICENSE.txt)).
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "minitest/test_task"
5
+
6
+ Minitest::TestTask.create do |t|
7
+ # Solargraph and its dependencies emit many -w warnings on Ruby 4.0.
8
+ t.warning = false
9
+ end
10
+
11
+ require "standard/rake"
12
+
13
+ task default: %i[test standard]
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Dragonruby
5
+ # Adds pins parsed from the bundled DragonRuby YARD stubs to every ApiMap.
6
+ class Convention < Solargraph::Convention::Base
7
+ STUBS_DIR = File.expand_path("../../../stubs", __dir__)
8
+
9
+ # Parsed once per process. ApiMap#catalog asks for global pins on every
10
+ # re-map, and returning the same pin objects keeps the store from
11
+ # reindexing them.
12
+ #
13
+ # @return [Array<Solargraph::Pin::Base>]
14
+ def self.pins
15
+ @pins ||= begin
16
+ upstream = load_pins("upstream")
17
+ extensions = load_pins("extensions")
18
+ # Solargraph prefers the first method pin for a path, so an extension
19
+ # that re-declares an upstream method (e.g. to add a return type)
20
+ # only takes effect if the upstream pin is dropped.
21
+ overridden = extensions.grep(Solargraph::Pin::Method).to_set(&:path)
22
+ upstream.reject { |pin| pin.is_a?(Solargraph::Pin::Method) && overridden.include?(pin.path) }
23
+ .concat(extensions)
24
+ .freeze
25
+ end
26
+ end
27
+
28
+ # @param dir [String]
29
+ # @return [Array<Solargraph::Pin::Base>]
30
+ def self.load_pins(dir)
31
+ Dir[File.join(STUBS_DIR, dir, "*.rb")].sort
32
+ .flat_map { |path| Solargraph::SourceMap.load(path).all_pins }
33
+ end
34
+ private_class_method :load_pins
35
+
36
+ # @param _object [Object, nil] unused; Solargraph 0.61 passes nil
37
+ # @return [Solargraph::Environ]
38
+ def global(_object)
39
+ Solargraph::Environ.new(pins: self.class.pins.dup)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Dragonruby
5
+ # Maps DragonRuby's class macros (`attr_dr`, `attr_sprite`, ...) to the
6
+ # module each one includes (see stubs/extensions/attr.rb), so Solargraph
7
+ # treats `attr_sprite` like `include AttrSprite`.
8
+ #
9
+ # This is a node processor rather than a Convention#local because
10
+ # Solargraph 0.61 doesn't notice when a file's convention pins change, so
11
+ # adding or removing a macro wouldn't take effect until a restart.
12
+ class MacroNode < Solargraph::Parser::NodeProcessor::Base
13
+ MACROS = {
14
+ attr_dr: "AttrDR",
15
+ attr_gtk: "AttrDR",
16
+ attr_sprite: "AttrSprite",
17
+ attr_rect: "AttrRect",
18
+ attr_label: "AttrLabel",
19
+ attr_line: "AttrLine"
20
+ }.freeze
21
+
22
+ # Runs after Solargraph's own SendNode, which has already processed the
23
+ # children, so this only adds the include.
24
+ #
25
+ # @return [Boolean] true, so later :send processors still run
26
+ def process
27
+ receiver, name, *arguments = node.children
28
+ return true unless receiver.nil? && arguments.empty? && MACROS.key?(name) && region.scope != :class
29
+
30
+ # Called in an instance method, the macro includes into `self.class`.
31
+ closure = region.closure.is_a?(Solargraph::Pin::Method) ? region.closure.closure : region.closure
32
+ return true unless closure.is_a?(Solargraph::Pin::Namespace) && !closure.path.empty?
33
+
34
+ pins.push Solargraph::Pin::Reference::Include.new(
35
+ location: location,
36
+ closure: closure,
37
+ name: MACROS[name],
38
+ source: :dragonruby
39
+ )
40
+ true
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Dragonruby
5
+ VERSION = "0.2.0"
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "solargraph"
4
+ require_relative "dragonruby/version"
5
+ require_relative "dragonruby/convention"
6
+ require_relative "dragonruby/macro_node"
7
+
8
+ module Solargraph
9
+ # Solargraph plugin providing DragonRuby Game Toolkit API pins.
10
+ module Dragonruby
11
+ end
12
+ end
13
+
14
+ Solargraph::Convention.register Solargraph::Dragonruby::Convention
15
+ Solargraph::Parser::NodeProcessor.register :send, Solargraph::Dragonruby::MacroNode
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Entry point for `.solargraph.yml` `plugins: [solargraph-dragonruby]`,
4
+ # which Solargraph loads with `require "solargraph-dragonruby"`.
5
+ require_relative "solargraph/dragonruby"
@@ -0,0 +1,19 @@
1
+ module Solargraph
2
+ module Dragonruby
3
+ VERSION: String
4
+
5
+ class Convention < Solargraph::Convention::Base
6
+ STUBS_DIR: String
7
+
8
+ def self.pins: () -> Array[Solargraph::Pin::Base]
9
+
10
+ def global: (untyped _object) -> Solargraph::Environ
11
+ end
12
+
13
+ class MacroNode < Solargraph::Parser::NodeProcessor::Base
14
+ MACROS: Hash[Symbol, String]
15
+
16
+ def process: () -> bool
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ # Extensions
2
+
3
+ YARD stubs for DragonRuby APIs that the vendored upstream stubs
4
+ (`../upstream`, synced from owenbutler/dragonruby-yard-doc) do not cover yet.
5
+
6
+ - Written against the DragonRuby 7.22 Pro SDK: the docs (`docs/api/*.md`),
7
+ the sample apps, and the open-source runtime (`docs/oss/dragon/*.rb`).
8
+ When they disagree, the runtime source and samples win. For example, the
9
+ docs still describe `outputs.shader_path`/`shader_tex1`, which no longer exist.
10
+ - Indie/Pro-only APIs say so in their doc comment ("Indie or Pro license." /
11
+ "Pro license.").
12
+ - These files reopen upstream classes. If one re-declares a method that
13
+ upstream already defines, the upstream pin is dropped (see
14
+ `Solargraph::Dragonruby::Convention.pins`), so the definition here wins.
15
+ - `rake stubs:sync` never touches this directory.
16
+ - Hashes with a known shape use the phantom types in `typing.rb`: return
17
+ `Typing::PointHash`, `Typing::RectHash`, ... (they subclass Hash), and type
18
+ shape parameters as `[Typing::Point, Object]`, `[Typing::Rect, Object]`, ...
19
+ Keep `Object` in parameter types: with only the phantom type,
20
+ `solargraph typecheck --level strict` rejects plain Hashes.
@@ -0,0 +1,91 @@
1
+ module GTK
2
+ class Args
3
+ # Property bag for your game's state. Values are retained across `tick`
4
+ # invocations and cleared by `DR.reset`. Arbitrarily nested properties
5
+ # are allowed, and a backing entity is created on your behalf.
6
+ #
7
+ # Recommended initialization (in `boot`): `args.state = {}`
8
+ #
9
+ # @return [GTK::OpenEntity]
10
+ attr_accessor :state
11
+
12
+ # Screen and canvas information. Also available globally as `Grid`
13
+ # (preferred) and `$grid`.
14
+ #
15
+ # @return [GTK::Grid]
16
+ attr_reader :grid
17
+
18
+ # Raw and window resize events.
19
+ #
20
+ # @return [GTK::Events]
21
+ attr_reader :events
22
+
23
+ # All pixel arrays created via #pixel_array, keyed by name.
24
+ #
25
+ # @return [Hash{Symbol => GTK::PixelArray}]
26
+ attr_reader :pixel_arrays
27
+
28
+ # Returns the pixel array named `name`, creating it if needed. Render it
29
+ # with `args.outputs.sprites << { ..., path: name }`.
30
+ #
31
+ # @param name [Symbol]
32
+ # @return [GTK::PixelArray]
33
+ def pixel_array name; end
34
+
35
+ # The runtime. Prefer the `DR` constant.
36
+ #
37
+ # @return [GTK::Runtime]
38
+ attr_reader :gtk
39
+
40
+ # Current tick of the game. Prefer `Kernel.tick_count`.
41
+ #
42
+ # @return [Integer]
43
+ attr_reader :tick_count
44
+
45
+ # Audio sources that are playing, keyed by name. Assign a Hash to play
46
+ # one (`args.audio[:music] = { input: "sounds/music.ogg", looping: true }`);
47
+ # a `:length` key (seconds) is added on the following tick.
48
+ #
49
+ # @return [AudioHash]
50
+ attr_reader :audio
51
+ end
52
+
53
+ class Events
54
+ # @return [Boolean] true if the window was resized or the orientation of the game changed.
55
+ attr_reader :resize_occurred
56
+
57
+ # @return [Boolean] true if the orientation of the game changed (only possible when
58
+ # `orientation` in `game_metadata.txt` is `landscape,portrait` or `portrait,landscape`).
59
+ attr_reader :orientation_changed
60
+
61
+ # Raw events. These are already reflected in the rest of the API, so this is
62
+ # mostly useful for debugging.
63
+ #
64
+ # @return [Array<Hash>]
65
+ attr_reader :raw
66
+ end
67
+
68
+ class PixelArray
69
+ # @return [Integer]
70
+ attr_accessor :w, :h
71
+
72
+ # Hexadecimal color values in ABGR format, starting at the top-left
73
+ # pixel. `nil` entries render as a checkerboard.
74
+ #
75
+ # @return [Array<Integer>]
76
+ attr_accessor :pixels
77
+ end
78
+ end
79
+
80
+ # The type of `args.audio`: a Hash of audio sources plus a global volume.
81
+ class AudioHash < Hash
82
+ # Global volume for all audio, from `0.0` to `1.0` (defaults to `1.0`, or
83
+ # `0.4` on iOS). Web builds in production return `0.0` while the game
84
+ # doesn't have focus.
85
+ #
86
+ # @return [Float]
87
+ attr_reader :volume
88
+
89
+ # @param value [Float] clamped to `0.0..1.0`
90
+ attr_writer :volume
91
+ end
@@ -0,0 +1,25 @@
1
+ class ::Array
2
+ # For an array of arrays, yields each element with its row and column index.
3
+ #
4
+ # @yieldparam row [Integer]
5
+ # @yieldparam col [Integer]
6
+ # @yieldparam value [Object]
7
+ # @return [Array<Array>]
8
+ def map_2d &block; end
9
+
10
+ # @param items [Array<Object>]
11
+ # @return [Boolean] true if any of `items` is in self
12
+ def include_any? *items; end
13
+
14
+ # @param other [Typing::Rect, Object] a rect
15
+ # @param tolerance [Float]
16
+ # @return [Boolean] true if any element intersects `other`
17
+ def any_intersect_rect? other, tolerance = 0.1; end
18
+
19
+ # Alias of `compact`.
20
+ # @return [Array]
21
+ def reject_nil; end
22
+
23
+ # @return [Array] self without `nil` or `false` items
24
+ def reject_false; end
25
+ end