Skip to content

Commit

Permalink
Adopt routes Cadl-ranch spec (#5138)
Browse files Browse the repository at this point in the history
Contributes to #5101
  • Loading branch information
JoshLove-msft authored Nov 18, 2024
1 parent ce9c388 commit b003714
Show file tree
Hide file tree
Showing 40 changed files with 4,818 additions and 94 deletions.
1 change: 0 additions & 1 deletion packages/http-client-csharp/eng/scripts/Generate.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ $failingSpecs = @(
Join-Path 'http' 'payload' 'json-merge-patch'
Join-Path 'http' 'payload' 'pageable'
Join-Path 'http' 'resiliency' 'srv-driven'
Join-Path 'http' 'routes'
Join-Path 'http' 'special-headers' 'conditional-request'
Join-Path 'http' 'type' 'model' 'flatten'
Join-Path 'http' 'type' 'model' 'templated'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,59 @@ namespace Microsoft.Generator.CSharp.ClientModel.Providers
{
internal sealed class ClientUriBuilderDefinition : TypeProvider
{
protected override TypeSignatureModifiers GetDeclarationModifiers()
{
return TypeSignatureModifiers.Internal;
}
private const string ToUriMethodName = "ToUri";
private const string ResetMethodName = "Reset";
private const string AppendQueryMethodName = "AppendQuery";
private const string AppendQueryDelimitedMethodName = "AppendQueryDelimited";
private const string AppendPathDelimitedMethodName = "AppendPathDelimited";
private const string AppendPathMethodName = "AppendPath";

private readonly FieldProvider _uriBuilderField;
private readonly FieldProvider _pathBuilderField;
private readonly FieldProvider _queryBuilderField;

private PropertyProvider? _uriBuilderProperty;
private PropertyProvider UriBuilderProperty => _uriBuilderProperty ??= new(
modifiers: MethodSignatureModifiers.Private,
name: "UriBuilder",
type: typeof(UriBuilder),
body: new ExpressionPropertyBody(new BinaryOperatorExpression(" ??= ", _uriBuilderField, New.Instance(typeof(UriBuilder)))),
description: null,
enclosingType: this);

private ValueExpression UriBuilderPath => new MemberExpression(UriBuilderProperty, "Path");
private ValueExpression UriBuilderQuery => new MemberExpression(UriBuilderProperty, "Query");

private PropertyProvider? _pathBuilderProperty;
private PropertyProvider PathBuilderProperty => _pathBuilderProperty ??= new(
modifiers: MethodSignatureModifiers.Private,
name: "PathBuilder",
type: typeof(StringBuilder),
body: new ExpressionPropertyBody(new BinaryOperatorExpression(" ??= ", _pathBuilderField, New.Instance(typeof(StringBuilder), UriBuilderPath))),
description: null,
enclosingType: this);

private PropertyProvider? _queryBuilderProperty;
private PropertyProvider QueryBuilderProperty => _queryBuilderProperty ??= new(
modifiers: MethodSignatureModifiers.Private,
name: "QueryBuilder",
type: typeof(StringBuilder),
body: new ExpressionPropertyBody(new BinaryOperatorExpression(" ??= ", _queryBuilderField, New.Instance(typeof(StringBuilder), UriBuilderQuery))),
description: null,
enclosingType: this);

public ClientUriBuilderDefinition()
{
_uriBuilderField = new(FieldModifiers.Private, typeof(UriBuilder), "_uriBuilder", this);
_pathBuilderField = new(FieldModifiers.Private, typeof(StringBuilder), "_pathBuilder", this);
_queryBuilderField = new(FieldModifiers.Private, typeof(StringBuilder), "_queryBuilder", this);
}

protected override TypeSignatureModifiers GetDeclarationModifiers()
{
return TypeSignatureModifiers.Internal;
}

protected override string BuildRelativeFilePath() => Path.Combine("src", "Generated", "Internal", $"{Name}.cs");

protected override string BuildName() => "ClientUriBuilder";
Expand All @@ -42,36 +79,6 @@ protected override FieldProvider[] BuildFields()
return [_uriBuilderField, _pathBuilderField, _queryBuilderField];
}

private PropertyProvider? _uriBuilderProperty;
private PropertyProvider UriBuilderProperty => _uriBuilderProperty ??= new(
modifiers: MethodSignatureModifiers.Private,
name: "UriBuilder",
type: typeof(UriBuilder),
body: new ExpressionPropertyBody(new BinaryOperatorExpression(" ??= ", _uriBuilderField, New.Instance(typeof(UriBuilder)))),
description: null,
enclosingType: this);

internal ValueExpression UriBuilderPath => new MemberExpression(UriBuilderProperty, "Path");
internal ValueExpression UriBuilderQuery => new MemberExpression(UriBuilderProperty, "Query");

private PropertyProvider? _pathBuilderProperty;
private PropertyProvider PathBuilderProperty => _pathBuilderProperty ??= new(
modifiers: MethodSignatureModifiers.Private,
name: "PathBuilder",
type: typeof(StringBuilder),
body: new ExpressionPropertyBody(new BinaryOperatorExpression(" ??= ", _pathBuilderField, New.Instance(typeof(StringBuilder), UriBuilderPath))),
description: null,
enclosingType: this);

private PropertyProvider? _queryBuilderProperty;
private PropertyProvider QueryBuilderProperty => _queryBuilderProperty ??= new(
modifiers: MethodSignatureModifiers.Private,
name: "QueryBuilder",
type: typeof(StringBuilder),
body: new ExpressionPropertyBody(new BinaryOperatorExpression(" ??= ", _queryBuilderField, New.Instance(typeof(StringBuilder), UriBuilderQuery))),
description: null,
enclosingType: this);

protected override PropertyProvider[] BuildProperties()
{
return [UriBuilderProperty, PathBuilderProperty, QueryBuilderProperty];
Expand All @@ -95,23 +102,22 @@ protected override MethodProvider[] BuildMethods()
{
methods.Add(BuildResetMethod());
methods.AddRange(BuildAppendPathMethods());
methods.AddRange(BuildAppendPathDelimitedMethods());
methods.AddRange(BuildAppendQueryMethods());
methods.AddRange(BuildAppendQueryDelimitedMethods());
methods.Add(BuildToUriMethod());
}

methods.AddRange(BuildAppendQueryDelimitedMethods());

return methods.ToArray();
}

protected override CSharpType? GetBaseType() => ClientModelPlugin.Instance.TypeFactory.ClientUriBuilderBaseType;

private const string _resetMethodName = "Reset";
private MethodProvider BuildResetMethod()
{
var uriParameter = new ParameterProvider("uri", $"The uri.", typeof(Uri));
var signature = new MethodSignature(
Name: _resetMethodName,
Name: ResetMethodName,
Modifiers: MethodSignatureModifiers.Public,
Parameters: new[]
{
Expand All @@ -130,13 +136,12 @@ private MethodProvider BuildResetMethod()
return new(signature, body, this);
}

private const string _appendPathMethodName = "AppendPath";
private MethodProvider[] BuildAppendPathMethods()
{
var valueParameter = new ParameterProvider("value", $"The value.", typeof(string));
var escapeParameter = new ParameterProvider("escape", $"The escape", typeof(bool));
var signature = new MethodSignature(
Name: _appendPathMethodName,
Name: AppendPathMethodName,
Modifiers: MethodSignatureModifiers.Public,
Parameters: [valueParameter, escapeParameter],
ReturnType: null,
Expand Down Expand Up @@ -168,7 +173,6 @@ private MethodProvider[] BuildAppendPathMethods()
BuildAppendPathMethod(typeof(double), true, false),
BuildAppendPathMethod(typeof(int), true, false),
BuildAppendPathMethod(typeof(byte[]), true, true),
BuildAppendPathMethod(typeof(IEnumerable<string>), true, false),
BuildAppendPathMethod(typeof(DateTimeOffset), true, true),
BuildAppendPathMethod(typeof(TimeSpan), true, true),
BuildAppendPathMethod(typeof(Guid), true, false),
Expand All @@ -186,26 +190,25 @@ private MethodProvider BuildAppendPathMethod(CSharpType valueType, bool escapeDe
: new[] { valueParameter, escapeParameter };

var signature = new MethodSignature(
Name: _appendPathMethodName,
Name: AppendPathMethodName,
Modifiers: MethodSignatureModifiers.Public,
Parameters: parameters,
ReturnType: null,
Description: null, ReturnDescription: null);
var convertToStringExpression = TypeFormattersSnippets.ConvertToString(valueParameter, hasFormat ? (ValueExpression)formatParameter : null);
var body = new InvokeMethodExpression(null, _appendPathMethodName, [convertToStringExpression, escapeParameter]);
var body = new InvokeMethodExpression(null, AppendPathMethodName, [convertToStringExpression, escapeParameter]);

return new(signature, body, this);
}

private const string _appendQueryMethodName = "AppendQuery";
private MethodProvider[] BuildAppendQueryMethods()
{
var nameParameter = new ParameterProvider("name", $"The name.", typeof(string));
var valueParameter = new ParameterProvider("value", $"The value.", typeof(string));
var escapeParameter = new ParameterProvider("escape", $"The escape.", typeof(bool));

var signature = new MethodSignature(
Name: _appendQueryMethodName,
Name: AppendQueryMethodName,
Modifiers: MethodSignatureModifiers.Public,
Parameters: [nameParameter, valueParameter, escapeParameter],
ReturnType: null,
Expand Down Expand Up @@ -258,38 +261,50 @@ private MethodProvider BuildAppendQueryMethod(CSharpType valueType, bool escapeD
: new[] { nameParameter, valueParameter, escapeParameter };

var signature = new MethodSignature(
Name: _appendQueryMethodName,
Name: AppendQueryMethodName,
Modifiers: MethodSignatureModifiers.Public,
Parameters: parameters,
ReturnType: null,
Description: null, ReturnDescription: null);
var convertToStringExpression = TypeFormattersSnippets.ConvertToString(valueParameter, hasFormat ? (ValueExpression)formatParameter : null);
var body = new InvokeMethodExpression(null, _appendQueryMethodName, [nameParameter, convertToStringExpression, escapeParameter]);
var body = new InvokeMethodExpression(null, AppendQueryMethodName, [nameParameter, convertToStringExpression, escapeParameter]);

return new(signature, body, this);
}

private MethodProvider[] BuildAppendQueryDelimitedMethods()
{
return [ BuildAppendQueryDelimitedMethod(false), BuildAppendQueryDelimitedMethod(true)];
return
[
BuildAppendDelimitedMethod(AppendQueryDelimitedMethodName, AppendQueryMethodName)
];
}

private MethodProvider[] BuildAppendPathDelimitedMethods()
{
return
[
BuildAppendDelimitedMethod(AppendPathDelimitedMethodName, AppendPathMethodName, false),
];
}

private readonly CSharpType _t = typeof(IEnumerable<>).GetGenericArguments()[0];

private const string _appendQueryDelimitedMethodName = "AppendQueryDelimited";
private MethodProvider BuildAppendQueryDelimitedMethod(bool hasFormat)
private MethodProvider BuildAppendDelimitedMethod(string appendDelimitedMethodName, string appendMethodName, bool hasName = true)
{
var nameParameter = new ParameterProvider("name", $"The name.", typeof(string));
var valueParameter = new ParameterProvider("value", $"The value.", new CSharpType(typeof(IEnumerable<>), _t));
var valueParameter =
new ParameterProvider("value", $"The value.", new CSharpType(typeof(IEnumerable<>), _t));
var delimiterParameter = new ParameterProvider("delimiter", $"The delimiter.", typeof(string));
var formatParameter = new ParameterProvider("format", $"The format.", typeof(string));
var formatParameter = new ParameterProvider("format", $"The format.", typeof(string), Literal(null));
var escapeParameter = new ParameterProvider("escape", $"The escape.", typeof(bool), Bool(true));

var parameters = hasFormat
var parameters = hasName
? new[] { nameParameter, valueParameter, delimiterParameter, formatParameter, escapeParameter }
: new[] { nameParameter, valueParameter, delimiterParameter, escapeParameter };
: new[] { valueParameter, delimiterParameter, formatParameter, escapeParameter };

var signature = new MethodSignature(
Name: _appendQueryDelimitedMethodName,
Name: appendDelimitedMethodName,
Modifiers: MethodSignatureModifiers.Public,
Parameters: parameters,
ReturnType: null,
Expand All @@ -299,22 +314,26 @@ private MethodProvider BuildAppendQueryDelimitedMethod(bool hasFormat)
var value = valueParameter.As(_t);

var v = new VariableExpression(_t, "v");
var convertToStringExpression = TypeFormattersSnippets.ConvertToString(v, hasFormat ? formatParameter : (ValueExpression?)null);
var convertToStringExpression = v.ConvertToString(formatParameter);
var selector = new FuncExpression([v.Declaration], convertToStringExpression).As<string>();
var body = new[]
{
delimiterParameter.Assign(Literal(","), true).Terminate(),
Declare("stringValues", value.Select(selector), out var stringValues),
new InvokeMethodExpression(null, _appendQueryMethodName, [nameParameter, StringSnippets.Join(delimiterParameter, stringValues), escapeParameter]).Terminate()
};

hasName ? new InvokeMethodExpression(
null, appendMethodName,
[nameParameter, StringSnippets.Join(delimiterParameter, stringValues), escapeParameter])
.Terminate()
: new InvokeMethodExpression(null, appendMethodName, [StringSnippets.Join(delimiterParameter, stringValues), escapeParameter])
.Terminate()
};
return new(signature, body, this);
}

private const string _toUriMethodName = "ToUri";
private MethodProvider BuildToUriMethod()
{
var signature = new MethodSignature(
Name: _toUriMethodName,
Name: ToUriMethodName,
Modifiers: MethodSignatureModifiers.Public,
Parameters: Array.Empty<ParameterProvider>(),
ReturnType: typeof(Uri),
Expand Down
Loading

0 comments on commit b003714

Please sign in to comment.