public void ImportOpenGenericType()
        {
            // class C<T, U> { void M<X>() {} }

            var c = new DefaultUnresolvedTypeDefinition(string.Empty, "C");
            c.TypeParameters.Add(new DefaultUnresolvedTypeParameter(EntityType.TypeDefinition, 0, "T"));
            c.TypeParameters.Add(new DefaultUnresolvedTypeParameter(EntityType.TypeDefinition, 1, "U"));
            var m = new DefaultUnresolvedMethod(c, "M");
            m.TypeParameters.Add(new DefaultUnresolvedTypeParameter(EntityType.Method, 0, "X"));
            c.Members.Add(m);

            var resolvedC1 = TypeSystemHelper.CreateCompilationAndResolve(c);
            var resolvedM1 = resolvedC1.Methods.Single(method => method.Name == "M");

            var resolvedC2 = TypeSystemHelper.CreateCompilationAndResolve(c);
            var resolvedM2 = resolvedC2.Methods.Single(method => method.Name == "M");

            // the types, methods and type parameters differ in the two compilations:
            Assert.AreNotEqual(resolvedC1, resolvedC2);
            Assert.AreNotEqual(resolvedM1, resolvedM2);
            Assert.AreNotEqual(resolvedC1.TypeParameters[1], resolvedC2.TypeParameters[1]);
            Assert.AreNotEqual(resolvedM1.TypeParameters[0], resolvedM2.TypeParameters[0]);

            // C<U, X>
            var pt1 = new ParameterizedType(resolvedC1, new[] { resolvedC1.TypeParameters[1], resolvedM1.TypeParameters[0] });
            var pt2 = (ParameterizedType)resolvedC2.Compilation.Import(pt1);

            // importing resulted in C<U, X> in the new compilation:
            Assert.AreEqual(resolvedC2, pt2.GetDefinition());
            Assert.AreEqual(resolvedC2.TypeParameters[1], pt2.TypeArguments[0]);
            Assert.AreEqual(resolvedM2.TypeParameters[0], pt2.TypeArguments[1]);
        }
		/// <summary>
		/// Finds IList&lt;T&gt; or IEnumerable&lt;T&gt; base type.
		/// </summary>
		/// <param name="fullNamePrefix">Type code to search for (IList&lt;T&gt; or IEnumerable&lt;T&gt;)</param></param>
		/// <param name="implementation">Found implementation.</param>
		/// <param name="itemType">The only generic argument of <paramref name="implementation"/></param>
		/// <returns>True if found, false otherwise.</returns>
		private static bool ResolveKnownBaseType(this IType type, KnownTypeCode knownTypeCode, out ParameterizedType implementation, out IType itemType)
		{
			if (type == null) throw new ArgumentNullException("type");
			implementation = null;
			itemType = null;
			ParameterizedType impl = 
				type.GetAllBaseTypes().OfType<ParameterizedType>().
				Where(t => t.IsKnownType(knownTypeCode) && t.TypeParameterCount == 1)
				.FirstOrDefault();
			if (impl != null) {
				implementation = impl;
				itemType = impl.GetTypeArgument(0);
				return true;
			}
			return false;
		}
Exemple #3
0
        public IEnumerable <IType> GetNestedTypes(ITypeResolveContext context, Predicate <ITypeDefinition> filter = null)
        {
            /*
             * class Base<T> {
             *      class Nested {}
             * }
             * class Derived<A, B> : Base<B> {}
             *
             * Derived<string,int>.GetNestedTypes() = { Base`1+Nested<int> }
             * Derived.GetNestedTypes() = { Base`1+Nested<B> }
             * Base<B>.GetNestedTypes() = { Base`1+Nested<B> }
             * Base.GetNestedTypes() = { Base`1+Nested<T2> } where T2 = copy of T in Base`1+Nested
             */
            Substitution substitution = new Substitution(typeArguments);
            List <IType> types        = genericType.GetNestedTypes(context, filter).ToList();

            for (int i = 0; i < types.Count; i++)
            {
                ITypeDefinition def = types[i] as ITypeDefinition;
                if (def != null && def.TypeParameterCount > 0)
                {
                    // (partially) parameterize the nested type definition
                    IType[] newTypeArgs = new IType[def.TypeParameterCount];
                    for (int j = 0; j < newTypeArgs.Length; j++)
                    {
                        if (j < typeArguments.Length)
                        {
                            newTypeArgs[j] = typeArguments[i];
                        }
                        else
                        {
                            newTypeArgs[j] = def.TypeParameters[j];
                        }
                    }
                    types[i] = new ParameterizedType(def, newTypeArgs);
                }
                else
                {
                    types[i] = types[i].AcceptVisitor(substitution);
                }
            }
            return(types);
        }
		public void EnumerableToArrayInContravariantType()
		{
			ITypeParameter tp = new DefaultTypeParameter(EntityType.Method, 0, "T");
			IType stringType = KnownTypeReference.String.Resolve(ctx);
			ITypeDefinition enumerableType = ctx.GetTypeDefinition(typeof(IEnumerable<>));
			ITypeDefinition comparerType = ctx.GetTypeDefinition(typeof(IComparer<>));
			
			var comparerOfIEnumerableOfString = new ParameterizedType(comparerType, new [] { new ParameterizedType(enumerableType, new [] { stringType} ) });
			var comparerOfTpArray = new ParameterizedType(comparerType, new [] { new ArrayType(tp) });
			
			bool success;
			Assert.AreEqual(
				new [] { stringType },
				ti.InferTypeArguments(new [] { tp },
				                      new [] { new ResolveResult(comparerOfIEnumerableOfString) },
				                      new [] { comparerOfTpArray },
				                      out success));
			Assert.IsTrue(success);
		}
