/// <inheritdoc /> protected override IEnumerable <IDataItem> GetItemsImpl(ICollection <DataBinding> bindings, bool includeDynamicItems) { IDataProvider[] providers = GenericCollectionUtils.ToArray(DataSets); int providerCount = providers.Length; var bindingsPerProvider = new List <DataBinding> [providerCount]; for (int i = 0; i < providerCount; i++) { bindingsPerProvider[i] = new List <DataBinding>(); } foreach (DataBinding binding in bindings) { ResolvedBinding resolvedBinding = ResolveBinding(binding); if (resolvedBinding != null) { bindingsPerProvider[resolvedBinding.DataSetInfo.DataSetIndex].Add(resolvedBinding.Inner); } } foreach (IList <IDataItem> itemList in strategy.Join(providers, bindingsPerProvider, includeDynamicItems)) { yield return(new JoinedDataItem(this, itemList)); } }
public LocationInfoBindingProperty GetLocationInfo(ResolvedBinding resolvedBinding) { return(new LocationInfoBindingProperty( resolvedBinding.TreeRoot?.FileName, resolvedBinding.DothtmlNode?.Tokens?.Select(t => (t.StartPosition, t.EndPosition)).ToArray(), resolvedBinding.DothtmlNode?.Tokens?.FirstOrDefault()?.LineNumber ?? -1, resolvedBinding.GetAncestors().OfType <ResolvedControl>().FirstOrDefault()?.Metadata?.Type)); }
public virtual IBinding CreateMinimalClone(ResolvedBinding binding) { var properties = GetMinimalCloneProperties(binding.Binding); return((IBinding)Activator.CreateInstance(binding.BindingType, new object[] { binding.BindingService, properties })); }
protected override object GetValueImpl(DataBinding binding) { ResolvedBinding resolvedBinding = owner.ResolveBinding(binding); if (resolvedBinding == null) { throw new DataBindingException("Could not determine the underlying data set that supports the binding.", binding); } return(items[resolvedBinding.DataSetInfo.DataSetIndex].GetValue(resolvedBinding.Inner)); }
public virtual IBinding CreateMinimalClone(ResolvedBinding binding) { var requirements = binding.BindingService.GetRequirements(binding.Binding); var properties = requirements.Required.Concat(requirements.Optional) .Concat(new[] { typeof(OriginalStringBindingProperty), typeof(DataContextStack), typeof(LocationInfoBindingProperty) }) .Select(p => binding.Binding.GetProperty(p, ErrorHandlingMode.ReturnNull)) .Where(p => p != null).ToArray(); return((IBinding)Activator.CreateInstance(binding.BindingType, new object[] { binding.BindingService, properties })); }
public override string CompileToJs(ResolvedBinding binding, CompiledBindingExpression compiledExpression) { var expression = binding.GetExpression(); var visitor = new ExtractExpressionVisitor(ex => ex.NodeType == ExpressionType.Call); var rootCallback = visitor.Visit(expression); var js = SouldCompileCallback(rootCallback) ? JavascriptTranslator.CompileToJavascript(rootCallback, binding.DataContextTypeStack) : null; foreach (var param in visitor.ParameterOrder) { var callback = js == null ? null : $"function({param.Name}){{{js}}}"; var method = visitor.Replaced[param] as MethodCallExpression; js = CompileMethodCall(method, binding.DataContextTypeStack, callback); } return("var $context = ko.contextFor(this);var sender = this;(function(i_pageArea){with($context){" + js + "}})"); }
protected virtual Expression GetExpression(ResolvedPropertySetter a, out ResolvedBinding binding) { binding = null; if (a is ResolvedPropertyValue) { return(Expression.Constant(a.CastTo <ResolvedPropertyValue>().Value)); } else if (a is ResolvedPropertyBinding) { binding = a.CastTo <ResolvedPropertyBinding>().Binding; return(binding.GetExpression()); } else { return(null); } }
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); }
public new string CompileToJavascript(ResolvedBinding binding, CompiledBindingExpression compiledExpression, DotvvmConfiguration config) { var vmMapper = config.ServiceLocator.GetService <IViewModelSerializationMapper>(); var expression = binding.GetExpression(); var visitor = new ExtractExpressionVisitor(ex => ex.NodeType == ExpressionType.Call); var rootCallback = visitor.Visit(expression); var js = SouldCompileCallback(rootCallback) ? "resultPromise.resolve(" + JavascriptTranslator.FormatKnockoutScript(JavascriptTranslator.CompileToJavascript(rootCallback, binding.DataContextTypeStack, vmMapper), allowDataGlobal: false) + ")" : null; foreach (var param in visitor.ParameterOrder.Reverse <ParameterExpression>()) { if (js == null) { js = $"resultPromise.resolve({param.Name})"; } var callback = $"function({param.Name}){{{js}}}"; var method = visitor.Replaced[param] as MethodCallExpression; js = CompileMethodCall(method, binding.DataContextTypeStack, vmMapper, callback); } return("var $context = ko.contextFor(this);var sender = this;var resultPromise = new DotvvmPromise();(function(i_pageArea){with($context){" + js + "}})"); }
public IdBindingProperty CreateBindingId( OriginalStringBindingProperty originalString = null, ParsedExpressionBindingProperty expression = null, DataContextStack dataContext = null, ResolvedBinding resolvedBinding = null, AssignedPropertyBindingProperty assignedProperty = null) { var sb = new StringBuilder(); // don't append expression when original string is present, so it does not have to be always exactly same if (originalString != null) { sb.Append(originalString.Code); } else { sb.Append(expression.ToString()); } sb.Append("|||"); sb.Append(dataContext?.GetHashCode()); sb.Append("|||"); sb.Append(assignedProperty?.DotvvmProperty?.FullName); sb.Append(assignedProperty?.DotvvmProperty?.GetHashCode()); if (resolvedBinding?.TreeRoot != null) { var bindingIndex = bindingCounts.GetOrCreateValue(resolvedBinding.TreeRoot).AddOrUpdate(dataContext, 0, (_, i) => i + 1); sb.Append("|||"); sb.Append(bindingIndex); } using (var sha = System.Security.Cryptography.SHA256.Create()) { var hash = sha.ComputeHash(Encoding.Unicode.GetBytes(sb.ToString())); // use just 12 bytes = 96 bits return(new IdBindingProperty(Convert.ToBase64String(hash, 0, 12))); } }
public virtual string CompileToJavascript(ResolvedBinding binding, CompiledBindingExpression expression) { var javascript = JavascriptTranslator.CompileToJavascript(binding.GetExpression(), binding.DataContextTypeStack); if (javascript == "$data") { javascript = "$rawData"; } else if (javascript.StartsWith("$data.", StringComparison.Ordinal)) { javascript = javascript.Substring("$data.".Length); } // do not produce try/eval on single properties if (javascript.Contains(".") || javascript.Contains("(")) { return("dotvvm.evaluator.tryEval(function(){return " + javascript + "})"); } else { return(javascript); } }
/// <summary> /// Emits binding constructor and returns variable name /// </summary> protected ExpressionSyntax ProcessBinding(ResolvedBinding binding) { return(bindingCompiler.EmitCreateBinding(emitter, binding)); }
public override ExpressionSyntax EmitCreateBinding(DefaultViewCompilerCodeEmitter emitter, ResolvedBinding binding, string id, Type expectedType) { 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); } }
public override string CompileToJs(ResolvedBinding binding, CompiledBindingExpression expression) { return($"dotvvm.postbackScript('{ expression.Id }')"); }
public virtual Expression GetExpression(ResolvedBinding binding) { return(binding.GetExpression()); }
public string GetId(ResolvedBinding binding, string fileHash) { return(binding.Value); }
public virtual ExpressionSyntax EmitCreateBinding(DefaultViewCompilerCodeEmitter emitter, ResolvedBinding binding) { var newbinding = CreateMinimalClone(binding); return(emitter.EmitValue(newbinding)); }
/// <summary> /// Emits binding contructor and returns variable name /// </summary> protected ExpressionSyntax ProcessBinding(ResolvedBinding binding, Type expectedType) { //return emitter.EmitCreateObject(binding.Type, new object[] { binding.Value }); return(emitter.CreateObjectExpression(binding.BindingType, new[] { bindingCompiler.EmitCreateBinding(emitter, binding, bindingIdGenerator(binding), expectedType) })); }
/// <summary> /// https://tc39.es/ecma262/#sec-resolveexport /// </summary> internal override ResolvedBinding ResolveExport(string exportName, List <ExportResolveSetItem> resolveSet = null) { resolveSet ??= new List <ExportResolveSetItem>(); for (var i = 0; i < resolveSet.Count; i++) { var r = resolveSet[i]; if (ReferenceEquals(this, r.Module) && exportName == r.ExportName) { // circular import request return(null); } } resolveSet.Add(new ExportResolveSetItem(this, exportName)); for (var i = 0; i < _localExportEntries.Count; i++) { var e = _localExportEntries[i]; if (exportName == e.ExportName) { // i. Assert: module provides the direct binding for this export. return(new ResolvedBinding(this, e.LocalName)); } } for (var i = 0; i < _indirectExportEntries.Count; i++) { var e = _indirectExportEntries[i]; if (exportName == e.ExportName) { var importedModule = _engine._host.ResolveImportedModule(this, e.ModuleRequest); if (e.ImportName == "*") { // 1. Assert: module does not provide the direct binding for this export. return(new ResolvedBinding(importedModule, "*namespace*")); } else { // 1. Assert: module imports a specific binding for this export. return(importedModule.ResolveExport(e.ImportName, resolveSet)); } } } if ("default".Equals(exportName)) { // Assert: A default export was not explicitly defined by this module return(null); } ResolvedBinding starResolution = null; for (var i = 0; i < _starExportEntries.Count; i++) { var e = _starExportEntries[i]; var importedModule = _engine._host.ResolveImportedModule(this, e.ModuleRequest); var resolution = importedModule.ResolveExport(exportName, resolveSet); if (resolution == ResolvedBinding.Ambiguous) { return(resolution); } if (resolution is not null) { if (starResolution is null) { starResolution = resolution; } else { if (resolution.Module != starResolution.Module || resolution.BindingName != starResolution.BindingName) { return(ResolvedBinding.Ambiguous); } } } } return(starResolution); }
/// <inheritdoc /> protected override bool CanBindImpl(DataBinding binding) { ResolvedBinding resolvedBinding = ResolveBinding(binding); return(resolvedBinding != null && DataSets[resolvedBinding.DataSetInfo.DataSetIndex].CanBind(resolvedBinding.Inner)); }
public string CompileToJavascript(ResolvedBinding binding, CompiledBindingExpression expression, DotvvmConfiguration config) { return(new JsIdentifierExpression("dotvvm").Member("postbackScript").Invoke(new JsLiteral(expression.Id)).FormatScript()); }
public override string CompileToJavascript(ResolvedBinding binding, CompiledBindingExpression expression) { return($"dotvvm.postbackScript({ JsonConvert.SerializeObject(expression.Id) })"); }
protected virtual ResolvedPropertySetter EmitBinding(Expression expression, DotvvmProperty property, ResolvedBinding originalBidning, ref string errror) { if (originalBidning == null) { errror = $"Could not merge constant values to binding '{expression}'."; return(null); } return(new ResolvedPropertyBinding(property, new ResolvedBinding(originalBidning.BindingService, originalBidning.Binding.GetProperty <BindingParserOptions>(), originalBidning.DataContextTypeStack, null, expression, property)) { DothtmlNode = originalBidning.DothtmlNode }); }
public virtual ExpressionSyntax EmitCreateBinding(DefaultViewCompilerCodeEmitter emitter, ResolvedBinding binding, string id, Type expectedType) { var compilerAttribute = GetCompilationAttribute(binding.BindingType); var requirements = compilerAttribute.GetRequirements(binding.BindingType); var expression = new Lazy <Expression>(() => compilerAttribute.GetExpression(binding)); var compiled = new CompiledBindingExpression(); compiled.Delegate = TryExecute(binding.BindingNode, "Error while compiling binding to delegate.", requirements.Delegate, () => CompileExpression(compilerAttribute.CompileToDelegate(binding.GetExpression(), binding.DataContextTypeStack, expectedType), binding.DebugInfo)); compiled.UpdateDelegate = TryExecute(binding.BindingNode, "Error while compiling update delegate.", requirements.UpdateDelegate, () => compilerAttribute.CompileToUpdateDelegate(binding.GetExpression(), binding.DataContextTypeStack).Compile()); compiled.OriginalString = TryExecute(binding.BindingNode, "hey, no, that should not happen. Really.", requirements.OriginalString, () => binding.Value); compiled.Expression = TryExecute(binding.BindingNode, "Could not get binding expression.", requirements.Expression, () => binding.GetExpression()); compiled.Id = id; compiled.ActionFilters = TryExecute(binding.BindingNode, "", requirements.ActionFilters, () => compilerAttribute.GetActionFilters(binding.GetExpression()).ToArray()); compiled.Javascript = TryExecute(binding.BindingNode, "Could not compile binding to Javascript.", requirements.Javascript, () => compilerAttribute.CompileToJavascript(binding, compiled)); var index = Interlocked.Increment(ref globalBindingIndex); if (!GlobalBindingList.TryAdd(index, compiled)) { throw new Exception("internal bug"); } return(EmitGetCompiledBinding(index)); }
protected virtual ResolvedPropertySetter EmitBinding(Expression expression, DotvvmProperty property, ResolvedBinding originalBidning, ref string errror) { if (originalBidning == null) { errror = $"Could not merge constant values to binding '{expression}'."; return(null); } return(new ResolvedPropertyBinding(property, new ResolvedBinding { BindingType = originalBidning.BindingType, DataContextTypeStack = originalBidning.DataContextTypeStack, Expression = expression, Parent = originalBidning.Parent, ResultType = new ResolvedTypeDescriptor(expression.Type) })); }
public IdBindingProperty CreateBindingId( OriginalStringBindingProperty originalString = null, ParsedExpressionBindingProperty expression = null, DataContextStack dataContext = null, ResolvedBinding resolvedBinding = null, LocationInfoBindingProperty locationInfo = null) { var sb = new StringBuilder(); if (resolvedBinding?.TreeRoot != null && dataContext != null) { var bindingIndex = bindingCounts.GetOrCreateValue(resolvedBinding.TreeRoot).AddOrUpdate(dataContext, 0, (_, i) => i + 1); sb.Append(bindingIndex); sb.Append(" || "); } // don't append expression when original string is present, so it does not have to be always exactly same if (originalString != null) { sb.Append(originalString.Code); } else { sb.Append(expression.Expression.ToString()); } sb.Append(" || "); while (dataContext != null) { sb.Append(dataContext.DataContextType.FullName); sb.Append('('); foreach (var ns in dataContext.NamespaceImports) { sb.Append(ns.Alias); sb.Append('='); sb.Append(ns.Namespace); } sb.Append(';'); foreach (var ext in dataContext.ExtensionParameters) { sb.Append(ext.Identifier); if (ext.Inherit) { sb.Append('*'); } sb.Append(':'); sb.Append(ext.ParameterType.FullName); sb.Append(':'); sb.Append(ext.GetType().FullName); } sb.Append(") -- "); dataContext = dataContext.Parent; } sb.Append(" || "); sb.Append(locationInfo?.RelatedProperty?.FullName); using (var sha = System.Security.Cryptography.SHA256.Create()) { var hash = sha.ComputeHash(Encoding.Unicode.GetBytes(sb.ToString())); // use just 12 bytes = 96 bits return(new IdBindingProperty(Convert.ToBase64String(hash, 0, 12))); } }
//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 // }, configuration)); // return result; //} public override ExpressionSyntax EmitCreateBinding(DefaultViewCompilerCodeEmitter emitter, ResolvedBinding binding) { 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; }