MemberDeclarationSyntax MakeCaseCtorFunction(InterfaceDeclarationSyntax applyTo, TypeSyntax returnType, MethodDeclarationSyntax method) { var typeParamList = applyTo.TypeParameterList; if (method.TypeParameterList != null) { typeParamList = typeParamList.AddParameters(method.TypeParameterList.Parameters.ToArray()); } var thisType = ParseTypeName($"{method.Identifier.Text}{typeParamList}"); var args = CodeGenUtil.Interleave( method.ParameterList .Parameters .Select(p => (SyntaxNodeOrToken)Argument(IdentifierName(p.Identifier.Text))) .ToArray(), Token(SyntaxKind.CommaToken)); var @case = MethodDeclaration(returnType, method.Identifier) .WithModifiers( TokenList( new[] { Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword) })) .WithParameterList(method.ParameterList) .WithExpressionBody( ArrowExpressionClause( ObjectCreationExpression(thisType) .WithArgumentList( ArgumentList( SeparatedList <ArgumentSyntax>(args))))) .WithSemicolonToken( Token(SyntaxKind.SemicolonToken)); if (typeParamList != null) { @case = @case.WithTypeParameterList(typeParamList); } return(@case); }
static MemberDeclarationSyntax MakeCaseCtorFunction( SyntaxToken applyToIdentifier, TypeParameterListSyntax applyToTypeParams, SyntaxList <TypeParameterConstraintClauseSyntax> applyToConstraints, TypeSyntax returnType, MethodDeclarationSyntax method, MethodDeclarationSyntax pure) { bool isPure = method.AttributeLists .SelectMany(a => a.Attributes) .Any(a => a.Name.ToString() == "Pure"); if (isPure) { var typeParamList = applyToTypeParams; if (method.TypeParameterList != null) { typeParamList = typeParamList.AddParameters(method.TypeParameterList.Parameters.ToArray()); } var thisType = ParseTypeName($"{method.Identifier.Text}{typeParamList}"); var paramIdents = method.ParameterList .Parameters .Select(p => (SyntaxNodeOrToken)Argument(IdentifierName(p.Identifier.Text))) .ToArray(); var args = CodeGenUtil.Interleave( paramIdents, Token(SyntaxKind.CommaToken)); var @case = MethodDeclaration(returnType, method.Identifier) .WithModifiers( TokenList( new[] { Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword) })) .WithParameterList( isPure ? method.ParameterList : method.ParameterList.WithParameters(method.ParameterList.Parameters.RemoveAt(method.ParameterList.Parameters.Count - 1))) .WithConstraintClauses(applyToConstraints) .WithExpressionBody( ArrowExpressionClause( ObjectCreationExpression(thisType) .WithArgumentList( ArgumentList( SeparatedList <ArgumentSyntax>(args))))) .WithSemicolonToken( Token(SyntaxKind.SemicolonToken)); if (typeParamList != null) { @case = @case.WithTypeParameterList(typeParamList); } return(@case); } else { var nextType = ((GenericNameSyntax)((QualifiedNameSyntax)method.ParameterList.Parameters.Last().Type).Right) .TypeArgumentList .Arguments .First(); var thisType = ParseTypeName($"{method.Identifier.Text}<{nextType}>"); returnType = ParseTypeName($"{applyToIdentifier}<{nextType}>"); var paramIdents = method.ParameterList .Parameters .Select(p => (SyntaxNodeOrToken)Argument(IdentifierName(p.Identifier.Text))) .ToArray(); paramIdents[paramIdents.Length - 1] = Argument(IdentifierName(pure.Identifier.Text)); var args = CodeGenUtil.Interleave( paramIdents, Token(SyntaxKind.CommaToken)); var @case = MethodDeclaration(returnType, method.Identifier) .WithModifiers( TokenList( new[] { Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword) })) .WithParameterList( method.ParameterList.WithParameters(method.ParameterList.Parameters.RemoveAt(method.ParameterList.Parameters.Count - 1))) .WithConstraintClauses(applyToConstraints) .WithExpressionBody( ArrowExpressionClause( ObjectCreationExpression(thisType) .WithArgumentList( ArgumentList( SeparatedList <ArgumentSyntax>(args))))) .WithSemicolonToken( Token(SyntaxKind.SemicolonToken)); return(@case); } }