-
Notifications
You must be signed in to change notification settings - Fork 629
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add GDScript support #3194
Add GDScript support #3194
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
--sort=no |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
a input.gd /^@export_range(start=0, end=100, step=1) var a = 5$/;" v annotations:export_range(start=0, end=100, step=1) | ||
s input.gd /^var s = "Hello"$/;" v annotations:export | ||
arr input.gd /^@onready var arr = [1, 2, 3]$/;" v annotations:onready | ||
dict input.gd /^var dict = {"key": "value", 2: 3}$/;" v | ||
typed_var input.gd /^var typed_var: int$/;" v typeref:typename:int | ||
inferred_type input.gd /^inferred_type\\$/;" v annotations:onready,export_multiline | ||
ANSWER input.gd /^const ANSWER = 42$/;" v typeref:typename:const | ||
THE_NAME input.gd /^const THE_NAME:String = "Charly"$/;" v typeref:typename:const String | ||
anon_enum_e3cc11790105 input.gd /^enum {UNIT_NEUTRAL, UNIT_ENEMY, UNIT_ALL}$/;" g | ||
Named input.gd /^enum Named {THING_1, THING_2, ANOTHER_THING=1}$/;" g | ||
v2 input.gd /^var v2 = Vector2(1, 2)$/;" v | ||
v3 input.gd /^var v3 = Vector3(1, 2, 3)$/;" v | ||
some_function input.gd /^func some_function(param1: Vector3, param2: int) -> int:$/;" f typeref:typename:int annotations:master | ||
param1 input.gd /^func some_function(param1: Vector3, param2: int) -> int:$/;" z function:some_function typeref:typename:Vector3 file: | ||
param2 input.gd /^func some_function(param1: Vector3, param2: int) -> int:$/;" z function:some_function typeref:typename:int file: | ||
local_var input.gd /^ var local_var = 5$/;" l function:some_function file: | ||
local_var2 input.gd /^ var local_var2 = param1 + 3$/;" l function:some_function file: | ||
something input.gd /^func something(p1, p2):$/;" f annotations:puppet | ||
p1 input.gd /^func something(p1, p2):$/;" z function:something file: | ||
p2 input.gd /^func something(p1, p2):$/;" z function:something file: | ||
Something input.gd /^class Something:$/;" c | ||
a input.gd /^ var a = 10$/;" v class:Something | ||
_private_var input.gd /^ const _private_var:String = "hi\\n\\\\escape"$/;" v class:Something typeref:typename:const String | ||
foooooooo input.gd /^ func foooooooo() -> String:$/;" m class:Something typeref:typename:String | ||
_init input.gd /^func _init():$/;" f | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you add a test case for method, module, enumerator, parameter, and local? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have lines that would be related to module, enumerator, parameter and local, not showing up in the test output though. Module is extends (kind of), enumerator is by the two enums, there's some functions with parameters and a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Put
to the args.ctags file. |
||
lv input.gd /^ var lv = Something.new()$/;" l function:_init file: |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
# Derived from https://docs.godotengine.org/en/latest/tutorials/scripting/gdscript/gdscript_basics.html | ||
|
||
# A file is a class! | ||
|
||
# Inheritance | ||
|
||
extends BaseClass | ||
|
||
# (optional) class definition with a custom icon | ||
|
||
class_name MyClass, "res://path/to/optional/icon.svg" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder MyClass should be tagged with "class" kind? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The class_name keyword in gdscript is a little bit weird. Actually, all files in GDScript are by default sort of anonymous classes. This actually means that the parser I've submitted is slightly incomplete, because it also needs to crawl the rest of the directory for .gd files with |
||
|
||
|
||
# Member variables | ||
|
||
@export_range(start=0, end=100, step=1) var a = 5 | ||
@export | ||
var s = "Hello" | ||
@onready var arr = [1, 2, 3] | ||
var dict = {"key": "value", 2: 3} | ||
var typed_var: int | ||
@onready | ||
@export_multiline | ||
var\ | ||
inferred_type\ | ||
:=\ | ||
"String" | ||
|
||
# Constants | ||
|
||
const ANSWER = 42 | ||
const THE_NAME:String = "Charly" | ||
|
||
# Enums | ||
|
||
enum {UNIT_NEUTRAL, UNIT_ENEMY, UNIT_ALL} | ||
enum Named {THING_1, THING_2, ANOTHER_THING=1} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that your parser has the ability to tag THING_1, THING_2,... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My first handwritten test case had lines for the enumerated values because I thought they'd show up. Thought this was how it was supposed to be, they do show up in the geany symbols list, back to checking code then. Local variables in functions also don't show up outside |
||
|
||
# Built-in vector types | ||
|
||
var v2 = Vector2(1, 2) | ||
var v3 = Vector3(1, 2, 3) | ||
|
||
|
||
# Function | ||
|
||
@master | ||
func some_function(param1: Vector3, param2: int) -> int: | ||
var local_var = 5 | ||
|
||
if param1 < local_var: | ||
print(param1) | ||
elif param2 > 5: | ||
print(param2) | ||
elif param2 == 2: | ||
print(20) | ||
elif param2 <= 2: | ||
print((-20 % | ||
|
||
|
||
|
||
3) / 5) | ||
else: | ||
print("Fail!") | ||
|
||
for i in range(20): | ||
print(i) | ||
|
||
while param2 != 0: | ||
param2 -= 1 | ||
|
||
var local_var2 = param1 + 3 | ||
return local_var2 | ||
|
||
|
||
# Functions override functions with the same name on the base/parent class. | ||
# If you still want to call them, use '.' (like 'super' in other languages). | ||
@puppet | ||
func something(p1, p2): | ||
.something(p1, p2) | ||
|
||
|
||
# Inner class | ||
|
||
class Something: | ||
var a = 10 | ||
const _private_var:String = "hi\n\\escape" | ||
func foooooooo() -> String: | ||
print(""" | ||
test\\ | ||
|
||
test""") | ||
return "" | ||
|
||
# Constructor | ||
|
||
func _init(): | ||
print("Constructed!") | ||
var lv = Something.new() | ||
print(lv.a) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one,
ANSWER
is tagged as av
, a variable.However, I think it should be tagged as a
const
orconstant
.How do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just followed the example of the first file with a constant variable that I saw in a grep, I went by
parser-cxx.r/cxx11-raw-strings.d/expected.tags
, which has:Which classifies them with v and puts const in the type, which I followed. GDScript does do a thing where you substitute the keyword
var
entirely with the wordconst
to declare a constant, but it's functionally the same as a constant variable I'd thinkThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I could drop into godot dev chat real quick and get a thought from there from someone who might have written const on which to prefer real quick
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are developers think differently.
constant
kind is used in https://github.com/syskrank/vim-gdscript-ctags .C
kind is used for constants in https://github.com/PrestonKnopp/gdtags .C/C++ parser takes a different approach. Base on the target language's sematic, the parser recognizes
const
is a part of a type.ctags is a low-level tool. If possible, ctags should represents different things in different ways. This is one of the mottos of u-ctags.
If you want you can map "const" kind items extracted in ctags to "variable" kind items in geany.
A questionable thing is "const" defined in a method. What kind we should use for it? My idea is just using "const".
Instead, we can delete the "local" kind. You may think deleting "local" kind conflicts with the motto.
However, it is acceptable because the scope: field of a tag for a local variable can represent the difference.
Let's think about the followig input:
The current parser output:
My idea:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the local type gets wiped in favor of metadata I'll have to figure out how to look at metadata to exclude locals from the symbol table in geany, otherwise this is probably fine I guess. Still feel like the relationship between const and var is more akin to C behavior despite the keywording though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here ctags is built from the source code I proposed in #3194.
Consider the following as input:
ctags-#3194's output:
--fields=+n
option is for attachingline:
fields:If we add
--fields=+Z
option to the command line,scope:
field markers are added. It helps us understand tags file:If we add
--fields=+ZK
option to the command line, the long-name of kinds are used. It helps us understand tags file:The question is how it will be if we use
variable
kind instead oflocal
. Let's replace "local" with "variable" with a text editor:Both using the kind information (parameter or variable) and the scope fields, you can distinguish all
x
.So I think deleting the
local
kind is acceptable in your use case.However, keeping is o.k. My original suggestion was introducing "const" kind.