Exemple #1
0
        public void TypeMap()
        {
            var source = @"
struct S<T> where T : struct
{
}
";

            var comp = CreateCompilation(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   = ArrayTypeSymbol.CreateCSharpArray(comp.Assembly, typeParamType, customModifiers); // This is legal, but we're already manually constructing types.

            var typeMap = new TypeMap(ImmutableArray.Create(typeParamType), ImmutableArray.Create(new TypeWithModifiers(intType)));

            var substitutedPointerType = (PointerTypeSymbol)typeMap.SubstituteType(pointerType).AsTypeSymbolOnly();
            var substitutedArrayType   = (ArrayTypeSymbol)typeMap.SubstituteType(arrayType).AsTypeSymbolOnly();

            // 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);
        }
Exemple #2
0
        public void TestArrayType()
        {
            CSharpCompilation compilation = CSharpCompilation.Create("Test");

            NamedTypeSymbol elementType = new MockNamedTypeSymbol("TestClass", Enumerable.Empty <Symbol>());   // this can be any type.

            ArrayTypeSymbol ats1 = ArrayTypeSymbol.CreateCSharpArray(compilation.Assembly, elementType, rank: 1);

            Assert.Equal(1, ats1.Rank);
            Assert.True(ats1.IsSZArray);
            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 = ArrayTypeSymbol.CreateCSharpArray(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 = ArrayTypeSymbol.CreateCSharpArray(compilation.Assembly, elementType, rank: 3);

            Assert.Equal(3, ats3.Rank);
            Assert.Equal("TestClass[,,]", ats3.ToTestDisplayString());
        }
        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.
            SyntaxNode syntax = MethodDeclarationIfAvailable(methodBody.Syntax);

            if (!method.IsImplicitlyDeclared)
            {
                _methodEntryInstrumentation = AddAnalysisPoint(syntax, SkipAttributes(syntax), methodBodyFactory);
            }
        }
        private DynamicAnalysisInjector(
            MethodSymbol method,
            BoundStatement methodBody,
            SyntheticBoundNodeFactory methodBodyFactory,
            MethodSymbol createPayloadForMethodsSpanningSingleFile,
            MethodSymbol createPayloadForMethodsSpanningMultipleFiles,
            BindingDiagnosticBag diagnostics,
            DebugDocumentProvider debugDocumentProvider,
            Instrumenter previous
            ) : base(previous)
        {
            _createPayloadForMethodsSpanningSingleFile    = createPayloadForMethodsSpanningSingleFile;
            _createPayloadForMethodsSpanningMultipleFiles =
                createPayloadForMethodsSpanningMultipleFiles;
            _method       = method;
            _methodBody   = methodBody;
            _spansBuilder = ArrayBuilder <SourceSpan> .GetInstance();

            TypeSymbol payloadElementType = methodBodyFactory.SpecialType(
                SpecialType.System_Boolean
                );

            _payloadType = ArrayTypeSymbol.CreateCSharpArray(
                methodBodyFactory.Compilation.Assembly,
                TypeWithAnnotations.Create(payloadElementType)
                );
            _diagnostics           = diagnostics;
            _debugDocumentProvider = debugDocumentProvider;
            _methodBodyFactory     = methodBodyFactory;

            // Set the factory context to generate nodes for the current method
            var oldMethod = methodBodyFactory.CurrentFunction;

            methodBodyFactory.CurrentFunction = method;

            _methodPayload = methodBodyFactory.SynthesizedLocal(
                _payloadType,
                kind: SynthesizedLocalKind.InstrumentationPayload,
                syntax: methodBody.Syntax
                );
            // The first point indicates entry into the method and has the span of the method definition.
            SyntaxNode syntax = MethodDeclarationIfAvailable(methodBody.Syntax);

            if (
                !method.IsImplicitlyDeclared &&
                !(method is SynthesizedSimpleProgramEntryPointSymbol)
                )
            {
                _methodEntryInstrumentation = AddAnalysisPoint(
                    syntax,
                    SkipAttributes(syntax),
                    methodBodyFactory
                    );
            }

            // Restore context
            methodBodyFactory.CurrentFunction = oldMethod;
        }
        public override BoundStatement CreateBlockPrologue(BoundBlock original, out LocalSymbol synthesizedLocal)
        {
            BoundStatement previousPrologue = base.CreateBlockPrologue(original, out synthesizedLocal);

            if (_methodBody == original)
            {
                _dynamicAnalysisSpans = _spansBuilder.ToImmutableAndFree();
                // In the future there will be multiple analysis kinds.
                const int analysisKind = 0;

                ArrayTypeSymbol modulePayloadType = ArrayTypeSymbol.CreateCSharpArray(_methodBodyFactory.Compilation.Assembly, _payloadType);

                // Synthesize the initialization of the instrumentation payload array, using concurrency-safe code:
                //
                // var payload = PID.PayloadRootField[methodIndex];
                // if (payload == null)
                //     payload = Instrumentation.CreatePayload(mvid, methodIndex, fileIndex, ref PID.PayloadRootField[methodIndex], payloadLength);

                BoundStatement  payloadInitialization = _methodBodyFactory.Assignment(_methodBodyFactory.Local(_methodPayload), _methodBodyFactory.ArrayAccess(_methodBodyFactory.InstrumentationPayloadRoot(analysisKind, modulePayloadType), ImmutableArray.Create(_methodBodyFactory.MethodDefIndex(_method))));
                BoundExpression mvid              = _methodBodyFactory.ModuleVersionId();
                BoundExpression methodToken       = _methodBodyFactory.MethodDefIndex(_method);
                BoundExpression fileIndex         = _methodBodyFactory.SourceDocumentIndex(GetSourceDocument(_methodBody.Syntax));
                BoundExpression payloadSlot       = _methodBodyFactory.ArrayAccess(_methodBodyFactory.InstrumentationPayloadRoot(analysisKind, modulePayloadType), ImmutableArray.Create(_methodBodyFactory.MethodDefIndex(_method)));
                BoundStatement  createPayloadCall = _methodBodyFactory.Assignment(_methodBodyFactory.Local(_methodPayload), _methodBodyFactory.Call(null, _createPayload, mvid, methodToken, fileIndex, payloadSlot, _methodBodyFactory.Literal(_dynamicAnalysisSpans.Length)));

                BoundExpression payloadNullTest = _methodBodyFactory.Binary(BinaryOperatorKind.ObjectEqual, _methodBodyFactory.SpecialType(SpecialType.System_Boolean), _methodBodyFactory.Local(_methodPayload), _methodBodyFactory.Null(_payloadType));
                BoundStatement  payloadIf       = _methodBodyFactory.If(payloadNullTest, createPayloadCall);

                Debug.Assert(synthesizedLocal == null);
                synthesizedLocal = _methodPayload;

                ArrayBuilder <BoundStatement> prologueStatements = ArrayBuilder <BoundStatement> .GetInstance(previousPrologue == null? 3 : 4);

                prologueStatements.Add(payloadInitialization);
                prologueStatements.Add(payloadIf);
                if (_methodEntryInstrumentation != null)
                {
                    prologueStatements.Add(_methodEntryInstrumentation);
                }

                if (previousPrologue != null)
                {
                    prologueStatements.Add(previousPrologue);
                }

                return(_methodBodyFactory.StatementList(prologueStatements.ToImmutableAndFree()));
            }

            return(previousPrologue);
        }
        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 = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(unsafeClassTypeParam), 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(TypeWithAnnotations.Create(_intType));
            var arrayOfPointerToInt = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(pointerToInt), 1);
            // int*[][]
            var arrayOfArrayOfPointerToInt = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(arrayOfPointerToInt), 1);
            // Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int*[][]>
            var complicatedInnerInner = complicatedInner.GetTypeMember("InnerInner").Construct(arrayOfArrayOfPointerToInt);
            // Outer<dynamic>.Inner<T[], dynamic>.InnerInner<int*[][]>[]
            var complicatedInnerInnerArray = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(complicatedInnerInner), 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 = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(complicatedInnerInner), 1);
            var complicatedInnerInnerArrayOfArray = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(complicatedInnerInnerArray), 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());
        }
