Exemple #1
0
        IEnumerable <IMethodReference> IPropertyDefinition.GetAccessors(EmitContext context)
        {
            CheckDefinitionInvariant();

            MethodSymbol getMethod = this.GetMethod;

            if (getMethod != null && getMethod.ShouldInclude(context))
            {
                yield return(getMethod);
            }

            MethodSymbol setMethod = this.SetMethod;

            if (setMethod != null && setMethod.ShouldInclude(context))
            {
                yield return(setMethod);
            }

            SourcePropertySymbol sourceProperty = this as SourcePropertySymbol;

            if ((object)sourceProperty != null && sourceProperty.ShouldInclude(context))
            {
                SynthesizedSealedPropertyAccessor synthesizedAccessor = sourceProperty.SynthesizedSealedAccessorOpt;
                if ((object)synthesizedAccessor != null)
                {
                    yield return(synthesizedAccessor);
                }
            }
        }
        public static SourcePropertyAccessorSymbol CreateAccessorSymbol(
            NamedTypeSymbol containingType,
            SourcePropertySymbol property,
            DeclarationModifiers propertyModifiers,
            string propertyName,
            ArrowExpressionClauseSyntax syntax,
            PropertySymbol explicitlyImplementedPropertyOpt,
            string aliasQualifierOpt,
            DiagnosticBag diagnostics)
        {
            string name;
            ImmutableArray <MethodSymbol> explicitInterfaceImplementations;

            GetNameAndExplicitInterfaceImplementations(
                explicitlyImplementedPropertyOpt,
                propertyName,
                property.IsCompilationOutputWinMdObj(),
                aliasQualifierOpt,
                isGetMethod: true,
                name: out name,
                explicitInterfaceImplementations:
                out explicitInterfaceImplementations);

            return(new SourcePropertyAccessorSymbol(
                       containingType,
                       name,
                       property,
                       propertyModifiers,
                       explicitInterfaceImplementations,
                       syntax.Expression.GetLocation(),
                       syntax,
                       diagnostics));
        }
Exemple #3
0
        private IMethodReference GetSynthesizedSealedAccessor(MethodKind targetMethodKind)
        {
            SourcePropertySymbol sourceProperty = this as SourcePropertySymbol;

            if ((object)sourceProperty != null)
            {
                SynthesizedSealedPropertyAccessor synthesized = sourceProperty.SynthesizedSealedAccessorOpt;
                return((object)synthesized != null && synthesized.MethodKind == targetMethodKind ? synthesized : null);
            }

            return(null);
        }
        private SourcePropertyAccessorSymbol(
            NamedTypeSymbol containingType,
            string name,
            SourcePropertySymbol property,
            DeclarationModifiers propertyModifiers,
            ImmutableArray <MethodSymbol> explicitInterfaceImplementations,
            Location location,
            ArrowExpressionClauseSyntax syntax,
            DiagnosticBag diagnostics) :
            base(containingType, syntax.GetReference(), location)
        {
            _property = property;
            _explicitInterfaceImplementations = explicitInterfaceImplementations;
            _name = name;
            _isAutoPropertyAccessor = false;
            _isExpressionBodied     = true;

            // The modifiers for the accessor are the same as the modifiers for the property,
            // minus the indexer bit
            var declarationModifiers = propertyModifiers & ~DeclarationModifiers.Indexer;

            // ReturnsVoid property is overridden in this class so
            // returnsVoid argument to MakeFlags is ignored.
            this.MakeFlags(MethodKind.PropertyGet, declarationModifiers, returnsVoid: false, isExtensionMethod: false,
                           isMetadataVirtualIgnoringModifiers: explicitInterfaceImplementations.Any());

            CheckModifiersForBody(location, diagnostics);

            var info = ModifierUtils.CheckAccessibility(this.DeclarationModifiers);

            if (info != null)
            {
                diagnostics.Add(info, location);
            }

            this.CheckModifiers(location, hasBody: true, isAutoPropertyOrExpressionBodied: true, diagnostics: diagnostics);

            if (this.IsOverride)
            {
                MethodSymbol overriddenMethod = this.OverriddenMethod;
                if ((object)overriddenMethod != null)
                {
                    // If this accessor is overriding a method from metadata, it is possible that
                    // the name of the overridden method doesn't follow the C# get_X/set_X pattern.
                    // We should copy the name so that the runtime will recognize this as an override.
                    _name = overriddenMethod.Name;
                }
            }
        }