Exemple #5
0
        public void GetIndexSpecializedTypeParameter()
        {
            var testClass = GetTypeDefinition(typeof(GenericClass <,>));
            var methodDef = testClass.Methods.Single(me => me.Name == "GetIndex");
            var m         = new SpecializedMethod(methodDef, new TypeParameterSubstitution(
                                                      new[] { compilation.FindType(KnownTypeCode.Int16), compilation.FindType(KnownTypeCode.Int32) },
                                                      null
                                                      ));

            Assert.AreEqual("T", m.TypeParameters[0].Name);
            Assert.AreEqual(EntityType.Method, m.TypeParameters[0].OwnerType);
            Assert.AreSame(m, m.TypeParameters[0].Owner);

            ParameterizedType constraint = (ParameterizedType)m.TypeParameters[0].DirectBaseTypes.First();

            Assert.AreEqual("IEquatable", constraint.Name);
            Assert.AreEqual(1, constraint.TypeParameterCount);
            Assert.AreEqual(1, constraint.TypeArguments.Count);
            Assert.AreSame(m.TypeParameters[0], constraint.TypeArguments[0]);
        }
Exemple #6
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);
        }
Exemple #7
0
        public void AssemblyAttribute()
        {
            var attributes = testCasePC.AssemblyAttributes;
            var typeTest   = attributes.First(a => a.AttributeType.Resolve(ctx).FullName == typeof(TypeTestAttribute).FullName);

            Assert.AreEqual(3, typeTest.PositionalArguments.Count);
            // first argument is (int)42
            Assert.AreEqual(42, (int)typeTest.PositionalArguments[0].GetValue(ctx));
            // second argument is typeof(System.Action<>)
            IType rt = (IType)typeTest.PositionalArguments[1].GetValue(ctx);

            Assert.IsFalse(rt is ParameterizedType);             // rt must not be constructed - it's just an unbound type
            Assert.AreEqual("System.Action", rt.FullName);
            Assert.AreEqual(1, rt.TypeParameterCount);
            // third argument is typeof(IDictionary<string, IList<TestAttribute>>)
            ParameterizedType crt = (ParameterizedType)typeTest.PositionalArguments[2].GetValue(ctx);

            Assert.AreEqual("System.Collections.Generic.IDictionary", crt.FullName);
            Assert.AreEqual("System.String", crt.TypeArguments[0].FullName);
            // ? for NUnit.TestAttribute (because that assembly isn't in ctx)
            Assert.AreEqual("System.Collections.Generic.IList`1[[?]]", crt.TypeArguments[1].ReflectionName);
        }
        public void GetGenericNestedTypeOfBoundGenericClass()
        {
            // class A<X> { class B<Y> { } }
            DefaultUnresolvedTypeDefinition a = new DefaultUnresolvedTypeDefinition(string.Empty, "A");
            a.TypeParameters.Add(new DefaultUnresolvedTypeParameter(SymbolKind.TypeDefinition, 0, "X"));

            DefaultUnresolvedTypeDefinition b = new DefaultUnresolvedTypeDefinition(a, "B");
            b.TypeParameters.Add(a.TypeParameters[0]);
            b.TypeParameters.Add(new DefaultUnresolvedTypeParameter(SymbolKind.TypeDefinition, 1, "Y"));

            a.NestedTypes.Add(b);

            var compilation = TypeSystemHelper.CreateCompilation(a, b);
            ITypeDefinition resolvedA = compilation.MainAssembly.GetTypeDefinition(a.FullTypeName);
            ITypeDefinition resolvedB = compilation.MainAssembly.GetTypeDefinition(b.FullTypeName);

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

            ParameterizedType pt = new ParameterizedType(resolvedA, new [] { compilation.FindType(KnownTypeCode.String) });
            Assert.AreEqual("A`1+B`1[[System.String],[]]", pt.GetNestedTypes().Single().ReflectionName);
        }