Exemple #7
0
 protected override IArrayTypeSymbol CommonCreateArrayTypeSymbol(ITypeSymbol elementType, int rank)
 {
     return(ArrayTypeSymbol.CreateCSharpArray(SourceAssembly, (TypeSymbol)elementType, rank: rank));
 }
        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 = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(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 = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(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());
        }
        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.GetParameterType(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.GetParameterType(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 = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(s_dynamicType));

            Assert.Equal(arrayOfDynamic, f3.ReturnType);
            Assert.Equal(arrayOfDynamic, f3.GetParameterType(0));
            Assert.Equal(RefKind.None, f3.Parameters[0].RefKind);

            var derivedTypeParam        = _derivedClass.TypeParameters[0];
            var arrayOfDerivedTypeParam = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(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 = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(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 = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(complicatedInnerInner));
            var complicatedInnerInnerArrayOfArray = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(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.GetParameterType(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.GetParameterType(0));
        }
        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 = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(s_dynamicType), 1);

            Assert.Equal(arrayOfDynamic, field2.Type);

            //public static dynamic[][] field3;
            var field3 = _derivedClass.GetMember <FieldSymbol>("field3");
            var arrayOfArrayOfDynamic = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(arrayOfDynamic), 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 = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(complicatedInnerInner), 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 = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(complicatedInnerInner), 1);
            var complicatedInnerInnerArrayOfArray = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(complicatedInnerInnerArray), 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 = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(derivedTypeParam), 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 = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(complicatedInnerInner), 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        = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(complicatedInnerInner), 1);
            complicatedInnerInnerArrayOfArray = ArrayTypeSymbol.CreateCSharpArray(_assembly, TypeWithAnnotations.Create(complicatedInnerInnerArray), 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);
        }