Example #1
0
        internal override void GenerateMethodBody(TypeCompilationState compilationState, BindingDiagnosticBag diagnostics)
        {
            ImmutableArray <LocalSymbol> declaredLocalsArray;
            var body        = _generateMethodBody(this, diagnostics.DiagnosticBag, out declaredLocalsArray, out _lazyResultProperties);
            var compilation = compilationState.Compilation;

            _lazyReturnType = TypeWithAnnotations.Create(CalculateReturnType(compilation, body));

            // Can't do this until the return type has been computed.
            TypeParameterChecker.Check(this, _allTypeParameters);

            if (diagnostics.HasAnyErrors())
            {
                return;
            }

            DiagnosticsPass.IssueDiagnostics(compilation, body, diagnostics, this);
            if (diagnostics.HasAnyErrors())
            {
                return;
            }

            // Check for use-site diagnostics (e.g. missing types in the signature).
            UseSiteInfo <AssemblySymbol> useSiteInfo = default;

            this.CalculateUseSiteDiagnostic(ref useSiteInfo);
            if (useSiteInfo.DiagnosticInfo != null && useSiteInfo.DiagnosticInfo.Severity == DiagnosticSeverity.Error)
            {
                diagnostics.Add(useSiteInfo.DiagnosticInfo, this.Locations[0]);
                return;
            }

            try
            {
                var declaredLocals = PooledHashSet <LocalSymbol> .GetInstance();

                try
                {
                    // Rewrite local declaration statement.
                    body = (BoundStatement)LocalDeclarationRewriter.Rewrite(
                        compilation,
                        _container,
                        declaredLocals,
                        body,
                        declaredLocalsArray,
                        diagnostics.DiagnosticBag);

                    // Verify local declaration names.
                    foreach (var local in declaredLocals)
                    {
                        Debug.Assert(local.Locations.Length > 0);
                        var name = local.Name;
                        if (name.StartsWith("$", StringComparison.Ordinal))
                        {
                            diagnostics.Add(ErrorCode.ERR_UnexpectedCharacter, local.Locations[0], name[0]);
                            return;
                        }
                    }

                    // Rewrite references to placeholder "locals".
                    body = (BoundStatement)PlaceholderLocalRewriter.Rewrite(compilation, _container, declaredLocals, body, diagnostics.DiagnosticBag);

                    if (diagnostics.HasAnyErrors())
                    {
                        return;
                    }
                }
                finally
                {
                    declaredLocals.Free();
                }

                var syntax            = body.Syntax;
                var statementsBuilder = ArrayBuilder <BoundStatement> .GetInstance();

                statementsBuilder.Add(body);
                // Insert an implicit return statement if necessary.
                if (body.Kind != BoundKind.ReturnStatement)
                {
                    statementsBuilder.Add(new BoundReturnStatement(syntax, RefKind.None, expressionOpt: null));
                }

                var localsSet = PooledHashSet <LocalSymbol> .GetInstance();

                try
                {
                    var localsBuilder = ArrayBuilder <LocalSymbol> .GetInstance();

                    foreach (var local in this.LocalsForBinding)
                    {
                        Debug.Assert(!localsSet.Contains(local));
                        localsBuilder.Add(local);
                        localsSet.Add(local);
                    }
                    foreach (var local in this.Locals)
                    {
                        if (localsSet.Add(local))
                        {
                            localsBuilder.Add(local);
                        }
                    }

                    body = new BoundBlock(syntax, localsBuilder.ToImmutableAndFree(), statementsBuilder.ToImmutableAndFree())
                    {
                        WasCompilerGenerated = true
                    };

                    Debug.Assert(!diagnostics.HasAnyErrors());
                    Debug.Assert(!body.HasErrors);

                    bool sawLambdas;
                    bool sawLocalFunctions;
                    bool sawAwaitInExceptionHandler;
                    ImmutableArray <SourceSpan> dynamicAnalysisSpans = ImmutableArray <SourceSpan> .Empty;
                    body = LocalRewriter.Rewrite(
                        compilation: this.DeclaringCompilation,
                        method: this,
                        methodOrdinal: _methodOrdinal,
                        containingType: _container,
                        statement: body,
                        compilationState: compilationState,
                        previousSubmissionFields: null,
                        allowOmissionOfConditionalCalls: false,
                        instrumentForDynamicAnalysis: false,
                        debugDocumentProvider: null,
                        dynamicAnalysisSpans: ref dynamicAnalysisSpans,
                        diagnostics: diagnostics,
                        sawLambdas: out sawLambdas,
                        sawLocalFunctions: out sawLocalFunctions,
                        sawAwaitInExceptionHandler: out sawAwaitInExceptionHandler);

                    Debug.Assert(!sawAwaitInExceptionHandler);
                    Debug.Assert(dynamicAnalysisSpans.Length == 0);

                    if (body.HasErrors)
                    {
                        return;
                    }

                    // Variables may have been captured by lambdas in the original method
                    // or in the expression, and we need to preserve the existing values of
                    // those variables in the expression. This requires rewriting the variables
                    // in the expression based on the closure classes from both the original
                    // method and the expression, and generating a preamble that copies
                    // values into the expression closure classes.
                    //
                    // Consider the original method:
                    // static void M()
                    // {
                    //     int x, y, z;
                    //     ...
                    //     F(() => x + y);
                    // }
                    // and the expression in the EE: "F(() => x + z)".
                    //
                    // The expression is first rewritten using the closure class and local <1>
                    // from the original method: F(() => <1>.x + z)
                    // Then lambda rewriting introduces a new closure class that includes
                    // the locals <1> and z, and a corresponding local <2>: F(() => <2>.<1>.x + <2>.z)
                    // And a preamble is added to initialize the fields of <2>:
                    //     <2> = new <>c__DisplayClass0();
                    //     <2>.<1> = <1>;
                    //     <2>.z = z;

                    // Rewrite "this" and "base" references to parameter in this method.
                    // Rewrite variables within body to reference existing display classes.
                    body = (BoundStatement)CapturedVariableRewriter.Rewrite(
                        this.GenerateThisReference,
                        compilation.Conversions,
                        _displayClassVariables,
                        body,
                        diagnostics.DiagnosticBag);

                    if (body.HasErrors)
                    {
                        Debug.Assert(false, "Please add a test case capturing whatever caused this assert.");
                        return;
                    }

                    if (diagnostics.HasAnyErrors())
                    {
                        return;
                    }

                    if (sawLambdas || sawLocalFunctions)
                    {
                        var closureDebugInfoBuilder = ArrayBuilder <ClosureDebugInfo> .GetInstance();

                        var lambdaDebugInfoBuilder = ArrayBuilder <LambdaDebugInfo> .GetInstance();

                        body = ClosureConversion.Rewrite(
                            loweredBody: body,
                            thisType: this.SubstitutedSourceMethod.ContainingType,
                            thisParameter: _thisParameter,
                            method: this,
                            methodOrdinal: _methodOrdinal,
                            substitutedSourceMethod: this.SubstitutedSourceMethod.OriginalDefinition,
                            closureDebugInfoBuilder: closureDebugInfoBuilder,
                            lambdaDebugInfoBuilder: lambdaDebugInfoBuilder,
                            slotAllocatorOpt: null,
                            compilationState: compilationState,
                            diagnostics: diagnostics,
                            assignLocals: localsSet);

                        // we don't need this information:
                        closureDebugInfoBuilder.Free();
                        lambdaDebugInfoBuilder.Free();
                    }
                }
                finally
                {
                    localsSet.Free();
                }

                // Insert locals from the original method,
                // followed by any new locals.
                var block        = (BoundBlock)body;
                var localBuilder = ArrayBuilder <LocalSymbol> .GetInstance();

                foreach (var local in this.Locals)
                {
                    Debug.Assert(!(local is EELocalSymbol) || (((EELocalSymbol)local).Ordinal == localBuilder.Count));
                    localBuilder.Add(local);
                }
                foreach (var local in block.Locals)
                {
                    if (local is EELocalSymbol oldLocal)
                    {
                        Debug.Assert(localBuilder[oldLocal.Ordinal] == oldLocal);
                        continue;
                    }
                    localBuilder.Add(local);
                }

                body = block.Update(localBuilder.ToImmutableAndFree(), block.LocalFunctions, block.Statements);
                TypeParameterChecker.Check(body, _allTypeParameters);
                compilationState.AddSynthesizedMethod(this, body);
            }
            catch (BoundTreeVisitor.CancelledByStackGuardException ex)
            {
                ex.AddAnError(diagnostics);
            }
        }
        private DeclarationModifiers MakeModifiers(SyntaxTokenList modifiers, MethodKind methodKind, bool hasBody, Location location, BindingDiagnosticBag diagnostics, out bool modifierErrors)
        {
            var defaultAccess = (methodKind == MethodKind.StaticConstructor) ? DeclarationModifiers.None : DeclarationModifiers.Private;

            // Check that the set of modifiers is allowed
            const DeclarationModifiers allowedModifiers =
                DeclarationModifiers.AccessibilityMask |
                DeclarationModifiers.Static |
                DeclarationModifiers.Extern |
                DeclarationModifiers.Unsafe;

            var mods = ModifierUtils.MakeAndCheckNontypeMemberModifiers(modifiers, defaultAccess, allowedModifiers, location, diagnostics, out modifierErrors);

            this.CheckUnsafeModifier(mods, diagnostics);

            if (methodKind == MethodKind.StaticConstructor)
            {
                // Don't report ERR_StaticConstructorWithAccessModifiers if the ctor symbol name doesn't match the containing type name.
                // This avoids extra unnecessary errors.
                // There will already be a diagnostic saying Method must have a return type.
                if ((mods & DeclarationModifiers.AccessibilityMask) != 0 &&
                    ContainingType.Name == ((ConstructorDeclarationSyntax)this.SyntaxNode).Identifier.ValueText)
                {
                    diagnostics.Add(ErrorCode.ERR_StaticConstructorWithAccessModifiers, location, this);
                    mods           = mods & ~DeclarationModifiers.AccessibilityMask;
                    modifierErrors = true;
                }

                mods |= DeclarationModifiers.Private; // we mark static constructors private in the symbol table

                if (this.ContainingType.IsInterface)
                {
                    ModifierUtils.ReportDefaultInterfaceImplementationModifiers(hasBody, mods,
                                                                                DeclarationModifiers.Extern,
                                                                                location, diagnostics);
                }
            }

            return(mods);
        }
