コード例 #1
0
        public override IEntity VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data)
        {
            var td = currentTypeDefinition = CreateTypeDefinition(typeDeclaration.Name);

            td.ClassType  = typeDeclaration.ClassType;
            td.Region     = MakeRegion(typeDeclaration);
            td.BodyRegion = MakeBraceRegion(typeDeclaration);
            td.AddDefaultConstructorIfRequired = true;

            ConvertAttributes(td.Attributes, typeDeclaration.Attributes);
            ApplyModifiers(td, typeDeclaration.Modifiers);
            if (td.ClassType == ClassType.Interface)
            {
                td.IsAbstract = true;                 // interfaces are implicitly abstract
            }
            else if (td.ClassType == ClassType.Enum || td.ClassType == ClassType.Struct)
            {
                td.IsSealed = true;                 // enums/structs are implicitly sealed
            }
            ConvertTypeParameters(td.TypeParameters, typeDeclaration.TypeParameters, typeDeclaration.Constraints);

            foreach (AstType baseType in typeDeclaration.BaseTypes)
            {
                td.BaseTypes.Add(ConvertType(baseType));
            }

            foreach (AttributedNode member in typeDeclaration.Members)
            {
                member.AcceptVisitor(this, data);
            }

            currentTypeDefinition = (DefaultTypeDefinition)currentTypeDefinition.DeclaringTypeDefinition;
            return(td);
        }
コード例 #2
0
 static void ApplyModifiers(DefaultTypeDefinition td, Modifiers modifiers)
 {
     td.Accessibility = GetAccessibility(modifiers) ?? (td.DeclaringTypeDefinition != null ? Accessibility.Private : Accessibility.Internal);
     td.IsAbstract    = (modifiers & (Modifiers.Abstract | Modifiers.Static)) != 0;
     td.IsSealed      = (modifiers & (Modifiers.Sealed | Modifiers.Static)) != 0;
     td.IsShadowing   = (modifiers & Modifiers.New) != 0;
 }
コード例 #3
0
        private MinimalResolveContext()
        {
            List <ITypeDefinition> types = new List <ITypeDefinition>();

            types.Add(systemObject    = new DefaultTypeDefinition(this, "System", "Object"));
            types.Add(systemValueType = new DefaultTypeDefinition(this, "System", "ValueType")
            {
                BaseTypes = { systemObject }
            });
            types.Add(CreateStruct("System", "Boolean"));
            types.Add(CreateStruct("System", "SByte"));
            types.Add(CreateStruct("System", "Byte"));
            types.Add(CreateStruct("System", "Int16"));
            types.Add(CreateStruct("System", "UInt16"));
            types.Add(CreateStruct("System", "Int32"));
            types.Add(CreateStruct("System", "UInt32"));
            types.Add(CreateStruct("System", "Int64"));
            types.Add(CreateStruct("System", "UInt64"));
            types.Add(CreateStruct("System", "Single"));
            types.Add(CreateStruct("System", "Double"));
            types.Add(CreateStruct("System", "Decimal"));
            types.Add(new DefaultTypeDefinition(this, "System", "String")
            {
                BaseTypes = { systemObject }
            });
            foreach (ITypeDefinition type in types)
            {
                type.Freeze();
            }
            this.types = types.AsReadOnly();
        }
コード例 #4
0
        public override IEntity VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration, object data)
        {
            var td = currentTypeDefinition = CreateTypeDefinition(delegateDeclaration.Name);

            td.ClassType = ClassType.Delegate;
            td.Region    = MakeRegion(delegateDeclaration);
            td.BaseTypes.Add(multicastDelegateReference);

            ApplyModifiers(td, delegateDeclaration.Modifiers);
            td.IsSealed = true;             // delegates are implicitly sealed

            ConvertTypeParameters(td.TypeParameters, delegateDeclaration.TypeParameters, delegateDeclaration.Constraints);

            ITypeReference    returnType = ConvertType(delegateDeclaration.ReturnType);
            List <IParameter> parameters = new List <IParameter>();

            ConvertParameters(parameters, delegateDeclaration.Parameters);
            AddDefaultMethodsToDelegate(td, returnType, parameters);

            foreach (AttributeSection section in delegateDeclaration.Attributes)
            {
                if (section.AttributeTarget == "return")
                {
                    ConvertAttributes(td.Methods.Single(m => m.Name == "Invoke").ReturnTypeAttributes, section);
                    ConvertAttributes(td.Methods.Single(m => m.Name == "EndInvoke").ReturnTypeAttributes, section);
                }
                else
                {
                    ConvertAttributes(td.Attributes, section);
                }
            }

            currentTypeDefinition = (DefaultTypeDefinition)currentTypeDefinition.DeclaringTypeDefinition;
            return(td);
        }
