コード例 #1
0
        /// <summary>
        /// Substitute types, and return the results without duplicates, preserving the original order.
        /// Note, all occurrences of 'dynamic' in resulting types will be replaced with 'object'.
        /// </summary>
        internal void SubstituteConstraintTypesDistinctWithoutModifiers(
            TypeParameterSymbol owner,
            ImmutableArray <TypeWithAnnotations> original,
            ArrayBuilder <TypeWithAnnotations> result,
            HashSet <TypeParameterSymbol> ignoreTypesDependentOnTypeParametersOpt)
        {
            DynamicTypeEraser dynamicEraser = null;

            if (original.Length == 0)
            {
                return;
            }
            else if (original.Length == 1)
            {
                var type = original[0];
                if (ignoreTypesDependentOnTypeParametersOpt == null ||
                    !type.Type.ContainsTypeParameters(ignoreTypesDependentOnTypeParametersOpt))
                {
                    result.Add(substituteConstraintType(type));
                }
            }
            else
            {
                var map = PooledDictionary <TypeSymbol, int> .GetInstance();

                foreach (var type in original)
                {
                    if (ignoreTypesDependentOnTypeParametersOpt == null ||
                        !type.Type.ContainsTypeParameters(ignoreTypesDependentOnTypeParametersOpt))
                    {
                        var substituted = substituteConstraintType(type);

                        if (!map.TryGetValue(substituted.Type, out int mergeWith))
                        {
                            map.Add(substituted.Type, result.Count);
                            result.Add(substituted);
                        }
                        else
                        {
                            result[mergeWith] = ConstraintsHelper.ConstraintWithMostSignificantNullability(result[mergeWith], substituted);
                        }
                    }
                }

                map.Free();
            }

            TypeWithAnnotations substituteConstraintType(TypeWithAnnotations type)
            {
                if (dynamicEraser == null)
                {
                    dynamicEraser = new DynamicTypeEraser(owner.ContainingAssembly.CorLibrary.GetSpecialType(SpecialType.System_Object));
                }

                TypeWithAnnotations substituted = SubstituteType(type);

                return(substituted.WithTypeAndModifiers(dynamicEraser.EraseDynamic(substituted.Type), substituted.CustomModifiers));
            }
        }
コード例 #2
0
        internal override ImmutableArray <TypeWithAnnotations> GetConstraintTypes(ConsList <TypeParameterSymbol> inProgress, bool canIgnoreNullableContext)
        {
            var constraintTypes = ArrayBuilder <TypeWithAnnotations> .GetInstance();

            _map.SubstituteConstraintTypesDistinctWithoutModifiers(_underlyingTypeParameter, _underlyingTypeParameter.GetConstraintTypes(inProgress, canIgnoreNullableContext), constraintTypes, null);

            TypeWithAnnotations bestObjectConstraint = default;

            // Strip all Object constraints.
            for (int i = constraintTypes.Count - 1; i >= 0; i--)
            {
                TypeWithAnnotations type = constraintTypes[i];
                if (ConstraintsHelper.IsObjectConstraint(type, ref bestObjectConstraint))
                {
                    constraintTypes.RemoveAt(i);
                }
            }

            if (bestObjectConstraint.HasType)
            {
                // See if we need to put Object! or Object~ back in order to preserve nullability information for the type parameter.
                if (!canIgnoreNullableContext && ConstraintsHelper.IsObjectConstraintSignificant(CalculateIsNotNullableFromNonTypeConstraints(), bestObjectConstraint))
                {
                    Debug.Assert(!HasNotNullConstraint && !HasValueTypeConstraint);
                    if (constraintTypes.Count == 0)
                    {
                        if (bestObjectConstraint.NullableAnnotation.IsOblivious() && !HasReferenceTypeConstraint)
                        {
                            bestObjectConstraint = default;
                        }
                    }
                    else
                    {
                        foreach (TypeWithAnnotations constraintType in constraintTypes)
                        {
                            if (!ConstraintsHelper.IsObjectConstraintSignificant(IsNotNullableFromConstraintType(constraintType, out _), bestObjectConstraint))
                            {
                                bestObjectConstraint = default;
                                break;
                            }
                        }
                    }

                    if (bestObjectConstraint.HasType)
                    {
                        constraintTypes.Insert(0, bestObjectConstraint);
                    }
                }
            }

            return(constraintTypes.ToImmutableAndFree());
        }
コード例 #3
0
        public override ImmutableArray <TypeParameterConstraintClause> GetTypeParameterConstraintClauses(bool early)
        {
            var clauses = _lazyTypeParameterConstraints;

            if (clauses.IsDefault)
            {
                // Early step.
                var diagnostics = DiagnosticBag.GetInstance();
                var constraints = this.MakeTypeParameterConstraintsEarly(
                    _binder,
                    TypeParameters,
                    _syntax.TypeParameterList,
                    _syntax.ConstraintClauses,
                    _syntax.Identifier.GetLocation(),
                    diagnostics);
                lock (_declarationDiagnostics)
                {
                    if (_lazyTypeParameterConstraints.IsDefault)
                    {
                        _declarationDiagnostics.AddRange(diagnostics);
                        _lazyTypeParameterConstraints = constraints;
                    }
                }
                diagnostics.Free();
                clauses = _lazyTypeParameterConstraints;
            }

            if (!early && clauses.IsEarly())
            {
                // Late step.
                var diagnostics = DiagnosticBag.GetInstance();
                var constraints = ConstraintsHelper.MakeTypeParameterConstraintsLate(TypeParameters, clauses, diagnostics);
                Debug.Assert(!constraints.IsEarly());
                lock (_declarationDiagnostics)
                {
                    if (_lazyTypeParameterConstraints.IsEarly())
                    {
                        _declarationDiagnostics.AddRange(diagnostics);
                        _lazyTypeParameterConstraints = constraints;
                    }
                }
                diagnostics.Free();
            }

            return(_lazyTypeParameterConstraints);
        }
コード例 #4
0
ファイル: AbstractTypeMap.cs プロジェクト: bonomali/roslyn
        /// <summary>
        /// Substitute types, and return the results without duplicates, preserving the original order.
        /// </summary>
        internal void SubstituteConstraintTypesDistinctWithoutModifiers(
            ImmutableArray <TypeWithAnnotations> original,
            ArrayBuilder <TypeWithAnnotations> result,
            HashSet <TypeParameterSymbol> ignoreTypesDependentOnTypeParametersOpt)
        {
            if (original.Length == 0)
            {
                return;
            }
            else if (original.Length == 1)
            {
                var type = original[0];
                if (ignoreTypesDependentOnTypeParametersOpt == null ||
                    !type.Type.ContainsTypeParameters(ignoreTypesDependentOnTypeParametersOpt))
                {
                    result.Add(SubstituteType(type));
                }
            }
            else
            {
                var map = PooledDictionary <TypeSymbol, int> .GetInstance();

                foreach (var type in original)
                {
                    if (ignoreTypesDependentOnTypeParametersOpt == null ||
                        !type.Type.ContainsTypeParameters(ignoreTypesDependentOnTypeParametersOpt))
                    {
                        var substituted = SubstituteType(type);

                        if (!map.TryGetValue(substituted.Type, out int mergeWith))
                        {
                            map.Add(substituted.Type, result.Count);
                            result.Add(substituted);
                        }
                        else
                        {
                            result[mergeWith] = ConstraintsHelper.ConstraintWithMostSignificantNullability(result[mergeWith], substituted);
                        }
                    }
                }

                map.Free();
            }
        }