protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) { using (Compiler.Local oldList = AppendToCollection ? ctx.GetLocalWithValue(ExpectedType, valueFrom) : null) using (Compiler.Local builder = new Compiler.Local(ctx, builderFactory.ReturnType)) { ctx.EmitCall(builderFactory); ctx.StoreValue(builder); if (AppendToCollection) { Compiler.CodeLabel done = ctx.DefineLabel(); if (!Helpers.IsValueType(ExpectedType)) { ctx.LoadValue(oldList); ctx.BranchIfFalse(done, false); // old value null; nothing to add } #if COREFX TypeInfo typeInfo = ExpectedType.GetTypeInfo(); #else Type typeInfo = ExpectedType; #endif PropertyInfo prop = Helpers.GetProperty(typeInfo, "Length", false); if (prop == null) { prop = Helpers.GetProperty(typeInfo, "Count", false); } #if !NO_GENERICS if (prop == null) { prop = Helpers.GetProperty(ResolveIReadOnlyCollection(ExpectedType, Tail.ExpectedType), "Count", false); } #endif ctx.LoadAddress(oldList, oldList.Type); ctx.EmitCall(Helpers.GetGetMethod(prop, false, false)); ctx.BranchIfFalse(done, false); // old list is empty; nothing to add Type voidType = ctx.MapType(typeof(void)); if (addRange != null) { ctx.LoadValue(builder); ctx.LoadValue(oldList); ctx.EmitCall(addRange); if (addRange.ReturnType != null && add.ReturnType != voidType) { ctx.DiscardValue(); } } else { // loop and call Add repeatedly MethodInfo moveNext, current, getEnumerator = GetEnumeratorInfo(ctx.Model, out moveNext, out current); Helpers.DebugAssert(moveNext != null); Helpers.DebugAssert(current != null); Helpers.DebugAssert(getEnumerator != null); Type enumeratorType = getEnumerator.ReturnType; using (Compiler.Local iter = new Compiler.Local(ctx, enumeratorType)) { ctx.LoadAddress(oldList, ExpectedType); ctx.EmitCall(getEnumerator); ctx.StoreValue(iter); using (ctx.Using(iter)) { Compiler.CodeLabel body = ctx.DefineLabel(), next = ctx.DefineLabel(); ctx.Branch(next, false); ctx.MarkLabel(body); ctx.LoadAddress(builder, builder.Type); ctx.LoadAddress(iter, enumeratorType); ctx.EmitCall(current); ctx.EmitCall(add); if (add.ReturnType != null && add.ReturnType != voidType) { ctx.DiscardValue(); } ctx.MarkLabel(@next); ctx.LoadAddress(iter, enumeratorType); ctx.EmitCall(moveNext); ctx.BranchIfTrue(body, false); } } } ctx.MarkLabel(done); } EmitReadList(ctx, builder, Tail, add, packedWireType, false); ctx.LoadAddress(builder, builder.Type); ctx.EmitCall(finish); if (ExpectedType != finish.ReturnType) { ctx.Cast(ExpectedType); } } }
protected MethodInfo GetEnumeratorInfo(TypeModel model, out MethodInfo moveNext, out MethodInfo current) { #if WINRT TypeInfo enumeratorType = null, iteratorType, expectedType = ExpectedType.GetTypeInfo(); #else Type enumeratorType = null, iteratorType, expectedType = ExpectedType; #endif // try a custom enumerator MethodInfo getEnumerator = Helpers.GetInstanceMethod(expectedType, "GetEnumerator", null); Type itemType = Tail.ExpectedType; Type getReturnType = null; if (getEnumerator != null) { getReturnType = getEnumerator.ReturnType; iteratorType = getReturnType #if WINRT .GetTypeInfo() #endif ; moveNext = Helpers.GetInstanceMethod(iteratorType, "MoveNext", null); PropertyInfo prop = Helpers.GetProperty(iteratorType, "Current", false); current = prop == null ? null : Helpers.GetGetMethod(prop, false, false); if (moveNext == null && (model.MapType(ienumeratorType).IsAssignableFrom(iteratorType))) { moveNext = Helpers.GetInstanceMethod(model.MapType(ienumeratorType), "MoveNext", null); } // fully typed if (moveNext != null && moveNext.ReturnType == model.MapType(typeof(bool)) && current != null && current.ReturnType == itemType) { return(getEnumerator); } moveNext = current = getEnumerator = null; } #if !NO_GENERICS // try IEnumerable<T> Type tmp = model.MapType(typeof(System.Collections.Generic.IEnumerable <>), false); if (tmp != null) { tmp = tmp.MakeGenericType(itemType); #if WINRT enumeratorType = tmp.GetTypeInfo(); #else enumeratorType = tmp; #endif } ; if (enumeratorType != null && enumeratorType.IsAssignableFrom(expectedType)) { getEnumerator = Helpers.GetInstanceMethod(enumeratorType, "GetEnumerator"); getReturnType = getEnumerator.ReturnType; #if WINRT iteratorType = getReturnType.GetTypeInfo(); #else iteratorType = getReturnType; #endif moveNext = Helpers.GetInstanceMethod(model.MapType(ienumeratorType), "MoveNext"); current = Helpers.GetGetMethod(Helpers.GetProperty(iteratorType, "Current", false), false, false); return(getEnumerator); } #endif // give up and fall-back to non-generic IEnumerable enumeratorType = model.MapType(ienumerableType); getEnumerator = Helpers.GetInstanceMethod(enumeratorType, "GetEnumerator"); getReturnType = getEnumerator.ReturnType; iteratorType = getReturnType #if WINRT .GetTypeInfo() #endif ; moveNext = Helpers.GetInstanceMethod(iteratorType, "MoveNext"); current = Helpers.GetGetMethod(Helpers.GetProperty(iteratorType, "Current", false), false, false); return(getEnumerator); }
protected override void EmitRead(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom) { Type listType; #if NO_GENERICS listType = typeof(BasicList); #else listType = ctx.MapType(typeof(System.Collections.Generic.List <>)).MakeGenericType(itemType); #endif using (Compiler.Local oldArr = AppendToCollection ? ctx.GetLocalWithValue(ExpectedType, valueFrom) : null) using (Compiler.Local newArr = new Compiler.Local(ctx, ExpectedType)) using (Compiler.Local list = new Compiler.Local(ctx, listType)) { ctx.EmitCtor(listType); ctx.StoreValue(list); ListDecorator.EmitReadList(ctx, list, Tail, listType.GetMethod("Add"), packedWireType, false); // leave this "using" here, as it can share the "FieldNumber" local with EmitReadList using (Compiler.Local oldLen = AppendToCollection ? new ProtoBuf.Compiler.Local(ctx, ctx.MapType(typeof(int))) : null) { Type[] copyToArrayInt32Args = new Type[] { ctx.MapType(typeof(Array)), ctx.MapType(typeof(int)) }; if (AppendToCollection) { ctx.LoadLength(oldArr, true); ctx.CopyValue(); ctx.StoreValue(oldLen); ctx.LoadAddress(list, listType); ctx.LoadValue(listType.GetProperty("Count")); ctx.Add(); ctx.CreateArray(itemType, null); // length is on the stack ctx.StoreValue(newArr); ctx.LoadValue(oldLen); Compiler.CodeLabel nothingToCopy = ctx.DefineLabel(); ctx.BranchIfFalse(nothingToCopy, true); ctx.LoadValue(oldArr); ctx.LoadValue(newArr); ctx.LoadValue(0); // index in target ctx.EmitCall(ExpectedType.GetMethod("CopyTo", copyToArrayInt32Args)); ctx.MarkLabel(nothingToCopy); ctx.LoadValue(list); ctx.LoadValue(newArr); ctx.LoadValue(oldLen); } else { ctx.LoadAddress(list, listType); ctx.LoadValue(listType.GetProperty("Count")); ctx.CreateArray(itemType, null); ctx.StoreValue(newArr); ctx.LoadAddress(list, listType); ctx.LoadValue(newArr); ctx.LoadValue(0); } copyToArrayInt32Args[0] = ExpectedType; // // prefer: CopyTo(T[], int) MethodInfo copyTo = listType.GetMethod("CopyTo", copyToArrayInt32Args); if (copyTo == null) { // fallback: CopyTo(Array, int) copyToArrayInt32Args[1] = ctx.MapType(typeof(Array)); copyTo = listType.GetMethod("CopyTo", copyToArrayInt32Args); } ctx.EmitCall(copyTo); } ctx.LoadValue(newArr); } }
private void AddProperties(ExpectedType expectedType, string alias, string name, int count = 3) { expectedType.Properties = new List <ExpectedProperty>(); count--; if (count < 0) { return; } expectedType.Properties.Add(new ExpectedProperty() { Name = alias == "master" ? "Master Textstring Renamed Root" : name + " Textstring Root", Alias = alias + "TextstringRoot", DataType = new ExpectedDataType() { DataTypeName = "Textstring", DbType = DataTypeDatabaseType.Nvarchar, PropertyEditorAlias = "Umbraco.Textbox" }, Description = "", Mandatory = false, SortOrder = alias == "child1" ? 2 : 0, Regex = "" }); count--; if (count < 0) { return; } expectedType.Properties.Add(new ExpectedProperty() { Name = name + " True False Root", Alias = alias + "TrueFalseRoot", DataType = new ExpectedDataType() { DataTypeName = "Checkbox", DbType = DataTypeDatabaseType.Integer, PropertyEditorAlias = "Umbraco.TrueFalse" }, Description = "", Mandatory = false, SortOrder = alias == "child1" ? 3 : 0, Regex = "" }); count--; if (count < 0) { return; } expectedType.Properties.Add(new ExpectedProperty() { Name = name + " Numeric Root", Alias = alias + "NumericRoot", DataType = new ExpectedDataType() { DataTypeName = "Numeric", DbType = DataTypeDatabaseType.Integer, PropertyEditorAlias = "Umbraco.Integer" }, Description = "", Mandatory = false, SortOrder = alias == "child1" ? 1 : 0, Regex = "" }); count--; if (count < 0) { return; } expectedType.Properties.Add(new ExpectedProperty() { Name = name + " Label Root", Alias = alias + "LabelRoot", DataType = new ExpectedDataType() { DataTypeName = "Label", DbType = DataTypeDatabaseType.Nvarchar, PropertyEditorAlias = "Umbraco.NoEdit" }, Description = " This be a lABel ", Mandatory = true, SortOrder = 0, Regex = "" }); }
private void AddTab(ExpectedType expectedType, string alias, string name, bool useCommon = true, int count = 2) { expectedType.Tabs = new List <ExpectedTab>(); expectedType.Tabs.Add(new ExpectedTab() { Name = name + " Tab", SortOrder = 0 }); expectedType.Tabs.Last().Properties = new List <ExpectedProperty>(); if (useCommon) { expectedType.Tabs.Last().Properties.Add(CommonTabProperty(name)); } if (expectedType.Alias == "child2" || expectedType.Alias == "mediaChild2") { expectedType.Tabs.Last().Properties.Add(new ExpectedProperty() { Alias = "folderPicker_" + name.Replace(" ", "_") + "_Tab", Name = "Folder Picker", Description = "", DataType = new ExpectedDataType() { DataTypeName = "Single Media Picker - Folder", DbType = DataTypeDatabaseType.Ntext, PropertyEditorAlias = "Umbraco.MultiNodeTreePicker" }, Mandatory = false, SortOrder = 0, Regex = "" }); } count--; if (count < 0) { return; } expectedType.Tabs.Last().Properties.Add(new ExpectedProperty() { Alias = alias + "RichtextEditorTab_" + name.Replace(" ", "_") + "_Tab", Name = name + " Richtext Editor Tab", Description = "", DataType = new ExpectedDataType() { DataTypeName = "Richtext editor", DbType = DataTypeDatabaseType.Ntext, PropertyEditorAlias = "Umbraco.TinyMCEv3" }, Mandatory = false, SortOrder = 0, Regex = "" }); count--; if (count < 0) { return; } expectedType.Tabs.Last().Properties.Add(new ExpectedProperty() { Alias = alias + "DatePickerTab_" + name.Replace(" ", "_") + "_Tab", Name = name + " Date Picker Tab", Description = "", DataType = new ExpectedDataType() { DataTypeName = "Date Picker", DbType = DataTypeDatabaseType.Date, PropertyEditorAlias = "Umbraco.Date" }, Mandatory = alias == "master", SortOrder = 0, Regex = "" }); count--; if (count < 0) { return; } expectedType.Tabs.Last().Properties.Add(new ExpectedProperty() { Alias = alias + "TextstringTab_" + name.Replace(" ", "_") + "_Tab", Name = name + " Textstring Tab", Description = "", DataType = new ExpectedDataType() { DataTypeName = "Textstring", DbType = DataTypeDatabaseType.Nvarchar, PropertyEditorAlias = "Umbraco.Textbox" }, Mandatory = false, SortOrder = 0, Regex = "" }); }
/// <summary> /// Test whether an object is of the specified type or a derived type /// </summary> /// <param name="actual">The object to be tested</param> /// <returns>True if the object is of the provided type or derives from it, otherwise false.</returns> protected override bool Matches <TActual>(TActual actual) { return(actual != null && ExpectedType.IsInstanceOfType(actual)); }
/// <summary> /// Write human readable output. /// </summary> public override void WriteTo(ITextOutput output) { if (Operand is AstVariable && ((AstVariable)Operand).IsGenerated) { if (Code == AstCode.Stloc && InferredType == null) { output.Write(((AstVariable)Operand).Name); output.Write(" = "); Arguments.First().WriteTo(output); return; } if (Code == AstCode.Ldloc) { output.Write(((AstVariable)Operand).Name); if (InferredType != null) { output.Write(':'); InferredType.WriteTo(output, AstNameSyntax.ShortTypeName); if ((ExpectedType != null) && (ExpectedType.FullName != this.InferredType.FullName)) { output.Write("[exp:"); ExpectedType.WriteTo(output, AstNameSyntax.ShortTypeName); output.Write(']'); } } return; } } if (Prefixes != null) { foreach (var prefix in Prefixes) { output.Write(prefix.Code.GetName()); output.Write(". "); } } output.Write(Code.GetName()); if (InferredType != null) { output.Write(':'); InferredType.WriteTo(output, AstNameSyntax.ShortTypeName); if ((ExpectedType != null) && (ExpectedType.FullName != InferredType.FullName)) { output.Write("[exp:"); ExpectedType.WriteTo(output, AstNameSyntax.ShortTypeName); output.Write(']'); } } else if (ExpectedType != null) { output.Write("[exp:"); ExpectedType.WriteTo(output, AstNameSyntax.ShortTypeName); output.Write(']'); } output.Write('('); var first = true; if (Operand != null) { if (Operand is AstLabel) { output.WriteReference(((AstLabel)Operand).Name, Operand); } else if (Operand is AstLabel[]) { var labels = (AstLabel[])Operand; for (var i = 0; i < labels.Length; i++) { if (i > 0) { output.Write(", "); } output.WriteReference(labels[i].Name, labels[i]); } } else if (Operand is AstLabelKeyPair[]) { var pairs = (AstLabelKeyPair[])Operand; for (var i = 0; i < pairs.Length; i++) { if (i > 0) { output.Write(", "); } output.Write("{0} -> ", pairs[i].Key); output.WriteReference(pairs[i].Label.Name, pairs[i].Label); } } else if (Operand is XMethodReference) { var method = (XMethodReference)Operand; if (method.DeclaringType != null) { method.DeclaringType.WriteTo(output, AstNameSyntax.ShortTypeName); output.Write("::"); } output.WriteReference(method.Name, method); } else if (Operand is XFieldReference) { var field = (XFieldReference)Operand; field.DeclaringType.WriteTo(output, AstNameSyntax.ShortTypeName); output.Write("::"); output.WriteReference(field.Name, field); } else { DisassemblerHelpers.WriteOperand(output, Operand); } first = false; } foreach (var arg in Arguments) { if (!first) { output.Write(", "); } arg.WriteTo(output); first = false; } output.Write(')'); }