diff --git a/haxelib.json b/haxelib.json index 7a74593..685b975 100644 --- a/haxelib.json +++ b/haxelib.json @@ -10,9 +10,9 @@ "javascript" ], "description": "This library provides a macros to add 'async' and 'await' keywords for Python and JavaScript and does nothing for other platoforms.", - "version": "1.1.0", + "version": "1.1.1", "classPath": "src", - "releasenote": "Move type inference under flag", + "releasenote": "Fix handling parenthesis", "contributors": [ "botsman" ], diff --git a/src/hxasync/AsyncMacro.hx b/src/hxasync/AsyncMacro.hx index f414768..7b87aec 100644 --- a/src/hxasync/AsyncMacro.hx +++ b/src/hxasync/AsyncMacro.hx @@ -66,14 +66,18 @@ class AsyncMacro { return false; } - public static inline function handleEMeta(expr: Expr, isAsyncContext: Bool) { + public static inline function handleEMeta( + expr: Expr, + isAsyncContext: Bool, + addParenthesis: Bool = false + ) { switch expr.expr { case EMeta(s, e): if (s.name == "await") { if (!isAsyncContext) { Context.error("await allowed only inside async function", e.pos); } - transformToAwait(expr); + transformToAwait(expr, addParenthesis); } else if (s.name == "async") { switch e.expr { case EFunction(kind, f): @@ -121,7 +125,12 @@ class AsyncMacro { handleAny(field.expr, isAsyncContext); } case EParenthesis(e): - handleAny(e, isAsyncContext); + switch e.expr { + case EMeta(s, expr): + handleEMeta(e, isAsyncContext, true); + default: + handleAny(e, isAsyncContext); + } case ECheckType(e, t): handleAny(e, isAsyncContext); case EIf(econd, eif, eelse): @@ -410,11 +419,11 @@ class AsyncMacro { if (fun.ret != null) { return fun.ret; } - var complexType = - try { - var typed = Context.typeExpr({expr: EFunction(null, fun), pos:fun.expr.pos}); + var complexType = try { + var typed = Context.typeExpr({expr: EFunction(null, fun), pos: fun.expr.pos}); typed.t.followWithAbstracts().toComplexType(); - } catch (e) { + } + catch (e) { null; }; @@ -430,17 +439,21 @@ class AsyncMacro { var returnType = inferReturnType(fun); return switch returnType { case TPath({name: "StdTypes", sub: "Void"}): - macro: hxasync.Abstracts.Awaitable; + macro + : hxasync.Abstracts.Awaitable; case TPath(p): - macro: hxasync.Abstracts.Awaitable<$returnType>; + macro + : hxasync.Abstracts.Awaitable<$returnType>; case null: - null; // TODO: fix. Temporary fallback solution for cases when we failed to infer return type + null; // TODO: fix. Temporary fallback solution for cases when we failed to infer return type case TAnonymous(fields): - macro: hxasync.Abstracts.Awaitable<$returnType>; + macro + : hxasync.Abstracts.Awaitable<$returnType>; default: trace('Unexpected return type: ${returnType}'); trace(fun.expr.pos); - macro: hxasync.Abstracts.Awaitable<$returnType>; + macro + : hxasync.Abstracts.Awaitable<$returnType>; } } @@ -469,11 +482,15 @@ class AsyncMacro { } } - public static function transformToAwait(e: Expr) { + public static function transformToAwait(e: Expr, addParenthesis: Bool) { switch (e.expr) { case EMeta(s, metaE): processAwaitedFuncArgs(metaE); - e.expr = (macro hxasync.AsyncMacroUtils.await(${metaE})).expr; + if (addParenthesis) { + e.expr = (macro hxasync.AsyncMacroUtils.awaitWithParenthesis(${metaE})).expr; + } else { + e.expr = (macro hxasync.AsyncMacroUtils.await(${metaE})).expr; + } default: Context.error("Invalid expression", e.pos); } diff --git a/src/hxasync/AsyncMacroUtils.hx b/src/hxasync/AsyncMacroUtils.hx index 0ed465d..0b16866 100644 --- a/src/hxasync/AsyncMacroUtils.hx +++ b/src/hxasync/AsyncMacroUtils.hx @@ -13,6 +13,16 @@ class AsyncMacroUtils { #end } + public static extern inline function awaitWithParenthesis(arg: Awaitable): T { + #if js + return std.js.Syntax.code("(await {0})", arg); + #elseif python + return std.python.Syntax.code("(await {0})", arg); + #else + return cast arg; + #end + } + #if macro public static inline function count(text: String, char: String): Int { var counter = 0; diff --git a/tests/Tests.hx b/tests/Tests.hx index 12cd12c..a262a67 100644 --- a/tests/Tests.hx +++ b/tests/Tests.hx @@ -1,12 +1,9 @@ package tests; - - class Cases { public var some = "some variable"; - public function new() { - } + public function new() {} @async public static function testBasic() { return "basic func called"; @@ -51,6 +48,15 @@ class Cases { @await nestedFunction(); } + @async public static function testBrackets() { + var nestedFunction = @async function() { + return { + a: 10 + }; + } + return (@await nestedFunction()).a; + } + @async public function returnDynamic() { var a = 10; return { @@ -65,6 +71,7 @@ class Cases { @await testArrowFunction(); @await testFunctionWithDefaultArgs(); @await testNestedFunction(); + @await testBrackets(); } }