// 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.
// Dart test program to test check that we can parse labels.


class Helper {

  static int ticks;

  // Helper function to prevent endless loops in case labels or
  // break/continue is broken.
  static doAgain() {
    ++ticks;
    if (ticks > 300) {
      // obfuscating man's assert(false)
      Expect.equals(true, false);
    }
    return true;
  }

  static test1() {
    var i = 1;
    while (doAgain()) {
      if (i > 0) break;
      return 0;
    }
    return 111;
  }

  static test2() {
    // Make sure we break out to default label.
    var i = 1;
    L: while (doAgain()) { // unused label
      if (i > 0) break;
      return 0;
    }
    return 111;
  }

  static test3() {
    // Make sure we break out of outer loop.
    var i = 1;
    L: while (doAgain()) {
      while (doAgain()) {
        if (i > 0) break L;
        return 0;
      }
      return 1;
    }
    return 111;
  }

  static test4() {
    // Make sure we break out of inner loop.
    var i = 100;
    L: while (doAgain()) { // unused label
      while (doAgain()) {
        if (i > 0) break;
        return 0;
      }
      return 111;
    }
    return 1;
  }

  static test5() {
    // Make sure we jump to loop condition.
    var i = 10;
    while (i > 0) {
      i--;
      if (true) continue; // without the if the following return is dead code.
      return 0;
    }
    return 111;
  }

  static test6() {
    // Make sure we jump to loop condition.
    L: for (int i = 10; i > 0; i--) { // unreferenced label, should warn
      if (true) continue; // without the if the following return is dead code.
      return 0;
    }
    // Make sure this L does not conflict with previous L.
    var k = 20;
    L: while (doAgain()) {
      L0: while (doAgain()) break L; // unreferenced label L0, should warn
      return 1;
    }
    return 111;
  }

  static test7() {
    // Just weird stuff.
    var i = 10;
    L: do {
      L: while (doAgain()) {
        if (true) break L; // without the if the following line is dead code.
        continue L;
      }
      i = 0;
      continue L;
    } while (i == 10 && doAgain());
    return 111;
  }

  static test8() {
    L: while (false) {
      var L = 33; // OK, shouldn't collide with label.
      if (true) break L;
    }
    return 111;
  }

  static test9() {
    var i = 111;
    L1: if (i == 0) { // unreferenced label, should warn
      return 0;
    }

    L2: while (i == 0) { // unreferenced label, should warn
      return 0;
    }

    L3: // useless label, should warn
      return i;
  }

  // Labels should be allowed on block/if/for/switch/while/do stmts.
  static test10() {
    int i = 111;
    // block
    while (doAgain()) {
      L: {
        while (doAgain()) {
          break L;
        }
        i--;
      }
      break;
    }
    Expect.equals(111, i);

    while(doAgain()) {
      L: if (doAgain()) {  
        while(doAgain()) {
          break L;
        }
        i--;
      }
      break;
    }
    Expect.equals(111, i);

    while(doAgain()) {
      L: for (;doAgain();) {
        while (doAgain()) {
          break L;
        }
        i--;
      }
      break;
    }
    Expect.equals(111, i);

    L: for (i in [111]) {
      while(doAgain()) {
         break L;
       }
       i--;
       break;
    }
    Expect.equals(111, i);

    L: for (var j in [111]) {
       while(doAgain()) {
         break L;
       }
       i--;
      break;
    }
    Expect.equals(111, i);

    while(doAgain()) {
      L: switch (i) {  
        case 111:
        while(doAgain()) {
          break L;
        }
        default:
        i--;
      }
      break;
    }
    Expect.equals(111, i);

    while(doAgain()) {
      L: do {  
        while(doAgain()) {
          break L;
        }
        i--;
      } while (doAgain());
      break;
    }
    Expect.equals(111, i);

    while(doAgain()) {
      L: try {  
        while(doAgain()) {
          break L;
        }
        i--;
      } finally {
      }
      break;
    }
    Expect.equals(111, i);

    return i;
  }

   static test11() {
     // Kind of odd, but is valid and shouldn't be flagged as useless either.
     L: break L;
     return 111;
   }

   static test12() {
     int i = 111;

     // label the inner block on compound stmts
     if (true) L: {
       while (doAgain()) {
         break L;
       }
       i--;
     }
     Expect.equals(111, i);

     // loop will execute each time, but won't execute code below the break
     var forCount = 0;
     for (forCount = 0 ; forCount < 2 ; forCount++) L: {
       while(doAgain()) {
         break L;
       }
       i--;
       break;
     }
     Expect.equals(111, i);
     Expect.equals(forCount, 2);

     for (i in [111]) L: {
       while(doAgain()) {
         break L;
       }
       i--;
       break;
     }
     Expect.equals(111, i);

     for (var j in [111]) L: {
       while(doAgain()) {
         break L;
       }
       i--;
       break;
     }
     Expect.equals(111, i);

     if (false) { 
     } else L: {
       while (doAgain()) {
         break L;
       }
       i--;
     }
     Expect.equals(111, i);

     int whileCount = 0;
     while (whileCount < 2) L: {
        whileCount++;
        while(doAgain()) {
   	  break L;
        }
        i--;
        break;
     }
     Expect.equals(111, i);
     Expect.equals(2, whileCount);

     return i;
   }
}

class LabelTest {
  static testMain() {
    Helper.ticks = 0;
    Expect.equals(111, Helper.test1());
    Expect.equals(111, Helper.test2());
    Expect.equals(111, Helper.test3());
    Expect.equals(111, Helper.test4());
    Expect.equals(111, Helper.test5());
    Expect.equals(111, Helper.test6());
    Expect.equals(111, Helper.test7());
    Expect.equals(111, Helper.test8());
    Expect.equals(111, Helper.test9());
    Expect.equals(111, Helper.test10());
    Expect.equals(111, Helper.test11());
    Expect.equals(111, Helper.test12());
  }
}

main() {
  LabelTest.testMain();
}
