/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*/
/**
* This is a utility class for managing indentation and other basic
* formatting for PrintWriter.
*/
public final class JFormatter {
/** all classes and ids encountered during the collection mode **/
/** map from short type name to ReferenceList (list of JClass and ids sharing that name) **/
/** set of imported types (including package java types, eventhough we won't generate imports for them) */
private static enum Mode {
/**
* Collect all the type names and identifiers.
* In this mode we don't actually generate anything.
*/
/**
* Print the actual source code.
*/
}
/**
* The current running mode.
* Set to PRINTING so that a casual client can use a formatter just like before.
*/
/**
* Current number of indentation strings to print
*/
private int indentLevel;
/**
* String to be used for each indentation.
* Defaults to four spaces.
*/
/**
* Stream associated with this JFormatter
*/
/**
* Creates a JFormatter.
*
* @param s
* PrintWriter to JFormatter to use.
*
* @param space
* Incremental indentation string, similar to tab value.
*/
pw = s;
indentSpace = space;
//ids = new HashSet<String>();
}
/**
* Creates a formatter with default incremental indentations of
* four spaces.
*/
this(s, " ");
}
/**
* Creates a formatter with default incremental indentations of
* four spaces.
*/
this(new PrintWriter(w));
}
/**
* Closes this formatter.
*/
public void close() {
}
/**
* Returns true if we are in the printing mode,
* where we actually produce text.
*
* The other mode is the "collecting mode'
*/
public boolean isPrinting() {
}
/**
* Decrement the indentation level.
*/
public JFormatter o() {
indentLevel--;
return this;
}
/**
* Increment the indentation level.
*/
public JFormatter i() {
indentLevel++;
return this;
}
if (c1 == ';') return true;
if (c1 == CLOSE_TYPE_ARGS) {
// e.g., "public Foo<Bar> test;"
return false;
return true;
}
if (c2 == '=') return true;
return false;
return true;
}
switch (c2) {
case '{':
case '}':
case '+':
case '>':
case '@':
return true;
default:
}
}
switch (c1) {
case ']':
case ')':
case '}':
case '+':
return true;
default:
return false;
}
}
if (c1 == '(') return false;
return true;
}
return false;
}
private boolean atBeginningOfLine = true;
private void spaceIfNeeded(char c) {
if (atBeginningOfLine) {
for (int i = 0; i < indentLevel; i++)
atBeginningOfLine = false;
}
/**
* Print a char into the stream
*
* @param c the char
*/
public JFormatter p(char c) {
if(c==CLOSE_TYPE_ARGS) {
} else {
spaceIfNeeded(c);
}
lastChar = c;
}
return this;
}
/**
* Print a String into the stream
*
* @param s the String
*/
public JFormatter p(String s) {
}
return this;
}
if(type.isReference()) {
} else {
return g(type);
}
}
/**
* Print a type name.
*
* <p>
* In the collecting mode we use this information to
* decide what types to import and what not to.
*/
switch(mode) {
case PRINTING:
// many of the JTypes in this list are either primitive or belong to package java
// so we don't need a FQCN
} else {
else
}
break;
case COLLECTING:
} else {
}
break;
}
return this;
}
/**
* Print an identifier
*/
switch(mode) {
case PRINTING:
p(id);
break;
case COLLECTING:
// see if there is a type name that collides with this id
return this;
}
}
}
} else {
// not a type, but we need to create a place holder to
// see if there might be a collision with a type
}
break;
}
return this;
}
/**
* Print a new line into the stream
*/
lastChar = 0;
atBeginningOfLine = true;
}
return this;
}
/**
* Cause the JGenerable object to generate source for iteself
*
* @param g the JGenerable object
*/
public JFormatter g(JGenerable g) {
g.generate(this);
return this;
}
/**
* Produces {@link JGenerable}s separated by ','
*/
boolean first = true;
if (!first)
p(',');
g(item);
first = false;
}
}
return this;
}
/**
* Cause the JDeclaration to generate source for itself
*
* @param d the JDeclaration object
*/
public JFormatter d(JDeclaration d) {
d.declare(this);
return this;
}
/**
* Cause the JStatement to generate source for itself
*
* @param s the JStatement object
*/
public JFormatter s(JStatement s) {
s.state(this);
return this;
}
/**
* Cause the JVar to generate source for itself
*
* @param v the JVar object
*/
public JFormatter b(JVar v) {
v.bind(this);
return this;
}
/**
* Generates the whole source code out of the specified class.
*/
// first collect all the types and identifiers
d(c);
// collate type names and identifiers to determine which types can be imported
// add to list of collected types
}
}
// the class itself that we will be generating is always accessible
importedClasses.add(c);
// then print the declaration
nl();
}
// generate import statements
// suppress import statements for primitive types, built-in types,
// types in the root package, and types in
// the same package as the current type
if(!supressImport(clazz, c)) {
if (clazz instanceof JNarrowedClass) {
}
}
}
nl();
d(c);
}
/**
* determine if an import statement should be supressed
*
* @param clazz JType that may or may not have an import
* @param c JType that is the current class being processed
* @return true if an import statement should be suppressed, false otherwise
*/
if (clazz instanceof JNarrowedClass) {
}
if (clazz instanceof JAnonymousClass) {
}
return true;
return true; // no need to explicitly import java.lang classes
// inner classes require an import stmt.
// All other pkg local classes do not need an
// import stmt for ref.
return true; // no need to explicitly import a class into itself
}
}
return false;
}
/**
* Special character token we use to differenciate '>' as an operator and
* '>' as the end of the type arguments. The former uses '>' and it requires
* a preceding whitespace. The latter uses this, and it does not have a preceding
* whitespace.
*/
/**
* Used during the optimization of class imports.
*
* List of {@link JClass}es whose short name is the same.
*
* @author Ryan.Shoemaker@Sun.COM
*/
final class ReferenceList {
/** true if this name is used as an identifier (like a variable name.) **/
private boolean id;
/**
* Returns true if the symbol represented by the short name
* is "importable".
*/
// special case where a generated type collides with a type in package java
// more than one type with the same name
return true;
// an id and (at least one) type with the same name
return true;
if (c instanceof JAnonymousClass) {
c = c._extends();
}
// make sure that there's no other class with this name within the same package
// even if this is the only "String" class we use,
// if the class called "String" is in the same package,
// we still need to import it.
return true; //collision
}
}
return true; // avoid importing inner class to work around 6431987. Also see jaxb issue 166
}
return false;
}
}
return classes;
}
}
/**
* Return true iff this is strictly an id, meaning that there
* are no collisions with type names.
*/
public boolean isId() {
}
}
}