private static int[] GetDynamicFlagStartIndices(Type type) { var typeArgs = type.GetGenericArguments(); Debug.Assert(typeArgs.Length > 0); int pos = 1; // Consider "type" to have already been consumed. var startsBuilder = ArrayBuilder <int> .GetInstance(); var tupleElementNameStartIndices = ArrayBuilder <int> .GetInstance(); foreach (var typeArg in typeArgs) { startsBuilder.Add(pos); foreach (Type curr in new TypeWalker(typeArg)) { pos++; } } Debug.Assert(pos > 1); startsBuilder.Add(pos); return(startsBuilder.ToArrayAndFree()); }
private CustomTypeInfoTypeArgumentMap( Type typeDefinition, ReadOnlyCollection <byte> dynamicFlags, int[] dynamicFlagStartIndices, ReadOnlyCollection <string> tupleElementNames, int[] tupleElementNameStartIndices ) { Debug.Assert(typeDefinition != null); Debug.Assert((dynamicFlags != null) == (dynamicFlagStartIndices != null)); Debug.Assert((tupleElementNames != null) == (tupleElementNameStartIndices != null)); #if DEBUG Debug.Assert(typeDefinition.IsGenericTypeDefinition); int n = typeDefinition.GetGenericArguments().Length; Debug.Assert( dynamicFlagStartIndices == null || dynamicFlagStartIndices.Length == n + 1 ); Debug.Assert( tupleElementNameStartIndices == null || tupleElementNameStartIndices.Length == n + 1 ); #endif _typeDefinition = typeDefinition; _dynamicFlags = dynamicFlags; _dynamicFlagStartIndices = dynamicFlagStartIndices; _tupleElementNames = tupleElementNames; _tupleElementNameStartIndices = tupleElementNameStartIndices; }
private static int[] GetTupleElementNameStartIndices(Type type) { var typeArgs = type.GetGenericArguments(); Debug.Assert(typeArgs.Length > 0); int pos = GetTupleCardinalityIfAny(type); var startsBuilder = ArrayBuilder <int> .GetInstance(); var tupleElementNameStartIndices = ArrayBuilder <int> .GetInstance(); foreach (var typeArg in typeArgs) { startsBuilder.Add(pos); foreach (Type curr in new TypeWalker(typeArg)) { pos += GetTupleCardinalityIfAny(curr); } } Debug.Assert(pos > 1); startsBuilder.Add(pos); return(startsBuilder.ToArrayAndFree()); }
/// <summary> /// Convert a type from the debugger's type system into X# type system /// </summary> /// <param name="lmrType">LMR Type</param> /// <returns>X# type</returns> public static XSharpType GetXSharpTypeForLmrType(Type lmrType) { if (lmrType.IsPrimitive) { return(XSharpType.Create(lmrType.FullName)); } else if (lmrType.IsArray) { XSharpType elementType = GetXSharpTypeForLmrType(lmrType.GetElementType()); return(elementType.MakeArrayType()); } else if (lmrType.IsByRef) { XSharpType elementType = GetXSharpTypeForLmrType(lmrType.GetElementType()); return(elementType.MakeByRefType()); } else if (lmrType.IsGenericType) { var args = lmrType.GetGenericArguments(); var td = lmrType.GetGenericTypeDefinition(); return(XSharpType.Create(td, args)); } else if (lmrType.FullName.Equals("System.String")) { return(XSharpType.String); } // Unknown return(XSharpType.Create(lmrType.FullName)); }
private void AppendTupleElements( StringBuilder builder, Type type, int cardinality, ReadOnlyCollection <byte> dynamicFlags, ref int dynamicFlagIndex, ReadOnlyCollection <string> tupleElementNames, ref int tupleElementIndex, bool escapeKeywordIdentifiers, out bool sawInvalidIdentifier) { sawInvalidIdentifier = false; int nameIndex = tupleElementIndex; tupleElementIndex += cardinality; builder.Append('('); bool any = false; while (true) { var typeArguments = type.GetGenericArguments(); int nTypeArgs = typeArguments.Length; Debug.Assert(nTypeArgs > 0); Debug.Assert(nTypeArgs <= TypeHelpers.TupleFieldRestPosition); int nFields = Math.Min(nTypeArgs, TypeHelpers.TupleFieldRestPosition - 1); for (int i = 0; i < nFields; i++) { if (any) { builder.Append(", "); } bool sawSingleInvalidIdentifier; var name = CustomTypeInfo.GetTupleElementNameIfAny(tupleElementNames, nameIndex); nameIndex++; AppendTupleElement( builder, typeArguments[i], name, dynamicFlags, ref dynamicFlagIndex, tupleElementNames, ref tupleElementIndex, escapeKeywordIdentifiers, sawInvalidIdentifier: out sawSingleInvalidIdentifier); sawInvalidIdentifier |= sawSingleInvalidIdentifier; any = true; } if (nTypeArgs < TypeHelpers.TupleFieldRestPosition) { break; } Debug.Assert(!DynamicFlagsCustomTypeInfo.GetFlag(dynamicFlags, dynamicFlagIndex)); dynamicFlagIndex++; type = typeArguments[nTypeArgs - 1]; } builder.Append(')'); }
internal TypeVariablesExpansion(Type declaredType) { Debug.Assert(declaredType.IsGenericType); Debug.Assert(!declaredType.IsGenericTypeDefinition); var typeDef = declaredType.GetGenericTypeDefinition(); _typeParameters = typeDef.GetGenericArguments(); _typeArguments = declaredType.GetGenericArguments(); Debug.Assert(_typeParameters.Length == _typeArguments.Length); Debug.Assert(Array.TrueForAll(_typeParameters, t => t.IsGenericParameter)); Debug.Assert(Array.TrueForAll(_typeArguments, t => !t.IsGenericParameter)); }
private DynamicFlagsMap( Type typeDefinition, DynamicFlagsCustomTypeInfo dynamicFlagsArray, int[] startIndices) { Debug.Assert(typeDefinition != null); Debug.Assert(startIndices != null); Debug.Assert(typeDefinition.IsGenericTypeDefinition); Debug.Assert(startIndices.Length == typeDefinition.GetGenericArguments().Length + 1); _typeDefinition = typeDefinition; _dynamicFlags = dynamicFlagsArray; _startIndices = startIndices; }
private void AppendTupleFields( StringBuilder builder, Type type, DynamicFlagsCustomTypeInfo dynamicFlags, ref int index, bool escapeKeywordIdentifiers, out bool sawInvalidIdentifier) { sawInvalidIdentifier = false; builder.Append('('); bool any = false; while (true) { var typeArguments = type.GetGenericArguments(); int nTypeArgs = typeArguments.Length; Debug.Assert(nTypeArgs > 0); Debug.Assert(nTypeArgs <= TypeHelpers.TupleFieldRestPosition); int nFields = Math.Min(nTypeArgs, TypeHelpers.TupleFieldRestPosition - 1); for (int i = 0; i < nFields; i++) { if (any) { builder.Append(", "); } bool sawSingleInvalidIdentifier; AppendQualifiedTypeName(builder, typeArguments[i], dynamicFlags, ref index, escapeKeywordIdentifiers, out sawSingleInvalidIdentifier); sawInvalidIdentifier |= sawSingleInvalidIdentifier; any = true; } if (nTypeArgs < TypeHelpers.TupleFieldRestPosition) { break; } Debug.Assert(!dynamicFlags[index]); index++; type = typeArguments[nTypeArgs - 1]; } builder.Append(')'); }
private static int[] GetStartIndices(Type type, GetIndexCount getIndexCount) { var typeArgs = type.GetGenericArguments(); Debug.Assert(typeArgs.Length > 0); int pos = getIndexCount(type); // Consider "type" to have already been consumed. var startsBuilder = ArrayBuilder <int> .GetInstance(); foreach (var typeArg in typeArgs) { startsBuilder.Add(pos); foreach (Type curr in new TypeWalker(typeArg)) { pos += getIndexCount(curr); } } startsBuilder.Add(pos); return(startsBuilder.ToArrayAndFree()); }
/// <summary> /// Append the qualified name (i.e. including containing types and namespaces) of a named type /// (i.e. not a pointer or array type) to <paramref name="builder"/>. /// </summary> /// <remarks> /// Keyword strings are appended for primitive types (e.g. "int" for "System.Int32"). /// </remarks> /// <remarks> /// Does not call itself or <see cref="AppendQualifiedTypeName"/> (directly). /// </remarks> private void AppendQualifiedTypeNameInternal( StringBuilder builder, Type type, DynamicFlagsCustomTypeInfo dynamicFlags, ref int index, bool escapeKeywordIdentifiers, out bool sawInvalidIdentifier) { var isDynamic = dynamicFlags[index++] && type.IsObject(); if (AppendSpecialTypeName(builder, type, isDynamic)) { sawInvalidIdentifier = false; return; } Debug.Assert(!isDynamic, $"Dynamic should have been handled by {nameof(AppendSpecialTypeName)}"); Debug.Assert(!IsPredefinedType(type)); if (type.IsGenericParameter) { AppendIdentifier(builder, escapeKeywordIdentifiers, type.Name, out sawInvalidIdentifier); return; } // Note: in the Reflection/LMR object model, all type arguments are on the most nested type. var hasTypeArguments = type.IsGenericType; var typeArguments = type.IsGenericType ? type.GetGenericArguments() : null; Debug.Assert(hasTypeArguments == (typeArguments != null)); var numTypeArguments = hasTypeArguments ? typeArguments.Length : 0; sawInvalidIdentifier = false; bool sawSingleInvalidIdentifier; if (type.IsNested) { // Push from inside, out. var stack = ArrayBuilder<Type>.GetInstance(); { var containingType = type.DeclaringType; while (containingType != null) { stack.Add(containingType); containingType = containingType.DeclaringType; } } var lastContainingTypeIndex = stack.Count - 1; AppendNamespacePrefix(builder, stack[lastContainingTypeIndex], escapeKeywordIdentifiers, out sawSingleInvalidIdentifier); sawInvalidIdentifier |= sawSingleInvalidIdentifier; var typeArgumentOffset = 0; // Pop from outside, in. for (int i = lastContainingTypeIndex; i >= 0; i--) { var containingType = stack[i]; // ACASEY: I explored the type in the debugger and couldn't find the arity stored/exposed separately. int arity = hasTypeArguments ? containingType.GetGenericArguments().Length - typeArgumentOffset : 0; AppendUnqualifiedTypeName(builder, containingType, dynamicFlags, ref index, escapeKeywordIdentifiers, typeArguments, typeArgumentOffset, arity, out sawSingleInvalidIdentifier); sawInvalidIdentifier |= sawSingleInvalidIdentifier; builder.Append('.'); typeArgumentOffset += arity; } stack.Free(); AppendUnqualifiedTypeName(builder, type, dynamicFlags, ref index, escapeKeywordIdentifiers, typeArguments, typeArgumentOffset, numTypeArguments - typeArgumentOffset, out sawSingleInvalidIdentifier); sawInvalidIdentifier |= sawSingleInvalidIdentifier; } else { AppendNamespacePrefix(builder, type, escapeKeywordIdentifiers, out sawSingleInvalidIdentifier); sawInvalidIdentifier |= sawSingleInvalidIdentifier; AppendUnqualifiedTypeName(builder, type, dynamicFlags, ref index, escapeKeywordIdentifiers, typeArguments, 0, numTypeArguments, out sawSingleInvalidIdentifier); sawInvalidIdentifier |= sawSingleInvalidIdentifier; } }
/// <summary> /// Append the qualified name (i.e. including containing types and namespaces) of a named type /// (i.e. not a pointer or array type) to <paramref name="builder"/>. /// </summary> /// <remarks> /// Keyword strings are appended for primitive types (e.g. "int" for "System.Int32"). /// </remarks> /// <remarks> /// Does not call itself or <see cref="AppendQualifiedTypeName"/> (directly). /// </remarks> private void AppendQualifiedTypeNameInternal(StringBuilder builder, Type type, DynamicFlagsCustomTypeInfo dynamicFlags, ref int index, bool escapeKeywordIdentifiers) { var isDynamic = dynamicFlags[index++] && type.IsObject(); if (AppendSpecialTypeName(builder, type, isDynamic, escapeKeywordIdentifiers)) { return; } Debug.Assert(!isDynamic, $"Dynamic should have been handled by {nameof(AppendSpecialTypeName)}"); Debug.Assert(!IsPredefinedType(type)); // Note: in the Reflection/LMR object model, all type arguments are on the most nested type. var hasTypeArguments = type.IsGenericType; var typeArguments = type.IsGenericType ? type.GetGenericArguments() : null; Debug.Assert(hasTypeArguments == (typeArguments != null)); var numTypeArguments = hasTypeArguments ? typeArguments.Length : 0; if (type.IsNested) { // Push from inside, out. var stack = ArrayBuilder <Type> .GetInstance(); { var containingType = type.DeclaringType; while (containingType != null) { stack.Add(containingType); containingType = containingType.DeclaringType; } } var lastContainingTypeIndex = stack.Count - 1; AppendNamespacePrefix(builder, stack[lastContainingTypeIndex], escapeKeywordIdentifiers); var typeArgumentOffset = 0; // Pop from outside, in. for (int i = lastContainingTypeIndex; i >= 0; i--) { var containingType = stack[i]; // ACASEY: I explored the type in the debugger and couldn't find the arity stored/exposed separately. int arity = hasTypeArguments ? containingType.GetGenericArguments().Length - typeArgumentOffset : 0; AppendUnqualifiedTypeName(builder, containingType, dynamicFlags, ref index, escapeKeywordIdentifiers, typeArguments, typeArgumentOffset, arity); builder.Append('.'); typeArgumentOffset += arity; } stack.Free(); AppendUnqualifiedTypeName(builder, type, dynamicFlags, ref index, escapeKeywordIdentifiers, typeArguments, typeArgumentOffset, numTypeArguments - typeArgumentOffset); } else { AppendNamespacePrefix(builder, type, escapeKeywordIdentifiers); AppendUnqualifiedTypeName(builder, type, dynamicFlags, ref index, escapeKeywordIdentifiers, typeArguments, 0, numTypeArguments); } }
/// <summary> /// Append the qualified name (i.e. including containing types and namespaces) of a named type /// (i.e. not a pointer or array type) to <paramref name="builder"/>. /// </summary> /// <remarks> /// Keyword strings are appended for primitive types (e.g. "int" for "System.Int32"). /// </remarks> /// <remarks> /// Does not call itself or <see cref="AppendQualifiedTypeName"/> (directly). /// </remarks> private void AppendQualifiedTypeNameInternal( StringBuilder builder, Type type, ReadOnlyCollection <byte> dynamicFlags, ref int dynamicFlagIndex, ReadOnlyCollection <string> tupleElementNames, ref int tupleElementIndex, bool escapeKeywordIdentifiers, out bool sawInvalidIdentifier) { var isDynamic = DynamicFlagsCustomTypeInfo.GetFlag(dynamicFlags, dynamicFlagIndex++) && type.IsObject(); if (AppendSpecialTypeName(builder, type, isDynamic)) { sawInvalidIdentifier = false; return; } Debug.Assert(!isDynamic, $"Dynamic should have been handled by {nameof(AppendSpecialTypeName)}"); Debug.Assert(!IsPredefinedType(type)); if (type.IsGenericParameter) { AppendIdentifier(builder, escapeKeywordIdentifiers, type.Name, out sawInvalidIdentifier); return; } int cardinality; if (type.IsTupleCompatible(out cardinality)) { if (cardinality == 1) { // Not displayed as a tuple but is included in tuple element names. tupleElementIndex++; } else { AppendTupleElements( builder, type, cardinality, dynamicFlags, ref dynamicFlagIndex, tupleElementNames, ref tupleElementIndex, escapeKeywordIdentifiers, out sawInvalidIdentifier); return; } } // Note: in the Reflection/LMR object model, all type arguments are on the most nested type. var hasTypeArguments = type.IsGenericType; var typeArguments = hasTypeArguments ? type.GetGenericArguments() : null; Debug.Assert(hasTypeArguments == (typeArguments != null)); var numTypeArguments = hasTypeArguments ? typeArguments.Length : 0; sawInvalidIdentifier = false; bool sawSingleInvalidIdentifier; var typeArgumentOffset = 0; if (type.IsNested) { // Push from inside, out. var stack = ArrayBuilder <Type> .GetInstance(); { var containingType = type.DeclaringType; while (containingType != null) { stack.Add(containingType); containingType = containingType.DeclaringType; } } var lastContainingTypeIndex = stack.Count - 1; AppendNamespacePrefix(builder, stack[lastContainingTypeIndex], escapeKeywordIdentifiers, out sawSingleInvalidIdentifier); sawInvalidIdentifier |= sawSingleInvalidIdentifier; // Pop from outside, in. for (int i = lastContainingTypeIndex; i >= 0; i--) { var containingType = stack[i]; // ACASEY: I explored the type in the debugger and couldn't find the arity stored/exposed separately. int arity = hasTypeArguments ? containingType.GetGenericArguments().Length - typeArgumentOffset : 0; AppendUnqualifiedTypeName( builder, containingType, dynamicFlags, ref dynamicFlagIndex, tupleElementNames, ref tupleElementIndex, escapeKeywordIdentifiers, typeArguments, typeArgumentOffset, arity, out sawSingleInvalidIdentifier); sawInvalidIdentifier |= sawSingleInvalidIdentifier; builder.Append('.'); typeArgumentOffset += arity; } stack.Free(); } else { AppendNamespacePrefix(builder, type, escapeKeywordIdentifiers, out sawSingleInvalidIdentifier); sawInvalidIdentifier |= sawSingleInvalidIdentifier; } AppendUnqualifiedTypeName( builder, type, dynamicFlags, ref dynamicFlagIndex, tupleElementNames, ref tupleElementIndex, escapeKeywordIdentifiers, typeArguments, typeArgumentOffset, numTypeArguments - typeArgumentOffset, out sawSingleInvalidIdentifier); sawInvalidIdentifier |= sawSingleInvalidIdentifier; }
private void AppendTupleElements( StringBuilder builder, Type type, int cardinality, ReadOnlyCollection<byte> dynamicFlags, ref int dynamicFlagIndex, ReadOnlyCollection<string> tupleElementNames, ref int tupleElementIndex, bool escapeKeywordIdentifiers, out bool sawInvalidIdentifier) { sawInvalidIdentifier = false; #if DEBUG int lastNameIndex = tupleElementIndex + cardinality; #endif int nameIndex = tupleElementIndex; builder.Append('('); bool any = false; while (true) { tupleElementIndex += cardinality; var typeArguments = type.GetGenericArguments(); int nTypeArgs = typeArguments.Length; Debug.Assert(nTypeArgs > 0); Debug.Assert(nTypeArgs <= TypeHelpers.TupleFieldRestPosition); int nFields = Math.Min(nTypeArgs, TypeHelpers.TupleFieldRestPosition - 1); for (int i = 0; i < nFields; i++) { if (any) { builder.Append(", "); } bool sawSingleInvalidIdentifier; var name = CustomTypeInfo.GetTupleElementNameIfAny(tupleElementNames, nameIndex); nameIndex++; AppendTupleElement( builder, typeArguments[i], name, dynamicFlags, ref dynamicFlagIndex, tupleElementNames, ref tupleElementIndex, escapeKeywordIdentifiers, sawInvalidIdentifier: out sawSingleInvalidIdentifier); sawInvalidIdentifier |= sawSingleInvalidIdentifier; any = true; } if (nTypeArgs < TypeHelpers.TupleFieldRestPosition) { break; } Debug.Assert(!DynamicFlagsCustomTypeInfo.GetFlag(dynamicFlags, dynamicFlagIndex)); dynamicFlagIndex++; type = typeArguments[nTypeArgs - 1]; cardinality = type.GetTupleCardinalityIfAny(); } #if DEBUG Debug.Assert(nameIndex == lastNameIndex); #endif builder.Append(')'); }
/// <summary> /// Append the qualified name (i.e. including containing types and namespaces) of a named type /// (i.e. not a pointer or array type) to <paramref name="builder"/>. /// </summary> /// <remarks> /// Keyword strings are appended for primitive types (e.g. "int" for "System.Int32"). /// </remarks> /// <remarks> /// Does not call itself or <see cref="AppendQualifiedTypeName"/> (directly). /// </remarks> private void AppendQualifiedTypeNameInternal(StringBuilder builder, Type type, bool escapeKeywordIdentifiers) { if (AppendSpecialTypeName(builder, type, escapeKeywordIdentifiers)) { return; } Debug.Assert(!IsPredefinedType(type)); // Note: in the Reflection/LMR object model, all type arguments are on the most nested type. var hasTypeArguments = type.IsGenericType; var typeArguments = type.IsGenericType ? type.GetGenericArguments() : null; Debug.Assert(hasTypeArguments == (typeArguments != null)); var numTypeArguments = hasTypeArguments ? typeArguments.Length : 0; if (type.IsNested) { // Push from inside, out. var stack = ArrayBuilder<Type>.GetInstance(); { var containingType = type.DeclaringType; while (containingType != null) { stack.Add(containingType); containingType = containingType.DeclaringType; } } var lastContainingTypeIndex = stack.Count - 1; AppendNamespacePrefix(builder, stack[lastContainingTypeIndex], escapeKeywordIdentifiers); var typeArgumentOffset = 0; // Pop from outside, in. for (int i = lastContainingTypeIndex; i >= 0; i--) { var containingType = stack[i]; // ACASEY: I explored the type in the debugger and couldn't find the arity stored/exposed separately. int arity = hasTypeArguments ? containingType.GetGenericArguments().Length - typeArgumentOffset : 0; AppendUnqualifiedTypeName(builder, containingType, escapeKeywordIdentifiers, typeArguments, typeArgumentOffset, arity); builder.Append('.'); typeArgumentOffset += arity; } stack.Free(); AppendUnqualifiedTypeName(builder, type, escapeKeywordIdentifiers, typeArguments, typeArgumentOffset, numTypeArguments - typeArgumentOffset); } else { AppendNamespacePrefix(builder, type, escapeKeywordIdentifiers); AppendUnqualifiedTypeName(builder, type, escapeKeywordIdentifiers, typeArguments, 0, numTypeArguments); } }