Example #1
0
        private static void StructDependsClosure(NamedTypeSymbol type, HashSet <Symbol> partialClosure, NamedTypeSymbol on)
        {
            Debug.Assert((object)type != null);

            if ((object)type.OriginalDefinition == on)
            {
                // found a possibly expanding cycle, for example
                //     struct X<T> { public T t; }
                //     struct W<T> { X<W<W<T>>> x; }
                // while not explicitly forbidden by the spec, it should be.
                partialClosure.Add(on);
                return;
            }

            if (partialClosure.Add(type))
            {
                foreach (var member in type.GetMembersUnordered())
                {
                    var field = member as FieldSymbol;
                    if ((object)field == null || field.Type.TypeKind != TypeKind.Struct || field.IsStatic)
                    {
                        continue;
                    }

                    StructDependsClosure((NamedTypeSymbol)field.Type.TypeSymbol, partialClosure, on);
                }
            }
        }
Example #2
0
        /// <summary>
        /// Accumulate diagnostics related to the variance safety of an interface.
        /// </summary>
        internal static void CheckInterfaceVarianceSafety(this NamedTypeSymbol interfaceType, DiagnosticBag diagnostics)
        {
            Debug.Assert((object)interfaceType != null && interfaceType.IsInterface);

            foreach (NamedTypeSymbol baseInterface in interfaceType.InterfacesNoUseSiteDiagnostics())
            {
                IsVarianceUnsafe(
                    baseInterface,
                    requireOutputSafety: true,
                    requireInputSafety: false,
                    context: baseInterface,
                    locationProvider: i => null,
                    locationArg: baseInterface,
                    diagnostics: diagnostics);
            }

            foreach (Symbol member in interfaceType.GetMembersUnordered())
            {
                switch (member.Kind)
                {
                case SymbolKind.Method:
                    if (!member.IsAccessor())
                    {
                        CheckMethodVarianceSafety((MethodSymbol)member, diagnostics);
                    }
                    break;

                case SymbolKind.Property:
                    CheckPropertyVarianceSafety((PropertySymbol)member, diagnostics);
                    break;

                case SymbolKind.Event:
                    CheckEventVarianceSafety((EventSymbol)member, diagnostics);
                    break;
                }
            }
        }