Skip to content

Commit ddf5945

Browse files
committed
Add script to generate pre-assigned property IDs
* Optimize relevant property accessed using the new compile-time constants * Optimize PropertyGroup.Clear * Cover DotvvmPropertyDictionary with more tests (and fix some bugs)
1 parent ddf4d6a commit ddf5945

32 files changed

+2457
-337
lines changed

src/Framework/Framework/Binding/BindingHelper.cs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ public static string FormatKnockoutScript(this ParametrizedCode code, DotvvmBind
6464
/// Gets Internal.PathFragmentProperty or DataContext.KnockoutExpression. Returns null if none of these is set.
6565
/// </summary>
6666
public static string? GetDataContextPathFragment(this DotvvmBindableObject currentControl) =>
67-
currentControl.properties.TryGet(Internal.PathFragmentProperty, out var pathFragment) && pathFragment is string pathFragmentStr ? pathFragmentStr :
68-
currentControl.properties.TryGet(DotvvmBindableObject.DataContextProperty, out var dataContext) && dataContext is IValueBinding binding ?
67+
currentControl.properties.TryGet(DotvvmPropertyIdAssignment.PropertyIds.Internal_PathFragment, out var pathFragment) && pathFragment is string pathFragmentStr ? pathFragmentStr :
68+
currentControl.properties.TryGet(DotvvmPropertyIdAssignment.PropertyIds.DotvvmBindableObject_DataContext, out var dataContext) && dataContext is IValueBinding binding ?
6969
binding.GetProperty<SimplePathExpressionBindingProperty>()
7070
.Code.FormatKnockoutScript(currentControl, binding) :
7171
null;
@@ -88,16 +88,16 @@ internal static (int stepsUp, DotvvmBindableObject target) FindDataContextTarget
8888
if (bindingContext == null || controlContext == null || controlContext.Equals(bindingContext)) return (0, control);
8989

9090
var changes = 0;
91-
foreach (var a in control.GetAllAncestors(includingThis: true))
91+
for (var ancestor = control; ancestor is {}; ancestor = ancestor.Parent)
9292
{
93-
var ancestorContext = a.GetDataContextType(inherit: false);
93+
var ancestorContext = ancestor.GetDataContextType(inherit: false);
9494
if (bindingContext.Equals(ancestorContext))
95-
return (changes, a);
95+
return (changes, ancestor);
9696

9797
// count only client-side data contexts (DataContext={resource:} is skipped in JS)
98-
if (a.properties.TryGet(DotvvmBindableObject.DataContextProperty, out var ancestorRuntimeContext))
98+
if (ancestor.properties.TryGet(DotvvmPropertyIdAssignment.PropertyIds.DotvvmBindableObject_DataContext, out var ancestorRuntimeContext))
9999
{
100-
if (a.properties.TryGet(Internal.IsServerOnlyDataContextProperty, out var isServerOnly) && isServerOnly != null)
100+
if (ancestor.properties.GetOrNull(DotvvmPropertyIdAssignment.PropertyIds.Internal_IsServerOnlyDataContext) is {} isServerOnly)
101101
{
102102
if (isServerOnly is false)
103103
changes++;
@@ -173,9 +173,8 @@ public static T ExecDelegate<T>(this BindingDelegate<T> func, DotvvmBindableObje
173173
// this has O(h^2) complexity because GetValue calls another GetDataContexts,
174174
// but this function is used rarely - for exceptions, manually created bindings, ...
175175
// Normal bindings have specialized code generated in BindingCompiler
176-
if (c.IsPropertySet(DotvvmBindableObject.DataContextProperty, inherit: false))
176+
if (c.properties.Contains(DotvvmPropertyIdAssignment.PropertyIds.DotvvmBindableObject_DataContext))
177177
{
178-
Debug.Assert(c.properties.Contains(DotvvmBindableObject.DataContextProperty), "Control claims that DataContextProperty is set, but it's not present in the properties dictionary.");
179178
yield return c.GetValue(DotvvmBindableObject.DataContextProperty);
180179
count--;
181180
}

src/Framework/Framework/Binding/DotvvmCapabilityProperty.CodeGeneration.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,27 +76,28 @@ public static (LambdaExpression getter, LambdaExpression setter) CreatePropertyG
7676
var valueParameter = Expression.Parameter(type, "value");
7777
var ctor = typeof(VirtualPropertyGroupDictionary<>)
7878
.MakeGenericType(propType)
79-
.GetConstructor(new [] { typeof(DotvvmBindableObject), typeof(DotvvmPropertyGroup) })!;
79+
.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, [ typeof(DotvvmBindableObject), typeof(ushort), typeof(bool) ])!;
8080
var createMethod = typeof(VirtualPropertyGroupDictionary<>)
8181
.MakeGenericType(propType)
8282
.GetMethod(
8383
typeof(ValueOrBinding).IsAssignableFrom(elementType) ? nameof(VirtualPropertyGroupDictionary<int>.CreatePropertyDictionary) :
8484
nameof(VirtualPropertyGroupDictionary<int>.CreateValueDictionary),
85-
BindingFlags.Public | BindingFlags.Static
85+
BindingFlags.NonPublic | BindingFlags.Static,
86+
[ typeof(DotvvmBindableObject), typeof(ushort) ]
8687
)!;
8788
var enumerableType = typeof(IEnumerable<>).MakeGenericType(typeof(KeyValuePair<,>).MakeGenericType(typeof(string), elementType));
8889
var copyFromMethod =
8990
typeof(VirtualPropertyGroupDictionary<>)
9091
.MakeGenericType(propType)
91-
.GetMethod("CopyFrom", new [] { enumerableType, typeof(bool) })!;
92+
.GetMethod("CopyFrom", [ enumerableType, typeof(bool) ])!;
9293
return (
9394
Lambda(
94-
Convert(Call(createMethod, currentControlParameter, Constant(pgroup)), type),
95+
Convert(Call(createMethod, currentControlParameter, Constant(pgroup.Id)), type),
9596
currentControlParameter
9697
),
9798
Lambda(
9899
Call(
99-
New(ctor, currentControlParameter, Constant(pgroup)),
100+
New(ctor, currentControlParameter, Constant(pgroup.Id), Constant(pgroup.IsBindingProperty)),
100101
copyFromMethod,
101102
Convert(valueParameter, enumerableType),
102103
Constant(true) // clear

src/Framework/Framework/Binding/DotvvmProperty.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,10 @@ public bool IsOwnedByCapability(DotvvmCapabilityProperty capability) =>
209209

210210
private object? GetInheritedValue(DotvvmBindableObject control)
211211
{
212+
var id = this.Id;
212213
for (var p = control.Parent; p is not null; p = p.Parent)
213214
{
214-
if (p.properties.TryGet(Id, out var v))
215+
if (p.properties.TryGet(id, out var v))
215216
return v;
216217
}
217218
return DefaultValue;

src/Framework/Framework/Binding/DotvvmPropertyId.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ public bool IsZero
129129

130130
public override string ToString()
131131
{
132+
if (IsZero)
133+
return "[0000_0000]";
132134
if (IsPropertyGroup)
133135
{
134136
var pg = PropertyGroupInstance;

0 commit comments

Comments
 (0)