If a virtual "clone" method is present in the base record, the synthesized "clone" method overrides it and the return type of the method is the current containing type if the "covariant returns" feature is supported and the override return type otherwise. An error is produced if the base record clone method is sealed. If a virtual "clone" method is not present in the base record, the return type of the clone method is the containing type and the method is virtual, unless the record is sealed or abstract. If the containing record is abstract, the synthesized clone method is also abstract. If the "clone" method is not abstract, it returns the result of a call to a copy constructor.
Inheritance: Microsoft.CodeAnalysis.CSharp.Symbols.SynthesizedRecordOrdinaryMethod
Esempio n. 1
0
        protected override void CheckBase(DiagnosticBag diagnostics)
        {
            var localBase = this.BaseTypeNoUseSiteDiagnostics;

            if ((object)localBase == null)
            {
                // nothing to verify
                return;
            }

            Location baseLocation           = null;
            bool     baseContainsErrorTypes = localBase.ContainsErrorType();

            if (!baseContainsErrorTypes)
            {
                baseLocation = FindBaseRefSyntax(localBase);
                Debug.Assert(!this.IsClassType() || localBase.IsObjectType() || baseLocation != null);
            }

            // you need to know all bases before you can ask this question... (asking this causes a cycle)
            if (this.IsGenericType && !baseContainsErrorTypes && this.DeclaringCompilation.IsAttributeType(localBase))
            {
                // A generic type cannot derive from '{0}' because it is an attribute class
                diagnostics.Add(ErrorCode.ERR_GenericDerivingFromAttribute, baseLocation, localBase);
            }

            // Check constraints on the first declaration with explicit bases.
            var singleDeclaration = this.FirstDeclarationWithExplicitBases();

            if (singleDeclaration != null)
            {
                var corLibrary  = this.ContainingAssembly.CorLibrary;
                var conversions = new TypeConversions(corLibrary);
                var location    = singleDeclaration.NameLocation;

                localBase.CheckAllConstraints(DeclaringCompilation, conversions, location, diagnostics);
            }

            // Records can only inherit from other records or object
            if (this.IsClassType() && !localBase.IsObjectType() && !baseContainsErrorTypes)
            {
                HashSet <DiagnosticInfo> useSiteDiagnostics = null;

                if (declaration.Kind == DeclarationKind.Record)
                {
                    if (SynthesizedRecordClone.FindValidCloneMethod(localBase, ref useSiteDiagnostics) is null ||
                        SynthesizedRecordPrintMembers.FindValidPrintMembersMethod(localBase, DeclaringCompilation) is null)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadRecordBase, baseLocation);
                    }
                }
                else if (SynthesizedRecordClone.FindValidCloneMethod(localBase, ref useSiteDiagnostics) is object)
                {
                    diagnostics.Add(ErrorCode.ERR_BadInheritanceFromRecord, baseLocation);
                }

                diagnostics.Add(baseLocation, useSiteDiagnostics);
            }
        }
        protected override void CheckBase(BindingDiagnosticBag diagnostics)
        {
            var localBase = this.BaseTypeNoUseSiteDiagnostics;

            if ((object)localBase == null)
            {
                // nothing to verify
                return;
            }

            Location baseLocation           = null;
            bool     baseContainsErrorTypes = localBase.ContainsErrorType();

            if (!baseContainsErrorTypes)
            {
                baseLocation = FindBaseRefSyntax(localBase);
                Debug.Assert(!this.IsClassType() || localBase.IsObjectType() || baseLocation != null);
            }

            // you need to know all bases before you can ask this question... (asking this causes a cycle)
            if (this.IsGenericType && !baseContainsErrorTypes && this.DeclaringCompilation.IsAttributeType(localBase))
            {
                MessageID.IDS_FeatureGenericAttributes.CheckFeatureAvailability(diagnostics, this.DeclaringCompilation, baseLocation);
            }

            // Check constraints on the first declaration with explicit bases.
            var singleDeclaration = this.FirstDeclarationWithExplicitBases();

            if (singleDeclaration != null)
            {
                var corLibrary  = this.ContainingAssembly.CorLibrary;
                var conversions = new TypeConversions(corLibrary);
                var location    = singleDeclaration.NameLocation;

                localBase.CheckAllConstraints(DeclaringCompilation, conversions, location, diagnostics);
            }

            // Records can only inherit from other records or object
            if (this.IsClassType() && !localBase.IsObjectType() && !baseContainsErrorTypes)
            {
                var useSiteInfo = new CompoundUseSiteInfo <AssemblySymbol>(diagnostics, ContainingAssembly);

                if (declaration.Kind == DeclarationKind.Record)
                {
                    if (SynthesizedRecordClone.FindValidCloneMethod(localBase, ref useSiteInfo) is null)
                    {
                        diagnostics.Add(ErrorCode.ERR_BadRecordBase, baseLocation);
                    }
                }
                else if (SynthesizedRecordClone.FindValidCloneMethod(localBase, ref useSiteInfo) is object)
                {
                    diagnostics.Add(ErrorCode.ERR_BadInheritanceFromRecord, baseLocation);
                }

                diagnostics.Add(baseLocation, useSiteInfo);
            }
        }