Skip to content

Commit aa27467

Browse files
authored
added support for short lambda syntax in upcoming haxe, fixes #337 (#341)
* added support for short lambda syntax in upcoming haxe, fixes #337 * fixed handling of kwdVar, added unittest from Haxe source
1 parent f874f80 commit aa27467

File tree

7 files changed

+182
-11
lines changed

7 files changed

+182
-11
lines changed

src/checkstyle/token/walk/WalkFieldDef.hx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ class WalkFieldDef {
3232
WalkStatement.walkStatement(stream, name);
3333
}
3434
switch (stream.token()) {
35+
case Arrow:
36+
var arrowTok:TokenTree = stream.consumeTokenDef(Arrow);
37+
name.addChild(arrowTok);
38+
walkFieldDef (stream, arrowTok);
3539
case Comma:
3640
name.addChild(stream.consumeTokenDef(Comma));
3741
case Semicolon:

src/checkstyle/token/walk/WalkPOpen.hx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package checkstyle.token.walk;
22

33
class WalkPOpen {
4-
public static function walkPOpen(stream:TokenStream, parent:TokenTree) {
4+
public static function walkPOpen(stream:TokenStream, parent:TokenTree):TokenTree {
55
var pOpen:TokenTree = stream.consumeTokenDef(POpen);
66
parent.addChild(pOpen);
77
WalkPOpen.walkPOpenParts(stream, pOpen);
88
pOpen.addChild(stream.consumeTokenDef(PClose));
9+
return pOpen;
910
}
1011

1112
public static function walkPOpenParts(stream:TokenStream, parent:TokenTree) {

src/checkstyle/token/walk/WalkStatement.hx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ class WalkStatement {
2727
case Kwd(_):
2828
if (WalkStatement.walkKeyword(stream, parent)) wantMore = true;
2929
else return;
30+
case Arrow:
31+
wantMore = true;
3032
case BrOpen:
3133
WalkObjectDecl.walkObjectDecl(stream, parent);
3234
return;
@@ -40,8 +42,8 @@ class WalkStatement {
4042
WalkBlock.walkBlock(stream, dollarTok);
4143
return;
4244
case POpen:
43-
WalkPOpen.walkPOpen(stream, parent);
44-
WalkStatement.walkStatementContinue(stream, parent);
45+
var pOpen:TokenTree = WalkPOpen.walkPOpen(stream, parent);
46+
WalkStatement.walkStatementContinue(stream, pOpen);
4547
return;
4648
case Question:
4749
WalkQuestion.walkQuestion(stream, parent);
@@ -74,6 +76,13 @@ class WalkStatement {
7476
WalkStatement.walkStatement(stream, question);
7577
return;
7678
}
79+
var dblDotTok:TokenTree = stream.consumeToken();
80+
parent.addChild(dblDotTok);
81+
WalkTypeNameDef.walkTypeNameDef(stream, dblDotTok);
82+
if (stream.is(Arrow)) {
83+
WalkStatement.walkStatement(stream, parent);
84+
}
85+
case Arrow:
7786
WalkStatement.walkStatement(stream, parent);
7887
case Binop(_), Unop(_):
7988
WalkStatement.walkStatement(stream, parent);

src/checkstyle/token/walk/WalkTypeNameDef.hx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,6 @@ class WalkTypeNameDef {
3939
return name;
4040
}
4141
if (stream.is(Binop(OpLt))) WalkLtGt.walkLtGt(stream, name);
42-
if (stream.is(Arrow)) {
43-
var arrow:TokenTree = stream.consumeTokenDef(Arrow);
44-
name.addChild(arrow);
45-
WalkTypeNameDef.walkTypeNameDef(stream, arrow);
46-
}
4742
return name;
4843
}
4944
}

src/checkstyle/token/walk/WalkTypedefBody.hx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class WalkTypedefBody {
77
parent.addChild(openTok);
88
var progress:TokenStreamProgress = new TokenStreamProgress(stream);
99
while (progress.streamHasChanged()) {
10-
switch (stream.token()) {
10+
switch (stream.token()) {
1111
case BrClose: break;
1212
default:
1313
WalkFieldDef.walkFieldDef(stream, openTok);
@@ -17,6 +17,21 @@ class WalkTypedefBody {
1717
}
1818
openTok.addChild(stream.consumeTokenDef(BrClose));
1919
}
20-
else WalkTypeNameDef.walkTypeNameDef(stream, parent);
20+
else walkTypedefAlias(stream, parent);
21+
}
22+
23+
public static function walkTypedefAlias(stream:TokenStream, parent:TokenTree) {
24+
var newParent:TokenTree;
25+
if (stream.is(POpen)) {
26+
newParent = WalkPOpen.walkPOpen(stream, parent);
27+
}
28+
else {
29+
newParent = WalkTypeNameDef.walkTypeNameDef(stream, parent);
30+
}
31+
if (stream.is(Arrow)) {
32+
var arrowTok:TokenTree = stream.consumeTokenDef(Arrow);
33+
newParent.addChild(arrowTok);
34+
walkTypedefAlias(stream, arrowTok);
35+
}
2136
}
2237
}

src/checkstyle/token/walk/WalkVar.hx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class WalkVar {
1616
if (stream.is(DblDot)) {
1717
var dblDot:TokenTree = stream.consumeTokenDef(DblDot);
1818
name.addChild(dblDot);
19-
WalkTypeNameDef.walkTypeNameDef(stream, dblDot);
19+
WalkTypedefBody.walkTypedefAlias(stream, dblDot);
2020
}
2121
if (stream.is(Binop(OpAssign))) {
2222
WalkStatement.walkStatement(stream, name);

test/token/TokenTreeBuilderParsingTest.hx

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class TokenTreeBuilderParsingTest extends haxe.unit.TestCase {
2020
assertCodeParses(ISSUE_256);
2121
assertCodeParses(DOLLAR_TOKEN_AS_VAR_NAME);
2222
assertCodeParses(REFERENCE_CONSTRUCTOR);
23+
assertCodeParses(SHORT_LAMBDA);
2324
}
2425

2526
public function assertCodeParses(code:String, ?pos:PosInfos) {
@@ -170,4 +171,150 @@ abstract TokenTreeBuilderParsingTests(String) to String {
170171
var constructor = SomeClass.new;
171172
}";
172173

174+
var SHORT_LAMBDA = "
175+
class TestArrowFunctions extends Test {
176+
177+
var f0_0: Void -> Int;
178+
var f0_1: Void -> W;
179+
180+
var f1_0: Int->Int;
181+
var f1_1: ?Int->Int;
182+
183+
var f2_0: Int->Int;
184+
185+
var f3_0: Int->Int->Int;
186+
var f3_1: ?Int->String->Int;
187+
var f3_2: Int->?Int->Int;
188+
189+
var f4: Int->(Int->Int);
190+
var f5: Int->Int->(Int->Int);
191+
var f6_a: Int->(Int->(Int->Int));
192+
var f6_b: Int->(Int->(Int->Int));
193+
var f7: (Int->Int)->(Int->Int);
194+
var f8: Int -> String;
195+
196+
var arr: Array<Int->Int> = [];
197+
var map: Map<Int,Int->Int> = new Map();
198+
var obj: { f : Int->Int };
199+
200+
var v0: Int;
201+
var v1: String;
202+
203+
var maybe : Void -> Bool;
204+
205+
function testSyntax(){
206+
207+
// skipping hl for now due to variance errors:
208+
// Don't know how to cast ref(i32) to null(i32) see issue #6210
209+
#if !(hl || as3)
210+
211+
maybe = () -> Math.random() > 0.5;
212+
213+
v0 = (123);
214+
v0 = (123:Int);
215+
216+
f0_0 = function () return 1;
217+
f0_0 = () -> 1;
218+
219+
f0_0 = (() -> 1);
220+
f0_0 = (() -> 1:Void->Int);
221+
f0_0 = cast (() -> 1:Void->Int);
222+
223+
v0 = f0_0();
224+
225+
f0_1 = function () : W return 1;
226+
v1 = f0_1();
227+
228+
f0_1 = () -> (1:W);
229+
v1 = f0_1();
230+
231+
f1_0 = function (a:Int) return a;
232+
f1_1 = function (?a:Int) return a;
233+
234+
f1_0 = a -> a;
235+
v0 = f1_0(1);
236+
237+
f1_1 = (?a) -> a;
238+
v0 = f1_1(1);
239+
240+
f1_1 = (?a:Int) -> a;
241+
v0 = f1_1(1);
242+
243+
f1_1 = (a:Int=1) -> a;
244+
v0 = f1_1();
245+
246+
f1_1 = (?a:Int=1) -> a;
247+
v0 = f1_1();
248+
249+
f1_1 = function (a=2) return a;
250+
eq(f1_1(),2);
251+
252+
f1_1 = (a=2) -> a;
253+
eq(f1_1(),2);
254+
255+
f3_0 = function (a:Int, b:Int) return a + b;
256+
f3_1 = function (?a:Int, b:String) return a + b.length;
257+
f3_2 = function (a:Int, ?b:Int) return a + b;
258+
259+
f3_0 = (a:Int, b:Int) -> a + b;
260+
f3_1 = (?a:Int, b:String) -> a + b.length;
261+
f3_2 = (a:Int, ?b:Int) -> a + b;
262+
263+
#if !flash
264+
f3_1 = function (a=1, b:String) return a + b.length;
265+
eq(f3_1('--'),3);
266+
267+
f3_1 = function (?a:Int=1, b:String) return a + b.length;
268+
eq(f3_1('--'),3);
269+
270+
f3_2 = function (a:Int, b=2) return a + b;
271+
eq(f3_2(1),3);
272+
273+
f3_1 = (a=1, b:String) -> a + b.length;
274+
eq(f3_1('--'),3);
275+
276+
f3_1 = (a:Int=1, b:String) -> a + b.length;
277+
eq(f3_1('--'),3);
278+
279+
f3_1 = (?a:Int=1, b:String) -> a + b.length;
280+
eq(f3_1('--'),3);
281+
282+
f3_2 = (a:Int, b=2) -> a + b;
283+
eq(f3_2(1),3);
284+
#end
285+
286+
f4 = function (a) return function (b) return a + b;
287+
f4 = a -> b -> a + b;
288+
289+
f5 = function (a,b) return function (c) return a + b + c;
290+
f5 = (a, b) -> c -> a + b + c;
291+
292+
f6_a = function (a) return function (b) return function (c) return a + b + c;
293+
f6_b = a -> b -> c -> a + b + c;
294+
eq(f6_a(1)(2)(3),f6_b(1)(2)(3));
295+
296+
f7 = function (f:Int->Int) return f;
297+
f7 = f -> f;
298+
f7 = (f:Int->Int) -> f;
299+
f7 = maybe() ? f -> f : f -> g -> f(g);
300+
f7 = switch maybe() {
301+
case true: f -> f;
302+
case false: f -> g -> f(g);
303+
};
304+
305+
f8 = (a:Int) -> ('$a':String);
306+
307+
arr = [for (i in 0...5) a -> a * i];
308+
arr = [a -> a + a, b -> b + b, c -> c + c];
309+
arr.map( f -> f(2) );
310+
311+
var arr2:Array<Int->W> = [for (f in arr) x -> f(x)];
312+
313+
map = [1 => a -> a + a, 2 => a -> a + a, 3 => a -> a + a];
314+
315+
obj = { f : a -> a + a };
316+
317+
#end
318+
}
319+
}";
173320
}

0 commit comments

Comments
 (0)