private void ImplementSortedChildrenInterface() { this.baseTypes.Add(SyntaxFactory.SimpleBaseType(Syntax.GetTypeSyntax(typeof(IRecursiveParentWithSortedChildren)))); // int IRecursiveParentWithSortedChildren.Compare(IRecursiveType first, IRecursiveType second) var firstParameterName = SyntaxFactory.IdentifierName("first"); var secondParameterName = SyntaxFactory.IdentifierName("second"); this.innerMembers.Add(SyntaxFactory.MethodDeclaration( SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword)), nameof(IRecursiveParentWithSortedChildren.Compare)) .WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(SyntaxFactory.IdentifierName(nameof(IRecursiveParentWithSortedChildren)))) .AddParameterListParameters( SyntaxFactory.Parameter(firstParameterName.Identifier).WithType(Syntax.GetTypeSyntax(typeof(IRecursiveType))), SyntaxFactory.Parameter(secondParameterName.Identifier).WithType(Syntax.GetTypeSyntax(typeof(IRecursiveType)))) .WithBody(SyntaxFactory.Block( // return this.Children.KeyComparer.Compare((<#= templateType.RecursiveType.TypeName #>)first, (<#= templateType.RecursiveType.TypeName #>)second); SyntaxFactory.ReturnStatement( SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, Syntax.ThisDot(SyntaxFactory.IdentifierName(this.generator.applyToMetaType.RecursiveField.Name.ToPascalCase())), SyntaxFactory.IdentifierName(nameof(ImmutableSortedSet <int> .KeyComparer))), SyntaxFactory.IdentifierName(nameof(IComparer <int> .Compare))), SyntaxFactory.ArgumentList(Syntax.JoinSyntaxNodes(SyntaxKind.CommaToken, SyntaxFactory.Argument(SyntaxFactory.CastExpression(this.generator.applyToMetaType.RecursiveType.TypeSyntax, firstParameterName)), SyntaxFactory.Argument(SyntaxFactory.CastExpression(this.generator.applyToMetaType.RecursiveType.TypeSyntax, secondParameterName))))))))); }
private void ImplementRecursiveParentInterface() { var irecursiveParentOfT = CreateIRecursiveParentOfTSyntax(GetFullyQualifiedSymbolName(this.generator.applyToMetaType.RecursiveType.TypeSymbol)); this.baseTypes.Add(SyntaxFactory.SimpleBaseType(irecursiveParentOfT)); // this.Children; var thisDotChildren = Syntax.ThisDot(SyntaxFactory.IdentifierName(this.generator.applyToMetaType.RecursiveField.Name.ToPascalCase())); // System.Collections.Generic.IReadOnlyCollection<IRecursiveType> IRecursiveParent.Children this.innerMembers.Add( SyntaxFactory.PropertyDeclaration( Syntax.GetTypeSyntax(typeof(IReadOnlyCollection <IRecursiveType>)), nameof(IRecursiveParent.Children)) .WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(Syntax.GetTypeSyntax(typeof(IRecursiveParent)))) .WithExpressionBody(SyntaxFactory.ArrowExpressionClause(thisDotChildren)) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)) .AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SingletonSeparatedList(DebuggerBrowsableNeverAttribute)))); // public ParentedRecursiveType<TRecursiveParent, TRecursiveType> GetParentedNode(uint identity) this.innerMembers.Add( SyntaxFactory.MethodDeclaration( SyntaxFactory.GenericName(nameof(ParentedRecursiveType <IRecursiveParent <IRecursiveType>, IRecursiveType>)).AddTypeArgumentListArguments( this.applyTo.RecursiveParent.TypeSyntax, this.applyTo.RecursiveType.TypeSyntax), nameof(IRecursiveParent.GetParentedNode)) .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) //.WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(Syntax.GetTypeSyntax(typeof(IRecursiveParent)))) .AddParameterListParameters(RequiredIdentityParameter) .WithBody(SyntaxFactory.Block( // return this.GetParentedNode<TRecursiveParent, TRecursiveType>(identity); SyntaxFactory.ReturnStatement( SyntaxFactory.InvocationExpression( Syntax.ThisDot(SyntaxFactory.GenericName(nameof(RecursiveTypeExtensions.GetParentedNode)).AddTypeArgumentListArguments( this.applyTo.RecursiveParent.TypeSyntax, this.applyTo.RecursiveType.TypeSyntax))) .AddArgumentListArguments(SyntaxFactory.Argument(IdentityParameterName)))))); // ParentedRecursiveType<IRecursiveParent<IRecursiveType>, IRecursiveType> IRecursiveParent.GetParentedNode(<#= templateType.RequiredIdentityField.TypeName #> identity) { var parentedVar = SyntaxFactory.IdentifierName("parented"); var returnType = Syntax.GetTypeSyntax(typeof(ParentedRecursiveTypeNonGeneric)); this.innerMembers.Add( SyntaxFactory.MethodDeclaration( returnType, nameof(IRecursiveParent.GetParentedNode)) .WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(Syntax.GetTypeSyntax(typeof(IRecursiveParent)))) .AddParameterListParameters(RequiredIdentityParameter) .WithBody(SyntaxFactory.Block( // var parented = this.GetParentedNode(identity); SyntaxFactory.LocalDeclarationStatement(SyntaxFactory.VariableDeclaration(varType).AddVariables( SyntaxFactory.VariableDeclarator(parentedVar.Identifier).WithInitializer(SyntaxFactory.EqualsValueClause( SyntaxFactory.InvocationExpression(Syntax.ThisDot(SyntaxFactory.IdentifierName(nameof(RecursiveTypeExtensions.GetParentedNode)))) .AddArgumentListArguments(SyntaxFactory.Argument(IdentityParameterName)))))), // return new ParentedRecursiveType<IRecursiveParent<IRecursiveType>, IRecursiveType>(parented.Value, parented.Parent); SyntaxFactory.ReturnStatement(SyntaxFactory.ObjectCreationExpression(returnType).AddArgumentListArguments( SyntaxFactory.Argument(SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, parentedVar, SyntaxFactory.IdentifierName(nameof(ParentedRecursiveTypeNonGeneric.Value)))), SyntaxFactory.Argument(SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, parentedVar, SyntaxFactory.IdentifierName(nameof(ParentedRecursiveTypeNonGeneric.Parent))))))))); ////System.Collections.Generic.IReadOnlyCollection<<#= templateType.RecursiveType.TypeName #>> IRecursiveParent<<#= templateType.RecursiveType.TypeName #>>.Children //// => return this.Children; this.innerMembers.Add( SyntaxFactory.PropertyDeclaration( Syntax.IReadOnlyCollectionOf(this.generator.applyToMetaType.RecursiveType.TypeSyntax), nameof(IRecursiveParent <IRecursiveType> .Children)) .WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(irecursiveParentOfT)) .WithExpressionBody(SyntaxFactory.ArrowExpressionClause(thisDotChildren)) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)) .AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SingletonSeparatedList(DebuggerBrowsableNeverAttribute)))); }
private void ImplementOrderedChildrenInterface() { // We only need to declare this interface if the children are not sorted, // since sorted children merit a derived interface making this redundant. if (!this.generator.applyToMetaType.ChildrenAreSorted) { this.baseTypes.Add(SyntaxFactory.SimpleBaseType(Syntax.GetTypeSyntax(typeof(IRecursiveParentWithOrderedChildren)))); } // IReadOnlyList<IRecursiveType> IRecursiveParentWithOrderedChildren.Children => this.children; this.innerMembers.Add(SyntaxFactory.PropertyDeclaration( Syntax.IReadOnlyListOf(Syntax.GetTypeSyntax(typeof(IRecursiveType))), nameof(IRecursiveParentWithOrderedChildren.Children)) .WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(SyntaxFactory.IdentifierName(nameof(IRecursiveParentWithOrderedChildren)))) .WithExpressionBody(SyntaxFactory.ArrowExpressionClause(Syntax.ThisDot(SyntaxFactory.IdentifierName(this.generator.applyToMetaType.RecursiveField.Name)))) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)) .AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SingletonSeparatedList(DebuggerBrowsableNeverAttribute)))); // int IRecursiveParentWithOrderedChildren.IndexOf(IRecursiveType value) var valueParameterName = SyntaxFactory.IdentifierName("value"); this.innerMembers.Add(SyntaxFactory.MethodDeclaration( SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntKeyword)), nameof(IRecursiveParentWithOrderedChildren.IndexOf)) .WithExplicitInterfaceSpecifier(SyntaxFactory.ExplicitInterfaceSpecifier(SyntaxFactory.IdentifierName(nameof(IRecursiveParentWithOrderedChildren)))) .AddParameterListParameters(SyntaxFactory.Parameter(valueParameterName.Identifier).WithType(Syntax.GetTypeSyntax(typeof(IRecursiveType)))) .WithBody(SyntaxFactory.Block( // return this.Children.IndexOf((<#= templateType.RecursiveType.TypeName #>)value); SyntaxFactory.ReturnStatement( SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, Syntax.ThisDot(SyntaxFactory.IdentifierName(this.generator.applyToMetaType.RecursiveField.Name.ToPascalCase())), SyntaxFactory.IdentifierName(nameof(IList <int> .IndexOf))), SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList( SyntaxFactory.Argument( SyntaxFactory.CastExpression( this.generator.applyToMetaType.RecursiveType.TypeSyntax, valueParameterName))))))))); }
protected MethodDeclarationSyntax CreateToImmutableMethod() { // var fieldName = this.fieldName.IsDefined ? this.fieldName.Value?.ToImmutable() : this.immutable.FieldName; var body = SyntaxFactory.Block( from field in this.generator.applyToMetaType.AllFields where field.IsGeneratedImmutableType let thisField = Syntax.ThisDot(field.NameAsField) // this.fieldName let thisFieldValue = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, thisField, SyntaxFactory.IdentifierName(nameof(ImmutableObjectGraph.Optional <int> .Value))) // this.fieldName.Value select SyntaxFactory.LocalDeclarationStatement( SyntaxFactory.VariableDeclaration(varType)) .AddDeclarationVariables( SyntaxFactory.VariableDeclarator(field.Name).WithInitializer( SyntaxFactory.EqualsValueClause( SyntaxFactory.ConditionalExpression( Syntax.OptionalIsDefined(thisField), // this.fieldName.IsDefined SyntaxFactory.InvocationExpression( // this.fieldName.Value?.ToImmutable() SyntaxFactory.ConditionalAccessExpression(thisFieldValue, SyntaxFactory.MemberBindingExpression(ToImmutableMethodName)), SyntaxFactory.ArgumentList()), SyntaxFactory.MemberAccessExpression( // this.immutable.FieldName SyntaxKind.SimpleMemberAccessExpression, Syntax.ThisDot(ImmutableFieldName), field.NameAsProperty)))))); ExpressionSyntax returnExpression; if (this.generator.applyToMetaType.AllFields.Any()) { // this.immutable = this.immutable.With(...) returnExpression = SyntaxFactory.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, Syntax.ThisDot(ImmutableFieldName), SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, Syntax.ThisDot(ImmutableFieldName), WithMethodName), SyntaxFactory.ArgumentList( Syntax.JoinSyntaxNodes( SyntaxKind.CommaToken, this.generator.applyToMetaType.AllFields.Select( f => SyntaxFactory.Argument(Syntax.OptionalFor(f.IsGeneratedImmutableType ? SyntaxFactory.IdentifierName(f.Name) : Syntax.ThisDot(SyntaxFactory.IdentifierName(f.Name.ToPascalCase()))))))))); } else { // this.immutable returnExpression = Syntax.ThisDot(ImmutableFieldName); } body = body.AddStatements( SyntaxFactory.ReturnStatement(returnExpression)); // public TemplateType ToImmutable() { ... } var method = SyntaxFactory.MethodDeclaration( SyntaxFactory.IdentifierName(this.generator.applyTo.Identifier), ToImmutableMethodName.Identifier) .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) .AddAttributeLists(PureAttributeList) .WithBody(body); if (this.generator.applyToMetaType.HasAncestor) { method = Syntax.AddNewKeyword(method); } return(method); }
protected IReadOnlyList <MemberDeclarationSyntax> CreateMutableProperties() { var properties = new List <PropertyDeclarationSyntax>(); foreach (var field in this.generator.applyToMetaType.LocalFields) { var thisField = Syntax.ThisDot(field.NameAsField); var optionalFieldNotYetDefined = SyntaxFactory.PrefixUnaryExpression(SyntaxKind.LogicalNotExpression, Syntax.OptionalIsDefined(thisField)); var getterBlock = field.IsGeneratedImmutableType ? SyntaxFactory.Block( // if (!this.fieldName.IsDefined) { SyntaxFactory.IfStatement( optionalFieldNotYetDefined, SyntaxFactory.Block( // this.fieldName = this.immutable.fieldName?.ToBuilder(); SyntaxFactory.ExpressionStatement(SyntaxFactory.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, thisField, SyntaxFactory.ConditionalAccessExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, Syntax.ThisDot(ImmutableFieldName), field.NameAsField), SyntaxFactory.InvocationExpression( SyntaxFactory.MemberBindingExpression(ToBuilderMethodName), SyntaxFactory.ArgumentList())))))), SyntaxFactory.ReturnStatement(Syntax.OptionalValue(thisField))) : SyntaxFactory.Block(SyntaxFactory.ReturnStatement(thisField)); var setterValueArg = SyntaxFactory.IdentifierName("value"); var setterCondition = field.IsGeneratedImmutableType ? SyntaxFactory.BinaryExpression( SyntaxKind.LogicalOrExpression, optionalFieldNotYetDefined, SyntaxFactory.BinaryExpression( SyntaxKind.NotEqualsExpression, Syntax.OptionalValue(thisField), setterValueArg)) : HasEqualityOperators(field.Symbol.Type) ? SyntaxFactory.BinaryExpression( SyntaxKind.NotEqualsExpression, thisField, setterValueArg) : null; var setterSignificantBlock = SyntaxFactory.Block( SyntaxFactory.ExpressionStatement(SyntaxFactory.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, thisField, setterValueArg)), SyntaxFactory.ExpressionStatement( SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.ThisExpression(), OnPropertyChangedMethodName)))); var setterBlock = setterCondition != null? SyntaxFactory.Block( SyntaxFactory.IfStatement( setterCondition, setterSignificantBlock)) : setterSignificantBlock; var property = SyntaxFactory.PropertyDeclaration( this.GetPropertyTypeForBuilder(field), field.Name.ToPascalCase()) .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) .WithAccessorList(SyntaxFactory.AccessorList(SyntaxFactory.List(new AccessorDeclarationSyntax[] { SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration, getterBlock), SyntaxFactory.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration, setterBlock), }))); properties.Add(property); } return(properties); }
protected MemberDeclarationSyntax CreateConstructor() { var immutableParameterName = SyntaxFactory.IdentifierName("immutable"); var body = SyntaxFactory.Block( SyntaxFactory.ExpressionStatement(SyntaxFactory.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, Syntax.ThisDot(ImmutableFieldName), immutableParameterName))); foreach (var field in this.generator.applyToMetaType.LocalFields) { if (!field.IsGeneratedImmutableType) { body = body.AddStatements(SyntaxFactory.ExpressionStatement(SyntaxFactory.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, Syntax.ThisDot(field.NameAsField), SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, immutableParameterName, field.NameAsField)))); } } var ctor = SyntaxFactory.ConstructorDeclaration(BuilderTypeName.Identifier) .AddParameterListParameters( SyntaxFactory.Parameter(immutableParameterName.Identifier).WithType(SyntaxFactory.IdentifierName(this.generator.applyTo.Identifier))) .AddModifiers(SyntaxFactory.Token(SyntaxKind.InternalKeyword)) .WithBody(body); if (this.generator.applyToMetaType.HasAncestor) { ctor = ctor.WithInitializer(SyntaxFactory.ConstructorInitializer( SyntaxKind.BaseConstructorInitializer, SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(immutableParameterName))))); } return(ctor); }
private MemberDeclarationSyntax CreateCreateWithIdentityMethod() { ExpressionSyntax returnExpression = DefaultInstanceFieldName; if (this.generator.applyToMetaType.LocalFields.Any()) { returnExpression = SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, returnExpression, WithFactoryMethodName), this.generator.CreateArgumentList(this.generator.applyToMetaType.AllFields, ArgSource.OptionalArgumentOrTemplate, OptionalStyle.Always) .AddArguments(OptionalIdentityArgument)); } var method = SyntaxFactory.MethodDeclaration( this.generator.applyToTypeName, CreateWithIdentityMethodName.Identifier) .AddModifiers( SyntaxFactory.Token(SyntaxKind.InternalKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword)) .WithParameterList( this.generator.CreateParameterList( this.generator.applyToMetaType.AllFields, ParameterStyle.OptionalOrRequired) .AddParameters(OptionalIdentityParameter)) .WithBody(SyntaxFactory.Block( SyntaxFactory.IfStatement( SyntaxFactory.PrefixUnaryExpression(SyntaxKind.LogicalNotExpression, Syntax.OptionalIsDefined(IdentityParameterName)), SyntaxFactory.ExpressionStatement(SyntaxFactory.AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, IdentityParameterName, SyntaxFactory.InvocationExpression(NewIdentityMethodName, SyntaxFactory.ArgumentList())))), SyntaxFactory.ReturnStatement(returnExpression))); // BUG: the condition should be if there are local fields on *any* ancestor // from the closest non-abstract ancestor (exclusive) to this type (inclusive). if (!this.generator.applyToMetaType.LocalFields.Any() && this.generator.applyToMetaType.Ancestors.Any(a => !a.TypeSymbol.IsAbstract)) { method = Syntax.AddNewKeyword(method); } return(method); }
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))); }