Skip to content

Commit

Permalink
GDScript 2.0 mostly is ready
Browse files Browse the repository at this point in the history
  • Loading branch information
elamaunt committed Dec 20, 2023
1 parent b8a51f3 commit 0ba8644
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 12 deletions.
4 changes: 2 additions & 2 deletions src/GDShrapt.Reader.Tests/AssertHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ internal static void CompareCodeStrings(string s1, string s2)
}
#endif

Assert.AreEqual(s1, s2);
Assert.AreEqual(s1, s2, "The code strings are not same");
}

internal static void NoInvalidTokens(GDNode node)
Expand All @@ -47,7 +47,7 @@ internal static void NoInvalidTokens(GDNode node)
for (int i = 0; i < invalidTokens.Length; i++)
messageBuilder.AppendLine((i+1) + ". " + invalidTokens[i]);

Assert.AreEqual(0, invalidTokens.Length, messageBuilder.ToString());
Assert.AreEqual(0, invalidTokens.Length, messageBuilder.ToString(), "There are invalid tokens in the code");
}
}
}
88 changes: 88 additions & 0 deletions src/GDShrapt.Reader.Tests/ParsingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2215,5 +2215,93 @@ public void ParseInlinedLambda()
AssertHelper.CompareCodeStrings(code, @statementsList.ToString());
AssertHelper.NoInvalidTokens(@statementsList);
}

[TestMethod]
public void RpcAttributeTest()
{
var reader = new GDScriptReader();

var code = @"@rpc
func fn(): pass
@rpc(""any_peer"", ""unreliable_ordered"")
func fn_update_pos(): pass
@rpc(""authority"", ""call_remote"", ""unreliable"", 0) # Equivalent to @rpc
func fn_default(): pass";

var @class = reader.ParseFileContent(code);

var attributes = @class.AllNodes.OfType<GDClassMemberAttributeDeclaration>().ToArray();

Assert.AreEqual(3, attributes.Length);

Assert.AreEqual("@rpc", attributes[0].ToString());
Assert.AreEqual("@rpc(\"any_peer\", \"unreliable_ordered\")", attributes[1].ToString());
Assert.AreEqual("@rpc(\"authority\", \"call_remote\", \"unreliable\", 0)", attributes[2].ToString());

AssertHelper.CompareCodeStrings(code, @class.ToString());
AssertHelper.NoInvalidTokens(@class);
}

[TestMethod]
public void NewClassAttributesTest()
{
var reader = new GDScriptReader();

var code = @"@static_unload
@tool
extends Node";

var @class = reader.ParseFileContent(code);
var attributes = @class.AllNodes.OfType<GDClassMemberAttributeDeclaration>().ToArray();
Assert.AreEqual(3, attributes.Length);

Assert.AreEqual("@static_unload", attributes[0].ToString());
Assert.AreEqual("@tool", attributes[1].ToString());
Assert.AreEqual("extends Node", attributes[2].ToString());

AssertHelper.CompareCodeStrings(code, @class.ToString());
AssertHelper.NoInvalidTokens(@class);
}

[TestMethod]
public void StatementAtributesTest()
{
var reader = new GDScriptReader();

var code = @"func test():
print(""hello"")
return
@warning_ignore(""unreachable_code"")
print(""unreachable"")";

var @class = reader.ParseFileContent(code);

var attributes = @class.AllNodes.OfType<GDAttribute>().ToArray();
Assert.AreEqual(1, attributes.Length);

AssertHelper.CompareCodeStrings(code, @class.ToString());
AssertHelper.NoInvalidTokens(@class);
}

[TestMethod]
public void StatementAtributesTest2()
{
var reader = new GDScriptReader();

var code = @"func test():
print(""hello"")
return
@warning_ignore(""unreachable_code"") print(""unreachable"")";

var @class = reader.ParseFileContent(code);

var attributes = @class.AllNodes.OfType<GDAttribute>().ToArray();
Assert.AreEqual(1, attributes.Length);

AssertHelper.CompareCodeStrings(code, @class.ToString());
AssertHelper.NoInvalidTokens(@class);
}
}
}
10 changes: 9 additions & 1 deletion src/GDShrapt.Reader/Atributes/GDAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ public enum State
}

