/// <summary> /// Most of the above optimizations are not applicable in expression trees as the operator /// must stay a binary operator. We cannot do much beyond constant folding which is done in binder. /// </summary> private BoundExpression RewriteStringConcatInExpressionLambda(SyntaxNode syntax, BinaryOperatorKind operatorKind, BoundExpression loweredLeft, BoundExpression loweredRight, TypeSymbol type) { SpecialMember member = (operatorKind == BinaryOperatorKind.StringConcatenation) ? SpecialMember.System_String__ConcatStringString : SpecialMember.System_String__ConcatObjectObject; var method = UnsafeGetSpecialTypeMethod(syntax, member); Debug.Assert((object)method != null); return(new BoundBinaryOperator(syntax, operatorKind, default(ConstantValue), method, default(LookupResultKind), loweredLeft, loweredRight, type)); }
private BoundNode RewriteDelegateOperation(BoundBinaryOperator node, SpecialMember member) { Debug.Assert(node != null); var method = (MethodSymbol)this.compilation.Assembly.GetSpecialTypeMember(member); // UNDONE: Handle the bizarre error case where we don't have the expected methods. Debug.Assert(method != null); BoundExpression call = BoundCall.SynthesizedCall(null, method, node.Left, node.Right); BoundExpression result = method.ReturnType.SpecialType == SpecialType.System_Delegate ? BoundConversion.SynthesizedConversion(call, ConversionKind.ExplicitReference, node.Type) : call; return Visit(result); }
private BoundExpression RewriteStringConcatenationTwoExprs(SyntaxNode syntax, BoundExpression loweredLeft, BoundExpression loweredRight) { SpecialMember member = (loweredLeft.Type.SpecialType == SpecialType.System_String && loweredRight.Type.SpecialType == SpecialType.System_String) ? SpecialMember.System_String__ConcatStringString : SpecialMember.System_String__ConcatObjectObject; var method = GetSpecialTypeMethod(syntax, member); Debug.Assert((object)method != null); return((BoundExpression)BoundCall.Synthesized(syntax, null, method, loweredLeft, loweredRight)); }
private BoundNode RewriteDelegateOperation(BoundBinaryOperator node, SpecialMember member) { Debug.Assert(node != null); var method = (MethodSymbol)this.compilation.Assembly.GetSpecialTypeMember(member); // UNDONE: Handle the bizarre error case where we don't have the expected methods. Debug.Assert(method != null); BoundExpression call = BoundCall.SynthesizedCall(null, method, node.Left, node.Right); BoundExpression result = method.ReturnType.SpecialType == SpecialType.System_Delegate ? BoundConversion.SynthesizedConversion(call, ConversionKind.ExplicitReference, node.Type) : call; return(Visit(result)); }
private static void ReportErrorOnSpecialMember(Symbol symbol, SpecialMember member, DiagnosticBag diagnostics, ref bool hasError) { if ((object)symbol == null) { MemberDescriptor memberDescriptor = SpecialMembers.GetDescriptor(member); diagnostics.Add(ErrorCode.ERR_MissingPredefinedMember, NoLocation.Singleton, ((SpecialType)memberDescriptor.DeclaringTypeId).GetMetadataName(), memberDescriptor.Name); hasError = true; } else { ReportErrorOnSymbol(symbol, diagnostics, ref hasError); } }
private static void ReportErrorOnSpecialMember(Symbol symbol, SpecialMember member, BindingDiagnosticBag diagnostics, ref bool hasError) { if ((object)symbol == null) { MemberDescriptor memberDescriptor = SpecialMembers.GetDescriptor(member); diagnostics.Add(ErrorCode.ERR_MissingPredefinedMember, NoLocation.Singleton, memberDescriptor.DeclaringTypeMetadataName, memberDescriptor.Name); hasError = true; } else { ReportErrorOnSymbol(symbol, diagnostics, ref hasError); } }
private BoundExpression RewriteStringConcatenationThreeExprs(SyntaxNode syntax, BoundExpression loweredFirst, BoundExpression loweredSecond, BoundExpression loweredThird) { SpecialMember member = (loweredFirst.Type.SpecialType == SpecialType.System_String && loweredSecond.Type.SpecialType == SpecialType.System_String && loweredThird.Type.SpecialType == SpecialType.System_String) ? SpecialMember.System_String__ConcatStringStringString : SpecialMember.System_String__ConcatObjectObjectObject; var method = UnsafeGetSpecialTypeMethod(syntax, member); Debug.Assert((object)method != null); return(BoundCall.Synthesized(syntax, null, method, ImmutableArray.Create(loweredFirst, loweredSecond, loweredThird))); }
/// <summary> /// Get the symbol for a special member. The use of this method to get a special 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="sm">The desired special member</param> /// <returns>A symbol for the special member.</returns> public Symbol SpecialMember(SpecialMember sm) { Symbol specialMember = Compilation.GetSpecialTypeMember(sm); if (specialMember == null) { RuntimeMembers.MemberDescriptor memberDescriptor = SpecialMembers.GetDescriptor(sm); SpecialType containingType = (SpecialType)memberDescriptor.DeclaringTypeId; var diagnostic = new CSDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_MissingPredefinedMember, containingType.GetMetadataName(), memberDescriptor.Name), Syntax.Location); throw new MissingPredefinedMember(diagnostic); } Binder.ReportUseSiteDiagnostics(specialMember, Diagnostics, Syntax); return(specialMember); }
private BoundNode RewriteStringEquality(BoundBinaryOperator node, SpecialMember member) { Debug.Assert(node != null); Debug.Assert(node.ConstantValueOpt == null); if (node.Left.ConstantValue == ConstantValue.Null || node.Right.ConstantValue == ConstantValue.Null) { return base.VisitBinaryOperator(node); } var method = (MethodSymbol)this.compilation.Assembly.GetSpecialTypeMember(member); Debug.Assert(method != null); return Visit(BoundCall.SynthesizedCall(null, method, node.Left, node.Right)); }
private BoundNode RewriteStringEquality(BoundBinaryOperator node, SpecialMember member) { Debug.Assert(node != null); Debug.Assert(node.ConstantValueOpt == null); if (node.Left.ConstantValue == ConstantValue.Null || node.Right.ConstantValue == ConstantValue.Null) { return(base.VisitBinaryOperator(node)); } var method = (MethodSymbol)this.compilation.Assembly.GetSpecialTypeMember(member); Debug.Assert(method != null); return(Visit(BoundCall.SynthesizedCall(null, method, node.Left, node.Right))); }
private void EnsureSpecialPropertyGetter(SpecialMember member, BindingDiagnosticBag bag) { PropertySymbol symbol = (PropertySymbol)EnsureSpecialMember(member, bag); if ((object)symbol != null) { var getter = symbol.GetMethod; if ((object)getter == null) { Binder.Error(bag, ErrorCode.ERR_PropertyLacksGet, body.Syntax, symbol); return; } bag.ReportUseSite(getter, body.Syntax.Location); } }
/// <summary> /// This function provides a false sense of security, it is likely going to surprise you when the requested member is missing. /// Recommendation: Do not use, use <see cref="TryGetSpecialTypeMethod(SyntaxNode, SpecialMember, CSharpCompilation, DiagnosticBag, out MethodSymbol)"/> instead! /// If used, a unit-test with a missing member is absolutely a must have. /// </summary> private static MethodSymbol UnsafeGetSpecialTypeMethod(SyntaxNode syntax, SpecialMember specialMember, CSharpCompilation compilation, DiagnosticBag diagnostics) { MethodSymbol method; if (TryGetSpecialTypeMethod(syntax, specialMember, compilation, diagnostics, out method)) { return(method); } else { MemberDescriptor descriptor = SpecialMembers.GetDescriptor(specialMember); SpecialType type = (SpecialType)descriptor.DeclaringTypeId; TypeSymbol container = compilation.Assembly.GetSpecialType(type); TypeSymbol returnType = new ExtendedErrorTypeSymbol(compilation: compilation, name: descriptor.Name, errorInfo: null, arity: descriptor.Arity); return(new ErrorMethodSymbol(container, returnType, "Missing")); } }
private MethodSymbol GetSpecialTypeMethod(CSharpSyntaxNode syntax, SpecialMember specialMember) { MethodSymbol method; if (Binder.TryGetSpecialTypeMember(_compilation, specialMember, syntax, _diagnostics, out method)) { return(method); } else { MemberDescriptor descriptor = SpecialMembers.GetDescriptor(specialMember); SpecialType type = (SpecialType)descriptor.DeclaringTypeId; TypeSymbol container = _compilation.Assembly.GetSpecialType(type); TypeSymbol returnType = new ExtendedErrorTypeSymbol(compilation: _compilation, name: descriptor.Name, errorInfo: null, arity: descriptor.Arity); return(new ErrorMethodSymbol(container, returnType, "Missing")); } }
private BoundExpression RewriteStringConcatenationManyExprs(SyntaxNode syntax, ImmutableArray <BoundExpression> loweredArgs) { Debug.Assert(loweredArgs.Length > 3); Debug.Assert(loweredArgs.All(a => a.HasErrors || a.Type.SpecialType == SpecialType.System_Object || a.Type.SpecialType == SpecialType.System_String)); bool isObject = false; TypeSymbol elementType = null; foreach (var arg in loweredArgs) { elementType = arg.Type; if (elementType.SpecialType != SpecialType.System_String) { isObject = true; break; } } // Count == 4 is handled differently because there is a Concat method with 4 arguments // for strings, but there is no such method for objects. if (!isObject && loweredArgs.Length == 4) { SpecialMember member = SpecialMember.System_String__ConcatStringStringStringString; var method = UnsafeGetSpecialTypeMethod(syntax, member); Debug.Assert((object)method != null); return((BoundExpression)BoundCall.Synthesized(syntax, null, method, loweredArgs)); } else { SpecialMember member = isObject ? SpecialMember.System_String__ConcatObjectArray : SpecialMember.System_String__ConcatStringArray; var method = UnsafeGetSpecialTypeMethod(syntax, member); Debug.Assert((object)method != null); var array = _factory.ArrayOrEmpty(elementType, loweredArgs); return((BoundExpression)BoundCall.Synthesized(syntax, null, method, array)); } }
/// <summary> /// Check that the property and its getter exist and collect any use-site errors. /// </summary> private void EnsureSpecialPropertyGetter(SpecialMember member, DiagnosticBag bag) { PropertySymbol symbol = (PropertySymbol)EnsureSpecialMember(member, bag); if ((object)symbol != null) { var getter = symbol.GetMethod; if ((object)getter == null) { Binder.Error(bag, ErrorCode.ERR_PropertyLacksGet, body.Syntax, symbol); return; } var info = getter.GetUseSiteDiagnostic(); if ((object)info != null) { bag.Add(new CSDiagnostic(info, body.Syntax.Location)); } } }
private bool TryGetSpecialTypeMember <TSymbol>(CSharpSyntaxNode syntax, SpecialMember specialMember, out TSymbol symbol) where TSymbol : Symbol { symbol = (TSymbol)this.compilation.Assembly.GetSpecialTypeMember(specialMember); if ((object)symbol == null) { MemberDescriptor descriptor = SpecialMembers.GetDescriptor(specialMember); diagnostics.Add(ErrorCode.ERR_MissingPredefinedMember, syntax.Location, descriptor.DeclaringTypeMetadataName, descriptor.Name); return(false); } else { var useSiteDiagnostic = symbol.GetUseSiteDiagnosticForSymbolOrContainingType(); if (useSiteDiagnostic != null) { Symbol.ReportUseSiteDiagnostic(useSiteDiagnostic, diagnostics, new SourceLocation(syntax)); } } return(true); }
public static string TranslateSpecialProperty(this MemberReferenceExpression mre) { IEnumerable <object> annotations = mre.Target.Annotations;//mre.Annotations.Any() ? mre.Annotations : if (annotations.Count() > 0) { foreach (var ann in mre.Target.Annotations) { var pd = ann as ICSharpCode.Decompiler.ILAst.ILVariable; if (pd != null) { SpecialMember sm = CUDALanguage.GetSpecialProperty(mre.MemberName, pd.Type.FullName); if (sm != null) { return(sm.GetTranslation(mre)); } else { return(mre.MemberName); } } else { var fd = ann as FieldDefinition; if (fd != null) { SpecialMember sm = CUDALanguage.GetSpecialProperty(mre.MemberName, fd.FieldType.GetType().Name); return(sm.GetTranslation(mre)); } else if (mre.NodeType == NodeType.Expression) { if (mre.MemberName == "Length") { return((mre.Target.ToString().Length - 2).ToString()); } } } } } throw new InvalidOperationException("SpecialProperty not found."); }
/// <summary> /// Lookup member declaration in predefined CorLib type in this Assembly. Only valid if this /// assembly is the Cor Library /// </summary> internal override Symbol GetDeclaredSpecialTypeMember(SpecialMember member) { #if DEBUG foreach (var module in this.Modules) { Debug.Assert(module.ReferencedAssemblies.Length == 0); } #endif if (_lazySpecialTypeMembers == null || ReferenceEquals(_lazySpecialTypeMembers[(int)member], ErrorTypeSymbol.UnknownResultType)) { if (_lazySpecialTypeMembers == null) { var specialTypeMembers = new Symbol[(int)SpecialMember.Count]; for (int i = 0; i < specialTypeMembers.Length; i++) { specialTypeMembers[i] = ErrorTypeSymbol.UnknownResultType; } Interlocked.CompareExchange(ref _lazySpecialTypeMembers, specialTypeMembers, null); } var descriptor = SpecialMembers.GetDescriptor(member); NamedTypeSymbol type = (NamedTypeSymbol)GetDeclaredSpecialSymbol((SpecialType)descriptor.DeclaringTypeId); Symbol result = null; if (!type.IsErrorType()) { throw new NotImplementedException("TODO:MetaDslx"); // result = LanguageCompilation.GetRuntimeMember(type, ref descriptor, LanguageCompilation.SpecialMembersSignatureComparer.Instance, accessWithinOpt: null); } Interlocked.CompareExchange(ref _lazySpecialTypeMembers[(int)member], result, ErrorTypeSymbol.UnknownResultType); } return(_lazySpecialTypeMembers[(int)member]); }
/// <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 } &&
public static SpecialMember GetSpecialMethod(this MemberReferenceExpression mre) { SpecialMember sm = null; if (mre.Target.Annotations.Count() > 0) { foreach (var ann in mre.Target.Annotations) { var pd = ann as ICSharpCode.Decompiler.ILAst.ILVariable; if (pd != null) { sm = CUDALanguage.GetSpecialMethod(mre.MemberName, pd.Type.FullName);//.GetType().Name)) if (sm != null) { return(sm); } } else { var fd = ann as FieldDefinition; if (fd != null) { sm = CUDALanguage.GetSpecialMethod(mre.MemberName, fd.FieldType.GetType().Name); if (sm != null) { return(sm); } } } } } else { return(CUDALanguage.GetSpecialMethod(mre.MemberName, mre.Target.ToString())); } return(sm); }
/// <summary> /// This function provides a false sense of security, it is likely going to surprise you when the requested member is missing. /// Recommendation: Do not use, use <see cref="TryGetSpecialTypeMethod(SyntaxNode, SpecialMember, out MethodSymbol)"/> instead! /// If used, a unit-test with a missing member is absolutely a must have. /// </summary> private MethodSymbol UnsafeGetSpecialTypeMethod(SyntaxNode syntax, SpecialMember specialMember) { return(UnsafeGetSpecialTypeMethod(syntax, specialMember, _compilation, _diagnostics)); }
/// <summary> /// Get the symbol for the predefined type member from the COR Library referenced by this compilation. /// </summary> internal Symbol GetSpecialTypeMember(SpecialMember specialMember) { return(this.CorLibrary.GetDeclaredSpecialTypeMember(specialMember)); }
internal override Symbol GetDeclaredSpecialTypeMember(SpecialMember member) { return null; }
/// <summary> /// Get the symbol for a special member. The use of this method to get a special 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="sm">The desired special member</param> /// <returns>A symbol for the special member.</returns> public Symbol SpecialMember(SpecialMember sm) { Symbol specialMember = Compilation.GetSpecialTypeMember(sm); if (specialMember == null) { RuntimeMembers.MemberDescriptor memberDescriptor = SpecialMembers.GetDescriptor(sm); SpecialType containingType = (SpecialType)memberDescriptor.DeclaringTypeId; var diagnostic = new CSDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_MissingPredefinedMember, containingType.GetMetadataName(), memberDescriptor.Name), Syntax.Location); throw new MissingPredefinedMember(diagnostic); } Binder.ReportUseSiteDiagnostics(specialMember, Diagnostics, Syntax); return specialMember; }
public PropertySymbol SpecialProperty(SpecialMember sm) { return (PropertySymbol)SpecialMember(sm); }
/// <summary> /// Lookup member declaration in predefined CorLib type in this Assembly. Only valid if this /// assembly is the Cor Library /// </summary> internal Symbol GetDeclaredSpecialTypeMember(SpecialMember member) { if (_lazySpecialTypeMembers == null || ReferenceEquals(_lazySpecialTypeMembers[(int)member], ErrorTypeSymbol.UnknownResultType)) { if (_lazySpecialTypeMembers == null) { var specialTypeMembers = new Symbol[(int)SpecialMember.Count]; for (int i = 0; i < specialTypeMembers.Length; i++) { specialTypeMembers[i] = ErrorTypeSymbol.UnknownResultType; } Interlocked.CompareExchange(ref _lazySpecialTypeMembers, specialTypeMembers, null); } var descriptor = SpecialMembers.GetDescriptor(member); NamedTypeSymbol type = GetDeclaredSpecialType((SpecialType)descriptor.DeclaringTypeId); Symbol result = null; if (!type.IsErrorType()) { result = PhpCompilation.GetRuntimeMember(type, ref descriptor, PhpCompilation.SpecialMembersSignatureComparer.Instance, null); } Interlocked.CompareExchange(ref _lazySpecialTypeMembers[(int)member], result, ErrorTypeSymbol.UnknownResultType); } return _lazySpecialTypeMembers[(int)member]; }
private static bool TryGetSpecialTypeMethod(SyntaxNode syntax, SpecialMember specialMember, CSharpCompilation compilation, DiagnosticBag diagnostics, out MethodSymbol method) { return(Binder.TryGetSpecialTypeMember(compilation, specialMember, syntax, diagnostics, out method)); }
internal bool IsMemberMissing(SpecialMember member) { return IsMemberMissing(-(int)member - 1); }
private BoundExpression RewriteStringEquality(BoundBinaryOperator oldNode, CSharpSyntaxNode syntax, BinaryOperatorKind operatorKind, BoundExpression loweredLeft, BoundExpression loweredRight, TypeSymbol type, SpecialMember member) { if (oldNode != null && (loweredLeft.ConstantValue == ConstantValue.Null || loweredRight.ConstantValue == ConstantValue.Null)) { return oldNode.Update(operatorKind, loweredLeft, loweredRight, oldNode.ConstantValueOpt, oldNode.MethodOpt, oldNode.ResultKind, type); } var method = GetSpecialTypeMethod(syntax, member); Debug.Assert((object)method != null); return BoundCall.Synthesized(syntax, null, method, loweredLeft, loweredRight); }
/// <summary> /// Get the symbol for the predefined type member from the COR Library referenced by this compilation. /// </summary> internal Symbol GetSpecialTypeMember(SpecialMember specialMember) { return Assembly.GetSpecialTypeMember(specialMember); }
/// <summary> /// Lookup member declaration in predefined CorLib type in this Assembly. Only valid if this /// assembly is the Cor Library /// </summary> internal virtual Symbol GetDeclaredSpecialTypeMember(SpecialMember member) { return(null); }
public static MemberDescriptor GetDescriptor(SpecialMember member) { return(s_descriptors[(int)member]); }
private BoundNode BuildBinaryOperatorCall(SyntaxNode syntaxNode, BoundExpression left, BoundExpression right, SpecialMember member) { // call Operator (left, right) var memberSymbol = (MethodSymbol)this.compilation.Assembly.GetSpecialTypeMember(member); Debug.Assert(memberSymbol != null); // Should have been checked during Warnings pass return BoundCall.Synthesized( syntaxNode, null, memberSymbol, ReadOnlyArray<BoundExpression>.CreateFrom(new BoundExpression[] { left, right })); }
private bool TryGetSpecialTypeMethod(SyntaxNode syntax, SpecialMember specialMember, out MethodSymbol method) { return(TryGetSpecialTypeMethod(syntax, specialMember, _compilation, _diagnostics, out method)); }
private Symbol EnsureSpecialMember(SpecialMember member, DiagnosticBag bag) { Symbol symbol; Binder.TryGetSpecialTypeMember(F.Compilation, member, body.Syntax, bag, out symbol); return symbol; }
internal override Symbol GetDeclaredSpecialTypeMember(SpecialMember member) { return(null); }
private BoundNode BuildBinaryOperatorCall(SyntaxNode syntaxNode, BoundExpression left, BoundExpression right, SpecialMember member) { // call Operator (left, right) var memberSymbol = (MethodSymbol)this.compilation.Assembly.GetSpecialTypeMember(member); Debug.Assert(memberSymbol != null); // Should have been checked during Warnings pass return(BoundCall.Synthesized( syntaxNode, null, memberSymbol, ReadOnlyArray <BoundExpression> .CreateFrom(new BoundExpression[] { left, right }))); }
public MethodSymbol SpecialMethod(SpecialMember sm) { return (MethodSymbol)SpecialMember(sm); }
/// <summary> /// Lookup member declaration in predefined CorLib type in this Assembly. Only valid if this /// assembly is the Cor Library /// </summary> internal override Symbol GetDeclaredSpecialTypeMember(SpecialMember member) { #if DEBUG foreach (var module in this.Modules) { Debug.Assert(module.GetReferencedAssemblies().Length == 0); } #endif if (_lazySpecialTypeMembers == null || ReferenceEquals(_lazySpecialTypeMembers[(int)member], ErrorTypeSymbol.UnknownResultType)) { if (_lazySpecialTypeMembers == null) { var specialTypeMembers = new Symbol[(int)SpecialMember.Count]; for (int i = 0; i < specialTypeMembers.Length; i++) { specialTypeMembers[i] = ErrorTypeSymbol.UnknownResultType; } Interlocked.CompareExchange(ref _lazySpecialTypeMembers, specialTypeMembers, null); } var descriptor = SpecialMembers.GetDescriptor(member); NamedTypeSymbol type = GetDeclaredSpecialType((SpecialType)descriptor.DeclaringTypeId); Symbol result = null; if (!type.IsErrorType()) { result = CSharpCompilation.GetRuntimeMember(type, ref descriptor, CSharpCompilation.SpecialMembersSignatureComparer.Instance, accessWithinOpt: null); } Interlocked.CompareExchange(ref _lazySpecialTypeMembers[(int)member], result, ErrorTypeSymbol.UnknownResultType); } return _lazySpecialTypeMembers[(int)member]; }
private static bool IsSpecialMember(MethodSymbol method, SpecialMember specialMember) { method = method.OriginalDefinition; return(method.ContainingAssembly?.GetSpecialTypeMember(specialMember) == method); }
public static MemberDescriptor GetDescriptor(SpecialMember member) { return descriptors[(int)member]; }
/// <summary> /// Generate a thread-safe accessor for a regular field-like event. /// /// DelegateType tmp0 = _event; //backing field /// DelegateType tmp1; /// DelegateType tmp2; /// do { /// tmp1 = tmp0; /// tmp2 = (DelegateType)Delegate.Combine(tmp1, value); //Remove for -= /// tmp0 = Interlocked.CompareExchange<DelegateType>(ref _event, tmp2, tmp1); /// } while ((object)tmp0 != (object)tmp1); /// /// Note, if System.Threading.Interlocked.CompareExchange<T> is not available, /// we emit the following code and mark the method Synchronized (unless it is a struct). /// /// _event = (DelegateType)Delegate.Combine(_event, value); //Remove for -= /// /// </summary> internal static BoundBlock ConstructFieldLikeEventAccessorBody_Regular(SourceEventSymbol eventSymbol, bool isAddMethod, CSharpCompilation compilation, DiagnosticBag diagnostics) { CSharpSyntaxNode syntax = eventSymbol.CSharpSyntaxNode; TypeSymbol delegateType = eventSymbol.Type; MethodSymbol accessor = isAddMethod ? eventSymbol.AddMethod : eventSymbol.RemoveMethod; ParameterSymbol thisParameter = accessor.ThisParameter; TypeSymbol boolType = compilation.GetSpecialType(SpecialType.System_Boolean); SpecialMember updateMethodId = isAddMethod ? SpecialMember.System_Delegate__Combine : SpecialMember.System_Delegate__Remove; MethodSymbol updateMethod = (MethodSymbol)compilation.GetSpecialTypeMember(updateMethodId); BoundStatement @return = new BoundReturnStatement(syntax, expressionOpt: null) { WasCompilerGenerated = true }; if (updateMethod == null) { MemberDescriptor memberDescriptor = SpecialMembers.GetDescriptor(updateMethodId); diagnostics.Add(new CSDiagnostic(new CSDiagnosticInfo(ErrorCode.ERR_MissingPredefinedMember, memberDescriptor.DeclaringTypeMetadataName, memberDescriptor.Name), syntax.Location)); return(new BoundBlock(syntax, locals: ImmutableArray <LocalSymbol> .Empty, statements: ImmutableArray.Create <BoundStatement>(@return)) { WasCompilerGenerated = true }); } Binder.ReportUseSiteDiagnostics(updateMethod, diagnostics, syntax); BoundThisReference fieldReceiver = eventSymbol.IsStatic ? null : new BoundThisReference(syntax, thisParameter.Type) { WasCompilerGenerated = true }; BoundFieldAccess boundBackingField = new BoundFieldAccess(syntax, receiver: fieldReceiver, fieldSymbol: eventSymbol.AssociatedField, constantValueOpt: null) { WasCompilerGenerated = true }; BoundParameter boundParameter = new BoundParameter(syntax, parameterSymbol: accessor.Parameters[0]) { WasCompilerGenerated = true }; BoundExpression delegateUpdate; MethodSymbol compareExchangeMethod = (MethodSymbol)compilation.GetWellKnownTypeMember(WellKnownMember.System_Threading_Interlocked__CompareExchange_T); if ((object)compareExchangeMethod == null) { // (DelegateType)Delegate.Combine(_event, value) delegateUpdate = BoundConversion.SynthesizedNonUserDefined(syntax, operand: BoundCall.Synthesized(syntax, receiverOpt: null, method: updateMethod, arguments: ImmutableArray.Create <BoundExpression>(boundBackingField, boundParameter)), kind: ConversionKind.ExplicitReference, type: delegateType); // _event = (DelegateType)Delegate.Combine(_event, value); BoundStatement eventUpdate = new BoundExpressionStatement(syntax, expression: new BoundAssignmentOperator(syntax, left: boundBackingField, right: delegateUpdate, type: delegateType) { WasCompilerGenerated = true }) { WasCompilerGenerated = true }; return(new BoundBlock(syntax, locals: ImmutableArray <LocalSymbol> .Empty, statements: ImmutableArray.Create <BoundStatement>( eventUpdate, @return)) { WasCompilerGenerated = true }); } compareExchangeMethod = compareExchangeMethod.Construct(ImmutableArray.Create <TypeSymbol>(delegateType)); Binder.ReportUseSiteDiagnostics(compareExchangeMethod, diagnostics, syntax); GeneratedLabelSymbol loopLabel = new GeneratedLabelSymbol("loop"); const int numTemps = 3; LocalSymbol[] tmps = new LocalSymbol[numTemps]; BoundLocal[] boundTmps = new BoundLocal[numTemps]; for (int i = 0; i < numTemps; i++) { tmps[i] = new SynthesizedLocal(accessor, delegateType, SynthesizedLocalKind.LoweringTemp); boundTmps[i] = new BoundLocal(syntax, tmps[i], null, delegateType); } // tmp0 = _event; BoundStatement tmp0Init = new BoundExpressionStatement(syntax, expression: new BoundAssignmentOperator(syntax, left: boundTmps[0], right: boundBackingField, type: delegateType) { WasCompilerGenerated = true }) { WasCompilerGenerated = true }; // LOOP: BoundStatement loopStart = new BoundLabelStatement(syntax, label: loopLabel) { WasCompilerGenerated = true }; // tmp1 = tmp0; BoundStatement tmp1Update = new BoundExpressionStatement(syntax, expression: new BoundAssignmentOperator(syntax, left: boundTmps[1], right: boundTmps[0], type: delegateType) { WasCompilerGenerated = true }) { WasCompilerGenerated = true }; // (DelegateType)Delegate.Combine(tmp1, value) delegateUpdate = BoundConversion.SynthesizedNonUserDefined(syntax, operand: BoundCall.Synthesized(syntax, receiverOpt: null, method: updateMethod, arguments: ImmutableArray.Create <BoundExpression>(boundTmps[1], boundParameter)), kind: ConversionKind.ExplicitReference, type: delegateType); // tmp2 = (DelegateType)Delegate.Combine(tmp1, value); BoundStatement tmp2Update = new BoundExpressionStatement(syntax, expression: new BoundAssignmentOperator(syntax, left: boundTmps[2], right: delegateUpdate, type: delegateType) { WasCompilerGenerated = true }) { WasCompilerGenerated = true }; // Interlocked.CompareExchange<DelegateType>(ref _event, tmp2, tmp1) BoundExpression compareExchange = BoundCall.Synthesized(syntax, receiverOpt: null, method: compareExchangeMethod, arguments: ImmutableArray.Create <BoundExpression>(boundBackingField, boundTmps[2], boundTmps[1])); // tmp0 = Interlocked.CompareExchange<DelegateType>(ref _event, tmp2, tmp1); BoundStatement tmp0Update = new BoundExpressionStatement(syntax, expression: new BoundAssignmentOperator(syntax, left: boundTmps[0], right: compareExchange, type: delegateType) { WasCompilerGenerated = true }) { WasCompilerGenerated = true }; // tmp0 == tmp1 // i.e. exit when they are equal, jump to start otherwise BoundExpression loopExitCondition = new BoundBinaryOperator(syntax, operatorKind: BinaryOperatorKind.ObjectEqual, left: boundTmps[0], right: boundTmps[1], constantValueOpt: null, methodOpt: null, resultKind: LookupResultKind.Viable, type: boolType) { WasCompilerGenerated = true }; // branchfalse (tmp0 == tmp1) LOOP BoundStatement loopEnd = new BoundConditionalGoto(syntax, condition: loopExitCondition, jumpIfTrue: false, label: loopLabel) { WasCompilerGenerated = true }; return(new BoundBlock(syntax, locals: tmps.AsImmutable(), statements: ImmutableArray.Create <BoundStatement>( tmp0Init, loopStart, tmp1Update, tmp2Update, tmp0Update, loopEnd, @return)) { WasCompilerGenerated = true }); }
private static bool IsSpecialMember(MethodSymbol method, SpecialMember specialMember) { method = method.OriginalDefinition; return method.ContainingAssembly?.GetSpecialTypeMember(specialMember) == method; }
/// <summary> /// Lookup member declaration in predefined CorLib type used by this Assembly. /// </summary> internal virtual Symbol GetSpecialTypeMember(SpecialMember member) { return(CorLibrary.GetDeclaredSpecialTypeMember(member)); }
public static ISymbol GetSpecialTypeMember(this Compilation compilation, SpecialMember specialMember) { return(((CSharpCompilation)compilation).GetSpecialTypeMember(specialMember).GetPublicSymbol()); }
internal void MakeMemberMissing(SpecialMember member) { MakeMemberMissing(-(int)member - 1); }
public SynthesizedImplementationMethod OpenMethodImplementation(NamedTypeSymbol interfaceType, SpecialMember interfaceMethod, string methodName = null, bool debuggerHidden = false) { var methodToImplement = ((MethodSymbol)this.SpecialMember(interfaceMethod)).AsMember(interfaceType); return OpenMethodImplementation(methodToImplement, methodName, debuggerHidden); }
private MethodSymbol GetNullableMethod(CSharpSyntaxNode syntax, TypeSymbol nullableType, SpecialMember member) { var nullableType2 = nullableType as NamedTypeSymbol; Debug.Assert((object)nullableType2 != null); return GetSpecialTypeMethod(syntax, member).AsMember(nullableType2); }
public MethodSymbol OpenPropertyImplementation(NamedTypeSymbol interfaceType, SpecialMember interfaceProperty, bool debuggerHidden = false) { var methodToImplement = (((PropertySymbol)SpecialMember(interfaceProperty)).GetMethod).AsMember(interfaceType); return OpenPropertyImplementation(methodToImplement, debuggerHidden); }
private BoundExpression RewriteDelegateOperation(CSharpSyntaxNode syntax, BinaryOperatorKind operatorKind, BoundExpression loweredLeft, BoundExpression loweredRight, TypeSymbol type, SpecialMember member) { MethodSymbol method; if (operatorKind == BinaryOperatorKind.DelegateEqual || operatorKind == BinaryOperatorKind.DelegateNotEqual) { method = (MethodSymbol)_compilation.Assembly.GetSpecialTypeMember(member); if (loweredRight.IsLiteralNull() || loweredLeft.IsLiteralNull() || (object)(method = (MethodSymbol)_compilation.Assembly.GetSpecialTypeMember(member)) == null) { // use reference equality in the absence of overloaded operators for System.Delegate. operatorKind = (operatorKind & (~BinaryOperatorKind.Delegate)) | BinaryOperatorKind.Object; return new BoundBinaryOperator(syntax, operatorKind, loweredLeft, loweredRight, default(ConstantValue), null, LookupResultKind.Empty, type); } } else { method = GetSpecialTypeMethod(syntax, member); } Debug.Assert((object)method != null); BoundExpression call = _inExpressionLambda ? new BoundBinaryOperator(syntax, operatorKind, loweredLeft, loweredRight, null, method, default(LookupResultKind), method.ReturnType) : (BoundExpression)BoundCall.Synthesized(syntax, null, method, loweredLeft, loweredRight); BoundExpression result = method.ReturnType.SpecialType == SpecialType.System_Delegate ? MakeConversionNode(syntax, call, Conversion.ExplicitReference, type, @checked: false) : call; return result; }
internal override ISymbol CommonGetSpecialTypeMember(SpecialMember specialMember) { return(this.CorLibrary.GetDeclaredSpecialTypeMember(specialMember)); }