Exemple #5
0
        private void CompileSynthesizedSealedAccessors(SourcePropertySymbol sourceProperty, TypeCompilationState compilationState)
        {
            SynthesizedSealedPropertyAccessor synthesizedAccessor = sourceProperty.SynthesizedSealedAccessorOpt;

            // we are not generating any observable diagnostics here so it is ok to shortcircuit on global errors.
            if ((object)synthesizedAccessor != null && !GlobalHasErrors)
            {
                Debug.Assert(synthesizedAccessor.SynthesizesLoweredBoundBody);
                var discardedDiagnostics = DiagnosticBag.GetInstance();
                synthesizedAccessor.GenerateMethodBody(compilationState, discardedDiagnostics);
                Debug.Assert(!discardedDiagnostics.HasAnyErrors());
                discardedDiagnostics.Free();

                moduleBeingBuilt.AddCompilerGeneratedDefinition(sourceProperty.ContainingType, synthesizedAccessor);
            }
        }
Exemple #6
0
        public SynthesizedBackingFieldSymbol(
            SourcePropertySymbol property,
            string name,
            bool isLet,
            bool isStatic,
            bool hasInitializer)
        {
            Debug.Assert(!string.IsNullOrEmpty(name));

            _name = name;

            Modifiers = DeclarationModifiers.Private |
                        (isLet ? DeclarationModifiers.Readable : DeclarationModifiers.None) |
                        (isStatic ? DeclarationModifiers.Static : DeclarationModifiers.None);

            _property      = property;
            HasInitializer = hasInitializer;
        }
        public static SourcePropertyAccessorSymbol CreateAccessorSymbol(
            NamedTypeSymbol containingType,
            SourcePropertySymbol property,
            DeclarationModifiers propertyModifiers,
            string propertyName,
            AccessorDeclarationSyntax syntax,
            PropertySymbol explicitlyImplementedPropertyOpt,
            string aliasQualifierOpt,
            bool isAutoPropertyAccessor,
            DiagnosticBag diagnostics)
        {
            Debug.Assert(syntax.Kind() == SyntaxKind.GetAccessorDeclaration || syntax.Kind() == SyntaxKind.SetAccessorDeclaration);

            bool   isGetMethod = (syntax.Kind() == SyntaxKind.GetAccessorDeclaration);
            string name;
            ImmutableArray <MethodSymbol> explicitInterfaceImplementations;

            GetNameAndExplicitInterfaceImplementations(
                explicitlyImplementedPropertyOpt,
                propertyName,
                property.IsCompilationOutputWinMdObj(),
                aliasQualifierOpt,
                isGetMethod,
                out name,
                out explicitInterfaceImplementations);

            var methodKind = isGetMethod ? MethodKind.PropertyGet : MethodKind.PropertySet;

            return(new SourcePropertyAccessorSymbol(
                       containingType,
                       name,
                       property,
                       propertyModifiers,
                       explicitInterfaceImplementations,
                       syntax.Keyword.GetLocation(),
                       syntax,
                       methodKind,
                       isAutoPropertyAccessor,
                       diagnostics));
        }
        private SourcePropertyAccessorSymbol(
            NamedTypeSymbol containingType,
            string name,
            SourcePropertySymbol property,
            DeclarationModifiers propertyModifiers,
            ImmutableArray <MethodSymbol> explicitInterfaceImplementations,
            Location location,
            AccessorDeclarationSyntax syntax,
            MethodKind methodKind,
            bool isAutoPropertyAccessor,
            DiagnosticBag diagnostics)
            : base(containingType,
                   syntax.GetReference(),
                   location)
        {
            _property = property;
            _explicitInterfaceImplementations = explicitInterfaceImplementations;
            _name = name;
            _isAutoPropertyAccessor = isAutoPropertyAccessor;
            Debug.Assert(!_property.IsExpressionBodied, "Cannot have accessors in expression bodied lightweight properties");
            var hasBody           = syntax.Body != null;
            var hasExpressionBody = syntax.ExpressionBody != null;

            _isExpressionBodied = !hasBody && hasExpressionBody;

            bool modifierErrors;
            var  declarationModifiers = this.MakeModifiers(syntax, location, diagnostics, out modifierErrors);

            // Include modifiers from the containing property.
            propertyModifiers &= ~DeclarationModifiers.AccessibilityMask;
            if ((declarationModifiers & DeclarationModifiers.Private) != 0)
            {
                // Private accessors cannot be virtual.
                propertyModifiers &= ~DeclarationModifiers.Virtual;
            }
            declarationModifiers |= propertyModifiers & ~DeclarationModifiers.Indexer;

            // ReturnsVoid property is overridden in this class so
            // returnsVoid argument to MakeFlags is ignored.
            this.MakeFlags(methodKind, declarationModifiers, returnsVoid: false, isExtensionMethod: false,
                           isMetadataVirtualIgnoringModifiers: explicitInterfaceImplementations.Any());

            if (hasBody || hasExpressionBody)
            {
                CheckModifiersForBody(location, diagnostics);
            }

            var info = ModifierUtils.CheckAccessibility(this.DeclarationModifiers);

            if (info != null)
            {
                diagnostics.Add(info, location);
            }

            if (!modifierErrors)
            {
                this.CheckModifiers(location, hasBody || hasExpressionBody, isAutoPropertyAccessor, diagnostics);
            }

            if (this.IsOverride)
            {
                MethodSymbol overriddenMethod = this.OverriddenMethod;
                if ((object)overriddenMethod != null)
                {
                    // If this accessor is overriding a method from metadata, it is possible that
                    // the name of the overridden method doesn't follow the C# get_X/set_X pattern.
                    // We should copy the name so that the runtime will recognize this as an override.
                    _name = overriddenMethod.Name;
                }
            }

            CheckForBlockAndExpressionBody(
                syntax.Body, syntax.ExpressionBody, syntax, diagnostics);
        }