readonly GDTokensForm<State, GDAt, GDIdentifier, GDOpenBracket, GDExpressionsList, GDCloseBracket> _form;
readonly bool _parseWithoutBrackets;

public override GDTokensForm Form => _form;
public GDTokensForm<State, GDAt, GDIdentifier, GDOpenBracket, GDExpressionsList, GDCloseBracket> TypedForm => _form;

Expand All @@ -56,6 +58,12 @@ public GDAttribute()
_form = new GDTokensForm<State, GDAt, GDIdentifier, GDOpenBracket, GDExpressionsList, GDCloseBracket>(this);
}

internal GDAttribute(bool parseWithoutBrackets)
: this()
{
_parseWithoutBrackets = parseWithoutBrackets;
}

public override GDNode CreateEmptyInstance()
{
return new GDAttribute();
Expand Down Expand Up @@ -167,7 +175,7 @@ void ITokenSkipReceiver<GDOpenBracket>.HandleReceivedTokenSkip()
{
if (_form.IsOrLowerState(State.OpenBracket))
{
_form.State = State.Completed;
_form.State = _parseWithoutBrackets ? State.Parameters : State.Completed;
return;
}

Expand Down
5 changes: 5 additions & 0 deletions src/GDShrapt.Reader/Basics/GDNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,11 @@ void ITokenReceiver<GDSpace>.HandleReceivedToken(GDSpace token)
Form.AddBeforeActiveToken(token);
}

void ITokenReceiver.HandleReceivedToken(GDAttribute token)
{
Form.AddBeforeActiveToken(token);
}

void ITokenReceiver.HandleReceivedToken(GDSpace token)
{
Form.AddBeforeActiveToken(token);
Expand Down
1 change: 1 addition & 0 deletions src/GDShrapt.Reader/Basics/Receiving/ITokenReceiver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public interface ITokenReceiver
{
void HandleReceivedToken(GDComment token);
void HandleReceivedToken(GDSpace token);
void HandleReceivedToken(GDAttribute token);
void HandleReceivedToken(GDInvalidToken token);
void HandleReceivedToken(GDMultiLineSplitToken token);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@ public enum State
}

readonly GDTokensForm<State, GDAttribute> _form;
readonly bool _parseWithoutBrackets;

public override GDTokensForm Form => _form;
public GDTokensForm<State, GDAttribute> TypedForm => _form;

internal GDClassMemberAttributeDeclaration(int intendation)
internal GDClassMemberAttributeDeclaration(int intendation, bool parseWithoutBrackets)
: base(intendation)
{
_form = new GDTokensForm<State, GDAttribute>(this);
_parseWithoutBrackets = parseWithoutBrackets;
}

public GDClassMemberAttributeDeclaration()
Expand Down Expand Up @@ -57,7 +60,7 @@ internal override void HandleChar(char c, GDReadingState state)
return;
}

Attribute = state.PushAndPass(new GDAttribute(), c);
Attribute = state.PushAndPass(new GDAttribute(_parseWithoutBrackets), c);
_form.State = State.Completed;
break;
default:
Expand Down
5 changes: 5 additions & 0 deletions src/GDShrapt.Reader/GDReceiver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ public void HandleReceivedToken(GDComment token)
Tokens.Add(token);
}

public void HandleReceivedToken(GDAttribute token)
{
Tokens.Add(token);
}