Example #3
0
 public SynthesizedRecordToString(SourceMemberContainerTypeSymbol containingType, MethodSymbol printMethod, int memberOffset, BindingDiagnosticBag diagnostics)
     : base(containingType, WellKnownMemberNames.ObjectToString, memberOffset, diagnostics)
 {
     Debug.Assert(printMethod is object);
     _printMethod = printMethod;
 }
 private SynthesizedEmbeddedNativeIntegerAttributeSymbol CreateNativeIntegerAttributeSymbol(string name, NamespaceSymbol containingNamespace, BindingDiagnosticBag diagnostics)
 => new SynthesizedEmbeddedNativeIntegerAttributeSymbol(
     name,
     containingNamespace,
     SourceModule,
     GetWellKnownType(WellKnownType.System_Attribute, diagnostics),
     GetSpecialType(SpecialType.System_Boolean, diagnostics));
Example #5
0
        private static Symbol FindExplicitlyImplementedMember(
            Symbol implementingMember,
            TypeSymbol explicitInterfaceType,
            string interfaceMemberName,
            ExplicitInterfaceSpecifierSyntax explicitInterfaceSpecifierSyntax,
            BindingDiagnosticBag diagnostics
            )
        {
            if ((object)explicitInterfaceType == null)
            {
                return(null);
            }

            var memberLocation = implementingMember.Locations[0];
            var containingType = implementingMember.ContainingType;

            switch (containingType.TypeKind)
            {
            case TypeKind.Class:
            case TypeKind.Struct:
            case TypeKind.Interface:
                break;

            default:
                diagnostics.Add(
                    ErrorCode.ERR_ExplicitInterfaceImplementationInNonClassOrStruct,
                    memberLocation,
                    implementingMember
                    );
                return(null);
            }

            if (!explicitInterfaceType.IsInterfaceType())
            {
                //we'd like to highlight just the type part of the name
                var explicitInterfaceSyntax = explicitInterfaceSpecifierSyntax.Name;
                var location = new SourceLocation(explicitInterfaceSyntax);

                diagnostics.Add(
                    ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface,
                    location,
                    explicitInterfaceType
                    );
                return(null);
            }

            var explicitInterfaceNamedType = (NamedTypeSymbol)explicitInterfaceType;

            // 13.4.1: "For an explicit interface member implementation to be valid, the class or struct must name an
            // interface in its base class list that contains a member ..."
            MultiDictionary <NamedTypeSymbol, NamedTypeSymbol> .ValueSet set =
                containingType.InterfacesAndTheirBaseInterfacesNoUseSiteDiagnostics[
                    explicitInterfaceNamedType
                ];
            int setCount = set.Count;

            if (
                setCount == 0 ||
                !set.Contains(
                    explicitInterfaceNamedType,
                    Symbols.SymbolEqualityComparer.ObliviousNullableModifierMatchesAny
                    )
                )
            {
                //we'd like to highlight just the type part of the name
                var explicitInterfaceSyntax = explicitInterfaceSpecifierSyntax.Name;
                var location = new SourceLocation(explicitInterfaceSyntax);

                if (
                    setCount > 0 &&
                    set.Contains(
                        explicitInterfaceNamedType,
                        Symbols.SymbolEqualityComparer.IgnoringNullable
                        )
                    )
                {
                    diagnostics.Add(
                        ErrorCode.WRN_NullabilityMismatchInExplicitlyImplementedInterface,
                        location
                        );
                }
                else
                {
                    diagnostics.Add(
                        ErrorCode.ERR_ClassDoesntImplementInterface,
                        location,
                        implementingMember,
                        explicitInterfaceNamedType
                        );
                }
                //do a lookup anyway
            }

            // Do not look in itself
            if (containingType == (object)explicitInterfaceNamedType.OriginalDefinition)
            {
                // An error will be reported elsewhere.
                // Either the interface is not implemented, or it causes a cycle in the interface hierarchy.
                return(null);
            }

            var hasParamsParam = implementingMember.HasParamsParameter();

            // Setting this flag to true does not imply that an interface member has been successfully implemented.
            // It just indicates that a corresponding interface member has been found (there may still be errors).
            var foundMatchingMember = false;

            Symbol implementedMember = null;

            foreach (
                Symbol interfaceMember in explicitInterfaceNamedType.GetMembers(interfaceMemberName)
                )
            {
                // At this point, we know that explicitInterfaceNamedType is an interface.
                // However, metadata interface members can be static - we ignore them, as does Dev10.
                if (
                    interfaceMember.Kind != implementingMember.Kind ||
                    !interfaceMember.IsImplementableInterfaceMember()
                    )
                {
                    continue;
                }

                if (
                    MemberSignatureComparer.ExplicitImplementationComparer.Equals(
                        implementingMember,
                        interfaceMember
                        )
                    )
                {
                    foundMatchingMember = true;
                    // Cannot implement accessor directly unless
                    // the accessor is from an indexed property.
                    if (
                        interfaceMember.IsAccessor() &&
                        !((MethodSymbol)interfaceMember).IsIndexedPropertyAccessor()
                        )
                    {
                        diagnostics.Add(
                            ErrorCode.ERR_ExplicitMethodImplAccessor,
                            memberLocation,
                            implementingMember,
                            interfaceMember
                            );
                    }
                    else
                    {
                        if (interfaceMember.MustCallMethodsDirectly())
                        {
                            diagnostics.Add(
                                ErrorCode.ERR_BogusExplicitImpl,
                                memberLocation,
                                implementingMember,
                                interfaceMember
                                );
                        }
                        else if (hasParamsParam && !interfaceMember.HasParamsParameter())
                        {
                            // Note: no error for !hasParamsParam && interfaceMethod.HasParamsParameter()
                            // Still counts as an implementation.
                            diagnostics.Add(
                                ErrorCode.ERR_ExplicitImplParams,
                                memberLocation,
                                implementingMember,
                                interfaceMember
                                );
                        }

                        implementedMember = interfaceMember;
                        break;
                    }
                }
            }

            if (!foundMatchingMember)
            {
                // CONSIDER: we may wish to suppress this error in the event that another error
                // has been reported about the signature.
                diagnostics.Add(
                    ErrorCode.ERR_InterfaceMemberNotFound,
                    memberLocation,
                    implementingMember
                    );
            }

            // Make sure implemented member is accessible
            if ((object)implementedMember != null)
            {
                var useSiteInfo = new CompoundUseSiteInfo <AssemblySymbol>(
                    diagnostics,
                    implementingMember.ContainingAssembly
                    );

                if (
                    !AccessCheck.IsSymbolAccessible(
                        implementedMember,
                        implementingMember.ContainingType,
                        ref useSiteInfo,
                        throughTypeOpt: null
                        )
                    )
                {
                    diagnostics.Add(ErrorCode.ERR_BadAccess, memberLocation, implementedMember);
                }
                else
                {
                    switch (implementedMember.Kind)
                    {
                    case SymbolKind.Property:
                        var propertySymbol = (PropertySymbol)implementedMember;
                        checkAccessorIsAccessibleIfImplementable(propertySymbol.GetMethod);
                        checkAccessorIsAccessibleIfImplementable(propertySymbol.SetMethod);
                        break;

                    case SymbolKind.Event:
                        var eventSymbol = (EventSymbol)implementedMember;
                        checkAccessorIsAccessibleIfImplementable(eventSymbol.AddMethod);
                        checkAccessorIsAccessibleIfImplementable(eventSymbol.RemoveMethod);
                        break;
                    }

                    void checkAccessorIsAccessibleIfImplementable(MethodSymbol accessor)
                    {
                        if (
                            accessor.IsImplementable() &&
                            !AccessCheck.IsSymbolAccessible(
                                accessor,
                                implementingMember.ContainingType,
                                ref useSiteInfo,
                                throughTypeOpt: null
                                )
                            )
                        {
                            diagnostics.Add(ErrorCode.ERR_BadAccess, memberLocation, accessor);
                        }
                    }
                }

                diagnostics.Add(memberLocation, useSiteInfo);
            }

            return(implementedMember);
        }
 public SynthesizedRecordObjEquals(SourceMemberContainerTypeSymbol containingType, MethodSymbol typedRecordEquals, int memberOffset, BindingDiagnosticBag diagnostics)
     : base(containingType, WellKnownMemberNames.ObjectEquals, memberOffset, isReadOnly: containingType.IsRecordStruct, diagnostics)
 {
     _typedRecordEquals = typedRecordEquals;
 }
        private void CreateEmbeddedAttributesIfNeeded(BindingDiagnosticBag diagnostics)
        {
            EmbeddableAttributes needsAttributes = GetNeedsGeneratedAttributes();

            if (ShouldEmitNullablePublicOnlyAttribute() &&
                Compilation.CheckIfAttributeShouldBeEmbedded(EmbeddableAttributes.NullablePublicOnlyAttribute, diagnostics, Location.None))
            {
                needsAttributes |= EmbeddableAttributes.NullablePublicOnlyAttribute;
            }
            else if (needsAttributes == 0)
            {
                return;
            }

            var createParameterlessEmbeddedAttributeSymbol = new Func <string, NamespaceSymbol, BindingDiagnosticBag, SynthesizedEmbeddedAttributeSymbol>(CreateParameterlessEmbeddedAttributeSymbol);

            CreateAttributeIfNeeded(
                ref _lazyEmbeddedAttribute,
                diagnostics,
                AttributeDescription.CodeAnalysisEmbeddedAttribute,
                createParameterlessEmbeddedAttributeSymbol);

            if ((needsAttributes & EmbeddableAttributes.IsReadOnlyAttribute) != 0)
            {
                CreateAttributeIfNeeded(
                    ref _lazyIsReadOnlyAttribute,
                    diagnostics,
                    AttributeDescription.IsReadOnlyAttribute,
                    createParameterlessEmbeddedAttributeSymbol);
            }

            if ((needsAttributes & EmbeddableAttributes.IsByRefLikeAttribute) != 0)
            {
                CreateAttributeIfNeeded(
                    ref _lazyIsByRefLikeAttribute,
                    diagnostics,
                    AttributeDescription.IsByRefLikeAttribute,
                    createParameterlessEmbeddedAttributeSymbol);
            }

            if ((needsAttributes & EmbeddableAttributes.IsUnmanagedAttribute) != 0)
            {
                CreateAttributeIfNeeded(
                    ref _lazyIsUnmanagedAttribute,
                    diagnostics,
                    AttributeDescription.IsUnmanagedAttribute,
                    createParameterlessEmbeddedAttributeSymbol);
            }

            if ((needsAttributes & EmbeddableAttributes.NullableAttribute) != 0)
            {
                CreateAttributeIfNeeded(
                    ref _lazyNullableAttribute,
                    diagnostics,
                    AttributeDescription.NullableAttribute,
                    CreateNullableAttributeSymbol);
            }

            if ((needsAttributes & EmbeddableAttributes.NullableContextAttribute) != 0)
            {
                CreateAttributeIfNeeded(
                    ref _lazyNullableContextAttribute,
                    diagnostics,
                    AttributeDescription.NullableContextAttribute,
                    CreateNullableContextAttributeSymbol);
            }

            if ((needsAttributes & EmbeddableAttributes.NullablePublicOnlyAttribute) != 0)
            {
                CreateAttributeIfNeeded(
                    ref _lazyNullablePublicOnlyAttribute,
                    diagnostics,
                    AttributeDescription.NullablePublicOnlyAttribute,
                    CreateNullablePublicOnlyAttributeSymbol);
            }

            if ((needsAttributes & EmbeddableAttributes.NativeIntegerAttribute) != 0)
            {
                Debug.Assert(Compilation.ShouldEmitNativeIntegerAttributes());
                CreateAttributeIfNeeded(
                    ref _lazyNativeIntegerAttribute,
                    diagnostics,
                    AttributeDescription.NativeIntegerAttribute,
                    CreateNativeIntegerAttributeSymbol);
            }
        }
