internal override void GenerateMethodBody( TypeCompilationState compilationState, BindingDiagnosticBag diagnostics ) { var F = new SyntheticBoundNodeFactory( this, ContainingType.GetNonNullSyntaxNode(), compilationState, diagnostics ); try { // => (object)left == right || ((object)left != null && left.Equals(right)); MethodSymbol?equals = null; foreach (var member in ContainingType.GetMembers(WellKnownMemberNames.ObjectEquals)) { if ( member is MethodSymbol candidate && candidate.ParameterCount == 1 && candidate.Parameters[0].RefKind == RefKind.None && candidate.ReturnType.SpecialType == SpecialType.System_Boolean && !candidate.IsStatic && candidate.Parameters[0].Type.Equals( ContainingType, TypeCompareKind.AllIgnoreOptions ) ) { equals = candidate; break; } } if (equals is null) { // Unable to locate expected method, an error was reported elsewhere F.CloseMethod(F.ThrowNull()); return; } var left = F.Parameter(Parameters[0]); var right = F.Parameter(Parameters[1]); BoundExpression objectEqual = F.ObjectEqual(left, right); BoundExpression recordEquals = F.LogicalAnd( F.ObjectNotEqual(left, F.Null(F.SpecialType(SpecialType.System_Object))), F.Call(left, equals, right) ); F.CloseMethod(F.Block(F.Return(F.LogicalOr(objectEqual, recordEquals)))); } catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex) { diagnostics.Add(ex.Diagnostic); F.CloseMethod(F.ThrowNull()); } }
internal override void GenerateMethodBody(TypeCompilationState compilationState, BindingDiagnosticBag diagnostics) { var F = new SyntheticBoundNodeFactory(this, ContainingType.GetNonNullSyntaxNode(), compilationState, diagnostics); try { ImmutableArray <Symbol> printableMembers = ContainingType.GetMembers().WhereAsArray(m => isPrintable(m)); if (ReturnType.IsErrorType() || printableMembers.Any(static m => m.GetTypeOrReturnType().Type.IsErrorType()))
private FieldSymbol GetAutoField(BindContext context) { PropertySymbol containingProperty = (PropertySymbol)context.GetSymbol(RoslynSymbol.AssociatedSymbol); foreach (var field in ContainingType.GetMembers <FieldSymbol>(context)) { if (field.RoslynSymbol.AssociatedSymbol != null && field.RoslynSymbol.AssociatedSymbol.Equals(containingProperty.RoslynSymbol)) { return(field); } } return(null); }
internal override void GenerateMethodBody(TypeCompilationState compilationState, DiagnosticBag diagnostics) { var F = new SyntheticBoundNodeFactory(this, ContainingType.GetNonNullSyntaxNode(), compilationState, diagnostics); try { // => !(r1 == r2); F.CloseMethod(F.Block(F.Return(F.Not(F.Call(receiver: null, ContainingType.GetMembers(WellKnownMemberNames.EqualityOperatorName).OfType <SynthesizedRecordEqualityOperator>().Single(), F.Parameter(Parameters[0]), F.Parameter(Parameters[1])))))); } catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex) { diagnostics.Add(ex.Diagnostic); F.CloseMethod(F.ThrowNull()); } }
internal override void GenerateMethodBody(TypeCompilationState compilationState, BindingDiagnosticBag diagnostics) { var F = new SyntheticBoundNodeFactory(this, ContainingType.GetNonNullSyntaxNode(), compilationState, diagnostics); try { ImmutableArray <Symbol> printableMembers = ContainingType.GetMembers().WhereAsArray(m => isPrintable(m)); if (ReturnType.IsErrorType() || printableMembers.Any(m => m.GetTypeOrReturnType().Type.IsErrorType())) { F.CloseMethod(F.ThrowNull()); return; } ArrayBuilder <BoundStatement> block; BoundParameter builder = F.Parameter(this.Parameters[0]); if (ContainingType.BaseTypeNoUseSiteDiagnostics.IsObjectType() || ContainingType.IsRecordStruct) { if (printableMembers.IsEmpty) { // return false; F.CloseMethod(F.Return(F.Literal(false))); return; } block = ArrayBuilder <BoundStatement> .GetInstance(); if (!ContainingType.IsRecordStruct) { var ensureStackMethod = F.WellKnownMethod( WellKnownMember.System_Runtime_CompilerServices_RuntimeHelpers__EnsureSufficientExecutionStack, isOptional: true); if (ensureStackMethod is not null) { block.Add(F.ExpressionStatement( F.Call(receiver: null, ensureStackMethod))); } } } else { MethodSymbol?basePrintMethod = OverriddenMethod; if (basePrintMethod is null || basePrintMethod.ReturnType.SpecialType != SpecialType.System_Boolean) { F.CloseMethod(F.ThrowNull()); // an error was reported in base checks already return; } var basePrintCall = F.Call(receiver: F.Base(ContainingType.BaseTypeNoUseSiteDiagnostics), basePrintMethod, builder); if (printableMembers.IsEmpty) { // return base.PrintMembers(builder); F.CloseMethod(F.Return(basePrintCall)); return; } else { block = ArrayBuilder <BoundStatement> .GetInstance(); // if (base.PrintMembers(builder)) // builder.Append(", ") block.Add(F.If(basePrintCall, makeAppendString(F, builder, ", "))); } } Debug.Assert(!printableMembers.IsEmpty); for (var i = 0; i < printableMembers.Length; i++) { // builder.Append(", <name> = "); // if previous members exist // builder.Append("<name> = "); // if it is the first member // The only printable members are fields and properties, // which cannot be generic so as to have variant names var member = printableMembers[i]; var memberHeader = $"{member.Name} = "; if (i > 0) { memberHeader = ", " + memberHeader; } block.Add(makeAppendString(F, builder, memberHeader)); var value = member.Kind switch { SymbolKind.Field => F.Field(F.This(), (FieldSymbol)member), SymbolKind.Property => F.Property(F.This(), (PropertySymbol)member), _ => throw ExceptionUtilities.UnexpectedValue(member.Kind) }; // builder.Append((object)<value>); OR builder.Append(<value>.ToString()); for value types Debug.Assert(value.Type is not null); if (value.Type.IsValueType) { block.Add(F.ExpressionStatement( F.Call(receiver: builder, F.WellKnownMethod(WellKnownMember.System_Text_StringBuilder__AppendString), F.Call(value, F.SpecialMethod(SpecialMember.System_Object__ToString))))); } else { block.Add(F.ExpressionStatement( F.Call(receiver: builder, F.WellKnownMethod(WellKnownMember.System_Text_StringBuilder__AppendObject), F.Convert(F.SpecialType(SpecialType.System_Object), value)))); } } block.Add(F.Return(F.Literal(true))); F.CloseMethod(F.Block(block.ToImmutableAndFree())); } catch (SyntheticBoundNodeFactory.MissingPredefinedMember ex) { diagnostics.Add(ex.Diagnostic); F.CloseMethod(F.ThrowNull()); }