Skip to content

Commit

Permalink
Generic function call tokens fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
Milan Mikuš committed Oct 24, 2023
1 parent d2d6cdb commit e072f63
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,7 @@ private BindingParserNode ReadIdentifierExpression(bool onlyTypeName)
Read();
var member = ReadIdentifierNameExpression();
if (expression is TypeOrFunctionReferenceBindingParserNode typeOrFunction)
expression = typeOrFunction.ToTypeReference();
expression = CreateNode(typeOrFunction.ToTypeReference(), startIndex);

expression = CreateNode(new MemberAccessBindingParserNode(expression, member), startIndex);
}
Expand All @@ -653,7 +653,7 @@ private BindingParserNode ReadIdentifierExpression(bool onlyTypeName)
else if (!onlyTypeName && next.Type == BindingTokenType.OpenParenthesis)
{
if (expression is TypeOrFunctionReferenceBindingParserNode typeOrFunction)
expression = typeOrFunction.ToFunctionReference();
expression = CreateNode(typeOrFunction.ToFunctionReference(), startIndex);

expression = ReadFunctionCall(startIndex, expression);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,24 @@ public virtual IEnumerable<BindingParserNode> EnumerateNodes()

public abstract string ToDisplayString();

internal void TransferTokens(BindingParserNode sourceNode)
internal void TransferTokens(BindingParserNode sourceNode, int? startPosition = null)
{
Length = sourceNode.Length;
StartPosition = sourceNode.StartPosition;

StartPosition = startPosition ?? sourceNode.StartPosition;
Length = 0;

Tokens.Clear();
Tokens.Capacity = sourceNode.Tokens.Capacity;

for (int i = 0; i < sourceNode.Tokens.Count; i++)
Tokens.Add(sourceNode.Tokens[i]);
{
var token = sourceNode.Tokens[i];
if ((startPosition ?? 0) <= token.StartPosition)
{
Length += token.Length;
Tokens.Add(token);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ public BindingParserNode ToFunctionReference()
if (TypeArguments.Count == 0)
return memberAccess;

var genericName = new GenericNameBindingParserNode(memberAccess.MemberNameExpression.NameToken, TypeArguments);
var name = memberAccess.MemberNameExpression.NameToken;
var genericName = new GenericNameBindingParserNode(name, TypeArguments);
genericName.TransferTokens(this, name.StartPosition);

memberAccess.MemberNameExpression = genericName;
return memberAccess;
}
Expand Down
65 changes: 62 additions & 3 deletions src/Tests/Parser/Binding/BindingParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -937,9 +937,10 @@ public void BindingParser_Lambda_WithTypeInfo_SingleParameter(string expr, strin
var parameters = lambda.ParameterExpressions;

Assert.AreEqual(1, parameters.Count);
Assert.AreEqual(type, parameters[0].Type.ToDisplayString());
Assert.AreEqual("arg", parameters[0].Name.ToDisplayString());
Assert.AreEqual("Method(arg)", body.ToDisplayString());

AssertNode(parameters[0].Type, type, 1, type.Length+1);
AssertNode(parameters[0].Name, "arg", type.Length + 2, 3);
AssertNode(body, "Method(arg)", type.Length + 10, 11);
}

[TestMethod]
Expand Down Expand Up @@ -1346,6 +1347,64 @@ public void BindingParser_GenericTypePropertyDeclaration()
AssertNode(arg2, "System.String", 17, 13);
}

[TestMethod]
public void BindingParser_GenericMethodCall_SimpleName()
{
var source = "GetType<string>(StringProp)";
var parser = bindingParserNodeFactory.SetupParser(source);
var root = parser.ReadExpression().As<FunctionCallBindingParserNode>();

var generic = root.TargetExpression.As<GenericNameBindingParserNode>();
var typeArgument = generic.TypeArguments[0].As<TypeReferenceBindingParserNode>();

AssertNode(root, source, 0, source.Length);
AssertNode(generic, "GetType<string>", 0, source.Length-12);
AssertNode(typeArgument, "string", 8, 6);
}

[TestMethod]
public void BindingParser_GenericMethodCall_MemberAccessName()
{
var source = "service.GetType<string?>(StringProp)";

var parser = bindingParserNodeFactory.SetupParser(source);
var root = parser.ReadExpression().As<FunctionCallBindingParserNode>();

var memberAccess = root.TargetExpression.As<MemberAccessBindingParserNode>();
var generic = memberAccess.MemberNameExpression.As<GenericNameBindingParserNode>();
var typeArgument = generic.TypeArguments[0].As<TypeReferenceBindingParserNode>();

AssertNode(root, source, 0, source.Length);
AssertNode(memberAccess, "service.GetType<string?>", 0, source.Length-12);
AssertNode(generic, "GetType<string?>", 8, source.Length - 20);

AssertNode(typeArgument, "string?", 16, 7);

}

[TestMethod]
public void BindingParser_GenericMethodCall_MultipleGenericArguments()
{
var source = "_this.Modal.GetType<string?, System.String>(StringProp)";

var parser = bindingParserNodeFactory.SetupParser(source);
var root = parser.ReadExpression().As<FunctionCallBindingParserNode>();

var memberAccess1 = root.TargetExpression.As<MemberAccessBindingParserNode>();
var memberAccess2 = memberAccess1.TargetExpression.As<MemberAccessBindingParserNode>();
var generic = memberAccess1.MemberNameExpression.As<GenericNameBindingParserNode>();
var typeArgument1 = generic.TypeArguments[0].As<TypeReferenceBindingParserNode>();
var typeArgument2 = generic.TypeArguments[1].As<TypeReferenceBindingParserNode>();

AssertNode(root, source, 0, source.Length);
AssertNode(memberAccess1, "_this.Modal.GetType<string?, System.String>", 0, source.Length - 12);
AssertNode(memberAccess2, "_this.Modal", 0, 11);
AssertNode(generic, "GetType<string?, System.String>", 12, 31);

AssertNode(typeArgument1, "string?", 20, 7);
AssertNode(typeArgument2, "System.String", 29, 13);
}

private static void AssertNode(BindingParserNode elementType, string expectedDisplayString, int start, int length)
{
Assert.AreEqual(expectedDisplayString, elementType.ToDisplayString(), $"Node {elementType.GetType().Name}: display string incorrect.");
Expand Down

0 comments on commit e072f63

Please sign in to comment.