Example #8
0
 internal abstract ConstantValue GetConstantValue(
     SyntaxNode node,
     LocalSymbol inProgress,
     BindingDiagnosticBag diagnostics = null
     );
Example #9
0
        internal override void GenerateMethodBody(TypeCompilationState compilationState, BindingDiagnosticBag diagnostics)
        {
            SyntheticBoundNodeFactory F = new SyntheticBoundNodeFactory(this, this.GetNonNullSyntaxNode(), compilationState, diagnostics);

            F.CurrentFunction = this;

            try
            {
                ParameterSymbol argument  = this.Parameters[0];
                ParameterSymbol paramName = this.Parameters[1];

                //if (argument is null)
                //{
                //    Throw(paramName);
                //}

                var body = F.Block(
                    ImmutableArray <LocalSymbol> .Empty,
                    F.If(
                        F.Binary(BinaryOperatorKind.ObjectEqual, F.SpecialType(SpecialType.System_Boolean),
                                 F.Parameter(argument),
                                 F.Null(argument.Type)),
                        F.ExpressionStatement(F.Call(receiver: null, ThrowMethod, F.Parameter(paramName)))),
                    F.Return());

                // NOTE: we created this block in its most-lowered form, so analysis is unnecessary
                F.CloseMethod(body);
            }
            catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex)
            {
                diagnostics.Add(ex.Diagnostic);
                F.CloseMethod(F.ThrowNull());
            }
        }