コード例 #5
0
		private MinimalResolveContext()
		{
			List<ITypeDefinition> types = new List<ITypeDefinition>();
			types.Add(systemObject = new DefaultTypeDefinition(this, "System", "Object") {
			          	Accessibility = Accessibility.Public
			          });
			types.Add(systemValueType = new DefaultTypeDefinition(this, "System", "ValueType") {
			          	Accessibility = Accessibility.Public,
			          	BaseTypes = { systemObject }
			          });
			types.Add(CreateStruct("System", "Boolean"));
			types.Add(CreateStruct("System", "SByte"));
			types.Add(CreateStruct("System", "Byte"));
			types.Add(CreateStruct("System", "Int16"));
			types.Add(CreateStruct("System", "UInt16"));
			types.Add(CreateStruct("System", "Int32"));
			types.Add(CreateStruct("System", "UInt32"));
			types.Add(CreateStruct("System", "Int64"));
			types.Add(CreateStruct("System", "UInt64"));
			types.Add(CreateStruct("System", "Single"));
			types.Add(CreateStruct("System", "Double"));
			types.Add(CreateStruct("System", "Decimal"));
			types.Add(new DefaultTypeDefinition(this, "System", "String") {
			          	Accessibility = Accessibility.Public,
			          	BaseTypes = { systemObject }
			          });
			types.Add(new VoidTypeDefinition(this));
			foreach (ITypeDefinition type in types)
				type.Freeze();
			this.types = types.AsReadOnly();
		}
コード例 #6
0
		public void ClassDerivingFromItself()
		{
			// class C : C {}
			DefaultTypeDefinition c = new DefaultTypeDefinition(mscorlib, string.Empty, "C");
			c.BaseTypes.Add(c);
			Assert.AreEqual(new [] { c }, c.GetAllBaseTypes(context).ToArray());
		}
コード例 #7
0
ファイル: GetAllBaseTypesTest.cs プロジェクト: shalang/ILSpy
        public void ClassDerivingFromItself()
        {
            // class C : C {}
            DefaultTypeDefinition c = new DefaultTypeDefinition(mscorlib, string.Empty, "C");

            c.BaseTypes.Add(c);
            Assert.AreEqual(new [] { c }, c.GetAllBaseTypes(context).ToArray());
        }
コード例 #8
0
		public void ClassDerivingFromParameterizedVersionOfItself()
		{
			// class C<X> : C<C<X>> {}
			DefaultTypeDefinition c = new DefaultTypeDefinition(mscorlib, string.Empty, "C");
			c.TypeParameters.Add(new DefaultTypeParameter(EntityType.TypeDefinition, 0, "X"));
			c.BaseTypes.Add(new ParameterizedType(c, new [] { new ParameterizedType(c, new [] { c.TypeParameters[0] }) }));
			Assert.AreEqual(new [] { c }, c.GetAllBaseTypes(context).ToArray());
		}
コード例 #9
0
ファイル: GetAllBaseTypesTest.cs プロジェクト: shalang/ILSpy
        public void ClassDerivingFromParameterizedVersionOfItself()
        {
            // class C<X> : C<C<X>> {}
            DefaultTypeDefinition c = new DefaultTypeDefinition(mscorlib, string.Empty, "C");

            c.TypeParameters.Add(new DefaultTypeParameter(EntityType.TypeDefinition, 0, "X"));
            c.BaseTypes.Add(new ParameterizedType(c, new [] { new ParameterizedType(c, new [] { c.TypeParameters[0] }) }));
            Assert.AreEqual(new [] { c }, c.GetAllBaseTypes(context).ToArray());
        }
