Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add shell language support #738

Merged
merged 88 commits into from
Feb 16, 2022
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
ad5cf7d
Add shell writer based on C# writer
calebkiage Oct 18, 2021
7ec5869
Fix method writer reference
calebkiage Oct 18, 2021
5ee05a0
Add shell writer based on C# writer
calebkiage Oct 18, 2021
e0061ea
Fix method writer reference
calebkiage Oct 18, 2021
f3bf3f6
Fix generation error
calebkiage Oct 19, 2021
b36cf92
Add code class kind for shell language
calebkiage Oct 21, 2021
5d370c7
Remove unused code
calebkiage Oct 21, 2021
e7ce85f
Rename AddCodeElementWriter function to reflect updated behavior whic…
calebkiage Oct 21, 2021
0802de4
- adds path and query parameters for non fluent languages
baywet Oct 21, 2021
0c668ec
Update shell refiner to add command builders
calebkiage Oct 25, 2021
d23f2a7
Merge branch 'feat/cli_generator' of https://github.com/microsoft/kio…
calebkiage Oct 25, 2021
87d12e6
Remove parameters from build command
calebkiage Oct 25, 2021
cdd23bb
Update command handler
calebkiage Oct 25, 2021
4a78a55
Apply suggested Linq optimization
calebkiage Oct 26, 2021
c43d8fa
Add code to set up command tree
calebkiage Oct 26, 2021
14995f9
Update import declarations in generated code
calebkiage Oct 27, 2021
1c613e5
Merge remote-tracking branch 'origin/main' into feat/cli_generator
calebkiage Oct 27, 2021
7162adb
Generate code to output command results
calebkiage Nov 1, 2021
2bb0dad
Read request body input as json string
calebkiage Nov 2, 2021
d65d247
Add file IO support for stream data upload & download
calebkiage Nov 3, 2021
fe9b1e8
Merge branch main into feat/cli_generator
calebkiage Nov 10, 2021
84b2fc5
Fix NullReferenceException when there are no parameters
calebkiage Dec 2, 2021
9b418e7
Apply suggested code changes
calebkiage Dec 2, 2021
e567be5
Handle edge cases that broke the generated code build
calebkiage Dec 3, 2021
4597b62
Merge branch 'main' into feat/cli_generator
calebkiage Dec 6, 2021
8772b4a
Order methods for deterministic output
calebkiage Dec 6, 2021
0ba0e09
Add missing import
calebkiage Dec 6, 2021
b23dc85
Throw exception for attempts to use CommandBuilders in CSharp
calebkiage Dec 6, 2021
1d0f3c3
Fix bug with command builder writer
calebkiage Dec 7, 2021
a3ea49b
Fix stack overflow exception in builder methods
calebkiage Dec 7, 2021
7d6745f
- fixes a bug where path and query parameters of type collection woul…
baywet Dec 8, 2021
db176be
Update src/Kiota.Builder/Writers/Shell/ShellCodeMethodWriter.cs
calebkiage Dec 9, 2021
8e7236f
Add required flag to options
calebkiage Dec 9, 2021
0c81ef4
Merge branch 'feat/cli_generator' of https://github.com/microsoft/kio…
calebkiage Dec 9, 2021
af989d1
Use generator method to add query parameters to request
calebkiage Dec 9, 2021
d593305
Merge remote-tracking branch 'origin/main' into feat/cli_generator
calebkiage Jan 19, 2022
a0b4c3a
Update shell writer to accomodate breaking changes in System.Commandl…
calebkiage Jan 19, 2022
9ecf819
Merge pull request #1038 from microsoft/chore/update_system_commandline
baywet Jan 19, 2022
7f19244
Update method writer to use output formatter
calebkiage Jan 25, 2022
0610a1f
Fix duplicated output in generated code for streams
calebkiage Jan 26, 2022
6ee2632
Merge branch 'main' into feat/cli_generator
calebkiage Jan 26, 2022
839c8c0
Fix issue with some commands being skipped.
calebkiage Jan 27, 2022
fad1be8
Merge branch 'feat/cli_generator' into feat/output_formatter
calebkiage Jan 27, 2022
f835f83
Print server response if an error occurs in the request
calebkiage Jan 27, 2022
1a23e25
Refactor for generation performance
calebkiage Jan 28, 2022
e2f825f
Move from using response handler and use SendPrimitiveAsync<Stream>
calebkiage Feb 4, 2022
cfba6ef
Add CLI commons package
calebkiage Feb 9, 2022
9a2fdf7
Add missing types
calebkiage Feb 9, 2022
fa2bec3
Update dependabot config
calebkiage Feb 10, 2022
20169c1
Merge remote-tracking branch 'origin/main' into chore/commons_package
calebkiage Feb 10, 2022
eee1036
Merge remote-tracking branch 'origin/main' into feat/output_formatter
calebkiage Feb 10, 2022
e285e77
Merge branch 'feat/output_formatter' into chore/commons_package
calebkiage Feb 10, 2022
00471e9
Add shell language to main readme
calebkiage Feb 10, 2022
5bb480e
Merge pull request #1180 from microsoft/chore/commons_package
calebkiage Feb 10, 2022
9bc455d
Merge remote-tracking branch 'origin/main' into feat/cli_generator
calebkiage Feb 10, 2022
0188007
Merge branch 'feat/cli_generator' into feat/output_formatter
calebkiage Feb 10, 2022
8e6f55f
Merge pull request #1071 from microsoft/feat/output_formatter
calebkiage Feb 10, 2022
ef8c275
Fix possible null pointer exception
calebkiage Feb 10, 2022
d562acc
Fix code smells
calebkiage Feb 10, 2022
d2e6be9
Simplify WriteCommandBuilderBody function
calebkiage Feb 10, 2022
bf6614c
Correct core types in shell refiner
calebkiage Feb 11, 2022
1f61f7e
Remove raw url constructor overload
calebkiage Feb 11, 2022
9aed749
Simplify CreateCommandType method
calebkiage Feb 11, 2022
8cc0438
Remove unused request methods
calebkiage Feb 11, 2022
61d6311
Check for whitespace as well as null on string values
calebkiage Feb 11, 2022
a6f9d7d
Refactor duplicated code
calebkiage Feb 11, 2022
3eaa361
Get serialization contect type from generator method
calebkiage Feb 11, 2022
5cfb3a1
Add IsOfKind extension method for CodeParameter
calebkiage Feb 11, 2022
3bd2e32
Merge branch 'main' into feat/cli_generator
calebkiage Feb 11, 2022
e06f262
Fix build error
calebkiage Feb 11, 2022
0ac97f3
Remove unnecessary extension method
calebkiage Feb 11, 2022
1fe18c4
Fix unintended revert in CodeMethodWriter after conflict resolution
calebkiage Feb 11, 2022
c9352e7
Refactor code
calebkiage Feb 14, 2022
81670b1
Add shell code method writer tests
calebkiage Feb 14, 2022
b166e23
Replace if...else with switch expression
calebkiage Feb 14, 2022
791578d
Use string.Equals function
calebkiage Feb 14, 2022
bf6d4b9
Add additional unit tests
calebkiage Feb 15, 2022
e27e15a
Add unit tests
calebkiage Feb 16, 2022
11d6e82
Refactor code
calebkiage Feb 16, 2022
65e245c
Update default value to handle string option types
calebkiage Feb 16, 2022
f4aaa20
Add assertion for optional parameters
calebkiage Feb 16, 2022
bfff3a1
Rename root build command
calebkiage Feb 16, 2022
ebb18a1
Merge remote-tracking branch 'origin/main' into feat/cli_generator
calebkiage Feb 16, 2022
f5597b8
Fix failing tests
calebkiage Feb 16, 2022
97671bd
Simplify code complexity
calebkiage Feb 16, 2022
5c0347c
Use OfKind extension method
calebkiage Feb 16, 2022
a7cf475
Add error handling support to shell generation
calebkiage Feb 16, 2022
d5d3c02
Fix failing tests
calebkiage Feb 16, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/Kiota.Builder/CodeDOM/CodeClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace Kiota.Builder
{
public enum CodeClassKind {
Custom,
CommandBuilder,
RequestBuilder,
Model,
QueryParameters,
Expand Down Expand Up @@ -115,6 +116,10 @@ public class Declaration : BlockDeclaration
implements.AddRange(types);
}
public IEnumerable<CodeType> Implements => implements;
public Boolean IsStatic
{
get; set;
}
}

