Esempio n. 1
0
        private TypeParameterBounds GetBounds(ConsList <TypeParameterSymbol> inProgress, bool early)
        {
            Debug.Assert(!inProgress.ContainsReference(this));
            Debug.Assert(!inProgress.Any() || ReferenceEquals(inProgress.Head.ContainingSymbol, this.ContainingSymbol));

            var currentBounds = _lazyBounds;

            if (!currentBounds.IsSet(early))
            {
                var diagnostics = DiagnosticBag.GetInstance();
                var bounds      = this.ResolveBounds(inProgress, early, diagnostics);

                if (ReferenceEquals(Interlocked.CompareExchange(ref _lazyBounds, bounds, currentBounds), currentBounds))
                {
                    if (_lazyBounds?.IsEarly != true)
                    {
                        this.CheckConstraintTypeConstraints(diagnostics);
                        this.CheckUnmanagedConstraint(diagnostics);
                        this.CheckNullableAnnotationsInConstraints(diagnostics);
                        this.AddDeclarationDiagnostics(diagnostics);
                        _state.NotePartComplete(CompletionPart.TypeParameterConstraints);
                    }
                }

                diagnostics.Free();
            }

            return(_lazyBounds);
        }
        private TypeParameterBounds GetBounds(ConsList <TypeParameterSymbol> inProgress, bool canIgnoreNullableContext)
        {
            Debug.Assert(!inProgress.ContainsReference(this));
            Debug.Assert(!inProgress.Any() || ReferenceEquals(inProgress.Head.ContainingSymbol, this.ContainingSymbol));

            if (!_lazyBounds.HasValue(canIgnoreNullableContext))
            {
                var diagnostics = DiagnosticBag.GetInstance();
                var bounds      = this.ResolveBounds(inProgress, canIgnoreNullableContext, diagnostics);

                if (TypeParameterBoundsExtensions.InterlockedUpdate(ref _lazyBounds, bounds) &&
                    _lazyBounds.HasValue(canIgnoreNullableContext: false))
                {
                    this.CheckConstraintTypeConstraints(diagnostics);
                    this.CheckUnmanagedConstraint(diagnostics);
                    this.EnsureAttributesFromConstraints(diagnostics);
                    this.AddDeclarationDiagnostics(diagnostics);
                    _state.NotePartComplete(CompletionPart.TypeParameterConstraints);
                }

                diagnostics.Free();
            }

            return(_lazyBounds);
        }
Esempio n. 3
0
        private TypeParameterBounds GetBounds(ConsList <TypeParameterSymbol> inProgress, bool early)
        {
            Debug.Assert(!inProgress.ContainsReference(this));
            Debug.Assert(!inProgress.Any() || ReferenceEquals(inProgress.Head.ContainingSymbol, this.ContainingSymbol));

            var currentBounds = _lazyBounds;

            if (currentBounds == TypeParameterBounds.Unset)
            {
                var constraintTypes = GetDeclaredConstraintTypes();
                Debug.Assert(!constraintTypes.IsDefault);
                var bounds = new TypeParameterBounds(constraintTypes);
                Interlocked.CompareExchange(ref _lazyBounds, bounds, currentBounds);
                currentBounds = _lazyBounds;
            }

            if (!currentBounds.IsSet(early))
            {
                var constraintTypes = currentBounds.ConstraintTypes;
                var diagnostics     = ArrayBuilder <TypeParameterDiagnosticInfo> .GetInstance();

                ArrayBuilder <TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
                bool inherited = (_containingSymbol.Kind == SymbolKind.Method) && ((MethodSymbol)_containingSymbol).IsOverride;
                var  bounds    = this.ResolveBounds(this.ContainingAssembly.CorLibrary, inProgress.Prepend(this), constraintTypes, inherited, currentCompilation: null,
                                                    diagnosticsBuilder: diagnostics, useSiteDiagnosticsBuilder: ref useSiteDiagnosticsBuilder);
                DiagnosticInfo errorInfo = null;

                if (diagnostics.Count > 0)
                {
                    errorInfo = diagnostics[0].DiagnosticInfo;
                }
                else if (useSiteDiagnosticsBuilder != null && useSiteDiagnosticsBuilder.Count > 0)
                {
                    foreach (var diag in useSiteDiagnosticsBuilder)
                    {
                        if (diag.DiagnosticInfo.Severity == DiagnosticSeverity.Error)
                        {
                            errorInfo = diag.DiagnosticInfo;
                            break;
                        }
                        else if ((object)errorInfo == null)
                        {
                            errorInfo = diag.DiagnosticInfo;
                        }
                    }
                }

                diagnostics.Free();

                Interlocked.CompareExchange(ref _lazyConstraintsUseSiteErrorInfo, errorInfo, CSDiagnosticInfo.EmptyErrorInfo);
                Interlocked.CompareExchange(ref _lazyBounds, bounds, currentBounds);
            }

            return(_lazyBounds);
        }
        private static ConsList<FieldSymbol> SubstituteFields(ConsList<FieldSymbol> fields, TypeMap typeMap)
        {
            if (!fields.Any())
            {
                return ConsList<FieldSymbol>.Empty;
            }

            var head = SubstituteField(fields.Head, typeMap);
            var tail = SubstituteFields(fields.Tail, typeMap);
            return tail.Prepend(head);
        }
        internal DisplayClassVariable(string name, DisplayClassVariableKind kind, DisplayClassInstance displayClassInstance, ConsList<FieldSymbol> displayClassFields)
        {
            Debug.Assert(displayClassFields.Any());

            this.Name = name;
            this.Kind = kind;
            this.DisplayClassInstance = displayClassInstance;
            this.DisplayClassFields = displayClassFields;

            // Verify all type parameters are substituted.
            Debug.Assert(this.ContainingSymbol.IsContainingSymbolOfAllTypeParameters(this.Type));
        }
