|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable disable
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Emit;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Symbols
{
internal class SynthesizedInstanceConstructor : SynthesizedInstanceMethodSymbol
{
private readonly NamedTypeSymbol _containingType;
internal SynthesizedInstanceConstructor(NamedTypeSymbol containingType)
{
Debug.Assert((object)containingType != null);
_containingType = containingType;
}
//
// Consider overriding when implementing a synthesized subclass.
//
internal override bool GenerateDebugInfo
{
get { return true; }
}
public override ImmutableArray<ParameterSymbol> Parameters
{
get { return ImmutableArray<ParameterSymbol>.Empty; }
}
public override Accessibility DeclaredAccessibility
{
get { return ContainingType.IsAbstract ? Accessibility.Protected : Accessibility.Public; }
}
internal override bool IsMetadataFinal
{
get
{
return false;
}
}
#region Sealed
public sealed override Symbol ContainingSymbol
{
get { return _containingType; }
}
public sealed override NamedTypeSymbol ContainingType
{
get
{
return _containingType;
}
}
public sealed override string Name
{
get { return WellKnownMemberNames.InstanceConstructorName; }
}
internal sealed override bool HasSpecialName
{
get { return true; }
}
internal sealed override System.Reflection.MethodImplAttributes ImplementationAttributes
{
get
{
if (_containingType.IsComImport)
{
Debug.Assert(_containingType.TypeKind == TypeKind.Class);
return System.Reflection.MethodImplAttributes.Runtime | System.Reflection.MethodImplAttributes.InternalCall;
}
if (_containingType.TypeKind == TypeKind.Delegate)
{
return System.Reflection.MethodImplAttributes.Runtime;
}
return default(System.Reflection.MethodImplAttributes);
}
}
internal sealed override bool RequiresSecurityObject
{
get { return false; }
}
public sealed override DllImportData GetDllImportData()
{
return null;
}
internal sealed override MarshalPseudoCustomAttributeData ReturnValueMarshallingInformation
{
get { return null; }
}
internal sealed override bool HasDeclarativeSecurity
{
get { return false; }
}
internal sealed override IEnumerable<Cci.SecurityAttribute> GetSecurityInformation()
{
throw ExceptionUtilities.Unreachable();
}
internal sealed override ImmutableArray<string> GetAppliedConditionalSymbols()
{
return ImmutableArray<string>.Empty;
}
public sealed override bool IsVararg
{
get { return false; }
}
public sealed override ImmutableArray<TypeParameterSymbol> TypeParameters
{
get { return ImmutableArray<TypeParameterSymbol>.Empty; }
}
internal override LexicalSortKey GetLexicalSortKey()
{
//For the sake of matching the metadata output of the native compiler, make synthesized constructors appear last in the metadata.
//This is not critical, but it makes it easier on tools that are comparing metadata.
return LexicalSortKey.SynthesizedCtor;
}
public sealed override ImmutableArray<Location> Locations
{
get { return ContainingType.Locations; }
}
public override RefKind RefKind
{
get { return RefKind.None; }
}
public sealed override TypeWithAnnotations ReturnTypeWithAnnotations
{
get { return TypeWithAnnotations.Create(ContainingAssembly.GetSpecialType(SpecialType.System_Void)); }
}
public sealed override FlowAnalysisAnnotations ReturnTypeFlowAnalysisAnnotations => FlowAnalysisAnnotations.None;
public sealed override ImmutableHashSet<string> ReturnNotNullIfParameterNotNull => ImmutableHashSet<string>.Empty;
public override ImmutableArray<CustomModifier> RefCustomModifiers
{
get { return ImmutableArray<CustomModifier>.Empty; }
}
public sealed override ImmutableArray<TypeWithAnnotations> TypeArgumentsWithAnnotations
{
get { return ImmutableArray<TypeWithAnnotations>.Empty; }
}
public sealed override Symbol AssociatedSymbol
{
get { return null; }
}
public sealed override int Arity
{
get { return 0; }
}
public sealed override bool ReturnsVoid
{
get { return true; }
}
public sealed override MethodKind MethodKind
{
get { return MethodKind.Constructor; }
}
public sealed override bool IsExtern
{
get
{
// Synthesized constructors of ComImport type are extern
NamedTypeSymbol containingType = this.ContainingType;
return (object)containingType != null && containingType.IsComImport;
}
}
public sealed override bool IsSealed
{
get { return false; }
}
public sealed override bool IsAbstract
{
get { return false; }
}
public sealed override bool IsOverride
{
get { return false; }
}
public sealed override bool IsVirtual
{
get { return false; }
}
public sealed override bool IsStatic
{
get { return false; }
}
public sealed override bool IsAsync
{
get { return false; }
}
public sealed override bool HidesBaseMethodsByName
{
get { return false; }
}
internal sealed override bool IsMetadataNewSlot(bool ignoreInterfaceImplementationChanges = false)
{
return false;
}
internal sealed override bool IsMetadataVirtual(IsMetadataVirtualOption option = IsMetadataVirtualOption.None)
{
return false;
}
public sealed override bool IsExtensionMethod
{
get { return false; }
}
internal sealed override Cci.CallingConvention CallingConvention
{
get { return Cci.CallingConvention.HasThis; }
}
internal sealed override bool IsExplicitInterfaceImplementation
{
get { return false; }
}
public sealed override ImmutableArray<MethodSymbol> ExplicitInterfaceImplementations
{
get { return ImmutableArray<MethodSymbol>.Empty; }
}
internal sealed override int CalculateLocalSyntaxOffset(int localPosition, SyntaxTree localTree)
{
var containingType = (SourceMemberContainerTypeSymbol)this.ContainingType;
return containingType.CalculateSyntaxOffsetInSynthesizedConstructor(localPosition, localTree, isStatic: false);
}
internal sealed override UseSiteInfo<AssemblySymbol> GetUseSiteInfo()
{
var result = new UseSiteInfo<AssemblySymbol>(PrimaryDependency);
MergeUseSiteInfo(ref result, ReturnTypeWithAnnotations.Type.GetUseSiteInfo());
return result;
}
internal sealed override bool IsNullableAnalysisEnabled() =>
(ContainingType as SourceMemberContainerTypeSymbol)?.IsNullableEnabledForConstructorsAndInitializers(useStatic: false) ?? false;
#endregion
protected void GenerateMethodBodyCore(TypeCompilationState compilationState, BindingDiagnosticBag diagnostics)
{
var factory = new SyntheticBoundNodeFactory(this, this.GetNonNullSyntaxNode(), compilationState, diagnostics);
factory.CurrentFunction = this;
if (ContainingType.BaseTypeNoUseSiteDiagnostics is MissingMetadataTypeSymbol)
{
// Containing type was not found or was inaccessible
factory.CloseMethod(factory.Block());
return;
}
var baseConstructorCall = Binder.GenerateBaseParameterlessConstructorInitializer(this, diagnostics);
if (baseConstructorCall == null)
{
// .ctor was not found or was inaccessible
factory.CloseMethod(factory.Block());
return;
}
var statements = ArrayBuilder<BoundStatement>.GetInstance();
statements.Add(factory.ExpressionStatement(baseConstructorCall));
GenerateMethodBodyStatements(factory, statements, diagnostics);
statements.Add(factory.Return());
var block = factory.Block(statements.ToImmutableAndFree());
factory.CloseMethod(block);
}
internal virtual void GenerateMethodBodyStatements(SyntheticBoundNodeFactory factory, ArrayBuilder<BoundStatement> statements, BindingDiagnosticBag diagnostics)
{
// overridden in a derived class to add extra statements to the body of the generated constructor
}
protected override bool HasSetsRequiredMembersImpl => false;
internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder<SynthesizedAttributeData> attributes)
{
base.AddSynthesizedAttributes(moduleBuilder, ref attributes);
AddRequiredMembersMarkerAttributes(ref attributes, this);
}
}
}
|