Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binding system refactoring #341

Merged
merged 60 commits into from
Mar 19, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
1ba9778
property null propagation
exyi Oct 29, 2015
151ce08
Implemented Core of Javascript AST
exyi Dec 20, 2016
9a56994
added few tests for the tree
exyi Dec 20, 2016
4081e1f
Added view model type annotations to the JS tree and cleaned up the t…
exyi Dec 24, 2016
e4ecb5c
Js AST: Implemented symbolic parameter node and parametrized string
exyi Dec 27, 2016
1fbe63f
Merge branch 'master' into feature-bindingSystemRefactoring
exyi Dec 29, 2016
3f7fc9f
added symbolic parameters to the javascirpt translator
exyi Dec 29, 2016
77731c8
Fixed build of DotVVM.Compiler
exyi Dec 30, 2016
0b8300f
binding property system, first compilable sketch
exyi Jan 14, 2017
96798e8
binding property system checkpoint #2
exyi Jan 15, 2017
682dccf
binding system refactoring: ValueBinding are now working
exyi Jan 17, 2017
17db0fd
binding system refactoring: Command bindings are working
exyi Jan 17, 2017
0a2fc5e
Binding System Refactoring: Most unit tests fixed.
exyi Jan 19, 2017
60cfa36
Binding System Refactoring: fixed html attribute merging, all UnitTes…
exyi Jan 19, 2017
03a6b1e
Removed SeeCurrentcontrolBindingFlag as automatic dataContext correct…
exyi Jan 23, 2017
670cc33
merge master
exyi Jan 24, 2017
1b647dd
.
exyi Jan 24, 2017
811e6bc
Binding System Refactoring: GridView and DataPager updated, fixes in …
exyi Jan 26, 2017
4d20eaf
Merge branch 'master' into feature-bindingSystemRefactoring
exyi Jan 28, 2017
c0ce3a2
Merge branch 'master' into feature-bindingSystemRefactoring
exyi Jan 31, 2017
7168d5f
Implemented ExtensionParameters PoC, used for index access in gridView
exyi Feb 3, 2017
cb57eea
Fixed repeater
exyi Feb 3, 2017
27fbfa8
Merge branch 'master' into feature-bindingSystemRefactoring
exyi Feb 3, 2017
4bf01a3
Fixed unit tests
exyi Feb 3, 2017
68c2ba8
Fixed ko.observable handling for indexers
exyi Feb 3, 2017
2756683
JS translation: Implemented null and observable checks
exyi Feb 5, 2017
12dcce7
Binding System: static commands migrated to JsAst
exyi Feb 7, 2017
6b207f2
merge old null-propagation branch
exyi Feb 10, 2017
81430e8
Implemented null checks to compiled bindings
exyi Feb 12, 2017
3874e19
Fixed build of "sideprojects" in solution. Should fix CI build and sh…
exyi Feb 14, 2017
7e2a047
Fixed binding error reporting.
exyi Feb 16, 2017
03c7774
Fixed a StackOverflow in NullPropagationVisitor
exyi Feb 19, 2017
88899ad
merge master
exyi Mar 1, 2017
8b02518
Fixed tests after merge
exyi Mar 2, 2017
19d11d4
CommandBindingExpressions from DataPager moved to separate service
exyi Mar 2, 2017
da8f805
Repeater support IEnumerable in DataSource
exyi Mar 3, 2017
b621e33
JavascriptTranslation: fixed formatting of unary expression
exyi Mar 5, 2017
b9c0d13
Added compile-time preprocessing event support
exyi Mar 7, 2017
aec91c5
Fixed client id binding generation
exyi Mar 7, 2017
82833a3
Fixed client ID generation
exyi Mar 9, 2017
f04d7a5
Fixed markup control bindings
exyi Mar 9, 2017
d251a94
merge master
exyi Mar 14, 2017
a51c7c6
Fixed GridView and DataPager.
exyi Mar 14, 2017
bc83ec9
Merge remote-tracking branch 'origin/master' into feature-bindingSyst…
exyi Mar 15, 2017
8190bd5
Fixed the ItemsControl compile time transformation for ComboBoxes
exyi Mar 16, 2017
651b052
Fixed CreateDelegate from method group expression
exyi Mar 17, 2017
bcbbe04
Maybe fixed Error page tests
exyi Mar 17, 2017
54d8249
Merge master
exyi Mar 17, 2017
2960f2a
Fixed Javascript translation bug and test
exyi Mar 18, 2017
68eacd6
fixed typo
exyi Mar 18, 2017
5273d5c
Resolved all obsolete warnings
exyi Mar 18, 2017
ceb4748
Fixed DataContextStack in DataPager
exyi Mar 19, 2017
d1fc3eb
Fixed validation target nesting.
exyi Mar 19, 2017
05d7a95
Fixed null-propagation in client-side bindings
exyi Mar 19, 2017
211aaab
Introduced separate property for PathFragment in DataContextProperty …
exyi Mar 19, 2017
f92c463
Fixed CommandResolverTest
exyi Mar 19, 2017
4ccf08d
Added few doc-comments to the new public API
exyi Mar 19, 2017
adae83c
merge master
exyi Mar 19, 2017
79bfc4b
Added missing compiled delegate cache.
exyi Mar 19, 2017
de6ade0
Control properties are referenced using GetValue in bindings now. Sho…
exyi Mar 19, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 91 additions & 90 deletions src/DotVVM.Compiler/AssemblyBindingCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,106 +49,107 @@ protected string CompileMethod(LambdaExpression expr)
}
}

