internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder <SynthesizedAttributeData> attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); AddSynthesizedAttribute( ref attributes, moduleBuilder.Compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor)); if (!DeclaringCompilation.GetWellKnownType(WellKnownType.Microsoft_CodeAnalysis_EmbeddedAttribute).IsErrorType()) { AddSynthesizedAttribute( ref attributes, moduleBuilder.Compilation.TrySynthesizeAttribute(WellKnownMember.Microsoft_CodeAnalysis_EmbeddedAttribute__ctor)); } }
/// <summary> /// Adds an `[AttributeUsage(AttributeTargets.Class | ...)]` (if possible) and captures any diagnostics in the process. /// </summary> private ImmutableArray <CSharpAttributeData> MakeAttributes() { var ctor = (MethodSymbol)Binder.GetWellKnownTypeMember(DeclaringCompilation, WellKnownMember.System_AttributeUsageAttribute__ctor, _diagnostics, Location.None); if (ctor is null) { // member is missing return(ImmutableArray <CSharpAttributeData> .Empty); } NamedTypeSymbol attributeTargets = DeclaringCompilation.GetWellKnownType(WellKnownType.System_AttributeTargets); Binder.ReportUseSiteDiagnostics(attributeTargets, _diagnostics, Location.None); var usage = new SynthesizedAttributeData(ctor, arguments: ImmutableArray.Create(new TypedConstant(attributeTargets, TypedConstantKind.Enum, attributeUsage)), namedArguments: ImmutableArray <KeyValuePair <string, TypedConstant> > .Empty); return(ImmutableArray.Create <CSharpAttributeData>(usage)); }
public override ImmutableArray <AttributeData> GetAttributes() { var builder = ImmutableArray.CreateBuilder <AttributeData>(); if (IsPhpHidden) { // [PhpHiddenAttribute] builder.Add(new SynthesizedAttributeData( DeclaringCompilation.CoreMethods.Ctors.PhpHiddenAttribute, ImmutableArray <TypedConstant> .Empty, ImmutableArray <KeyValuePair <string, TypedConstant> > .Empty)); } if (IsEditorBrowsableHidden) { builder.Add(new SynthesizedAttributeData( (MethodSymbol)DeclaringCompilation.GetWellKnownTypeMember(WellKnownMember.System_ComponentModel_EditorBrowsableAttribute__ctor), ImmutableArray.Create( new TypedConstant( DeclaringCompilation.GetWellKnownType(WellKnownType.System_ComponentModel_EditorBrowsableState), TypedConstantKind.Enum, System.ComponentModel.EditorBrowsableState.Never)), ImmutableArray <KeyValuePair <string, TypedConstant> > .Empty)); } if (this is SynthesizedPhpCtorSymbol sctor && sctor.IsInitFieldsOnly) // we do it here to avoid allocating new ImmutableArray in derived class { // [PhpFieldsOnlyCtorAttribute] builder.Add(new SynthesizedAttributeData( DeclaringCompilation.CoreMethods.Ctors.PhpFieldsOnlyCtorAttribute, ImmutableArray <TypedConstant> .Empty, ImmutableArray <KeyValuePair <string, TypedConstant> > .Empty)); // [CompilerGeneratedAttribute] builder.Add(DeclaringCompilation.CreateCompilerGeneratedAttribute()); } return(builder.ToImmutable()); }
internal override void GenerateMethodBody(TypeCompilationState compilationState, DiagnosticBag 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) => // 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(); F.CloseMethod(F.Block(F.Return(retExpr))); } catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex) { diagnostics.Add(ex.Diagnostic); F.CloseMethod(F.ThrowNull()); } }
private Tuple <NamedTypeSymbol, ImmutableArray <NamedTypeSymbol> > MakeDeclaredBases( ConsList <TypeSymbol> basesBeingResolved, BindingDiagnosticBag diagnostics ) { if (this.TypeKind == TypeKind.Enum) { // Handled by GetEnumUnderlyingType(). return(new Tuple <NamedTypeSymbol, ImmutableArray <NamedTypeSymbol> >( null, ImmutableArray <NamedTypeSymbol> .Empty )); } var reportedPartialConflict = false; Debug.Assert( basesBeingResolved == null || !basesBeingResolved.ContainsReference(this.OriginalDefinition) ); var newBasesBeingResolved = basesBeingResolved.Prepend(this.OriginalDefinition); var baseInterfaces = ArrayBuilder <NamedTypeSymbol> .GetInstance(); NamedTypeSymbol baseType = null; SourceLocation baseTypeLocation = null; var interfaceLocations = SpecializedSymbolCollections.GetPooledSymbolDictionaryInstance < NamedTypeSymbol, SourceLocation >(); foreach (var decl in this.declaration.Declarations) { Tuple <NamedTypeSymbol, ImmutableArray <NamedTypeSymbol> > one = MakeOneDeclaredBases( newBasesBeingResolved, decl, diagnostics ); if ((object)one == null) { continue; } var partBase = one.Item1; var partInterfaces = one.Item2; if (!reportedPartialConflict) { if ((object)baseType == null) { baseType = partBase; baseTypeLocation = decl.NameLocation; } else if (baseType.TypeKind == TypeKind.Error && (object)partBase != null) { // if the old base was an error symbol, copy it to the interfaces list so it doesn't get lost partInterfaces = partInterfaces.Add(baseType); baseType = partBase; baseTypeLocation = decl.NameLocation; } else if ( (object)partBase != null && !TypeSymbol.Equals( partBase, baseType, TypeCompareKind.ConsiderEverything2 ) && partBase.TypeKind != TypeKind.Error ) { // the parts do not agree var info = diagnostics.Add( ErrorCode.ERR_PartialMultipleBases, Locations[0], this ); baseType = new ExtendedErrorTypeSymbol( baseType, LookupResultKind.Ambiguous, info ); baseTypeLocation = decl.NameLocation; reportedPartialConflict = true; } } foreach (var t in partInterfaces) { if (!interfaceLocations.ContainsKey(t)) { baseInterfaces.Add(t); interfaceLocations.Add(t, decl.NameLocation); } } } CompoundUseSiteInfo <AssemblySymbol> useSiteInfo = new CompoundUseSiteInfo <AssemblySymbol>(diagnostics, ContainingAssembly); if (declaration.Kind == DeclarationKind.Record) { var type = DeclaringCompilation .GetWellKnownType(WellKnownType.System_IEquatable_T) .Construct(this); if (baseInterfaces.IndexOf(type, SymbolEqualityComparer.AllIgnoreOptions) < 0) { baseInterfaces.Add(type); type.AddUseSiteInfo(ref useSiteInfo); } } if ((object)baseType != null) { Debug.Assert(baseTypeLocation != null); if (baseType.IsStatic) { // '{1}': cannot derive from static class '{0}' diagnostics.Add( ErrorCode.ERR_StaticBaseClass, baseTypeLocation, baseType, this ); } if (!this.IsNoMoreVisibleThan(baseType, ref useSiteInfo)) { // Inconsistent accessibility: base class '{1}' is less accessible than class '{0}' diagnostics.Add( ErrorCode.ERR_BadVisBaseClass, baseTypeLocation, this, baseType ); } } var baseInterfacesRO = baseInterfaces.ToImmutableAndFree(); if (DeclaredAccessibility != Accessibility.Private && IsInterface) { foreach (var i in baseInterfacesRO) { if (!i.IsAtLeastAsVisibleAs(this, ref useSiteInfo)) { // Inconsistent accessibility: base interface '{1}' is less accessible than interface '{0}' diagnostics.Add( ErrorCode.ERR_BadVisBaseInterface, interfaceLocations[i], this, i ); } } } interfaceLocations.Free(); diagnostics.Add(Locations[0], useSiteInfo); return(new Tuple <NamedTypeSymbol, ImmutableArray <NamedTypeSymbol> >( baseType, baseInterfacesRO )); }
protected override TypeWithAnnotations ComputeType(Binder?binder, SyntaxNode syntax, DiagnosticBag diagnostics) { // No need to worry about reporting use-site diagnostics, we already did that in the constructor return(TypeWithAnnotations.Create(DeclaringCompilation.GetWellKnownType(WellKnownType.System_Type), NullableAnnotation.NotAnnotated)); }