Ejemplo n.º 1
0
        /// <summary>
        /// Generates a class mapping for the specified type based on available meta-data.
        /// </summary>
        /// <remarks>
        /// The mapping incorporates declarative meta-data derived from attributes
        /// such as <see cref="ActionScriptClassAttribute" />.  The ActionScript class
        /// layout is determined based on whether the type implements <see cref="IDynamic" />
        /// or <see cref="IExternalizable" />.
        /// If the class is not decorated with a <see cref="ActionScriptClassAttribute" /> then
        /// you should specify a non-null value for <paramref name="classAliasOverride"/> if you want
        /// to include type information in the class mapping.
        /// </remarks>
        /// <param name="nativeType">The class for which to generate the mapping</param>
        /// <param name="classAliasOverride">The class alias to use or null to use the default.
        /// If <paramref name="classAliasOverride"/> is non-null then
        /// it overrides the value specified in the <see cref="ActionScriptClassAttribute" />.  If <paramref name="classAliasOverride"/>
        /// is an empty string then the class mapping will be untyped.</param>
        /// <returns>A new default class mapping for the specified type</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="nativeType"/> is null</exception>
        /// <exception cref="ActionScriptException">Thrown when an error occurs generating the class mapping</exception>
        public static ActionScriptClassMapping CreateClassMapping(Type nativeType, string classAliasOverride)
        {
            if (nativeType == null)
            {
                throw new ArgumentNullException("nativeType");
            }

            ActionScriptClassAttribute classAttribute = GetActionScriptClassAttribute(nativeType);

            return(InternalCreateDefaultClassMapping(nativeType, classAliasOverride, classAttribute));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Generates class mappings for all public types in the specified assembly
        /// that are decorated with the <see cref="ActionScriptClassAttribute" />.
        /// </summary>
        /// <param name="assembly">The assembly to search for serializable types</param>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="assembly"/> is null</exception>
        /// <returns>The enumeration of class mappings</returns>
        public static IEnumerable <ActionScriptClassMapping> GetClassMappingsForTypesInAssembly(Assembly assembly)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException("assembly");
            }

            foreach (Type type in assembly.GetExportedTypes())
            {
                ActionScriptClassAttribute classAttribute = GetActionScriptClassAttribute(type);
                if (classAttribute != null)
                {
                    ActionScriptClassMapping classMapping = InternalCreateDefaultClassMapping(type, null, classAttribute);
                    yield return(classMapping);
                }
            }
        }
        private static ActionScriptClassMapping InternalCreateDefaultClassMapping(Type nativeType, string classAliasOverride,
            ActionScriptClassAttribute classAttribute)
        {
            // Determine the class alias.
            string classAlias;

            if (classAliasOverride != null)
                classAlias = classAliasOverride;
            else if (classAttribute != null)
                classAlias = classAttribute.ClassAlias;
            else
                classAlias = "";

            // Determine the class layout.
            ASClassLayout classLayout = ASClassLayout.Normal;

            if (typeof(IDynamic).IsAssignableFrom(nativeType))
            {
                classLayout = ASClassLayout.Dynamic;
            }

            if (typeof(IExternalizable).IsAssignableFrom(nativeType))
            {
                if (classAlias.Length == 0)
                    throw new ActionScriptException(String.Format(CultureInfo.CurrentCulture,
                        "Type '{0}' implements IExternalizable but does not have a non-empty class alias name which is required by the externalizable serialization protocol.",
                        nativeType.FullName));

                if (classLayout == ASClassLayout.Dynamic)
                    throw new ActionScriptException(String.Format(CultureInfo.CurrentCulture,
                        "Type '{0}' implements IExternalizable as well as IDynamic which is not supported by the externalizable serialization protocol.",
                        nativeType.FullName));

                classLayout = ASClassLayout.Externalizable;
            }

            // Populate the list of property mappings.
            List<ActionScriptPropertyMapping> propertyMappings = new List<ActionScriptPropertyMapping>();
            List<string> memberNames = new List<string>();

            foreach (PropertyInfo property in nativeType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
            {
                AddPropertyMappingIfNeeded(property, propertyMappings, memberNames, ref classLayout);
            }

            foreach (FieldInfo field in nativeType.GetFields(BindingFlags.Instance | BindingFlags.Public))
            {
                AddPropertyMappingIfNeeded(field, propertyMappings, memberNames, ref classLayout);
            }

            // Finish up.
            // Convert the lists to arrays to reduce the memory footprint.
            string[] memberNamesArray = memberNames.Count == 0 ? EmptyArray<string>.Instance : memberNames.ToArray();
            ActionScriptPropertyMapping[] propertyMappingsArray = propertyMappings.Count == 0 ?
                EmptyArray<ActionScriptPropertyMapping>.Instance : propertyMappings.ToArray();

            ASClass classDefinition = ASClassCache.GetClass(classAlias, classLayout, memberNamesArray);
            ActionScriptClassMapping classMapping = new ActionScriptClassMapping(nativeType, classDefinition, propertyMappingsArray);

            return classMapping;
        }
Ejemplo n.º 4
0
        private static ActionScriptClassMapping InternalCreateDefaultClassMapping(Type nativeType, string classAliasOverride,
                                                                                  ActionScriptClassAttribute classAttribute)
        {
            // Determine the class alias.
            string classAlias;

            if (classAliasOverride != null)
            {
                classAlias = classAliasOverride;
            }
            else if (classAttribute != null)
            {
                classAlias = classAttribute.ClassAlias;
            }
            else
            {
                classAlias = "";
            }

            // Determine the class layout.
            ASClassLayout classLayout = ASClassLayout.Normal;

            if (typeof(IDynamic).IsAssignableFrom(nativeType))
            {
                classLayout = ASClassLayout.Dynamic;
            }

            if (typeof(IExternalizable).IsAssignableFrom(nativeType))
            {
                if (classAlias.Length == 0)
                {
                    throw new ActionScriptException(String.Format(CultureInfo.CurrentCulture,
                                                                  "Type '{0}' implements IExternalizable but does not have a non-empty class alias name which is required by the externalizable serialization protocol.",
                                                                  nativeType.FullName));
                }

                if (classLayout == ASClassLayout.Dynamic)
                {
                    throw new ActionScriptException(String.Format(CultureInfo.CurrentCulture,
                                                                  "Type '{0}' implements IExternalizable as well as IDynamic which is not supported by the externalizable serialization protocol.",
                                                                  nativeType.FullName));
                }

                classLayout = ASClassLayout.Externalizable;
            }

            // Populate the list of property mappings.
            List <ActionScriptPropertyMapping> propertyMappings = new List <ActionScriptPropertyMapping>();
            List <string> memberNames = new List <string>();

            foreach (PropertyInfo property in nativeType.GetProperties(BindingFlags.Instance | BindingFlags.Public))
            {
                AddPropertyMappingIfNeeded(property, propertyMappings, memberNames, ref classLayout);
            }

            foreach (FieldInfo field in nativeType.GetFields(BindingFlags.Instance | BindingFlags.Public))
            {
                AddPropertyMappingIfNeeded(field, propertyMappings, memberNames, ref classLayout);
            }

            // Finish up.
            // Convert the lists to arrays to reduce the memory footprint.
            string[] memberNamesArray = memberNames.Count == 0 ? EmptyArray <string> .Instance : memberNames.ToArray();
            ActionScriptPropertyMapping[] propertyMappingsArray = propertyMappings.Count == 0 ?
                                                                  EmptyArray <ActionScriptPropertyMapping> .Instance : propertyMappings.ToArray();

            ASClass classDefinition = ASClassCache.GetClass(classAlias, classLayout, memberNamesArray);
            ActionScriptClassMapping classMapping = new ActionScriptClassMapping(nativeType, classDefinition, propertyMappingsArray);

            return(classMapping);
        }