Example #10
0
 protected sealed override void MethodChecks(BindingDiagnosticBag diagnostics)
 {
     base.MethodChecks(diagnostics);
     VerifyOverridesMethodFromObject(this, OverriddenSpecialMember, diagnostics);
 }
Example #11
0
        /// <summary>
        /// Returns true if reported an error
        /// </summary>
        internal static bool VerifyOverridesMethodFromObject(MethodSymbol overriding, SpecialMember overriddenSpecialMember, BindingDiagnosticBag diagnostics)
        {
            bool reportAnError = false;

            if (!overriding.IsOverride)
            {
                reportAnError = true;
            }
            else
            {
                var overridden = overriding.OverriddenMethod?.OriginalDefinition;

                if (overridden is object && !(overridden.ContainingType is SourceMemberContainerTypeSymbol {
                    IsRecord : true
                } && overridden.ContainingModule == overriding.ContainingModule))
Example #12
0
        protected sealed override DeclarationModifiers MakeDeclarationModifiers(DeclarationModifiers allowedModifiers, BindingDiagnosticBag diagnostics)
        {
            const DeclarationModifiers result = DeclarationModifiers.Public | DeclarationModifiers.Override;

            Debug.Assert((result & ~allowedModifiers) == 0);
            return(result);
        }
Example #13
0
 protected SynthesizedRecordObjectMethod(SourceMemberContainerTypeSymbol containingType, string name, int memberOffset, bool isReadOnly, BindingDiagnosticBag diagnostics)
     : base(containingType, name, isReadOnly: isReadOnly, hasBody: true, memberOffset, diagnostics)
 {
 }
Example #14
0
        private NamespaceOrTypeSymbol ResolveAliasTarget(NameSyntax?syntax, BindingDiagnosticBag diagnostics, ConsList <TypeSymbol>?basesBeingResolved)
        {
            var declarationBinder = _binder.WithAdditionalFlags(BinderFlags.SuppressConstraintChecks | BinderFlags.SuppressObsoleteChecks);

            return(declarationBinder.BindNamespaceOrTypeSymbol(syntax, diagnostics, basesBeingResolved).NamespaceOrTypeSymbol);
        }
Example #15
0
        internal override void GenerateMethodBody(TypeCompilationState compilationState, BindingDiagnosticBag diagnostics)
        {
            var F = new SyntheticBoundNodeFactory(this, ContainingType.GetNonNullSyntaxNode(), compilationState, diagnostics);

            try
            {
                var             other = F.Parameter(Parameters[0]);
                BoundExpression?retExpr;

                // This method is the strongly-typed Equals method where the parameter type is
                // the containing type.

                if (ContainingType.BaseTypeNoUseSiteDiagnostics.IsObjectType())
                {
                    if (_equalityContract.GetMethod is null)
                    {
                        // The equality contract isn't usable, an error was reported elsewhere
                        F.CloseMethod(F.ThrowNull());
                        return;
                    }

                    if (_equalityContract.IsStatic || !_equalityContract.Type.Equals(DeclaringCompilation.GetWellKnownType(WellKnownType.System_Type), TypeCompareKind.AllIgnoreOptions))
                    {
                        // There is a signature mismatch, an error was reported elsewhere
                        F.CloseMethod(F.ThrowNull());
                        return;
                    }

                    // There are no base record types.
                    // The definition of the method is as follows
                    //
                    // virtual bool Equals(T other) =>
                    //     other != null &&
                    //     EqualityContract == other.EqualityContract &&
                    //     field1 == other.field1 && ... && fieldN == other.fieldN;

                    // other != null
                    Debug.Assert(!other.Type.IsStructType());
                    retExpr = F.ObjectNotEqual(other, F.Null(F.SpecialType(SpecialType.System_Object)));

                    // EqualityContract == other.EqualityContract
                    var contractsEqual = F.Call(receiver: null, F.WellKnownMethod(WellKnownMember.System_Type__op_Equality),
                                                F.Property(F.This(), _equalityContract),
                                                F.Property(other, _equalityContract));

                    retExpr = F.LogicalAnd(retExpr, contractsEqual);
                }
                else
                {
                    MethodSymbol?baseEquals = ContainingType.GetMembersUnordered().OfType <SynthesizedRecordBaseEquals>().Single().OverriddenMethod;

                    if (baseEquals is null || !baseEquals.ContainingType.Equals(ContainingType.BaseTypeNoUseSiteDiagnostics, TypeCompareKind.AllIgnoreOptions) ||
                        baseEquals.ReturnType.SpecialType != SpecialType.System_Boolean)
                    {
                        // There was a problem with overriding of base equals, an error was reported elsewhere
                        F.CloseMethod(F.ThrowNull());
                        return;
                    }

                    // There are base record types.
                    // The definition of the method is as follows, and baseEquals
                    // is the corresponding method on the nearest base record type to
                    // delegate to:
                    //
                    // virtual bool Equals(Derived other) =>
                    //     (object)other == this || (base.Equals((Base)other) &&
                    //     field1 == other.field1 && ... && fieldN == other.fieldN);
                    retExpr = F.Call(
                        F.Base(baseEquals.ContainingType),
                        baseEquals,
                        F.Convert(baseEquals.Parameters[0].Type, other));
                }

                // field1 == other.field1 && ... && fieldN == other.fieldN
                var fields = ArrayBuilder <FieldSymbol> .GetInstance();

                bool foundBadField = false;
                foreach (var f in ContainingType.GetFieldsToEmit())
                {
                    if (!f.IsStatic)
                    {
                        fields.Add(f);

                        var parameterType = f.Type;
                        if (parameterType.IsUnsafe())
                        {
                            diagnostics.Add(ErrorCode.ERR_BadFieldTypeInRecord, f.Locations.FirstOrNone(), parameterType);
                            foundBadField = true;
                        }
                        else if (parameterType.IsRestrictedType())
                        {
                            // We'll have reported a diagnostic elsewhere (SourceMemberFieldSymbol.TypeChecks)
                            foundBadField = true;
                        }
                    }
                }
                if (fields.Count > 0 && !foundBadField)
                {
                    retExpr = MethodBodySynthesizer.GenerateFieldEquals(
                        retExpr,
                        other,
                        fields,
                        F);
                }

                fields.Free();
                retExpr = F.LogicalOr(F.ObjectEqual(F.This(), other), retExpr);
                F.CloseMethod(F.Block(F.Return(retExpr)));
            }
            catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex)
            {
                diagnostics.Add(ex.Diagnostic);
                F.CloseMethod(F.ThrowNull());
            }
        }
Example #16
0
 protected override void CheckInterfaces(BindingDiagnosticBag diagnostics)
 {
     // nop
 }
        internal SynthesizedInteractiveInitializerMethod(SourceMemberContainerTypeSymbol containingType, BindingDiagnosticBag diagnostics)
        {
            Debug.Assert(containingType.IsScriptClass);

            _containingType = containingType;
            CalculateReturnType(containingType, diagnostics, out _resultType, out _returnType);
        }
Example #18
0
        internal SimpleProgramNamedTypeSymbol(NamespaceSymbol globalNamespace, MergedTypeDeclaration declaration, BindingDiagnosticBag diagnostics)
            : base(globalNamespace, declaration, diagnostics)
        {
            Debug.Assert(globalNamespace.IsGlobalNamespace);
            Debug.Assert(declaration.Kind == DeclarationKind.SimpleProgram);
            Debug.Assert(declaration.Name == WellKnownMemberNames.TopLevelStatementsEntryPointTypeName);

            state.NotePartComplete(CompletionPart.EnumUnderlyingType); // No work to do for this.
        }
        internal override void GenerateMethodBody(TypeCompilationState compilationState, BindingDiagnosticBag diagnostics)
        {
            var F = new SyntheticBoundNodeFactory(this, this.SyntaxNode, compilationState, diagnostics);

            try
            {
                if (_typedRecordEquals.ReturnType.SpecialType != SpecialType.System_Boolean)
                {
                    // There is a signature mismatch, an error was reported elsewhere
                    F.CloseMethod(F.ThrowNull());
                    return;
                }

                var paramAccess = F.Parameter(Parameters[0]);

                BoundExpression expression;
                if (ContainingType.IsRecordStruct)
                {
                    // For record structs:
                    //      return other is R && Equals((R)other)
                    expression = F.LogicalAnd(
                        F.Is(paramAccess, ContainingType),
                        F.Call(F.This(), _typedRecordEquals, F.Convert(ContainingType, paramAccess)));
                }
                else
                {
                    // For record classes:
                    //      return this.Equals(param as ContainingType);
                    expression = F.Call(F.This(), _typedRecordEquals, F.As(paramAccess, ContainingType));
                }

                F.CloseMethod(F.Block(ImmutableArray.Create <BoundStatement>(F.Return(expression))));
            }
            catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex)
            {
                diagnostics.Add(ex.Diagnostic);
                F.CloseMethod(F.ThrowNull());
            }
        }
