Skip to content

Commit

Permalink
Merge pull request #1725 from riganti/binding-parser-ranges-1
Browse files Browse the repository at this point in the history
BindingParser: Fixing missing tokens and ranges
  • Loading branch information
tomasherceg authored Oct 27, 2023
2 parents 1e179e2 + 698edcd commit 1bbbe0a
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public interface IAbstractTreeBuilder

IAbstractViewModuleDirective BuildViewModuleDirective(DothtmlDirectiveNode directiveNode, string modulePath, string resourceName);
IAbstractPropertyDeclarationDirective BuildPropertyDeclarationDirective(DothtmlDirectiveNode directive, TypeReferenceBindingParserNode typeSyntax, SimpleNameBindingParserNode nameSyntax, BindingParserNode? initializer, IList<IAbstractDirectiveAttributeReference> resolvedAttributes, BindingParserNode valueSyntaxRoot, ImmutableList<NamespaceImport> imports);
IAbstractDirectiveAttributeReference BuildPropertyDeclarationAttributeReference(DothtmlDirectiveNode directiveNode, IdentifierNameBindingParserNode propertyNameSyntax, ActualTypeReferenceBindingParserNode typeSyntax, LiteralExpressionBindingParserNode initializer, ImmutableList<NamespaceImport> imports);
IAbstractDirectiveAttributeReference BuildPropertyDeclarationAttributeReference(DothtmlDirectiveNode directiveNode, IdentifierNameBindingParserNode propertyNameSyntax, TypeReferenceBindingParserNode typeSyntax, LiteralExpressionBindingParserNode initializer, ImmutableList<NamespaceImport> imports);
IAbstractPropertyBinding BuildPropertyBinding(IPropertyDescriptor property, IAbstractBinding binding, DothtmlAttributeNode? sourceAttributeNode);

IAbstractPropertyControl BuildPropertyControl(IPropertyDescriptor property, IAbstractControl? control, DothtmlElementNode? wrapperElementNode);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public IAbstractPropertyDeclarationDirective BuildPropertyDeclarationDirective(
public IAbstractDirectiveAttributeReference BuildPropertyDeclarationAttributeReference(
DothtmlDirectiveNode directiveNode,
IdentifierNameBindingParserNode propertyNameSyntax,
ActualTypeReferenceBindingParserNode typeSyntax,
TypeReferenceBindingParserNode typeSyntax,
LiteralExpressionBindingParserNode initializer,
ImmutableList<NamespaceImport> imports)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ protected override IAbstractPropertyDeclarationDirective Resolve(DothtmlDirectiv
return TreeBuilder.BuildPropertyDeclarationDirective(directiveNode, type, name, declaration?.Initializer, resolvedAttributes, valueSyntaxRoot, imports);
}

private List<(ActualTypeReferenceBindingParserNode type, IdentifierNameBindingParserNode name, LiteralExpressionBindingParserNode initializer)> ProcessPropertyDirectiveAttributeReference(DothtmlDirectiveNode directiveNode, List<BindingParserNode> attributeReferences)
private List<(TypeReferenceBindingParserNode type, IdentifierNameBindingParserNode name, LiteralExpressionBindingParserNode initializer)> ProcessPropertyDirectiveAttributeReference(DothtmlDirectiveNode directiveNode, List<BindingParserNode> attributeReferences)
{
var result = new List<(ActualTypeReferenceBindingParserNode, IdentifierNameBindingParserNode, LiteralExpressionBindingParserNode)>();
var result = new List<(TypeReferenceBindingParserNode, IdentifierNameBindingParserNode, LiteralExpressionBindingParserNode)>();
foreach (var attributeReference in attributeReferences)
{
if (attributeReference is not BinaryOperatorBindingParserNode { Operator: BindingTokenType.AssignOperator } assignment)
Expand All @@ -75,7 +75,7 @@ protected override IAbstractPropertyDeclarationDirective Resolve(DothtmlDirectiv
var attributePropertyNameReference = attributePropertyReference?.MemberNameExpression;
var initializer = assignment.SecondExpression as LiteralExpressionBindingParserNode;

if (attributeTypeReference == null || attributePropertyNameReference == null)
if (attributeTypeReference is null || attributePropertyNameReference is null)
{
directiveNode.AddError("Property attributes must be in the form Attribute.Property = value.");
continue;
Expand All @@ -85,7 +85,10 @@ protected override IAbstractPropertyDeclarationDirective Resolve(DothtmlDirectiv
directiveNode.AddError($"Value for property {attributeTypeReference.ToDisplayString()} of attribute {attributePropertyNameReference.ToDisplayString()} is missing or not a constant.");
continue;
}
result.Add((new ActualTypeReferenceBindingParserNode(attributeTypeReference), attributePropertyNameReference, initializer));

var type = new ActualTypeReferenceBindingParserNode(attributeTypeReference);
type.TransferTokens(attributeTypeReference);
result.Add(new (type, attributePropertyNameReference, initializer));
}
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -585,14 +585,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 @@ -602,8 +602,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 @@ -612,10 +612,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 All @@ -632,7 +642,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 @@ -647,7 +657,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,5 +47,24 @@ public virtual IEnumerable<BindingParserNode> EnumerateNodes()

public abstract string ToDisplayString();

internal void TransferTokens(BindingParserNode sourceNode, int? startPosition = null)
{

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

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

for (int i = 0; i < sourceNode.Tokens.Count; 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 @@ -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 All @@ -52,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
Loading

0 comments on commit 1bbbe0a

Please sign in to comment.