protected override CSharpAttributeData CreateCompilerGeneratedAttribute() { Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor)); var compilation = ModuleBeingBuilt.Compilation; return(compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor)); }
public bool ReportMissingOrErroneousSymbols(BindingDiagnosticBag diagnostics) { bool hasErrors = false; ReportErrorOnSymbol(System_Object, diagnostics, ref hasErrors); ReportErrorOnSymbol(System_Void, diagnostics, ref hasErrors); ReportErrorOnSymbol(System_Boolean, diagnostics, ref hasErrors); ReportErrorOnSymbol(System_String, diagnostics, ref hasErrors); ReportErrorOnSymbol(System_Int32, diagnostics, ref hasErrors); ReportErrorOnSpecialMember(System_Object__Equals, SpecialMember.System_Object__Equals, diagnostics, ref hasErrors); ReportErrorOnSpecialMember(System_Object__ToString, SpecialMember.System_Object__ToString, diagnostics, ref hasErrors); ReportErrorOnSpecialMember(System_Object__GetHashCode, SpecialMember.System_Object__GetHashCode, diagnostics, ref hasErrors); ReportErrorOnWellKnownMember(System_String__Format_IFormatProvider, WellKnownMember.System_String__Format_IFormatProvider, diagnostics, ref hasErrors); // optional synthesized attributes: Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor)); Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(WellKnownMember.System_Diagnostics_DebuggerHiddenAttribute__ctor)); Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(WellKnownMember.System_Diagnostics_DebuggerBrowsableAttribute__ctor)); ReportErrorOnWellKnownMember(System_Collections_Generic_EqualityComparer_T__Equals, WellKnownMember.System_Collections_Generic_EqualityComparer_T__Equals, diagnostics, ref hasErrors); ReportErrorOnWellKnownMember(System_Collections_Generic_EqualityComparer_T__GetHashCode, WellKnownMember.System_Collections_Generic_EqualityComparer_T__GetHashCode, diagnostics, ref hasErrors); ReportErrorOnWellKnownMember(System_Collections_Generic_EqualityComparer_T__get_Default, WellKnownMember.System_Collections_Generic_EqualityComparer_T__get_Default, diagnostics, ref hasErrors); return(hasErrors); }
// Useful for testing internal static bool Override(WellKnownMembers kind, string proto) { var name = proto.Replace("$", "").Split('(').First(); var s = Binder.LookupName(name); if (s == null) { return(false); } if (s is SymbolList) { var isStatic = proto.Contains('$'); var args = proto.Replace(")", "").Split('(').Last().Split(','); var argTypes = args.Select(x => Binder.LookupFullName(x) as TypeSymbol).ToArray(); s = (s as SymbolList).Symbols.Find(x => (x as MethodBaseSymbol)?.MethodBase.GetParameters().Length == args.Length && (x as MethodBaseSymbol)?.MethodBase.IsStatic == isStatic && (x as MethodBaseSymbol)?.MethodBase.GetParameters().All(y => args[y.Position] == "*" || y.ParameterType == argTypes[y.Position].Type) == true); if (!(s is MethodBaseSymbol)) { return(false); } } if (!(s is MemberSymbol)) { return(false); } WellKnownMemberSymbols[(int)kind] = s as MemberSymbol; return(true); }
/// <summary> /// Synthesizes a custom attribute. /// Returns null if the <paramref name="constructor"/> symbol is missing and the attribute is synthesized only if present. /// </summary> internal SynthesizedAttributeData SynthesizeAttribute( WellKnownMember constructor, ImmutableArray <TypedConstant> arguments = default(ImmutableArray <TypedConstant>), ImmutableArray <KeyValuePair <string, TypedConstant> > namedArguments = default(ImmutableArray <KeyValuePair <string, TypedConstant> >)) { var ctorSymbol = (MethodSymbol)GetWellKnownTypeMember(constructor); if ((object)ctorSymbol == null) { // if this assert fails, UseSiteErrors for "member" have not been checked before emitting ... Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(constructor)); return(null); } if (arguments.IsDefault) { arguments = ImmutableArray <TypedConstant> .Empty; } if (namedArguments.IsDefault) { namedArguments = ImmutableArray <KeyValuePair <string, TypedConstant> > .Empty; } return(new SynthesizedAttributeData(ctorSymbol, arguments, namedArguments)); }
private static bool TryGetBuilderMember <TSymbol>( SyntheticBoundNodeFactory F, WellKnownMember?member, NamedTypeSymbol builderType, bool customBuilder, out TSymbol symbol ) where TSymbol : Symbol { if (!member.HasValue) { symbol = null; return(true); } WellKnownMember memberValue = member.Value; if (customBuilder) { var descriptor = WellKnownMembers.GetDescriptor(memberValue); var sym = CSharpCompilation.GetRuntimeMember( builderType.OriginalDefinition, descriptor, F.Compilation.WellKnownMemberSignatureComparer, accessWithinOpt: null ); if ((object)sym != null) { sym = sym.SymbolAsMember(builderType); } symbol = sym as TSymbol; } else { symbol = F.WellKnownMember(memberValue, isOptional: true) as TSymbol; if ((object)symbol != null) { symbol = (TSymbol)symbol.SymbolAsMember(builderType); } } if ((object)symbol == null) { var descriptor = WellKnownMembers.GetDescriptor(memberValue); var diagnostic = new CSDiagnostic( new CSDiagnosticInfo( ErrorCode.ERR_MissingPredefinedMember, ( customBuilder ? (object)builderType : descriptor.DeclaringTypeMetadataName ), descriptor.Name ), F.Syntax.Location ); F.Diagnostics.Add(diagnostic); return(false); } return(true); }
internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, ref ArrayBuilder <SynthesizedAttributeData> attributes) { base.AddSynthesizedAttributes(moduleBuilder, ref attributes); Debug.Assert(IsImplicitlyDeclared); var compilation = this.DeclaringCompilation; AddSynthesizedAttribute(ref attributes, compilation.TrySynthesizeAttribute(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor)); Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(WellKnownMember.System_Runtime_CompilerServices_CompilerGeneratedAttribute__ctor)); }
/// <summary> /// Get the MethodSymbol for System.Threading.Interlocked.CompareExchange<T> for a given T. /// </summary> private static MethodSymbol GetConstructedCompareExchangeMethod(TypeSymbol typeArg, CSharpCompilation compilation, Location errorLocation, DiagnosticBag diagnostics) { MethodSymbol compareExchangeDefinition = (MethodSymbol)compilation.GetWellKnownTypeMember(WellKnownMember.System_Threading_Interlocked__CompareExchange_T); if ((object)compareExchangeDefinition == null) { MemberDescriptor memberDescriptor = WellKnownMembers.GetDescriptor(WellKnownMember.System_Threading_Interlocked__CompareExchange_T); WellKnownType containingType = (WellKnownType)memberDescriptor.DeclaringTypeId; diagnostics.Add(ErrorCode.ERR_MissingPredefinedMember, errorLocation, containingType.GetMetadataName(), memberDescriptor.Name); return(null); } return(compareExchangeDefinition.Construct(ImmutableArray.Create <TypeSymbol>(typeArg))); }
/// <summary> /// Synthesizes a custom attribute. /// Returns null if the <paramref name="constructor"/> symbol is missing, /// or any of the members in <paramref name="namedArguments" /> are missing. /// The attribute is synthesized only if present. /// </summary> /// <param name="constructor"> /// Constructor of the attribute. If it doesn't exist, the attribute is not created. /// </param> /// <param name="arguments">Arguments to the attribute constructor.</param> /// <param name="namedArguments"> /// Takes a list of pairs of well-known members and constants. The constants /// will be passed to the field/property referenced by the well-known member. /// If the well-known member does not exist in the compilation then no attribute /// will be synthesized. /// </param> /// <param name="isOptionalUse"> /// Indicates if this particular attribute application should be considered optional. /// </param> internal SynthesizedAttributeData TrySynthesizeAttribute( WellKnownMember constructor, ImmutableArray <TypedConstant> arguments = default(ImmutableArray <TypedConstant>), ImmutableArray <KeyValuePair <WellKnownMember, TypedConstant> > namedArguments = default(ImmutableArray <KeyValuePair <WellKnownMember, TypedConstant> >), bool isOptionalUse = false) { DiagnosticInfo diagnosticInfo; var ctorSymbol = (MethodSymbol)Binder.GetWellKnownTypeMember(this, constructor, out diagnosticInfo, isOptional: true); if ((object)ctorSymbol == null) { // if this assert fails, UseSiteErrors for "member" have not been checked before emitting ... Debug.Assert(isOptionalUse || WellKnownMembers.IsSynthesizedAttributeOptional(constructor)); return(null); } if (arguments.IsDefault) { arguments = ImmutableArray <TypedConstant> .Empty; } ImmutableArray <KeyValuePair <string, TypedConstant> > namedStringArguments; if (namedArguments.IsDefault) { namedStringArguments = ImmutableArray <KeyValuePair <string, TypedConstant> > .Empty; } else { var builder = new ArrayBuilder <KeyValuePair <string, TypedConstant> >(namedArguments.Length); foreach (var arg in namedArguments) { var wellKnownMember = Binder.GetWellKnownTypeMember(this, arg.Key, out diagnosticInfo, isOptional: true); if (wellKnownMember == null || wellKnownMember is ErrorTypeSymbol) { // if this assert fails, UseSiteErrors for "member" have not been checked before emitting ... Debug.Assert(WellKnownMembers.IsSynthesizedAttributeOptional(constructor)); return(null); } else { builder.Add(new KeyValuePair <string, TypedConstant>( wellKnownMember.Name, arg.Value)); } } namedStringArguments = builder.ToImmutableAndFree(); } return(new SynthesizedAttributeData(ctorSymbol, arguments, namedStringArguments)); }
/// <summary> /// Get the symbol for a well-known member. The use of this method to get a well-known member /// that does not exist will result in an exception of type MissingPredefinedMember being thrown /// containing an appropriate diagnostic for the caller to report. /// </summary> /// <param name="wm">The desired well-known member</param> /// <param name="isOptional">If true, the method may return null for a missing member without an exception</param> /// <returns>A symbol for the well-known member, or null if it is missing and isOptions == true</returns> public Symbol WellKnownMember(WellKnownMember wm, bool isOptional = false) { Symbol wellKnownMember = Binder.GetWellKnownTypeMember(Compilation, wm, Diagnostics, syntax: Syntax, isOptional: true); if (wellKnownMember == null && !isOptional) { RuntimeMembers.MemberDescriptor memberDescriptor = WellKnownMembers.GetDescriptor(wm); WellKnownType containingType = (WellKnownType)memberDescriptor.DeclaringTypeId; var diagnostic = new CSDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_MissingPredefinedMember, containingType.GetMetadataName(), memberDescriptor.Name), Syntax.Location); throw new MissingPredefinedMember(diagnostic); } return(wellKnownMember); }
/// <summary> /// Report diagnostics that should be reported when using a synthesized attribute. /// </summary> internal static void ReportUseSiteDiagnosticForSynthesizedAttribute( CSharpCompilation compilation, WellKnownMember attributeMember, DiagnosticBag diagnostics, Location location = null, CSharpSyntaxNode syntax = null) { Debug.Assert((location != null) ^ (syntax != null)); // Dev11 reports use-site diagnostics when an optional attribute is found but is bad for some other reason // (comes from an unified assembly). When the symbol is not found no error is reported. See test VersionUnification_UseSiteDiagnostics_OptionalAttributes. bool isOptional = WellKnownMembers.IsSynthesizedAttributeOptional(attributeMember); GetWellKnownTypeMember(compilation, attributeMember, diagnostics, location, syntax, isOptional); }
private static void ReportErrorOnWellKnownMember(Symbol symbol, WellKnownMember member, BindingDiagnosticBag diagnostics, ref bool hasError) { if ((object)symbol == null) { MemberDescriptor memberDescriptor = WellKnownMembers.GetDescriptor(member); diagnostics.Add(ErrorCode.ERR_MissingPredefinedMember, NoLocation.Singleton, memberDescriptor.DeclaringTypeMetadataName, memberDescriptor.Name); hasError = true; } else { ReportErrorOnSymbol(symbol, diagnostics, ref hasError); ReportErrorOnSymbol(symbol.ContainingType, diagnostics, ref hasError); } }
/// <summary> /// Lookup member declaration in well known type used by this Compilation. /// </summary> /// <remarks> /// If a well-known member of a generic type instantiation is needed use this method to get the corresponding generic definition and /// <see cref="MethodSymbol.AsMember"/> to construct an instantiation. /// </remarks> internal Symbol GetWellKnownTypeMember(WellKnownMember member) { Debug.Assert(member >= 0 && member < WellKnownMember.Count); // Test hook: if a member is marked missing, then return null. if (IsMemberMissing(member)) { return(null); } if (_lazyWellKnownTypeMembers == null || ReferenceEquals(_lazyWellKnownTypeMembers[(int)member], ErrorTypeSymbol.UnknownResultType)) { if (_lazyWellKnownTypeMembers == null) { var wellKnownTypeMembers = new Symbol[(int)WellKnownMember.Count]; for (int i = 0; i < wellKnownTypeMembers.Length; i++) { wellKnownTypeMembers[i] = ErrorTypeSymbol.UnknownResultType; } Interlocked.CompareExchange(ref _lazyWellKnownTypeMembers, wellKnownTypeMembers, null); } MemberDescriptor descriptor = WellKnownMembers.GetDescriptor(member); NamedTypeSymbol type = descriptor.DeclaringTypeId <= (int)SpecialType.Count ? this.GetSpecialType((SpecialType)descriptor.DeclaringTypeId) : this.GetWellKnownType((WellKnownType)descriptor.DeclaringTypeId); Symbol result = null; if (!type.IsErrorType()) { result = GetRuntimeMember(type, ref descriptor, _wellKnownMemberSignatureComparer, accessWithinOpt: this.Assembly); } Interlocked.CompareExchange(ref _lazyWellKnownTypeMembers[(int)member], result, ErrorTypeSymbol.UnknownResultType); } return(_lazyWellKnownTypeMembers[(int)member]); }
private void MethodChecks(MethodDeclarationSyntax syntax, Binder withTypeParamsBinder, DiagnosticBag diagnostics) { SyntaxToken arglistToken; // Constraint checking for parameter and return types must be delayed until // the method has been added to the containing type member list since // evaluating the constraints may depend on accessing this method from // the container (comparing this method to others to find overrides for // instance). Constraints are checked in AfterAddingTypeMembersChecks. var signatureBinder = withTypeParamsBinder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this); _lazyParameters = ParameterHelpers.MakeParameters(signatureBinder, this, syntax.ParameterList, true, out arglistToken, diagnostics, false); _lazyIsVararg = (arglistToken.Kind() == SyntaxKind.ArgListKeyword); RefKind refKind; var returnTypeSyntax = syntax.ReturnType.SkipRef(out refKind); _lazyReturnType = signatureBinder.BindType(returnTypeSyntax, diagnostics); if (_lazyReturnType.IsRestrictedType()) { if (_lazyReturnType.SpecialType == SpecialType.System_TypedReference && (this.ContainingType.SpecialType == SpecialType.System_TypedReference || this.ContainingType.SpecialType == SpecialType.System_ArgIterator)) { // Two special cases: methods in the special types TypedReference and ArgIterator are allowed to return TypedReference } else { // Method or delegate cannot return type '{0}' diagnostics.Add(ErrorCode.ERR_MethodReturnCantBeRefAny, syntax.ReturnType.Location, _lazyReturnType); } } var returnsVoid = _lazyReturnType.SpecialType == SpecialType.System_Void; if (this.RefKind != RefKind.None && returnsVoid) { Debug.Assert(returnTypeSyntax.HasErrors); } // set ReturnsVoid flag this.SetReturnsVoid(returnsVoid); var location = this.Locations[0]; this.CheckEffectiveAccessibility(_lazyReturnType, _lazyParameters, diagnostics); // Checks taken from MemberDefiner::defineMethod if (this.Name == WellKnownMemberNames.DestructorName && this.ParameterCount == 0 && this.Arity == 0 && this.ReturnsVoid) { diagnostics.Add(ErrorCode.WRN_FinalizeMethod, location); } // errors relevant for extension methods if (IsExtensionMethod) { var parameter0Type = this.Parameters[0].Type; if (!parameter0Type.IsValidExtensionParameterType()) { // Duplicate Dev10 behavior by selecting the parameter type. var parameterSyntax = syntax.ParameterList.Parameters[0]; Debug.Assert(parameterSyntax.Type != null); var loc = parameterSyntax.Type.Location; diagnostics.Add(ErrorCode.ERR_BadTypeforThis, loc, parameter0Type); } else if ((object)ContainingType.ContainingType != null) { diagnostics.Add(ErrorCode.ERR_ExtensionMethodsDecl, location, ContainingType.Name); } else if (!ContainingType.IsScriptClass && !(ContainingType.IsStatic && ContainingType.Arity == 0)) { // Duplicate Dev10 behavior by selecting the containing type identifier. However if there // is no containing type (in the interactive case for instance), select the method identifier. var typeDecl = syntax.Parent as TypeDeclarationSyntax; var identifier = (typeDecl != null) ? typeDecl.Identifier : syntax.Identifier; var loc = identifier.GetLocation(); diagnostics.Add(ErrorCode.ERR_BadExtensionAgg, loc); } else if (!IsStatic) { diagnostics.Add(ErrorCode.ERR_BadExtensionMeth, location); } else { // Verify ExtensionAttribute is available. var attributeConstructor = withTypeParamsBinder.Compilation.GetWellKnownTypeMember(WellKnownMember.System_Runtime_CompilerServices_ExtensionAttribute__ctor); if ((object)attributeConstructor == null) { var memberDescriptor = WellKnownMembers.GetDescriptor(WellKnownMember.System_Runtime_CompilerServices_ExtensionAttribute__ctor); // do not use Binder.ReportUseSiteErrorForAttributeCtor in this case, because we'll need to report a special error id, not a generic use site error. diagnostics.Add( ErrorCode.ERR_ExtensionAttrNotFound, syntax.ParameterList.Parameters[0].Modifiers.FirstOrDefault(SyntaxKind.ThisKeyword).GetLocation(), memberDescriptor.DeclaringTypeMetadataName); } } } if (this.MethodKind == MethodKind.UserDefinedOperator) { foreach (var p in this.Parameters) { if (p.RefKind != RefKind.None) { diagnostics.Add(ErrorCode.ERR_IllegalRefParam, location); break; } } } else if (IsPartial) { // check that there are no out parameters in a partial foreach (var p in this.Parameters) { if (p.RefKind == RefKind.Out) { diagnostics.Add(ErrorCode.ERR_PartialMethodCannotHaveOutParameters, location); break; } } if (MethodKind == MethodKind.ExplicitInterfaceImplementation) { diagnostics.Add(ErrorCode.ERR_PartialMethodNotExplicit, location); } if (!ContainingType.IsPartial() || ContainingType.IsInterface) { diagnostics.Add(ErrorCode.ERR_PartialMethodOnlyInPartialClass, location); } } if (!IsPartial) { LazyAsyncMethodChecks(CancellationToken.None); Debug.Assert(state.HasComplete(CompletionPart.FinishAsyncMethodChecks)); } // The runtime will not treat this method as an override or implementation of another // method unless both the signatures and the custom modifiers match. Hence, in the // case of overrides and *explicit* implementations, we need to copy the custom modifiers // that are in the signature of the overridden/implemented method. (From source, we know // that there can only be one such method, so there are no conflicts.) This is // unnecessary for implicit implementations because, if the custom modifiers don't match, // we'll insert a bridge method (an explicit implementation that delegates to the implicit // implementation) with the correct custom modifiers // (see SourceNamedTypeSymbol.ImplementInterfaceMember). // Note: we're checking if the syntax indicates explicit implementation rather, // than if explicitInterfaceType is null because we don't want to look for an // overridden property if this is supposed to be an explicit implementation. if (syntax.ExplicitInterfaceSpecifier == null) { Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault); _lazyExplicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty; // This value may not be correct, but we need something while we compute this.OverriddenMethod. // May be re-assigned below. Debug.Assert(_lazyReturnTypeCustomModifiers.IsDefault); Debug.Assert(_lazyCountOfCustomModifiersPrecedingByRef == 0); _lazyReturnTypeCustomModifiers = ImmutableArray <CustomModifier> .Empty; _lazyCountOfCustomModifiersPrecedingByRef = 0; // If this method is an override, we may need to copy custom modifiers from // the overridden method (so that the runtime will recognize it as an override). // We check for this case here, while we can still modify the parameters and // return type without losing the appearance of immutability. if (this.IsOverride) { // This computation will necessarily be performed with partially incomplete // information. There is no way we can determine the complete signature // (i.e. including custom modifiers) until we have found the method that // this method overrides. To accommodate this, MethodSymbol.OverriddenOrHiddenMembers // is written to allow relaxed matching of custom modifiers for source methods, // on the assumption that they will be updated appropriately. MethodSymbol overriddenMethod = this.OverriddenMethod; if ((object)overriddenMethod != null) { CustomModifierUtils.CopyMethodCustomModifiers(overriddenMethod, this, out _lazyReturnType, out _lazyReturnTypeCustomModifiers, out _lazyCountOfCustomModifiersPrecedingByRef, out _lazyParameters, alsoCopyParamsModifier: true); } } } else if ((object)_explicitInterfaceType != null) { //do this last so that it can assume the method symbol is constructed (except for ExplicitInterfaceImplementation) MethodSymbol implementedMethod = this.FindExplicitlyImplementedMethod(_explicitInterfaceType, syntax.Identifier.ValueText, syntax.ExplicitInterfaceSpecifier, diagnostics); if ((object)implementedMethod != null) { Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault); _lazyExplicitInterfaceImplementations = ImmutableArray.Create <MethodSymbol>(implementedMethod); CustomModifierUtils.CopyMethodCustomModifiers(implementedMethod, this, out _lazyReturnType, out _lazyReturnTypeCustomModifiers, out _lazyCountOfCustomModifiersPrecedingByRef, out _lazyParameters, alsoCopyParamsModifier: false); } else { Debug.Assert(_lazyExplicitInterfaceImplementations.IsDefault); _lazyExplicitInterfaceImplementations = ImmutableArray <MethodSymbol> .Empty; Debug.Assert(_lazyReturnTypeCustomModifiers.IsDefault); Debug.Assert(_lazyCountOfCustomModifiersPrecedingByRef == 0); _lazyReturnTypeCustomModifiers = ImmutableArray <CustomModifier> .Empty; _lazyCountOfCustomModifiersPrecedingByRef = 0; } } CheckModifiers(location, diagnostics); }
internal static MemberSymbol Get(WellKnownMembers kind) { Debug.Assert(WellKnownMemberSymbols != null); return(WellKnownMemberSymbols[(int)kind]); }