public static bool Apply(TypeParameterName typeParam, ResolvedType typeParamRes) { var walker = new CheckForConstriction(typeParam); walker.OnType(typeParamRes); return(walker.SharedState.IsConstrictive); }
public void ShouldDeriveTypeParameterFromTypeParameter() { var actual = ArrayTypeName.From(new TypeParameterName("T"), 1); var expected = new TypeParameterName("T[]"); Assert.AreEqual(expected, actual); }
public void CanCreateTypeParameter_unbound() { var actual = Names.TypeParameter("T"); var expected = new TypeParameterName("T"); Assert.AreEqual(expected, actual); }
public void IsArrayName(string baseTypeId, string expected1DId, string expected2DId) { Assert.IsFalse(ArrayTypeName.IsArrayTypeNameIdentifier(baseTypeId)); foreach (var arrId in new[] { expected1DId, expected2DId }) { if (TypeParameterName.IsTypeParameterNameIdentifier(baseTypeId)) { Assert.IsTrue(TypeParameterName.IsTypeParameterNameIdentifier(arrId)); Assert.IsFalse(TypeName.IsTypeNameIdentifier(arrId)); Assert.IsFalse(ArrayTypeName.IsArrayTypeNameIdentifier(arrId)); Assert.IsFalse(DelegateTypeName.IsDelegateTypeNameIdentifier(arrId)); Assert.IsFalse(PredefinedTypeName.IsPredefinedTypeNameIdentifier(arrId)); Assert.IsFalse(TypeUtils.IsUnknownTypeIdentifier(arrId)); } else if (PredefinedTypeName.IsPredefinedTypeNameIdentifier(baseTypeId)) { Assert.IsTrue(PredefinedTypeName.IsPredefinedTypeNameIdentifier(arrId)); Assert.IsFalse(TypeName.IsTypeNameIdentifier(arrId)); Assert.IsFalse(ArrayTypeName.IsArrayTypeNameIdentifier(arrId)); Assert.IsFalse(TypeParameterName.IsTypeParameterNameIdentifier(arrId)); Assert.IsFalse(DelegateTypeName.IsDelegateTypeNameIdentifier(arrId)); Assert.IsFalse(TypeUtils.IsUnknownTypeIdentifier(arrId)); } else { Assert.IsTrue(ArrayTypeName.IsArrayTypeNameIdentifier(arrId)); Assert.IsFalse(TypeName.IsTypeNameIdentifier(arrId)); Assert.IsFalse(TypeParameterName.IsTypeParameterNameIdentifier(arrId)); Assert.IsFalse(DelegateTypeName.IsDelegateTypeNameIdentifier(arrId)); Assert.IsFalse(PredefinedTypeName.IsPredefinedTypeNameIdentifier(arrId)); Assert.IsFalse(TypeUtils.IsUnknownTypeIdentifier(arrId)); } } }
public void ShouldIdentifyValidTypeParameterNames(string typeParameter, string shortName, string boundType) { Assert.IsTrue(TypeParameterName.IsTypeParameterNameIdentifier(typeParameter)); Assert.IsFalse(DelegateTypeName.IsDelegateTypeNameIdentifier(typeParameter)); Assert.IsFalse(ArrayTypeName.IsArrayTypeNameIdentifier(typeParameter)); Assert.IsFalse(TypeUtils.IsUnknownTypeIdentifier(typeParameter)); Assert.IsFalse(PredefinedTypeName.IsPredefinedTypeNameIdentifier(typeParameter)); Assert.IsFalse(TypeName.IsTypeNameIdentifier(typeParameter)); }
public void ShouldRecognizeIdentifier(string shortName, string fullName, string id) { Assert.IsTrue(PredefinedTypeName.IsPredefinedTypeNameIdentifier(id)); Assert.IsFalse(ArrayTypeName.IsArrayTypeNameIdentifier(id)); Assert.IsFalse(TypeUtils.IsUnknownTypeIdentifier(id)); Assert.IsFalse(TypeParameterName.IsTypeParameterNameIdentifier(id)); Assert.IsFalse(DelegateTypeName.IsDelegateTypeNameIdentifier(id)); Assert.IsFalse(TypeName.IsTypeNameIdentifier(id)); }
public void ShouldNotCrashForInvalidNames(string invalidId) { Assert.IsFalse(ArrayTypeName.IsArrayTypeNameIdentifier(invalidId)); Assert.IsFalse(TypeParameterName.IsTypeParameterNameIdentifier(invalidId)); Assert.IsFalse(DelegateTypeName.IsDelegateTypeNameIdentifier(invalidId)); Assert.IsFalse(PredefinedTypeName.IsPredefinedTypeNameIdentifier(invalidId)); Assert.IsFalse(TypeUtils.IsUnknownTypeIdentifier(invalidId)); Assert.IsFalse(TypeName.IsTypeNameIdentifier(invalidId)); }
public void ShouldRecognizeDelegateNames(string delegateId, string delegateTypeId) { Assert.IsTrue(DelegateTypeName.IsDelegateTypeNameIdentifier(delegateId)); Assert.IsFalse(TypeUtils.IsUnknownTypeIdentifier(delegateId)); Assert.IsFalse(ArrayTypeName.IsArrayTypeNameIdentifier(delegateId)); Assert.IsFalse(TypeParameterName.IsTypeParameterNameIdentifier(delegateId)); Assert.IsFalse(PredefinedTypeName.IsPredefinedTypeNameIdentifier(delegateId)); Assert.IsFalse(TypeName.IsTypeNameIdentifier(delegateId)); }
public static IEnumerable <string> NonArrayTypeSource() { var types = new HashSet <string> { "?", "p:int", "T", "T -> ?", "n.T`1[[G]],P", "n.T`1[[G -> p:byte]],P", "T`1[[T -> d:[TR] [T2, P2].([T] arg)]], P", "n.C1+C2,P", "C1`1[[T1]],P", "C1+C2`1[[T2]],P", "C1`1[[T2]]+C2,P", "C1`1[[T1]]+C2`1[[T2]],P", "T -> T[],P", "T1`1[][[T2 -> T3[],P]]+T4`1[][[T5 -> T6[],P]]+T7`1[[T8 -> T9[],P]], P", "d:[?] [?].()", "d:[T,P] [T,P].()", "d:[R, P] [O+D, P].()", "d:[T`1[[T -> n.C+D, P]], P] [n.C+D, P].()", "d:[?] [n.C+D, P].([T`1[[T -> n.C+D, P]], P] p)", "d:[RT[], A] [DT, A].([PT[], A] p)", "i:n.T1`1[[T2 -> p:int]], P", "n.T,P", "n.T, A, 1.2.3.4", "s:n.T,P", "e:n.T,P", "i:n.T,P", "n.T1+T2, P", "n.T1`1[[T2]]+T3`1[[T4]], P", "n.C+N`1[[T]],P", "n.C`1[[T]]+N,P", "n.C`1[[T]]+N`1[[T]],P", "s:System.Nullable`1[[T -> p:sbyte]], mscorlib, 4.0.0.0", "System.Nullable`1[[System.Int32, mscorlib, 4.0.0.0]], mscorlib, 4.0.0.0", "Task`1[[TResult -> i:IList`1[[T -> T]], mscorlib, 4.0.0.0]], mscorlib, 4.0.0.0" }; foreach (var typeId in BasicTypes()) { types.Add("d:[{0}] [{0}].()".FormatEx(typeId)); types.Add("d:[{0}] [{0}].([{0}] p1)".FormatEx(typeId)); types.Add("d:[{0}] [{0}].([{0}] p1, [{0}] p2)".FormatEx(typeId)); } foreach (var tp in BasicTypes()) { if (!TypeParameterName.IsTypeParameterNameIdentifier(tp)) { types.Add("T -> {0}".FormatEx(tp)); } } return(types); }
public void ShouldRecognizeUnknownType() { foreach (var id in new[] { null, "", "?" }) { Assert.IsTrue(TypeUtils.IsUnknownTypeIdentifier(id)); Assert.IsFalse(TypeName.IsTypeNameIdentifier(id)); Assert.IsFalse(ArrayTypeName.IsArrayTypeNameIdentifier(id)); Assert.IsFalse(DelegateTypeName.IsDelegateTypeNameIdentifier(id)); Assert.IsFalse(TypeParameterName.IsTypeParameterNameIdentifier(id)); Assert.IsFalse(PredefinedTypeName.IsPredefinedTypeNameIdentifier(id)); } }
public void ShouldRecognizeRegularTypes(string typeId, string assemblyId, string namespaceId, string fullName, string name) { Assert.IsFalse(TypeUtils.IsUnknownTypeIdentifier(typeId)); Assert.IsFalse(ArrayTypeName.IsArrayTypeNameIdentifier(typeId)); Assert.IsFalse(DelegateTypeName.IsDelegateTypeNameIdentifier(typeId)); Assert.IsFalse(TypeParameterName.IsTypeParameterNameIdentifier(typeId)); Assert.IsFalse(PredefinedTypeName.IsPredefinedTypeNameIdentifier(typeId)); Assert.IsTrue(TypeName.IsTypeNameIdentifier(typeId)); }
/// <summary> /// Walks the given ResolvedType, typeParamRes, and returns true if there is a reference /// to a different type parameter of the same callable as the given type parameter, typeParam, /// or the same type parameter but in a nested type. /// Otherwise returns false. /// </summary> public static bool IsConstrictiveResolution(TypeParameterName typeParam, ResolvedType typeParamRes) { if (typeParamRes.Resolution is ResolvedTypeKind.TypeParameter tp && tp.Item.Origin.Equals(typeParam.Item1)) { // If given a type parameter whose origin matches the callable, // the only valid resolution is a direct self-resolution return(!tp.Item.TypeName.Equals(typeParam.Item2)); } var walker = new CheckForConstriction(typeParam.Item1); walker.OnType(typeParamRes); return(walker.SharedState.IsConstrictive); }
/// <summary> /// Uses the given lookup, mayBeReplaced, to determine what records in the combinedBuilder can be updated /// from the given type parameter, typeParam, and its resolution, paramRes. Then updates the combinedBuilder /// appropriately. /// </summary> private void UpdatedReplaceableResolutions( ILookup <TypeParameterName, TypeParameterName> mayBeReplaced, TypeParameterResolutions.Builder combinedBuilder, TypeParameterName typeParam, ResolvedType paramRes) { // Create a dictionary with just the current resolution in it. var singleResolution = new[] { 0 }.ToImmutableDictionary(_ => typeParam, _ => paramRes); // Get all the parameters whose value is dependent on the current resolution's type parameter, // and update their values with this resolution's value. foreach (var keyInCombined in mayBeReplaced[typeParam]) { // Check that we are not constricting a type parameter to another type parameter of the same callable. this.UpdateConstrictionFlag(keyInCombined, paramRes); combinedBuilder[keyInCombined] = ResolvedType.ResolveTypeParameters(singleResolution, combinedBuilder[keyInCombined]); } }
public void ArraysAreNothingElse(string baseTypeId, string expected1DId, string expected2DId) { foreach (var id in new[] { expected1DId, expected2DId }) { var sut = TypeUtils.CreateTypeName(id); Assert.IsFalse(sut.IsClassType); Assert.IsFalse(sut.IsDelegateType); Assert.IsFalse(sut.IsEnumType); Assert.IsFalse(sut.IsInterfaceType); Assert.IsFalse(sut.IsNestedType); Assert.IsFalse(sut.IsNullableType); Assert.IsTrue(sut.IsReferenceType); Assert.IsTrue(sut.IsArray); Assert.IsFalse(sut.IsSimpleType); Assert.IsFalse(sut.IsStructType); Assert.IsFalse(sut.IsValueType); Assert.IsFalse(sut.IsVoidType); Assert.IsFalse(sut.IsTypeParameter); Assert.IsFalse(sut.IsDelegateType); Assert.IsFalse(sut.IsPredefined); Assert.IsFalse(TypeName.IsTypeNameIdentifier(id)); Assert.IsFalse(TypeUtils.IsUnknownTypeIdentifier(id)); Assert.IsFalse(DelegateTypeName.IsDelegateTypeNameIdentifier(id)); if (TypeParameterName.IsTypeParameterNameIdentifier(baseTypeId)) { Assert.IsTrue(TypeParameterName.IsTypeParameterNameIdentifier(id)); } if (PredefinedTypeName.IsPredefinedTypeNameIdentifier(baseTypeId)) { Assert.IsTrue(PredefinedTypeName.IsPredefinedTypeNameIdentifier(id)); } if (DelegateTypeName.IsDelegateTypeNameIdentifier(baseTypeId)) { Assert.IsFalse(DelegateTypeName.IsDelegateTypeNameIdentifier(id)); } } }
// Static Members /// <summary> /// Checks if the given type parameter directly resolves to itself. /// </summary> private static bool IsSelfResolution(TypeParameterName typeParam, ResolvedType res) { return(res.Resolution is ResolvedTypeKind.TypeParameter tp && tp.Item.Origin.Equals(typeParam.Item1) && tp.Item.TypeName.Equals(typeParam.Item2)); }
public void CannotBeInitializedAsUnknownType() { // ReSharper disable once ObjectCreationAsStatement new TypeParameterName("?"); Assert.IsFalse(TypeParameterName.IsTypeParameterNameIdentifier("?")); }
public void ShouldCrashIfConversionIsNotAppropriate_NonArray() { // ReSharper disable once UnusedVariable var n = new TypeParameterName("T").AsArrayTypeName; }
public void IsNoTypeParameterId(string typeId) { Assert.IsFalse(TypeParameterName.IsTypeParameterNameIdentifier(typeId)); }
private void AppendAssertsForTypeName(ITypeName t) { _sb.AppendLine("String id = \"{0}\";".FormatEx(t.Identifier)); _sb.Append("assertEquals(") .AppendBool(TypeUtils.IsUnknownTypeIdentifier(t.Identifier)) .AppendLine(", TypeUtils.isUnknownTypeIdentifier(id));"); _sb.Append("assertEquals(") .AppendBool(TypeName.IsTypeNameIdentifier(t.Identifier)) .AppendLine(", TypeName.isTypeNameIdentifier(id));"); _sb.Append("assertEquals(") .AppendBool(ArrayTypeName.IsArrayTypeNameIdentifier(t.Identifier)) .AppendLine(", ArrayTypeName.isArrayTypeNameIdentifier(id));"); _sb.Append("assertEquals(") .AppendBool(TypeParameterName.IsTypeParameterNameIdentifier(t.Identifier)) .AppendLine(", TypeParameterName.isTypeParameterNameIdentifier(id));"); _sb.Append("assertEquals(") .AppendBool(DelegateTypeName.IsDelegateTypeNameIdentifier(t.Identifier)) .AppendLine(", DelegateTypeName.isDelegateTypeNameIdentifier(id));"); _sb.Append("assertEquals(") .AppendBool(PredefinedTypeName.IsPredefinedTypeNameIdentifier(t.Identifier)) .AppendLine(", PredefinedTypeName.isPredefinedTypeNameIdentifier(id));"); _sb.AppendLine("ITypeName sut = TypeUtils.createTypeName(id);"); _sb.AppendLine("assertTrue(sut instanceof {0});".FormatEx(t.GetType().Name)); _sb.AppendAreEqual(t.IsHashed, "sut.isHashed()"); _sb.AppendAreEqual(t.IsUnknown, "sut.isUnknown()"); _sb.AppendAreEqual(t.Namespace, "sut.getNamespace()"); _sb.AppendAreEqual(t.Assembly, "sut.getAssembly()"); _sb.AppendAreEqual(t.FullName, "sut.getFullName()"); _sb.AppendAreEqual(t.Name, "sut.getName()"); _sb.AppendAreEqual(t.IsClassType, "sut.isClassType()"); _sb.AppendAreEqual(t.IsEnumType, "sut.isEnumType()"); _sb.AppendAreEqual(t.IsInterfaceType, "sut.isInterfaceType()"); _sb.AppendAreEqual(t.IsNullableType, "sut.isNullableType()"); _sb.AppendAreEqual(t.IsPredefined, "sut.isPredefined()"); _sb.AppendAreEqual(t.IsReferenceType, "sut.isReferenceType()"); _sb.AppendAreEqual(t.IsSimpleType, "sut.isSimpleType()"); _sb.AppendAreEqual(t.IsStructType, "sut.isStructType()"); _sb.AppendAreEqual(t.IsTypeParameter, "sut.isTypeParameter()"); _sb.AppendAreEqual(t.IsValueType, "sut.isValueType()"); _sb.AppendAreEqual(t.IsVoidType, "sut.isVoidType()"); _sb.AppendAreEqual(t.IsNestedType, "sut.isNestedType()"); _sb.AppendAreEqual(t.DeclaringType, "sut.getDeclaringType()"); _sb.AppendAreEqual(t.HasTypeParameters, "sut.hasTypeParameters()"); _sb.AppendAreEqual(t.TypeParameters, "sut.getTypeParameters()"); // used for several checks; _sb.AppendLine("boolean hasThrown;"); // array _sb.Comment("array"); _sb.AppendAreEqual(t.IsArray, "sut.isArray()"); if (t.IsArray) { var tArr = t.AsArrayTypeName; _sb.AppendLine("IArrayTypeName sutArr = sut.asArrayTypeName();"); _sb.AppendAreEqual(tArr.Rank, "sutArr.getRank()"); _sb.AppendAreEqual(tArr.ArrayBaseType, "sutArr.getArrayBaseType()"); } else { _sb.AppendThrowValidation("sut.asArrayTypeName();", "AssertionException"); } // delegates _sb.Comment("delegates"); _sb.AppendAreEqual(t.IsDelegateType, "sut.isDelegateType()"); if (t.IsDelegateType) { var tD = t.AsDelegateTypeName; _sb.AppendLine("IDelegateTypeName sutD = sut.asDelegateTypeName();"); _sb.AppendAreEqual(tD.DelegateType, "sutD.getDelegateType()"); _sb.AppendAreEqual(tD.HasParameters, "sutD.hasParameters()"); _sb.AppendAreEqual(tD.IsRecursive, "sutD.isRecursive()"); _sb.AppendAreEqual(tD.Parameters, "sutD.getParameters()"); _sb.AppendAreEqual(tD.ReturnType, "sutD.getReturnType()"); } else { _sb.AppendThrowValidation("sut.asDelegateTypeName();", "AssertionException"); } // predefined _sb.Comment("predefined"); _sb.AppendAreEqual(t.IsPredefined, "sut.isPredefined()"); if (t.IsPredefined) { var sutP = t.AsPredefinedTypeName; _sb.AppendLine("IPredefinedTypeName sutP = sut.asPredefinedTypeName();"); _sb.AppendAreEqual(sutP.FullType, "sutP.getFullType()"); } else { _sb.AppendThrowValidation("sut.asPredefinedTypeName();", "AssertionException"); } // type parameters _sb.Comment("type parameters"); _sb.AppendAreEqual(t.IsTypeParameter, "sut.isTypeParameter()"); if (t.IsTypeParameter) { var sutT = t.AsTypeParameterName; _sb.AppendLine("ITypeParameterName sutT = sut.asTypeParameterName();"); _sb.AppendAreEqual(sutT.IsBound, "sutT.isBound()"); _sb.AppendAreEqual(sutT.TypeParameterShortName, "sutT.getTypeParameterShortName()"); _sb.AppendAreEqual(sutT.TypeParameterType, "sutT.getTypeParameterType()"); } else { _sb.AppendThrowValidation("sut.asTypeParameterName();", "AssertionException"); } }
// Methods /// <summary> /// Updates the combinesOverParameterConstriction flag. If the flag is already set to true, /// nothing will be done. If not, the given type parameter will be checked against the given /// resolution for type parameter constriction, which is when one type parameter is dependent /// on another type parameter of the same callable. /// </summary> private void UpdateConstrictionFlag(TypeParameterName typeParamName, ResolvedType typeParamResolution) { this.combinesOverParameterConstriction = this.combinesOverParameterConstriction || CheckForConstriction.IsConstrictiveResolution(typeParamName, typeParamResolution); }
private CheckForConstriction(TypeParameterName typeParamName) : base(new TransformationState(), TransformationOptions.NoRebuild) { this.typeParamName = typeParamName; }