Skip to content

Commit

Permalink
Improved properties parsing. Fixed comma bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
elamaunt committed Jan 30, 2024
1 parent 63f00e7 commit 562889a
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 61 deletions.
32 changes: 28 additions & 4 deletions src/GDShrapt.Reader.Tests/ParsingTests.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Linq;
using System.Security.Claims;
using System.Threading;
using System.Xml.Linq;
using static GDShrapt.Reader.GD;

namespace GDShrapt.Reader.Tests
{
Expand Down Expand Up @@ -2249,6 +2245,34 @@ func _update_score_display():
AssertHelper.NoInvalidTokens(@class);
}

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

var code = @"var prop:
set ( value ) :
print(value)
get :
return 0
var prop2:
set = _setter,
get = _getter
var prop3: set=_setter, \
get=_getter
var prop4: set\
=_setter, get\
=_getter";

var @class = reader.ParseFileContent(code);

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

[TestMethod]
public void ParseNewExportsTest()
{
Expand Down
15 changes: 15 additions & 0 deletions src/GDShrapt.Reader/Declarations/GDVariableDeclaration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,12 @@ internal override void HandleChar(char c, GDReadingState state)
this.ResolveComma(c, state);
break;
case State.SecondAccessorDeclarationNode:
if (c == ',' && Comma == null)
{
Comma = new GDComma();
return;
}

state.PushAndPass(new GDSetGetAccessorsResolver<GDVariableDeclaration>(this, !_skipComma, Intendation + 1), c);
break;
default:
Expand All @@ -194,6 +200,15 @@ internal override void HandleNewLineChar(GDReadingState state)

state.PopAndPassNewLine();
}
internal override void HandleLeftSlashChar(GDReadingState state)
{
if (_form.IsOrLowerState(State.FirstAccessorDeclarationNode))
{
_skipComma = true;
}

base.HandleLeftSlashChar(state);
}

