Beispiel #1
0
        public static void CombineFormats(FileGeneration generation, TypeTree origin)
        {
            if (TypeTreeNode.IsFormat5(generation))
            {
                Dictionary <uint, string> customTypes = new Dictionary <uint, string>();
                using (MemoryStream stream = new MemoryStream(origin.CustomTypeBuffer))
                {
                    using (EndianReader reader = new EndianReader(stream, EndianType.LittleEndian))
                    {
                        while (stream.Position < stream.Length)
                        {
                            uint   position = (uint)stream.Position;
                            string name     = reader.ReadStringZeroTerm();
                            customTypes.Add(position, name);
                        }
                    }
                }

                foreach (TypeTreeNode node in origin.Nodes)
                {
                    node.Type = GetTypeName(customTypes, node.TypeOffset);
                    node.Name = GetTypeName(customTypes, node.NameOffset);
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Gets the type tree for the base class.
        /// If class has multi inheritance, it can return MultiClassInheritanceTypeTree or SingleClassInheritanceWithInterfacesTypeTree.
        /// </summary>
        /// <param name="error">The error text writer.</param>
        /// <param name="type">The type for which we are getting base class.</param>
        /// <param name="factory">The user type factory.</param>
        /// <param name="baseClassOffset">The base class offset.</param>
        protected override TypeTree GetBaseClassTypeTree(TextWriter error, Symbol type, UserTypeFactory factory, out int baseClassOffset)
        {
            TypeTree baseType = base.GetBaseClassTypeTree(error, type, factory, out baseClassOffset);

            this.baseClassOffset = baseClassOffset;
            return(baseType);
        }
Beispiel #3
0
        static IEnumerable <object> Resolve(ITypeTree <ServiceDefinition> services, ITypeTree <object> scope, Type root, IEnumerable <Type> types)
        {
            if (scope == null)
            {
                scope = new TypeTree <object>();
            }

            var any = false;

            foreach (var key in types)
            {
                any = true;
                yield return(SolveExact(services, scope, key));
            }

            if (!any && root != null && CanCreate(services, scope, root))
            {
                var result = Create(services, scope, root);
                if (!root.IsValueType)
                {
                    scope[root] = result;
                }
                yield return(result);
            }
        }
Beispiel #4
0
        public static void ClassInitialize(TestContext context)
        {
            var file = @".\Data\bundle_5.1.unity3d";
            var abr  = new AssestFile(file);

            _tree = abr.TypeTree;
        }
Beispiel #5
0
        private static bool DoesContractContainBreakingChanges(string dllName, string baselinePath, string breakingChangesPath)
        {
            TypeTree locally = new TypeTree(typeof(object));

            ContractEnforcement.BuildTypeTree(locally, ContractEnforcement.GetAssemblyLocally(dllName).GetExportedTypes());

            TypeTree baseline = JsonConvert.DeserializeObject <TypeTree>(File.ReadAllText(baselinePath));

            string localJson = JsonConvert.SerializeObject(locally, Formatting.Indented);

            File.WriteAllText($"{breakingChangesPath}", localJson);
            string baselineJson = JsonConvert.SerializeObject(baseline, Formatting.Indented);

            System.Diagnostics.Trace.TraceWarning($"String length Expected: {baselineJson.Length};Actual:{localJson.Length}");
            if (string.Equals(localJson, baselineJson, StringComparison.InvariantCulture))
            {
                return(false);
            }
            else
            {
                System.Diagnostics.Trace.TraceWarning($"Expected: {baselineJson}");
                System.Diagnostics.Trace.TraceWarning($"Actual: {localJson}");
                return(true);
            }
        }
Beispiel #6
0
        public AssetTypeValueField GetBaseField(AssetContainer cont)
        {
            AssetsFileInstance fileInst = cont.FileInstance;
            if (cont.ClassId == 0x72)
            {
                TypeTree tt = cont.FileInstance.file.typeTree;
                //check if typetree data exists already
                if (!tt.hasTypeTree || AssetHelper.FindTypeTreeTypeByScriptIndex(tt, cont.MonoId) == null)
                {
                    //deserialize from dll (todo: ask user if dll isn't in normal location)
                    string filePath;
                    if (fileInst.parentBundle != null)
                        filePath = Path.GetDirectoryName(fileInst.parentBundle.path);
                    else
                        filePath = Path.GetDirectoryName(fileInst.path);

                    string managedPath = Path.Combine(filePath, "Managed");
                    if (Directory.Exists(managedPath))
                    {
                        AssetTypeValueField monoBaseField = GetConcatMonoBaseField(cont, managedPath);
                        if (monoBaseField != null)
                            return monoBaseField;
                    }
                    //fallback to no mono deserialization for now
                }
            }

            cont = GetAssetContainer(cont.FileInstance, 0, cont.PathId, false);
            if (cont != null)
                return cont.TypeInstance.GetBaseField();
            else
                return null;
        }
Beispiel #7
0
        /// <summary>
        /// Gets the type tree for the specified field.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <param name="factory">The user type factory.</param>
        /// <param name="extractingBaseClass">if set to <c>true</c> user type field is being generated for getting base class.</param>
        /// <param name="bitLength">Number of bits used for this symbol.</param>
        protected override TypeTree GetFieldTypeTree(SymbolField field, UserTypeFactory factory, bool extractingBaseClass, int bitLength = 0)
        {
            // Do not match specializations when getting type for base class.
            if (extractingBaseClass || NumberOfTemplateArguments == 0)
            {
                return(GetSymbolTypeTree(field.Type, factory, bitLength));
            }

            // Check field in all specializations
            var specializedFields = SpecializedTypes.Select(r => new Tuple <TemplateUserType, SymbolField>(r, r.Symbol.Fields.FirstOrDefault(q => q.Name == field.Name))).ToArray();

            if (specializedFields.Any(r => r.Item2 == null))
            {
                // TODO: Incorrect bucketization. Field does not exist in all specialization.
                return(GetSymbolTypeTree(field.Type, factory, bitLength));
            }

            if (specializedFields.All(r => r.Item2.Type.Name == field.Type.Name))
            {
                // There is no specialization, all types across the specializations are the same.
                return(GetSymbolTypeTree(field.Type, factory, bitLength));
            }

            // Try to get type tree
            TypeTree result = GetSymbolTypeTree(field.Type, factory, bitLength);

            return(FixTypeTree(result, field.Type, factory));
        }
    public static Tuple <Type, IEnumerable <Type> > GetCommonBases(Type left, Type right)
    {
        var tree = new TypeTree(left);

        tree.Add(right);
        var findLeft         = tree.Find(left);
        var findRight        = tree.Find(right);
        var commonInterfaces =
            findLeft.Interfaces.Select(i => i.Value)
            .Intersect(findRight.Interfaces.Select(i => i.Value))
            .Distinct();
        var leftStack = new Stack <TypeTree>();
        var temp      = findLeft;

        while (temp != null)
        {
            leftStack.Push(temp);
            temp = temp.Parent;
        }
        var rightStack = new Stack <TypeTree>();

        temp = findRight;
        while (temp != null)
        {
            rightStack.Push(temp);
            temp = temp.Parent;
        }
        var zippedPaths = leftStack.Zip(rightStack, Tuple.Create);
        var result      = zippedPaths.TakeWhile(tup => tup.Item1.Value == tup.Item2.Value).Last();

        return(Tuple.Create(result.Item1.Value, commonInterfaces));
    }
Beispiel #9
0
        private static string NormalizeJsonString(string file)
        {
            TypeTree baseline      = JsonConvert.DeserializeObject <TypeTree>(file);
            string   updatedString = JsonConvert.SerializeObject(baseline, Formatting.Indented);

            return(updatedString);
        }
Beispiel #10
0
        private void AssetInfo_Load(object sender, EventArgs e)
        {
            AssetsFileHeader header   = file.header;
            TypeTree         typeTree = file.typeTree;

            //header
            hdr_mds.Text = header.metadataSize.ToString();
            hdr_fs.Text  = header.fileSize.ToString();
            hdr_fmt.Text = $"{header.format.ToString()} (0x{header.format.ToString("x")})";
            hdr_ffo.Text = $"{header.firstFileOffset.ToString()} (0x{header.firstFileOffset.ToString("x")})";
            hdr_en.Text  = header.endianness == 1 ? "big endian" : "little endian";
            hdr_uvr.Text = typeTree.unityVersion;
            hdr_ver.Text = $"{typeTree.version.ToString()} (0x{typeTree.version.ToString("x")})";
            hdr_htt.Text = typeTree.hasTypeTree == true ? "true" : "false";
            //type tree
            if (!typeTree.hasTypeTree)
            {
                ttr_tree.Nodes.Add("There is no type tree data available.");
            }
            else
            {
                ttr_tree.Nodes.Add("Select a type to show the type tree data.");
            }
            foreach (Type_0D type in typeTree.unity5Types)
            {
                if (type.typeFieldsExCount == 0)
                {
                    ClassDatabaseType cldt = cldb.classes.First(c => c.classId == type.classId);
                    ttr_list.Items.Add($"[{cldt.name.GetString(cldb)}] (0x{type.classId.ToString("x")})");
                }
                else
                {
                    TypeField_0D baseField = type.typeFieldsEx[0];
                    ttr_list.Items.Add($"{baseField.GetTypeString(type.stringTable)} (0x{type.classId.ToString("x")})");
                }
            }
            //preload list
            foreach (AssetPPtr pptr in file.preloadTable.items)
            {
                string pptrFileName = "[self]";
                if (pptr.fileID != 0)
                {
                    pptrFileName = file.dependencies.dependencies[pptr.fileID - 1].assetPath;
                }
                plt_list.Items.Add(new ListViewItem(new[] { pptrFileName, pptr.pathID.ToString() }));
            }
            plt_list.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
            //dependencies
            foreach (AssetsFileDependency dep in file.dependencies.dependencies)
            {
                string guid = string.Empty;
                if (dep.guid.mostSignificant != 0 || dep.guid.leastSignificant != 0)
                {
                    guid = $"{dep.guid.mostSignificant.ToString("x8")}{dep.guid.leastSignificant.ToString("x8")}";
                }
                dep_list.Items.Add(new ListViewItem(new[] { dep.assetPath, "0x" + dep.type.ToString(), guid }));
            }
            dep_list.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
        }
Beispiel #11
0
 public static IEnumerable <Type> DescendantsAndSelf(Type type)
 {
     if (type == null)
     {
         throw new ArgumentNullException(nameof(type));
     }
     return(TypeTree.DescendantsAndSelf(type));
 }
Beispiel #12
0
 static MessageHierarchy()
 {
     // Get the all of the types in the Assembly that are derived from Message and then build a
     // backing TypeTree.
     // TODO: Put in timing logging
     TypeTree.BuildTree(GetTypesDerivedFrom(typeof(Message)));
     AppDomain.CurrentDomain.AssemblyLoad += AssemblyLoadEventHandler;
 }
Beispiel #13
0
        public static void RenderTree(IRenderContext g, TypeTree tree)
        {
            RenderNode rRoot = RenderNode.ConvertFromNode(tree.root);
            Size       size  = rRoot.GetSize();

            g.DrawBackground(size);
            DrawTree(g, rRoot, rRoot.GetOriginX((int)size.Width), SquareSize);
        }
Beispiel #14
0
        public void From_AnyType_RootTreeTypeShouldMatch(Type type)
        {
            // Act
            var tree = TypeTree.From(type);

            // Assert
            Assert.Equal(type, tree.Type);
        }
Beispiel #15
0
        public void From_ClassWithNoImplementedInterfaces_TreeShouldNotHaveAny()
        {
            // Act
            var tree = TypeTree.From(typeof(NonGenericNoInterfacesClass));

            // Assert
            Assert.Null(tree.DirectlyImplementedInterfaces);
        }
Beispiel #16
0
        public void From_BuiltInType_TreeShouldNotHaveGenericArguments(Type simpleType)
        {
            // Act
            var tree = TypeTree.From(simpleType);

            // Assert
            Assert.Null(tree.GenericArguments);
        }
        public Tree makeNewArray(ExpressionContext context)
        {
            TypeTree   type   = (TypeTree)VisitType(context.type());
            Expression length = (Expression)VisitExpression(context.length);

            return(new NewArray(context.Start.Line, context.Start.Column, context.Stop.Line,
                                context.Stop.Column, type, length));
        }
Beispiel #18
0
        public void From_ClassWithNoGenericArguments_TreeShouldNotHaveAny()
        {
            // Act
            var tree = TypeTree.From(typeof(NonGenericNoInterfacesClass));

            // Assert
            Assert.Null(tree.GenericArguments);
        }
        public override Tree VisitFieldDef(FieldDefContext context)
        {
            String   name = context.name.Text;
            TypeTree type = (TypeTree)VisitType(context.type());

            return(new VariableDeclaration(context.Start.Line, context.Start.Column, context.Stop.Line,
                                           context.Stop.Column, name, type, null));
        }
        static unsafe void ExportStructDump()
        {
            Directory.CreateDirectory(OutputDirectory);
            var flags = TransferInstructionFlags.SerializeGameRelease;

            using var tw = new StreamWriter(Path.Combine(OutputDirectory, "structs.dump"));

            for (int i = 0; i < RuntimeTypes.Count; i++)
            {
                var type        = RuntimeTypes.Types[i];
                var iter        = type;
                var inheritance = string.Empty;

                while (true)
                {
                    inheritance += Marshal.PtrToStringAnsi(iter->ClassName);

                    if (iter->Base == null)
                    {
                        break;
                    }

                    inheritance += " <- ";
                    iter         = iter->Base;
                }

                tw.WriteLine("\n// classID{{{0}}}: {1}", (int)type->PersistentTypeID, inheritance);

                iter = type;
                while (iter->IsAbstract)
                {
                    tw.WriteLine("// {0} is abstract", Marshal.PtrToStringAnsi(iter->ClassName));

                    if (iter->Base == null)
                    {
                        break;
                    }

                    iter = iter->Base;
                }

                var obj = NativeObject.GetOrProduce(*iter);

                if (obj == null)
                {
                    continue;
                }

                var tree = new TypeTree();
                tree.Init();
                if (obj->GetTypeTree(flags, ref tree))
                {
                    TypeTreeUtility.CreateTextDump(tree, tw);
                }

                NativeObject.DestroyIfNotSingletonOrPersistent(obj);
            }
        }
Beispiel #21
0
        private static TypeTree BuildTypeTree(TypeTree root, Type[] types)
        {
            IEnumerable <Type> subclassTypes = types.Where((type) => type.IsSubclassOf(root.Type)).OrderBy(o => o.FullName, invariantComparer);

            foreach (Type subclassType in subclassTypes)
            {
                root.Subclasses[ContractEnforcement.GenerateNameWithClassAttributes(subclassType)] = ContractEnforcement.BuildTypeTree(new TypeTree(subclassType), types);
            }

            IEnumerable <KeyValuePair <string, MemberInfo> > memberInfos =
                root.Type.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly)
                .Select(memberInfo => new KeyValuePair <string, MemberInfo>($"{memberInfo.ToString()}{string.Join("-", ContractEnforcement.RemoveDebugSpecificAttributes(memberInfo.CustomAttributes))}", memberInfo))
                .OrderBy(o => o.Key, invariantComparer);

            foreach (KeyValuePair <string, MemberInfo> memberInfo in memberInfos)
            {
                List <string> attributes = ContractEnforcement.RemoveDebugSpecificAttributes(memberInfo.Value.CustomAttributes)
                                           .Select((customAttribute) => customAttribute.AttributeType.Name)
                                           .ToList();
                attributes.Sort(invariantComparer);

                string methodSignature = null;

                if (memberInfo.Value.MemberType == MemberTypes.Method)
                {
                    MethodInfo methodInfo = (MethodInfo)memberInfo.Value;
                    methodSignature = ContractEnforcement.GenerateNameWithMethodAttributes(methodInfo);
                }
                else if (memberInfo.Value.MemberType == MemberTypes.Property)
                {
                    PropertyInfo propertyInfo = (PropertyInfo)memberInfo.Value;
                    methodSignature = ContractEnforcement.GenerateNameWithPropertyAttributes(propertyInfo);
                }
                else if (memberInfo.Value.MemberType == MemberTypes.Field)
                {
                    FieldInfo fieldInfo = (FieldInfo)memberInfo.Value;
                    methodSignature = ContractEnforcement.GenerateNameWithFieldAttributes(fieldInfo);
                }
                else if (memberInfo.Value.MemberType == MemberTypes.Constructor || memberInfo.Value.MemberType == MemberTypes.Event)
                {
                    methodSignature = memberInfo.ToString();
                }

                root.Members[
                    memberInfo.Key
                ] = new MemberMetadata(
                    memberInfo.Value.MemberType,
                    attributes,
                    methodSignature);
            }

            foreach (Type nestedType in root.Type.GetNestedTypes().OrderBy(o => o.FullName))
            {
                root.NestedTypes[ContractEnforcement.GenerateNameWithClassAttributes(nestedType)] = ContractEnforcement.BuildTypeTree(new TypeTree(nestedType), types);
            }

            return(root);
        }
Beispiel #22
0
 private static void AssemblyLoadEventHandler(object sender, AssemblyLoadEventArgs args)
 {
     // TODO: Comment on this if condition.
     if (!args.LoadedAssembly.IsDynamic && args.LoadedAssembly.Location.Contains(AppDomain.CurrentDomain.BaseDirectory))
     {
         TypeTree.ResetTypeTree(GetTypesDerivedFrom(typeof(Message)));
         MessageTypesAdded(null, null);
     }
 }
Beispiel #23
0
        private TypeTree FixTypeTree(TypeTree typeTree, Symbol type, UserTypeFactory factory)
        {
            // Check basic type
            BasicTypeTree basicTypeTree = typeTree as BasicTypeTree;

            if (basicTypeTree != null)
            {
                // Basic type tree is not challenged against template arguments, so try to do that.
                UserType basicUserType;

                if (CreateFactory(factory).GetUserType(type, out basicUserType))
                {
                    TypeTree tree = UserTypeTree.Create(basicUserType, factory);

                    if (tree != null)
                    {
                        return(tree);
                    }
                }

                // Failed to match the type
                // TODO: Look for typedeclared. Class is using different types than in template specialization. We cannot support it right now.
                return(new VariableTypeTree());
            }

            // Check array type
            ArrayTypeTree arrayTypeTree = typeTree as ArrayTypeTree;

            if (arrayTypeTree != null)
            {
                TypeTree elementTypeTree = FixTypeTree(arrayTypeTree.ElementType, type.ElementType, factory);

                if (elementTypeTree != arrayTypeTree.ElementType)
                {
                    return(new ArrayTypeTree(elementTypeTree));
                }

                return(arrayTypeTree);
            }

            // Check pointer type
            PointerTypeTree pointerTypeTree = typeTree as PointerTypeTree;

            if (pointerTypeTree != null)
            {
                TypeTree elementTypeTree = FixTypeTree(pointerTypeTree.ElementType, type.ElementType, factory);

                if (elementTypeTree != pointerTypeTree.ElementType)
                {
                    return(new PointerTypeTree(elementTypeTree));
                }

                return(pointerTypeTree);
            }

            return(typeTree);
        }
        public ResourceManagerTypeTreeV09()
        {
            this.name = "Base";
            this.type = "ResourceManager";
            var map = new TypeTree();

            map.name = "m_Container";
            map.type = "map";

            var array = new TypeTree();

            array.name = "Array";
            array.type = "Array";

            var arraySize = new TypeTree();

            arraySize.name = "size";
            arraySize.type = "int";
            array.AddChild(arraySize);

            var arrayData = new TypeTree();

            arrayData.name = "data";
            arrayData.type = "pair";

            var arrayDataPairKey = new TypeTree();

            arrayDataPairKey.name = "path";
            arrayDataPairKey.type = "string";

            arrayData.AddChild(arrayDataPairKey);

            var arrayDataPairValue = new TypeTree();

            arrayDataPairValue.name = "asset";
            arrayDataPairValue.type = "PPtr<Object>";

            var objectFileIdentInType = new TypeTree();

            objectFileIdentInType.name = "m_FileID";
            objectFileIdentInType.type = "int";

            arrayDataPairValue.AddChild(objectFileIdentInType);

            var objectUnkowFiled = new TypeTree();

            objectUnkowFiled.name = "m_PathID";
            objectUnkowFiled.type = "int";

            arrayDataPairValue.AddChild(objectUnkowFiled);
            arrayData.AddChild(arrayDataPairValue);

            array.AddChild(arrayData);
            map.AddChild(array);

            AddChild(map);
        }
Beispiel #25
0
        public static string Visualize(this Type type)
        {
            var typeTree = TypeTree.From(type);

            var visualizationRoot = new TreeNode();

            Traverse(visualizationRoot, typeTree);

            return(new TreeVisualization(visualizationRoot).ToString());
        }
        public override Tree VisitFormalParameter(FormalParameterContext context)
        {
            String   name = context.name.Text;
            TypeTree type = (TypeTree)VisitType(context.type());

            IToken stopToken = context.Stop;
            int    stopLine  = stopToken.Line;
            int    stopCol   = stopToken.Column + (stopToken.StopIndex - stopToken.StartIndex);

            return(new VariableDeclaration(type.beginLine, type.beginCol, stopLine, stopCol, name, type, null));
        }
Beispiel #27
0
 public static Type_0D FindTypeTreeTypeByID(TypeTree typeTree, uint id)
 {
     foreach (Type_0D type in typeTree.unity5Types)
     {
         if (type.classId == id)
         {
             return(type);
         }
     }
     return(null);
 }
Beispiel #28
0
 public static Type_0D FindTypeTreeTypeByScriptIndex(TypeTree typeTree, ushort scriptIndex)
 {
     foreach (Type_0D type in typeTree.unity5Types)
     {
         if (type.scriptIndex == scriptIndex)
         {
             return(type);
         }
     }
     return(null);
 }
Beispiel #29
0
 public static Type_0D FindTypeTreeTypeByName(TypeTree typeTree, string name)
 {
     foreach (Type_0D type in typeTree.unity5Types)
     {
         if (type.typeFieldsEx[0].GetTypeString(type.stringTable) == name)
         {
             return(type);
         }
     }
     return(null);
 }
Beispiel #30
0
 public static Type_0D FindTypeTreeTypeByID(TypeTree typeTree, uint id, ushort scriptIndex)
 {
     foreach (Type_0D type in typeTree.unity5Types)
     {
         if (type.classId == id && type.scriptIndex == scriptIndex)
         {
             return(type);
         }
     }
     return(null);
 }
        public ResourceManagerTypeTreeV09()
        {
            this.name = "Base";
            this.type = "ResourceManager";
            var map = new TypeTree();
            map.name = "m_Container";
            map.type = "map";

            var array = new TypeTree();
            array.name = "Array";
            array.type = "Array";

            var arraySize = new TypeTree();
            arraySize.name = "size";
            arraySize.type = "int";
            array.AddChild(arraySize);

            var arrayData = new TypeTree();
            arrayData.name = "data";
            arrayData.type = "pair";

            var arrayDataPairKey = new TypeTree();
            arrayDataPairKey.name = "path";
            arrayDataPairKey.type = "string";

            arrayData.AddChild(arrayDataPairKey);

            var arrayDataPairValue = new TypeTree();
            arrayDataPairValue.name = "asset";
            arrayDataPairValue.type = "PPtr<Object>";

            var objectFileIdentInType = new TypeTree();
            objectFileIdentInType.name = "m_FileID";
            objectFileIdentInType.type = "int";

            arrayDataPairValue.AddChild(objectFileIdentInType);

            var objectUnkowFiled = new TypeTree();
            objectUnkowFiled.name = "m_PathID";
            objectUnkowFiled.type = "int";

            arrayDataPairValue.AddChild(objectUnkowFiled);
            arrayData.AddChild(arrayDataPairValue);

            array.AddChild(arrayData);
            map.AddChild(array);

            AddChild(map);
        }
Beispiel #32
0
        public void TypeTreeLookups()
        {
            var tree = new TypeTree<int>();
            tree.Set<Shape>(1);
            tree.Set<Circle>(11);
            tree.Set<Para>(3);
            tree.Set<Isosceles>(9);
            tree.Set<Polygon>(6);
            tree.Set<IRegular>(15);
            tree.Set<IEssential>(20);

            Expect.Some(1, tree.Get<Shape>());
            Expect.Some(6, tree.Get<Quad>());
            Expect.Some(1, tree.Get<Ellipse>());
            Expect.Some(11, tree.Get<Circle>());
            Expect.None(tree.Get<Object>());
            Expect.None(tree.Get<String>());
            Expect.Some(3, tree.Get<Rhombus>());
            Expect.Some(9, tree.Get<Equilateral>());
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="PointerTypeTree"/> class.
 /// </summary>
 /// <param name="elementType">The element type tree.</param>
 public PointerTypeTree(TypeTree elementType)
 {
     ElementType = elementType;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="ArrayTypeTree"/> class.
 /// </summary>
 /// <param name="elementType">The element type tree.</param>
 public ArrayTypeTree(TypeTree elementType)
 {
     ElementType = elementType;
 }