OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 package com.google.dart.compiler.backend.js; | |
6 | |
7 import com.google.dart.compiler.backend.js.ast.JsArrayAccess; | |
8 import com.google.dart.compiler.backend.js.ast.JsArrayLiteral; | |
9 import com.google.dart.compiler.backend.js.ast.JsBinaryOperation; | |
10 import com.google.dart.compiler.backend.js.ast.JsConditional; | |
11 import com.google.dart.compiler.backend.js.ast.JsContext; | |
12 import com.google.dart.compiler.backend.js.ast.JsExprStmt; | |
13 import com.google.dart.compiler.backend.js.ast.JsExpression; | |
14 import com.google.dart.compiler.backend.js.ast.JsFunction; | |
15 import com.google.dart.compiler.backend.js.ast.JsInvocation; | |
16 import com.google.dart.compiler.backend.js.ast.JsNameRef; | |
17 import com.google.dart.compiler.backend.js.ast.JsNew; | |
18 import com.google.dart.compiler.backend.js.ast.JsObjectLiteral; | |
19 import com.google.dart.compiler.backend.js.ast.JsPostfixOperation; | |
20 import com.google.dart.compiler.backend.js.ast.JsPrefixOperation; | |
21 import com.google.dart.compiler.backend.js.ast.JsRegExp; | |
22 import com.google.dart.compiler.backend.js.ast.JsVisitor; | |
23 | |
24 /** | |
25 * Determines if an expression statement needs to be surrounded by parentheses. | |
26 * | |
27 * The statement or the left-most expression needs to be surrounded by | |
28 * parentheses if the left-most expression is an object literal or a function | |
29 * object. Function declarations do not need parentheses. | |
30 * | |
31 * For example the following require parentheses:<br> | |
32 * <ul> | |
33 * <li>{ key : 'value'}</li> | |
34 * <li>{ key : 'value'}.key</li> | |
35 * <li>function () {return 1;}()</li> | |
36 * <li>function () {return 1;}.prototype</li> | |
37 * </ul> | |
38 * | |
39 * The following do not require parentheses:<br> | |
40 * <ul> | |
41 * <li>var x = { key : 'value'}</li> | |
42 * <li>"string" + { key : 'value'}.key</li> | |
43 * <li>function func() {}</li> | |
44 * <li>function() {}</li> | |
45 * </ul> | |
46 */ | |
47 public class JsFirstExpressionVisitor extends JsVisitor { | |
48 | |
49 public static boolean exec(JsExprStmt statement) { | |
50 JsFirstExpressionVisitor visitor = new JsFirstExpressionVisitor(); | |
51 JsExpression expression = statement.getExpression(); | |
52 // Pure function declarations do not need parentheses | |
53 if (expression instanceof JsFunction) { | |
54 return false; | |
55 } | |
56 visitor.accept(statement.getExpression()); | |
57 return visitor.needsParentheses; | |
58 } | |
59 | |
60 private boolean needsParentheses = false; | |
61 | |
62 private JsFirstExpressionVisitor() { | |
63 } | |
64 | |
65 @Override | |
66 public boolean visit(JsArrayAccess x, JsContext ctx) { | |
67 accept(x.getArrayExpr()); | |
68 return false; | |
69 } | |
70 | |
71 @Override | |
72 public boolean visit(JsArrayLiteral x, JsContext ctx) { | |
73 return false; | |
74 } | |
75 | |
76 @Override | |
77 public boolean visit(JsBinaryOperation x, JsContext ctx) { | |
78 accept(x.getArg1()); | |
79 return false; | |
80 } | |
81 | |
82 @Override | |
83 public boolean visit(JsConditional x, JsContext ctx) { | |
84 accept(x.getTestExpression()); | |
85 return false; | |
86 } | |
87 | |
88 @Override | |
89 public boolean visit(JsFunction x, JsContext ctx) { | |
90 needsParentheses = true; | |
91 return false; | |
92 } | |
93 | |
94 @Override | |
95 public boolean visit(JsInvocation x, JsContext ctx) { | |
96 accept(x.getQualifier()); | |
97 return false; | |
98 } | |
99 | |
100 @Override | |
101 public boolean visit(JsNameRef x, JsContext ctx) { | |
102 if (!x.isLeaf()) { | |
103 accept(x.getQualifier()); | |
104 } | |
105 return false; | |
106 } | |
107 | |
108 @Override | |
109 public boolean visit(JsNew x, JsContext ctx) { | |
110 return false; | |
111 } | |
112 | |
113 @Override | |
114 public boolean visit(JsObjectLiteral x, JsContext ctx) { | |
115 needsParentheses = true; | |
116 return false; | |
117 } | |
118 | |
119 @Override | |
120 public boolean visit(JsPostfixOperation x, JsContext ctx) { | |
121 accept(x.getArg()); | |
122 return false; | |
123 } | |
124 | |
125 @Override | |
126 public boolean visit(JsPrefixOperation x, JsContext ctx) { | |
127 return false; | |
128 } | |
129 | |
130 @Override | |
131 public boolean visit(JsRegExp x, JsContext ctx) { | |
132 return false; | |
133 } | |
134 } | |
OLD | NEW |