public BindingExpressionCompilationInfo PrecompileBinding(ResolvedBinding binding, string id, Type expectedType)
{
var compilerAttribute = GetCompilationAttribute(binding.BindingType);
var requirements = compilerAttribute.GetRequirements(binding.BindingType);
//public BindingExpressionCompilationInfo PrecompileBinding(ResolvedBinding binding, string id, Type expectedType)
//{
// var compilerAttribute = GetCompilationAttribute(binding.BindingType);
// var requirements = compilerAttribute.GetRequirements(binding.BindingType);

var result = new BindingExpressionCompilationInfo();
result.MethodName = TryExecute(binding.BindingNode, "Error while compiling binding to delegate.", requirements.Delegate, () => CompileMethod(compilerAttribute.CompileToDelegate(binding.GetExpression(), binding.DataContextTypeStack, expectedType)));
result.UpdateMethodName = TryExecute(binding.BindingNode, "Error while compiling update delegate.", requirements.UpdateDelegate, () => CompileMethod(compilerAttribute.CompileToUpdateDelegate(binding.GetExpression(), binding.DataContextTypeStack)));
result.OriginalString = TryExecute(binding.BindingNode, "hey, no, that should not happen. Really.", requirements.OriginalString, () => binding.Value);
result.Expression = TryExecute(binding.BindingNode, "Could not get binding expression.", requirements.Expression, () => binding.GetExpression());
result.ActionFilters = TryExecute(binding.BindingNode, "", requirements.ActionFilters, () => GetActionAttributeData(binding.GetExpression()));
result.Javascript = TryExecute(binding.BindingNode, "Could not compile binding to Javascript.", requirements.Javascript, () => compilerAttribute.CompileToJavascript(binding, new CompiledBindingExpression()
{
Expression = result.Expression,
Id = id,
OriginalString = result.OriginalString
}));
return result;
}
// var result = new BindingExpressionCompilationInfo();
// result.MethodName = TryExecute(binding.BindingNode, "Error while compiling binding to delegate.", requirements.Delegate, () => CompileMethod(compilerAttribute.CompileToDelegate(binding.GetExpression(), binding.DataContextTypeStack, expectedType)));
// result.UpdateMethodName = TryExecute(binding.BindingNode, "Error while compiling update delegate.", requirements.UpdateDelegate, () => CompileMethod(compilerAttribute.CompileToUpdateDelegate(binding.GetExpression(), binding.DataContextTypeStack)));
// result.OriginalString = TryExecute(binding.BindingNode, "hey, no, that should not happen. Really.", requirements.OriginalString, () => binding.Value);
// result.Expression = TryExecute(binding.BindingNode, "Could not get binding expression.", requirements.Expression, () => binding.GetExpression());
// result.ActionFilters = TryExecute(binding.BindingNode, "", requirements.ActionFilters, () => GetActionAttributeData(binding.GetExpression()));
// result.Javascript = TryExecute(binding.BindingNode, "Could not compile binding to Javascript.", requirements.Javascript, () => compilerAttribute.CompileToJavascript(binding, new CompiledBindingExpression()
// {
// Expression = result.Expression,
// Id = id,
// OriginalString = result.OriginalString
// }, configuration));
// return result;
//}

public override ExpressionSyntax EmitCreateBinding(DefaultViewCompilerCodeEmitter emitter, ResolvedBinding binding, string id, Type expectedType)
public override ExpressionSyntax EmitCreateBinding(DefaultViewCompilerCodeEmitter emitter, ResolvedBinding binding)
{
var info = PrecompileBinding(binding, id, expectedType);
if (emitter != null)
{
return GetCachedInitializer(emitter, GetCompiledBindingCreation(emitter, info.MethodName, info.UpdateMethodName, info.OriginalString, this.GetAttributeInitializers(info.ActionFilters, emitter)?.ToArray(), info.Javascript, id));
}
else return null;
throw new NotImplementedException();
//var info = PrecompileBinding(binding, id, expectedType);
//if (emitter != null)
//{
// return GetCachedInitializer(emitter, GetCompiledBindingCreation(emitter, info.MethodName, info.UpdateMethodName, info.OriginalString, this.GetAttributeInitializers(info.ActionFilters, emitter)?.ToArray(), info.Javascript, id));
//}
//else return null;
}