コード例 #10
0
        /// <summary>
        /// Adds the 'Invoke', 'BeginInvoke', 'EndInvoke' methods, and a constructor, to the <paramref name="delegateType"/>.
        /// </summary>
        public static void AddDefaultMethodsToDelegate(DefaultTypeDefinition delegateType, ITypeReference returnType, IEnumerable <IParameter> parameters)
        {
            if (delegateType == null)
            {
                throw new ArgumentNullException("delegateType");
            }
            if (returnType == null)
            {
                throw new ArgumentNullException("returnType");
            }
            if (parameters == null)
            {
                throw new ArgumentNullException("parameters");
            }

            DomRegion region = new DomRegion(delegateType.Region.FileName, delegateType.Region.BeginLine, delegateType.Region.BeginColumn);

            DefaultMethod invoke = new DefaultMethod(delegateType, "Invoke");

            invoke.Accessibility = Accessibility.Public;
            invoke.IsSynthetic   = true;
            invoke.Parameters.AddRange(parameters);
            invoke.ReturnType = returnType;
            invoke.Region     = region;
            delegateType.Methods.Add(invoke);

            DefaultMethod beginInvoke = new DefaultMethod(delegateType, "BeginInvoke");

            beginInvoke.Accessibility = Accessibility.Public;
            beginInvoke.IsSynthetic   = true;
            beginInvoke.Parameters.AddRange(invoke.Parameters);
            beginInvoke.Parameters.Add(delegateAsyncCallbackParameter);
            beginInvoke.Parameters.Add(delegateObjectParameter);
            beginInvoke.ReturnType = delegateResultParameter.Type;
            beginInvoke.Region     = region;
            delegateType.Methods.Add(beginInvoke);

            DefaultMethod endInvoke = new DefaultMethod(delegateType, "EndInvoke");

            endInvoke.Accessibility = Accessibility.Public;
            endInvoke.IsSynthetic   = true;
            endInvoke.Parameters.Add(delegateResultParameter);
            endInvoke.ReturnType = invoke.ReturnType;
            endInvoke.Region     = region;
            delegateType.Methods.Add(endInvoke);

            DefaultMethod ctor = new DefaultMethod(delegateType, ".ctor");

            ctor.EntityType    = EntityType.Constructor;
            ctor.Accessibility = Accessibility.Public;
            ctor.IsSynthetic   = true;
            ctor.Parameters.Add(delegateObjectParameter);
            ctor.Parameters.Add(delegateIntPtrMethodParameter);
            ctor.ReturnType = delegateType;
            ctor.Region     = region;
            delegateType.Methods.Add(ctor);
        }
コード例 #11
0
		public void TwoClassesDerivingFromEachOther()
		{
			// class C1 : C2 {} class C2 : C1 {}
			DefaultTypeDefinition c1 = new DefaultTypeDefinition(mscorlib, string.Empty, "C1");
			DefaultTypeDefinition c2 = new DefaultTypeDefinition(mscorlib, string.Empty, "C2");
			c1.BaseTypes.Add(c2);
			c2.BaseTypes.Add(c1);
			Assert.AreEqual(new [] { c1, c2 }, c1.GetAllBaseTypes(context).ToArray());
		}
コード例 #12
0
ファイル: GetAllBaseTypesTest.cs プロジェクト: shalang/ILSpy
        public void TwoClassesDerivingFromEachOther()
        {
            // class C1 : C2 {} class C2 : C1 {}
            DefaultTypeDefinition c1 = new DefaultTypeDefinition(mscorlib, string.Empty, "C1");
            DefaultTypeDefinition c2 = new DefaultTypeDefinition(mscorlib, string.Empty, "C2");

            c1.BaseTypes.Add(c2);
            c2.BaseTypes.Add(c1);
            Assert.AreEqual(new [] { c2, c1 }, c1.GetAllBaseTypes(context).ToArray());
        }
コード例 #13
0
 /// <summary>
 /// Creates a new TypeSystemConvertVisitor and initializes it with a given context.
 /// </summary>
 /// <param name="parsedFile">The parsed file to which members should be added.</param>
 /// <param name="currentUsingScope">The current using scope.</param>
 /// <param name="currentTypeDefinition">The current type definition.</param>
 public TypeSystemConvertVisitor(ParsedFile parsedFile, UsingScope currentUsingScope = null, DefaultTypeDefinition currentTypeDefinition = null)
 {
     if (parsedFile == null)
     {
         throw new ArgumentNullException("parsedFile");
     }
     this.parsedFile            = parsedFile;
     this.usingScope            = currentUsingScope ?? parsedFile.RootUsingScope;
     this.currentTypeDefinition = currentTypeDefinition;
 }
