public void CorLibTypes() { var mdTestLib1 = TestReferences.SymbolsTests.MDTestLib1; var c1 = CSharpCompilation.Create("Test", references: new MetadataReference[] { MscorlibRef_v4_0_30316_17626, mdTestLib1 }); TypeSymbol c107 = c1.GlobalNamespace.GetTypeMembers("C107").Single(); Assert.Equal(SpecialType.None, c107.SpecialType); for (int i = 1; i <= (int)SpecialType.Count; i++) { NamedTypeSymbol type = c1.GetSpecialType((SpecialType)i); Assert.False(type.IsErrorType()); Assert.Equal((SpecialType)i, type.SpecialType); } Assert.Equal(SpecialType.None, c107.SpecialType); var arrayOfc107 = new ArrayTypeSymbol(c1.Assembly, c107); Assert.Equal(SpecialType.None, arrayOfc107.SpecialType); var c2 = CSharpCompilation.Create("Test", references: new[] { mdTestLib1 }); Assert.Equal(SpecialType.None, c2.GlobalNamespace.GetTypeMembers("C107").Single().SpecialType); }
public void TestArrayType() { CSharpCompilation compilation = CSharpCompilation.Create("Test"); NamedTypeSymbol elementType = new MockNamedTypeSymbol("TestClass", Enumerable.Empty<Symbol>()); // this can be any type. ArrayTypeSymbol ats1 = new ArrayTypeSymbol(compilation.Assembly, elementType, rank: 1); Assert.Equal(1, ats1.Rank); Assert.Same(elementType, ats1.ElementType); Assert.Equal(SymbolKind.ArrayType, ats1.Kind); Assert.True(ats1.IsReferenceType); Assert.False(ats1.IsValueType); Assert.Equal("TestClass[]", ats1.ToTestDisplayString()); ArrayTypeSymbol ats2 = new ArrayTypeSymbol(compilation.Assembly, elementType, rank: 2); Assert.Equal(2, ats2.Rank); Assert.Same(elementType, ats2.ElementType); Assert.Equal(SymbolKind.ArrayType, ats2.Kind); Assert.True(ats2.IsReferenceType); Assert.False(ats2.IsValueType); Assert.Equal("TestClass[,]", ats2.ToTestDisplayString()); ArrayTypeSymbol ats3 = new ArrayTypeSymbol(compilation.Assembly, elementType, rank: 3); Assert.Equal(3, ats3.Rank); Assert.Equal("TestClass[,,]", ats3.ToTestDisplayString()); }
public TypedConstantTests() { compilation = CreateCompilationWithMscorlib("class C {}"); namedType = compilation.GlobalNamespace.GetMember<NamedTypeSymbol>("C"); systemType = compilation.GetWellKnownType(WellKnownType.System_Type); arrayType = compilation.CreateArrayTypeSymbol(compilation.GetSpecialType(SpecialType.System_Object)); intType = compilation.GetSpecialType(SpecialType.System_Int32); stringType = compilation.GetSpecialType(SpecialType.System_String); enumString1 = compilation.GetSpecialType(SpecialType.System_Collections_Generic_IEnumerable_T).Construct(compilation.GetSpecialType(SpecialType.System_String)); enumString2 = compilation.GetSpecialType(SpecialType.System_Collections_Generic_IEnumerable_T).Construct(compilation.GetSpecialType(SpecialType.System_String)); }
private void EmitElementInitializers(ArrayTypeSymbol arrayType, ImmutableArray<BoundExpression> inits, bool includeConstants) { if (!IsMultidimensionalInitializer(inits)) { EmitVectorElementInitializers(arrayType, inits, includeConstants); } else { EmitMultidimensionalElementInitializers(arrayType, inits, includeConstants); } }
private void EmitVectorElementInitializers(ArrayTypeSymbol arrayType, ImmutableArray<BoundExpression> inits, bool includeConstants) { for (int i = 0; i < inits.Length; i++) { var init = inits[i]; if (ShouldEmitInitExpression(includeConstants, init)) { _builder.EmitOpCode(ILOpCode.Dup); _builder.EmitIntConstant(i); EmitExpression(init, true); EmitVectorElementStore(arrayType, init.Syntax); } } }
private DynamicAnalysisInjector(MethodSymbol method, BoundStatement methodBody, SyntheticBoundNodeFactory methodBodyFactory, MethodSymbol createPayload, DiagnosticBag diagnostics, DebugDocumentProvider debugDocumentProvider, Instrumenter previous) : base(previous) { _createPayload = createPayload; _method = method; _methodBody = methodBody; _spansBuilder = ArrayBuilder<SourceSpan>.GetInstance(); TypeSymbol payloadElementType = methodBodyFactory.SpecialType(SpecialType.System_Boolean); _payloadType = ArrayTypeSymbol.CreateCSharpArray(methodBodyFactory.Compilation.Assembly, payloadElementType); _methodPayload = methodBodyFactory.SynthesizedLocal(_payloadType, kind: SynthesizedLocalKind.InstrumentationPayload, syntax: methodBody.Syntax); _diagnostics = diagnostics; _debugDocumentProvider = debugDocumentProvider; _methodHasExplicitBlock = MethodHasExplicitBlock(method); _methodBodyFactory = methodBodyFactory; // The first point indicates entry into the method and has the span of the method definition. _methodEntryInstrumentation = AddAnalysisPoint(MethodDeclarationIfAvailable(methodBody.Syntax), methodBodyFactory); }
/// <summary> /// Entry point to the array initialization. /// Assumes that we have newly created array on the stack. /// /// inits could be an array of values for a single dimensional array /// or an array (of array)+ of values for a multidimensional case /// /// in either case it is expected that number of leaf values will match number /// of elements in the array and nesting level should match the rank of the array. /// </summary> private void EmitArrayInitializers(ArrayTypeSymbol arrayType, BoundArrayInitialization inits) { var initExprs = inits.Initializers; var initializationStyle = ShouldEmitBlockInitializer(arrayType.ElementType, initExprs); if (initializationStyle == ArrayInitializerStyle.Element) { this.EmitElementInitializers(arrayType, initExprs, true); } else { ImmutableArray<byte> data = this.GetRawData(initExprs); _builder.EmitArrayBlockInitializer(data, inits.Syntax, _diagnostics); if (initializationStyle == ArrayInitializerStyle.Mixed) { EmitElementInitializers(arrayType, initExprs, false); } } }
public void TestPointerTypeTransforms() { CommonTestInitialization(); // public unsafe class UnsafeClass<T> : Base2<int*[], Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int*[][]>[], dynamic>.InnerInner<dynamic>[][]> { } var unsafeClass = _assembly.Modules[0].GlobalNamespace.GetMember<NamedTypeSymbol>("UnsafeClass"); Assert.False(unsafeClass.ContainsDynamic()); Assert.True(unsafeClass.BaseType.ContainsDynamic()); var unsafeClassTypeParam = unsafeClass.TypeParameters[0]; // T[] var arrayOfDerivedTypeParam = new ArrayTypeSymbol(_assembly, unsafeClassTypeParam, ImmutableArray.Create<CustomModifier>(), 1); // Outer<dynamic> var outerClassOfDynamic = _outerClass.Construct(s_dynamicType); // Outer<dynamic>.Inner<T[], dynamic> var complicatedInner = outerClassOfDynamic.GetTypeMember("Inner").Construct(arrayOfDerivedTypeParam, s_dynamicType); // int*[] var pointerToInt = new PointerTypeSymbol(_intType, ImmutableArray.Create<CustomModifier>()); var arrayOfPointerToInt = new ArrayTypeSymbol(_assembly, pointerToInt, ImmutableArray.Create<CustomModifier>(), 1); // int*[][] var arrayOfArrayOfPointerToInt = new ArrayTypeSymbol(_assembly, arrayOfPointerToInt, ImmutableArray.Create<CustomModifier>(), 1); // Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int*[][]> var complicatedInnerInner = complicatedInner.GetTypeMember("InnerInner").Construct(arrayOfArrayOfPointerToInt); // Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int*[][]>[] var complicatedInnerInnerArray = new ArrayTypeSymbol(_assembly, complicatedInnerInner, ImmutableArray.Create<CustomModifier>(), 1); // Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int*[][]>[], dynamic> complicatedInner = outerClassOfDynamic.GetTypeMember("Inner").Construct(complicatedInnerInnerArray, s_dynamicType); // Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int*[][]>[], dynamic>.InnerInner<dynamic> complicatedInnerInner = complicatedInner.GetTypeMember("InnerInner").Construct(s_dynamicType); // Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int*[][]>[], dynamic>.InnerInner<dynamic>[][] complicatedInnerInnerArray = new ArrayTypeSymbol(_assembly, complicatedInnerInner, ImmutableArray.Create<CustomModifier>(), 1); var complicatedInnerInnerArrayOfArray = new ArrayTypeSymbol(_assembly, complicatedInnerInnerArray, ImmutableArray.Create<CustomModifier>(), 1); // Base2<int*[], Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int*[][]>[], dynamic>.InnerInner<dynamic>[][]> var baseType = _base2Class.Construct(arrayOfPointerToInt, complicatedInnerInnerArrayOfArray); Assert.Equal(baseType, unsafeClass.BaseType); }
public void TestReturnValueParameterAndPropertyTransforms() { CommonTestInitialization(); //public static dynamic F1(dynamic x) { return x; } var f1 = _derivedClass.GetMember<MethodSymbol>("F1"); Assert.Equal(s_dynamicType, f1.ReturnType); Assert.Equal(s_dynamicType, f1.ParameterTypes[0]); //public static dynamic F2(ref dynamic x) { return x; } var f2 = _derivedClass.GetMember<MethodSymbol>("F2"); Assert.Equal(s_dynamicType, f2.ReturnType); Assert.Equal(s_dynamicType, f2.ParameterTypes[0]); Assert.Equal(RefKind.Ref, f2.Parameters[0].RefKind); //public static dynamic[] F3(dynamic[] x) { return x; } var f3 = _derivedClass.GetMember<MethodSymbol>("F3"); var arrayOfDynamic = new ArrayTypeSymbol(_assembly, s_dynamicType); Assert.Equal(arrayOfDynamic, f3.ReturnType); Assert.Equal(arrayOfDynamic, f3.ParameterTypes[0]); Assert.Equal(RefKind.None, f3.Parameters[0].RefKind); var derivedTypeParam = _derivedClass.TypeParameters[0]; var arrayOfDerivedTypeParam = new ArrayTypeSymbol(_assembly, derivedTypeParam); // Outer<dynamic> var outerClassOfDynamic = _outerClass.Construct(s_dynamicType); // Outer<dynamic>.Inner<T[], dynamic> var complicatedInner = outerClassOfDynamic.GetTypeMember("Inner").Construct(arrayOfDerivedTypeParam, s_dynamicType); // Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int> var complicatedInnerInner = complicatedInner.GetTypeMember("InnerInner").Construct(_intType); // Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int>[] var complicatedInnerInnerArray = new ArrayTypeSymbol(_assembly, complicatedInnerInner); // Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int>[], dynamic> complicatedInner = outerClassOfDynamic.GetTypeMember("Inner").Construct(complicatedInnerInnerArray, s_dynamicType); // Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int>[], dynamic>.InnerInner<dynamic> complicatedInnerInner = complicatedInner.GetTypeMember("InnerInner").Construct(s_dynamicType); // Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int>[], dynamic>.InnerInner<dynamic>[][] complicatedInnerInnerArray = new ArrayTypeSymbol(_assembly, complicatedInnerInner); var complicatedInnerInnerArrayOfArray = new ArrayTypeSymbol(_assembly, complicatedInnerInnerArray); //public static Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int>[], dynamic>.InnerInner<dynamic>[][] F4(Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int>[], dynamic>.InnerInner<dynamic>[][] x) { return x; } var f4 = _derivedClass.GetMember<MethodSymbol>("F4"); Assert.Equal(complicatedInnerInnerArrayOfArray, f4.ReturnType); Assert.Equal(complicatedInnerInnerArrayOfArray, f4.ParameterTypes[0]); Assert.Equal(RefKind.None, f4.Parameters[0].RefKind); //public static dynamic Prop1 { get { return field1; } } var prop1 = _derivedClass.GetMember<PropertySymbol>("Prop1"); Assert.Equal(s_dynamicType, prop1.Type); Assert.Equal(s_dynamicType, prop1.GetMethod.ReturnType); //public static Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int>[], dynamic>.InnerInner<dynamic>[][] Prop2 { get { return field17; } set { field17 = value; } } var prop2 = _derivedClass.GetMember<PropertySymbol>("Prop2"); Assert.Equal(complicatedInnerInnerArrayOfArray, prop2.Type); Assert.Equal(complicatedInnerInnerArrayOfArray, prop2.GetMethod.ReturnType); Assert.Equal(SpecialType.System_Void, prop2.SetMethod.ReturnType.SpecialType); Assert.Equal(complicatedInnerInnerArrayOfArray, prop2.SetMethod.ParameterTypes[0]); }
internal bool Equals(ArrayTypeSymbol other) { return(Equals(other, false, false)); }
private void EmitArrayElementStore(ArrayTypeSymbol arrayType, SyntaxNode syntaxNode) { if (arrayType.IsSZArray) { EmitVectorElementStore(arrayType, syntaxNode); } else { _builder.EmitArrayElementStore(Emit.PEModuleBuilder.Translate(arrayType), syntaxNode, _diagnostics); } }
private ArrayTypeSymbol TransformArrayType(ArrayTypeSymbol arrayType) { var flag = ConsumeFlag(); Debug.Assert(!flag); if (!HandleCustomModifiers(arrayType.CustomModifiers.Length)) { return null; } TypeSymbol transformedElementType = TransformType(arrayType.ElementType); if ((object)transformedElementType == null) { return null; } return transformedElementType == arrayType.ElementType ? arrayType : arrayType.IsSZArray ? ArrayTypeSymbol.CreateSZArray(_containingAssembly, transformedElementType, arrayType.CustomModifiers) : ArrayTypeSymbol.CreateMDArray(_containingAssembly, transformedElementType, arrayType.Rank, arrayType.Sizes, arrayType.LowerBounds, arrayType.CustomModifiers); }
private void EmitMultidimensionalElementInitializers(ArrayTypeSymbol arrayType, ImmutableArray<BoundExpression> inits, bool includeConstants) { // Using a List for the stack instead of the framework Stack because IEnumerable from Stack is top to bottom. // This algorithm requires the IEnumerable to be from bottom to top. See extensions for List in CollectionExtensions.vb. var indices = new ArrayBuilder<IndexDesc>(); // emit initializers for all values of the leftmost index. for (int i = 0; i < inits.Length; i++) { indices.Push(new IndexDesc(i, ((BoundArrayInitialization)inits[i]).Initializers)); EmitAllElementInitializersRecursive(arrayType, indices, includeConstants); } Debug.Assert(!indices.Any()); }
private string BuildArrayTypeString(ArrayTypeSymbol arrayType, out string assemblyNameSuffix) { TypeSymbol elementType = arrayType.ElementType; string typeArgumentsOpt = null; string elementTypeString = elementType.IsArray() ? BuildArrayTypeString((ArrayTypeSymbol)elementType, out assemblyNameSuffix) : BuildTypeString(elementType, out typeArgumentsOpt, out assemblyNameSuffix); PooledStringBuilder pool = PooledStringBuilder.GetInstance(); StringBuilder builder = pool.Builder; builder.Append(elementTypeString); AppendTypeArguments(builder, typeArgumentsOpt); builder.Append(BuildArrayShapeString(arrayType)); return pool.ToStringAndFree(); }
public void TestBaseTypeDynamicTransforms() { CommonTestInitialization(); // public class Base0 { } Assert.Equal(_objectType, _base0Class.BaseType); Assert.False(_base0Class.ContainsDynamic()); // public class Base1<T> { } Assert.Equal(_objectType, _base1Class.BaseType); Assert.False(_base1Class.ContainsDynamic()); // public class Base2<T, U> { } Assert.Equal(_objectType, _base2Class.BaseType); Assert.False(_base2Class.ContainsDynamic()); // public class Derived<T> : Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int>[], dynamic>.InnerInner<dynamic> where T : Derived<T> { ... } Assert.False(_derivedClass.ContainsDynamic()); Assert.True(_derivedClass.BaseType.ContainsDynamic()); // Outer<dynamic> var outerClassOfDynamic = _outerClass.Construct(s_dynamicType); // Outer<dynamic>.Inner<T[], dynamic> var t = _derivedClass.TypeParameters[0]; var arrayOfT = new ArrayTypeSymbol(_assembly, t); var innerClassOfTArrDynamic = outerClassOfDynamic.GetTypeMember("Inner").Construct(arrayOfT, s_dynamicType); // Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int>[] var memberInnerInnerOfInt = innerClassOfTArrDynamic.GetTypeMember("InnerInner").Construct(_intType); var arrayOfInnerInnerOfInt = new ArrayTypeSymbol(_assembly, memberInnerInnerOfInt); // Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int>[], dynamic> var memberComplicatedInner = outerClassOfDynamic.GetTypeMember("Inner").Construct(arrayOfInnerInnerOfInt, s_dynamicType); // Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int>[], dynamic>.InnerInner<dynamic> var memberInnerInnerOfDynamic = memberComplicatedInner.GetTypeMember("InnerInner").Construct(s_dynamicType); Assert.Equal(memberInnerInnerOfDynamic, _derivedClass.BaseType); // public class Outer<T> : Base1<dynamic> Assert.False(_outerClass.ContainsDynamic()); Assert.True(_outerClass.BaseType.ContainsDynamic()); var base1OfDynamic = _base1Class.Construct(s_dynamicType); Assert.Equal(base1OfDynamic, _outerClass.BaseType); // public class Inner<U, V> : Base2<dynamic, V> Assert.False(_innerClass.ContainsDynamic()); Assert.True(_innerClass.BaseType.ContainsDynamic()); var base2OfDynamicV = _base2Class.Construct(s_dynamicType, _innerClass.TypeParameters[1]); Assert.Equal(base2OfDynamicV, _innerClass.BaseType); // public class InnerInner<W> : Base1<dynamic> { } Assert.False(_innerInnerClass.ContainsDynamic()); Assert.True(_innerInnerClass.BaseType.ContainsDynamic()); Assert.Equal(base1OfDynamic, _innerInnerClass.BaseType); // public class Outer2<T> : Base1<dynamic> Assert.False(_outer2Class.ContainsDynamic()); Assert.True(_outer2Class.BaseType.ContainsDynamic()); Assert.Equal(base1OfDynamic, _outer2Class.BaseType); // public class Inner2<U, V> : Base0 Assert.False(_inner2Class.ContainsDynamic()); Assert.False(_inner2Class.BaseType.ContainsDynamic()); Assert.Equal(_base0Class, _inner2Class.BaseType); // public class InnerInner2<W> : Base0 { } Assert.False(_innerInner2Class.ContainsDynamic()); Assert.False(_innerInner2Class.BaseType.ContainsDynamic()); Assert.Equal(_base0Class, _innerInner2Class.BaseType); // public class Inner3<U> Assert.False(_inner3Class.ContainsDynamic()); }
private static BoundExpression GetCustomTypeInfoPayload(LocalSymbol local, CSharpSyntaxNode syntax, CSharpCompilation compilation, out bool hasCustomTypeInfoPayload) { var byteArrayType = new ArrayTypeSymbol( compilation.Assembly, compilation.GetSpecialType(SpecialType.System_Byte)); var flags = CSharpCompilation.DynamicTransformsEncoder.Encode(local.Type, customModifiersCount: 0, refKind: RefKind.None); var bytes = DynamicFlagsCustomTypeInfo.Create(flags).GetCustomTypeInfoPayload(); hasCustomTypeInfoPayload = bytes != null; if (!hasCustomTypeInfoPayload) { return new BoundLiteral(syntax, ConstantValue.Null, byteArrayType); } var byteType = byteArrayType.ElementType; var intType = compilation.GetSpecialType(SpecialType.System_Int32); var numBytes = bytes.Count; var initializerExprs = ArrayBuilder<BoundExpression>.GetInstance(numBytes); foreach (var b in bytes) { initializerExprs.Add(new BoundLiteral(syntax, ConstantValue.Create(b), byteType)); } var lengthExpr = new BoundLiteral(syntax, ConstantValue.Create(numBytes), intType); return new BoundArrayCreation( syntax, ImmutableArray.Create<BoundExpression>(lengthExpr), new BoundArrayInitialization(syntax, initializerExprs.ToImmutableAndFree()), byteArrayType); }
internal bool Equals(ArrayTypeSymbol other) { return(Equals(other, TypeCompareKind.ConsiderEverything)); }
internal bool HasSameShapeAs(ArrayTypeSymbol other) { return(Rank == other.Rank && IsSZArray == other.IsSZArray); }
/// <summary> /// Resolves <see cref="System.Type"/> to a <see cref="TypeSymbol"/> available in this assembly /// its referenced assemblies. /// </summary> /// <param name="type">The type to resolve.</param> /// <param name="includeReferences">Use referenced assemblies for resolution.</param> /// <returns>The resolved symbol if successful or null on failure.</returns> internal TypeSymbol GetTypeByReflectionType(Type type, bool includeReferences) { System.Reflection.TypeInfo typeInfo = type.GetTypeInfo(); Debug.Assert(!typeInfo.IsByRef); // not supported (we don't accept open types as submission results nor host types): Debug.Assert(!typeInfo.ContainsGenericParameters); if (typeInfo.IsArray) { TypeSymbol symbol = GetTypeByReflectionType(typeInfo.GetElementType(), includeReferences); if ((object)symbol == null) { return(null); } int rank = typeInfo.GetArrayRank(); return(ArrayTypeSymbol.CreateCSharpArray(this, TypeWithAnnotations.Create(symbol), rank)); } else if (typeInfo.IsPointer) { TypeSymbol symbol = GetTypeByReflectionType(typeInfo.GetElementType(), includeReferences); if ((object)symbol == null) { return(null); } return(new PointerTypeSymbol(TypeWithAnnotations.Create(symbol))); } else if (typeInfo.DeclaringType != null) { Debug.Assert(!typeInfo.IsArray); // consolidated generic arguments (includes arguments of all declaring types): Type[] genericArguments = typeInfo.GenericTypeArguments; int typeArgumentIndex = 0; var currentTypeInfo = typeInfo.IsGenericType ? typeInfo.GetGenericTypeDefinition().GetTypeInfo() : typeInfo; var nestedTypes = ArrayBuilder <System.Reflection.TypeInfo> .GetInstance(); while (true) { Debug.Assert(currentTypeInfo.IsGenericTypeDefinition || !currentTypeInfo.IsGenericType); nestedTypes.Add(currentTypeInfo); if (currentTypeInfo.DeclaringType == null) { break; } currentTypeInfo = currentTypeInfo.DeclaringType.GetTypeInfo(); } int i = nestedTypes.Count - 1; var symbol = (NamedTypeSymbol)GetTypeByReflectionType(nestedTypes[i].AsType(), includeReferences); if ((object)symbol == null) { return(null); } while (--i >= 0) { int forcedArity = nestedTypes[i].GenericTypeParameters.Length - nestedTypes[i + 1].GenericTypeParameters.Length; MetadataTypeName mdName = MetadataTypeName.FromTypeName(nestedTypes[i].Name, forcedArity: forcedArity); symbol = symbol.LookupMetadataType(ref mdName); if ((object)symbol == null || symbol.IsErrorType()) { return(null); } symbol = ApplyGenericArguments(symbol, genericArguments, ref typeArgumentIndex, includeReferences); if ((object)symbol == null) { return(null); } } nestedTypes.Free(); Debug.Assert(typeArgumentIndex == genericArguments.Length); return(symbol); } else { AssemblyIdentity assemblyId = AssemblyIdentity.FromAssemblyDefinition(typeInfo.Assembly); MetadataTypeName mdName = MetadataTypeName.FromNamespaceAndTypeName( typeInfo.Namespace ?? string.Empty, typeInfo.Name, forcedArity: typeInfo.GenericTypeArguments.Length); NamedTypeSymbol symbol = GetTopLevelTypeByMetadataName(ref mdName, assemblyId, includeReferences, isWellKnownType: false, conflicts: out var _); if ((object)symbol == null || symbol.IsErrorType()) { return(null); } int typeArgumentIndex = 0; Type[] genericArguments = typeInfo.GenericTypeArguments; symbol = ApplyGenericArguments(symbol, genericArguments, ref typeArgumentIndex, includeReferences); Debug.Assert(typeArgumentIndex == genericArguments.Length); return(symbol); } }
private static string BuildArrayShapeString(ArrayTypeSymbol arrayType) { PooledStringBuilder pool = PooledStringBuilder.GetInstance(); StringBuilder builder = pool.Builder; builder.Append("["); if (arrayType.Rank > 1) { builder.Append(',', arrayType.Rank - 1); } builder.Append("]"); return pool.ToStringAndFree(); }
private static TypeSymbol GetMatchingElementType(ArrayTypeSymbol source, TypeSymbol target, ref HashSet<DiagnosticInfo> useSiteDiagnostics) { Debug.Assert((object)source != null); Debug.Assert((object)target != null); // It might be an array of same rank. if (target.IsArray()) { var arrayTarget = (ArrayTypeSymbol)target; if (!arrayTarget.HasSameShapeAs(source)) { return null; } return arrayTarget.ElementType; } // Or it might be IEnum<T> and source is rank one. if (!source.IsSZArray) { return null; } // Arrays are specified as being convertible to IEnumerable<T>, ICollection<T> and // IList<T>; we also honor their convertibility to IReadOnlyCollection<T> and // IReadOnlyList<T>, and make inferences accordingly. if (!target.IsPossibleArrayGenericInterface()) { return null; } return ((NamedTypeSymbol)target).TypeArgumentWithDefinitionUseSiteDiagnostics(0, ref useSiteDiagnostics); }
private static bool IsArrayOfArrays(ArrayTypeSymbol arrayType) { return arrayType.ElementType.Kind == SymbolKind.ArrayType; }
public void TypeMap() { var source = @" struct S<T> where T : struct { } "; var comp = CreateCompilationWithMscorlib(source); comp.VerifyDiagnostics(); var intType = comp.GetSpecialType(SpecialType.System_Int32); var customModifiers = ImmutableArray.Create(CSharpCustomModifier.CreateOptional(intType)); var structType = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("S"); var typeParamType = structType.TypeParameters.Single(); var pointerType = new PointerTypeSymbol(typeParamType, customModifiers); // NOTE: We're constructing this manually, since it's illegal. var arrayType = new ArrayTypeSymbol(comp.Assembly, typeParamType, customModifiers); // This is legal, but we're already manually constructing types. var typeMap = new TypeMap(ImmutableArray.Create(typeParamType), ImmutableArray.Create<TypeSymbol>(intType)); var substitutedPointerType = (PointerTypeSymbol)typeMap.SubstituteType(pointerType); var substitutedArrayType = (ArrayTypeSymbol)typeMap.SubstituteType(arrayType); // The map changed the types. Assert.Equal(intType, substitutedPointerType.PointedAtType); Assert.Equal(intType, substitutedArrayType.ElementType); // The map preserved the custom modifiers. Assert.Equal(customModifiers, substitutedPointerType.CustomModifiers); Assert.Equal(customModifiers, substitutedArrayType.CustomModifiers); }
public void TestArrayTypeInAttributeArgument() { var source = @"using System; public class W {} public class Y<T> { public class F {} public class Z<U> {} } public class X : Attribute { public X(Type y) { } } [X(typeof(W[]))] public class C1 {} [X(typeof(W[,]))] public class C2 {} [X(typeof(W[,][]))] public class C3 {} [X(typeof(Y<W>[][,]))] public class C4 {} [X(typeof(Y<int>.F[,][][,,]))] public class C5 {} [X(typeof(Y<int>.Z<W>[,][]))] public class C6 {} "; var compilation = CreateCompilationWithMscorlib(source); Action<ModuleSymbol> attributeValidator = (ModuleSymbol m) => { NamedTypeSymbol classW = m.GlobalNamespace.GetTypeMember("W"); NamedTypeSymbol classY = m.GlobalNamespace.GetTypeMember("Y"); NamedTypeSymbol classF = classY.GetTypeMember("F"); NamedTypeSymbol classZ = classY.GetTypeMember("Z"); NamedTypeSymbol classX = m.GlobalNamespace.GetTypeMember("X"); NamedTypeSymbol classC1 = m.GlobalNamespace.GetTypeMember("C1"); NamedTypeSymbol classC2 = m.GlobalNamespace.GetTypeMember("C2"); NamedTypeSymbol classC3 = m.GlobalNamespace.GetTypeMember("C3"); NamedTypeSymbol classC4 = m.GlobalNamespace.GetTypeMember("C4"); NamedTypeSymbol classC5 = m.GlobalNamespace.GetTypeMember("C5"); NamedTypeSymbol classC6 = m.GlobalNamespace.GetTypeMember("C6"); var attrs = classC1.GetAttributes(); Assert.Equal(1, attrs.Length); var typeArg = new ArrayTypeSymbol(m.ContainingAssembly, classW, default(ImmutableArray<CustomModifier>)); attrs.First().VerifyValue<object>(0, TypedConstantKind.Type, typeArg); attrs = classC2.GetAttributes(); Assert.Equal(1, attrs.Length); typeArg = new ArrayTypeSymbol(m.ContainingAssembly, classW, default(ImmutableArray<CustomModifier>), rank: 2); attrs.First().VerifyValue<object>(0, TypedConstantKind.Type, typeArg); attrs = classC3.GetAttributes(); Assert.Equal(1, attrs.Length); typeArg = new ArrayTypeSymbol(m.ContainingAssembly, classW, default(ImmutableArray<CustomModifier>)); typeArg = new ArrayTypeSymbol(m.ContainingAssembly, typeArg, default(ImmutableArray<CustomModifier>), rank: 2); attrs.First().VerifyValue<object>(0, TypedConstantKind.Type, typeArg); attrs = classC4.GetAttributes(); Assert.Equal(1, attrs.Length); NamedTypeSymbol classYOfW = classY.ConstructIfGeneric(ImmutableArray.Create<TypeSymbol>(classW)); typeArg = new ArrayTypeSymbol(m.ContainingAssembly, classYOfW, default(ImmutableArray<CustomModifier>), rank: 2); typeArg = new ArrayTypeSymbol(m.ContainingAssembly, typeArg, default(ImmutableArray<CustomModifier>)); attrs.First().VerifyValue<object>(0, TypedConstantKind.Type, typeArg); attrs = classC5.GetAttributes(); Assert.Equal(1, attrs.Length); NamedTypeSymbol classYOfInt = classY.ConstructIfGeneric(ImmutableArray.Create<TypeSymbol>(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int32))); NamedTypeSymbol substNestedF = classYOfInt.GetTypeMember("F"); typeArg = new ArrayTypeSymbol(m.ContainingAssembly, substNestedF, default(ImmutableArray<CustomModifier>), rank: 3); typeArg = new ArrayTypeSymbol(m.ContainingAssembly, typeArg, default(ImmutableArray<CustomModifier>)); typeArg = new ArrayTypeSymbol(m.ContainingAssembly, typeArg, default(ImmutableArray<CustomModifier>), rank: 2); attrs.First().VerifyValue<object>(0, TypedConstantKind.Type, typeArg); attrs = classC6.GetAttributes(); Assert.Equal(1, attrs.Length); NamedTypeSymbol substNestedZ = classYOfInt.GetTypeMember("Z").ConstructIfGeneric(ImmutableArray.Create<TypeSymbol>(classW)); typeArg = new ArrayTypeSymbol(m.ContainingAssembly, substNestedZ, default(ImmutableArray<CustomModifier>)); typeArg = new ArrayTypeSymbol(m.ContainingAssembly, typeArg, default(ImmutableArray<CustomModifier>), rank: 2); attrs.First().VerifyValue<object>(0, TypedConstantKind.Type, typeArg); }; // Verify attributes from source and then load metadata to see attributes are written correctly. CompileAndVerify(compilation, sourceSymbolValidator: attributeValidator, symbolValidator: attributeValidator); }
/// <summary> /// Emits all initializers that match indices on the stack recursively. /// /// Example: /// if array has [0..2, 0..3, 0..2] shape /// and we have {1, 2} indices on the stack /// initializers for /// [1, 2, 0] /// [1, 2, 1] /// [1, 2, 2] /// /// will be emitted and the top index will be pushed off the stack /// as at that point we would be completely done with emitting initializers /// corresponding to that index. /// </summary> private void EmitAllElementInitializersRecursive(ArrayTypeSymbol arrayType, ArrayBuilder<IndexDesc> indices, bool includeConstants) { var top = indices.Peek(); var inits = top.Initializers; if (IsMultidimensionalInitializer(inits)) { // emit initializers for the less significant indices recursively for (int i = 0; i < inits.Length; i++) { indices.Push(new IndexDesc(i, ((BoundArrayInitialization)inits[i]).Initializers)); EmitAllElementInitializersRecursive(arrayType, indices, includeConstants); } } else { // leaf case for (int i = 0; i < inits.Length; i++) { var init = inits[i]; if (ShouldEmitInitExpression(includeConstants, init)) { // emit array ref _builder.EmitOpCode(ILOpCode.Dup); Debug.Assert(indices.Count == arrayType.Rank - 1); // emit values of all indices that are in progress foreach (var row in indices) { _builder.EmitIntConstant(row.Index); } // emit the leaf index _builder.EmitIntConstant(i); var initExpr = inits[i]; EmitExpression(initExpr, true); EmitArrayElementStore(arrayType, init.Syntax); } } } indices.Pop(); }
private ArrayTypeSymbol SubstituteArrayType(ArrayTypeSymbol t) { TypeSymbol element = SubstituteType(t.ElementType); if (ReferenceEquals(element, t.ElementType)) { return t; } ImmutableArray<NamedTypeSymbol> interfaces = t.InterfacesNoUseSiteDiagnostics(); Debug.Assert(0 <= interfaces.Length && interfaces.Length <= 2); if (interfaces.Length == 1) { Debug.Assert(interfaces[0] is NamedTypeSymbol); // IList<T> interfaces = ImmutableArray.Create<NamedTypeSymbol>((NamedTypeSymbol)SubstituteType(interfaces[0])); } else if (interfaces.Length == 2) { Debug.Assert(interfaces[0] is NamedTypeSymbol); // IList<T> interfaces = ImmutableArray.Create<NamedTypeSymbol>((NamedTypeSymbol)SubstituteType(interfaces[0]), (NamedTypeSymbol)SubstituteType(interfaces[1])); } return new ArrayTypeSymbol( element, t.Rank, t.BaseTypeNoUseSiteDiagnostics, interfaces, t.CustomModifiers); }
public void ReducedExtensionMethodSymbols() { var source = @"using System.Collections.Generic; static class S { internal static void M1(this object o) { } internal static void M2<T>(this IEnumerable<T> t) { } internal static void M3<T, U>(this U u, IEnumerable<T> t) { } }"; var compilation = CreateCompilationWithMscorlib(source, references: new[] { SystemCoreRef }, options: TestOptions.ReleaseDll.WithMetadataImportOptions(MetadataImportOptions.Internal)); Action<ModuleSymbol> validator = module => { var type = module.GlobalNamespace.GetMember<NamedTypeSymbol>("S"); var intType = compilation.GetSpecialType(SpecialType.System_Int32); var stringType = compilation.GetSpecialType(SpecialType.System_String); var arrayType = new ArrayTypeSymbol(compilation.Assembly, stringType, ImmutableArray.Create<CustomModifier>(), 1); // Non-generic method. var method = type.GetMember<MethodSymbol>("M1"); CheckExtensionMethod(method, ImmutableArray.Create<TypeSymbol>(), "void object.M1()", "void S.M1(object o)", "void object.M1()", "void S.M1(object o)"); // Generic method, one type argument. method = type.GetMember<MethodSymbol>("M2"); CheckExtensionMethod(method, ImmutableArray.Create<TypeSymbol>(intType), "void IEnumerable<int>.M2<int>()", "void S.M2<T>(IEnumerable<T> t)", "void IEnumerable<T>.M2<T>()", "void S.M2<T>(IEnumerable<T> t)"); // Generic method, multiple type arguments. method = type.GetMember<MethodSymbol>("M3"); CheckExtensionMethod(method, ImmutableArray.Create<TypeSymbol>(intType, arrayType), "void string[].M3<int, string[]>(IEnumerable<int> t)", "void S.M3<T, U>(U u, IEnumerable<T> t)", "void U.M3<T, U>(IEnumerable<T> t)", "void S.M3<T, U>(U u, IEnumerable<T> t)"); }; CompileAndVerify(compilation, emitOptions: TestEmitters.CCI, sourceSymbolValidator: validator, symbolValidator: validator); }
private void EmitArrayElementStore(ArrayTypeSymbol arrayType, CSharpSyntaxNode syntaxNode) { if (arrayType.Rank == 1) { EmitVectorElementStore(arrayType, syntaxNode); } else { builder.EmitArrayElementStore(Emit.PEModuleBuilder.Translate(arrayType), syntaxNode, diagnostics); } }
public virtual void VisitArrayType(ArrayTypeSymbol symbol) { DefaultVisit(symbol); }
private ArrayTypeSymbol SubstituteArrayType(ArrayTypeSymbol t) { var oldElement = new TypeWithModifiers(t.ElementType, t.CustomModifiers); TypeWithModifiers element = oldElement.SubstituteType(this); if (element == oldElement) { return t; } ImmutableArray<NamedTypeSymbol> interfaces = t.InterfacesNoUseSiteDiagnostics(); Debug.Assert(0 <= interfaces.Length && interfaces.Length <= 2); if (interfaces.Length == 1) { Debug.Assert(interfaces[0] is NamedTypeSymbol); // IList<T> interfaces = ImmutableArray.Create<NamedTypeSymbol>((NamedTypeSymbol)SubstituteType(interfaces[0]).AsTypeSymbolOnly()); } else if (interfaces.Length == 2) { Debug.Assert(interfaces[0] is NamedTypeSymbol); // IList<T> interfaces = ImmutableArray.Create<NamedTypeSymbol>((NamedTypeSymbol)SubstituteType(interfaces[0]).AsTypeSymbolOnly(), (NamedTypeSymbol)SubstituteType(interfaces[1]).AsTypeSymbolOnly()); } else if (interfaces.Length != 0) { throw ExceptionUtilities.Unreachable; } return new ArrayTypeSymbol( element.Type, t.Rank, t.BaseTypeNoUseSiteDiagnostics, interfaces, element.CustomModifiers); }
private ArrayTypeSymbol TransformArrayType(ArrayTypeSymbol arrayType) { var flag = ConsumeFlag(); Debug.Assert(!flag); if (!HandleCustomModifiers(arrayType.CustomModifiers.Length)) { return null; } TypeSymbol transformedElementType = TransformType(arrayType.ElementType); if ((object)transformedElementType == null) { return null; } return transformedElementType == arrayType.ElementType ? arrayType : new ArrayTypeSymbol(_containingAssembly, transformedElementType, arrayType.CustomModifiers, arrayType.Rank); }
public void TestFieldDynamicTransforms() { CommonTestInitialization(); //public static dynamic field1; var field1 = _derivedClass.GetMember<FieldSymbol>("field1"); Assert.Equal(s_dynamicType, field1.Type); //public static dynamic[] field2; var field2 = _derivedClass.GetMember<FieldSymbol>("field2"); var arrayOfDynamic = new ArrayTypeSymbol(_assembly, s_dynamicType, ImmutableArray.Create<CustomModifier>(), 1); Assert.Equal(arrayOfDynamic, field2.Type); //public static dynamic[][] field3; var field3 = _derivedClass.GetMember<FieldSymbol>("field3"); var arrayOfArrayOfDynamic = new ArrayTypeSymbol(_assembly, arrayOfDynamic, ImmutableArray.Create<CustomModifier>(), 1); Assert.Equal(arrayOfArrayOfDynamic, field3.Type); //public const dynamic field4 = null; var field4 = _derivedClass.GetMember<FieldSymbol>("field4"); Assert.Equal(s_dynamicType, field4.Type); //public const dynamic[] field5 = null; var field5 = _derivedClass.GetMember<FieldSymbol>("field5"); Assert.Equal(arrayOfDynamic, field5.Type); //public const dynamic[][] field6 = null; var field6 = _derivedClass.GetMember<FieldSymbol>("field6"); Assert.Equal(arrayOfArrayOfDynamic, field6.Type); //public const dynamic[][] field7 = null; var field7 = _derivedClass.GetMember<FieldSymbol>("field7"); Assert.Equal(arrayOfArrayOfDynamic, field7.Type); //public Outer<T>.Inner<int, T>.InnerInner<Outer<dynamic>> field8 = null; var field8 = _derivedClass.GetMember<FieldSymbol>("field8"); var derivedTypeParam = _derivedClass.TypeParameters[0]; var outerOfT = _outerClass.Construct(derivedTypeParam); var innerOfIntOfTWithOuterT = outerOfT.GetTypeMember("Inner").Construct(_intType, derivedTypeParam); // Outer<dynamic> var outerClassOfDynamic = _outerClass.Construct(s_dynamicType); var complicatedInnerInner = innerOfIntOfTWithOuterT.GetTypeMember("InnerInner").Construct(outerClassOfDynamic); Assert.Equal(complicatedInnerInner, field8.Type); //public Outer<dynamic>.Inner<T, T>.InnerInner<T> field9 = null; var field9 = _derivedClass.GetMember<FieldSymbol>("field9"); var innerOfTTWithOuterOfDynamic = outerClassOfDynamic.GetTypeMember("Inner").Construct(derivedTypeParam, derivedTypeParam); complicatedInnerInner = innerOfTTWithOuterOfDynamic.GetTypeMember("InnerInner").Construct(derivedTypeParam); Assert.Equal(complicatedInnerInner, field9.Type); //public Outer<Outer<dynamic>.Inner<T, dynamic>>.Inner<dynamic, T>.InnerInner<T> field10 = null; var field10 = _derivedClass.GetMember<FieldSymbol>("field10"); // Outer<dynamic>.Inner<T, dynamic> var innerOfTDynamicWithOuterOfDynamic = outerClassOfDynamic.GetTypeMember("Inner").Construct(derivedTypeParam, s_dynamicType); // Outer<Outer<dynamic>.Inner<T, dynamic>> var complicatedOuter = _outerClass.Construct(innerOfTDynamicWithOuterOfDynamic); // Outer<Outer<dynamic>.Inner<T, dynamic>>.Inner<dynamic, T> var complicatedInner = complicatedOuter.GetTypeMember("Inner").Construct(s_dynamicType, derivedTypeParam); complicatedInnerInner = complicatedInner.GetTypeMember("InnerInner").Construct(derivedTypeParam); Assert.Equal(complicatedInnerInner, field10.Type); //public Outer<T>.Inner<dynamic, dynamic>.InnerInner<T> field11 = null; var field11 = _derivedClass.GetMember<FieldSymbol>("field11"); // Outer<T>.Inner<dynamic, dynamic> var innerOfDynamicDynamicWithOuterOfT = outerOfT.GetTypeMember("Inner").Construct(s_dynamicType, s_dynamicType); complicatedInnerInner = innerOfDynamicDynamicWithOuterOfT.GetTypeMember("InnerInner").Construct(derivedTypeParam); Assert.Equal(complicatedInnerInner, field11.Type); //public Outer<T>.Inner<T, T>.InnerInner<Outer<dynamic>.Inner<T, dynamic>.InnerInner<int>> field12 = null; var field12 = _derivedClass.GetMember<FieldSymbol>("field12"); // Outer<T>.Inner<T, T> var innerOfTTWithOuterOfT = outerOfT.GetTypeMember("Inner").Construct(derivedTypeParam, derivedTypeParam); // Outer<dynamic>.Inner<T, dynamic>.InnerInner<int> complicatedInnerInner = innerOfTDynamicWithOuterOfDynamic.GetTypeMember("InnerInner").Construct(_intType); complicatedInnerInner = innerOfTTWithOuterOfT.GetTypeMember("InnerInner").Construct(complicatedInnerInner); Assert.Equal(complicatedInnerInner, field12.Type); //public Outer<dynamic>.Inner<Outer<T>, T>.InnerInner<dynamic> field13 = null; var field13 = _derivedClass.GetMember<FieldSymbol>("field13"); // Outer<dynamic>.Inner<Outer<T>, T> var innerOfOuterOfTTWithOuterDynamic = outerClassOfDynamic.GetTypeMember("Inner").Construct(outerOfT, derivedTypeParam); complicatedInnerInner = innerOfOuterOfTTWithOuterDynamic.GetTypeMember("InnerInner").Construct(s_dynamicType); Assert.Equal(complicatedInnerInner, field13.Type); //public Outer<dynamic>.Inner<dynamic, dynamic>.InnerInner<dynamic> field14 = null; var field14 = _derivedClass.GetMember<FieldSymbol>("field14"); // Outer<dynamic>.Inner<dynamic, dynamic> var innerOfDynamicDynamicWithOuterOfDynamic = outerClassOfDynamic.GetTypeMember("Inner").Construct(s_dynamicType, s_dynamicType); complicatedInnerInner = innerOfDynamicDynamicWithOuterOfDynamic.GetTypeMember("InnerInner").Construct(s_dynamicType); Assert.Equal(complicatedInnerInner, field14.Type); //public Outer<dynamic>.Inner<Outer<dynamic>, T>.InnerInner<dynamic>[] field15 = null; var field15 = _derivedClass.GetMember<FieldSymbol>("field15"); // Outer<dynamic>.Inner<Outer<dynamic>, T> var innerOfOuterOfDynamicTWithOuterDynamic = outerClassOfDynamic.GetTypeMember("Inner").Construct(outerClassOfDynamic, derivedTypeParam); // Outer<dynamic>.Inner<Outer<dynamic>, T>.InnerInner<dynamic> complicatedInnerInner = innerOfOuterOfDynamicTWithOuterDynamic.GetTypeMember("InnerInner").Construct(s_dynamicType); var complicatedInnerInnerArray = new ArrayTypeSymbol(_assembly, complicatedInnerInner, ImmutableArray.Create<CustomModifier>(), 1); Assert.Equal(complicatedInnerInnerArray, field15.Type); //public Outer<dynamic>.Inner<Outer<dynamic>.Inner<T, dynamic.InnerInner<int>, dynamic[]>.InnerInner<dynamic>[][] field16 = null; var field16 = _derivedClass.GetMember<FieldSymbol>("field16"); // Outer<dynamic>.Inner<T, dynamic>.InnerInner<int> complicatedInnerInner = innerOfTDynamicWithOuterOfDynamic.GetTypeMember("InnerInner").Construct(_intType); // Outer<dynamic>.Inner<Outer<dynamic>.Inner<T, dynamic>.InnerInner<int>, dynamic[]> complicatedInner = outerClassOfDynamic.GetTypeMember("Inner").Construct(complicatedInnerInner, arrayOfDynamic); // Outer<dynamic>.Inner<Outer<dynamic>.Inner<T, dynamic>.InnerInner<int>, dynamic[]>.InnerInner<dynamic> complicatedInnerInner = complicatedInner.GetTypeMember("InnerInner").Construct(s_dynamicType); complicatedInnerInnerArray = new ArrayTypeSymbol(_assembly, complicatedInnerInner, ImmutableArray.Create<CustomModifier>(), 1); var complicatedInnerInnerArrayOfArray = new ArrayTypeSymbol(_assembly, complicatedInnerInnerArray, ImmutableArray.Create<CustomModifier>(), 1); Assert.Equal(complicatedInnerInnerArrayOfArray, field16.Type); //public static Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int>[], dynamic>.InnerInner<dynamic>[][] field17 = null; var field17 = _derivedClass.GetMember<FieldSymbol>("field17"); // T[] var arrayOfDerivedTypeParam = new ArrayTypeSymbol(_assembly, derivedTypeParam, ImmutableArray.Create<CustomModifier>(), 1); // Outer<dynamic>.Inner<T[], dynamic> complicatedInner = outerClassOfDynamic.GetTypeMember("Inner").Construct(arrayOfDerivedTypeParam, s_dynamicType); // Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int> complicatedInnerInner = complicatedInner.GetTypeMember("InnerInner").Construct(_intType); // Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int>[] complicatedInnerInnerArray = new ArrayTypeSymbol(_assembly, complicatedInnerInner, ImmutableArray.Create<CustomModifier>(), 1); // Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int>[], dynamic> complicatedInner = outerClassOfDynamic.GetTypeMember("Inner").Construct(complicatedInnerInnerArray, s_dynamicType); // Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int>[], dynamic>.InnerInner<dynamic> complicatedInnerInner = complicatedInner.GetTypeMember("InnerInner").Construct(s_dynamicType); // Outer<dynamic>.Inner<Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int>[], dynamic>.InnerInner<dynamic>[][] complicatedInnerInnerArray = new ArrayTypeSymbol(_assembly, complicatedInnerInner, ImmutableArray.Create<CustomModifier>(), 1); complicatedInnerInnerArrayOfArray = new ArrayTypeSymbol(_assembly, complicatedInnerInnerArray, ImmutableArray.Create<CustomModifier>(), 1); Assert.Equal(complicatedInnerInnerArrayOfArray, field17.Type); //public static Outer3.Inner3<dynamic> field1 = null; field1 = _inner3Class.GetMember<FieldSymbol>("field1"); var inner3OfDynamic = _inner3Class.Construct(s_dynamicType); Assert.Equal(inner3OfDynamic, field1.Type); }
/// <summary> /// Emit an element store instruction for a single dimensional array. /// </summary> private void EmitVectorElementStore(ArrayTypeSymbol arrayType, SyntaxNode syntaxNode) { var elementType = arrayType.ElementType; if (elementType.IsEnumType()) { //underlying primitives do not need type tokens. elementType = ((NamedTypeSymbol)elementType).EnumUnderlyingType; } switch (elementType.PrimitiveTypeCode) { case Microsoft.Cci.PrimitiveTypeCode.Boolean: case Microsoft.Cci.PrimitiveTypeCode.Int8: case Microsoft.Cci.PrimitiveTypeCode.UInt8: _builder.EmitOpCode(ILOpCode.Stelem_i1); break; case Microsoft.Cci.PrimitiveTypeCode.Char: case Microsoft.Cci.PrimitiveTypeCode.Int16: case Microsoft.Cci.PrimitiveTypeCode.UInt16: _builder.EmitOpCode(ILOpCode.Stelem_i2); break; case Microsoft.Cci.PrimitiveTypeCode.Int32: case Microsoft.Cci.PrimitiveTypeCode.UInt32: _builder.EmitOpCode(ILOpCode.Stelem_i4); break; case Microsoft.Cci.PrimitiveTypeCode.Int64: case Microsoft.Cci.PrimitiveTypeCode.UInt64: _builder.EmitOpCode(ILOpCode.Stelem_i8); break; case Microsoft.Cci.PrimitiveTypeCode.IntPtr: case Microsoft.Cci.PrimitiveTypeCode.UIntPtr: case Microsoft.Cci.PrimitiveTypeCode.Pointer: _builder.EmitOpCode(ILOpCode.Stelem_i); break; case Microsoft.Cci.PrimitiveTypeCode.Float32: _builder.EmitOpCode(ILOpCode.Stelem_r4); break; case Microsoft.Cci.PrimitiveTypeCode.Float64: _builder.EmitOpCode(ILOpCode.Stelem_r8); break; default: if (elementType.IsVerifierReference()) { _builder.EmitOpCode(ILOpCode.Stelem_ref); } else { _builder.EmitOpCode(ILOpCode.Stelem); EmitSymbolToken(elementType, syntaxNode); } break; } }
private ArrayTypeSymbol TransformArrayType(ArrayTypeSymbol arrayType) { Debug.Assert(!dynamicTransformFlags[index]); index++; if (!HandleCustomModifiers(arrayType.CustomModifiers.Length)) { return null; } TypeSymbol transformedElementType = TransformType(arrayType.ElementType); if ((object)transformedElementType == null) { return null; } return transformedElementType == arrayType.ElementType ? arrayType : new ArrayTypeSymbol(containingAssembly, transformedElementType, arrayType.CustomModifiers, arrayType.Rank); }