//===================================================================== /// <summary> /// Write out a type name /// </summary> /// <param name="type">The type for which to write out the name</param> /// <param name="sb">The string builder to which the name is written</param> private static void WriteType(TypeNode type, StringBuilder sb) { switch(type.NodeType) { case NodeType.ArrayType: ArrayType array = (ArrayType)type; WriteType(array.ElementType, sb); sb.Append("["); if(array.Rank > 1) for(int i = 0; i < array.Rank; i++) { if(i > 0) sb.Append(","); sb.Append("0:"); } sb.Append("]"); break; case NodeType.Reference: Reference reference = (Reference)type; WriteType(reference.ElementType, sb); sb.Append("@"); break; case NodeType.Pointer: Pointer pointer = (Pointer)type; WriteType(pointer.ElementType, sb); sb.Append("*"); break; case NodeType.OptionalModifier: TypeModifier optionalModifierClause = (TypeModifier)type; WriteType(optionalModifierClause.ModifiedType, sb); sb.Append("!"); WriteType(optionalModifierClause.Modifier, sb); break; case NodeType.RequiredModifier: TypeModifier requiredModifierClause = (TypeModifier)type; WriteType(requiredModifierClause.ModifiedType, sb); sb.Append("|"); WriteType(requiredModifierClause.Modifier, sb); break; default: if(type.IsTemplateParameter) { ITypeParameter gtp = (ITypeParameter)type; if(gtp.DeclaringMember is TypeNode) sb.Append("`"); else if(gtp.DeclaringMember is Method) sb.Append("``"); else throw new InvalidOperationException("Generic parameter not on type or method"); sb.Append(gtp.ParameterListIndex); } else { // Namespace TypeNode declaringType = type.DeclaringType; if(declaringType != null) { // Names of nested types begin with outer type name WriteType(declaringType, sb); sb.Append("."); } else { // Otherwise just prefix with the namespace Identifier space = type.Namespace; if(space != null && !String.IsNullOrEmpty(space.Name)) { sb.Append(space.Name); sb.Append("."); } } // Name sb.Append(type.GetUnmangledNameWithoutTypeParameters()); // Generic parameters if(type.IsGeneric) { // Number of parameters TypeNodeList parameters = type.TemplateParameters; if(parameters != null) { sb.Append('`'); sb.Append(parameters.Count); } // Arguments TypeNodeList arguments = type.TemplateArguments; if(arguments != null && arguments.Count > 0) { sb.Append("{"); for(int i = 0; i < arguments.Count; i++) { if(i > 0) sb.Append(","); WriteType(arguments[i], sb); } sb.Append("}"); } } } break; } }
public static string GetTypeNameFor(TypeNode type, bool suppressTemplateParameters, bool fullName){ if (type == null || type.Name == Looker.NotFound) return ""; switch(type.TypeCode){ case TypeCode.Boolean: return "bool"; case TypeCode.Byte: return "byte"; case TypeCode.Char: return "char"; case TypeCode.Decimal: return "decimal"; case TypeCode.Double: return "double"; case TypeCode.Int16: return "short"; case TypeCode.Int32: return "int"; case TypeCode.Int64: return "long"; case TypeCode.SByte: return "sbyte"; case TypeCode.Single: return "float"; case TypeCode.String: return "string"; case TypeCode.UInt16: return "ushort"; case TypeCode.UInt32: return "uint"; case TypeCode.UInt64: return "ulong"; } if (type == SystemTypes.Object) return "object"; if (type == SystemTypes.Void) return "void"; if (type.Template == SystemTypes.GenericNullable){ if (type.TemplateArguments != null && type.TemplateArguments.Count > 0) return ErrorHandler.GetTypeNameFor(type.TemplateArguments[0]) + "?"; } switch (type.NodeType){ case NodeType.ArrayType: ArrayType aType = (ArrayType)type; StringBuilder sb = new StringBuilder(ErrorHandler.GetTypeNameFor(aType.ElementType)); sb.Append('['); for (int i = 0, n = aType.Rank; i < n; i++){ if (i == 0 && n > 1) sb.Append('*'); if (i < n-1){ sb.Append(','); if (n > 1) sb.Append('*'); } } sb.Append(']'); return sb.ToString(); case NodeType.Class: FunctionType fType = type as FunctionType; if (fType != null){ ErrorHandler eh = new ErrorHandler(new ErrorNodeList(0)); return "delegate " + eh.GetTypeName(fType.ReturnType)+" "+eh.GetSignatureString("", fType.Parameters, "(", ")", ", "); } ClosureClass cClass = type as ClosureClass; if (cClass != null){ MemberList mems = cClass.Members; for (int i = 0, n = mems == null ? 0 : mems.Count; i < n; i++){ Method meth = mems[i] as Method; if (meth == null || meth is InstanceInitializer || (meth.Parameters != null && meth.Parameters.Count != 0)) continue; return ErrorHandler.GetTypeNameFor(meth.ReturnType); } } if (type.Template != null && type.TemplateArguments != null && type.TemplateArguments.Count > 0){ sb = new StringBuilder(ErrorHandler.GetTypeNameFor(type.Template, true, fullName)); for (int i = 0, n = type.TemplateArguments == null ? 0 : type.TemplateArguments.Count; i < n; i++){ if (i == 0) sb.Append('<'); sb.Append(ErrorHandler.GetTypeNameFor(type.TemplateArguments[i])); if (i < n - 1) sb.Append(','); else sb.Append('>'); } return sb.ToString(); } if (type.DeclaringType != null) sb = new StringBuilder(ErrorHandler.GetTypeNameFor(type.DeclaringType)+"."+type.GetUnmangledNameWithoutTypeParameters()); else sb = new StringBuilder(type.GetFullUnmangledNameWithoutTypeParameters()); if (!suppressTemplateParameters && type.TemplateParameters != null){ for (int i = 0, n = type.TemplateParameters == null ? 0 : type.TemplateParameters.Count; i < n; i++){ if (i == 0) sb.Append('<'); sb.Append(ErrorHandler.GetTypeNameFor(type.TemplateParameters[i], false, fullName)); if (i < n - 1) sb.Append(','); else sb.Append('>'); } return sb.ToString(); } return sb.ToString(); case NodeType.ConstrainedType: case NodeType.DelegateNode: case NodeType.EnumNode: case NodeType.Interface: case NodeType.TypeAlias: goto case NodeType.Class; case NodeType.OptionalModifier: if (((OptionalModifier)type).Modifier == SystemTypes.NonNullType) return ErrorHandler.GetTypeNameFor(((OptionalModifier)type).ModifiedType)+"!"; if (((OptionalModifier)type).Modifier == SystemTypes.NullableType) return ErrorHandler.GetTypeNameFor(((OptionalModifier)type).ModifiedType) + "?"; goto case NodeType.RequiredModifier; case NodeType.RequiredModifier: return ErrorHandler.GetTypeNameFor(((TypeModifier)type).ModifiedType); case NodeType.Pointer: return ErrorHandler.GetTypeNameFor(((Pointer)type).ElementType)+"*"; case NodeType.Reference: return "ref "+ErrorHandler.GetTypeNameFor(((Reference)type).ElementType); case NodeType.Refanytype: case NodeType.Struct: goto case NodeType.Class; case NodeType.ClassParameter: case NodeType.TypeParameter: return type.Name.ToString(); case NodeType.ClassExpression : case NodeType.InterfaceExpression : case NodeType.TypeExpression : case NodeType.ArrayTypeExpression: case NodeType.FlexArrayTypeExpression: case NodeType.FunctionTypeExpression: case NodeType.PointerTypeExpression: case NodeType.ReferenceTypeExpression: case NodeType.StreamTypeExpression: case NodeType.NonEmptyStreamTypeExpression: case NodeType.NonNullTypeExpression: case NodeType.NonNullableTypeExpression: case NodeType.BoxedTypeExpression: case NodeType.NullableTypeExpression: case NodeType.InvariantTypeExpression: case NodeType.TupleTypeExpression: case NodeType.TypeIntersectionExpression: case NodeType.TypeUnionExpression: return type.SourceContext.SourceText; } if (fullName) return type.FullName; if (type.Name == null) return ""; return type.Name.ToString(); }
public static TypeNode GetTemplateType(TypeNode type) { if (type == null) throw new ArgumentNullException("type"); // Console.WriteLine(type.FullName); // only generic types have templates if (!type.IsGeneric) return (type); if (type.DeclaringType == null) { // if the type is not nested, life is simpler // if the type is not specified, the type is the template if (type.TemplateArguments == null) return (type); // otherwise, construct the template type identifier and use it to fetch the template type Module templateModule = type.DeclaringModule; Identifier name = new Identifier(String.Format("{0}`{1}", type.GetUnmangledNameWithoutTypeParameters(), type.TemplateArguments.Count)); Identifier space = type.Namespace; TypeNode template = templateModule.GetType(space, name); return (template); } else { // if the type is nested, life is harder; we have to walk up the chain, constructing // un-specialized identifiers as we go, then walk back down the chain, fetching // template types as we go // create a stack to keep track of identifiers Stack < Identifier > identifiers = new Stack < Identifier >(); // populate the stack with the identifiers of all the types up to the outermost type TypeNode current = type; while (true) { int count = 0; if ((current.TemplateArguments != null) && (current.TemplateArguments.Count > count)) count = current.TemplateArguments.Count; if ((current.TemplateParameters != null) && (current.TemplateParameters.Count > count)) count = current.TemplateParameters.Count; TypeNodeList arguments = current.TemplateParameters; if (count == 0) { identifiers.Push(new Identifier(current.GetUnmangledNameWithoutTypeParameters())); } else { identifiers.Push(new Identifier(String.Format("{0}`{1}", current.GetUnmangledNameWithoutTypeParameters(), count))); } // Console.WriteLine("U {0} {1}", identifiers.Peek(), CountArguments(current)); if (current.DeclaringType == null) break; current = current.DeclaringType; } // fetch a TypeNode representing that outermost type Module module = current.DeclaringModule; Identifier space = current.Namespace; current = module.GetType(space, identifiers.Pop()); // move down the stack to the inner type we want while (identifiers.Count > 0) { current = (TypeNode)current.GetMembersNamed(identifiers.Pop())[0]; // Console.WriteLine("D {0} {1}", current.GetFullUnmangledNameWithTypeParameters(), CountArguments(current)); } // whew, finally we've got it return (current); } }
private static void WriteType(TypeNode type, TextWriter writer) { switch (type.NodeType) { case NodeType.ArrayType: ArrayType array = type as ArrayType; WriteType(array.ElementType, writer); writer.Write("["); if (array.Rank > 1) { for (int i = 0; i < array.Rank; i++) { if (i > 0) writer.Write(","); writer.Write("0:"); } } writer.Write("]"); break; case NodeType.Reference: Reference reference = type as Reference; TypeNode referencedType = reference.ElementType; WriteType(referencedType, writer); writer.Write("@"); break; case NodeType.Pointer: Pointer pointer = type as Pointer; WriteType(pointer.ElementType, writer); writer.Write("*"); break; case NodeType.OptionalModifier: TypeModifier optionalModifierClause = type as TypeModifier; WriteType(optionalModifierClause.ModifiedType, writer); writer.Write("!"); WriteType(optionalModifierClause.Modifier, writer); break; case NodeType.RequiredModifier: TypeModifier requiredModifierClause = type as TypeModifier; WriteType(requiredModifierClause.ModifiedType, writer); writer.Write("|"); WriteType(requiredModifierClause.Modifier, writer); break; default: if (type.IsTemplateParameter) { ITypeParameter gtp = (ITypeParameter)type; if (gtp.DeclaringMember is TypeNode) { writer.Write("`"); } else if (gtp.DeclaringMember is Method) { writer.Write("``"); } else { throw new InvalidOperationException("Generic parameter not on type or method."); } writer.Write(gtp.ParameterListIndex); } else { // namespace TypeNode declaringType = type.DeclaringType; if (declaringType != null) { // names of nested types begin with outer type name WriteType(declaringType, writer); writer.Write("."); } else { // otherwise just prepend the namespace Identifier space = type.Namespace; if ((space != null) && !String.IsNullOrEmpty(space.Name)) { //string space = type.Namespace.Name; //if (space != null && space.Length > 0) { writer.Write(space.Name); writer.Write("."); } } // name writer.Write(type.GetUnmangledNameWithoutTypeParameters()); // generic parameters if (type.IsGeneric) { // number of parameters TypeNodeList parameters = type.TemplateParameters; if (parameters != null) { writer.Write("`{0}", parameters.Count); } // arguments TypeNodeList arguments = type.TemplateArguments; if ((arguments != null) && (arguments.Count > 0)) { writer.Write("{"); for (int i = 0; i < arguments.Count; i++) { TypeNode argument = arguments[i]; if (i > 0) writer.Write(","); WriteType(arguments[i], writer); } writer.Write("}"); } } } break; } }