Exemple #9
0
        public void AssemblyAttribute()
        {
            var attributes = compilation.MainAssembly.AssemblyAttributes;
            var typeTest   = attributes.Single(a => a.AttributeType.FullName == typeof(TypeTestAttribute).FullName);

            Assert.AreEqual(3, typeTest.PositionalArguments.Count);
            // first argument is (int)42
            Assert.AreEqual(42, (int)typeTest.PositionalArguments[0].ConstantValue);
            // second argument is typeof(System.Action<>)
            TypeOfResolveResult rt = (TypeOfResolveResult)typeTest.PositionalArguments[1];

            Assert.IsFalse(rt.ReferencedType is ParameterizedType);             // rt must not be constructed - it's just an unbound type
            Assert.AreEqual("System.Action", rt.ReferencedType.FullName);
            Assert.AreEqual(1, rt.ReferencedType.TypeParameterCount);
            // third argument is typeof(IDictionary<string, IList<TestAttribute>>)
            rt = (TypeOfResolveResult)typeTest.PositionalArguments[2];
            ParameterizedType crt = (ParameterizedType)rt.ReferencedType;

            Assert.AreEqual("System.Collections.Generic.IDictionary", crt.FullName);
            Assert.AreEqual("System.String", crt.TypeArguments[0].FullName);
            // ? for NUnit.TestAttribute (because that assembly isn't in ctx)
            Assert.AreEqual("System.Collections.Generic.IList`1[[?]]", crt.TypeArguments[1].ReflectionName);
        }
Exemple #10
0
        public void GetGenericNestedTypeOfBoundGenericClass()
        {
            // class A<X> { class B<Y> { } }
            DefaultUnresolvedTypeDefinition a = new DefaultUnresolvedTypeDefinition(string.Empty, "A");

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

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

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

            a.NestedTypes.Add(b);

            ITypeDefinition resolvedA = compilation.MainAssembly.GetTypeDefinition(a);
            ITypeDefinition resolvedB = compilation.MainAssembly.GetTypeDefinition(b);

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

            ParameterizedType pt = new ParameterizedType(resolvedA, new [] { compilation.FindType(KnownTypeCode.String) });

            Assert.AreEqual("A`1+B`1[[System.String],[]]", pt.GetNestedTypes().Single().ReflectionName);
        }
        IList<IType> FindTypesInBounds(IList<IType> lowerBounds, IList<IType> upperBounds)
        {
            // If there's only a single type; return that single type.
            // If both inputs are empty, return the empty list.
            if (lowerBounds.Count == 0 && upperBounds.Count <= 1)
                return upperBounds;
            if (upperBounds.Count == 0 && lowerBounds.Count <= 1)
                return lowerBounds;
            if (nestingLevel > maxNestingLevel)
                return EmptyList<IType>.Instance;

            // Finds a type X so that "LB <: X <: UB"
            Log.WriteCollection("FindTypesInBound, LowerBounds=", lowerBounds);
            Log.WriteCollection("FindTypesInBound, UpperBounds=", upperBounds);

            // First try the Fixing algorithm from the C# spec (§7.5.2.11)
            List<IType> candidateTypes = lowerBounds.Union(upperBounds)
                .Where(c => lowerBounds.All(b => conversions.ImplicitConversion(b, c).IsValid))
                .Where(c => upperBounds.All(b => conversions.ImplicitConversion(c, b).IsValid))
                .ToList(); // evaluate the query only once

            Log.WriteCollection("FindTypesInBound, Candidates=", candidateTypes);

            // According to the C# specification, we need to pick the most specific
            // of the candidate types. (the type which has conversions to all others)
            // However, csc actually seems to choose the least specific.
            candidateTypes = candidateTypes.Where(
                c => candidateTypes.All(o => conversions.ImplicitConversion(o, c).IsValid)
            ).ToList();

            // If the specified algorithm produces a single candidate, we return
            // that candidate.
            // We also return the whole candidate list if we're not using the improved
            // algorithm.
            if (candidateTypes.Count == 1 || !(algorithm == TypeInferenceAlgorithm.Improved || algorithm == TypeInferenceAlgorithm.ImprovedReturnAllResults))
            {
                return candidateTypes;
            }
            candidateTypes.Clear();

            // Now try the improved algorithm
            Log.Indent();
            List<ITypeDefinition> candidateTypeDefinitions;
            if (lowerBounds.Count > 0) {
                // Find candidates by using the lower bounds:
                var hashSet = new HashSet<ITypeDefinition>(lowerBounds[0].GetAllBaseTypeDefinitions());
                for (int i = 1; i < lowerBounds.Count; i++) {
                    hashSet.IntersectWith(lowerBounds[i].GetAllBaseTypeDefinitions());
                }
                candidateTypeDefinitions = hashSet.ToList();
            } else {
                // Find candidates by looking at all classes in the project:
                candidateTypeDefinitions = compilation.GetAllTypeDefinitions().ToList();
            }

            // Now filter out candidates that violate the upper bounds:
            foreach (IType ub in upperBounds) {
                ITypeDefinition ubDef = ub.GetDefinition();
                if (ubDef != null) {
                    candidateTypeDefinitions.RemoveAll(c => !c.IsDerivedFrom(ubDef));
                }
            }

            foreach (ITypeDefinition candidateDef in candidateTypeDefinitions) {
                // determine the type parameters for the candidate:
                IType candidate;
                if (candidateDef.TypeParameterCount == 0) {
                    candidate = candidateDef;
                } else {
                    Log.WriteLine("Inferring arguments for candidate type definition: " + candidateDef);
                    bool success;
                    IType[] result = InferTypeArgumentsFromBounds(
                        candidateDef.TypeParameters,
                        new ParameterizedType(candidateDef, candidateDef.TypeParameters),
                        lowerBounds, upperBounds,
                        out success);
                    if (success) {
                        candidate = new ParameterizedType(candidateDef, result);
                    } else {
                        Log.WriteLine("Inference failed; ignoring candidate");
                        continue;
                    }
                }
                Log.WriteLine("Candidate type: " + candidate);

                if (upperBounds.Count == 0) {
                    // if there were only lower bounds, we aim for the most specific candidate:

                    // if this candidate isn't made redundant by an existing, more specific candidate:
                    if (!candidateTypes.Any(c => c.GetDefinition().IsDerivedFrom(candidateDef))) {
                        // remove all existing candidates made redundant by this candidate:
                        candidateTypes.RemoveAll(c => candidateDef.IsDerivedFrom(c.GetDefinition()));
                        // add new candidate
                        candidateTypes.Add(candidate);
                    }
                } else {
                    // if there were upper bounds, we aim for the least specific candidate:

                    // if this candidate isn't made redundant by an existing, less specific candidate:
                    if (!candidateTypes.Any(c => candidateDef.IsDerivedFrom(c.GetDefinition()))) {
                        // remove all existing candidates made redundant by this candidate:
                        candidateTypes.RemoveAll(c => c.GetDefinition().IsDerivedFrom(candidateDef));
                        // add new candidate
                        candidateTypes.Add(candidate);
                    }
                }
            }
            Log.Unindent();
            return candidateTypes;
        }