コード例 #14
0
        // TODO: assembly attributes

        #region Type Definitions
        DefaultTypeDefinition CreateTypeDefinition(string name)
        {
            DefaultTypeDefinition newType;

            if (currentTypeDefinition != null)
            {
                newType = new DefaultTypeDefinition(currentTypeDefinition, name);
                currentTypeDefinition.InnerClasses.Add(newType);
            }
            else
            {
                newType = new DefaultTypeDefinition(usingScope.ProjectContent, usingScope.NamespaceName, name);
                parsedFile.TopLevelTypeDefinitions.Add(newType);
            }
            return(newType);
        }
コード例 #15
0
 public void ClassDerivingFromTwoInstanciationsOfIEnumerable()
 {
     // class C : IEnumerable<int>, IEnumerable<uint> {}
     DefaultTypeDefinition c = new DefaultTypeDefinition(mscorlib, string.Empty, "C");
     c.BaseTypes.Add(typeof(IEnumerable<int>).ToTypeReference());
     c.BaseTypes.Add(typeof(IEnumerable<uint>).ToTypeReference());
     IType[] expected = {
         c,
         c.BaseTypes[0].Resolve(context),
         c.BaseTypes[1].Resolve(context),
         mscorlib.GetClass(typeof(IEnumerable)),
         mscorlib.GetClass(typeof(object))
     };
     Assert.AreEqual(expected,
                     c.GetAllBaseTypes(context).OrderBy(t => t.ReflectionName).ToArray());
 }
コード例 #16
0
ファイル: GetAllBaseTypesTest.cs プロジェクト: shalang/ILSpy
        public void StructImplementingIEquatable()
        {
            // struct S : IEquatable<S> {}
            // don't use a Cecil-loaded struct for this test; we're testing the implicit addition of System.ValueType
            DefaultTypeDefinition s = new DefaultTypeDefinition(mscorlib, string.Empty, "S");

            s.Kind = TypeKind.Struct;
            s.BaseTypes.Add(new ParameterizedType(mscorlib.GetTypeDefinition(typeof(IEquatable <>)), new[] { s }));
            IType[] expected =
            {
                s,
                s.BaseTypes[0].Resolve(context),
                mscorlib.GetTypeDefinition(typeof(object)),
                mscorlib.GetTypeDefinition(typeof(ValueType))
            };
            Assert.AreEqual(expected,
                            s.GetAllBaseTypes(context).OrderBy(t => t.ReflectionName).ToArray());
        }
コード例 #17
0
ファイル: GetAllBaseTypesTest.cs プロジェクト: shalang/ILSpy
        public void ClassDerivingFromTwoInstanciationsOfIEnumerable()
        {
            // class C : IEnumerable<int>, IEnumerable<uint> {}
            DefaultTypeDefinition c = new DefaultTypeDefinition(mscorlib, string.Empty, "C");

            c.BaseTypes.Add(typeof(IEnumerable <int>).ToTypeReference());
            c.BaseTypes.Add(typeof(IEnumerable <uint>).ToTypeReference());
            IType[] expected =
            {
                c,
                c.BaseTypes[0].Resolve(context),
                c.BaseTypes[1].Resolve(context),
                mscorlib.GetTypeDefinition(typeof(IEnumerable)),
                mscorlib.GetTypeDefinition(typeof(object))
            };
            Assert.AreEqual(expected,
                            c.GetAllBaseTypes(context).OrderBy(t => t.ReflectionName).ToArray());
        }
