public static TypeBuilder WithComparableCompare(this TypeBuilder builder, EntityModifier modifier = null) { return(builder.With(FunctionBuilder.Create(NameFactory.ComparableCompare, ExpressionReadMode.ReadRequired, NameFactory.OrderingNameReference(), Block.CreateStatement( IfBranch.CreateIf(IsSame.Create(NameReference.CreateThised(), NameReference.Create("cmp")), new[] { Return.Create(NameFactory.OrderingEqualReference()) }), // let obj = cmp cast? Self VariableDeclaration.CreateStatement("obj", null, ExpressionFactory.CheckedSelfCast("cmp", NameFactory.ReferenceNameReference(builder.CreateTypeNameReference(TypeMutability.ReadOnly)))), // return this.compare(obj.value) Return.Create(FunctionCall.Create(NameReference.CreateThised(NameFactory.ComparableCompare), NameReference.Create("obj"))))) .SetModifier(EntityModifier.Override | modifier) .Parameters(FunctionParameter.Create("cmp", NameFactory.ReferenceNameReference(NameFactory.IComparableNameReference(TypeMutability.ReadOnly)))))); }
public static TypeBuilder WithEquatableEquals(this TypeBuilder builder, EntityModifier modifier = null) { return(builder.With(FunctionBuilder.Create(NameFactory.EqualOperator, ExpressionReadMode.ReadRequired, NameFactory.BoolNameReference(), Block.CreateStatement( IfBranch.CreateIf(IsSame.Create(NameReference.CreateThised(), NameReference.Create("cmp")), new[] { Return.Create(BoolLiteral.CreateTrue()) }), // let obj = cmp cast? Self VariableDeclaration.CreateStatement("obj", null, ExpressionFactory.CheckedSelfCast("cmp", NameFactory.ReferenceNameReference(builder.CreateTypeNameReference(TypeMutability.ReadOnly)))), // return this==obj.value Return.Create(ExpressionFactory.IsEqual(NameReference.Create(NameFactory.ThisVariableName), NameReference.Create("obj"))))) .SetModifier(EntityModifier.Override | modifier) .Parameters(FunctionParameter.Create("cmp", NameFactory.ReferenceNameReference(NameFactory.IEquatableNameReference(TypeMutability.ReadOnly)))))); }
public static IExpression CheckedSelfCast(string paramName, INameReference currentTypeName) { return(Block.CreateExpression( // this is basically check for Self type // assert this.getType()==other.GetType() // please note // assert other is CurrentType // has different (and incorrect) meaning, because it does not really check both entities type // consider this to be IFooChild of IFoo->IFooParent->IFooChild // and current type would be IFooParent and the other would be of this type AssertTrue(IsSame.Create(FunctionCall.Create(NameReference.CreateThised(NameFactory.GetTypeFunctionName)), FunctionCall.Create(NameReference.Create(paramName, NameFactory.GetTypeFunctionName)))), // maybe in future it would be possible to dynamically cast to the actual type of other // this would mean static dispatch to later calls ExpressionFactory.GetOptionValue(ExpressionFactory.DownCast(NameReference.Create(paramName), currentTypeName)) )); }