Example #20
0
 protected override void CheckBase(BindingDiagnosticBag diagnostics)
 {
     // check that System.Object is available.
     Binder.GetSpecialType(this.DeclaringCompilation, SpecialType.System_Object, NoLocation.Singleton, diagnostics);
 }
 private SynthesizedEmbeddedAttributeSymbol CreateParameterlessEmbeddedAttributeSymbol(string name, NamespaceSymbol containingNamespace, BindingDiagnosticBag diagnostics)
 => new SynthesizedEmbeddedAttributeSymbol(
     name,
     containingNamespace,
     SourceModule,
     baseType: GetWellKnownType(WellKnownType.System_Attribute, diagnostics));
Example #22
0
 internal abstract override void GenerateMethodBody(
     TypeCompilationState compilationState,
     BindingDiagnosticBag diagnostics
     );
        private void AddDiagnosticsForExistingAttribute(AttributeDescription description, BindingDiagnosticBag diagnostics)
        {
            var attributeMetadataName = MetadataTypeName.FromFullName(description.FullName);
            var userDefinedAttribute  = _sourceAssembly.SourceModule.LookupTopLevelMetadataType(ref attributeMetadataName);

            Debug.Assert((object)userDefinedAttribute.ContainingModule == _sourceAssembly.SourceModule);

            if (!(userDefinedAttribute is MissingMetadataTypeSymbol))
            {
                diagnostics.Add(ErrorCode.ERR_TypeReserved, userDefinedAttribute.Locations[0], description.FullName);
            }
        }