コード例 #18
0
ファイル: GetMembersTests.cs プロジェクト: shalang/ILSpy
		public void MultipleInheritanceTest()
		{
			DefaultTypeDefinition b1 = new DefaultTypeDefinition(mscorlib, string.Empty, "B1");
			b1.Kind = TypeKind.Interface;
			b1.Properties.Add(new DefaultProperty(b1, "P1"));
			
			DefaultTypeDefinition b2 = new DefaultTypeDefinition(mscorlib, string.Empty, "B1");
			b2.Kind = TypeKind.Interface;
			b2.Properties.Add(new DefaultProperty(b1, "P2"));
			
			DefaultTypeDefinition c = new DefaultTypeDefinition(mscorlib, string.Empty, "C");
			c.Kind = TypeKind.Interface;
			c.BaseTypes.Add(b1);
			c.BaseTypes.Add(b2);
			
			Assert.AreEqual(new[] { "P1", "P2" }, c.GetProperties(mscorlib).Select(p => p.Name).ToArray());
			// Test that there's only one copy of ToString():
			Assert.AreEqual(1, c.GetMethods(mscorlib, m => m.Name == "ToString").Count());
		}
コード例 #19
0
        public void GetGenericNestedTypeOfBoundGenericClass()
        {
            // class A<X> { class B<Y> { } }
            DefaultTypeDefinition a = new DefaultTypeDefinition(mscorlib, string.Empty, "A");

            a.TypeParameters.Add(new DefaultTypeParameter(EntityType.TypeDefinition, 0, "X"));

            DefaultTypeDefinition b = new DefaultTypeDefinition(a, "B");

            b.TypeParameters.Add(a.TypeParameters[0]);
            b.TypeParameters.Add(new DefaultTypeParameter(EntityType.TypeDefinition, 1, "Y"));

            a.NestedTypes.Add(b);

            // A<> gets self-parameterized, B<> stays unbound
            Assert.AreEqual("A`1+B`1[[`0],[]]", a.GetNestedTypes(mscorlib).Single().ReflectionName);

            ParameterizedType pt = new ParameterizedType(a, new [] { KnownTypeReference.String.Resolve(mscorlib) });

            Assert.AreEqual("A`1+B`1[[System.String],[]]", pt.GetNestedTypes(mscorlib).Single().ReflectionName);
        }
コード例 #20
0
        public void MultipleInheritanceTest()
        {
            DefaultTypeDefinition b1 = new DefaultTypeDefinition(mscorlib, string.Empty, "B1");

            b1.Kind = TypeKind.Interface;
            b1.Properties.Add(new DefaultProperty(b1, "P1"));

            DefaultTypeDefinition b2 = new DefaultTypeDefinition(mscorlib, string.Empty, "B1");

            b2.Kind = TypeKind.Interface;
            b2.Properties.Add(new DefaultProperty(b1, "P2"));

            DefaultTypeDefinition c = new DefaultTypeDefinition(mscorlib, string.Empty, "C");

            c.Kind = TypeKind.Interface;
            c.BaseTypes.Add(b1);
            c.BaseTypes.Add(b2);

            Assert.AreEqual(new[] { "P1", "P2" }, c.GetProperties(mscorlib).Select(p => p.Name).ToArray());
            // Test that there's only one copy of ToString():
            Assert.AreEqual(1, c.GetMethods(mscorlib, m => m.Name == "ToString").Count());
        }
コード例 #21
0
        public void ExpansiveInheritance()
        {
            SimpleProjectContent  pc = new SimpleProjectContent();
            DefaultTypeDefinition a  = new DefaultTypeDefinition(pc, string.Empty, "A");
            DefaultTypeDefinition b  = new DefaultTypeDefinition(pc, string.Empty, "B");

            // interface A<in U>
            a.Kind = TypeKind.Interface;
            a.TypeParameters.Add(new DefaultTypeParameter(EntityType.TypeDefinition, 0, "U")
            {
                Variance = VarianceModifier.Contravariant
            });
            // interface B<X> : A<A<B<X>>> { }
            DefaultTypeParameter x = new DefaultTypeParameter(EntityType.TypeDefinition, 0, "X");

            b.TypeParameters.Add(x);
            b.BaseTypes.Add(new ParameterizedType(a, new[] { new ParameterizedType(a, new [] { new ParameterizedType(b, new [] { x }) }) }));

            IType type1 = new ParameterizedType(b, new[] { KnownTypeReference.Double.Resolve(ctx) });
            IType type2 = new ParameterizedType(a, new [] { new ParameterizedType(b, new[] { KnownTypeReference.String.Resolve(ctx) }) });

            Assert.IsFalse(conversions.ImplicitConversion(type1, type2));
        }
