private MethodDeclarationSyntax CreateMethodStarter(SyntaxToken name, MetaField field) { var method = SyntaxFactory.MethodDeclaration( GetFullyQualifiedSymbolName(this.generator.applyToSymbol), name) .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)); if (!field.IsLocallyDefined) { method = Syntax.AddNewKeyword(method); } return(method); }
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); }
protected MethodDeclarationSyntax CreateToBuilderMethod() { var method = SyntaxFactory.MethodDeclaration( BuilderTypeName, ToBuilderMethodName.Identifier) .AddModifiers(SyntaxFactory.Token(SyntaxKind.PublicKeyword)) .WithBody(SyntaxFactory.Block( SyntaxFactory.ReturnStatement( SyntaxFactory.ObjectCreationExpression( BuilderTypeName, SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(SyntaxFactory.ThisExpression()))), null)))); if (this.generator.applyToMetaType.HasAncestor) { method = Syntax.AddNewKeyword(method); } return(method); }
protected MethodDeclarationSyntax CreateCreateBuilderMethod() { var method = SyntaxFactory.MethodDeclaration( BuilderTypeName, CreateBuilderMethodName.Identifier) .AddModifiers( SyntaxFactory.Token(SyntaxKind.PublicKeyword), SyntaxFactory.Token(SyntaxKind.StaticKeyword)) .WithBody(SyntaxFactory.Block( SyntaxFactory.ReturnStatement( SyntaxFactory.ObjectCreationExpression( BuilderTypeName, SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(DefaultInstanceFieldName))), null)))); if (this.generator.applyToMetaType.Ancestors.Any(a => !a.TypeSymbol.IsAbstract)) { method = Syntax.AddNewKeyword(method); } return(method); }
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)) .WithBody(body); if (this.generator.applyToMetaType.HasAncestor) { method = Syntax.AddNewKeyword(method); } return(method); }