Esempio n. 6
0
        internal DisplayClassVariable(string name, DisplayClassVariableKind kind, DisplayClassInstance displayClassInstance, ConsList <FieldSymbol> displayClassFields)
        {
            Debug.Assert(displayClassFields.Any());

            this.Name = name;
            this.Kind = kind;
            this.DisplayClassInstance = displayClassInstance;
            this.DisplayClassFields   = displayClassFields;

            // Verify all type parameters are substituted.
            Debug.Assert(this.ContainingSymbol.IsContainingSymbolOfAllTypeParameters(this.Type));
        }
Esempio n. 7
0
        private static ConsList <FieldSymbol> SubstituteFields(ConsList <FieldSymbol> fields, TypeMap typeMap)
        {
            if (!fields.Any())
            {
                return(ConsList <FieldSymbol> .Empty);
            }

            var head = SubstituteField(fields.Head, typeMap);
            var tail = SubstituteFields(fields.Tail, typeMap);

            return(tail.Prepend(head));
        }
        private TypeParameterBounds GetBounds(ConsList <TypeParameterSymbol> inProgress)
        {
            Debug.Assert(!inProgress.ContainsReference(this));
            Debug.Assert(!inProgress.Any() || ReferenceEquals(inProgress.Head.ContainingSymbol, this.ContainingSymbol));

            if (ReferenceEquals(_lazyBounds, TypeParameterBounds.Unset))
            {
                var constraintTypes = GetDeclaredConstraintTypes();
                Debug.Assert(!constraintTypes.IsDefault);

                //var diagnostics = ArrayBuilder<TypeParameterDiagnosticInfo>.GetInstance();
                //ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
                bool inherited = (_containingSymbol.Kind == SymbolKind.Method) && ((MethodSymbol)_containingSymbol).IsOverride;
                //var bounds = this.ResolveBounds(this.ContainingAssembly.CorLibrary, inProgress.Prepend(this), constraintTypes, inherited, currentCompilation: null,
                //                                diagnosticsBuilder: diagnostics, useSiteDiagnosticsBuilder: ref useSiteDiagnosticsBuilder);
                var bounds = new TypeParameterBounds(ImmutableArray <TypeSymbol> .Empty, ImmutableArray <NamedTypeSymbol> .Empty, null, null);
                //DiagnosticInfo errorInfo = null;

                //if (diagnostics.Count > 0)
                //{
                //    errorInfo = diagnostics[0].DiagnosticInfo;
                //}
                //else if (useSiteDiagnosticsBuilder != null && useSiteDiagnosticsBuilder.Count > 0)
                //{
                //    foreach (var diag in useSiteDiagnosticsBuilder)
                //    {
                //        if (diag.DiagnosticInfo.Severity == DiagnosticSeverity.Error)
                //        {
                //            errorInfo = diag.DiagnosticInfo;
                //            break;
                //        }
                //        else if ((object)errorInfo == null)
                //        {
                //            errorInfo = diag.DiagnosticInfo;
                //        }
                //    }
                //}

                //diagnostics.Free();

                //Interlocked.CompareExchange(ref _lazyBoundsErrorInfo, errorInfo, CSDiagnosticInfo.EmptyErrorInfo);
                Interlocked.CompareExchange(ref _lazyBounds, bounds, TypeParameterBounds.Unset);
            }

            //Debug.Assert(!ReferenceEquals(_lazyBoundsErrorInfo, CSDiagnosticInfo.EmptyErrorInfo));
            return(_lazyBounds);
        }
