// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. import "package:expect/expect.dart"; // Tests function statement and expression syntax. class FunctionSyntaxTest { static void testMain /* //# 00: syntax error () */ //# 00: continued { testNestedFunctions(); testFunctionExpressions(); testPrecedence(); testInitializers(); testFunctionParameter(); testFunctionIdentifierExpression(); testFunctionIdentifierStatement(); } static void testNestedFunctions /* //# 01: syntax error () */ //# 01: continued { // No types - braces. nb0 /* //# 02: syntax error () */ //# 02: continued { return 42; } nb1 /* //# 03: syntax error (a) */ //# 03: continued { return a; } nb2 /* //# 04: syntax error (a, b) */ //# 04: continued { return a + b; } Expect.equals(42, nb0()); Expect.equals(87, nb1(87)); Expect.equals(1 + 2, nb2(1, 2)); // No types - arrows. na0 /* //# 05: syntax error () */ //# 05: continued => 42; na1 /* //# 06: syntax error (a) */ //# 06: continued => a; na2 /* //# 07: syntax error (a, b) */ //# 07: continued => a + b; Expect.equals(42, na0()); Expect.equals(87, na1(87)); Expect.equals(1 + 2, na2(1, 2)); // Return type - braces. int rb0 /* //# 08: syntax error () */ //# 08: continued { return 42; } int rb1 /* //# 09: syntax error (a) */ //# 09: continued { return a; } int rb2 /* //# 10: syntax error (a, b) */ //# 10: continued { return a + b; } Expect.equals(42, rb0()); Expect.equals(87, rb1(87)); Expect.equals(1 + 2, rb2(1, 2)); // Return type - arrows. int ra0 /* //# 11: syntax error () */ //# 11: continued => 42; int ra1 /* //# 12: syntax error (a) */ //# 12: continued => a; int ra2 /* //# 13: syntax error (a, b) */ //# 13: continued => a + b; Expect.equals(42, ra0()); Expect.equals(87, ra1(87)); Expect.equals(1 + 2, ra2(1, 2)); // Fully typed - braces. int fb1 /* //# 14: syntax error (int a) */ //# 14: continued { return a; } int fb2 /* //# 15: syntax error (int a, int b) */ //# 15: continued { return a + b; } Expect.equals(42, rb0()); Expect.equals(87, rb1(87)); Expect.equals(1 + 2, rb2(1, 2)); // Fully typed - arrows. int fa1 /* //# 16: syntax error (int a) */ //# 16: continued => a; int fa2 /* //# 17: syntax error (int a, int b) */ //# 17: continued => a + b; Expect.equals(42, ra0()); Expect.equals(87, ra1(87)); Expect.equals(1 + 2, ra2(1, 2)); // Generic types - braces. List gb0 /* //# 18: syntax error () */ //# 18: continued { return [42]; } List gb1 /* //# 19: syntax error (List a) */ //# 19: continued { return a; } Expect.equals(42, gb0()[0]); Expect.equals(87, gb1([87])[0]); // Generic types - arrows. List ga0 /* //# 20: syntax error () */ //# 20: continued => [42]; List ga1 /* //# 21: syntax error (List a) */ //# 21: continued => a; Expect.equals(42, ga0()[0]); Expect.equals(87, ga1([87])[0]); } static void testFunctionExpressions /* //# 22: syntax error () */ //# 22: continued { eval0 /* //# 23: syntax error (fn) */ //# 23: continued => fn(); eval1 /* //# 24: syntax error (fn, a) */ //# 24: continued => fn(a); eval2 /* //# 25: syntax error (fn, a, b) */ //# 25: continued => fn(a, b); // No types - braces. Expect.equals(42, eval0( /* //# 26: syntax error () */ //# 26: continued { return 42; })); Expect.equals( 87, eval1( /* //# 27: syntax error (a) */ //# 27: continued { return a; }, 87)); Expect.equals( 1 + 2, eval2( /* //# 28: syntax error (a, b) */ //# 28: continued { return a + b; }, 1, 2)); Expect.equals(42, eval0( /* //# 29: syntax error () */ //# 29: continued { return 42; })); Expect.equals( 87, eval1( /* //# 30: syntax error (a) */ //# 30: continued { return a; }, 87)); Expect.equals( 1 + 2, eval2( /* //# 31: syntax error (a, b) */ //# 31: continued { return a + b; }, 1, 2)); // No types - arrows. Expect.equals( 42, eval0( /* //# 32: syntax error () */ //# 32: continued => 42)); Expect.equals( 87, eval1( /* //# 33: syntax error (a) */ //# 33: continued => a, 87)); Expect.equals( 1 + 2, eval2( /* //# 34: syntax error (a, b) */ //# 34: continued => a + b, 1, 2)); Expect.equals( 42, eval0( /* //# 35: syntax error () */ //# 35: continued => 42)); Expect.equals( 87, eval1( /* //# 36: syntax error (a) */ //# 36: continued => a, 87)); Expect.equals( 1 + 2, eval2( /* //# 37: syntax error (a, b) */ //# 37: continued => a + b, 1, 2)); // Argument types - braces. Expect.equals(42, eval0( /* //# 44: syntax error () */ //# 44: continued { return 42; })); Expect.equals( 87, eval1( /* //# 45: syntax error (int a) */ //# 45: continued { return a; }, 87)); Expect.equals( 1 + 2, eval2( /* //# 46: syntax error (int a, int b) */ //# 46: continued { return a + b; }, 1, 2)); Expect.equals(42, eval0( /* //# 47: syntax error () */ //# 47: continued { return 42; })); Expect.equals( 87, eval1( /* //# 48: syntax error (int a) */ //# 48: continued { return a; }, 87)); Expect.equals( 1 + 2, eval2( /* //# 49: syntax error (int a, int b) */ //# 49: continued { return a + b; }, 1, 2)); // Argument types - arrows. Expect.equals( 42, eval0( /* //# 50: syntax error () */ //# 50: continued => 42)); Expect.equals( 87, eval1( /* //# 51: syntax error (int a) */ //# 51: continued => a, 87)); Expect.equals( 1 + 2, eval2( /* //# 52: syntax error (int a, int b) */ //# 52: continued => a + b, 1, 2)); Expect.equals( 42, eval0( /* //# 53: syntax error () */ //# 53: continued => 42)); Expect.equals( 87, eval1( /* //# 54: syntax error (int a) */ //# 54: continued => a, 87)); Expect.equals( 1 + 2, eval2( /* //# 55: syntax error (int a, int b) */ //# 55: continued => a + b, 1, 2)); } static void testPrecedence /* //# 64: syntax error () */ //# 64: continued { expectEvaluatesTo /* //# 65: syntax error (value, fn) */ //# 65: continued { Expect.equals(value, fn()); } // Assignment. var x; expectEvaluatesTo(42, () => x = 42); Expect.equals(42, x); x = 1; expectEvaluatesTo(100, () => x += 99); Expect.equals(100, x); x = 1; expectEvaluatesTo(87, () => x *= 87); Expect.equals(87, x); // Conditional. expectEvaluatesTo(42, () => true ? 42 : 87); expectEvaluatesTo(87, () => false ? 42 : 87); // Logical or. expectEvaluatesTo(true, () => true || true); expectEvaluatesTo(true, () => true || false); expectEvaluatesTo(true, () => false || true); expectEvaluatesTo(false, () => false || false); // Logical and. expectEvaluatesTo(true, () => true && true); expectEvaluatesTo(false, () => true && false); expectEvaluatesTo(false, () => false && true); expectEvaluatesTo(false, () => false && false); // Bitwise operations. expectEvaluatesTo(3, () => 1 | 2); expectEvaluatesTo(2, () => 3 ^ 1); expectEvaluatesTo(1, () => 3 & 1); // Equality. expectEvaluatesTo(true, () => 1 == 1); expectEvaluatesTo(false, () => 1 != 1); expectEvaluatesTo(true, () => identical(1, 1)); expectEvaluatesTo(false, () => !identical(1, 1)); // Relational. expectEvaluatesTo(true, () => 1 <= 1); expectEvaluatesTo(false, () => 1 < 1); expectEvaluatesTo(false, () => 1 > 1); expectEvaluatesTo(true, () => 1 >= 1); // Is. expectEvaluatesTo(true, () => 1 is int); expectEvaluatesTo(true, () => 1.0 is double); // Shift. expectEvaluatesTo(2, () => 1 << 1); expectEvaluatesTo(1, () => 2 >> 1); // Additive. expectEvaluatesTo(2, () => 1 + 1); expectEvaluatesTo(1, () => 2 - 1); // Multiplicative. expectEvaluatesTo(2, () => 1 * 2); expectEvaluatesTo(2.0, () => 4 / 2); expectEvaluatesTo(2, () => 4 ~/ 2); expectEvaluatesTo(0, () => 4 % 2); // Negate. expectEvaluatesTo(false, () => !true); // Postfix / prefix. var y = 0; expectEvaluatesTo(0, () => y++); expectEvaluatesTo(2, () => ++y); expectEvaluatesTo(1, () => --y); expectEvaluatesTo(1, () => y--); Expect.equals(0, y); // Selector. fn /* //# 66: syntax error () */ //# 66: continued => 42; var list = [87]; expectEvaluatesTo(42, () => fn()); expectEvaluatesTo(1, () => list.length); expectEvaluatesTo(87, () => list[0]); expectEvaluatesTo(87, () => list.removeLast()); } static void testInitializers /* //# 67: syntax error () */ //# 67: continued { Expect.equals(42, (new C.cb0().fn)()); Expect.equals(43, (new C.ca0().fn)()); Expect.equals(44, (new C.cb1().fn)()); Expect.equals(45, (new C.ca1().fn)()); Expect.equals(46, (new C.cb2().fn)()); Expect.equals(47, (new C.ca2().fn)()); Expect.equals(48, (new C.cb3().fn)()); Expect.equals(49, (new C.ca3().fn)()); Expect.equals(52, (new C.nb0().fn)()); Expect.equals(53, (new C.na0().fn)()); Expect.equals(54, (new C.nb1().fn)()); Expect.equals(55, (new C.na1().fn)()); Expect.equals(56, (new C.nb2().fn)()); Expect.equals(57, (new C.na2().fn)()); Expect.equals(58, (new C.nb3().fn)()); Expect.equals(59, (new C.na3().fn)()); Expect.equals(62, (new C.rb0().fn)()); Expect.equals(63, (new C.ra0().fn)()); Expect.equals(64, (new C.rb1().fn)()); Expect.equals(65, (new C.ra1().fn)()); Expect.equals(66, (new C.rb2().fn)()); Expect.equals(67, (new C.ra2().fn)()); Expect.equals(68, (new C.rb3().fn)()); Expect.equals(69, (new C.ra3().fn)()); } static void testFunctionParameter /* //# 68: syntax error () */ //# 68: continued { f0(fn()) => fn(); Expect.equals(42, f0(() => 42)); f1(int fn()) => fn(); Expect.equals(87, f1(() => 87)); f2(fn(a)) => fn(42); Expect.equals(43, f2((a) => a + 1)); f3(fn(int a)) => fn(42); Expect.equals(44, f3((int a) => a + 2)); } static void testFunctionIdentifierExpression /* //# 69: syntax error () */ //# 69: continued { Expect.equals( 87, ( /* //# 70: syntax error () */ //# 70: continued => 87)()); } static void testFunctionIdentifierStatement /* //# 71: syntax error () */ //# 71: continued { function /* //# 72: syntax error () */ //# 72: continued => 42; Expect.equals(42, function()); Expect.equals(true, function is Function); } } class C { C.cb0() : fn = (() { return 42; }) {} C.ca0() : fn = (() => 43) {} C.cb1() : fn = wrap(() { return 44; }) {} C.ca1() : fn = wrap(() => 45) {} C.cb2() : fn = [ () { return 46; } ][0] {} C.ca2() : fn = [() => 47][0] {} C.cb3() : fn = { 'x': () { return 48; } }['x'] {} C.ca3() : fn = {'x': () => 49}['x'] {} C.nb0() : fn = (() { return 52; }) {} C.na0() : fn = (() => 53) {} C.nb1() : fn = wrap(() { return 54; }) {} C.na1() : fn = wrap(() => 55) {} C.nb2() : fn = [ () { return 56; } ][0] {} C.na2() : fn = [() => 57][0] {} C.nb3() : fn = { 'x': () { return 58; } }['x'] {} C.na3() : fn = {'x': () => 59}['x'] {} C.rb0() : fn = (() { return 62; }) {} C.ra0() : fn = (() => 63) {} C.rb1() : fn = wrap(() { return 64; }) {} C.ra1() : fn = wrap(() => 65) {} C.rb2() : fn = [ () { return 66; } ][0] {} C.ra2() : fn = [() => 67][0] {} C.rb3() : fn = { 'x': () { return 68; } }['x'] {} C.ra3() : fn = {'x': () => 69}['x'] {} static wrap /* //# 73: syntax error (fn) */ //# 73: continued { return fn; } final fn; } main /* //# 74: syntax error () */ //# 74: continued { FunctionSyntaxTest.testMain(); }