Example #24
0
 public SynthesizedRecordEquals(SourceMemberContainerTypeSymbol containingType, PropertySymbol equalityContract, int memberOffset, BindingDiagnosticBag diagnostics)
     : base(containingType, WellKnownMemberNames.ObjectEquals, hasBody: true, memberOffset, diagnostics)
 {
     _equalityContract = equalityContract;
 }
Example #25
0
        private static void FindExplicitImplementationCollisions(
            Symbol implementingMember,
            Symbol implementedMember,
            BindingDiagnosticBag diagnostics
            )
        {
            if ((object)implementedMember == null)
            {
                return;
            }

            NamedTypeSymbol explicitInterfaceType             = implementedMember.ContainingType;
            bool            explicitInterfaceTypeIsDefinition = explicitInterfaceType.IsDefinition; //no runtime ref/out ambiguities if this is true

            foreach (
                Symbol collisionCandidateMember in explicitInterfaceType.GetMembers(
                    implementedMember.Name
                    )
                )
            {
                if (
                    collisionCandidateMember.Kind == implementingMember.Kind &&
                    implementedMember != collisionCandidateMember
                    )
                {
                    // NOTE: we are more precise than Dev10 - we will not generate a diagnostic if the return types differ
                    // because that is enough to distinguish them in the runtime.
                    if (
                        !explicitInterfaceTypeIsDefinition &&
                        MemberSignatureComparer.RuntimeSignatureComparer.Equals(
                            implementedMember,
                            collisionCandidateMember
                            )
                        )
                    {
                        bool foundMismatchedRefKind = false;
                        ImmutableArray <ParameterSymbol> implementedMemberParameters =
                            implementedMember.GetParameters();
                        ImmutableArray <ParameterSymbol> collisionCandidateParameters =
                            collisionCandidateMember.GetParameters();
                        int numParams = implementedMemberParameters.Length;
                        for (int i = 0; i < numParams; i++)
                        {
                            if (
                                implementedMemberParameters[i].RefKind
                                != collisionCandidateParameters[i].RefKind
                                )
                            {
                                foundMismatchedRefKind = true;
                                break;
                            }
                        }

                        if (foundMismatchedRefKind)
                        {
                            diagnostics.Add(
                                ErrorCode.ERR_ExplicitImplCollisionOnRefOut,
                                explicitInterfaceType.Locations[0],
                                explicitInterfaceType,
                                implementedMember
                                );
                        }
                        else
                        {
                            //UNDONE: related locations for conflicting members - keep iterating to find others?
                            diagnostics.Add(
                                ErrorCode.WRN_ExplicitImplCollision,
                                implementingMember.Locations[0],
                                implementingMember
                                );
                        }
                        break;
                    }
                    else
                    {
                        if (
                            MemberSignatureComparer.ExplicitImplementationComparer.Equals(
                                implementedMember,
                                collisionCandidateMember
                                )
                            )
                        {
                            // NOTE: this is different from the same error code above.  Above, the diagnostic means that
                            // the runtime behavior is ambiguous because the runtime cannot distinguish between two or
                            // more interface members.  This diagnostic means that *C#* cannot distinguish between two
                            // or more interface members (because of custom modifiers).
                            diagnostics.Add(
                                ErrorCode.WRN_ExplicitImplCollision,
                                implementingMember.Locations[0],
                                implementingMember
                                );
                        }
                    }
                }
            }
        }
