001: /*
002: * The contents of this file are subject to the terms
003: * of the Common Development and Distribution License
004: * (the "License"). You may not use this file except
005: * in compliance with the License.
006: *
007: * You can obtain a copy of the license at
008: * https://jwsdp.dev.java.net/CDDLv1.0.html
009: * See the License for the specific language governing
010: * permissions and limitations under the License.
011: *
012: * When distributing Covered Code, include this CDDL
013: * HEADER in each file and include the License file at
014: * https://jwsdp.dev.java.net/CDDLv1.0.html If applicable,
015: * add the following below this CDDL HEADER, with the
016: * fields enclosed by brackets "[]" replaced with your
017: * own identifying information: Portions Copyright [yyyy]
018: * [name of copyright owner]
019: */
020:
021: package com.sun.codemodel;
022:
023: /**
024: * Factory methods that generate various {@link JExpression}s.
025: */
026: public abstract class JExpr {
027:
028: /**
029: * This class is not instanciable.
030: */
031: private JExpr() {
032: }
033:
034: public static JExpression assign(JAssignmentTarget lhs,
035: JExpression rhs) {
036: return new JAssignment(lhs, rhs);
037: }
038:
039: public static JExpression assignPlus(JAssignmentTarget lhs,
040: JExpression rhs) {
041: return new JAssignment(lhs, rhs, "+");
042: }
043:
044: public static JInvocation _new(JClass c) {
045: return new JInvocation(c);
046: }
047:
048: public static JInvocation _new(JType t) {
049: return new JInvocation(t);
050: }
051:
052: public static JInvocation invoke(String method) {
053: return new JInvocation((JExpression) null, method);
054: }
055:
056: public static JInvocation invoke(JMethod method) {
057: return new JInvocation((JExpression) null, method);
058: }
059:
060: public static JInvocation invoke(JExpression lhs, JMethod method) {
061: return new JInvocation(lhs, method);
062: }
063:
064: public static JInvocation invoke(JExpression lhs, String method) {
065: return new JInvocation(lhs, method);
066: }
067:
068: public static JFieldRef ref(String field) {
069: return new JFieldRef((JExpression) null, field);
070: }
071:
072: public static JFieldRef ref(JExpression lhs, JVar field) {
073: return new JFieldRef(lhs, field);
074: }
075:
076: public static JFieldRef ref(JExpression lhs, String field) {
077: return new JFieldRef(lhs, field);
078: }
079:
080: public static JFieldRef refthis (String field) {
081: return new JFieldRef(null, field, true);
082: }
083:
084: public static JExpression dotclass(final JClass cl) {
085: return new JExpressionImpl() {
086: public void generate(JFormatter f) {
087: JClass c;
088: if (cl instanceof JNarrowedClass)
089: c = ((JNarrowedClass) cl).basis;
090: else
091: c = cl;
092: f.g(c).p(".class");
093: }
094: };
095: }
096:
097: public static JArrayCompRef component(JExpression lhs,
098: JExpression index) {
099: return new JArrayCompRef(lhs, index);
100: }
101:
102: public static JCast cast(JType type, JExpression expr) {
103: return new JCast(type, expr);
104: }
105:
106: public static JArray newArray(JType type) {
107: return newArray(type, null);
108: }
109:
110: /**
111: * Generates {@code new T[size]}.
112: *
113: * @param type
114: * The type of the array component. 'T' or {@code new T[size]}.
115: */
116: public static JArray newArray(JType type, JExpression size) {
117: // you cannot create an array whose component type is a generic
118: return new JArray(type.erasure(), size);
119: }
120:
121: /**
122: * Generates {@code new T[size]}.
123: *
124: * @param type
125: * The type of the array component. 'T' or {@code new T[size]}.
126: */
127: public static JArray newArray(JType type, int size) {
128: return newArray(type, lit(size));
129: }
130:
131: private static final JExpression __this = new JAtom("this");
132:
133: /**
134: * Returns a reference to "this", an implicit reference
135: * to the current object.
136: */
137: public static JExpression _this () {
138: return __this ;
139: }
140:
141: private static final JExpression __super = new JAtom("super");
142:
143: /**
144: * Returns a reference to "super", an implicit reference
145: * to the super class.
146: */
147: public static JExpression _super () {
148: return __super ;
149: }
150:
151: /* -- Literals -- */
152:
153: private static final JExpression __null = new JAtom("null");
154:
155: public static JExpression _null() {
156: return __null;
157: }
158:
159: /**
160: * Boolean constant that represents <code>true</code>
161: */
162: public static final JExpression TRUE = new JAtom("true");
163:
164: /**
165: * Boolean constant that represents <code>false</code>
166: */
167: public static final JExpression FALSE = new JAtom("false");
168:
169: public static JExpression lit(boolean b) {
170: return b ? TRUE : FALSE;
171: }
172:
173: public static JExpression lit(int n) {
174: return new JAtom(Integer.toString(n));
175: }
176:
177: public static JExpression lit(long n) {
178: return new JAtom(Long.toString(n) + "L");
179: }
180:
181: public static JExpression lit(float f) {
182: return new JAtom(Float.toString(f) + "F");
183: }
184:
185: public static JExpression lit(double d) {
186: return new JAtom(Double.toString(d) + "D");
187: }
188:
189: static final String charEscape = "\b\t\n\f\r\"\'\\";
190: static final String charMacro = "btnfr\"'\\";
191:
192: /**
193: * Escapes the given string, then surrounds it by the specified
194: * quotation mark.
195: */
196: public static String quotify(char quote, String s) {
197: int n = s.length();
198: StringBuilder sb = new StringBuilder(n + 2);
199: sb.append(quote);
200: for (int i = 0; i < n; i++) {
201: char c = s.charAt(i);
202: int j = charEscape.indexOf(c);
203: if (j >= 0) {
204: sb.append('\\');
205: sb.append(charMacro.charAt(j));
206: } else {
207: // technically Unicode escape shouldn't be done here,
208: // for it's a lexical level handling.
209: //
210: // However, various tools are so broken around this area,
211: // so just to be on the safe side, it's better to do
212: // the escaping here (regardless of the actual file encoding)
213: //
214: // see bug
215: if (c < 0x20 || 0x7E < c) {
216: // not printable. use Unicode escape
217: sb.append("\\u");
218: String hex = Integer
219: .toHexString(((int) c) & 0xFFFF);
220: for (int k = hex.length(); k < 4; k++)
221: sb.append('0');
222: sb.append(hex);
223: } else {
224: sb.append(c);
225: }
226: }
227: }
228: sb.append(quote);
229: return sb.toString();
230: }
231:
232: public static JExpression lit(char c) {
233: return new JAtom(quotify('\'', "" + c));
234: }
235:
236: public static JExpression lit(String s) {
237: return new JStringLiteral(s);
238: }
239:
240: /**
241: * Creates an expression directly from a source code fragment.
242: *
243: * <p>
244: * This method can be used as a short-cut to create a JExpression.
245: * For example, instead of <code>_a.gt(_b)</code>, you can write
246: * it as: <code>JExpr.direct("a>b")</code>.
247: *
248: * <p>
249: * Be warned that there is a danger in using this method,
250: * as it obfuscates the object model.
251: */
252: public static JExpression direct(final String source) {
253: return new JExpressionImpl() {
254: public void generate(JFormatter f) {
255: f.p('(').p(source).p(')');
256: }
257: };
258: }
259: }
|