private MemberDeclarationSyntax CreateToDerivedTypeOverrideMethod(MetaType derivedType, MetaType ancestor) { var derivedTypeName = GetFullyQualifiedSymbolName(derivedType.TypeSymbol); return(SyntaxFactory.MethodDeclaration( derivedTypeName, GetToTypeMethodName(derivedType.TypeSymbol.Name).Identifier) .AddModifiers( SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.OverrideKeyword)) .WithParameterList( this.generator.CreateParameterList(derivedType.GetFieldsBeyond(ancestor), ParameterStyle.OptionalOrRequired)) .WithBody(SyntaxFactory.Block( SyntaxFactory.ReturnStatement( SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.BaseExpression(), GetToTypeMethodName(derivedType.TypeSymbol.Name)), this.generator.CreateArgumentList(this.generator.applyToMetaType.GetFieldsBeyond(ancestor), ArgSource.OptionalArgumentOrProperty, OptionalStyle.WhenNotRequired) .AddArguments(this.generator.CreateArgumentList(derivedType.GetFieldsBeyond(this.generator.applyToMetaType), ArgSource.Argument).Arguments.ToArray())))))); }
private MemberDeclarationSyntax CreateToDerivedTypeOverrideMethod(MetaType derivedType, MetaType ancestor) { var derivedTypeName = GetFullyQualifiedSymbolName(derivedType.TypeSymbol); return SyntaxFactory.MethodDeclaration( derivedTypeName, GetToTypeMethodName(derivedType.TypeSymbol.Name).Identifier) .AddModifiers( SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.OverrideKeyword)) .WithParameterList( this.generator.CreateParameterList(derivedType.GetFieldsBeyond(ancestor), ParameterStyle.OptionalOrRequired)) .WithBody(SyntaxFactory.Block( // return base.ToDerivedType(args); SyntaxFactory.ReturnStatement( SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.BaseExpression(), GetToTypeMethodName(derivedType.TypeSymbol.Name)), this.generator.CreateArgumentList(this.generator.applyToMetaType.GetFieldsBeyond(ancestor), ArgSource.OptionalArgumentOrPropertyExceptWhenRequired, OptionalStyle.WhenNotRequired) .AddArguments(this.generator.CreateArgumentList(derivedType.GetFieldsBeyond(this.generator.applyToMetaType), ArgSource.Argument).Arguments.ToArray()))))); }
private MemberDeclarationSyntax CreateToDerivedTypeMethod(MetaType derivedType) { var derivedTypeName = GetFullyQualifiedSymbolName(derivedType.TypeSymbol); var thatLocal = SyntaxFactory.IdentifierName("that"); var body = new List <StatementSyntax>(); // var that = this as DerivedType; body.Add(SyntaxFactory.LocalDeclarationStatement( SyntaxFactory.VariableDeclaration( varType, SyntaxFactory.SingletonSeparatedList( SyntaxFactory.VariableDeclarator(thatLocal.Identifier) .WithInitializer(SyntaxFactory.EqualsValueClause( SyntaxFactory.BinaryExpression( SyntaxKind.AsExpression, SyntaxFactory.ThisExpression(), derivedTypeName))))))); // this.GetType() var thisDotGetType = SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.ThisExpression(), SyntaxFactory.IdentifierName("GetType")), SyntaxFactory.ArgumentList()); // {0}.IsEquivalentTo(typeof(derivedType)) var thisTypeIsEquivalentToDerivedType = SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, thisDotGetType, SyntaxFactory.IdentifierName(nameof(Type.IsEquivalentTo))), SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument( SyntaxFactory.TypeOfExpression(derivedTypeName))))); var ifEquivalentTypeBlock = new List <StatementSyntax>(); var fieldsBeyond = derivedType.GetFieldsBeyond(this.generator.applyToMetaType); if (fieldsBeyond.Any()) { Func <MetaField, ExpressionSyntax> isUnchanged = v => SyntaxFactory.ParenthesizedExpression( v.IsRequired ? // ({0} == that.{1}) SyntaxFactory.BinaryExpression( SyntaxKind.EqualsExpression, v.NameAsField, SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, thatLocal, v.NameAsProperty)) : // (!{0}.IsDefined || {0}.Value == that.{1}) SyntaxFactory.BinaryExpression( SyntaxKind.LogicalOrExpression, SyntaxFactory.PrefixUnaryExpression(SyntaxKind.LogicalNotExpression, Syntax.OptionalIsDefined(v.NameAsField)), SyntaxFactory.BinaryExpression( SyntaxKind.EqualsExpression, Syntax.OptionalValue(v.NameAsField), SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, thatLocal, v.NameAsProperty)))); var noChangesExpression = fieldsBeyond.Select(isUnchanged).ChainBinaryExpressions(SyntaxKind.LogicalAndExpression); ifEquivalentTypeBlock.Add(SyntaxFactory.IfStatement( noChangesExpression, SyntaxFactory.ReturnStatement(thatLocal))); } else { ifEquivalentTypeBlock.Add(SyntaxFactory.ReturnStatement(thatLocal)); } // if (that != null && this.GetType().IsEquivalentTo(typeof(derivedType))) { ... } body.Add(SyntaxFactory.IfStatement( SyntaxFactory.BinaryExpression( SyntaxKind.LogicalAndExpression, SyntaxFactory.BinaryExpression(SyntaxKind.NotEqualsExpression, thatLocal, SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression)), thisTypeIsEquivalentToDerivedType), SyntaxFactory.Block(ifEquivalentTypeBlock))); // return DerivedType.CreateWithIdentity(...) body.Add(SyntaxFactory.ReturnStatement( SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, derivedTypeName, CreateWithIdentityMethodName), this.generator.CreateArgumentList(this.generator.applyToMetaType.AllFields, asOptional: OptionalStyle.WhenNotRequired) .AddArguments(RequiredIdentityArgumentFromProperty) .AddArguments(this.generator.CreateArgumentList(fieldsBeyond, ArgSource.Argument).Arguments.ToArray())))); return(SyntaxFactory.MethodDeclaration( derivedTypeName, GetToTypeMethodName(derivedType.TypeSymbol.Name).Identifier) .AddModifiers( SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.VirtualKeyword)) .WithParameterList(this.generator.CreateParameterList(fieldsBeyond, ParameterStyle.OptionalOrRequired)) .WithBody(SyntaxFactory.Block(body))); }
private MemberDeclarationSyntax CreateToDerivedTypeMethod(MetaType derivedType) { var derivedTypeName = GetFullyQualifiedSymbolName(derivedType.TypeSymbol); var thatLocal = SyntaxFactory.IdentifierName("that"); var body = new List<StatementSyntax>(); // var that = this as DerivedType; body.Add(SyntaxFactory.LocalDeclarationStatement( SyntaxFactory.VariableDeclaration( varType, SyntaxFactory.SingletonSeparatedList( SyntaxFactory.VariableDeclarator(thatLocal.Identifier) .WithInitializer(SyntaxFactory.EqualsValueClause( SyntaxFactory.BinaryExpression( SyntaxKind.AsExpression, SyntaxFactory.ThisExpression(), derivedTypeName))))))); // this.GetType() var thisDotGetType = SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.ThisExpression(), SyntaxFactory.IdentifierName("GetType")), SyntaxFactory.ArgumentList()); // {0}.Equals(typeof(derivedType)) var thisTypeIsEquivalentToDerivedType = SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, thisDotGetType, SyntaxFactory.IdentifierName(nameof(Type.Equals))), SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument( SyntaxFactory.TypeOfExpression(derivedTypeName))))); var ifEquivalentTypeBlock = new List<StatementSyntax>(); var fieldsBeyond = derivedType.GetFieldsBeyond(this.generator.applyToMetaType); if (fieldsBeyond.Any()) { Func<MetaField, ExpressionSyntax> isUnchanged = v => SyntaxFactory.ParenthesizedExpression( v.IsRequired ? // ({0} == that.{1}) SyntaxFactory.BinaryExpression( SyntaxKind.EqualsExpression, v.NameAsField, SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, thatLocal, v.NameAsProperty)) : // (!{0}.IsDefined || {0}.Value == that.{1}) SyntaxFactory.BinaryExpression( SyntaxKind.LogicalOrExpression, SyntaxFactory.PrefixUnaryExpression(SyntaxKind.LogicalNotExpression, Syntax.OptionalIsDefined(v.NameAsField)), SyntaxFactory.BinaryExpression( SyntaxKind.EqualsExpression, Syntax.OptionalValue(v.NameAsField), SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, thatLocal, v.NameAsProperty)))); var noChangesExpression = fieldsBeyond.Select(isUnchanged).ChainBinaryExpressions(SyntaxKind.LogicalAndExpression); ifEquivalentTypeBlock.Add(SyntaxFactory.IfStatement( noChangesExpression, SyntaxFactory.ReturnStatement(thatLocal))); } else { ifEquivalentTypeBlock.Add(SyntaxFactory.ReturnStatement(thatLocal)); } // if (that != null && this.GetType().IsEquivalentTo(typeof(derivedType))) { ... } body.Add(SyntaxFactory.IfStatement( SyntaxFactory.BinaryExpression( SyntaxKind.LogicalAndExpression, SyntaxFactory.BinaryExpression(SyntaxKind.NotEqualsExpression, thatLocal, SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression)), thisTypeIsEquivalentToDerivedType), SyntaxFactory.Block(ifEquivalentTypeBlock))); // return DerivedType.CreateWithIdentity(...) body.Add(SyntaxFactory.ReturnStatement( SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, derivedTypeName, CreateWithIdentityMethodName), this.generator.CreateArgumentList(this.generator.applyToMetaType.AllFields, asOptional: OptionalStyle.WhenNotRequired) .AddArguments(RequiredIdentityArgumentFromProperty) .AddArguments(this.generator.CreateArgumentList(fieldsBeyond, ArgSource.Argument).Arguments.ToArray())))); return SyntaxFactory.MethodDeclaration( derivedTypeName, GetToTypeMethodName(derivedType.TypeSymbol.Name).Identifier) .AddModifiers( SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.VirtualKeyword)) .WithParameterList(this.generator.CreateParameterList(fieldsBeyond, ParameterStyle.OptionalOrRequired)) .WithBody(SyntaxFactory.Block(body)); }