-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSemanticBinder.TreeHandler.cs
95 lines (81 loc) · 3.22 KB
/
SemanticBinder.TreeHandler.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
using Microsoft.OData.Edm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Lib;
public partial class SemanticBinder
{
internal class TreeHandler : ISyntacticExpressionHandler<SemanticNode>
{
IEdmModel _model;
IEdmType _rootType;
Stack<State> _stateStack = new Stack<State>();
public TreeHandler(IEdmModel model, IEdmType type)
{
_model = model;
_rootType = type;
_stateStack.Push(new State(type));
}
public SemanticNode HandleAnd(SlimQueryNode andNode)
{
var left = andNode.GetLeft().Accept(this);
var right = andNode.GetRight().Accept(this);
ValidateSameType(left, right);
return new AndNode(left, right);
}
public SemanticNode HandleEq(SlimQueryNode eqNode)
{
var left = eqNode.GetLeft().Accept(this);
var right = eqNode.GetRight().Accept(this);
ValidateSameType(left, right);
return new EqNode(left, right);
}
public SemanticNode HandleGt(SlimQueryNode gtNode)
{
var left = gtNode.GetLeft().Accept(this);
var right = gtNode.GetRight().Accept(this);
ValidateSameType(left, right);
return new GtNode(left, right);
}
public SemanticNode HandleIdentifier(SlimQueryNode identifier)
{
var state = _stateStack.Peek();
if (state.ParentType is not IEdmStructuredType structuredType)
{
throw new InvalidOperationException("Cannot use identifier in this context since there's not parent type for property access");
}
// TODO compare FindProperty with scanning through the properties and comparing withut having to _get string
var prop = structuredType.FindProperty(identifier.GetIdentifier());
if (prop == null)
{
throw new InvalidOperationException($"Property {identifier.GetString()} not found in type {structuredType.FullTypeName()}");
}
return new SingleValuePropertyAccessNode(prop);
}
public SemanticNode HandleIntConstant(SlimQueryNode intConst)
{
return new IntLiteralNode(intConst.GetInt());
}
public SemanticNode HandleOr(SlimQueryNode orNode)
{
var left = orNode.GetLeft().Accept(this);
var right = orNode.GetRight().Accept(this);
ValidateSameType(left, right);
return new OrNode(left, right);
}
public SemanticNode HandleStringConstant(SlimQueryNode stringConst)
{
return new StringLiteralNode(stringConst.GetString());
}
private static void ValidateSameType(SemanticNode left, SemanticNode right)
{
if (left.EdmType.Definition != right.EdmType.Definition)
{
throw new InvalidOperationException($"Cannot compare values of different types: {left.EdmType.Definition.FullTypeName()} and {right.EdmType.Definition.FullTypeName()}");
}
}
record struct State(IEdmType ParentType);
}
}