Exemple #12
0
		ResolveResult LookInCurrentUsingScope(string identifier, IList<IType> typeArguments, bool isInUsingDeclaration, bool parameterizeResultType)
		{
			// look in current namespace definitions
			ResolvedUsingScope currentUsingScope = this.CurrentUsingScope;
			for (ResolvedUsingScope u = currentUsingScope; u != null; u = u.Parent) {
				var resultInNamespace = LookInUsingScopeNamespace(u, u.Namespace, identifier, typeArguments, parameterizeResultType);
				if (resultInNamespace != null)
					return resultInNamespace;
				// then look for aliases:
				if (typeArguments.Count == 0) {
					if (u.ExternAliases.Contains(identifier)) {
						return ResolveExternAlias(identifier);
					}
					if (!(isInUsingDeclaration && u == currentUsingScope)) {
						foreach (var pair in u.UsingAliases) {
							if (pair.Key == identifier) {
								return pair.Value;
							}
						}
					}
				}
				// finally, look in the imported namespaces:
				if (!(isInUsingDeclaration && u == currentUsingScope)) {
					IType firstResult = null;
					foreach (var importedNamespace in u.Usings) {
						ITypeDefinition def = importedNamespace.GetTypeDefinition(identifier, typeArguments.Count);
						if (def != null) {
							IType resultType;
							if (parameterizeResultType && typeArguments.Count > 0)
								resultType = new ParameterizedType(def, typeArguments);
							else
								resultType = def;
							
							if (firstResult == null || !TopLevelTypeDefinitionIsAccessible(firstResult.GetDefinition())) {
								firstResult = resultType;
							} else if (TopLevelTypeDefinitionIsAccessible(def)) {
								return new AmbiguousTypeResolveResult(firstResult);
							}
						}
					}
					if (firstResult != null)
						return new TypeResolveResult(firstResult);
				}
				// if we didn't find anything: repeat lookup with parent namespace
			}
			return null;
		}
		public void NestedTypeInDerivedClass()
		{
			var type1 = new ParameterizedType(nestedClass, new[] { derivedClass.TypeParameters[0], compilation.FindType(KnownTypeCode.String) });
			// short form "Nested<string>" cannot be used as it would refer to "Base<S>.Nested<string>"
			Assert.AreEqual("Base<T>.Nested<string>", TypeToString(type1, derivedClass));
			
			var type2 = new ParameterizedType(nestedClass, new[] { derivedClass.TypeParameters[1], compilation.FindType(KnownTypeCode.String) });
			Assert.AreEqual("Nested<string>", TypeToString(type2, derivedClass));
		}
 static bool IsGenericInterfaceImplementedByArray(ParameterizedType rt)
 {
     if (rt == null || rt.TypeParameterCount != 1)
         return false;
     switch (rt.GetDefinition().FullName) {
         case "System.Collections.Generic.IEnumerable":
         case "System.Collections.Generic.ICollection":
         case "System.Collections.Generic.IList":
         case "System.Collections.Generic.IReadOnlyList":
             return true;
         default:
             return false;
     }
 }
		ResolveResult CreateTypeResolveResult(IType returnedType, bool isAmbiguous, IList<IType> typeArguments)
		{
			if (typeArguments.Count > 0) {
				// parameterize the type if necessary
				ITypeDefinition returnedTypeDef = returnedType as ITypeDefinition;
				if (returnedTypeDef != null)
					returnedType = new ParameterizedType(returnedTypeDef, typeArguments);
			}
			if (isAmbiguous)
				return new AmbiguousTypeResolveResult(returnedType);
			else
				return new TypeResolveResult(returnedType);
		}
		public void IEnumerableCovarianceWithDynamic()
		{
			ITypeParameter tp = new DefaultTypeParameter(compilation, SymbolKind.Method, 0, "T");
			var ienumerableOfT = new ParameterizedType(compilation.FindType(typeof(IEnumerable<>)).GetDefinition(), new[] { tp });
			var ienumerableOfString = compilation.FindType(typeof(IEnumerable<string>));
			var ienumerableOfDynamic = compilation.FindType(typeof(IEnumerable<ReflectionHelper.Dynamic>));
			
			// static T M<T>(IEnumerable<T> x, IEnumerable<T> y) {}
			// M(IEnumerable<dynamic>, IEnumerable<string>); -> should infer T=dynamic, no ambiguity
			// See http://blogs.msdn.com/b/cburrows/archive/2010/04/01/errata-dynamic-conversions-and-overload-resolution.aspx
			// for details.
			
			bool success;
			Assert.AreEqual(
				new [] { SpecialType.Dynamic },
				ti.InferTypeArguments(
					new [] { tp },
					new [] { new ResolveResult(ienumerableOfDynamic), new ResolveResult(ienumerableOfString) },
					new [] { ienumerableOfT, ienumerableOfT },
					out success));
			Assert.IsTrue(success);
		}