コード例 #22
0
		private MinimalResolveContext()
		{
			List<ITypeDefinition> types = new List<ITypeDefinition>();
			
			systemObject = new DefaultTypeDefinition(this, "System", "Object") {
				Accessibility = Accessibility.Public
			};
			systemValueType = new DefaultTypeDefinition(this, "System", "ValueType") {
				Accessibility = Accessibility.Public,
				BaseTypes = { systemObject }
			};
			// TypeCode.Empty = void
			types.Add(new VoidTypeDefinition(this));
			// types are added in the order they are defined in the TypeCode enum
			types.Add(systemObject);
			types.Add(CreateClass("System", "DBNull"));
			types.Add(CreateStruct("System", "Boolean"));
			types.Add(CreateStruct("System", "Char"));
			types.Add(CreateStruct("System", "SByte"));
			types.Add(CreateStruct("System", "Byte"));
			types.Add(CreateStruct("System", "Int16"));
			types.Add(CreateStruct("System", "UInt16"));
			types.Add(CreateStruct("System", "Int32"));
			types.Add(CreateStruct("System", "UInt32"));
			types.Add(CreateStruct("System", "Int64"));
			types.Add(CreateStruct("System", "UInt64"));
			types.Add(CreateStruct("System", "Single"));
			types.Add(CreateStruct("System", "Double"));
			types.Add(CreateStruct("System", "Decimal"));
			types.Add(CreateStruct("System", "DateTime"));
			types.Add(systemValueType); // misuse unused enum value (TypeCode)17 for System.ValueType
			types.Add(CreateClass("System", "String"));
			foreach (ITypeDefinition type in types)
				type.Freeze();
			this.types = types.AsReadOnly();
		}
コード例 #23
0
		public void ExpansiveInheritance()
		{
			SimpleProjectContent pc = new SimpleProjectContent();
			DefaultTypeDefinition a = new DefaultTypeDefinition(pc, string.Empty, "A");
			DefaultTypeDefinition b = new DefaultTypeDefinition(pc, string.Empty, "B");
			// interface A<in U>
			a.Kind = TypeKind.Interface;
			a.TypeParameters.Add(new DefaultTypeParameter(EntityType.TypeDefinition, 0, "U") { Variance = VarianceModifier.Contravariant });
			// interface B<X> : A<A<B<X>>> { }
			DefaultTypeParameter x = new DefaultTypeParameter(EntityType.TypeDefinition, 0, "X");
			b.TypeParameters.Add(x);
			b.BaseTypes.Add(new ParameterizedType(a, new[] { new ParameterizedType(a, new [] { new ParameterizedType(b, new [] { x }) } ) }));
			
			IType type1 = new ParameterizedType(b, new[] { KnownTypeReference.Double.Resolve(ctx) });
			IType type2 = new ParameterizedType(a, new [] { new ParameterizedType(b, new[] { KnownTypeReference.String.Resolve(ctx) }) });
			Assert.IsFalse(conversions.ImplicitConversion(type1, type2));
		}
コード例 #24
0
ファイル: GetMembersTests.cs プロジェクト: shalang/ILSpy
		public void EmptyClassHasToString()
		{
			DefaultTypeDefinition c = new DefaultTypeDefinition(mscorlib, string.Empty, "C");
			Assert.AreEqual("System.Object.ToString", c.GetMethods(mscorlib, m => m.Name == "ToString").Single().FullName);
		}
コード例 #25
0
		public void StructImplementingIEquatable()
		{
			// struct S : IEquatable<S> {}
			// don't use a Cecil-loaded struct for this test; we're testing the implicit addition of System.ValueType
			DefaultTypeDefinition s = new DefaultTypeDefinition(mscorlib, string.Empty, "S");
			s.ClassType = ClassType.Struct;
			s.BaseTypes.Add(new ParameterizedType(mscorlib.GetTypeDefinition(typeof(IEquatable<>)), new[] { s }));
			IType[] expected = {
				s,
				s.BaseTypes[0].Resolve(context),
				mscorlib.GetTypeDefinition(typeof(object)),
				mscorlib.GetTypeDefinition(typeof(ValueType))
			};
			Assert.AreEqual(expected,
			                s.GetAllBaseTypes(context).OrderBy(t => t.ReflectionName).ToArray());
		}
