예제 #1
0
        private void DeserializeTypes(Json.Expression types, ref TypeDef[] typeDefs)
        {
            //
            // TODO: confirm this behavior, technically "optional" in Bonsai spec, so value could be null.
            //
            if (types is not Json.ArrayExpression typeTable)
            {
                throw new BonsaiParseException("Expected a JSON array containing the type table.", types);
            }

            var n = typeTable.ElementCount;

            typeDefs = new TypeDef[n];

            for (var i = 0; i < n; i++)
            {
                var type = typeTable.GetElement(i);

                var typeDef = TypeDef.FromJson(this, type);
                typeDefs[i] = typeDef;
            }
        }
예제 #2
0
        /// <summary>
        /// Gets a type space object from a JSON representation.
        /// </summary>
        /// <param name="expression">JSON representation of the type space.</param>
        /// <param name="typeResolutionService">Type resolution service. Can be null.</param>
        /// <returns>Type space for the given JSON representation.</returns>
        public static TypeSpace FromJson(Json.Expression expression, ITypeResolutionService typeResolutionService)
        {
            //
            // Referencing mscorlib for default lookups. See SimpleTypeDef.FromJson for the
            // special treatment of this assembly in order to shorten names in serialization
            // payload.
            //
            if (typeResolutionService != null)
            {
                typeResolutionService.ReferenceAssembly(typeof(int).Assembly.GetName() /* mscorlib */);
            }

            //
            // Inverse of ToJson.
            //
            var defs = ((Json.ArrayExpression)expression).Elements;

            //
            // First, get enough type reference objects to support the full range of ordinals.
            //
            var typeRefs = Enumerable.Range(0, defs.Count).Select(i => new TypeRef(i)).ToArray();

            //
            // Using a findRef delegate, we can now import the type definitions. Notice this
            // assumes that type references are in a fixed zero-based range.
            //
            var findRef  = new Func <Json.Expression, TypeRef>(r => typeRefs[TypeRef.FromJson(r).Ordinal]);
            var typeDefs = defs.Select(def => TypeDef.FromJson(def, findRef, typeResolutionService)).ToArray();

            //
            // Next, we associate all of the type references with their corresponding definition,
            // again based on ordinal number indexes.
            //
            var j = 0;

            foreach (var typeDef in typeDefs)
            {
                var typeRef = typeRefs[j++];
                typeRef.Definition = typeDef;
            }

            //
            // The first phase of defining the type space consists of compilation of the types,
            // resulting in recreation of structural types. Entries are added to the type def
            // table to allow for Lookup calls during deserialization of the expression tree.
            //
            var res             = new TypeSpace();
            var structuralTypes = new List <StructuralTypeDef>();

            foreach (var typeRef in typeRefs)
            {
                var def = typeRef.Definition;
                res._typeDefs[typeRef] = def;
                def.Compile(res._compiler, typeResolutionService);

                //
                // Structural types need a separate compilation stage in order to "freeze" the
                // reconstructed types. See comment below for more information.
                //
                if (def is StructuralTypeDef std)
                {
                    structuralTypes.Add(std);
                }
            }

            //
            // Second stage of compilation, triggering the CreateType on TypeBuilder to cause
            // final construction of the types.
            //
            foreach (var structuralType in structuralTypes)
            {
                structuralType.ToType(); // side-effect described above
            }

            //
            // The following piece of code can be re-enabled for debugging purposes in order to
            // see a Type-based index for type references. This is only needed for serialization,
            // so we eliminate this step for deserialization.
            //

            /*
             * foreach (var typeRef in typeRefs)
             * {
             *  var type = typeRef.Definition.ToType();
             *  res._typeRefs[type] = typeRef;
             * }
             */

            return(res);
        }