Exemple #17
0
 ResolveResult LookInCurrentUsingScope(string identifier, IList<IType> typeArguments, bool isInUsingDeclaration, bool parameterizeResultType)
 {
     int k = typeArguments.Count;
     // look in current namespace definitions
     ResolvedUsingScope currentUsingScope = this.CurrentUsingScope;
     for (ResolvedUsingScope u = currentUsingScope; u != null; u = u.Parent) {
         INamespace n = u.Namespace;
         // first look for a namespace
         if (k == 0 && n != null) {
             INamespace childNamespace = n.GetChildNamespace(identifier);
             if (childNamespace != null) {
                 if (u.HasAlias(identifier))
                     return new AmbiguousTypeResolveResult(new UnknownType(null, identifier));
                 return new NamespaceResolveResult(childNamespace);
             }
         }
         // then look for a type
         if (n != null) {
             ITypeDefinition def = n.GetTypeDefinition(identifier, k);
             if (def != null) {
                 IType result = def;
                 if (parameterizeResultType) {
                     result = new ParameterizedType(def, typeArguments);
                 }
                 if (u.HasAlias(identifier))
                     return new AmbiguousTypeResolveResult(result);
                 else
                     return new TypeResolveResult(result);
             }
         }
         // then look for aliases:
         if (k == 0) {
             if (u.ExternAliases.Contains(identifier)) {
                 return ResolveExternAlias(identifier);
             }
             if (!(isInUsingDeclaration && u == currentUsingScope)) {
                 foreach (var pair in u.UsingAliases) {
                     if (pair.Key == identifier) {
                         return pair.Value;
                     }
                 }
             }
         }
         // finally, look in the imported namespaces:
         if (!(isInUsingDeclaration && u == currentUsingScope)) {
             IType firstResult = null;
             foreach (var importedNamespace in u.Usings) {
                 ITypeDefinition def = importedNamespace.GetTypeDefinition(identifier, k);
                 if (def != null) {
                     if (firstResult == null) {
                         if (parameterizeResultType && k > 0)
                             firstResult = new ParameterizedType(def, typeArguments);
                         else
                             firstResult = def;
                     } else {
                         return new AmbiguousTypeResolveResult(firstResult);
                     }
                 }
             }
             if (firstResult != null)
                 return new TypeResolveResult(firstResult);
         }
         // if we didn't find anything: repeat lookup with parent namespace
     }
     return null;
 }
		public virtual IType VisitParameterizedType(ParameterizedType type)
		{
			return type.VisitChildren(this);
		}
 public void NestedType()
 {
     var type = new ParameterizedType(nestedClass, new[] { compilation.FindType(KnownTypeCode.Char), compilation.FindType(KnownTypeCode.String) });
     Assert.AreEqual("Base<char>.Nested<string>", TypeToString(type));
     Assert.AreEqual("Base<char>.Nested<string>", TypeToString(type, baseClass));
     Assert.AreEqual("Base<char>.Nested<string>", TypeToString(type, nestedClass));
     Assert.AreEqual("Base<char>.Nested<string>", TypeToString(type, derivedClass));
 }
		public void AliasedTypeWrongTypeArgument()
		{
			var type = new ParameterizedType(compilation.FindType(typeof(List<>)).GetDefinition(), new[] { compilation.FindType(KnownTypeCode.Int32) });
			Assert.AreEqual("List<int>", TypeToString(type, systemClass));
		}
		public void NestedType()
		{
			var type = new ParameterizedType(nestedClass, new[] { compilation.FindType(KnownTypeCode.Char), compilation.FindType(KnownTypeCode.String) });
			Assert.AreEqual("Base<char>.Nested<string>", TypeToString(type));
			// The short form "Nested<string>" refers to "Base<T>.Nested<string>",
			// so we need to use the long form to specify that T=char.
			Assert.AreEqual("Base<char>.Nested<string>", TypeToString(type, baseClass));
			Assert.AreEqual("Base<char>.Nested<string>", TypeToString(type, nestedClass));
			Assert.AreEqual("Base<char>.Nested<string>", TypeToString(type, derivedClass));
		}
 public override IType VisitParameterizedType(ParameterizedType type)
 {
     IType newType = base.VisitParameterizedType(type);
     if (newType != type && ConstraintsValid) {
         // something was changed, so we need to validate the constraints
         ParameterizedType newParameterizedType = newType as ParameterizedType;
         if (newParameterizedType != null) {
             // C# 4.0 spec: §4.4.4 Satisfying constraints
             var typeParameters = newParameterizedType.GetDefinition().TypeParameters;
             for (int i = 0; i < typeParameters.Count; i++) {
                 ITypeParameter tp = typeParameters[i];
                 IType typeArg = newParameterizedType.TypeArguments[i];
                 if (tp.HasReferenceTypeConstraint) {
                     if (typeArg.IsReferenceType != true)
                         ConstraintsValid = false;
                 }
                 if (tp.HasValueTypeConstraint) {
                     if (typeArg.IsReferenceType != false)
                         ConstraintsValid = false;
                     if (NullableType.IsNullable(typeArg))
                         ConstraintsValid = false;
                 }
                 if (tp.HasDefaultConstructorConstraint) {
                     ITypeDefinition def = typeArg.GetDefinition();
                     if (def != null && def.IsAbstract)
                         ConstraintsValid = false;
                     ConstraintsValid &= typeArg.GetConstructors(
                         overloadResolution.context,
                         m => m.Parameters.Count == 0 && m.Accessibility == Accessibility.Public
                     ).Any();
                 }
                 foreach (IType constraintType in tp.Constraints) {
                     IType c = newParameterizedType.SubstituteInType(constraintType);
                     ConstraintsValid &= overloadResolution.IsConstraintConvertible(typeArg, c);
                 }
             }
         }
     }
     return newType;
 }
