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 }