public class End : BlockEnd
Expand Down
23 changes: 22 additions & 1 deletion src/Kiota.Builder/CodeDOM/CodeMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public enum CodeMethodKind
ClientConstructor,
RequestBuilderBackwardCompatibility,
RequestBuilderWithParameters,
RawUrlConstructor
RawUrlConstructor,
CommandBuilder
}
public enum HttpMethod {
Get,
Expand Down Expand Up @@ -47,6 +48,11 @@ public class CodeMethod : CodeTerminal, ICloneable, IDocumentedElement
public void RemoveParametersByKind(params CodeParameterKind[] kinds) {
parameters.RemoveAll(p => p.IsOfKind(kinds));
}

public void ClearParameters()
{
parameters.Clear();
}
public IEnumerable<CodeParameter> Parameters { get => parameters; }
public bool IsStatic {get;set;} = false;
public bool IsAsync {get;set;} = true;
Expand All @@ -55,6 +61,21 @@ public class CodeMethod : CodeTerminal, ICloneable, IDocumentedElement
/// The property this method accesses to when it's a getter or setter.
/// </summary>
public CodeProperty AccessedProperty { get; set; }
/// <summary>
/// The combination of the path and query parameters for the current URL.
/// Only use this property if the language you are generating for doesn't support fluent API style (e.g. Shell/CLI)
/// </summary>
public IEnumerable<CodeParameter> PathAndQueryParameters { get; private set; }
public void AddPathOrQueryParameter(params CodeParameter[] parameters) {
if(parameters == null || !parameters.Any()) return;
foreach (var parameter in parameters) {
EnsureElementsAreChildren(parameter);
}
if(PathAndQueryParameters == null)
PathAndQueryParameters = new List<CodeParameter>(parameters);
else if (PathAndQueryParameters is List<CodeParameter> cast)
cast.AddRange(parameters);
}
public bool IsOfKind(params CodeMethodKind[] kinds) {
return kinds?.Contains(MethodKind) ?? false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,12 @@ public static bool IsComplexPathWithAnyNumberOfParameters(this OpenApiUrlTreeNod
if(string.IsNullOrEmpty(original) || !original.Contains('{')) return original;
var parameters = pathParamMatcher.Matches(original);
foreach(var value in parameters.Select(x => x.Value))
original = original.Replace(value, value.Replace('-', '_'));
original = original.SanitizePathParameterName();
return original;
}
public static string SanitizePathParameterName(this string original) {
if(string.IsNullOrEmpty(original)) return original;
return original.Replace('-', '_');
}
}
}
6 changes: 3 additions & 3 deletions src/Kiota.Builder/Extensions/StringExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
Expand Down Expand Up @@ -26,7 +26,7 @@ public static string ToPascalCase(this string name)
public static string TrimQuotes(this string original) =>
original?.Trim('\'', '"');