Exemple #23
0
 public virtual IType VisitParameterizedType(ParameterizedType type)
 {
     return(type.VisitChildren(this));
 }
Exemple #24
0
		ResolveResult LookInUsingScopeNamespace(ResolvedUsingScope usingScope, INamespace n, string identifier, IList<IType> typeArguments, bool parameterizeResultType)
		{
			if (n == null)
				return null;
			// first look for a namespace
			int k = typeArguments.Count;
			if (k == 0) {
				INamespace childNamespace = n.GetChildNamespace(identifier);
				if (childNamespace != null) {
					if (usingScope != null && usingScope.HasAlias(identifier))
						return new AmbiguousTypeResolveResult(new UnknownType(null, identifier));
					return new NamespaceResolveResult(childNamespace);
				}
			}
			// then look for a type
			ITypeDefinition def = n.GetTypeDefinition(identifier, k);
			if (def != null) {
				IType result = def;
				if (parameterizeResultType && k > 0) {
					result = new ParameterizedType(def, typeArguments);
				}
				if (usingScope != null && usingScope.HasAlias(identifier))
					return new AmbiguousTypeResolveResult(result);
				else
					return new TypeResolveResult(result);
			}
			return null;
		}
Exemple #25
0
		static bool IsIEnumerableCollectionOrList(ParameterizedType rt)
		{
			if (rt == null || rt.TypeParameterCount != 1)
				return false;
			switch (rt.GetDefinition().FullName) {
				case "System.Collections.Generic.IList":
				case "System.Collections.Generic.ICollection":
				case "System.Collections.Generic.IEnumerable":
					return true;
				default:
					return false;
			}
		}