Esempio n. 9
0
        // removes region directives from stack but leaves everything else
        private static ConsList <Directive> CompleteRegion(ConsList <Directive> stack)
        {
            // if we get to the top, the default rule is to include anything that follows
            if (!stack.Any())
            {
                return(stack);
            }

            if (stack.Head.Kind == SyntaxKind.RegionDirectiveTrivia)
            {
                return(stack.Tail);
            }

            var newStack = CompleteRegion(stack.Tail);

            newStack = new ConsList <Directive>(stack.Head, newStack);
            return(newStack);
        }
Esempio n. 10
0
        private static ConsList <Directive> SkipInsignificantDirectives(ConsList <Directive> directives)
        {
            for (; directives != null && directives.Any(); directives = directives.Tail)
            {
                switch (directives.Head.Kind)
                {
                case SyntaxKind.IfDirectiveTrivia:
                case SyntaxKind.ElifDirectiveTrivia:
                case SyntaxKind.ElseDirectiveTrivia:
                case SyntaxKind.EndIfDirectiveTrivia:
                case SyntaxKind.DefineDirectiveTrivia:
                case SyntaxKind.UndefDirectiveTrivia:
                case SyntaxKind.RegionDirectiveTrivia:
                case SyntaxKind.EndRegionDirectiveTrivia:
                    return(directives);
                }
            }

            return(directives);
        }
Esempio n. 11
0
        // removes unfinished if & related directives from stack and leaves active branch directives
        private static ConsList <Directive> CompleteIf(DirectiveTriviaSyntax branchEndSyntax, ConsList <Directive> stack, out bool include)
        {
            // if we get to the top, the default rule is to include anything that follows
            if (!stack.Any())
            {
                include = true;
                return(stack);
            }

            // if we reach the #if directive, then we stop unwinding and start
            // rebuilding the stack w/o the #if/#elif/#else/#endif directives
            // only including content from sections that are considered included
            var head = stack.Head;

            if (head.Kind.IsIfLikeDirective())
            {
                include        = head.BranchTaken;
                head.BranchEnd = branchEndSyntax;
                return(stack.Tail);
            }

            var newStack = CompleteIf(branchEndSyntax, stack.Tail, out include);

            switch (stack.Head.Kind)
            {
            case SyntaxKind.ElifDirectiveTrivia:
            case SyntaxKind.ElseDirectiveTrivia:
                include = stack.Head.BranchTaken;
                break;

            default:
                if (include)
                {
                    newStack = new ConsList <Directive>(head, newStack);
                }

                break;
            }

            return(newStack);
        }