コード例 #26
0
        public void SkeetEvilOverloadResolution()
        {
            // http://msmvps.com/blogs/jon_skeet/archive/2010/11/02/evil-code-overload-resolution-workaround.aspx

            // static void Foo<T>(T? ignored = default(T?)) where T : struct
            var m1 = MakeMethod();
            m1.TypeParameters.Add(new DefaultTypeParameter(m1, 0, "T") { HasValueTypeConstraint = true });
            m1.Parameters.Add(MakeOptionalParameter(
                NullableType.Create(m1.TypeParameters[0], context),
                "ignored"
            ));

            // class ClassConstraint<T> where T : class {}
            DefaultTypeDefinition classConstraint = new DefaultTypeDefinition(dummyClass, "ClassConstraint");
            classConstraint.TypeParameters.Add(new DefaultTypeParameter(classConstraint, 0, "T") { HasReferenceTypeConstraint = true });

            // static void Foo<T>(ClassConstraint<T> ignored = default(ClassConstraint<T>))
            // where T : class
            var m2 = MakeMethod();
            m2.TypeParameters.Add(new DefaultTypeParameter(m2, 0, "T") { HasReferenceTypeConstraint = true });
            m2.Parameters.Add(MakeOptionalParameter(
                new ParameterizedType(classConstraint, new[] { m2.TypeParameters[0] }),
                "ignored"
            ));

            // static void Foo<T>()
            var m3 = MakeMethod();
            m3.TypeParameters.Add(new DefaultTypeParameter(m3, 0, "T"));

            // Call: Foo<int>();
            OverloadResolution o;
            o = new OverloadResolution(context, new ResolveResult[0], typeArguments: new[] { typeof(int).ToTypeReference().Resolve(context) });
            Assert.AreEqual(OverloadResolutionErrors.None, o.AddCandidate(m1));
            Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(m2));
            Assert.AreSame(m1, o.BestCandidate);

            // Call: Foo<string>();
            o = new OverloadResolution(context, new ResolveResult[0], typeArguments: new[] { typeof(string).ToTypeReference().Resolve(context) });
            Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(m1));
            Assert.AreEqual(OverloadResolutionErrors.None, o.AddCandidate(m2));
            Assert.AreSame(m2, o.BestCandidate);

            // Call: Foo<int?>();
            o = new OverloadResolution(context, new ResolveResult[0], typeArguments: new[] { typeof(int?).ToTypeReference().Resolve(context) });
            Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(m1));
            Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(m2));
            Assert.AreEqual(OverloadResolutionErrors.None, o.AddCandidate(m3));
            Assert.AreSame(m3, o.BestCandidate);
        }
コード例 #27
0
        public void EmptyClassHasToString()
        {
            DefaultTypeDefinition c = new DefaultTypeDefinition(mscorlib, string.Empty, "C");

            Assert.AreEqual("System.Object.ToString", c.GetMethods(mscorlib, m => m.Name == "ToString").Single().FullName);
        }