Exemple #26
0
        public void ExpansiveInheritance()
        {
            var a = new DefaultUnresolvedTypeDefinition(string.Empty, "A");
            var b = new DefaultUnresolvedTypeDefinition(string.Empty, "B");
            // interface A<in U>
            a.Kind = TypeKind.Interface;
            a.TypeParameters.Add(new DefaultUnresolvedTypeParameter(EntityType.TypeDefinition, 0, "U") { Variance = VarianceModifier.Contravariant });
            // interface B<X> : A<A<B<X>>> { }
            b.TypeParameters.Add(new DefaultUnresolvedTypeParameter(EntityType.TypeDefinition, 0, "X"));
            b.BaseTypes.Add(new ParameterizedTypeReference(
                a, new[] { new ParameterizedTypeReference(
                    a, new [] { new ParameterizedTypeReference(
                        b, new [] { new TypeParameterReference(EntityType.TypeDefinition, 0) }
                    ) } ) }));

            ICompilation compilation = TypeSystemHelper.CreateCompilation(a, b);
            ITypeDefinition resolvedA = compilation.MainAssembly.GetTypeDefinition(a.FullTypeName);
            ITypeDefinition resolvedB = compilation.MainAssembly.GetTypeDefinition(b.FullTypeName);

            IType type1 = new ParameterizedType(resolvedB, new [] { compilation.FindType(KnownTypeCode.Double) });
            IType type2 = new ParameterizedType(resolvedA, new [] { new ParameterizedType(resolvedB, new[] { compilation.FindType(KnownTypeCode.String) }) });
            Assert.IsFalse(conversions.ImplicitConversion(type1, type2).IsValid);
        }
 public void ListOfNSSystem()
 {
     var type = new ParameterizedType(compilation.FindType(typeof(List<>)).GetDefinition(), new[] { systemClass });
     Assert.AreEqual("List<NS.System>", TypeToString(type));
     Assert.AreEqual("List<System>", TypeToString(type, systemClass));
 }
Exemple #28
0
			public override IType VisitParameterizedType(ParameterizedType type)
			{
				IType newType = base.VisitParameterizedType(type);
				if (newType != type && ConstraintsValid) {
					// something was changed, so we need to validate the constraints
					ParameterizedType newParameterizedType = newType as ParameterizedType;
					if (newParameterizedType != null) {
						// C# 4.0 spec: §4.4.4 Satisfying constraints
						var typeParameters = newParameterizedType.GetDefinition().TypeParameters;
						var substitution = newParameterizedType.GetSubstitution();
						for (int i = 0; i < typeParameters.Count; i++) {
							if (!ValidateConstraints(typeParameters[i], newParameterizedType.GetTypeArgument(i), substitution, conversions)) {
								ConstraintsValid = false;
								break;
							}
						}
					}
				}
				return newType;
			}