Example #26
0
        protected override DeclarationModifiers MakeDeclarationModifiers(DeclarationModifiers allowedModifiers, BindingDiagnosticBag diagnostics)
        {
            DeclarationModifiers result = DeclarationModifiers.Public | (ContainingType.IsSealed ? DeclarationModifiers.None : DeclarationModifiers.Virtual);

            Debug.Assert((result & ~allowedModifiers) == 0);
            return(result);
        }
 private void CheckModifiers(MethodKind methodKind, bool hasBody, Location location, BindingDiagnosticBag diagnostics)
 {
     if (!hasBody && !IsExtern)
     {
         diagnostics.Add(ErrorCode.ERR_ConcreteMissingBody, location, this);
     }
     else if (ContainingType.IsSealed && this.DeclaredAccessibility.HasProtected() && !this.IsOverride)
     {
         diagnostics.Add(AccessCheck.GetProtectedMemberInSealedTypeError(ContainingType), location, this);
     }
     else if (ContainingType.IsStatic && methodKind == MethodKind.Constructor)
     {
         diagnostics.Add(ErrorCode.ERR_ConstructorInStaticClass, location);
     }
 }
Example #28
0
        protected override (TypeWithAnnotations ReturnType, ImmutableArray <ParameterSymbol> Parameters, bool IsVararg, ImmutableArray <TypeParameterConstraintClause> DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics)
        {
            var compilation = DeclaringCompilation;
            var location    = ReturnTypeLocation;

            return(ReturnType : TypeWithAnnotations.Create(Binder.GetSpecialType(compilation, SpecialType.System_Boolean, location, diagnostics)),
                   Parameters : ImmutableArray.Create <ParameterSymbol>(
                       new SourceSimpleParameterSymbol(owner : this,
                                                       TypeWithAnnotations.Create(ContainingType, NullableAnnotation.Annotated),
                                                       ordinal : 0, RefKind.None, "other", isDiscard : false, Locations)),
                   IsVararg : false,
                   DeclaredConstraintsForOverrideOrImplementation : ImmutableArray <TypeParameterConstraintClause> .Empty);
        }