protected ExpressionSyntax GetCompiledBindingCreation(DefaultViewCompilerCodeEmitter emitter, string methodName, string updateMethodName, string originalString, ExpressionSyntax[] actionFilters, string javascript, string id)
{
var dict = new Dictionary<string, ExpressionSyntax>();
if (methodName != null) dict.Add(nameof(CompiledBindingExpression.Delegate), SyntaxFactory.ParseName(methodName));
if (updateMethodName != null) dict.Add(nameof(CompiledBindingExpression.UpdateDelegate), SyntaxFactory.ParseName(updateMethodName));
if (originalString != null) dict.Add(nameof(CompiledBindingExpression.OriginalString), emitter.EmitValue(originalString));
if (javascript != null) dict.Add(nameof(CompiledBindingExpression.Javascript), emitter.EmitValue(javascript));
if (id != null) dict.Add(nameof(CompiledBindingExpression.Id), emitter.EmitValue(id));
if (actionFilters != null)
dict.Add(nameof(CompiledBindingExpression.ActionFilters),
SyntaxFactory.ArrayCreationExpression(
SyntaxFactory.ArrayType(SyntaxFactory.ParseTypeName(typeof(ActionFilterAttribute).FullName))
.WithRankSpecifiers(
SyntaxFactory.SingletonList<ArrayRankSpecifierSyntax>(
SyntaxFactory.ArrayRankSpecifier(
SyntaxFactory.SingletonSeparatedList<ExpressionSyntax>(
SyntaxFactory.OmittedArraySizeExpression())))),
SyntaxFactory.InitializerExpression(SyntaxKind.CollectionInitializerExpression,
SyntaxFactory.SeparatedList(actionFilters))));
//protected ExpressionSyntax GetCompiledBindingCreation(DefaultViewCompilerCodeEmitter emitter, string methodName, string updateMethodName, string originalString, ExpressionSyntax[] actionFilters, string javascript, string id)
//{
// var dict = new Dictionary<string, ExpressionSyntax>();
// if (methodName != null) dict.Add(nameof(CompiledBindingExpression.Delegate), SyntaxFactory.ParseName(methodName));
// if (updateMethodName != null) dict.Add(nameof(CompiledBindingExpression.UpdateDelegate), SyntaxFactory.ParseName(updateMethodName));
// if (originalString != null) dict.Add(nameof(CompiledBindingExpression.OriginalString), emitter.EmitValue(originalString));
// if (javascript != null) dict.Add(nameof(CompiledBindingExpression.Javascript), emitter.EmitValue(javascript));
// if (id != null) dict.Add(nameof(CompiledBindingExpression.Id), emitter.EmitValue(id));
// if (actionFilters != null)
// dict.Add(nameof(CompiledBindingExpression.ActionFilters),
// SyntaxFactory.ArrayCreationExpression(
// SyntaxFactory.ArrayType(SyntaxFactory.ParseTypeName(typeof(ActionFilterAttribute).FullName))
// .WithRankSpecifiers(
// SyntaxFactory.SingletonList<ArrayRankSpecifierSyntax>(
// SyntaxFactory.ArrayRankSpecifier(
// SyntaxFactory.SingletonSeparatedList<ExpressionSyntax>(
// SyntaxFactory.OmittedArraySizeExpression())))),
// SyntaxFactory.InitializerExpression(SyntaxKind.CollectionInitializerExpression,
// SyntaxFactory.SeparatedList(actionFilters))));

return SyntaxFactory.ObjectCreationExpression(
SyntaxFactory.ParseTypeName(typeof(CompiledBindingExpression).FullName),
SyntaxFactory.ArgumentList(),
SyntaxFactory.InitializerExpression(SyntaxKind.ObjectInitializerExpression,
SyntaxFactory.SeparatedList(
dict.Select(p =>
(ExpressionSyntax)SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
SyntaxFactory.IdentifierName(p.Key),
p.Value
)
)
)
)
);
}
// return SyntaxFactory.ObjectCreationExpression(
// SyntaxFactory.ParseTypeName(typeof(CompiledBindingExpression).FullName),
// SyntaxFactory.ArgumentList(),
// SyntaxFactory.InitializerExpression(SyntaxKind.ObjectInitializerExpression,
// SyntaxFactory.SeparatedList(
// dict.Select(p =>
// (ExpressionSyntax)SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
// SyntaxFactory.IdentifierName(p.Key),
// p.Value
// )
// )
// )
// )
// );
//}