public override GDNode CreateEmptyInstance()
{
Expand Down
229 changes: 172 additions & 57 deletions src/GDShrapt.Reader/Resolvers/GDSetGetAccessorsResolver.cs
Original file line number Diff line number Diff line change
@@ -1,94 +1,209 @@
namespace GDShrapt.Reader
using System.Text;

namespace GDShrapt.Reader
{
internal class GDSetGetAccessorsResolver<T> : GDIntendedPatternResolver
internal class GDSetGetAccessorsResolver<T> : GDIntendedResolver
where T : IIntendedTokenOrSkipReceiver<GDAccessorDeclaration>
{
public new T Owner { get; }

public GDSetGetAccessorsResolver(T owner, bool allowZeroIntendationOnFirstLine, int lineIntendation)
: base(owner, lineIntendation)
readonly StringBuilder _sequenceBuilder = new StringBuilder(8);

State _state = State.Initial;
bool _ignoreNewLine;

private enum State
{
AllowZeroIntendationOnFirstLine = allowZeroIntendationOnFirstLine;
Owner = owner;
Initial,
GotSetKeyword,
GotGetKeyword,
}

public override string[] GeneratePatterns()
public GDSetGetAccessorsResolver(T owner, bool allowZeroIntendationOnFirstLine, int lineIntendation)
: base(owner, lineIntendation)
{
return new string[]
{
"get",
"set",

"get=",
"set=",

"get:",
"set("
};
AllowZeroIntendationOnFirstLine = allowZeroIntendationOnFirstLine;
Owner = owner;
}

protected override void PatternMatched(string pattern, GDReadingState state)
internal override void HandleCharAfterIntendation(char c, GDReadingState state)
{
if (pattern != null)
SendIntendationTokensToOwner();

switch (pattern)
switch (_sequenceBuilder.Length)
{
case "set":
case 0:
if (c == 's')
{
// TODO: check the colon
var accessor = new GDSetAccessorMethodDeclaration(LineIntendationThreshold);
Owner.HandleReceivedToken(accessor);
state.Push(accessor);
break;
_sequenceBuilder.Append(c);
_state = State.GotSetKeyword;
}
case "set=":
else if (c == 'g')
{
var accessor = new GDSetAccessorMethodDeclaration(LineIntendationThreshold);
Owner.HandleReceivedToken(accessor);
state.Push(accessor);
break;
_sequenceBuilder.Append(c);
_state = State.GotGetKeyword;
}
case "set(":
else
{
// TODO: check spaces
var accessor = new GDSetAccessorBodyDeclaration(LineIntendationThreshold);
Owner.HandleReceivedToken(accessor);
state.Push(accessor);
break;
Owner.HandleReceivedTokenSkip();
state.Pop();
PassIntendationSequence(state);
state.PassChar(c);
}
case "get":
break;
case 1:
if (c == 'e')
{
// TODO: check the colon
var accessor = new GDGetAccessorMethodDeclaration(LineIntendationThreshold);
Owner.HandleReceivedToken(accessor);
state.Push(accessor);
break;
_sequenceBuilder.Append(c);
}
case "get=":
else
{
Owner.HandleReceivedTokenSkip();

state.Pop();
PassIntendationSequence(state);
state.PassChar(_sequenceBuilder[0]);
state.PassChar(c);
}
break;
case 2:
if (c == 't')
{
_sequenceBuilder.Append(c);
}
else
{
Owner.HandleReceivedTokenSkip();
state.Pop();
PassIntendationSequence(state);
state.PassChar(_sequenceBuilder[0]);
state.PassChar(_sequenceBuilder[1]);
state.PassChar(c);
}
break;
default:
if (c.IsSpace())
{
_sequenceBuilder.Append(c);
return;
}

if (_state == State.GotGetKeyword && c == ':')
{
var accessor = new GDGetAccessorMethodDeclaration(LineIntendationThreshold);
SendIntendationTokensToOwner();
state.Pop();
var accessor = new GDGetAccessorBodyDeclaration(LineIntendationThreshold);
Owner.HandleReceivedToken(accessor);
state.Push(accessor);
break;
PassStoredSequence(state);
state.PassChar(c);
return;
}
case "get:":

if (_state == State.GotSetKeyword && c == '(')
{
var accessor = new GDGetAccessorBodyDeclaration(LineIntendationThreshold);
SendIntendationTokensToOwner();
state.Pop();
var accessor = new GDSetAccessorBodyDeclaration(LineIntendationThreshold);
Owner.HandleReceivedToken(accessor);
state.Push(accessor);
break;
PassStoredSequence(state);
state.PassChar(c);
return;
}
default:

if (c == '=')
{
SendIntendationTokensToOwner();
state.Pop();

GDReader reader;
if (_state == State.GotGetKeyword)
{
var accessor = new GDGetAccessorMethodDeclaration(LineIntendationThreshold);
Owner.HandleReceivedToken(accessor);
reader = accessor;
}
else
{
var accessor = new GDSetAccessorMethodDeclaration(LineIntendationThreshold);
Owner.HandleReceivedToken(accessor);
reader = accessor;
}

state.Push(reader);
PassStoredSequence(state);
state.PassChar(c);

return;
}

Owner.HandleReceivedTokenSkip();
break;
state.Pop();
PassIntendationSequence(state);
PassStoredSequence(state);
state.PassChar(c);
return;
}
}

protected override void OnIntendationThresholdMet(GDReadingState state)
{
Owner.HandleReceivedTokenSkip();
base.OnIntendationThresholdMet(state);
}

internal override void HandleNewLineAfterIntendation(GDReadingState state)
{
if (_ignoreNewLine)
{
_sequenceBuilder.Append('\n');
_ignoreNewLine = false;
return;
}

if (pattern != null)
Owner.HandleReceivedTokenSkip();
state.Pop();
PassIntendationSequence(state);
PassStoredSequence(state);
state.PassNewLine();
}

internal override void HandleSharpCharAfterIntendation(GDReadingState state)
{
Owner.HandleReceivedTokenSkip();
state.Pop();
PassIntendationSequence(state);
PassStoredSequence(state);
state.PassSharpChar();
}

internal override void HandleLeftSlashCharAfterIntendation(GDReadingState state)
{
if (_sequenceBuilder.Length < 3)
{
for (int i = 0; i < pattern.Length; i++)
state.PassChar(pattern[i]);
Owner.HandleReceivedTokenSkip();
state.Pop();
PassIntendationSequence(state);
PassStoredSequence(state);
state.PassLeftSlashChar();
return;
}

_sequenceBuilder.Append('\\');
_ignoreNewLine = true;
}

private void PassStoredSequence(GDReadingState state)
{
for (int i = 0; i < _sequenceBuilder.Length; i++)
state.PassChar(_sequenceBuilder[i]);
}

internal override void ForceComplete(GDReadingState state)
{
base.ForceComplete(state);
Owner.HandleReceivedTokenSkip();
PassIntendationSequence(state);
PassStoredSequence(state);
}
}
}
7 changes: 7 additions & 0 deletions src/GDShrapt.Reader/SimpleTokens/GDType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ internal override void HandleSharpChar(GDReadingState state)
base.HandleSharpChar(state);
}

internal override void HandleLeftSlashChar(GDReadingState state)
{
if (_builder.Length > 0)
Sequence = _builder.ToString();
base.HandleLeftSlashChar(state);
}

internal override void ForceComplete(GDReadingState state)
{
if (_builder.Length > 0)
Expand Down

0 comments on commit 562889a

Please sign in to comment.