public static string ToSnakeCase(this string name)
public static string ToSnakeCase(this string name, char separator = '_')
{
if(string.IsNullOrEmpty(name)) return name;
var chunks = name.Split('-', StringSplitOptions.RemoveEmptyEntries);
Expand All @@ -40,7 +40,7 @@ public static string ToSnakeCase(this string name)
foreach (var item in identifier[1..])
{
if(char.IsUpper(item)) {
sb.Append('_');
sb.Append(separator);
sb.Append(char.ToLowerInvariant(item));
} else {
sb.Append(item);
Expand Down
3 changes: 2 additions & 1 deletion src/Kiota.Builder/GenerationLanguage.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Kiota.Builder {
namespace Kiota.Builder {
public enum GenerationLanguage {
CSharp,
Java,
Expand All @@ -7,5 +7,6 @@ public enum GenerationLanguage {
Python,
Go,
Ruby,
Shell
}
}
27 changes: 27 additions & 0 deletions src/Kiota.Builder/KiotaBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -586,10 +586,37 @@ private void CreateOperationMethods(OpenApiUrlTreeNode currentNode, OperationTyp
Description = operation.Description ?? operation.Summary,
ReturnType = new CodeType { Name = "RequestInformation", IsNullable = false, IsExternal = true},
};
if(config.Language == GenerationLanguage.Shell)
SetPathAndQueryParameters(generatorMethod, currentNode, operation);
parentClass.AddMethod(generatorMethod);
AddRequestBuilderMethodParameters(currentNode, operation, parameterClass, generatorMethod);
logger.LogTrace("Creating method {name} of {type}", generatorMethod.Name, generatorMethod.ReturnType);
}
private static void SetPathAndQueryParameters(CodeMethod target, OpenApiUrlTreeNode currentNode, OpenApiOperation operation) {
var pathAndQueryParameters = currentNode
.PathItems[Constants.DefaultOpenApiLabel]
.Parameters
.Where(x => x.In == ParameterLocation.Path || x.In == ParameterLocation.Query)
.Select(x => new CodeParameter{
Name = x.Name.TrimStart('$').SanitizePathParameterName(),
Type = GetPrimitiveType(x.Schema),
Description = x.Description,
ParameterKind = x.In == ParameterLocation.Path ? CodeParameterKind.Path : CodeParameterKind.QueryParameter,
Optional = !x.Required
})
.Union(operation
.Parameters
.Where(x => x.In == ParameterLocation.Path || x.In == ParameterLocation.Query)
.Select(x => new CodeParameter{
Name = x.Name.TrimStart('$').SanitizePathParameterName(),
Type = GetPrimitiveType(x.Schema),
Description = x.Description,
ParameterKind = x.In == ParameterLocation.Path ? CodeParameterKind.Path : CodeParameterKind.QueryParameter,
Optional = !x.Required
}))
.ToArray();
target.AddPathOrQueryParameter(pathAndQueryParameters);
}
private void AddRequestBuilderMethodParameters(OpenApiUrlTreeNode currentNode, OpenApiOperation operation, CodeClass parameterClass, CodeMethod method) {
var nonBinaryRequestBody = operation.RequestBody?.Content?.FirstOrDefault(x => !RequestBodyBinaryContentType.Equals(x.Key, StringComparison.OrdinalIgnoreCase));
if (nonBinaryRequestBody.HasValue && nonBinaryRequestBody.Value.Value != null)
Expand Down
5 changes: 4 additions & 1 deletion src/Kiota.Builder/Refiners/ILanguageRefiner.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Kiota.Builder.Refiners
namespace Kiota.Builder.Refiners
{
public interface ILanguageRefiner
{
Expand All @@ -21,6 +21,9 @@ public interface ILanguageRefiner
case GenerationLanguage.Go:
new GoRefiner(config).Refine(generatedCode);
break;
case GenerationLanguage.Shell:
new ShellRefiner(config).Refine(generatedCode);
break;
default:
break; //Do nothing
}
Expand Down
186 changes: 186 additions & 0 deletions src/Kiota.Builder/Refiners/ShellRefiner.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Kiota.Builder.Extensions;

namespace Kiota.Builder.Refiners
{
public class ShellRefiner : CommonLanguageRefiner, ILanguageRefiner
{
public ShellRefiner(GenerationConfiguration configuration) : base(configuration) { }
public override void Refine(CodeNamespace generatedCode)
{
// Remove PathSegment field
// Convert Properties to AddCommand


AddDefaultImports(generatedCode);
MoveClassesWithNamespaceNamesUnderNamespace(generatedCode);
calebkiage marked this conversation as resolved.
Show resolved Hide resolved
ConvertUnionTypesToWrapper(generatedCode, _configuration.UsesBackingStore);
AddPropertiesAndMethodTypesImports(generatedCode, false, false, false);
//RemoveModelClasses(generatedCode);
//RemoveEnums(generatedCode);
//RemoveConstructors(generatedCode);
CreateCommandBuilders(generatedCode);
AddAsyncSuffix(generatedCode);
AddInnerClasses(generatedCode, false);
CapitalizeNamespacesFirstLetters(generatedCode);
ReplaceBinaryByNativeType(generatedCode, "Stream", "System.IO");
MakeEnumPropertiesNullable(generatedCode);
ReplaceReservedNames(generatedCode, new CSharpReservedNamesProvider(), x => $"@{x.ToFirstCharacterUpperCase()}");
DisambiguatePropertiesWithClassNames(generatedCode);
AddConstructorsForDefaultValues(generatedCode, false);
AddSerializationModulesImport(generatedCode);
}
private static void DisambiguatePropertiesWithClassNames(CodeElement currentElement)
{
calebkiage marked this conversation as resolved.
Show resolved Hide resolved
if (currentElement is CodeClass currentClass)
{
var sameNameProperty = currentClass
.GetChildElements(true)
.OfType<CodeProperty>()
.FirstOrDefault(x => x.Name.Equals(currentClass.Name, StringComparison.OrdinalIgnoreCase));
if (sameNameProperty != null)
{
currentClass.RemoveChildElement(sameNameProperty);
sameNameProperty.SerializationName ??= sameNameProperty.Name;
sameNameProperty.Name = $"{sameNameProperty.Name}_prop";
currentClass.AddProperty(sameNameProperty);
}
}
CrawlTree(currentElement, DisambiguatePropertiesWithClassNames);
}
private static void MakeEnumPropertiesNullable(CodeElement currentElement)
{
if (currentElement is CodeClass currentClass && currentClass.IsOfKind(CodeClassKind.Model))
currentClass.GetChildElements(true)
.OfType<CodeProperty>()
.Where(x => x.Type is CodeType propType && propType.TypeDefinition is CodeEnum)
.ToList()
.ForEach(x => x.Type.IsNullable = true);
CrawlTree(currentElement, MakeEnumPropertiesNullable);
}
private static void RemoveModelClasses(CodeElement currentElement)
calebkiage marked this conversation as resolved.
Show resolved Hide resolved
{
if (currentElement is CodeClass currentClass && currentClass.IsOfKind(CodeClassKind.Model))
{
var codeNamespace = currentClass.Parent as CodeNamespace;
codeNamespace.RemoveChildElement(currentClass);
}
CrawlTree(currentElement, RemoveModelClasses);
}

private static void RemoveEnums(CodeElement currentElement)
{
if (currentElement is CodeEnum currentEnum)
{
var codeNamespace = currentElement.Parent as CodeNamespace;
codeNamespace.RemoveChildElement(currentEnum);
}
CrawlTree(currentElement, RemoveEnums);
}

private static void RemoveConstructors(CodeElement currentElement)
{
if (currentElement is CodeMethod currentMethod && currentMethod.IsOfKind(CodeMethodKind.Constructor))
{
var codeClass = currentElement.Parent as CodeClass;
codeClass.RemoveChildElement(currentMethod);
}
CrawlTree(currentElement, RemoveConstructors);
}

private static void CreateCommandBuilders(CodeElement currentElement)
{
if (currentElement is CodeClass currentClass && currentClass.IsOfKind(CodeClassKind.RequestBuilder))
{
// Replace Nav Properties with BuildXXXCommand methods
var navProperties = currentClass.GetChildElements().OfType<CodeProperty>().Where(e => e.IsOfKind(CodePropertyKind.RequestBuilder));
baywet marked this conversation as resolved.
Show resolved Hide resolved
foreach (var navProp in navProperties)
{
var method = CreateBuildCommandMethod(navProp, currentClass);
currentClass.AddMethod(method);
currentClass.RemoveChildElement(navProp);
}
// Clone executors & convert to build command
var requestMethods = currentClass.GetChildElements().OfType<CodeMethod>().Where(e => e.IsOfKind(CodeMethodKind.RequestExecutor));
baywet marked this conversation as resolved.
Show resolved Hide resolved
foreach (var requestMethod in requestMethods)
calebkiage marked this conversation as resolved.
Show resolved Hide resolved
{
CodeMethod clone = requestMethod.Clone() as CodeMethod;
clone.IsAsync = false;
clone.Name = $"Build{clone.Name}Command";
clone.ReturnType = CreateCommandType(clone);
clone.MethodKind = CodeMethodKind.CommandBuilder;
clone.OriginalMethod = requestMethod;
clone.ClearParameters();
currentClass.AddMethod(clone);
}

var buildMethod = new CodeMethod
calebkiage marked this conversation as resolved.
Show resolved Hide resolved
{
Name = "Build",
IsAsync = false,
MethodKind = CodeMethodKind.CommandBuilder
};
buildMethod.AddParameter(new CodeParameter { Name = "httpCore", Type = new CodeType { Name = "IHttpCore", IsExternal = true } });
calebkiage marked this conversation as resolved.
Show resolved Hide resolved
// Add calls to BuildMethods here..
buildMethod.ReturnType = new CodeType
{
Name = "Command",
IsExternal = true
};
currentClass.AddMethod(buildMethod);

}
CrawlTree(currentElement, CreateCommandBuilders);
}

private static CodeType CreateCommandType(CodeElement parent)
{
return new CodeType
{
Name = "Command",
IsExternal = true
};
}

private static CodeMethod CreateBuildCommandMethod(CodeProperty navProperty, CodeClass parent)
{
var codeMethod = new CodeMethod();
codeMethod.IsAsync = false;
baywet marked this conversation as resolved.
Show resolved Hide resolved
codeMethod.IsStatic = true;
codeMethod.Name = $"Build{navProperty.Name.ToFirstCharacterUpperCase()}Command";
codeMethod.MethodKind = CodeMethodKind.CommandBuilder;
codeMethod.ReturnType = CreateCommandType(codeMethod);
return codeMethod;
}

private static readonly string[] defaultNamespacesForClasses = new string[] { "System", "System.Collections.Generic", "System.Linq" };
private static readonly string[] defaultNamespacesForRequestBuilders = new string[] { "System.Threading.Tasks", "System.IO", "Microsoft.Kiota.Abstractions", "Microsoft.Kiota.Abstractions.Serialization", "System.CommandLine", "System.CommandLine.Invocation" };

private static void AddDefaultImports(CodeElement current)
{
if (current is CodeClass currentClass)
{
currentClass.AddUsing(defaultNamespacesForClasses.Select(x => new CodeUsing { Name = x }).ToArray());
if (currentClass.IsOfKind(CodeClassKind.RequestBuilder))
currentClass.AddUsing(defaultNamespacesForRequestBuilders.Select(x => new CodeUsing { Name = x }).ToArray());
}
CrawlTree(current, AddDefaultImports);
}
private static void CapitalizeNamespacesFirstLetters(CodeElement current)
calebkiage marked this conversation as resolved.
Show resolved Hide resolved
{
if (current is CodeNamespace currentNamespace)
currentNamespace.Name = currentNamespace.Name?.Split('.')?.Select(x => x.ToFirstCharacterUpperCase())?.Aggregate((x, y) => $"{x}.{y}");
CrawlTree(current, CapitalizeNamespacesFirstLetters);
}
private static void AddAsyncSuffix(CodeElement currentElement)
{
if (currentElement is CodeMethod currentMethod && currentMethod.IsAsync)
currentMethod.Name += "Async";
CrawlTree(currentElement, AddAsyncSuffix);
}
}
}
14 changes: 7 additions & 7 deletions src/Kiota.Builder/Writers/CSharp/CSharpWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ public CSharpWriter(string rootPath, string clientNamespaceName)
{
PathSegmenter = new CSharpPathSegmenter(rootPath, clientNamespaceName);
var conventionService = new CSharpConventionService();
AddCodeElementWriter(new CodeClassDeclarationWriter(conventionService));
AddCodeElementWriter(new CodeClassEndWriter(conventionService));
AddCodeElementWriter(new CodeEnumWriter(conventionService));
AddCodeElementWriter(new CodeIndexerWriter(conventionService));
AddCodeElementWriter(new CodeMethodWriter(conventionService));
AddCodeElementWriter(new CodePropertyWriter(conventionService));
AddCodeElementWriter(new CodeTypeWriter(conventionService));
AddOrReplaceCodeElementWriter(new CodeClassDeclarationWriter(conventionService));
AddOrReplaceCodeElementWriter(new CodeClassEndWriter(conventionService));
AddOrReplaceCodeElementWriter(new CodeEnumWriter(conventionService));
AddOrReplaceCodeElementWriter(new CodeIndexerWriter(conventionService));
AddOrReplaceCodeElementWriter(new CodeMethodWriter(conventionService));
AddOrReplaceCodeElementWriter(new CodePropertyWriter(conventionService));
AddOrReplaceCodeElementWriter(new CodeTypeWriter(conventionService));

}
}
Expand Down