Esempio n. 12
0
        private TypeParameterBounds GetBounds(ConsList <TypeParameterSymbol> inProgress)
        {
            Debug.Assert(!inProgress.ContainsReference(this));
            Debug.Assert(!inProgress.Any() || ReferenceEquals(inProgress.Head.ContainingSymbol, this.ContainingSymbol));

            if (ReferenceEquals(_lazyBounds, TypeParameterBounds.Unset))
            {
                var diagnostics = DiagnosticBag.GetInstance();
                var bounds      = this.ResolveBounds(inProgress, diagnostics);

                if (ReferenceEquals(Interlocked.CompareExchange(ref _lazyBounds, bounds, TypeParameterBounds.Unset), TypeParameterBounds.Unset))
                {
                    this.CheckConstraintTypeConstraints(diagnostics);
                    this.AddDeclarationDiagnostics(diagnostics);
                    _state.NotePartComplete(CompletionPart.TypeParameterConstraints);
                }

                diagnostics.Free();
            }
            return(_lazyBounds);
        }
        private ImmutableArray <TypeWithAnnotations> GetDeclaredConstraintTypes(ConsList <PETypeParameterSymbol> inProgress)
        {
            Debug.Assert(!inProgress.ContainsReference(this));
            Debug.Assert(!inProgress.Any() || ReferenceEquals(inProgress.Head.ContainingSymbol, this.ContainingSymbol));

            if (_lazyDeclaredConstraintTypes.IsDefault)
            {
                ImmutableArray <TypeWithAnnotations> declaredConstraintTypes;

                var      moduleSymbol = ((PEModuleSymbol)this.ContainingModule);
                PEModule peModule     = moduleSymbol.Module;
                GenericParameterConstraintHandleCollection constraints = GetConstraintHandleCollection(peModule);

                bool hasUnmanagedModreqPattern = false;

                if (constraints.Count > 0)
                {
                    var symbolsBuilder = ArrayBuilder <TypeWithAnnotations> .GetInstance();

                    MetadataDecoder tokenDecoder = GetDecoder(moduleSymbol);

                    TypeWithAnnotations bestObjectConstraint = default;

                    var metadataReader = peModule.MetadataReader;
                    foreach (var constraintHandle in constraints)
                    {
                        TypeWithAnnotations type = GetConstraintTypeOrDefault(moduleSymbol, metadataReader, tokenDecoder, constraintHandle, ref hasUnmanagedModreqPattern);

                        if (!type.HasType)
                        {
                            // Dropped 'System.ValueType' constraint type when the 'valuetype' constraint was also specified.
                            continue;
                        }

                        // Drop 'System.Object' constraint type.
                        if (ConstraintsHelper.IsObjectConstraint(type, ref bestObjectConstraint))
                        {
                            continue;
                        }

                        symbolsBuilder.Add(type);
                    }

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

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

                    declaredConstraintTypes = symbolsBuilder.ToImmutableAndFree();
                }
                else
                {
                    declaredConstraintTypes = ImmutableArray <TypeWithAnnotations> .Empty;
                }

                // - presence of unmanaged pattern has to be matched with `valuetype`
                // - IsUnmanagedAttribute is allowed iff there is an unmanaged pattern
                if (hasUnmanagedModreqPattern && (_flags & GenericParameterAttributes.NotNullableValueTypeConstraint) == 0 ||
                    hasUnmanagedModreqPattern != peModule.HasIsUnmanagedAttribute(_handle))
                {
                    // we do not recognize these combinations as "unmanaged"
                    hasUnmanagedModreqPattern = false;
                    _lazyCachedConstraintsUseSiteInfo.InterlockedCompareExchange(primaryDependency: null, new UseSiteInfo <AssemblySymbol>(new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this)));
                }

                _lazyHasIsUnmanagedConstraint = hasUnmanagedModreqPattern.ToThreeState();
                ImmutableInterlocked.InterlockedInitialize(ref _lazyDeclaredConstraintTypes, declaredConstraintTypes);
            }

            return(_lazyDeclaredConstraintTypes);
        }
Esempio n. 14
0
        // removes region directives from stack but leaves everything else
        private static ConsList<Directive> CompleteRegion(ConsList<Directive> stack)
        {
            // if we get to the top, the default rule is to include anything that follows
            if (!stack.Any())
            {
                return stack;
            }

            if (stack.Head.Kind == SyntaxKind.RegionDirectiveTrivia)
            {
                return stack.Tail;
            }

            var newStack = CompleteRegion(stack.Tail);
            newStack = new ConsList<Directive>(stack.Head, newStack);
            return newStack;
        }
Esempio n. 15
0
        private static ConsList<Directive> SkipInsignificantDirectives(ConsList<Directive> directives)
        {
            for (; directives != null && directives.Any(); directives = directives.Tail)
            {
                switch (directives.Head.Kind)
                {
                    case SyntaxKind.IfDirectiveTrivia:
                    case SyntaxKind.ElifDirectiveTrivia:
                    case SyntaxKind.ElseDirectiveTrivia:
                    case SyntaxKind.EndIfDirectiveTrivia:
                    case SyntaxKind.DefineDirectiveTrivia:
                    case SyntaxKind.UndefDirectiveTrivia:
                    case SyntaxKind.RegionDirectiveTrivia:
                    case SyntaxKind.EndRegionDirectiveTrivia:
                        return directives;
                }
            }

            return directives;
        }
