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

Make export default class the main file class in GDScript, add support for subclasses #61

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
946cb1e
Proof of concept, export default is the main file class, others are s…
adamuso Dec 17, 2021
ddcea40
Fix dynamic defs generation and adjust test to use export default, al…
adamuso Dec 18, 2021
2753c88
Fix enum importing without file separation
adamuso Dec 18, 2021
b558ecd
Change inner classes import to preloading
adamuso Dec 18, 2021
5b3418e
Handle extending inner classes from other files
adamuso Dec 18, 2021
6687a9c
Implement anonymous classes
adamuso Dec 18, 2021
5894a26
Fix not taking into account declare classes
adamuso Dec 18, 2021
a544f34
Cleanup tests
adamuso Dec 18, 2021
1e9f87f
Handle inner classes super calls in constructor with arguments
adamuso Dec 19, 2021
bf51a77
Merge remote-tracking branch 'origin/HEAD' into support-for-multiple-…
adamuso Dec 19, 2021
1825ef2
Cleanup commented out code
adamuso Dec 19, 2021
e72f177
Merge branch 'johnfn:main' into support-for-multiple-classes-in-one-file
adamuso Dec 19, 2021
8381679
Fix node path def generation, refactor extending inner/anonymous classes
adamuso Dec 20, 2021
6030bc9
Fix not showing autoload error on non default class
adamuso Dec 21, 2021
ff497da
Update readme
adamuso Dec 21, 2021
c80d179
Merge branch 'main' into support-for-multiple-classes-in-one-file
adamuso Dec 21, 2021
c1f59dd
Fix tests after merging with main
adamuso Dec 21, 2021
f44ae4e
Merge commit '0d007f4b61ad131265d000ebda22f5708ba3ddbe' into support-…
adamuso Dec 23, 2021
fc82ee2
Merge remote-tracking branch 'origin/main' into support-for-multiple-…
adamuso Jan 4, 2022
060ec33
Change class declaration generation, single exported classes are now …
adamuso Jan 4, 2022
b43f26c
Adjust imports and dynamic defs generation
adamuso Jan 4, 2022
ced47d7
Add defs for main and inner attributes
adamuso Jan 4, 2022
e1ea6f2
Revert most test changes related to 'default'
adamuso Jan 4, 2022
b98306f
Revert accidental package-lock update and remove more default from tests
adamuso Jan 4, 2022
630d5ef
Update readme and main class check
adamuso Jan 4, 2022
a61f720
Update classes readme
adamuso Jan 15, 2022
751e2ee
Fix false positive tests when string is expected and add more autoloa…
adamuso Jan 15, 2022
4f65188
Make some error descriptions more user friendly
adamuso Jan 15, 2022
63756f6
Merge branch 'main' into support-for-multiple-classes-in-one-file
adamuso May 24, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .prettierignore

This file was deleted.

28 changes: 14 additions & 14 deletions parse_node/parse_call_expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ v1.distance_to(v1)

