forked from sebastienros/fluid
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Scope.cs
115 lines (98 loc) · 3.13 KB
/
Scope.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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Fluid.Values;
namespace Fluid
{
public class Scope
{
internal Dictionary<string, FluidValue> _properties;
private readonly bool _forLoopScope;
public Scope()
{
Parent = null;
}
public Scope(Scope parent)
{
Parent = parent;
}
public Scope(Scope parent, bool forLoopScope)
{
if (forLoopScope && parent == null) ExceptionHelper.ThrowArgumentNullException(nameof(parent));
Parent = parent;
// A ForLoop scope reads and writes its values in the parent scope.
// Internal accessors to the inner properties grant access to the local properties.
_forLoopScope = forLoopScope;
_properties = new Dictionary<string, FluidValue>();
}
/// <summary>
/// Gets the own properties of the scope
/// </summary>
public IEnumerable<string> Properties => _properties == null ? Array.Empty<string>() : _properties.Keys;
/// <summary>
/// Gets the parent scope if any.
/// </summary>
public Scope Parent { get; private set; }
/// <summary>
/// Returns the value with the specified name in the chain of scopes, or undefined
/// if it doesn't exist.
/// </summary>
/// <param name="name">The name of the value to return.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public FluidValue GetValue(string name)
{
if (name == null)
{
ExceptionHelper.ThrowArgumentNullException(nameof(name));
}
if (_properties != null && _properties.TryGetValue(name, out var result))
{
return result;
}
return Parent != null
? Parent.GetValue(name)
: NilValue.Instance;
}
public void Delete(string name)
{
if (_properties != null)
{
if (!_forLoopScope)
{
_properties.Remove(name);
}
else
{
Parent.Delete(name);
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void SetValue(string name, FluidValue value)
{
if (!_forLoopScope)
{
_properties ??= new Dictionary<string, FluidValue>();
_properties[name] = value ?? NilValue.Instance;
}
else
{
Parent.SetValue(name, value);
}
}
public FluidValue GetIndex(FluidValue index)
{
return GetValue(index.ToString());
}
public void CopyTo(Scope scope)
{
if (_properties != null)
{
foreach (var property in _properties)
{
scope.SetValue(property.Key, property.Value);
}
}
}
}
}