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

Added ResponseHandler property and default implementation function #10

Merged
merged 11 commits into from
Dec 31, 2020
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)
{
darrelmiller marked this conversation as resolved.
Show resolved Hide resolved
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