export const testArrowScoping: Test = {
ts: `
export class Foo {
export default class Foo {
a() {
const a = () => {};
}
Expand Down Expand Up @@ -513,7 +513,7 @@ d["b"] = 2
export const testConnect: Test = {
expectFail: true,
ts: `
export class Test extends Area2D {
export default class Test extends Area2D {
constructor() {
super()

Expand All @@ -537,7 +537,7 @@ func on_body_entered(_body):

export const testConnect2: Test = {
ts: `
export class Test extends Area2D {
export default class Test extends Area2D {
constructor() {
super()

Expand All @@ -559,7 +559,7 @@ func _ready():

export const testConnectWithClosures: Test = {
ts: `
export class Test extends Area2D {
export default class Test extends Area2D {
constructor() {
super()
let x = 1, y = 2;
Expand All @@ -584,7 +584,7 @@ func _ready():
// we intentionally do not capture `this` as self - see comment in parse_arrow_function.ts for rationale
export const testConnectWithClosuresNoThis: Test = {
ts: `
export class Test extends Area2D {
export default class Test extends Area2D {
constructor() {
super()
let x = 1, y = 2;
Expand All @@ -608,7 +608,7 @@ func _ready():

export const testConnectComplex: Test = {
ts: `
export class Test {
export default class Test {
enemies: any;

foo() {
Expand Down Expand Up @@ -643,7 +643,7 @@ d[[1, 2]] = 2

export const testEmitSignal: Test = {
ts: `
export class CityGridCollision extends Area {
export default class CityGridCollision extends Area {
$mouseenter!: Signal<[]>;
test() {
this.$mouseenter.emit()
Expand Down Expand Up @@ -678,7 +678,7 @@ __map(__filter(a, [funcref(self, "__gen"), {}]), [funcref(self, "__gen1"), {}])

export const testRewriteGetNode: Test = {
ts: `
export class Test {
export default class Test {
foo() {
this.get_node('hello')
}
Expand All @@ -694,7 +694,7 @@ func foo():

export const testRewriteGetNode2: Test = {
ts: `
export class Test {
export default class Test {
foo() {
this.get_node_unsafe('hello')
}
Expand Down Expand Up @@ -733,7 +733,7 @@ export const testFunctionNull: Test = {
x(): number | null;
}

export class Test {
export default class Test {
example() {
const thing: Foo = new Foo()
let result = thing.x()
Expand Down Expand Up @@ -782,7 +782,7 @@ x.get_node("Foo")

export const testConnectDirectlyToSig: Test = {
ts: `
export class Test extends Area2D {
export default class Test extends Area2D {
$mysig!: Signal

constructor() {
Expand All @@ -807,7 +807,7 @@ func _ready():

export const testNestedDirectSignalConnect: Test = {
ts: `
export class Test extends Area2D {
export default class Test extends Area2D {
$mysig!: Signal
test!: Test

Expand Down Expand Up @@ -839,7 +839,7 @@ func _ready():

export const testRpcRewrite: Test = {
ts: `
export class Test extends Area2D {
export default class Test extends Area2D {
rpc_me() {

}
Expand Down Expand Up @@ -879,7 +879,7 @@ func _ready():

export const testPassInFunction: Test = {
ts: `
export class Test extends Area2D {
export default class Test extends Area2D {
fn(other: () => void) {
other()
}
Expand Down
82 changes: 74 additions & 8 deletions parse_node/parse_class_declaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ export const parseClassDeclaration = (
node: ts.ClassDeclaration | ts.ClassExpression,
props: ParseState
): ParseNodeType => {
const modifiers = node.modifiers?.map((x) => x.getText())
const modifiers = (node.modifiers ?? []).map((x) => x.getText())

// skip class declarations; there's no code to generate here
if (modifiers?.includes("declare")) {
if (modifiers.includes("declare")) {
return combine({
parent: node,
nodes: [],
Expand All @@ -89,9 +89,13 @@ export const parseClassDeclaration = (
(dec) => dec.expression.getText() === "autoload"
)

if (!modifiers?.includes("export") && !isAutoload) {
if (
!modifiers.includes("export") &&
!modifiers.includes("default") &&
isAutoload
) {
addError({
description: "You must export this class.",
description: "Only class exported as default can be autoloaded.",
error: ErrorName.ClassMustBeExported,
location: node,
stack: new Error().stack ?? "",
Expand Down Expand Up @@ -124,18 +128,68 @@ ${members.join("")}
})
}

export const testRequireExportedClass: Test = {
export const testInnerClassExtends: Test = {
ts: `
export default class Test {
}

export class InnerTest extends Node2D {
field: int = 2;
}
`,
expected: `
class_name Test

class InnerTest extends Node2D:
var field: int = 2
`,
}

export const testInnerClassExtendsSuperCall: Test = {
ts: `
export default class Test {
}

export class InnerTest extends Node2D {
field: int = 2;

constructor() {
super();
}
}
`,
expected: `
class_name Test

class InnerTest extends Node2D:
var field: int = 2
func _init().():
pass
`,
}

export const testFileWithoutDefaultClass: Test = {
ts: `
class Foo {
x = 1
}

export class Foo2 {
x = 1
}`,
expected: { error: "You must export this class", type: "error" },
expected: `
class Foo:
var x: int = 1

class Foo2:
var x: int = 1
`,
}

export const testDontRequireExportingAutoloads: Test = {
ts: `
@autoload
class Foo {
export default class Foo {
x = 1
}`,
expected: `
Expand All @@ -147,7 +201,7 @@ var x: int = 1
export const testExportArgsSetGet: Test = {
ts: `
@autoload
class Foo {
export default class Foo {
@exports
get nodes(): PackedScene<Node2D>[] {
return [];
Expand All @@ -166,3 +220,15 @@ func nodes_set(_v):
pass
`,
}

export const testDontRequireDefaultExportingAutoloads: Test = {
ts: `
@autoload
class Foo {
x = 1
}`,
expected: {
adamuso marked this conversation as resolved.
Show resolved Hide resolved
error: "Only class exported as default can be autoloaded",
type: "error",
},
}
Loading