/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.codemodel.internal;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
A block of Java code, which may contain statements and local declarations.
JBlock
contains a large number of factory methods that creates new statements/declarations. Those newly created statements/declarations are inserted into the "current position"
. The position advances one every time you add a new instruction.
/**
* A block of Java code, which may contain statements and local declarations.
*
* <p>
* {@link JBlock} contains a large number of factory methods that creates new
* statements/declarations. Those newly created statements/declarations are
* inserted into the {@link #pos() "current position"}. The position advances
* one every time you add a new instruction.
*/
public final class JBlock implements JGenerable, JStatement {
Declarations and statements contained in this block. Either JStatement
or JDeclaration
. /**
* Declarations and statements contained in this block.
* Either {@link JStatement} or {@link JDeclaration}.
*/
private final List<Object> content = new ArrayList<Object>();
Whether or not this block must be braced and indented
/**
* Whether or not this block must be braced and indented
*/
private boolean bracesRequired = true;
private boolean indentRequired = true;
Current position.
/**
* Current position.
*/
private int pos;
public JBlock() {
this(true,true);
}
public JBlock(boolean bracesRequired, boolean indentRequired) {
this.bracesRequired = bracesRequired;
this.indentRequired = indentRequired;
}
Returns a read-only view of JStatement
s and JDeclaration
in this block. /**
* Returns a read-only view of {@link JStatement}s and {@link JDeclaration}
* in this block.
*/
public List<Object> getContents() {
return Collections.unmodifiableList(content);
}
private <T> T insert( T statementOrDeclaration ) {
content.add(pos,statementOrDeclaration);
pos++;
return statementOrDeclaration;
}
Gets the current position to which new statements will be inserted.
For example if the value is 0, newly created instructions will be
inserted at the very beginning of the block.
See Also: - pos(int)
/**
* Gets the current position to which new statements will be inserted.
*
* For example if the value is 0, newly created instructions will be
* inserted at the very beginning of the block.
*
* @see #pos(int)
*/
public int pos() {
return pos;
}
Sets the current position.
Throws: - IllegalArgumentException –
if the new position value is illegal.
See Also: Returns:
the old value of the current position.
/**
* Sets the current position.
*
* @return
* the old value of the current position.
* @throws IllegalArgumentException
* if the new position value is illegal.
*
* @see #pos()
*/
public int pos(int newPos) {
int r = pos;
if(newPos>content.size() || newPos<0)
throw new IllegalArgumentException();
pos = newPos;
return r;
}
Returns true if this block is empty and does not contain
any statement.
/**
* Returns true if this block is empty and does not contain
* any statement.
*/
public boolean isEmpty() {
return content.isEmpty();
}
Adds a local variable declaration to this block
Params: - type –
JType of the variable
- name –
Name of the variable
Returns: Newly generated JVar
/**
* Adds a local variable declaration to this block
*
* @param type
* JType of the variable
*
* @param name
* Name of the variable
*
* @return Newly generated JVar
*/
public JVar decl(JType type, String name) {
return decl(JMod.NONE, type, name, null);
}
Adds a local variable declaration to this block
Params: - type –
JType of the variable
- name –
Name of the variable
- init –
Initialization expression for this variable. May be null.
Returns: Newly generated JVar
/**
* Adds a local variable declaration to this block
*
* @param type
* JType of the variable
*
* @param name
* Name of the variable
*
* @param init
* Initialization expression for this variable. May be null.
*
* @return Newly generated JVar
*/
public JVar decl(JType type, String name, JExpression init) {
return decl(JMod.NONE, type, name, init);
}
Adds a local variable declaration to this block
Params: - mods –
Modifiers for the variable
- type –
JType of the variable
- name –
Name of the variable
- init –
Initialization expression for this variable. May be null.
Returns: Newly generated JVar
/**
* Adds a local variable declaration to this block
*
* @param mods
* Modifiers for the variable
*
* @param type
* JType of the variable
*
* @param name
* Name of the variable
*
* @param init
* Initialization expression for this variable. May be null.
*
* @return Newly generated JVar
*/
public JVar decl(int mods, JType type, String name, JExpression init) {
JVar v = new JVar(JMods.forVar(mods), type, name, init);
insert(v);
bracesRequired = true;
indentRequired = true;
return v;
}
Creates an assignment statement and adds it to this block.
Params: - lhs –
Assignable variable or field for left hand side of expression
- exp –
Right hand side expression
/**
* Creates an assignment statement and adds it to this block.
*
* @param lhs
* Assignable variable or field for left hand side of expression
*
* @param exp
* Right hand side expression
*/
public JBlock assign(JAssignmentTarget lhs, JExpression exp) {
insert(new JAssignment(lhs, exp));
return this;
}
public JBlock assignPlus(JAssignmentTarget lhs, JExpression exp) {
insert(new JAssignment(lhs, exp, "+"));
return this;
}
Creates an invocation statement and adds it to this block.
Params: - expr –
JExpression evaluating to the class or object upon which
the named method will be invoked
- method –
Name of method to invoke
Returns: Newly generated JInvocation
/**
* Creates an invocation statement and adds it to this block.
*
* @param expr
* JExpression evaluating to the class or object upon which
* the named method will be invoked
*
* @param method
* Name of method to invoke
*
* @return Newly generated JInvocation
*/
public JInvocation invoke(JExpression expr, String method) {
JInvocation i = new JInvocation(expr, method);
insert(i);
return i;
}
Creates an invocation statement and adds it to this block.
Params: - expr –
JExpression evaluating to the class or object upon which
the method will be invoked
- method –
JMethod to invoke
Returns: Newly generated JInvocation
/**
* Creates an invocation statement and adds it to this block.
*
* @param expr
* JExpression evaluating to the class or object upon which
* the method will be invoked
*
* @param method
* JMethod to invoke
*
* @return Newly generated JInvocation
*/
public JInvocation invoke(JExpression expr, JMethod method) {
return insert(new JInvocation(expr, method));
}
Creates a static invocation statement.
/**
* Creates a static invocation statement.
*/
public JInvocation staticInvoke(JClass type, String method) {
return insert(new JInvocation(type, method));
}
Creates an invocation statement and adds it to this block.
Params: - method –
Name of method to invoke
Returns: Newly generated JInvocation
/**
* Creates an invocation statement and adds it to this block.
*
* @param method
* Name of method to invoke
*
* @return Newly generated JInvocation
*/
public JInvocation invoke(String method) {
return insert(new JInvocation((JExpression)null, method));
}
Creates an invocation statement and adds it to this block.
Params: - method –
JMethod to invoke
Returns: Newly generated JInvocation
/**
* Creates an invocation statement and adds it to this block.
*
* @param method
* JMethod to invoke
*
* @return Newly generated JInvocation
*/
public JInvocation invoke(JMethod method) {
return insert(new JInvocation((JExpression)null, method));
}
Adds a statement to this block
Params: - s –
JStatement to be added
Returns: This block
/**
* Adds a statement to this block
*
* @param s
* JStatement to be added
*
* @return This block
*/
public JBlock add(JStatement s) { // ## Needed?
insert(s);
return this;
}
Create an If statement and add it to this block
Params: - expr –
JExpression to be tested to determine branching
Returns: Newly generated conditional statement
/**
* Create an If statement and add it to this block
*
* @param expr
* JExpression to be tested to determine branching
*
* @return Newly generated conditional statement
*/
public JConditional _if(JExpression expr) {
return insert(new JConditional(expr));
}
Create a For statement and add it to this block
Returns: Newly generated For statement
/**
* Create a For statement and add it to this block
*
* @return Newly generated For statement
*/
public JForLoop _for() {
return insert(new JForLoop());
}
Create a While statement and add it to this block
Returns: Newly generated While statement
/**
* Create a While statement and add it to this block
*
* @return Newly generated While statement
*/
public JWhileLoop _while(JExpression test) {
return insert(new JWhileLoop(test));
}
Create a switch/case statement and add it to this block
/**
* Create a switch/case statement and add it to this block
*/
public JSwitch _switch(JExpression test) {
return insert(new JSwitch(test));
}
Create a Do statement and add it to this block
Returns: Newly generated Do statement
/**
* Create a Do statement and add it to this block
*
* @return Newly generated Do statement
*/
public JDoLoop _do(JExpression test) {
return insert(new JDoLoop(test));
}
Create a Try statement and add it to this block
Returns: Newly generated Try statement
/**
* Create a Try statement and add it to this block
*
* @return Newly generated Try statement
*/
public JTryBlock _try() {
return insert(new JTryBlock());
}
Create a return statement and add it to this block
/**
* Create a return statement and add it to this block
*/
public void _return() {
insert(new JReturn(null));
}
Create a return statement and add it to this block
/**
* Create a return statement and add it to this block
*/
public void _return(JExpression exp) {
insert(new JReturn(exp));
}
Create a throw statement and add it to this block
/**
* Create a throw statement and add it to this block
*/
public void _throw(JExpression exp) {
insert(new JThrow(exp));
}
Create a break statement and add it to this block
/**
* Create a break statement and add it to this block
*/
public void _break() {
_break(null);
}
public void _break(JLabel label) {
insert(new JBreak(label));
}
Create a label, which can be referenced from
continue
and break
statements.
/**
* Create a label, which can be referenced from
* <code>continue</code> and <code>break</code> statements.
*/
public JLabel label(String name) {
JLabel l = new JLabel(name);
insert(l);
return l;
}
Create a continue statement and add it to this block
/**
* Create a continue statement and add it to this block
*/
public void _continue(JLabel label) {
insert(new JContinue(label));
}
public void _continue() {
_continue(null);
}
Create a sub-block and add it to this block
/**
* Create a sub-block and add it to this block
*/
public JBlock block() {
JBlock b = new JBlock();
b.bracesRequired = false;
b.indentRequired = false;
return insert(b);
}
Creates a "literal" statement directly.
Specified string is printed as-is.
This is useful as a short-cut.
For example, you can invoke this method as:
directStatement("a=b+c;")
.
/**
* Creates a "literal" statement directly.
*
* <p>
* Specified string is printed as-is.
* This is useful as a short-cut.
*
* <p>
* For example, you can invoke this method as:
* <code>directStatement("a=b+c;")</code>.
*/
public JStatement directStatement(final String source) {
JStatement s = new JStatement() {
public void state(JFormatter f) {
f.p(source).nl();
}
};
add(s);
return s;
}
public void generate(JFormatter f) {
if (bracesRequired)
f.p('{').nl();
if (indentRequired)
f.i();
generateBody(f);
if (indentRequired)
f.o();
if (bracesRequired)
f.p('}');
}
void generateBody(JFormatter f) {
for (Object o : content) {
if (o instanceof JDeclaration)
f.d((JDeclaration) o);
else
f.s((JStatement) o);
}
}
Creates an enhanced For statement based on j2se 1.5 JLS
and add it to this block
Returns: Newly generated enhanced For statement per j2se 1.5
specification
/**
* Creates an enhanced For statement based on j2se 1.5 JLS
* and add it to this block
*
* @return Newly generated enhanced For statement per j2se 1.5
* specification
*/
public JForEach forEach(JType varType, String name, JExpression collection) {
return insert(new JForEach( varType, name, collection));
}
public void state(JFormatter f) {
f.g(this);
if (bracesRequired)
f.nl();
}
}