[WIP] most of the grunt work to get httpclient integrated#105
[WIP] most of the grunt work to get httpclient integrated#105sergey-tihon merged 11 commits intofsprojects:devfrom
Conversation
|
Error messages like
means that we should not call methods defined in design-time assembly from provided quotation. So, all building blocks should be moved to runtime assembly. @baronfel would you like to move them? |
generated code public FSharpAsync<int[]> PostApiUpdateArrayInt(int[] x)
{
FSharpFunc<FSharpAsync<object>, object> fsharpFunc = Swagger.Internal.RuntimeHelpers.get_asyncCast().Invoke(typeof (int[]));
Lambdad92d1b9e\u002D8d77\u002D4787\u002D8a44\u002Dc9f992846b21 obj = new Lambdad92d1b9e\u002D8d77\u002D4787\u002D8a44\u002Dc9f992846b21();
obj.@this = this;
obj.x = x;
FSharpAsyncBuilder defaultAsyncBuilder = ExtraTopLevelOperators.DefaultAsyncBuilder;
FSharpAsync<object> func = ((FSharpFunc<FSharpAsyncBuilder, FSharpAsync<object>>) obj).Invoke(defaultAsyncBuilder);
return (FSharpAsync<int[]>) fsharpFunc.Invoke(func);
}internal class Lambdad92d1b9e\u002D8d77\u002D4787\u002D8a44\u002Dc9f992846b21 : FSharpFunc<FSharpAsyncBuilder, FSharpAsync<object>>
{
internal SwashbuckleReturnControllersTests.WebAPI.Client @this;
internal int[] x;
public override sealed FSharpAsync<object> Invoke([In] FSharpAsyncBuilder obj0)
{
SwashbuckleReturnControllersTests.WebAPI.Client client = this.@this;
int[] x = this.x;
return obj0.Delay<object>((FSharpFunc<Unit, FSharpAsync<object>>) new Lambda77b383a1\u002D35e4\u002D47ed\u002D84cf\u002Deddba544373c()
{
builder\u0040 = obj0,
@this = client,
x = x
});
}
}internal class Lambda77b383a1\u002D35e4\u002D47ed\u002D84cf\u002Deddba544373c : FSharpFunc<Unit, FSharpAsync<object>>
{
internal FSharpAsyncBuilder builder\u0040;
internal SwashbuckleReturnControllersTests.WebAPI.Client @this;
internal int[] x;
public override sealed FSharpAsync<object> Invoke([In] Unit obj0)
{
FSharpAsyncBuilder builder = this.builder\u0040;
SwashbuckleReturnControllersTests.WebAPI.Client client = this.@this;
int[] x = this.x;
FSharpAsyncBuilder fsharpAsyncBuilder = builder;
StringContent stringContent = new StringContent(RuntimeHelpers.get_serialize().Invoke((object) x), Encoding.UTF8, "application/json");
UriBuilder uriBuilder1 = new UriBuilder(RuntimeHelpers.combineUrl(RuntimeHelpers.combineUrl(client.Host, ""), "/api/UpdateArrayInt"));
Lambda2ac7e0f0\u002D6564\u002D4f6f\u002Db372\u002Da37aab7be429 b372A37aab7be429 = new Lambda2ac7e0f0\u002D6564\u002D4f6f\u002Db372\u002Da37aab7be429();
FSharpFunc<Tuple<string, string>, string> fsharpFunc1 = (FSharpFunc<Tuple<string, string>, string>) new Lambdaeb6c1cba\u002Dea2d\u002D4b3c\u002D9225\u002Daed56e6700e6();
Lambdaf58a7048\u002D295f\u002D4823\u002Daff2\u002D5c5d47ab9752 aff25c5d47ab9752 = new Lambdaf58a7048\u002D295f\u002D4823\u002Daff2\u002D5c5d47ab9752();
aff25c5d47ab9752.mapping = fsharpFunc1;
FSharpList<Tuple<string, string>> empty = FSharpList<Tuple<string, string>>.get_Empty();
IEnumerable<string> func1 = ((FSharpFunc<FSharpList<Tuple<string, string>>, IEnumerable<string>>) aff25c5d47ab9752).Invoke(empty);
string func2 = ((FSharpFunc<IEnumerable<string>, string>) b372A37aab7be429).Invoke(func1);
if (string.IsNullOrEmpty(uriBuilder1.Query))
{
UriBuilder uriBuilder2 = uriBuilder1;
FSharpFunc<string, FSharpFunc<string, string>> fsharpFunc2 = ExtraTopLevelOperators.PrintFormatToString<FSharpFunc<string, FSharpFunc<string, string>>>((PrintfFormat<FSharpFunc<string, FSharpFunc<string, string>>, Unit, string, string>) new PrintfFormat<FSharpFunc<string, FSharpFunc<string, string>>, Unit, string, string, Tuple<string, string>>("%s&%s"));
Lambdac780c90b\u002D354e\u002D4a1e\u002D8826\u002D1690749a9708 obj = new Lambdac780c90b\u002D354e\u002D4a1e\u002D8826\u002D1690749a9708();
obj.clo1 = fsharpFunc2;
string query = uriBuilder1.Query;
string str = ((FSharpFunc<string, FSharpFunc<string, string>>) obj).Invoke(query).Invoke(func2);
uriBuilder2.Query = str;
}
else
{
UriBuilder uriBuilder2 = uriBuilder1;
FSharpFunc<string, FSharpFunc<string, string>> fsharpFunc2 = ExtraTopLevelOperators.PrintFormatToString<FSharpFunc<string, FSharpFunc<string, string>>>((PrintfFormat<FSharpFunc<string, FSharpFunc<string, string>>, Unit, string, string>) new PrintfFormat<FSharpFunc<string, FSharpFunc<string, string>>, Unit, string, string, Tuple<string, string>>("%s?%s"));
Lambda65989771\u002D811c\u002D4bb4\u002Daf04\u002Dd24f9c59e9f0 af04D24f9c59e9f0 = new Lambda65989771\u002D811c\u002D4bb4\u002Daf04\u002Dd24f9c59e9f0();
af04D24f9c59e9f0.clo1 = fsharpFunc2;
string query = uriBuilder1.Query;
string str = ((FSharpFunc<string, FSharpFunc<string, string>>) af04D24f9c59e9f0).Invoke(query).Invoke(func2);
uriBuilder2.Query = str;
}
HttpRequestMessage httpRequestMessage1 = new HttpRequestMessage(new HttpMethod("Post"), uriBuilder1.Uri);
FSharpFunc<Tuple<string, string>, bool> fsharpFunc3 = (FSharpFunc<Tuple<string, string>, bool>) new Lambda07b64d8d\u002D2f0d\u002D4faa\u002D973b\u002Daef634f7dd3b();
Lambda4eefb031\u002D7cda\u002D4177\u002Db058\u002D268569af8b89 b058268569af8b89 = new Lambda4eefb031\u002D7cda\u002D4177\u002Db058\u002D268569af8b89();
b058268569af8b89.predicate = fsharpFunc3;
Tuple<string, string>[] headers = client.Headers;
Tuple<string, string>[] tupleArray1;
if ((!Operators.Not(((FSharpFunc<Tuple<string, string>[], bool>) b058268569af8b89).Invoke(headers)) ? 0 : 1) != 0)
tupleArray1 = ArrayModule.Append<Tuple<string, string>>(new Tuple<string, string>[1]
{
new Tuple<string, string>("Content-Type", "application/json")
}, client.Headers);
else
tupleArray1 = client.Headers;
Tuple<string, string>[] tupleArray2 = tupleArray1;
for (int index = 0; index <= (int) (ArrayModule.Length<Tuple<string, string>>(tupleArray2) - 1); ++index)
{
Tuple<string, string> array = LanguagePrimitives.IntrinsicFunctions.GetArray<Tuple<string, string>>(tupleArray2, index);
string str = array.Item2;
string name = array.Item1;
httpRequestMessage1.Headers.Add(name, str);
}
HttpRequestMessage httpRequestMessage2 = httpRequestMessage1;
httpRequestMessage2.Content = (HttpContent) stringContent;
Lambda38469ad6\u002D2abe\u002D4744\u002Db77b\u002D39423822d2f5 b77b39423822d2f5 = new Lambda38469ad6\u002D2abe\u002D4744\u002Db77b\u002D39423822d2f5();
b77b39423822d2f5.@this = client;
HttpRequestMessage func3 = httpRequestMessage2;
FSharpAsync<string> computation = RuntimeHelpers.sendMessage(((FSharpFunc<HttpRequestMessage, HttpRequestMessage>) b77b39423822d2f5).Invoke(func3));
return fsharpAsyncBuilder.Bind<string, object>(computation, (FSharpFunc<string, FSharpAsync<object>>) new Lambda520e5ab5\u002D479e\u002D4f5a\u002D908d\u002Dc856cad41e08()
{
builder\u0040 = builder
});
}
} |
|
Interesting... What is exactly not supported =) |
… to see if that fixes our 'op_Subtraction' issue
|
How did you dump the generated code? did you find the temporary assembly on-disk and use ildasm/dotpeek on it? |
|
The errors I get now are all related to an unsupported subtraction operator call: |
|
Compiler merges temp assembly to target assembly, so these samples dotpeek'ed from |
|
Thanks, that gives me enough information to do some digging on my own. |
|
One more error message (this time from Windows)
and the code of using Microsoft.FSharp.Collections;
using Microsoft.FSharp.Control;
using Microsoft.FSharp.Core;
using Swagger.Internal;
using System;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
internal class Lambda30cb63ff-f943-4fb8-8bb4-125c35c8a163 : FSharpFunc<Unit, FSharpAsync<Unit>>
{
internal FSharpAsyncBuilder builder@;
internal string key;
internal SwashbuckleReturnControllersTests.WebAPI.Client @this;
internal string value;
public sealed override FSharpAsync<Unit> Invoke(Unit P_0)
{
FSharpAsyncBuilder fSharpAsyncBuilder = this.builder@;
string text = this.key;
SwashbuckleReturnControllersTests.WebAPI.Client client = this.@this;
string text2 = this.value;
FSharpAsyncBuilder fSharpAsyncBuilder2 = fSharpAsyncBuilder;
StringContent stringContent = new StringContent(RuntimeHelpers.serialize.Invoke((object)text2), Encoding.UTF8, "application/json");
UriBuilder uriBuilder = new UriBuilder(RuntimeHelpers.combineUrl(((ProvidedSwaggerBaseType)client).Host, Regex.Replace("/api/ResourceStringString/{key}", "{key}", ((object)text).ToString())));
Lambdad5a343e1-86df-4083-986b-2e426dc32573 lambdad5a343e1-86df-4083-986b-2e426dc = new Lambdad5a343e1-86df-4083-986b-2e426dc32573();
FSharpFunc<Tuple<string, string>, string> mapping = new Lambda06ae4daf-22d3-4ffa-827f-9028b83fe252();
string text3 = lambdad5a343e1-86df-4083-986b-2e426dc.Invoke(new Lambda816af573-5b74-455c-ab88-2ecd5f855dd0
{
mapping = mapping
}.Invoke(FSharpList<Tuple<string, string>>.Empty));
if (string.IsNullOrEmpty(uriBuilder.Query))
{
uriBuilder.Query = text3;
}
else
{
uriBuilder.Query = string.Format("{0}&{1}", (object)uriBuilder.Query, (object)text3);
}
Uri uri = uriBuilder.Uri;
HttpMethod method = new HttpMethod("PUT");
HttpRequestMessage httpRequestMessage = new HttpRequestMessage(method, uri);
FSharpFunc<Tuple<string, string>, bool> predicate = new Lambdaf994f006-bf1f-4214-b467-a497daba022a();
bool flag = new Lambda8bb67850-4e78-435c-bc44-59d57d006a76
{
predicate = predicate
}.Invoke(((ProvidedSwaggerBaseType)client).Headers);
Tuple<string, string>[] array = (!Operators.Not(flag) || 1 == 0) ? ((ProvidedSwaggerBaseType)client).Headers : ArrayModule.Append(new Tuple<string, string>[1]
{
new Tuple<string, string>("Content-Type", "application/json")
}, ((ProvidedSwaggerBaseType)client).Headers);
int num = 0;
while (true)
{
if (num > ArrayModule.Length(array) - 1)
{
break;
}
Tuple<string, string> array2 = LanguagePrimitives.IntrinsicFunctions.GetArray(array, num);
string item = array2.Item2;
string item2 = array2.Item1;
httpRequestMessage.Headers.Add(item2, item);
num++;
}
HttpRequestMessage httpRequestMessage2 = httpRequestMessage;
httpRequestMessage2.Content = (HttpContent)stringContent;
HttpRequestMessage message = new Lambda3a7f3438-b2c7-4c4a-b462-3d1f1425d04d
{
@this = client
}.Invoke(httpRequestMessage2);
return fSharpAsyncBuilder2.Bind(RuntimeHelpers.sendMessage(message), new Lambda9528c2a3-90fe-444c-9e82-4e1ab737d311
{
builder@ = fSharpAsyncBuilder
});
}
}not so much options where while (true)
{
if (num > ArrayModule.Length(array) - 1)
{This is At this point, I really need some ideas or advice, because I do not see the issue ... @dsyme please take a look if you have a moment. The compilation is successful, but in the runtime provided code fails. The quotation is <@
...
for (name, value) in %heads do msg.Headers.Add(name, value)
msg
@> |
SummaryTPSDK can compile the for loop over spliced array, but generated code is incorrect <@
...
for (name, value) in %heads do msg.Headers.Add(name, value)
msg
@>as workaround we could replace for loop by <@
%heads
|> Seq.iter (fun (name, value) ->
msg.Headers.Add(name, value)
)
msg
@>@dsyme do you understand the reason? Could we fix it or should we update docs or improve error message? thx |
This doesn't do all of what we want in #100, like hiding the http calls behind the runtime-specific client class, but it brings in the HttpClient dependency and threads through most of the logic that would be needed in the OperationCompiler anyway. Moving to the runtime-specific client class would mostly be a matter of changing the actual call to the static httpclient in operationCompiler to a call to
SendAsyncor the appropriate call on our client wrapper class.I think I was having build issues locally, so part of this is just to see if the build servers are happier with this than my local machine is.