public static CodeObjectSource CreateArray(CodeObjectSource source, int rank)
        {
            if (source == null)
            {
                return null;
            }

            int[] ranks;
            CodeObjectSourceType type;

            if (source._type == CodeObjectSourceType.Indexer)
            {
                //Debug.Assert(source._arrayRanks[0] == 1);
                int rankCount = source._arrayRanks.Length - 1;
                ranks = new int[rankCount];

                if (rankCount == 0)
                {
                    type = CodeObjectSourceType.Normal;
                }
                else
                {
                    Array.Copy(source._arrayRanks, 1, ranks, 0, rankCount);
                    type = CodeObjectSourceType.Indexer;
                }
            }
            else
            {
                ranks = new int[source._arrayRanks.Length + 1];
                ranks[0] = rank;
                Array.Copy(source._arrayRanks, 0, ranks, 1, source._arrayRanks.Length);
                type = CodeObjectSourceType.Array;
            }

            return InternalCreate(source._target, ranks, type);
        }
        private static CodeObjectSource InternalCreate(object target, int[] arrayRanks, CodeObjectSourceType type)
        {
            if (target == null)
            {
                return null;
            }

            Debug.Assert(Utils.IsSource(target));

            if (arrayRanks == null)
            {
                arrayRanks = new int[0];
            }

            Type typeTarget = target as Type;

            if (typeTarget != null && typeTarget.IsArray)
            {
                List<int> ranks = new List<int>();

                while (typeTarget.IsArray)
                {
                    ranks.Add(typeTarget.GetArrayRank());
                    typeTarget = typeTarget.GetElementType();
                }

                target = typeTarget;
                arrayRanks = ranks.ToArray();
            }

            CodeObjectSource source = new CodeObjectSource(target, arrayRanks, type);
            //CodeObjectSource cachedSource;

            //if (_cache.TryGetValue(source, out cachedSource))
            //{
            //    source = cachedSource;
            //}
            //else
            //{
            //    _cache.Add(source, source);
            //}

            return source;
        }
        public static CodeObjectSource CreateMergeXXX(CodeObjectSource source, int[] ranks, CodeObjectSourceType type)
        {
            if (type == CodeObjectSourceType.Normal && ranks.Length > 0)
            {
                throw new ArgumentException("Invalid type", "type");
            }

            if (ranks.Length == 0)
            {
                return source;
            }
            else
            {
                CodeObjectSource newSource = source;

                if (type == CodeObjectSourceType.Array)
                {
                    for (int i = ranks.Length - 1; i >= 0; i--)
                    {
                        newSource = CreateIndexer(source, ranks[i]);
                    }
                }
                else
                {
                    for (int i = ranks.Length - 1; i >= 0; i--)
                    {
                        newSource = CreateArray(source, ranks[i]);
                    }
                }

                return newSource;
            }
        }
        //private static readonly IDictionary<CodeObjectSource, CodeObjectSource> _cache = new WeakKeyDictionary<CodeObjectSource, CodeObjectSource>();
        public static CodeObjectSource CreateNullable(CodeObjectSource source)
        {
            if (source == null)
            {
                return null;
            }

            Type type = source.Target as Type;

            if (type != null)
            {
                return InternalCreate(typeof (Nullable<>).MakeGenericType(type), source._arrayRanks, source._type);
            }
            else
            {
                Debug.Assert(false);
                return source;
            }
        }
Exemple #5
0
        public static CodeTypeReference CreateTypeReference(CodeObjectSource source)
        {
            CodeTypeReference typeRef;

            if (source.Type == CodeObjectSourceType.Indexer)
            {
                typeRef = new CodeTypeReference(typeof (object));
                CodeObjectMetaData.SetTypeReferenceSource(typeRef, CodeObjectSource.Create(typeof (object)));
                return typeRef;
            }

            if (source.Target is Type)
            {
                Type type = (Type) source.Target;

                for (int i = source.ArrayRanks.Length - 1; i >= 0; i--)
                {
                    int rank = source.ArrayRanks[i];
                    type = (rank == 1
                                ? type.MakeArrayType()
                                : type.MakeArrayType(rank));
                }

                source = CodeObjectSource.Create(type);
                typeRef = new CodeTypeReference(type);
            }
            else if (source.Target is CodeTypeDeclaration)
            {
                CodeTypeDeclaration typeDecl = (CodeTypeDeclaration) source.Target;
                StringBuilder builder = new StringBuilder();

                for (int i = source.ArrayRanks.Length - 1; i >= 0; i--)
                {
                    builder.Insert(0, "[");

                    for (int j = 0; j < source.ArrayRanks[i] - 1; j++)
                    {
                        builder.Insert(0, ",");
                    }

                    builder.Insert(0, "]");
                }

                CodeTypeDeclaration currentTypeDecl = typeDecl;

                while (true)
                {
                    builder.Insert(0, currentTypeDecl.Name);
                    CodeTypeDeclaration parentTypeDecl = CodeObjectMetaData.GetParent(currentTypeDecl);

                    if (parentTypeDecl == null)
                    {
                        builder.Insert(0, ".");
                        builder.Insert(0, CodeObjectMetaData.GetNamespaceName(currentTypeDecl));
                        break;
                    }
                    else
                    {
                        builder.Insert(0, "+");
                        currentTypeDecl = parentTypeDecl;
                    }
                }

                typeRef = new CodeTypeReference(builder.ToString());
            }
            else if (source.Target == null)
            {
                Debug.Assert(false, "Unexpected null source target");
                return null;
            }
            else
            {
                Debug.Assert(false, "Unexpected source target type: " + source.Target.GetType().Name);
                return null;
            }

            CodeObjectMetaData.SetTypeReferenceSource(typeRef, source);
            return typeRef;
        }