/// <summary>
        /// Returns the constraint clause for the given type parameter.
        /// The `early` parameter indicates whether the clauses can be from the first phase of constraint
        /// checking where the constraint types may still contain invalid or duplicate types.
        /// </summary>
        internal TypeParameterConstraintClause GetTypeParameterConstraintClause(bool early, int ordinal)
        {
            var clauses = _lazyTypeParameterConstraints;

            if (clauses.IsDefault)
            {
                // Early step.
                var diagnostics = DiagnosticBag.GetInstance();
                if (ImmutableInterlocked.InterlockedInitialize(ref _lazyTypeParameterConstraints, MakeTypeParameterConstraintsEarly(diagnostics)))
                {
                    this.AddDeclarationDiagnostics(diagnostics);
                }
                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());
                if (ImmutableInterlocked.InterlockedCompareExchange(ref _lazyTypeParameterConstraints, constraints, clauses) == clauses)
                {
                    this.AddDeclarationDiagnostics(diagnostics);
                }
                diagnostics.Free();
                clauses = _lazyTypeParameterConstraints;
            }

            return((clauses.Length > 0) ? clauses[ordinal] : TypeParameterConstraintClause.Empty);
        }
Beispiel #2
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.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);
        }