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; } }
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; }