protected NameSyntax GetCacheName(Type type)
{
lock (locker)
{
var name = "cache_" + methodCounter++;
bindingsClass.DefineField(name, type, FieldAttributes.Public | FieldAttributes.Static);
return SyntaxFactory.ParseName(bindingsClass.FullName + "." + name);
}
}
//protected NameSyntax GetCacheName(Type type)
//{
// lock (locker)
// {
// var name = "cache_" + methodCounter++;
// bindingsClass.DefineField(name, type, FieldAttributes.Public | FieldAttributes.Static);
// return SyntaxFactory.ParseName(bindingsClass.FullName + "." + name);
// }
//}

protected ExpressionSyntax GetCachedInitializer(DefaultViewCompilerCodeEmitter emitter, ExpressionSyntax constructor)
{
// emit (cache ?? (cache = ctor()))
var cacheId = GetCacheName(typeof(CompiledBindingExpression));
return SyntaxFactory.BinaryExpression(SyntaxKind.CoalesceExpression, cacheId,
SyntaxFactory.ParenthesizedExpression(
SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
cacheId, constructor)));
}
//protected ExpressionSyntax GetCachedInitializer(DefaultViewCompilerCodeEmitter emitter, ExpressionSyntax constructor)
//{
// // emit (cache ?? (cache = ctor()))
// var cacheId = GetCacheName(typeof(CompiledBindingExpression));
// return SyntaxFactory.BinaryExpression(SyntaxKind.CoalesceExpression, cacheId,
// SyntaxFactory.ParenthesizedExpression(
// SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
// cacheId, constructor)));
//}

protected List<CustomAttributeData> GetActionAttributeData(Expression expression)
{
var attributes = new List<CustomAttributeData>();
expression.ForEachMember(m =>
{
attributes.AddRange(m.CustomAttributes.Where(a => typeof(ActionFilterAttribute).IsAssignableFrom(a.AttributeType)));
});
return attributes;
}
//protected List<CustomAttributeData> GetActionAttributeData(Expression expression)
//{
// var attributes = new List<CustomAttributeData>();
// expression.ForEachMember(m =>
// {
// attributes.AddRange(m.CustomAttributes.Where(a => typeof(ActionFilterAttribute).IsAssignableFrom(a.AttributeType)));
// });
// return attributes;
//}

protected IEnumerable<ExpressionSyntax> GetAttributeInitializers(IEnumerable<CustomAttributeData> attributes, DefaultViewCompilerCodeEmitter emitter)
{
return attributes?.Select(a => emitter?.EmitAttributeInitializer(a)).ToArray();
}
//protected IEnumerable<ExpressionSyntax> GetAttributeInitializers(IEnumerable<CustomAttributeData> attributes, DefaultViewCompilerCodeEmitter emitter)
//{
// return attributes?.Select(a => emitter?.EmitAttributeInitializer(a)).ToArray();
//}

public void SaveAssembly()
{
Expand Down
3 changes: 2 additions & 1 deletion src/DotVVM.Compiler/ResolvedControlInfoVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ public override void VisitPropertyBinding(ResolvedPropertyBinding propertyBindin
// try to compile bindings to see errors
try
{
BindingCompiler.PrecompileBinding(propertyBinding.Binding, "id123", propertyBinding.Property.PropertyType);
// T+
//BindingCompiler.PrecompileBinding(propertyBinding.Binding, "id123", propertyBinding.Property.PropertyType);
}
catch(Exception exception)
{
Expand Down
4 changes: 2 additions & 2 deletions src/DotVVM.Compiler/ViewStaticCompilerCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ protected ViewCompilationResult CompileView(string fileName)
}
}

var styleVisitor = new StylingVisitor(configuration.Styles);
var styleVisitor = new StylingVisitor(configuration);
resolvedView.Accept(styleVisitor);

var validationVisitor = new ControlUsageValidationVisitor(configuration);
Expand All @@ -201,7 +201,7 @@ protected ViewCompilationResult CompileView(string fileName)
var className = DefaultControlBuilderFactory.GetClassFromFileName(file.FileName) + "ControlBuilder";
fullClassName = namespaceName + "." + className;
emitter = new DefaultViewCompilerCodeEmitter();
var compilingVisitor = new ViewCompilingVisitor(emitter, configuration.ServiceLocator.GetService<IBindingCompiler>(), className, b => configuration.ServiceLocator.GetService<IBindingIdGenerator>().GetId(b, fileName));
var compilingVisitor = new ViewCompilingVisitor(emitter, configuration.ServiceLocator.GetService<IBindingCompiler>(), className);

resolvedView.Accept(compilingVisitor);

Expand Down
1 change: 1 addition & 0 deletions src/DotVVM.Framework.PerfTests/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DotVVM.Framework.Compilation.ControlTree;

namespace DotVVM.Framework.PerfTests
{
Expand Down
Loading