001 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
002 // for details. All rights reserved. Use of this source code is governed by a
003 // BSD-style license that can be found in the LICENSE file.
004
005 package com.google.dart.compiler.backend.js;
006
007 import com.google.dart.compiler.backend.js.ast.*;
008
009 /**
010 * Determines if a statement at the end of a block requires a semicolon.
011 * <p/>
012 * For example, the following statements require semicolons:<br>
013 * <ul>
014 * <li>if (cond);</li>
015 * <li>while (cond);</li>
016 * </ul>
017 * <p/>
018 * The following do not require semicolons:<br>
019 * <ul>
020 * <li>return 1</li>
021 * <li>do {} while(true)</li>
022 * </ul>
023 */
024 public class JsRequiresSemiVisitor extends JsVisitor {
025 private boolean needsSemicolon;
026
027 private JsRequiresSemiVisitor() {
028 }
029
030 public static boolean exec(JsStatement lastStatement) {
031 JsRequiresSemiVisitor visitor = new JsRequiresSemiVisitor();
032 visitor.accept(lastStatement);
033 return visitor.needsSemicolon;
034 }
035
036 @Override
037 public void visitFor(JsFor x) {
038 if (x.getBody() instanceof JsEmpty) {
039 needsSemicolon = true;
040 }
041 }
042
043 @Override
044 public void visitForIn(JsForIn x) {
045 if (x.getBody() instanceof JsEmpty) {
046 needsSemicolon = true;
047 }
048 }
049
050 @Override
051 public void visitIf(JsIf x) {
052 JsStatement thenStmt = x.getThenStatement();
053 JsStatement elseStmt = x.getElseStatement();
054 JsStatement toCheck = thenStmt;
055 if (elseStmt != null) {
056 toCheck = elseStmt;
057 }
058 if (toCheck instanceof JsEmpty) {
059 needsSemicolon = true;
060 }
061 else {
062 // Must recurse to determine last statement (possible if-else chain).
063 accept(toCheck);
064 }
065 }
066
067 @Override
068 public void visitLabel(JsLabel x) {
069 if (x.getStatement() instanceof JsEmpty) {
070 needsSemicolon = true;
071 }
072 }
073
074 @Override
075 public void visitWhile(JsWhile x) {
076 if (x.getBody() instanceof JsEmpty) {
077 needsSemicolon = true;
078 }
079 }
080 }