Skip to content
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

GDScript: Add Self to reference a class from inside #74618

Closed
wants to merge 1 commit into from

Conversation

vonagam
Copy link
Contributor

@vonagam vonagam commented Mar 8, 2023

Add Self as a way to reference a class from inside its script.

class_name Global

const Constant := Self

class Extended extends Self:
  pass

static func static_func(instance: Self) -> Self:
  return instance

func instance_func() -> Self:
  return self

func test():
  assert(Self == Constant)
  assert(Self == Global)

  var extended := Extended.new()
  assert(extended is Self)

  var constructed := Self.new()
  assert(constructed is Self)

  var static_funced := Self.static_func(self)
  assert(static_funced is Self)

  var instance_funced := instance_func()
  assert(instance_funced is Self)

  var variable: Self = self
  assert(variable is Self)

While at it converted extends in ClassNode from Vector<StringName> to Vector<IdentifierNode *> - for better error placement.

And in is_shadowing removed bool return type and added a check for shadowing built-in types (var Array := 3, such check was done only for members before).

Implements proposal #391.

This is a simple implementation and Self here always points to the class where it is used, but it does not change its meaning with inheritance:

class A:
  static func create() -> Self:
    return Self.new()
    
class B extends A:
  pass
  
func _ready():
  var x := B.create()

Here x will be A, not B. I think that maybe it is desirable for it to be B - to match context dependent behavior of (potential future) type self. In that case there is a need for a separate name for simple type presented here.

Production edit: closes godotengine/godot-proposals#391

@vonagam vonagam requested a review from a team as a code owner March 8, 2023 20:18
@Calinou Calinou added this to the 4.1 milestone Mar 8, 2023
@dalexeev
Copy link
Member

dalexeev commented Mar 9, 2023

Here x will be A, not B. I think that maybe it is desirable for it to be B - to match context dependent behavior of (potential future) type self. In that case there is a need for a separate name for simple type presented here.

Yes, if we decide to add late static binding (like in PHP), then it should be a separate keyword/identifier.

@vonagam
Copy link
Contributor Author

vonagam commented Mar 20, 2023

I'll close this one for now. I think that Self type can be expected to be a type of self, what @dalexeev mentioned as late static binding. I've moved fixes into separate PRs and now they are merged.

As for accessing class without global pollution, I think maybe some new annotation can solve it:

@global(false)
class_name Foo

And if it can support strings as a value for a global name it might allow to expose nested classes and maybe have uses in plugin development:

@global("LongPluginNameFoo")
class_name Foo

  @global("GlobalBar")
  class Bar: pass

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

GDScript: Add keyword to access the current class
4 participants