Example #29
0
        protected override (TypeWithAnnotations ReturnType, ImmutableArray <ParameterSymbol> Parameters, bool IsVararg, ImmutableArray <TypeParameterConstraintClause> DeclaredConstraintsForOverrideOrImplementation) MakeParametersAndBindReturnType(BindingDiagnosticBag diagnostics)
        {
            var compilation = DeclaringCompilation;
            var location    = ReturnTypeLocation;

            return(ReturnType : TypeWithAnnotations.Create(Binder.GetSpecialType(compilation, SpecialType.System_String, location, diagnostics)),
                   Parameters : ImmutableArray <ParameterSymbol> .Empty,
                   IsVararg : false,
                   DeclaredConstraintsForOverrideOrImplementation : ImmutableArray <TypeParameterConstraintClause> .Empty);
        }
Example #30
0
        protected MethodToClassRewriter(VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, BindingDiagnosticBag diagnostics)
        {
            Debug.Assert(compilationState != null);
            Debug.Assert(diagnostics != null);
            Debug.Assert(diagnostics.DiagnosticBag != null);

            this.CompilationState = compilationState;
            this.Diagnostics      = diagnostics;
            this.slotAllocatorOpt = slotAllocatorOpt;
            this._placeholderMap  = new Dictionary <BoundValuePlaceholderBase, BoundExpression>();
        }