diff --git a/src/GDShrapt.Converter.Tests/ConversionTests.cs b/src/GDShrapt.Converter.Tests/ConversionTests.cs index 3cacd8c..c24c3e8 100644 --- a/src/GDShrapt.Converter.Tests/ConversionTests.cs +++ b/src/GDShrapt.Converter.Tests/ConversionTests.cs @@ -42,8 +42,8 @@ func save(path, resource, flags): ConvertGDScriptNamingStyleToSharp = true }); - var treeWalker = new GDTreeWalker(visitor); - treeWalker.WalkInNode(declaration); + // var treeWalker = new GDTreeWalker(visitor); + // treeWalker.WalkInNode(declaration); var csharpCode = visitor.BuildCSharpNormalisedCode(); diff --git a/src/GDShrapt.Converter/CSharpGeneratingVisitor.cs b/src/GDShrapt.Converter/CSharpGeneratingVisitor.cs index 8facc54..94d470c 100644 --- a/src/GDShrapt.Converter/CSharpGeneratingVisitor.cs +++ b/src/GDShrapt.Converter/CSharpGeneratingVisitor.cs @@ -9,7 +9,7 @@ namespace GDShrapt.Converter { - public class CSharpGeneratingVisitor : INodeVisitor + public class CSharpGeneratingVisitor //: INodeVisitor { private readonly ConversionSettings _settings; @@ -200,7 +200,7 @@ public void Visit(GDBracketExpression e) } ///////////////////////////////////////////////////////////////////////////////////////////////// - public void Visit(GDCallExression e) + public void Visit(GDCallExpression e) { } diff --git a/src/GDShrapt.Converter/Program.cs b/src/GDShrapt.Converter/Program.cs index 108b813..370b3b9 100644 --- a/src/GDShrapt.Converter/Program.cs +++ b/src/GDShrapt.Converter/Program.cs @@ -55,8 +55,8 @@ static void ParseFile(GDScriptReader parser, string filePath, string destination ConvertGDScriptNamingStyleToSharp = true }); - var treeWalker = new GDTreeWalker(visitor); - treeWalker.WalkInNode(declaration); + //var treeWalker = new GDTreeWalker(visitor); + //treeWalker.WalkInNode(declaration); // Generate C# code and save it in a file var newPath = Path.ChangeExtension(destinationPath, ".cs"); diff --git a/src/GDShrapt.Reader.Tests/ParsingTests.cs b/src/GDShrapt.Reader.Tests/ParsingTests.cs index 92ac887..41c9f95 100644 --- a/src/GDShrapt.Reader.Tests/ParsingTests.cs +++ b/src/GDShrapt.Reader.Tests/ParsingTests.cs @@ -346,7 +346,7 @@ public void ForStatementTest2() var forStatement = (GDForStatement)statement; Assert.AreEqual("i", forStatement.Variable?.Sequence); - Assert.IsInstanceOfType(forStatement.Collection, typeof(GDCallExression)); + Assert.IsInstanceOfType(forStatement.Collection, typeof(GDCallExpression)); Assert.AreEqual("range(2, 8, 2)", forStatement.Collection.ToString()); Assert.AreEqual(1, forStatement.Statements.Count); @@ -1348,7 +1348,7 @@ public void MethodsChainTest() Assert.AreEqual(GDDualOperatorType.Addition, dualOperator.OperatorType); - Assert.IsInstanceOfType(dualOperator.LeftExpression, typeof(GDCallExression)); + Assert.IsInstanceOfType(dualOperator.LeftExpression, typeof(GDCallExpression)); Assert.IsInstanceOfType(dualOperator.RightExpression, typeof(GDDualOperatorExression)); var rightDualOperator = (GDDualOperatorExression)dualOperator.RightExpression; @@ -1356,30 +1356,30 @@ public void MethodsChainTest() Assert.AreEqual(GDDualOperatorType.Division, rightDualOperator.OperatorType); Assert.AreEqual("D()", rightDualOperator.LeftExpression.ToString()); - Assert.IsInstanceOfType(rightDualOperator.RightExpression, typeof(GDCallExression)); + Assert.IsInstanceOfType(rightDualOperator.RightExpression, typeof(GDCallExpression)); - var rightCallExpression = (GDCallExression)rightDualOperator.RightExpression; + var rightCallExpression = (GDCallExpression)rightDualOperator.RightExpression; Assert.AreEqual("E()(\"test\")", rightCallExpression.ToString()); - var callExpression = (GDCallExression)dualOperator.LeftExpression; + var callExpression = (GDCallExpression)dualOperator.LeftExpression; Assert.AreEqual(0, callExpression.Parameters.Count); var memberOperatorExpression = callExpression.CallerExpression.CastOrAssert(); Assert.AreEqual("C", memberOperatorExpression.Identifier?.Sequence); - callExpression = memberOperatorExpression.CallerExpression.CastOrAssert(); + callExpression = memberOperatorExpression.CallerExpression.CastOrAssert(); Assert.AreEqual(0, callExpression.Parameters.Count); memberOperatorExpression = callExpression.CallerExpression.CastOrAssert(); Assert.AreEqual("B", memberOperatorExpression.Identifier?.Sequence); - callExpression = memberOperatorExpression.CallerExpression.CastOrAssert(); + callExpression = memberOperatorExpression.CallerExpression.CastOrAssert(); Assert.AreEqual(1, callExpression.Parameters.Count); Assert.AreEqual("-3", callExpression.Parameters.ToString()); - callExpression = callExpression.CallerExpression.CastOrAssert(); + callExpression = callExpression.CallerExpression.CastOrAssert(); Assert.AreEqual(0, callExpression.Parameters.Count); - callExpression = callExpression.CallerExpression.CastOrAssert(); + callExpression = callExpression.CallerExpression.CastOrAssert(); Assert.AreEqual(1, callExpression.Parameters.Count); Assert.AreEqual("1 + 2", callExpression.Parameters.ToString()); @@ -1428,7 +1428,7 @@ public void BaseMethodCallTest() Assert.IsInstanceOfType(callStatement.Tokens.Last(), typeof(GDSemiColon)); - var callExpression = callStatement.Expression.CastOrAssert(); + var callExpression = callStatement.Expression.CastOrAssert(); Assert.AreEqual("._init", callExpression.CallerExpression.ToString()); Assert.AreEqual("\"1234\"", callExpression.Parameters.ToString()); @@ -1468,7 +1468,7 @@ public void GetNodeTest() Assert.IsNotNull(expression); - var call = expression.CastOrAssert(); + var call = expression.CastOrAssert(); var memberOperator = call.CallerExpression.CastOrAssert(); Assert.AreEqual("CallMethod", memberOperator.Identifier.Sequence); @@ -1488,7 +1488,7 @@ public void NodePathTest() var expression = reader.ParseExpression(code); - var call = expression.CastOrAssert(); + var call = expression.CastOrAssert(); Assert.AreEqual("0", call.Parameters.ToString()); var memberOperator = call.CallerExpression.CastOrAssert(); diff --git a/src/GDShrapt.Reader.Tests/SyntaxTests.cs b/src/GDShrapt.Reader.Tests/SyntaxTests.cs index 63d0c2d..94e2891 100644 --- a/src/GDShrapt.Reader.Tests/SyntaxTests.cs +++ b/src/GDShrapt.Reader.Tests/SyntaxTests.cs @@ -137,5 +137,46 @@ public void DictionaryCodeStyleTest() Assert.AreEqual(2, expression.AllTokens.OfType().Count()); AssertHelper.CompareCodeStrings(code, "\n"+expression.ToString()); } + + [TestMethod] + public void SyntaxCloneTest() + { + var reader = new GDScriptReader(); + + var code = @" +# before tool comment +tool # tool comment + +# before class name comment +class_name HTerrainDataSaver # class name comment + +# before extends comment +extends ResourceFormatSaver # extends comment + +# before const comment +const HTerrainData = preload(""./ hterrain_data.gd"") # const comment + +# before func comment 1 +# before func comment 2 +func get_recognized_extensions(res): # func comment + + # before if statement comment + if res != null and res is HTerrainData: # if expression comment +# before return statement comment + return PoolStringArray([HTerrainData.META_EXTENSION]) # if true statement comment + + return PoolStringArray() + +# end file comment 1 +# end file comment 2 +"; + + var @class = reader.ParseFileContent(code); + + Assert.IsNotNull(@class); + + var clone = @class.Clone(); + AssertHelper.CompareCodeStrings(@class.ToString(), clone.ToString()); + } } } diff --git a/src/GDShrapt.Reader/Atributes/GDClassNameAtribute.cs b/src/GDShrapt.Reader/Atributes/GDClassNameAtribute.cs index ed29b87..39d5f6c 100644 --- a/src/GDShrapt.Reader/Atributes/GDClassNameAtribute.cs +++ b/src/GDShrapt.Reader/Atributes/GDClassNameAtribute.cs @@ -1,6 +1,6 @@ namespace GDShrapt.Reader { - public class GDClassNameAtribute : GDClassAtribute, + public sealed class GDClassNameAtribute : GDClassAtribute, IKeywordReceiver, IIdentifierReceiver, ITokenReceiver, diff --git a/src/GDShrapt.Reader/Atributes/GDExtendsAtribute.cs b/src/GDShrapt.Reader/Atributes/GDExtendsAtribute.cs index 80b514d..e189ef8 100644 --- a/src/GDShrapt.Reader/Atributes/GDExtendsAtribute.cs +++ b/src/GDShrapt.Reader/Atributes/GDExtendsAtribute.cs @@ -1,6 +1,6 @@ namespace GDShrapt.Reader { - public class GDExtendsAtribute : GDClassAtribute, + public sealed class GDExtendsAtribute : GDClassAtribute, IKeywordReceiver, ITypeReceiver, IStringReceiver diff --git a/src/GDShrapt.Reader/Atributes/GDToolAtribute.cs b/src/GDShrapt.Reader/Atributes/GDToolAtribute.cs index fd1b78b..f719499 100644 --- a/src/GDShrapt.Reader/Atributes/GDToolAtribute.cs +++ b/src/GDShrapt.Reader/Atributes/GDToolAtribute.cs @@ -1,6 +1,6 @@ namespace GDShrapt.Reader { - public class GDToolAtribute : GDClassAtribute, IKeywordReceiver + public sealed class GDToolAtribute : GDClassAtribute, IKeywordReceiver { internal GDToolKeyword ToolKeyword { diff --git a/src/GDShrapt.Reader/Basics/GDNode.cs b/src/GDShrapt.Reader/Basics/GDNode.cs index 09ffec0..9e61173 100644 --- a/src/GDShrapt.Reader/Basics/GDNode.cs +++ b/src/GDShrapt.Reader/Basics/GDNode.cs @@ -73,7 +73,7 @@ public override void AppendTo(StringBuilder builder) token.AppendTo(builder); } - public override string ToString() + public sealed override string ToString() { var builder = new StringBuilder(); @@ -92,7 +92,7 @@ public override string ToString() public override GDSyntaxToken Clone() { var node = CreateEmptyInstance(); - node.Form.CloneFrom(node.Form); + node.Form.CloneFrom(Form); return node; } diff --git a/src/GDShrapt.Reader/GDShrapt.Reader.csproj b/src/GDShrapt.Reader/GDShrapt.Reader.csproj index d5b7204..0329e7d 100644 --- a/src/GDShrapt.Reader/GDShrapt.Reader.csproj +++ b/src/GDShrapt.Reader/GDShrapt.Reader.csproj @@ -3,7 +3,7 @@ netstandard2.0 true - 2.0.0-alpha + 2.1.0-alpha elamaunt GDShrapt GDShrapt.Reader is .Net library and object-oriented one-pass parser of GDScript. It can build a lexical tree of GDScript code or generate a new code from scratch. @@ -16,8 +16,8 @@ Usage: Just create GDScriptReader instance and call methods from it.https://github.com/elamaunt/GDShrapt git GDShrapt GDScript reader parser codegeneration Godot lexical analyzer - 2.0.0 - 2.0.0 + 2.1.0 + 2.1.0 true diff --git a/src/GDShrapt.Reader/GDTokensForm.cs b/src/GDShrapt.Reader/GDTokensForm.cs index b0df5b9..55135ec 100644 --- a/src/GDShrapt.Reader/GDTokensForm.cs +++ b/src/GDShrapt.Reader/GDTokensForm.cs @@ -717,6 +717,30 @@ protected void Set(GDSyntaxToken value, int index) node.Value = value; } + /// + /// Used only by cloning methods. + /// + void SetOrAdd(GDSyntaxToken value, int index) + { + if (index >= _statePoints.Count) + { + // Only for ListForms + _statePoints.Add(_list.AddLast(value)); + + if (value != null) + value.Parent = _owner; + } + else + { + var node = _statePoints[index]; + + if (value != null) + value.Parent = _owner; + + node.Value = value; + } + } + protected T Get(int index) where T : GDSyntaxToken => (T)_statePoints[index].Value; protected GDSyntaxToken Get(int index) => _statePoints[index].Value; @@ -814,30 +838,35 @@ internal int CountTokensBetween(int start, int end) return counter; } + /// + /// Main nodes cloning method. Current form must be empty + /// + /// The form to be cloned internal void CloneFrom(GDTokensForm form) { - if (_initialSize != form._initialSize) - throw new InvalidOperationException("Forms must have same size"); + if ((_initialSize != 0 || form._initialSize != 0) && _initialSize != form._initialSize) + throw new InvalidOperationException("Forms must have same size or zero"); if (StateIndex > 0) throw new InvalidOperationException("The form must be at initial state"); + if (form._list.Count == 0) + return; + var node = form._list.First; var point = form._statePoints[StateIndex]; - while (true) + while (node != null) { if (point == node) { - Set(point.Value?.Clone(), StateIndex++); - point = form._statePoints[StateIndex]; + SetOrAdd(node.Value?.Clone(), StateIndex++); + point = form._statePoints.ElementAtOrDefault(StateIndex); } else { - var clone = point.Value?.Clone(); - - if (clone != null) - AddBeforeActiveToken(clone); + var clone = node.Value?.Clone(); + AddBeforeActiveToken(clone); } node = node.Next; diff --git a/src/GDShrapt.Reader/SimpleTokens/GDComment.cs b/src/GDShrapt.Reader/SimpleTokens/GDComment.cs index 3974575..b05666a 100644 --- a/src/GDShrapt.Reader/SimpleTokens/GDComment.cs +++ b/src/GDShrapt.Reader/SimpleTokens/GDComment.cs @@ -1,6 +1,6 @@ namespace GDShrapt.Reader { - public class GDComment : GDCharSequence + public sealed class GDComment : GDCharSequence { public GDComment() { diff --git a/src/GDShrapt.Reader/SimpleTokens/GDCornerCloseBracket.cs b/src/GDShrapt.Reader/SimpleTokens/GDCornerCloseBracket.cs index c6dad00..3fcadd6 100644 --- a/src/GDShrapt.Reader/SimpleTokens/GDCornerCloseBracket.cs +++ b/src/GDShrapt.Reader/SimpleTokens/GDCornerCloseBracket.cs @@ -1,6 +1,6 @@ namespace GDShrapt.Reader { - public class GDCornerCloseBracket : GDSingleCharToken, IGDStructureToken + public sealed class GDCornerCloseBracket : GDSingleCharToken, IGDStructureToken { public override char Char => '>'; diff --git a/src/GDShrapt.Reader/SimpleTokens/GDCornerOpenBracket.cs b/src/GDShrapt.Reader/SimpleTokens/GDCornerOpenBracket.cs index 0e5e49f..c3b3891 100644 --- a/src/GDShrapt.Reader/SimpleTokens/GDCornerOpenBracket.cs +++ b/src/GDShrapt.Reader/SimpleTokens/GDCornerOpenBracket.cs @@ -1,6 +1,6 @@ namespace GDShrapt.Reader { - public class GDCornerOpenBracket : GDSingleCharToken, IGDStructureToken + public sealed class GDCornerOpenBracket : GDSingleCharToken, IGDStructureToken { public override char Char => '<'; diff --git a/src/GDShrapt.Reader/SimpleTokens/GDFigureCloseBracket.cs b/src/GDShrapt.Reader/SimpleTokens/GDFigureCloseBracket.cs index 8491313..77be662 100644 --- a/src/GDShrapt.Reader/SimpleTokens/GDFigureCloseBracket.cs +++ b/src/GDShrapt.Reader/SimpleTokens/GDFigureCloseBracket.cs @@ -1,6 +1,6 @@ namespace GDShrapt.Reader { - public class GDFigureCloseBracket : GDSingleCharToken, IGDStructureToken + public sealed class GDFigureCloseBracket : GDSingleCharToken, IGDStructureToken { public override char Char => '}'; diff --git a/src/GDShrapt.Reader/SimpleTokens/GDFigureOpenBracket.cs b/src/GDShrapt.Reader/SimpleTokens/GDFigureOpenBracket.cs index b5c1554..ae4e2a4 100644 --- a/src/GDShrapt.Reader/SimpleTokens/GDFigureOpenBracket.cs +++ b/src/GDShrapt.Reader/SimpleTokens/GDFigureOpenBracket.cs @@ -1,6 +1,6 @@ namespace GDShrapt.Reader { - public class GDFigureOpenBracket : GDSingleCharToken, IGDStructureToken + public sealed class GDFigureOpenBracket : GDSingleCharToken, IGDStructureToken { public override char Char => '{'; diff --git a/src/GDShrapt.Reader/SimpleTokens/GDIdentifier.cs b/src/GDShrapt.Reader/SimpleTokens/GDIdentifier.cs index 2105e4c..0947dc8 100644 --- a/src/GDShrapt.Reader/SimpleTokens/GDIdentifier.cs +++ b/src/GDShrapt.Reader/SimpleTokens/GDIdentifier.cs @@ -3,7 +3,7 @@ namespace GDShrapt.Reader { - public class GDIdentifier : GDDataToken + public sealed class GDIdentifier : GDDataToken { public bool IsPi => string.Equals(Sequence, "PI", StringComparison.Ordinal); public bool IsTau => string.Equals(Sequence, "TAU", StringComparison.Ordinal); diff --git a/src/GDShrapt.Reader/SimpleTokens/GDIntendation.cs b/src/GDShrapt.Reader/SimpleTokens/GDIntendation.cs index ee7e9fc..36401b5 100644 --- a/src/GDShrapt.Reader/SimpleTokens/GDIntendation.cs +++ b/src/GDShrapt.Reader/SimpleTokens/GDIntendation.cs @@ -2,7 +2,7 @@ namespace GDShrapt.Reader { - public class GDIntendation : GDSimpleSyntaxToken + public sealed class GDIntendation : GDSimpleSyntaxToken { int _lineIntendation; int _spaceCounter; diff --git a/src/GDShrapt.Reader/SimpleTokens/GDNumber.cs b/src/GDShrapt.Reader/SimpleTokens/GDNumber.cs index f929e75..fedc0d8 100644 --- a/src/GDShrapt.Reader/SimpleTokens/GDNumber.cs +++ b/src/GDShrapt.Reader/SimpleTokens/GDNumber.cs @@ -4,7 +4,7 @@ namespace GDShrapt.Reader { - public class GDNumber : GDLiteralToken + public sealed class GDNumber : GDLiteralToken { readonly StringBuilder _stringBuilder = new StringBuilder(); diff --git a/src/GDShrapt.Reader/SimpleTokens/GDSpace.cs b/src/GDShrapt.Reader/SimpleTokens/GDSpace.cs index 75c60ad..04331f6 100644 --- a/src/GDShrapt.Reader/SimpleTokens/GDSpace.cs +++ b/src/GDShrapt.Reader/SimpleTokens/GDSpace.cs @@ -1,6 +1,6 @@ namespace GDShrapt.Reader { - public class GDSpace : GDCharSequence + public sealed class GDSpace : GDCharSequence { internal override bool CanAppendChar(char c, GDReadingState state) { diff --git a/src/GDShrapt.Reader/SimpleTokens/GDSquareCloseBracket.cs b/src/GDShrapt.Reader/SimpleTokens/GDSquareCloseBracket.cs index 58121b6..2c91949 100644 --- a/src/GDShrapt.Reader/SimpleTokens/GDSquareCloseBracket.cs +++ b/src/GDShrapt.Reader/SimpleTokens/GDSquareCloseBracket.cs @@ -1,6 +1,6 @@ namespace GDShrapt.Reader { - public class GDSquareCloseBracket : GDSingleCharToken, IGDStructureToken + public sealed class GDSquareCloseBracket : GDSingleCharToken, IGDStructureToken { public override char Char => ']'; diff --git a/src/GDShrapt.Reader/SimpleTokens/GDSquareOpenBracket.cs b/src/GDShrapt.Reader/SimpleTokens/GDSquareOpenBracket.cs index d9e821a..6f93d72 100644 --- a/src/GDShrapt.Reader/SimpleTokens/GDSquareOpenBracket.cs +++ b/src/GDShrapt.Reader/SimpleTokens/GDSquareOpenBracket.cs @@ -1,6 +1,6 @@ namespace GDShrapt.Reader { - public class GDSquareOpenBracket : GDSingleCharToken, IGDStructureToken + public sealed class GDSquareOpenBracket : GDSingleCharToken, IGDStructureToken { public override char Char => '['; diff --git a/src/GDShrapt.Reader/SimpleTokens/GDType.cs b/src/GDShrapt.Reader/SimpleTokens/GDType.cs index e28b376..4b6d8e2 100644 --- a/src/GDShrapt.Reader/SimpleTokens/GDType.cs +++ b/src/GDShrapt.Reader/SimpleTokens/GDType.cs @@ -3,7 +3,7 @@ namespace GDShrapt.Reader { - public class GDType : GDDataToken + public sealed class GDType : GDDataToken { public bool ExtractTypeFromInitializer => IsEmpty; public bool IsEmpty => Sequence.IsNullOrEmpty();