public void HandleReceivedToken(GDNewLine token)
{
Tokens.Add(token);
Expand Down
4 changes: 2 additions & 2 deletions src/GDShrapt.Reader/GDShrapt.Reader.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ Usage: Just create GDScriptReader instance and call methods from it.</Descriptio
<RepositoryUrl>https://github.com/elamaunt/GDShrapt</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>GDShrapt GDScript reader parser codegeneration Godot lexical analyzer</PackageTags>
<AssemblyVersion>3.2.1</AssemblyVersion>
<FileVersion>3.2.1</FileVersion>
<AssemblyVersion>4.0.0</AssemblyVersion>
<FileVersion>4.0.0</FileVersion>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>

Expand Down
20 changes: 16 additions & 4 deletions src/GDShrapt.Reader/Resolvers/GDClassMembersResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,10 @@ private void Complete(GDReadingState state, string sequence)

if (sequence[0] == '@')
{
Owner.HandleReceivedToken(state.Push(new GDClassMemberAttributeDeclaration(LineIntendationThreshold)));
Owner.HandleReceivedToken(state.Push(new GDClassMemberAttributeDeclaration(LineIntendationThreshold, false)));

if (sequence != null)
for (int i = 0; i < sequence.Length; i++)
state.PassChar(sequence[i]);
for (int i = 0; i < sequence.Length; i++)
state.PassChar(sequence[i]);

return;
}
Expand Down Expand Up @@ -190,6 +189,19 @@ void HandleStaticIfMet(ITokenReceiver<GDSpace> spaceReceiver, Action push, bool

switch (sequence)
{
case "tool":
case "extends":
case "class_name":
{
// Invalid order of the atributes found.
// Handling them as a ClassMemberAttribute instances.
// TODO: rework to GDClassCustomAttribute.
Owner.HandleReceivedToken(state.Push(new GDClassMemberAttributeDeclaration(LineIntendationThreshold, true)));

for (int i = 0; i < sequence.Length; i++)
state.PassChar(sequence[i]);
}
break;
case "signal":
{
var m = new GDSignalDeclaration(LineIntendationThreshold);
Expand Down
6 changes: 6 additions & 0 deletions src/GDShrapt.Reader/Resolvers/GDContentResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ private void HandleSequence(string seq, GDReadingState state)
case "signal":
case "const":
case "class":
case "@static_unload":
case "static":
case "@onready":
case "onready":
Owner.HandleReceivedToken(state.Push(new GDInnerClassDeclaration(CalculatedIntendation)));
break;
Expand All @@ -71,13 +73,17 @@ private void HandleSequence(string seq, GDReadingState state)
case "extends":
case "class_name":
case "tool":
case "@tool":
case "var":
case "func":
case "const":
case "signal":
case "export":
case "@export":
case "class":
case "@static_unload":
case "static":
case "@onready":
case "onready":
Owner.HandleReceivedToken(state.Push(new GDClassDeclaration()));
break;
Expand Down
5 changes: 5 additions & 0 deletions src/GDShrapt.Reader/Resolvers/GDExpressionResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,11 @@ public void HandleReceivedToken(GDComment token)
Owner.HandleReceivedToken(token);
}

public void HandleReceivedToken(GDAttribute token)
{
Owner.HandleReceivedToken(token);
}

public void HandleReceivedToken(GDSpace token)
{
Owner.HandleReceivedToken(token);
Expand Down
11 changes: 10 additions & 1 deletion src/GDShrapt.Reader/Resolvers/GDStatementsResolver.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text;
using System;
using System.Text;

namespace GDShrapt.Reader
{
Expand Down Expand Up @@ -50,6 +51,14 @@ internal override void HandleCharAfterIntendation(char c, GDReadingState state)
return;
}

if (c == '@')
{
SendIntendationTokensToOwner();
Owner.HandleReceivedToken(state.Push(new GDAttribute()));
state.PassChar(c);
return;
}

if (char.IsLetter(c))
{
_sequenceBuilder.Append(c);
Expand Down
5 changes: 5 additions & 0 deletions src/GDShrapt.Reader/Resolvers/GDTypeResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,11 @@ void ITokenReceiver<GDStringNode>.HandleReceivedToken(GDStringNode token)
_string = token;
}

void ITokenReceiver.HandleReceivedToken(GDAttribute token)
{
throw new GDInvalidStateException();
}

void ITokenSkipReceiver<GDStringNode>.HandleReceivedTokenSkip()
{
throw new GDInvalidStateException();
Expand Down

0 comments on commit 0ba8644

Please sign in to comment.