Esempio n. 16
0
        // removes unfinished if & related directives from stack and leaves active branch directives
        private static ConsList<Directive> CompleteIf(ConsList<Directive> stack, out bool include)
        {
            // if we get to the top, the default rule is to include anything that follows
            if (!stack.Any())
            {
                include = true;
                return stack;
            }

            // if we reach the #if directive, then we stop unwinding and start
            // rebuilding the stack w/o the #if/#elif/#else/#endif directives
            // only including content from sections that are considered included
            if (stack.Head.Kind.IsIfLikeDirective())
            {
                include = stack.Head.BranchTaken;
                return stack.Tail;
            }

            var newStack = CompleteIf(stack.Tail, out include);
            switch (stack.Head.Kind)
            {
                case SyntaxKind.ElifDirectiveTrivia:
                case SyntaxKind.ElseDirectiveTrivia:
                    include = stack.Head.BranchTaken;
                    break;
                default:
                    if (include)
                    {
                        newStack = new ConsList<Directive>(stack.Head, newStack);
                    }

                    break;
            }

            return newStack;
        }
Esempio n. 17
0
        private TypeParameterBounds GetBounds(ConsList<TypeParameterSymbol> inProgress)
        {
            Debug.Assert(!inProgress.ContainsReference(this));
            Debug.Assert(!inProgress.Any() || ReferenceEquals(inProgress.Head.ContainingSymbol, this.ContainingSymbol));

            if (ReferenceEquals(_lazyBounds, TypeParameterBounds.Unset))
            {
                var constraintTypes = GetDeclaredConstraintTypes();
                Debug.Assert(!constraintTypes.IsDefault);

                var diagnostics = ArrayBuilder<TypeParameterDiagnosticInfo>.GetInstance();
                ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null;
                bool inherited = (_containingSymbol.Kind == SymbolKind.Method) && ((MethodSymbol)_containingSymbol).IsOverride;
                var bounds = this.ResolveBounds(this.ContainingAssembly.CorLibrary, inProgress.Prepend(this), constraintTypes, inherited, currentCompilation: null,
                                                diagnosticsBuilder: diagnostics, useSiteDiagnosticsBuilder: ref useSiteDiagnosticsBuilder);
                DiagnosticInfo errorInfo = null;

                if (diagnostics.Count > 0)
                {
                    errorInfo = diagnostics[0].DiagnosticInfo;
                }
                else if (useSiteDiagnosticsBuilder != null && useSiteDiagnosticsBuilder.Count > 0)
                {
                    foreach (var diag in useSiteDiagnosticsBuilder)
                    {
                        if (diag.DiagnosticInfo.Severity == DiagnosticSeverity.Error)
                        {
                            errorInfo = diag.DiagnosticInfo;
                            break;
                        }
                        else if ((object)errorInfo == null)
                        {
                            errorInfo = diag.DiagnosticInfo;
                        }
                    }
                }

                diagnostics.Free();

                Interlocked.CompareExchange(ref _lazyBoundsErrorInfo, errorInfo, CSDiagnosticInfo.EmptyErrorInfo);
                Interlocked.CompareExchange(ref _lazyBounds, bounds, TypeParameterBounds.Unset);
            }

            Debug.Assert(!ReferenceEquals(_lazyBoundsErrorInfo, CSDiagnosticInfo.EmptyErrorInfo));
            return _lazyBounds;
        }
Esempio n. 18
0
 private static string GetDebuggerDisplay(string expr, ConsList <FieldSymbol> fields)
 {
     return(fields.Any()
       ? $"{GetDebuggerDisplay(expr, fields.Tail)}.{fields.Head.Name}"
       : expr);
 }
        private TypeParameterBounds GetBounds(ConsList<TypeParameterSymbol> inProgress)
        {
            Debug.Assert(!inProgress.ContainsReference(this));
            Debug.Assert(!inProgress.Any() || ReferenceEquals(inProgress.Head.ContainingSymbol, this.ContainingSymbol));

            if (ReferenceEquals(_lazyBounds, TypeParameterBounds.Unset))
            {
                var diagnostics = DiagnosticBag.GetInstance();
                var bounds = this.ResolveBounds(inProgress, diagnostics);

                if (ReferenceEquals(Interlocked.CompareExchange(ref _lazyBounds, bounds, TypeParameterBounds.Unset), TypeParameterBounds.Unset))
                {
                    this.CheckConstraintTypeConstraints(diagnostics);
                    this.AddDeclarationDiagnostics(diagnostics);
                    _state.NotePartComplete(CompletionPart.TypeParameterConstraints);
                }

                diagnostics.Free();
            }
            return _lazyBounds;
        }