Skip to content

Commit

Permalink
Tokens copied correctly for array types + tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Milan Mikuš committed Oct 20, 2023
1 parent 57a53e6 commit d2d6cdb
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -581,14 +581,14 @@ private bool TryReadTypeReference([NotNullWhen(returnValue: true)] out TypeRefer
// Generic
if (!TryReadGenericArguments(startIndex, expression, out var typeOrFunction))
return false;
expression = typeOrFunction!.ToTypeReference();
expression = CreateNode(typeOrFunction!.ToTypeReference(), startIndex);
}
else if (next.Type == BindingTokenType.QuestionMarkOperator)
{
// Nullable
Read();
var typeExpr = expression as TypeReferenceBindingParserNode ?? new ActualTypeReferenceBindingParserNode(expression);
expression = CreateNode(new NullableTypeReferenceBindingParserNode(typeExpr), startIndex);

expression = CreateNode(new NullableTypeReferenceBindingParserNode(EnsureTypeExpression(expression)), startIndex);
}
else if (next.Type == BindingTokenType.OpenArrayBrace)
{
Expand All @@ -598,8 +598,8 @@ private bool TryReadTypeReference([NotNullWhen(returnValue: true)] out TypeRefer
if (next?.Type != BindingTokenType.CloseArrayBrace)
return false;
Read();
var typeExpr = expression as TypeReferenceBindingParserNode ?? new ActualTypeReferenceBindingParserNode(expression);
expression = CreateNode(new ArrayTypeReferenceBindingParserNode(typeExpr), startIndex);

expression = CreateNode(new ArrayTypeReferenceBindingParserNode(EnsureTypeExpression(expression)), startIndex);
}
else
{
Expand All @@ -608,10 +608,20 @@ private bool TryReadTypeReference([NotNullWhen(returnValue: true)] out TypeRefer
next = Peek();
}

typeNode = expression as TypeReferenceBindingParserNode ?? new ActualTypeReferenceBindingParserNode(expression);
typeNode = EnsureTypeExpression(expression);
return true;
}

private static TypeReferenceBindingParserNode EnsureTypeExpression(BindingParserNode expression)
{
if (expression is TypeReferenceBindingParserNode typeExpr) { return typeExpr; }

typeExpr = new ActualTypeReferenceBindingParserNode(expression);
typeExpr.TransferTokens(expression);

return typeExpr;
}

private BindingParserNode ReadIdentifierExpression(bool onlyTypeName)
{
var startIndex = CurrentIndex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,14 @@ public virtual IEnumerable<BindingParserNode> EnumerateNodes()

public abstract string ToDisplayString();

internal void TransferTokens(BindingParserNode sourceNode)
{
Length = sourceNode.Length;
StartPosition = sourceNode.StartPosition;
Tokens.Clear();
Tokens.Capacity = sourceNode.Tokens.Capacity;
for (int i = 0; i < sourceNode.Tokens.Count; i++)
Tokens.Add(sourceNode.Tokens[i]);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public override string ToDisplayString()
public TypeReferenceBindingParserNode ToTypeReference()
{
var type = new ActualTypeReferenceBindingParserNode(TypeOrFunction);
type.TransferTokens(TypeOrFunction);

if (TypeArguments.Count == 0)
return type;

Expand Down
74 changes: 66 additions & 8 deletions src/Tests/Parser/Binding/BindingParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1162,11 +1162,68 @@ public void BindingParser_MinimalPropertyDeclaration()
var type = root.PropertyType.CastTo<TypeReferenceBindingParserNode>();
var name = root.Name.CastTo<SimpleNameBindingParserNode>();

AssertNode(root, "System.String MyProperty = \"Test\"", 0, 33);
AssertNode(root, "System.String MyProperty", 0, 24);
AssertNode(type, "System.String", 0, 14);
AssertNode(name, "MyProperty", 14, 10);
}

[TestMethod]
public void BindingParser_NullablePropertyDeclaration()
{
var parser = bindingParserNodeFactory.SetupParser("System.String? MyProperty");
var declaration = parser.ReadPropertyDirectiveValue();

var root = declaration.CastTo<PropertyDeclarationBindingParserNode>();
var nullable = root.PropertyType.CastTo<NullableTypeReferenceBindingParserNode>();
var type = nullable.InnerType.CastTo<ActualTypeReferenceBindingParserNode>();
var name = root.Name.CastTo<SimpleNameBindingParserNode>();

AssertNode(root, "System.String? MyProperty", 0, 25);
AssertNode(nullable, "System.String?", 0, 14);
AssertNode(type, "System.String", 0, 13);
AssertNode(name, "MyProperty", 14, 11);
}

[TestMethod]
public void BindingParser_ComplexTypePropertyDeclaration()
{
var parser = bindingParserNodeFactory.SetupParser("System.Func<System.String?, int?, string, IdentifierNameBindingParserNode?[]>? MyProperty");
var declaration = parser.ReadPropertyDirectiveValue();

var root = declaration.CastTo<PropertyDeclarationBindingParserNode>();
var nullableFunc = root.PropertyType.CastTo<NullableTypeReferenceBindingParserNode>();
var funcGeneric = nullableFunc.InnerType.CastTo<GenericTypeReferenceBindingParserNode>();
var func = funcGeneric.Type.CastTo<ActualTypeReferenceBindingParserNode>();

var arg1Nullable = funcGeneric.Arguments[0].CastTo<NullableTypeReferenceBindingParserNode>();
var arg2Nullable = funcGeneric.Arguments[1].CastTo<NullableTypeReferenceBindingParserNode>();
var arg4Array = funcGeneric.Arguments[3].CastTo<ArrayTypeReferenceBindingParserNode>();

var arg1 = arg1Nullable.InnerType.CastTo<ActualTypeReferenceBindingParserNode>();
var arg2 = arg2Nullable.InnerType.CastTo<ActualTypeReferenceBindingParserNode>();
var arg3 = funcGeneric.Arguments[2].CastTo<ActualTypeReferenceBindingParserNode>();
var arg4Nullable = arg4Array.ElementType.CastTo<NullableTypeReferenceBindingParserNode>();

var arg4 = arg4Nullable.InnerType.CastTo<ActualTypeReferenceBindingParserNode>();

AssertNode(root, "System.Func<System.String?, int?, string, IdentifierNameBindingParserNode?[]>? MyProperty", 0, 89);
AssertNode(nullableFunc, "System.Func<System.String?, int?, string, IdentifierNameBindingParserNode?[]>?", 0, 78);
AssertNode(funcGeneric, "System.Func<System.String?, int?, string, IdentifierNameBindingParserNode?[]>", 0, 77);
AssertNode(func, "System.Func", 0, 11);
AssertNode(root.Name, "MyProperty", 78, 11);

AssertNode(arg1Nullable, "System.String?", 12, 14);
AssertNode(arg2Nullable, "int?", 28, 4);
AssertNode(arg3, "string", 34, 6);
AssertNode(arg4Array, "IdentifierNameBindingParserNode?[]", 42, 34);

AssertNode(arg1, "System.String", 12, 13);
AssertNode(arg2, "int", 28, 3);
AssertNode(arg4Nullable, "IdentifierNameBindingParserNode?", 42, 32);

AssertNode(arg4, "IdentifierNameBindingParserNode", 42, 31);
}

[TestMethod]
public void BindingParser_InitializedPropertyDeclaration()
{
Expand All @@ -1179,7 +1236,7 @@ public void BindingParser_InitializedPropertyDeclaration()
var init = root.Initializer.CastTo<LiteralExpressionBindingParserNode>();

AssertNode(root, "System.String MyProperty = \"Test\"", 0, 33);
AssertNode(type, "System.String", 0, 13);
AssertNode(type, "System.String", 0, 14);
AssertNode(name, "MyProperty", 14, 11);
AssertNode(init, "\"Test\"", 27, 6);
}
Expand All @@ -1201,7 +1258,7 @@ public void BindingParser_InitializedAttributedPropertyDeclaration()
var att2 = root.Attributes[1].CastTo<BinaryOperatorBindingParserNode>();

AssertNode(root, "System.String MyProperty = \"Test\", MarkupOptions.AllowHardCodedValue = False, MarkupOptions.Required = True", 0, 107);
AssertNode(type, "System.String", 0, 13);
AssertNode(type, "System.String", 0, 14);
AssertNode(name, "MyProperty", 14, 11);
AssertNode(init, "\"Test\"", 27, 6);
AssertNode(att1, "MarkupOptions.AllowHardCodedValue = False", 35, 41);
Expand All @@ -1225,11 +1282,11 @@ public void BindingParser_AttributedPropertyDeclaration()
var att1 = root.Attributes[0].CastTo<BinaryOperatorBindingParserNode>();
var att2 = root.Attributes[1].CastTo<BinaryOperatorBindingParserNode>();

Assert.AreEqual("System.String MyProperty, MarkupOptions.AllowHardCodedValue = False, MarkupOptions.Required = True", root.ToDisplayString());
Assert.AreEqual("System.String", type.ToDisplayString());
Assert.AreEqual("MyProperty", name.ToDisplayString());
Assert.AreEqual("MarkupOptions.AllowHardCodedValue = False", att1.ToDisplayString());
Assert.AreEqual("MarkupOptions.Required = True", att2.ToDisplayString());
AssertNode(root, "System.String MyProperty, MarkupOptions.AllowHardCodedValue = False, MarkupOptions.Required = True", 0, 98);
AssertNode(type, "System.String", 0, 14);
AssertNode(name, "MyProperty", 14, 10);
AssertNode(att1, "MarkupOptions.AllowHardCodedValue = False", 26, 41);
AssertNode(att2, "MarkupOptions.Required = True", 68, 30);
}

[TestMethod]
Expand Down Expand Up @@ -1283,6 +1340,7 @@ public void BindingParser_GenericTypePropertyDeclaration()

AssertNode(root, "IDictionary<int, System.String> MyProperty", 0, 42);
AssertNode(name, "MyProperty", 31, 11);
AssertNode(genericType, "IDictionary<int, System.String>", 0, 31);
AssertNode(type, "IDictionary", 0, 11);
AssertNode(arg1, "int", 12, 3);
AssertNode(arg2, "System.String", 17, 13);
Expand Down

0 comments on commit d2d6cdb

Please sign in to comment.