Exemple #9
0
        private void CompileNamedType(NamedTypeSymbol symbol)
        {
            TypeCompilationState compilationState = new TypeCompilationState(symbol, moduleBeingBuilt);

            cancellationToken.ThrowIfCancellationRequested();

            // Find the constructor of a script class.
            MethodSymbol scriptCtor = null;

            if (symbol.IsScriptClass)
            {
                // The field initializers of a script class could be arbitrary statements,
                // including blocks.  Field initializers containing blocks need to
                // use a MethodBodySemanticModel to build up the appropriate tree of binders, and
                // MethodBodySemanticModel requires an "owning" method.  That's why we're digging out
                // the constructor - it will own the field initializers.
                scriptCtor = symbol.InstanceConstructors[0];
                Debug.Assert((object)scriptCtor != null);
            }

            var synthesizedSubmissionFields   = symbol.IsSubmissionClass ? new SynthesizedSubmissionFields(compilation, symbol) : null;
            var processedStaticInitializers   = new ProcessedFieldInitializers();
            var processedInstanceInitializers = new ProcessedFieldInitializers();

            var sourceTypeSymbol = symbol as SourceMemberContainerTypeSymbol;

            if ((object)sourceTypeSymbol != null)
            {
                BindFieldInitializers(sourceTypeSymbol, scriptCtor, sourceTypeSymbol.StaticInitializers, this.generateDebugInfo, ref processedStaticInitializers);
                BindFieldInitializers(sourceTypeSymbol, scriptCtor, sourceTypeSymbol.InstanceInitializers, this.generateDebugInfo, ref processedInstanceInitializers);

                if (compilationState.Emitting)
                {
                    CompileSynthesizedExplicitImplementations(sourceTypeSymbol, compilationState);
                }
            }

            // Indicates if a static constructor is in the member,
            // so we can decide to synthesize a static constructor.
            bool hasStaticConstructor = false;

            foreach (var member in symbol.GetMembers())
            {
                //When a filter is supplied, limit the compilation of members passing the filter.
                if ((this.filter != null) && !this.filter(member))
                {
                    continue;
                }

                switch (member.Kind)
                {
                case SymbolKind.NamedType:
                    member.Accept(this, compilationState);
                    break;

                case SymbolKind.Method:
                {
                    MethodSymbol method = (MethodSymbol)member;
                    if (method.IsSubmissionConstructor || IsFieldLikeEventAccessor(method))
                    {
                        continue;
                    }

                    if (method.IsPartial())
                    {
                        method = method.PartialImplementation();
                        if ((object)method == null)
                        {
                            continue;
                        }
                    }

                    ProcessedFieldInitializers processedInitializers =
                        method.MethodKind == MethodKind.Constructor ? processedInstanceInitializers :
                        method.MethodKind == MethodKind.StaticConstructor ? processedStaticInitializers :
                        default(ProcessedFieldInitializers);

                    CompileMethod(method, ref processedInitializers, synthesizedSubmissionFields, compilationState);

                    // Set a flag to indicate that a static constructor is created.
                    if (method.MethodKind == MethodKind.StaticConstructor)
                    {
                        hasStaticConstructor = true;
                    }

                    break;
                }

                case SymbolKind.Property:
                {
                    SourcePropertySymbol sourceProperty = member as SourcePropertySymbol;
                    if ((object)sourceProperty != null && sourceProperty.IsSealed && compilationState.Emitting)
                    {
                        CompileSynthesizedSealedAccessors(sourceProperty, compilationState);
                    }
                    break;
                }

                case SymbolKind.Event:
                {
                    SourceEventSymbol eventSymbol = member as SourceEventSymbol;
                    if ((object)eventSymbol != null && eventSymbol.HasAssociatedField && !eventSymbol.IsAbstract && compilationState.Emitting)
                    {
                        CompileFieldLikeEventAccessor(eventSymbol, isAddMethod: true, compilationState: compilationState);
                        CompileFieldLikeEventAccessor(eventSymbol, isAddMethod: false, compilationState: compilationState);
                    }
                    break;
                }

                case SymbolKind.Field:
                {
                    SourceMemberFieldSymbol fieldSymbol = member as SourceMemberFieldSymbol;
                    if ((object)fieldSymbol != null)
                    {
                        if (fieldSymbol.IsConst)
                        {
                            // We check specifically for constant fields with bad values because they never result
                            // in bound nodes being inserted into method bodies (in which case, they would be covered
                            // by the method-level check).
                            ConstantValue constantValue = fieldSymbol.GetConstantValue(ConstantFieldsInProgress.Empty, earlyDecodingWellKnownAttributes: false);
                            SetGlobalErrorIfTrue(constantValue == null || constantValue.IsBad);
                        }

                        if (fieldSymbol.IsFixed && compilationState.Emitting)
                        {
                            // force the generation of implementation types for fixed-size buffers
                            TypeSymbol discarded = fieldSymbol.FixedImplementationType(compilationState.ModuleBuilder);
                        }
                    }
                    break;
                }
                }
            }

            Debug.Assert(symbol.TypeKind != TypeKind.Submission || ((object)scriptCtor != null && scriptCtor.IsSubmissionConstructor));

            //  process additional anonymous type members
            if (AnonymousTypeManager.IsAnonymousTypeTemplate(symbol))
            {
                ProcessedFieldInitializers processedInitializers = default(ProcessedFieldInitializers);
                foreach (var method in AnonymousTypeManager.GetAnonymousTypeHiddenMethods(symbol))
                {
                    CompileMethod(method, ref processedInitializers, synthesizedSubmissionFields, compilationState);
                }
            }

            // In the case there are field initializers but we haven't created an implicit static constructor (.cctor) for it,
            // (since we may not add .cctor implicitly created for decimals into the symbol table)
            // it is necessary for the compiler to generate the static constructor here if we are emitting.
            if (moduleBeingBuilt != null && !hasStaticConstructor && !processedStaticInitializers.BoundInitializers.IsDefaultOrEmpty)
            {
                Debug.Assert(processedStaticInitializers.BoundInitializers.All((init) =>
                                                                               (init.Kind == BoundKind.FieldInitializer) && !((BoundFieldInitializer)init).Field.IsMetadataConstant));

                MethodSymbol method = new SynthesizedStaticConstructor(sourceTypeSymbol);
                if ((this.filter == null) || this.filter(method))
                {
                    CompileMethod(method, ref processedStaticInitializers, synthesizedSubmissionFields, compilationState);
                    // If this method has been successfully built, we emit it.
                    if (moduleBeingBuilt.GetMethodBody(method) != null)
                    {
                        moduleBeingBuilt.AddCompilerGeneratedDefinition(sourceTypeSymbol, method);
                    }
                }
            }

            // compile submission constructor last so that synthesized submission fields are collected from all script methods:
            if (synthesizedSubmissionFields != null && compilationState.Emitting)
            {
                Debug.Assert(scriptCtor.IsSubmissionConstructor);
                CompileMethod(scriptCtor, ref processedInstanceInitializers, synthesizedSubmissionFields, compilationState);
                synthesizedSubmissionFields.AddToType(scriptCtor.ContainingType, compilationState.ModuleBuilder);
            }

            //  Emit synthesized methods produced during lowering if any
            CompileGeneratedMethods(compilationState);
            compilationState.Free();
        }