bool IsAttributeRedundant(Attribute attribute)
            {
                var section           = attribute.GetParent <AttributeSection>();
                var targetDeclaration = section.Parent;

                if (targetDeclaration is FixedFieldDeclaration)
                {
                    //Fixed fields are never null
                    return(true);
                }

                var fieldDeclaration = targetDeclaration as FieldDeclaration;

                if (fieldDeclaration != null)
                {
                    return(fieldDeclaration.Variables.All(variable => NullableType.IsNonNullableValueType(ctx.Resolve(variable).Type)));
                }

                var resolveResult       = ctx.Resolve(targetDeclaration);
                var memberResolveResult = resolveResult as MemberResolveResult;

                if (memberResolveResult != null)
                {
                    return(NullableType.IsNonNullableValueType(memberResolveResult.Member.ReturnType));
                }
                var localResolveResult = resolveResult as LocalResolveResult;

                if (localResolveResult != null)
                {
                    return(NullableType.IsNonNullableValueType(localResolveResult.Type));
                }

                return(false);
            }
示例#2
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);
            }
示例#3
0
 internal static bool ValidateConstraints(ITypeParameter typeParameter, IType typeArgument, TypeVisitor substitution, CSharpConversions conversions)
 {
     switch (typeArgument.Kind)               // void, null, and pointers cannot be used as type arguments
     {
     case TypeKind.Void:
     case TypeKind.Null:
     case TypeKind.Pointer:
         return(false);
     }
     if (typeParameter.HasReferenceTypeConstraint)
     {
         if (typeArgument.IsReferenceType != true)
         {
             return(false);
         }
     }
     if (typeParameter.HasValueTypeConstraint)
     {
         if (!NullableType.IsNonNullableValueType(typeArgument))
         {
             return(false);
         }
     }
     if (typeParameter.HasDefaultConstructorConstraint)
     {
         ITypeDefinition def = typeArgument.GetDefinition();
         if (def != null && def.IsAbstract)
         {
             return(false);
         }
         var ctors = typeArgument.GetConstructors(
             m => m.Parameters.Count == 0 && m.Accessibility == Accessibility.Public,
             GetMemberOptions.IgnoreInheritedMembers | GetMemberOptions.ReturnMemberDefinitions
             );
         if (!ctors.Any())
         {
             return(false);
         }
     }
     foreach (IType constraintType in typeParameter.DirectBaseTypes)
     {
         IType c = constraintType;
         if (substitution != null)
         {
             c = c.AcceptVisitor(substitution);
         }
         if (!conversions.IsConstraintConvertible(typeArgument, c))
         {
             return(false);
         }
     }
     return(true);
 }
示例#4
0
        List <OperatorInfo> GetApplicableConversionOperators(IType fromType, IType toType, bool isExplicit)
        {
            // Find the candidate operators:
            Predicate <IUnresolvedMethod> opFilter;

            if (isExplicit)
            {
                opFilter = m => m.IsStatic && m.IsOperator && m.Name == "op_Explicit" && m.Parameters.Count == 1;
            }
            else
            {
                opFilter = m => m.IsStatic && m.IsOperator && m.Name == "op_Implicit" && m.Parameters.Count == 1;
            }

            var operators = NullableType.GetUnderlyingType(fromType).GetMethods(opFilter)
                            .Concat(NullableType.GetUnderlyingType(toType).GetMethods(opFilter)).Distinct();
            // Determine whether one of them is applicable:
            List <OperatorInfo> result = new List <OperatorInfo>();

            foreach (IMethod op in operators)
            {
                IType sourceType = op.Parameters[0].Type;
                IType targetType = op.ReturnType;
                // Try if the operator is applicable:
                bool isApplicable;
                if (isExplicit)
                {
                    isApplicable = IsEncompassingOrEncompassedBy(fromType, sourceType) &&
                                   IsEncompassingOrEncompassedBy(targetType, toType);
                }
                else
                {
                    isApplicable = IsEncompassedBy(fromType, sourceType) && IsEncompassedBy(targetType, toType);
                }
                if (isApplicable)
                {
                    result.Add(new OperatorInfo(op, sourceType, targetType, false));
                }
                // Try if the operator is applicable in lifted form:
                if (NullableType.IsNonNullableValueType(sourceType) &&
                    NullableType.IsNonNullableValueType(targetType))
                {
                    IType liftedSourceType = NullableType.Create(compilation, sourceType);
                    IType liftedTargetType = NullableType.Create(compilation, targetType);
                    if (isExplicit)
                    {
                        isApplicable = IsEncompassingOrEncompassedBy(fromType, liftedSourceType) &&
                                       IsEncompassingOrEncompassedBy(liftedTargetType, toType);
                    }
                    else
                    {
                        isApplicable = IsEncompassedBy(fromType, liftedSourceType) && IsEncompassedBy(liftedTargetType, toType);
                    }
                    if (isApplicable)
                    {
                        result.Add(new OperatorInfo(op, liftedSourceType, liftedTargetType, true));
                    }
                }
            }
            return(result);
        }