コード例 #28
0
        public void SkeetEvilOverloadResolution()
        {
            // http://msmvps.com/blogs/jon_skeet/archive/2010/11/02/evil-code-overload-resolution-workaround.aspx

            // static void Foo<T>(T? ignored = default(T?)) where T : struct
            var m1 = MakeMethod();

            m1.TypeParameters.Add(new DefaultTypeParameter(EntityType.Method, 0, "T")
            {
                HasValueTypeConstraint = true
            });
            m1.Parameters.Add(MakeOptionalParameter(
                                  NullableType.Create(m1.TypeParameters[0], context),
                                  "ignored"
                                  ));

            // class ClassConstraint<T> where T : class {}
            DefaultTypeDefinition classConstraint = new DefaultTypeDefinition(dummyClass, "ClassConstraint");

            classConstraint.TypeParameters.Add(new DefaultTypeParameter(EntityType.TypeDefinition, 0, "T")
            {
                HasReferenceTypeConstraint = true
            });

            // static void Foo<T>(ClassConstraint<T> ignored = default(ClassConstraint<T>))
            // where T : class
            var m2 = MakeMethod();

            m2.TypeParameters.Add(new DefaultTypeParameter(EntityType.Method, 0, "T")
            {
                HasReferenceTypeConstraint = true
            });
            m2.Parameters.Add(MakeOptionalParameter(
                                  new ParameterizedType(classConstraint, new[] { m2.TypeParameters[0] }),
                                  "ignored"
                                  ));

            // static void Foo<T>()
            var m3 = MakeMethod();

            m3.TypeParameters.Add(new DefaultTypeParameter(EntityType.Method, 0, "T"));

            // Call: Foo<int>();
            OverloadResolution o;

            o = new OverloadResolution(context, new ResolveResult[0], typeArguments: new[] { typeof(int).ToTypeReference().Resolve(context) });
            Assert.AreEqual(OverloadResolutionErrors.None, o.AddCandidate(m1));
            Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(m2));
            Assert.AreSame(m1, o.BestCandidate);

            // Call: Foo<string>();
            o = new OverloadResolution(context, new ResolveResult[0], typeArguments: new[] { typeof(string).ToTypeReference().Resolve(context) });
            Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(m1));
            Assert.AreEqual(OverloadResolutionErrors.None, o.AddCandidate(m2));
            Assert.AreSame(m2, o.BestCandidate);

            // Call: Foo<int?>();
            o = new OverloadResolution(context, new ResolveResult[0], typeArguments: new[] { typeof(int?).ToTypeReference().Resolve(context) });
            Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(m1));
            Assert.AreEqual(OverloadResolutionErrors.ConstructedTypeDoesNotSatisfyConstraint, o.AddCandidate(m2));
            Assert.AreEqual(OverloadResolutionErrors.None, o.AddCandidate(m3));
            Assert.AreSame(m3, o.BestCandidate);
        }
コード例 #29
0
 DefaultTypeDefinition GetDummyClassForTypeParameter()
 {
     DefaultTypeDefinition c = new DefaultTypeDefinition(ParentClass ?? ParentMethod.DeclaringTypeDefinition, this.Name);
     c.Region = new DomRegion(parent.Region.FileName, parent.Region.BeginLine, parent.Region.BeginColumn);
     if (HasValueTypeConstraint) {
         c.ClassType = ClassType.Struct;
     } else if (HasDefaultConstructorConstraint) {
         c.ClassType = ClassType.Class;
     } else {
         c.ClassType = ClassType.Interface;
     }
     return c;
 }
コード例 #30
0
		DefaultTypeDefinition GetDummyClassForTypeParameter()
		{
			DefaultTypeDefinition c = new DefaultTypeDefinition(dummyProjectContent, string.Empty, this.Name);
			c.Region = this.Region;
			if (HasValueTypeConstraint) {
				c.ClassType = ClassType.Struct;
			} else if (HasDefaultConstructorConstraint) {
				c.ClassType = ClassType.Class;
			} else {
				c.ClassType = ClassType.Interface;
			}
			return c;
		}
コード例 #31
0
ファイル: GetMembersTests.cs プロジェクト: shalang/ILSpy
		public void GetGenericNestedTypeOfBoundGenericClass()
		{
			// class A<X> { class B<Y> { } }
			DefaultTypeDefinition a = new DefaultTypeDefinition(mscorlib, string.Empty, "A");
			a.TypeParameters.Add(new DefaultTypeParameter(EntityType.TypeDefinition, 0, "X"));
			
			DefaultTypeDefinition b = new DefaultTypeDefinition(a, "B");
			b.TypeParameters.Add(a.TypeParameters[0]);
			b.TypeParameters.Add(new DefaultTypeParameter(EntityType.TypeDefinition, 1, "Y"));
			
			a.NestedTypes.Add(b);
			
			// A<> gets self-parameterized, B<> stays unbound
			Assert.AreEqual("A`1+B`1[[`0],[]]", a.GetNestedTypes(mscorlib).Single().ReflectionName);
			
			ParameterizedType pt = new ParameterizedType(a, new [] { KnownTypeReference.String.Resolve(mscorlib) });
			Assert.AreEqual("A`1+B`1[[System.String],[]]", pt.GetNestedTypes(mscorlib).Single().ReflectionName);
		}