Skip to content

Commit

Permalink
Merge pull request #10 from microsoft/dm/responsehandler
Browse files Browse the repository at this point in the history
Added ResponseHandler property and default implementation function
  • Loading branch information
baywet authored Dec 31, 2020
2 parents 0e49a8c + 034a601 commit 97b8ddb
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 13 deletions.
9 changes: 9 additions & 0 deletions src/kiota.core/CodeDOM/CodeMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,23 @@

namespace kiota.core
{
public enum CodeMethodKind
{
Custom,
ResponseHandler
}

public class CodeMethod : CodeTerminal, ICloneable
{
public CodeMethodKind MethodKind = CodeMethodKind.Custom;
public CodeType ReturnType;
public List<CodeParameter> Parameters = new List<CodeParameter>();
public bool IsStatic = false;

public object Clone()
{
return new CodeMethod {
MethodKind = MethodKind,
ReturnType = ReturnType.Clone() as CodeType,
Parameters = Parameters.Select(x => x.Clone() as CodeParameter).ToList(),
Name = Name.Clone() as string,
Expand Down
10 changes: 8 additions & 2 deletions src/kiota.core/CodeDOM/CodeParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,23 @@

namespace kiota.core
{
public enum CodeParameterKind
{
Custom,
QueryParameter
}

public class CodeParameter : CodeTerminal, ICloneable
{
public CodeParameterKind ParameterKind = CodeParameterKind.Custom;
public CodeType Type;
public bool Optional = false;
public bool IsQueryParameter { get; set; }

public object Clone()
{
return new CodeParameter{
Optional = Optional,
IsQueryParameter = IsQueryParameter,
ParameterKind = ParameterKind,
Name = Name.Clone() as string,
Type = Type.Clone() as CodeType,
};
Expand Down
9 changes: 9 additions & 0 deletions src/kiota.core/CodeDOM/CodeProperty.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
namespace kiota.core
{
public enum CodePropertyKind
{
Custom,
ResponseHandler
}

public class CodeProperty : CodeTerminal
{
public CodePropertyKind PropertyKind = CodePropertyKind.Custom;

public override string Name
{
get; set;
}
public bool ReadOnly = false;
public CodeType Type;
public string DefaultValue;
}
}
25 changes: 22 additions & 3 deletions src/kiota.core/KiotaBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,10 @@ private void CreateClass(CodeNamespace codeNamespace, OpenApiUrlSpaceNode node)
logger.LogDebug("Creating method {name} of {type}", method.Name, method.ReturnType);
codeClass.AddMethod(method);
}

CreateResponseHandler(codeClass);
}


codeNamespace.AddClass(codeClass);

Expand All @@ -246,12 +249,13 @@ private CodeIndexer CreateIndexer(string childIdentifier, string childType)
return prop;
}

private CodeProperty CreateProperty(string childIdentifier, string childType)
private CodeProperty CreateProperty(string childIdentifier, string childType, string defaultValue = null)
{
var prop = new CodeProperty()
{
Name = childIdentifier,
Type = new CodeType() { Name = childType }
Type = new CodeType() { Name = childType },
DefaultValue = defaultValue
};
logger.LogDebug("Creating property {name} of {type}", prop.Name, prop.Type.Name);
return prop;
Expand Down Expand Up @@ -279,7 +283,7 @@ private CodeMethod CreateOperationMethod(OperationType operationType, OpenApiOpe
Name = "q",
Type = new CodeType() { Name = parameterClass.Name, ActionOf = true, TypeDefinition = parameterClass },
Optional = true,
IsQueryParameter = true,
ParameterKind = CodeParameterKind.QueryParameter
};
method.AddParameter(methodParameter);
return method;
Expand Down Expand Up @@ -380,5 +384,20 @@ private static string FixPathIdentifier(string identifier)
}
return identifier.ToCamelCase();
}

private void CreateResponseHandler(CodeClass requestBuilder)
{
// Default ResponseHandler Implementation
var responseHandlerImpl = new CodeMethod { Name = "DefaultResponseHandler", IsStatic = true, MethodKind = CodeMethodKind.ResponseHandler };
responseHandlerImpl.AddParameter(new CodeParameter { Name = "response", Type = new CodeType { Name = "object" } }); // replace native HTTP response object type in language refiner
responseHandlerImpl.ReturnType = new CodeType { Name = "object" };
requestBuilder.AddMethod(responseHandlerImpl);

// Property to allow replacing Response Handler
var responseHandlerProperty = CreateProperty("ResponseHandler", "Func<object,object>", "DefaultResponseHandler"); // HttpResponseMessage, model
responseHandlerProperty.PropertyKind = CodePropertyKind.ResponseHandler;
responseHandlerProperty.ReadOnly = false;
requestBuilder.AddProperty(responseHandlerProperty);
}
}
}
34 changes: 33 additions & 1 deletion src/kiota.core/Refiners/CSharpRefiner.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,46 @@
using System.Linq;
using System.Linq;
using System.Text.RegularExpressions;

namespace kiota.core {
public class CSharpRefiner : CommonLanguageRefiner, ILanguageRefiner
{
private static readonly Regex responseHandlerType = new Regex("<(.*),object>");
public override void Refine(CodeNamespace generatedCode)
{
generatedCode.AddUsing(new CodeUsing() { Name = "System" });
generatedCode.AddUsing(new CodeUsing() { Name = "System.Threading.Tasks" });
generatedCode.AddUsing(new CodeUsing() { Name = "System.Net.Http" });
AddAsyncSuffix(generatedCode);
AddInnerClasses(generatedCode);
MakeNativeResponseHandlers(generatedCode);
}

private void MakeNativeResponseHandlers(CodeNamespace generatedCode)
{
foreach (var codeElement in generatedCode.InnerChildElements)
{
switch (codeElement)
{
case CodeClass c:
var responseHandlerProp = c.InnerChildElements.OfType<CodeProperty>().Where(e => e.PropertyKind == CodePropertyKind.ResponseHandler)
.FirstOrDefault();
if (responseHandlerProp != null)
{
responseHandlerProp.Type.Name = responseHandlerType.Replace(responseHandlerProp.Type.Name, "<HttpResponseMessage,Task<$1>>"); // TODO: We should probably generic types properly
}
var defaultResponseHandler = c.InnerChildElements.OfType<CodeMethod>()
.Where(m=> m.MethodKind == CodeMethodKind.ResponseHandler)
.FirstOrDefault();
if (defaultResponseHandler != null)
{
defaultResponseHandler.Parameters.FirstOrDefault().Type.Name = "HttpResponseMessage";
}
break;
case CodeNamespace n:
MakeNativeResponseHandlers(n);
break;
}
}
}
private void AddAsyncSuffix(CodeElement currentElement) {
if(currentElement is CodeMethod currentMethod)
Expand Down
8 changes: 4 additions & 4 deletions src/kiota.core/Refiners/JavaRefiner.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Linq;
using System.Linq;

namespace kiota.core {
public class JavaRefiner : CommonLanguageRefiner, ILanguageRefiner
Expand All @@ -15,7 +15,7 @@ private void MakeQueryStringParametersNonOptionalAndInsertOverrideMethod(CodeEle
if(currentElement is CodeClass currentClass && codeMethods.Any()) {
codeMethods
.SelectMany(x => x.Parameters)
.Where(x => x.IsQueryParameter)
.Where(x => x.ParameterKind == CodeParameterKind.QueryParameter)
.ToList()
.ForEach(x => x.Optional = false);
currentClass.AddMethod(codeMethods
Expand All @@ -28,9 +28,9 @@ private void MakeQueryStringParametersNonOptionalAndInsertOverrideMethod(CodeEle
MakeQueryStringParametersNonOptionalAndInsertOverrideMethod(childElement);
}
private CodeMethod GetMethodClone(CodeMethod currentMethod) {
if(currentMethod.Parameters.Any(x => x.IsQueryParameter)) {
if(currentMethod.Parameters.Any(x => x.ParameterKind == CodeParameterKind.QueryParameter)) {
var cloneMethod = currentMethod.Clone() as CodeMethod;
cloneMethod.Parameters.RemoveAll(x => x.IsQueryParameter);
cloneMethod.Parameters.RemoveAll(x => x.ParameterKind == CodeParameterKind.QueryParameter);
return cloneMethod;
}
else return null;
Expand Down
18 changes: 15 additions & 3 deletions src/kiota.core/Writers/CSharpWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,17 @@ public override void WriteCodeClassEnd(CodeClass.End code)

public override void WriteProperty(CodeProperty code)
{

WriteLine($"public {GetTypeString(code.Type)} {code.Name} {{get;}}");
var simpleBody = "get;";
if (!code.ReadOnly)
{
simpleBody = "get;set;";
}
var defaultValue = string.Empty;
if (code.DefaultValue != null)
{
defaultValue = " = " + code.DefaultValue + ";";
}
WriteLine($"public {GetTypeString(code.Type)} {code.Name} {{{simpleBody}}}{defaultValue}");
}

public override void WriteIndexer(CodeIndexer code)
Expand All @@ -47,7 +56,10 @@ public override void WriteIndexer(CodeIndexer code)

public override void WriteMethod(CodeMethod code)
{
WriteLine($"public Task<{GetTypeString(code.ReturnType)}> {code.Name}({string.Join(',', code.Parameters.Select(p=> GetParameterSignature(p)).ToList())}) {{ return null; }}");
var staticModifier = code.IsStatic ? "static " : string.Empty;
// Task type should be moved into the refiner
WriteLine($"public {staticModifier}Task<{GetTypeString(code.ReturnType)}> {code.Name}({string.Join(',', code.Parameters.Select(p=> GetParameterSignature(p)).ToList())}) {{ return null; }}");

}

public override void WriteType(CodeType code)
Expand Down

0 comments on commit 97b8ddb

Please sign in to comment.