Exemple #29
0
			public override IType VisitParameterizedType(ParameterizedType type)
			{
				IType newType = base.VisitParameterizedType(type);
				if (newType != type && ConstraintsValid) {
					// something was changed, so we need to validate the constraints
					ParameterizedType newParameterizedType = newType as ParameterizedType;
					if (newParameterizedType != null) {
						// C# 4.0 spec: §4.4.4 Satisfying constraints
						var typeParameters = newParameterizedType.GetDefinition().TypeParameters;
						for (int i = 0; i < typeParameters.Count; i++) {
							ITypeParameter tp = typeParameters[i];
							IType typeArg = newParameterizedType.GetTypeArgument(i);
							switch (typeArg.Kind) { // void, null, and pointers cannot be used as type arguments
								case TypeKind.Void:
								case TypeKind.Null:
								case TypeKind.Pointer:
									ConstraintsValid = false;
									break;
							}
							if (tp.HasReferenceTypeConstraint) {
								if (typeArg.IsReferenceType != true)
									ConstraintsValid = false;
							}
							if (tp.HasValueTypeConstraint) {
								if (!NullableType.IsNonNullableValueType(typeArg))
									ConstraintsValid = false;
							}
							if (tp.HasDefaultConstructorConstraint) {
								ITypeDefinition def = typeArg.GetDefinition();
								if (def != null && def.IsAbstract)
									ConstraintsValid = false;
								ConstraintsValid &= typeArg.GetConstructors(
									m => m.Parameters.Count == 0 && m.Accessibility == Accessibility.Public,
									GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions
								).Any();
							}
							foreach (IType constraintType in tp.DirectBaseTypes) {
								IType c = constraintType.AcceptVisitor(newParameterizedType.GetSubstitution());
								ConstraintsValid &= conversions.IsConstraintConvertible(typeArg, c);
							}
						}
					}
				}
				return newType;
			}
Exemple #30
0
		public void NestedClassInGenericClassTest()
		{
			ITypeDefinition dictionary = compilation.FindType(typeof(Dictionary<,>)).GetDefinition();
			Assert.IsNotNull(dictionary);
			ITypeDefinition valueCollection = compilation.FindType(typeof(Dictionary<,>.ValueCollection)).GetDefinition();
			Assert.IsNotNull(valueCollection);
			var dictionaryRT = new ParameterizedType(dictionary, new[] { compilation.FindType(typeof(string)).GetDefinition(), compilation.FindType(typeof(int)).GetDefinition() });
			IProperty valueProperty = dictionaryRT.GetProperties(p => p.Name == "Values").Single();
			IType parameterizedValueCollection = valueProperty.ReturnType;
			Assert.AreEqual("System.Collections.Generic.Dictionary`2+ValueCollection[[System.String],[System.Int32]]", parameterizedValueCollection.ReflectionName);
			Assert.AreSame(valueCollection, parameterizedValueCollection.GetDefinition());
		}
			public override IType VisitParameterizedType(ParameterizedType type)
			{
				return NullableType.Create(compilation, type.AcceptVisitor(typeParameterSubstitution));
			}
 public void NestedTypeInCurrentClass()
 {
     var type = new ParameterizedType(nestedClass, new[] { baseClass.TypeParameters[0], compilation.FindType(KnownTypeCode.String) });
     Assert.AreEqual("Nested<string>", TypeToString(type, baseClass));
     Assert.AreEqual("Nested<string>", TypeToString(type, nestedClass));
 }
		public void SiblingClass()
		{
			var type = new ParameterizedType(siblingClass, new[] { baseClass.TypeParameters[0] });
			Assert.AreEqual("Sibling", TypeToString(type, nestedClass));
		}
Exemple #34
0
		/// <summary> Evaluates 'new List&lt;T&gt;(iEnumerableValue)' in the debuggee. </summary>
		public static Value CreateListFromIEnumerable(ParameterizedType ienumerableType, Value iEnumerableValue)
		{
			var ilistDef = ienumerableType.Compilation.FindType(typeof(List<>)).GetDefinition();
			var ilistType = new ParameterizedType(ilistDef, ienumerableType.TypeArguments);
			var ctors = ilistType.GetConstructors(m => m.Parameters.Count == 1);
			var ctor = ctors.Single(m => m.Parameters[0].Type.IsKnownType(KnownTypeCode.IEnumerableOfT));
			return Eval.NewObject(WindowsDebugger.EvalThread, ctor, new Value[] { iEnumerableValue });
		}
        public void NestedTypeInDerivedClass()
        {
            var type1 = new ParameterizedType(nestedClass, new[] { derivedClass.TypeParameters[0], compilation.FindType(KnownTypeCode.String) });
            Assert.AreEqual("Base<T>.Nested<string>", TypeToString(type1, derivedClass));

            var type2 = new ParameterizedType(nestedClass, new[] { derivedClass.TypeParameters[1], compilation.FindType(KnownTypeCode.String) });
            Assert.AreEqual("Nested<string>", TypeToString(type2, derivedClass));
        }
Exemple #36
0
 public override IType VisitParameterizedType(ParameterizedType type)
 {
     return NullableType.Create(compilation, type);
 }
 public void AliasedType()
 {
     var type = new ParameterizedType(compilation.FindType(typeof(List<>)).GetDefinition(), new[] { compilation.FindType(KnownTypeCode.Char) });
     Assert.AreEqual("List<char>", TypeToString(type));
     Assert.AreEqual("L", TypeToString(type, systemClass));
 }