private void InitProperty(string property, string value, DomAttributeWithInitializers withInit) { PropertyInfo prop; DomAttribute attr = withInit.Attribute; if (property == null) { var valueProp = HxlAttributeFragmentDefinition.ForComponent(attr).ValueProperty; if (valueProp == null) { valueProp = Utility.ReflectGetProperty(attr.GetType(), "Value"); } // TODO Might not have a value property (should implement an expression around the Value property) prop = valueProp; } else { // TODO Obtain line numbers prop = Utility.ReflectGetProperty(attr.GetType(), property); if (prop == null) { throw HxlFailure.ServerAttributePropertyNotFound(attr.GetType(), property, -1, -1); } } if (!HxlAttributeConverter.IsExpr(value)) { if (property == null) { withInit.Attribute.Value = value; } withInit.Initializers.Add(prop.Name, value); return; } var buffer = new ExpressionBuffer(); RewriteExpressionSyntax.MatchVariablesAndEmit(buffer, value); // TODO Could allow multiple exprs if (buffer.Parts.Count == 1) { } else { throw new NotImplementedException("ex"); } attr.AddAnnotation(new ExpressionInitializers(prop, buffer.Parts[0])); }
internal static void EmitRenderingThunk(TextWriter sw, string name, DomObject component) { StringBuilder rendering = new StringBuilder(); // TODO Undesirable that expressions get serialized in EmitInstantiation // TODO This serialization logic implies that only strings can be used with expressions foreach (PropertyInfo m in Utility.ReflectGetProperties(component.GetType())) { if (m.CanWrite && m.PropertyType == typeof(string)) { // TODO Need to check more than CanWrite -- may need to check accessibility of the setter (rare) string text = (string)m.GetValue(component) ?? string.Empty; if (HxlAttributeConverter.IsExpr(text)) { CodeBuffer cb = new CodeBuffer(); RewriteExpressionSyntax.MatchVariablesAndEmit(cb, text); rendering.AppendFormat(" {2}.{0} = {1};", m.Name, cb, name); rendering.AppendLine(); } } } var additional = component.Annotations <ExpressionInitializers>(); foreach (ExpressionInitializers m in additional) { rendering.AppendFormat(" {2}.{0} = {1};", m.Member.Name, m.Expression, name); rendering.AppendLine(); } // TODO Use of __self__ is a hack (will it actually be used?) if (rendering.Length > 0) { sw.WriteLine("{0}.Rendering = (__context, __self__) => {{", name); sw.WriteLine(" dynamic __closure = __context;"); sw.Write(rendering); sw.WriteLine("};"); } }
internal static HxlCompilerConverter ChooseConverter(DomObject node) { switch (node.NodeType) { case DomNodeType.Element: return(HxlElementConverter.GetElementConverter((DomElement)node)); case DomNodeType.Attribute: return(HxlAttributeConverter.GetAttributeConverter((DomAttribute)node)); case DomNodeType.ProcessingInstruction: return(HxlProcessingInstructionConverter.GetProcessingInstructionConverter((DomProcessingInstruction)node)); case DomNodeType.Text: // TODO Could be noop if entity ref nodes were processed (design, perf) // Right now, inlining is the cleanest way to handle entities correctly return(Inline); case DomNodeType.DocumentType: default: return(Noop); } }