diff --git a/.gitignore b/.gitignore
index f5f547c..ed0737b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -243,3 +243,7 @@
/trunk/codemodel/codemodel-annotation-compiler/target
/trunk/codemodel/codemodel-annotation-compiler/velocity.log
/trunk/codemodel/codemodel-annotation-compiler/*.iml
+
+.gradle/
+codemodel/build/
+codemodel/target/
diff --git a/build.gradle b/build.gradle
index 3f428a3..e95ad98 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,7 +2,7 @@ allprojects {
apply plugin: 'maven'
group = 'com.unquietcode.tools.jcodemodel'
- version = '1.0.2'
+ version = '1.0.2-SNAPSHOT'
}
subprojects {
diff --git a/codemodel-annotation-compiler/pom.xml b/codemodel-annotation-compiler/pom.xml
index 38588cd..28b1378 100644
--- a/codemodel-annotation-compiler/pom.xml
+++ b/codemodel-annotation-compiler/pom.xml
@@ -44,20 +44,20 @@
4.0.0unquietcode.tools.jcodemodelcodemodel-annotation-compiler
- 1.0.2
+ 1.0.2-SNAPSHOTCodemodel Annotation CompilerThe annotation compiler ant task for the CodeModel java source code generation libraryunquietcode.tools.jcodemodelcodemodel-project
- 1.0.2
+ 1.0.2-SNAPSHOT../pom.xmlunquietcode.tools.jcodemodelcodemodel
- 1.0.2
+ 1.0.2-SNAPSHOTcom.sun.istack
diff --git a/codemodel/build.gradle b/codemodel/build.gradle
index a460734..238e630 100644
--- a/codemodel/build.gradle
+++ b/codemodel/build.gradle
@@ -28,14 +28,14 @@ artifacts {
uploadArchives {
repositories {
mavenDeployer {
- beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
+ //beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
- authentication(userName: ossrhUsername, password: ossrhPassword)
+ authentication(userName: hasProperty('ossrhUsername')?ossrhUsername:'', password: hasProperty('ossrhPassword')?ossrhPassword:'')
}
snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") {
- authentication(userName: ossrhUsername, password: ossrhPassword)
+ authentication(userName: hasProperty('ossrhUsername')?ossrhUsername:'', password: hasProperty('ossrhPassword')?ossrhPassword:'')
}
pom.project {
@@ -70,6 +70,6 @@ uploadArchives {
}
}
-signing {
- sign configurations.archives
-}
\ No newline at end of file
+//signing {
+// sign configurations.archives
+//}
\ No newline at end of file
diff --git a/codemodel/pom.xml b/codemodel/pom.xml
index ffa326a..18bba66 100644
--- a/codemodel/pom.xml
+++ b/codemodel/pom.xml
@@ -45,7 +45,7 @@
unquietcode.tools.jcodemodelcodemodel-project
- 1.0.2
+ 1.0.2-SNAPSHOT../pom.xml
diff --git a/codemodel/src/main/java/com/sun/codemodel/JAnnotationUse.java b/codemodel/src/main/java/com/sun/codemodel/JAnnotationUse.java
index bccd8b6..0665c82 100644
--- a/codemodel/src/main/java/com/sun/codemodel/JAnnotationUse.java
+++ b/codemodel/src/main/java/com/sun/codemodel/JAnnotationUse.java
@@ -306,10 +306,10 @@ public JAnnotationUse param(String name, JEnumConstant value){
* This can be used for e.g to specify
*
* @XmlCollectionItem(type=Integer.class);
- *
- * For adding a value of Class extends Annotation>
- * @link
- * #annotationParam(java.lang.String, java.lang.Class extends java.lang.annotation.Annotation>)
+ *
+ * For adding a value of {@code Class extends Annotation>}
+ * {@link
+ * #annotationParam(java.lang.String, java.lang.Class)}
* @param name
* The simple name for this annotation param
*
diff --git a/codemodel/src/main/java/com/sun/codemodel/JArray.java b/codemodel/src/main/java/com/sun/codemodel/JArray.java
index abb2a43..c75fb19 100644
--- a/codemodel/src/main/java/com/sun/codemodel/JArray.java
+++ b/codemodel/src/main/java/com/sun/codemodel/JArray.java
@@ -37,66 +37,84 @@
* only if the new code is made subject to such option by the copyright
* holder.
*/
-
package com.sun.codemodel;
import java.util.ArrayList;
import java.util.List;
-
/**
* array creation and initialization.
*/
public final class JArray extends JExpressionImpl {
private final JType type;
- private final JExpression size;
+ private final List sizes = new ArrayList();
private List exprs = null;
/**
* Add an element to the array initializer
+ * @param e
+ * @return
*/
public JArray add(JExpression e) {
- if (exprs == null)
+ if (exprs == null) {
exprs = new ArrayList();
+ }
exprs.add(e);
return this;
}
+ public JArray addSize(JExpression e) {
+ if (e != null) {
+ sizes.add(e);
+ }
+ return this;
+ }
+
JArray(JType type, JExpression size) {
this.type = type;
- this.size = size;
+ if (size != null) {
+ sizes.add(size);
+ }
}
public void generate(JFormatter f) {
-
+
// generally we produce new T[x], but when T is an array type (T=T'[])
// then new T'[][x] is wrong. It has to be new T'[x][].
int arrayCount = 0;
JType t = type;
-
- while( t.isArray() ) {
+
+ while (t.isArray()) {
t = t.elementType();
arrayCount++;
}
- f.p("new").g(t).p('[');
- if (size != null)
- f.g(size);
- f.p(']');
-
- for( int i=0; i bindings) {
return new JArrayClass(owner(),c);
}
+ @Override
+ public JClass inner(String name) {
+ return null;
+ }
+
}
diff --git a/codemodel/src/main/java/com/sun/codemodel/JBlock.java b/codemodel/src/main/java/com/sun/codemodel/JBlock.java
index 2ac9b27..a0ea793 100644
--- a/codemodel/src/main/java/com/sun/codemodel/JBlock.java
+++ b/codemodel/src/main/java/com/sun/codemodel/JBlock.java
@@ -41,8 +41,8 @@
package com.sun.codemodel;
import java.util.ArrayList;
-import java.util.List;
import java.util.Collections;
+import java.util.List;
/**
* A block of Java code, which may contain statements and local declarations.
@@ -66,6 +66,7 @@ public final class JBlock implements JGenerable, JStatement {
*/
private boolean bracesRequired = true;
private boolean indentRequired = true;
+ private boolean newlineRequired = true;
/**
* Current position.
@@ -73,12 +74,21 @@ public final class JBlock implements JGenerable, JStatement {
private int pos;
public JBlock() {
- this(true,true);
+ this(true, true, true);
}
public JBlock(boolean bracesRequired, boolean indentRequired) {
+ this(bracesRequired, indentRequired, true);
+ }
+
+ public JBlock(boolean bracesRequired, boolean indentRequired, boolean newlineRequired) {
this.bracesRequired = bracesRequired;
this.indentRequired = indentRequired;
+ this.newlineRequired = newlineRequired;
+ }
+
+ public void setNewlineRequired(boolean val) {
+ this.newlineRequired = val;
}
/**
@@ -402,10 +412,17 @@ public void _continue() {
*/
public JBlock block() {
JBlock b = new JBlock();
- b.bracesRequired = false;
- b.indentRequired = false;
+ // why false? of course they are both required
+// b.bracesRequired = false;
+// b.indentRequired = false;
return insert(b);
}
+
+ public JSynchronized _synchronized(JExpression lock) {
+ JSynchronized syn = new JSynchronized(lock);
+ insert(syn);
+ return syn;
+ }
/**
* Creates a "literal" statement directly.
@@ -462,7 +479,7 @@ public JForEach forEach(JType varType, String name, JExpression collection) {
}
public void state(JFormatter f) {
f.g(this);
- if (bracesRequired)
+ if (newlineRequired)
f.nl();
}
diff --git a/codemodel/src/main/java/com/sun/codemodel/JCatchBlock.java b/codemodel/src/main/java/com/sun/codemodel/JCatchBlock.java
index 8053e11..62be8a8 100644
--- a/codemodel/src/main/java/com/sun/codemodel/JCatchBlock.java
+++ b/codemodel/src/main/java/com/sun/codemodel/JCatchBlock.java
@@ -45,15 +45,18 @@
* Catch block for a try/catch/finally statement
*/
-public class JCatchBlock implements JGenerable {
+public class JCatchBlock implements JTryBlock.CatchBlock {
JClass exception;
private JVar var = null;
private JBlock body = new JBlock();
+ private boolean isMulti = false;
JCatchBlock(JClass exception) {
this.exception = exception;
}
+
+
public JVar param(String name) {
if (var != null) throw new IllegalStateException();
diff --git a/codemodel/src/main/java/com/sun/codemodel/JClass.java b/codemodel/src/main/java/com/sun/codemodel/JClass.java
index 954a9ef..54b0f1f 100644
--- a/codemodel/src/main/java/com/sun/codemodel/JClass.java
+++ b/codemodel/src/main/java/com/sun/codemodel/JClass.java
@@ -37,7 +37,6 @@
* only if the new code is made subject to such option by the copyright
* holder.
*/
-
package com.sun.codemodel;
import java.util.ArrayList;
@@ -49,14 +48,15 @@
/**
* Represents a Java reference type, such as a class, an interface,
* an enum, an array type, a parameterized type.
- *
+ *
*
* To be exact, this object represents an "use" of a reference type,
- * not necessarily a declaration of it, which is modeled as {@link JDefinedClass}.
+ * not necessarily a declaration of it, which is modeled as
+ * {@link JDefinedClass}.
*/
-public abstract class JClass extends JType
-{
- protected JClass( JCodeModel _owner ) {
+public abstract class JClass extends JType {
+
+ protected JClass(JCodeModel _owner) {
this._owner = _owner;
}
@@ -64,13 +64,13 @@ protected JClass( JCodeModel _owner ) {
* Gets the name of this class.
*
* @return
- * name of this class, without any qualification.
- * For example, this method returns "String" for
- * java.lang.String.
+ * name of this class, without any qualification.
+ * For example, this method returns "String" for
+ * java.lang.String.
*/
abstract public String name();
-
- /**
+
+ /**
* Gets the package to which this class belongs.
* TODO: shall we move move this down?
*/
@@ -83,41 +83,48 @@ protected JClass( JCodeModel _owner ) {
public JClass outer() {
return null;
}
-
- private final JCodeModel _owner;
- /** Gets the JCodeModel object to which this object belongs. */
- public final JCodeModel owner() { return _owner; }
+ public abstract JClass inner(String name);
+
+ private final JCodeModel _owner;
+
+ /**
+ * Gets the JCodeModel object to which this object belongs.
+ */
+ public final JCodeModel owner() {
+ return _owner;
+ }
+
/**
* Gets the super class of this class.
- *
+ *
* @return
- * Returns the JClass representing the superclass of the
- * entity (class or interface) represented by this {@link JClass}.
- * Even if no super class is given explicitly or this {@link JClass}
- * is not a class, this method still returns
- * {@link JClass} for {@link Object}.
- * If this JClass represents {@link Object}, return null.
+ * Returns the JClass representing the superclass of the
+ * entity (class or interface) represented by this {@link JClass}.
+ * Even if no super class is given explicitly or this {@link JClass}
+ * is not a class, this method still returns
+ * {@link JClass} for {@link Object}.
+ * If this JClass represents {@link Object}, return null.
*/
abstract public JClass _extends();
-
+
/**
* Iterates all super interfaces directly implemented by
* this class/interface.
- *
+ *
* @return
- * A non-null valid iterator that iterates all
- * {@link JClass} objects that represents those interfaces
- * implemented by this object.
+ * A non-null valid iterator that iterates all
+ * {@link JClass} objects that represents those interfaces
+ * implemented by this object.
*/
abstract public Iterator _implements();
-
+
/**
* Iterates all the type parameters of this class/interface.
- *
*
- * For example, if this {@link JClass} represents
- * Set<T>, this method returns an array
+ *
+ * For example, if this {@link JClass} represents
+ * Set<T>, this method returns an array
* that contains single {@link JTypeVar} for 'T'.
*/
public JTypeVar[] typeParams() {
@@ -144,18 +151,22 @@ public JTypeVar[] typeParams() {
* defined in the java.lang package, return the corresponding
* primitive type. Otherwise null.
*/
- public JPrimitiveType getPrimitiveType() { return null; }
+ public JPrimitiveType getPrimitiveType() {
+ return null;
+ }
/**
* @deprecated calling this method from {@link JClass}
* would be meaningless, since it's always guaranteed to
* return this.
*/
- public JClass boxify() { return this; }
+ public JClass boxify() {
+ return this;
+ }
public JType unboxify() {
JPrimitiveType pt = getPrimitiveType();
- return pt==null ? (JType)this : pt;
+ return pt == null ? (JType) this : pt;
}
public JClass erasure() {
@@ -165,32 +176,42 @@ public JClass erasure() {
/**
* Checks the relationship between two classes.
*
- * This method works in the same way as {@link Class#isAssignableFrom(Class)}
+ * This method works in the same way as
+ * {@link Class#isAssignableFrom(Class)}
* works. For example, baseClass.isAssignableFrom(derivedClass)==true.
*/
- public final boolean isAssignableFrom( JClass derived ) {
+ public final boolean isAssignableFrom(JClass derived) {
// to avoid the confusion, always use "this" explicitly in this method.
-
+
// null can be assigned to any type.
- if( derived instanceof JNullType ) return true;
-
- if( this==derived ) return true;
-
+ if (derived instanceof JNullType) {
+ return true;
+ }
+
+ if (this == derived) {
+ return true;
+ }
+
// the only class that is assignable from an interface is
// java.lang.Object
- if( this==_package().owner().ref(Object.class) ) return true;
-
+ if (this == _package().owner().ref(Object.class)) {
+ return true;
+ }
+
JClass b = derived._extends();
- if( b!=null && this.isAssignableFrom(b) )
+ if (b != null && this.isAssignableFrom(b)) {
return true;
-
- if( this.isInterface() ) {
+ }
+
+ if (this.isInterface()) {
Iterator itfs = derived._implements();
- while( itfs.hasNext() )
- if( this.isAssignableFrom(itfs.next()) )
+ while (itfs.hasNext()) {
+ if (this.isAssignableFrom(itfs.next())) {
return true;
+ }
+ }
}
-
+
return false;
}
@@ -199,101 +220,114 @@ public final boolean isAssignableFrom( JClass derived ) {
*
*
+ * {@code
* getBaseClass( Bar, List ) = List
* getBaseClass( Bar, Foo ) = Foo
* getBaseClass( Foo extends Number>, Collection ) = Collection>
* getBaseClass( ArrayList extends BigInteger>, List ) = List extends BigInteger>
- *
+ * }
*
* @param baseType
- * The class whose parameterization we are interested in.
+ * The class whose parameterization we are interested in.
* @return
- * The use of {@code baseType} in {@code this} type.
- * or null if the type is not assignable to the base type.
+ * The use of {@code baseType} in {@code this} type.
+ * or null if the type is not assignable to the base type.
*/
- public final JClass getBaseClass( JClass baseType ) {
+ public final JClass getBaseClass(JClass baseType) {
- if( this.erasure().equals(baseType) )
+ if (this.erasure().equals(baseType)) {
return this;
+ }
JClass b = _extends();
- if( b!=null ) {
+ if (b != null) {
JClass bc = b.getBaseClass(baseType);
- if(bc!=null)
+ if (bc != null) {
return bc;
+ }
}
Iterator itfs = _implements();
- while( itfs.hasNext() ) {
+ while (itfs.hasNext()) {
JClass bc = itfs.next().getBaseClass(baseType);
- if(bc!=null)
+ if (bc != null) {
return bc;
+ }
}
return null;
}
- public final JClass getBaseClass( Class> baseType ) {
+ public final JClass getBaseClass(Class> baseType) {
return getBaseClass(owner().ref(baseType));
}
-
private JClass arrayClass;
+
public JClass array() {
- if(arrayClass==null)
- arrayClass = new JArrayClass(owner(),this);
+ if (arrayClass == null) {
+ arrayClass = new JArrayClass(owner(), this);
+ }
return arrayClass;
}
/**
* "Narrows" a generic class to a concrete class by specifying
* a type argument.
- *
*
- * .narrow(X) builds Set<X> from Set.
+ *
+ * .narrow(X) builds Set<X> from
+ * Set.
*/
- public JClass narrow( Class> clazz ) {
+ public JClass narrow(Class> clazz) {
return narrow(owner().ref(clazz));
}
- public JClass narrow( Class>... clazz ) {
+ public JClass narrow(Class>... clazz) {
JClass[] r = new JClass[clazz.length];
- for( int i=0; i
- * .narrow(X) builds Set<X> from Set.
+ *
+ * .narrow(X) builds Set<X> from
+ * Set.
*/
- public JClass narrow( JClass clazz ) {
- return new JNarrowedClass(this,clazz);
+ public JClass narrow(JClass clazz) {
+ return new JNarrowedClass(this, clazz);
}
- public JClass narrow( JType type ) {
+ public JClass narrow(JType type) {
return narrow(type.boxify());
}
- public JClass narrow( JClass... clazz ) {
- return new JNarrowedClass(this,Arrays.asList(clazz.clone()));
+ public JClass narrow(JClass... clazz) {
+ return new JNarrowedClass(this, Arrays.asList(clazz.clone()));
}
- public JClass narrow( List extends JClass> clazz ) {
- return new JNarrowedClass(this,new ArrayList(clazz));
+ public JClass narrow(List extends JClass> clazz) {
+ return new JNarrowedClass(this, new ArrayList(clazz));
+ }
+
+ public JClass narrowDiamond() {
+ return new JNarrowedClass(this);
}
/**
- * If this class is parameterized, return the type parameter of the given index.
+ * If this class is parameterized, return the type parameter of the given
+ * index.
*/
public List getTypeParameters() {
return Collections.emptyList();
@@ -303,7 +337,7 @@ public List getTypeParameters() {
* Returns true if this class is a parameterized class.
*/
public final boolean isParameterized() {
- return erasure()!=this;
+ return erasure() != this;
}
/**
@@ -315,45 +349,61 @@ public final JClass wildcard() {
return new JTypeWildcard(this);
}
+ /**
+ * Create "? super T" from T
+ *
+ * @return never null
+ */
+ public final JClass superWildcard() {
+ return new JTypeWildcard(this, true);
+ }
+
/**
* Substitutes the type variables with their actual arguments.
- *
*
- * For example, when this class is Map<String,Map<V>>,
+ *
+ * For example, when this class is {@code Map>},
* (where V then doing
* substituteParams( V, Integer ) returns a {@link JClass}
- * for Map<String,Map<Integer>>.
- *
+ * for {@code Map>}.
+ *
*
* This method needs to work recursively.
*/
- protected abstract JClass substituteParams( JTypeVar[] variables, List bindings );
-
+ protected abstract JClass substituteParams(JTypeVar[] variables, List bindings);
+
public String toString() {
return this.getClass().getName() + '(' + name() + ')';
}
-
public final JExpression dotclass() {
return JExpr.dotclass(this);
}
- /** Generates a static method invocation. */
+ /**
+ * Generates a static method invocation.
+ */
public final JInvocation staticInvoke(JMethod method) {
- return new JInvocation(this,method);
+ return new JInvocation(this, method);
}
-
- /** Generates a static method invocation. */
+
+ /**
+ * Generates a static method invocation.
+ */
public final JInvocation staticInvoke(String method) {
- return new JInvocation(this,method);
+ return new JInvocation(this, method);
}
-
- /** Static field reference. */
+
+ /**
+ * Static field reference.
+ */
public final JFieldRef staticRef(String field) {
return new JFieldRef(this, field);
}
- /** Static field reference. */
+ /**
+ * Static field reference.
+ */
public final JFieldRef staticRef(JVar field) {
return new JFieldRef(this, field);
}
diff --git a/codemodel/src/main/java/com/sun/codemodel/JClassProxy.java b/codemodel/src/main/java/com/sun/codemodel/JClassProxy.java
new file mode 100644
index 0000000..53ec28b
--- /dev/null
+++ b/codemodel/src/main/java/com/sun/codemodel/JClassProxy.java
@@ -0,0 +1,253 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.sun.codemodel;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ *
+ * @author lkroll
+ */
+public class JClassProxy extends JClass {
+
+ private JClass proxee = null;
+ private final Map innerProxies = new HashMap();
+ private final String shortName;
+ private final ClassResolver resolver;
+
+ public JClassProxy(JCodeModel _owner, String shortName, ClassResolver resolver) {
+ super(_owner);
+ this.shortName = shortName;
+ this.resolver = resolver;
+ }
+
+ public boolean isResolved() {
+ return proxee != null;
+ }
+
+ public void assertResolved() {
+ if (proxee == null) {
+ proxee = resolver.resolveClass(shortName);
+ }
+ if (proxee == null) {
+ throw new RuntimeException("Class " + shortName + " could not be resolved using resolver " + resolver);
+ }
+ }
+
+ public void setProxee(JClass clazz) {
+ if (clazz instanceof JClassProxy) {
+ throw new RuntimeException("Building endless proxy hierarchies is not a good idea!");
+ }
+ this.proxee = clazz;
+ }
+
+ @Override
+ public String name() {
+ if (isResolved()) {
+ return proxee.name();
+ } else {
+ return shortName;
+ //throw new UnresolvedClassException(shortName);
+ }
+ }
+
+ @Override
+ public JPackage _package() {
+ assertResolved();
+ if (isResolved()) {
+ return proxee._package();
+ } else {
+ throw new UnresolvedClassException(shortName);
+ }
+ }
+
+ @Override
+ public JClass inner(String name) {
+ if (isResolved()) {
+ return proxee.inner(name);
+ } else {
+ return new JClassProxy(this.owner(), name, new InnerClassResolver(this));
+ }
+ }
+
+ @Override
+ public JClass outer() {
+ assertResolved();
+ if (isResolved()) {
+ return proxee.outer();
+ } else {
+ throw new UnresolvedClassException(shortName);
+ }
+ }
+
+ @Override
+ public JClass _extends() {
+ assertResolved();
+ if (isResolved()) {
+ return proxee._extends();
+ } else {
+ throw new UnresolvedClassException(shortName);
+ }
+ }
+
+ @Override
+ public Iterator _implements() {
+ assertResolved();
+ if (isResolved()) {
+ return proxee._implements();
+ } else {
+ throw new UnresolvedClassException(shortName);
+ }
+ }
+
+ @Override
+ public JTypeVar[] typeParams() {
+ assertResolved();
+ if (isResolved()) {
+ return proxee.typeParams();
+ } else {
+ throw new UnresolvedClassException(shortName);
+ }
+ }
+
+ @Override
+ public boolean isInterface() {
+ assertResolved();
+ if (isResolved()) {
+ return proxee.isInterface();
+ } else {
+ throw new UnresolvedClassException(shortName);
+ }
+ }
+
+ @Override
+ public boolean isAbstract() {
+ assertResolved();
+ if (isResolved()) {
+ return proxee.isAbstract();
+ } else {
+ throw new UnresolvedClassException(shortName);
+ }
+ }
+
+ @Override
+ public JPrimitiveType getPrimitiveType() {
+ assertResolved();
+ if (isResolved()) {
+ return proxee.getPrimitiveType();
+ } else {
+ throw new UnresolvedClassException(shortName);
+ }
+ }
+
+ @Override
+ public JClass erasure() {
+ assertResolved();
+ if (isResolved()) {
+ return proxee.erasure();
+ } else {
+ throw new UnresolvedClassException(shortName);
+ }
+ }
+
+ @Override
+ protected JClass substituteParams(JTypeVar[] variables, List bindings) {
+ assertResolved();
+ if (isResolved()) {
+ return proxee.substituteParams(variables, bindings);
+ } else {
+ throw new UnresolvedClassException(shortName);
+ }
+ }
+
+ @Override
+ public String fullName() {
+ assertResolved();
+ if (isResolved()) {
+ return proxee.fullName();
+ } else {
+ throw new UnresolvedClassException(shortName);
+ }
+ }
+
+ @Override
+ public void generate(JFormatter f) {
+ assertResolved();
+ if (isResolved()) {
+ f.t(proxee);
+ } else {
+ throw new UnresolvedClassException(shortName);
+ }
+ }
+
+ /**
+ * Prints the class name in javadoc @link format.
+ */
+ @Override
+ void printLink(JFormatter f) {
+ assertResolved();
+ if (isResolved()) {
+ f.p("{@link ").g(proxee).p('}');
+ } else {
+ throw new UnresolvedClassException(shortName);
+ }
+
+ }
+
+ public static class UnresolvedClassException extends RuntimeException {
+
+ private final String shortName;
+
+ private UnresolvedClassException(String shortName) {
+ this.shortName = shortName;
+ }
+
+ @Override
+ public String getMessage() {
+ return "Proxied class " + shortName + " has not been resolved, yet";
+ }
+
+ }
+
+ public static interface ClassResolver {
+
+ public JClass resolveClass(String name);
+ }
+
+ private static class InnerClassResolver implements ClassResolver {
+
+ private final JClassProxy outer;
+
+ InnerClassResolver(JClassProxy outer) {
+ this.outer = outer;
+ }
+
+ public JClass resolveClass(String name) {
+ if (!outer.isResolved()) {
+ outer.assertResolved();
+ }
+ System.out.println("Proxee type is: " + outer.proxee);
+ if (outer.proxee instanceof JDefinedClass) {
+ JDefinedClass jdc = (JDefinedClass) outer.proxee;
+ for (Entry e : jdc.getClasses().entrySet()) {
+ JDefinedClass jdcInner = e.getValue();
+ System.out.println(" " + e.getKey() + " --> " + jdcInner.fullName());
+ }
+ }
+ return outer.proxee.inner(name);
+
+ }
+
+ @Override
+ public String toString() {
+ return "InnerClassResolver(" + outer + ")";
+ }
+ }
+}
diff --git a/codemodel/src/main/java/com/sun/codemodel/JCodeModel.java b/codemodel/src/main/java/com/sun/codemodel/JCodeModel.java
index b993858..cf79c60 100644
--- a/codemodel/src/main/java/com/sun/codemodel/JCodeModel.java
+++ b/codemodel/src/main/java/com/sun/codemodel/JCodeModel.java
@@ -37,9 +37,11 @@
* only if the new code is made subject to such option by the copyright
* holder.
*/
-
package com.sun.codemodel;
+import com.sun.codemodel.util.NameUtilities;
+import com.sun.codemodel.writer.FileCodeWriter;
+import com.sun.codemodel.writer.ProgressCodeWriter;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
@@ -51,11 +53,6 @@
import java.util.List;
import java.util.Map;
-import com.sun.codemodel.util.NameUtilities;
-import com.sun.codemodel.writer.FileCodeWriter;
-import com.sun.codemodel.writer.ProgressCodeWriter;
-
-
/**
* Root of the code DOM.
*
@@ -75,74 +72,89 @@
*
*
* Every CodeModel node is always owned by one {@link JCodeModel} object
- * at any given time (which can be often accesesd by the owner() method.)
+ * at any given time (which can be often accesesd by the owner()
+ * method.)
*
* As such, when you generate Java code, most of the operation works
- * in a top-down fashion. For example, you create a class from {@link JCodeModel},
+ * in a top-down fashion. For example, you create a class from
+ * {@link JCodeModel},
* which gives you a {@link JDefinedClass}. Then you invoke a method on it
* to generate a new method, which gives you {@link JMethod}, and so on.
*
- * There are a few exceptions to this, most notably building {@link JExpression}s,
+ * There are a few exceptions to this, most notably building
+ * {@link JExpression}s,
* but generally you work with CodeModel in a top-down fashion.
*
- * Because of this design, most of the CodeModel classes aren't directly instanciable.
+ * Because of this design, most of the CodeModel classes aren't directly
+ * instanciable.
*
*
*
Where to go from here?
*
- * Most of the time you'd want to populate new type definitions in a {@link JCodeModel}.
+ * Most of the time you'd want to populate new type definitions in a
+ * {@link JCodeModel}.
* See {@link #_class(String, ClassType)}.
*/
public final class JCodeModel {
-
- /** The packages that this JCodeWriter contains. */
- private HashMap packages = new HashMap();
-
- /** All JReferencedClasses are pooled here. */
- private final HashMap,JReferencedClass> refClasses = new HashMap,JReferencedClass>();
- /** All JDirectClass are pooled here. */
- private final Map refDirectClasses = new HashMap();
+ /**
+ * The packages that this JCodeWriter contains.
+ */
+ private HashMap packages = new HashMap();
+
+ /**
+ * All JReferencedClasses are pooled here.
+ */
+ private final HashMap, JReferencedClass> refClasses = new HashMap, JReferencedClass>();
- /** Obtains a reference to the special "null" type. */
- public final JNullType NULL = new JNullType(this);
- // primitive types
- public final JPrimitiveType VOID = new JPrimitiveType(this,"void", Void.class);
- public final JPrimitiveType BOOLEAN = new JPrimitiveType(this,"boolean",Boolean.class);
- public final JPrimitiveType BYTE = new JPrimitiveType(this,"byte", Byte.class);
- public final JPrimitiveType SHORT = new JPrimitiveType(this,"short", Short.class);
- public final JPrimitiveType CHAR = new JPrimitiveType(this,"char", Character.class);
- public final JPrimitiveType INT = new JPrimitiveType(this,"int", Integer.class);
- public final JPrimitiveType FLOAT = new JPrimitiveType(this,"float", Float.class);
- public final JPrimitiveType LONG = new JPrimitiveType(this,"long", Long.class);
- public final JPrimitiveType DOUBLE = new JPrimitiveType(this,"double", Double.class);
-
/**
- * If the flag is true, we will consider two classes "Foo" and "foo"
- * as a collision.
+ * All JDirectClass are pooled here.
*/
- protected static final boolean isCaseSensitiveFileSystem = getFileSystemCaseSensitivity();
-
- private static boolean getFileSystemCaseSensitivity() {
- try {
- // let the system property override, in case the user really
- // wants to override.
- if( System.getProperty("com.sun.codemodel.FileSystemCaseSensitive")!=null )
- return true;
- } catch( Exception e ) {}
-
- // on Unix, it's case sensitive.
- return (File.separatorChar == '/');
- }
+ private final Map refDirectClasses = new HashMap();
+ /**
+ * Obtains a reference to the special "null" type.
+ */
+ public final JNullType NULL = new JNullType(this);
+ // primitive types
+ public final JPrimitiveType VOID = new JPrimitiveType(this, "void", Void.class);
+ public final JPrimitiveType BOOLEAN = new JPrimitiveType(this, "boolean", Boolean.class);
+ public final JPrimitiveType BYTE = new JPrimitiveType(this, "byte", Byte.class);
+ public final JPrimitiveType SHORT = new JPrimitiveType(this, "short", Short.class);
+ public final JPrimitiveType CHAR = new JPrimitiveType(this, "char", Character.class);
+ public final JPrimitiveType INT = new JPrimitiveType(this, "int", Integer.class);
+ public final JPrimitiveType FLOAT = new JPrimitiveType(this, "float", Float.class);
+ public final JPrimitiveType LONG = new JPrimitiveType(this, "long", Long.class);
+ public final JPrimitiveType DOUBLE = new JPrimitiveType(this, "double", Double.class);
+//
+// /**
+// * If the flag is true, we will consider two classes "Foo" and "foo"
+// * as a collision.
+// */
+// protected static final boolean isCaseSensitiveFileSystem = getFileSystemCaseSensitivity();
+
+// private static boolean getFileSystemCaseSensitivity() {
+// try {
+// // let the system property override, in case the user really
+// // wants to override.
+// if (System.getProperty("com.sun.codemodel.FileSystemCaseSensitive") != null) {
+// return true;
+// }
+// } catch (Exception e) {
+// }
+//
+// // on Unix, it's case sensitive.
+// return (File.separatorChar == '/');
+// }
+
+ public JCodeModel() {
+ }
- public JCodeModel() {}
-
/**
* Add a package to the list of packages to be generated
*
* @param name
- * Name of the package. Use "" to indicate the root package.
+ * Name of the package. Use "" to indicate the root package.
*
* @return Newly generated package
*/
@@ -154,7 +166,7 @@ public JPackage _package(String name) {
}
return p;
}
-
+
public final JPackage rootPackage() {
return _package("");
}
@@ -166,73 +178,79 @@ public final JPackage rootPackage() {
public Iterator packages() {
return packages.values().iterator();
}
-
+
/**
* Creates a new generated class.
- *
+ *
* @exception JClassAlreadyExistsException
- * When the specified class/interface was already created.
+ * When the specified class/interface was already created.
*/
public JDefinedClass _class(String fullyqualifiedName) throws JClassAlreadyExistsException {
- return _class(fullyqualifiedName,ClassType.CLASS);
+ return _class(fullyqualifiedName, ClassType.CLASS);
}
/**
* Creates a dummy, unknown {@link JClass} that represents a given name.
*
*
- * This method is useful when the code generation needs to include the user-specified
- * class that may or may not exist, and only thing known about it is a class name.
+ * This method is useful when the code generation needs to include the
+ * user-specified
+ * class that may or may not exist, and only thing known about it is a class
+ * name.
*/
public JClass directClass(String name) {
- return new JDirectClass(this,name);
+ return new JDirectClass(this, name);
}
/**
* Creates a new generated class.
*
* @exception JClassAlreadyExistsException
- * When the specified class/interface was already created.
+ * When the specified class/interface was already created.
*/
- public JDefinedClass _class(int mods, String fullyqualifiedName,ClassType t) throws JClassAlreadyExistsException {
+ public JDefinedClass _class(int mods, String fullyqualifiedName, ClassType t) throws JClassAlreadyExistsException {
int idx = fullyqualifiedName.lastIndexOf('.');
- if( idx<0 ) return rootPackage()._class(fullyqualifiedName);
- else
- return _package(fullyqualifiedName.substring(0,idx))
- ._class(mods, fullyqualifiedName.substring(idx+1), t );
+ if (idx < 0) {
+ return rootPackage()._class(fullyqualifiedName);
+ } else {
+ return _package(fullyqualifiedName.substring(0, idx))
+ ._class(mods, fullyqualifiedName.substring(idx + 1), t);
+ }
}
/**
* Creates a new generated class.
*
* @exception JClassAlreadyExistsException
- * When the specified class/interface was already created.
+ * When the specified class/interface was already created.
*/
- public JDefinedClass _class(String fullyqualifiedName,ClassType t) throws JClassAlreadyExistsException {
- return _class( JMod.PUBLIC, fullyqualifiedName, t );
+ public JDefinedClass _class(String fullyqualifiedName, ClassType t) throws JClassAlreadyExistsException {
+ return _class(JMod.PUBLIC, fullyqualifiedName, t);
}
/**
* Gets a reference to the already created generated class.
- *
+ *
* @return null
- * If the class is not yet created.
+ * If the class is not yet created.
* @see JPackage#_getClass(String)
*/
public JDefinedClass _getClass(String fullyQualifiedName) {
int idx = fullyQualifiedName.lastIndexOf('.');
- if( idx<0 ) return rootPackage()._getClass(fullyQualifiedName);
- else
- return _package(fullyQualifiedName.substring(0,idx))
- ._getClass( fullyQualifiedName.substring(idx+1) );
+ if (idx < 0) {
+ return rootPackage()._getClass(fullyQualifiedName);
+ } else {
+ return _package(fullyQualifiedName.substring(0, idx))
+ ._getClass(fullyQualifiedName.substring(idx + 1));
+ }
}
/**
* Creates a new anonymous class.
- *
+ *
* @deprecated
- * The naming convention doesn't match the rest of the CodeModel.
- * Use {@link #anonymousClass(JClass)} instead.
+ * The naming convention doesn't match the rest of the CodeModel.
+ * Use {@link #anonymousClass(JClass)} instead.
*/
public JDefinedClass newAnonymousClass(JClass baseType) {
return new JAnonymousClass(baseType);
@@ -248,18 +266,18 @@ public JDefinedClass anonymousClass(JClass baseType) {
public JDefinedClass anonymousClass(Class> baseType) {
return anonymousClass(ref(baseType));
}
-
+
/**
* Generates Java source code.
* A convenience method for build(destDir,destDir,System.out).
- *
+ *
* @param destDir
- * source files are generated into this directory.
- * @param status
- * if non-null, progress indication will be sent to this stream.
+ * source files are generated into this directory.
+ * @param status
+ * if non-null, progress indication will be sent to this stream.
*/
- public void build( File destDir, PrintStream status ) throws IOException {
- build(destDir,destDir,status);
+ public void build(File destDir, PrintStream status) throws IOException {
+ build(destDir, destDir, status);
}
/**
@@ -267,51 +285,53 @@ public void build( File destDir, PrintStream status ) throws IOException {
* A convenience method that calls {@link #build(CodeWriter,CodeWriter)}.
*
* @param srcDir
- * Java source files are generated into this directory.
+ * Java source files are generated into this directory.
* @param resourceDir
- * Other resource files are generated into this directory.
- * @param status
- * if non-null, progress indication will be sent to this stream.
+ * Other resource files are generated into this directory.
+ * @param status
+ * if non-null, progress indication will be sent to this stream.
*/
- public void build( File srcDir, File resourceDir, PrintStream status ) throws IOException {
+ public void build(File srcDir, File resourceDir, PrintStream status) throws IOException {
CodeWriter src = new FileCodeWriter(srcDir);
CodeWriter res = new FileCodeWriter(resourceDir);
- if(status!=null) {
- src = new ProgressCodeWriter(src, status );
- res = new ProgressCodeWriter(res, status );
+ if (status != null) {
+ src = new ProgressCodeWriter(src, status);
+ res = new ProgressCodeWriter(res, status);
}
- build(src,res);
+ build(src, res);
}
/**
* A convenience method for build(destDir,System.out).
*/
- public void build( File destDir ) throws IOException {
- build(destDir,System.out);
+ public void build(File destDir) throws IOException {
+ build(destDir, System.out);
}
/**
- * A convenience method for build(srcDir,resourceDir,System.out).
+ * A convenience method for
+ * build(srcDir,resourceDir,System.out).
*/
- public void build( File srcDir, File resourceDir ) throws IOException {
- build(srcDir,resourceDir,System.out);
+ public void build(File srcDir, File resourceDir) throws IOException {
+ build(srcDir, resourceDir, System.out);
}
/**
* A convenience method for build(out,out).
*/
- public void build( CodeWriter out ) throws IOException {
- build(out,out);
+ public void build(CodeWriter out) throws IOException {
+ build(out, out);
}
-
+
/**
* Generates Java source code.
*/
- public void build( CodeWriter source, CodeWriter resource ) throws IOException {
+ public void build(CodeWriter source, CodeWriter resource) throws IOException {
JPackage[] pkgs = packages.values().toArray(new JPackage[packages.size()]);
// avoid concurrent modification exception
- for( JPackage pkg : pkgs )
- pkg.build(source,resource);
+ for (JPackage pkg : pkgs) {
+ pkg.build(source, resource);
+ }
source.close();
resource.close();
}
@@ -324,12 +344,12 @@ public int countArtifacts() {
int r = 0;
JPackage[] pkgs = packages.values().toArray(new JPackage[packages.size()]);
// avoid concurrent modification exception
- for( JPackage pkg : pkgs )
+ for (JPackage pkg : pkgs) {
r += pkg.countArtifacts();
+ }
return r;
}
-
/**
* Obtains a reference to an existing class from its Class object.
*
@@ -339,10 +359,11 @@ public int countArtifacts() {
* @see #_ref(Class) for the version that handles more cases.
*/
public JClass ref(Class> clazz) {
- JReferencedClass jrc = (JReferencedClass)refClasses.get(clazz);
+ JReferencedClass jrc = (JReferencedClass) refClasses.get(clazz);
if (jrc == null) {
- if (clazz.isPrimitive())
- throw new IllegalArgumentException(clazz+" is a primitive");
+ if (clazz.isPrimitive()) {
+ throw new IllegalArgumentException(clazz + " is a primitive");
+ }
if (clazz.isArray()) {
return new JArrayClass(this, _ref(clazz.getComponentType()));
} else {
@@ -354,10 +375,11 @@ public JClass ref(Class> clazz) {
}
public JType _ref(Class> c) {
- if(c.isPrimitive())
- return JType.parse(this,c.getName());
- else
+ if (c.isPrimitive()) {
+ return JType.parse(this, c.getName());
+ } else {
return ref(c);
+ }
}
/**
@@ -386,12 +408,25 @@ public JClass ref(String fullyQualifiedClassName) {
// assume it's not visible to us.
JDirectClass jdrc = refDirectClasses.get(fullyQualifiedClassName);
if (jdrc == null) {
- jdrc = new JDirectClass(this,fullyQualifiedClassName);
- refDirectClasses.put(fullyQualifiedClassName, jdrc);
+ jdrc = new JDirectClass(this, fullyQualifiedClassName);
+ refDirectClasses.put(fullyQualifiedClassName, jdrc);
}
return jdrc;
}
+ public JClass refNoDirect(String fullyQualifiedClassName) throws ClassNotFoundException {
+ try {
+ // try the context class loader first
+ return ref(SecureLoader.getContextClassLoader().loadClass(fullyQualifiedClassName));
+ } catch (ClassNotFoundException e) {
+ // fall through
+ }
+ // then the default mechanism.
+
+ return ref(Class.forName(fullyQualifiedClassName));
+
+ }
+
/**
* Cached for {@link #wildcard()}.
*/
@@ -402,8 +437,9 @@ public JClass ref(String fullyQualifiedClassName) {
* which is equivalent to "? extends Object".
*/
public JClass wildcard() {
- if(wildcard==null)
+ if (wildcard == null) {
wildcard = ref(Object.class).wildcard();
+ }
return wildcard;
}
@@ -411,19 +447,21 @@ public JClass wildcard() {
* Obtains a type object from a type name.
*
*
- * This method handles primitive types, arrays, and existing {@link Class}es.
+ * This method handles primitive types, arrays, and existing
+ * {@link Class}es.
*
* @exception ClassNotFoundException
- * If the specified type is not found.
+ * If the specified type is not found.
*/
public JType parseType(String name) throws ClassNotFoundException {
// array
- if(name.endsWith("[]"))
- return parseType(name.substring(0,name.length()-2)).array();
+ if (name.endsWith("[]")) {
+ return parseType(name.substring(0, name.length() - 2)).array();
+ }
// try primitive type
try {
- return JType.parse(this,name);
+ return JType.parse(this, name);
} catch (IllegalArgumentException e) {
;
}
@@ -433,6 +471,7 @@ public JType parseType(String name) throws ClassNotFoundException {
}
private final class TypeNameParser {
+
private final String s;
private int idx;
@@ -441,7 +480,8 @@ public TypeNameParser(String s) {
}
/**
- * Parses a type name token T (which can be potentially of the form Tr&ly;T1,T2,...>,
+ * Parses a type name token T (which can be potentially of the form
+ * Tr&ly;T1,T2,...>,
* or "? extends/super T".)
*
* @return the index of the character next to T.
@@ -449,35 +489,35 @@ public TypeNameParser(String s) {
JClass parseTypeName() throws ClassNotFoundException {
int start = idx;
- if(s.charAt(idx)=='?') {
+ if (s.charAt(idx) == '?') {
// wildcard
idx++;
ws();
String head = s.substring(idx);
- if(head.startsWith("extends")) {
- idx+=7;
+ if (head.startsWith("extends")) {
+ idx += 7;
ws();
return parseTypeName().wildcard();
- } else
- if(head.startsWith("super")) {
+ } else if (head.startsWith("super")) {
throw new UnsupportedOperationException("? super T not implemented");
} else {
// not supported
- throw new IllegalArgumentException("only extends/super can follow ?, but found "+s.substring(idx));
+ throw new IllegalArgumentException("only extends/super can follow ?, but found " + s.substring(idx));
}
}
- while(idx'
*/
private JClass parseArguments(JClass rawType) throws ClassNotFoundException {
- if(s.charAt(idx)!='<')
+ if (s.charAt(idx) != '<') {
throw new IllegalArgumentException();
+ }
idx++;
List args = new ArrayList();
- while(true) {
+ while (true) {
args.add(parseTypeName());
- if(idx==s.length())
- throw new IllegalArgumentException("Missing '>' in "+s);
+ if (idx == s.length()) {
+ throw new IllegalArgumentException("Missing '>' in " + s);
+ }
char ch = s.charAt(idx);
- if(ch=='>')
+ if (ch == '>') {
return rawType.narrow(args.toArray(new JClass[args.size()]));
+ }
- if(ch!=',')
+ if (ch != ',') {
throw new IllegalArgumentException(s);
+ }
idx++;
}
@@ -544,17 +590,18 @@ private JClass parseArguments(JClass rawType) throws ClassNotFoundException {
/**
* References to existing classes.
- *
+ *
*
* JReferencedClass is kept in a pool so that they are shared.
* There is one pool for each JCodeModel object.
- *
+ *
*
* It is impossible to cache JReferencedClass globally only because
* there is the _package() method, which obtains the owner JPackage
* object, which is scoped to JCodeModel.
*/
private class JReferencedClass extends JClass implements JDeclaration {
+
private final Class> _class;
JReferencedClass(Class> _clazz) {
@@ -568,7 +615,7 @@ public String name() {
}
public String fullName() {
- return NameUtilities.getFullName(_class);
+ return NameUtilities.getFullName(_class);
}
public String binaryName() {
@@ -577,7 +624,9 @@ public String binaryName() {
public JClass outer() {
Class> p = _class.getDeclaringClass();
- if(p==null) return null;
+ if (p == null) {
+ return null;
+ }
return ref(p);
}
@@ -585,37 +634,44 @@ public JPackage _package() {
String name = fullName();
// this type is array
- if (name.indexOf('[') != -1)
+ if (name.indexOf('[') != -1) {
return JCodeModel.this._package("");
+ }
// other normal case
int idx = name.lastIndexOf('.');
- if (idx < 0)
+ if (idx < 0) {
return JCodeModel.this._package("");
- else
+ } else {
return JCodeModel.this._package(name.substring(0, idx));
+ }
}
public JClass _extends() {
Class> sp = _class.getSuperclass();
if (sp == null) {
- if(isInterface())
+ if (isInterface()) {
return owner().ref(Object.class);
+ }
return null;
- } else
+ } else {
return ref(sp);
+ }
}
public Iterator _implements() {
final Class>[] interfaces = _class.getInterfaces();
return new Iterator() {
private int idx = 0;
+
public boolean hasNext() {
return idx < interfaces.length;
}
+
public JClass next() {
return JCodeModel.this.ref(interfaces[idx++]);
}
+
public void remove() {
throw new UnsupportedOperationException();
}
@@ -632,10 +688,11 @@ public boolean isAbstract() {
public JPrimitiveType getPrimitiveType() {
Class> v = boxToPrimitive.get(_class);
- if(v!=null)
- return JType.parse(JCodeModel.this,v.getName());
- else
+ if (v != null) {
+ return JType.parse(JCodeModel.this, v.getName());
+ } else {
return null;
+ }
}
public boolean isArray() {
@@ -654,34 +711,41 @@ protected JClass substituteParams(JTypeVar[] variables, List bindings) {
// TODO: does JDK 1.5 reflection provides these information?
return this;
}
+
+ @Override
+ public JClass inner(String name) {
+ return ref(fullName() + "." + name);
+ }
}
/**
- * Conversion from primitive type {@link Class} (such as {@link Integer#TYPE}
+ * Conversion from primitive type {@link Class} (such as
+ * {@link Integer#TYPE}
* to its boxed type (such as Integer.class)
*/
- public static final Map,Class>> primitiveToBox;
+ public static final Map, Class>> primitiveToBox;
/**
* The reverse look up for {@link #primitiveToBox}
*/
- public static final Map,Class>> boxToPrimitive;
+ public static final Map, Class>> boxToPrimitive;
static {
- Map,Class>> m1 = new HashMap,Class>>();
- Map,Class>> m2 = new HashMap,Class>>();
-
- m1.put(Boolean.class,Boolean.TYPE);
- m1.put(Byte.class,Byte.TYPE);
- m1.put(Character.class,Character.TYPE);
- m1.put(Double.class,Double.TYPE);
- m1.put(Float.class,Float.TYPE);
- m1.put(Integer.class,Integer.TYPE);
- m1.put(Long.class,Long.TYPE);
- m1.put(Short.class,Short.TYPE);
- m1.put(Void.class,Void.TYPE);
-
- for (Map.Entry, Class>> e : m1.entrySet())
- m2.put(e.getValue(),e.getKey());
+ Map, Class>> m1 = new HashMap, Class>>();
+ Map, Class>> m2 = new HashMap, Class>>();
+
+ m1.put(Boolean.class, Boolean.TYPE);
+ m1.put(Byte.class, Byte.TYPE);
+ m1.put(Character.class, Character.TYPE);
+ m1.put(Double.class, Double.TYPE);
+ m1.put(Float.class, Float.TYPE);
+ m1.put(Integer.class, Integer.TYPE);
+ m1.put(Long.class, Long.TYPE);
+ m1.put(Short.class, Short.TYPE);
+ m1.put(Void.class, Void.TYPE);
+
+ for (Map.Entry, Class>> e : m1.entrySet()) {
+ m2.put(e.getValue(), e.getKey());
+ }
boxToPrimitive = Collections.unmodifiableMap(m1);
primitiveToBox = Collections.unmodifiableMap(m2);
diff --git a/codemodel/src/main/java/com/sun/codemodel/JConditional.java b/codemodel/src/main/java/com/sun/codemodel/JConditional.java
index 1db8587..ff8b918 100644
--- a/codemodel/src/main/java/com/sun/codemodel/JConditional.java
+++ b/codemodel/src/main/java/com/sun/codemodel/JConditional.java
@@ -54,12 +54,12 @@ public class JConditional implements JStatement {
/**
* JBlock of statements for "then" clause
*/
- private JBlock _then = new JBlock();
+ private JStatement _then = null;
/**
* JBlock of statements for optional "else" clause
*/
- private JBlock _else = null;
+ private JStatement _else = null;
/**
* Constructor
@@ -71,13 +71,24 @@ public class JConditional implements JStatement {
this.test = test;
}
+ public void setThen(JStatement _then) {
+ this._then = _then;
+ }
+
+ public void setElse(JStatement _else) {
+ this._else = _else;
+ }
+
/**
- * Return the block to be excuted by the "then" branch
+ * Return a block to be excuted by the "then" branch
*
* @return Then block
*/
public JBlock _then() {
- return _then;
+ if (_then == null || !(_then instanceof JBlock)) {
+ _then = new JBlock();
+ }
+ return (JBlock) _then;
}
/**
@@ -86,35 +97,30 @@ public JBlock _then() {
* @return Newly generated else block
*/
public JBlock _else() {
- if (_else == null) _else = new JBlock();
- return _else;
+ if (_else == null || !(_else instanceof JBlock)) {
+ _else = new JBlock();
+ }
+ return (JBlock) _else;
}
/**
* Creates ... else if(...) ... code.
*/
public JConditional _elseif(JExpression boolExp) {
- return _else()._if(boolExp);
+ _else = new JBlock(false, false);
+ return ((JBlock) _else)._if(boolExp);
}
public void state(JFormatter f) {
- if(test==JExpr.TRUE) {
- _then.generateBody(f);
- return;
- }
- if(test==JExpr.FALSE) {
- _else.generateBody(f);
- return;
- }
if (JOp.hasTopOp(test)) {
f.p("if ").g(test);
} else {
f.p("if (").g(test).p(')');
}
- f.g(_then);
+ f.s(_then);
if (_else != null)
- f.p("else").g(_else);
+ f.p("else").s(_else);
f.nl();
}
}
diff --git a/codemodel/src/main/java/com/sun/codemodel/JDefinedClass.java b/codemodel/src/main/java/com/sun/codemodel/JDefinedClass.java
index 41859a7..93fd1fc 100644
--- a/codemodel/src/main/java/com/sun/codemodel/JDefinedClass.java
+++ b/codemodel/src/main/java/com/sun/codemodel/JDefinedClass.java
@@ -143,7 +143,7 @@ public class JDefinedClass
* or enum
*
*/
- private final ClassType classType;
+ private ClassType classType;
/** List containing the enum value declarations
*
@@ -668,9 +668,9 @@ public JDefinedClass _class(int mods, String name, ClassType classTypeVal)
throws JClassAlreadyExistsException {
String NAME;
- if (JCodeModel.isCaseSensitiveFileSystem)
- NAME = name.toUpperCase();
- else
+// if (JCodeModel.isCaseSensitiveFileSystem)
+// NAME = name.toUpperCase();
+// else
NAME = name;
if (getClasses().containsKey(NAME))
@@ -754,7 +754,7 @@ public final Iterator classes() {
return classes.values().iterator();
}
- private Map getClasses() {
+ public Map getClasses() {
if(classes==null)
classes = new TreeMap();
return classes;
@@ -961,4 +961,20 @@ public Collection annotations() {
public JMods mods() {
return mods;
}
+
+ public void setMods(int mods) {
+ if (isInterface())
+ this.mods = JMods.forInterface(mods);
+ else
+ this.mods = JMods.forClass(mods);
+ }
+
+ public void setType(ClassType type) {
+ this.classType = type;
+ }
+
+ @Override
+ public JClass inner(String name) {
+ return getClasses().get(name);
+ }
}
diff --git a/codemodel/src/main/java/com/sun/codemodel/JDirectClass.java b/codemodel/src/main/java/com/sun/codemodel/JDirectClass.java
index 64a620f..b1b9f14 100644
--- a/codemodel/src/main/java/com/sun/codemodel/JDirectClass.java
+++ b/codemodel/src/main/java/com/sun/codemodel/JDirectClass.java
@@ -40,9 +40,9 @@
package com.sun.codemodel;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
-import java.util.Collections;
/**
* A special {@link JClass} that represents an unknown class (except its name.)
@@ -57,6 +57,7 @@ final class JDirectClass extends JClass {
public JDirectClass(JCodeModel _owner,String fullName) {
super(_owner);
this.fullName = fullName;
+ throw new RuntimeException("Stop using this it fucks up imports!");
}
public String name() {
@@ -94,4 +95,9 @@ public boolean isAbstract() {
protected JClass substituteParams(JTypeVar[] variables, List bindings) {
return this;
}
+
+ @Override
+ public JClass inner(String name) {
+ return new JDirectClass(owner(), fullName()+"."+name);
+ }
}
diff --git a/codemodel/src/main/java/com/sun/codemodel/JDirectRef.java b/codemodel/src/main/java/com/sun/codemodel/JDirectRef.java
new file mode 100644
index 0000000..5e327f4
--- /dev/null
+++ b/codemodel/src/main/java/com/sun/codemodel/JDirectRef.java
@@ -0,0 +1,32 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.sun.codemodel;
+
+/**
+ *
+ * @author lkroll
+ */
+public class JDirectRef extends JExpressionImpl implements JAssignmentTarget {
+
+ private final String ref;
+
+ public JDirectRef(String ref) {
+ this.ref = ref;
+ }
+
+ public void generate(JFormatter f) {
+ f.p(ref);
+ }
+
+ public JExpression assign(JExpression rhs) {
+ return JExpr.assign(this, rhs);
+ }
+
+ public JExpression assignPlus(JExpression rhs) {
+ return JExpr.assignPlus(this, rhs);
+ }
+
+}
diff --git a/codemodel/src/main/java/com/sun/codemodel/JDoLoop.java b/codemodel/src/main/java/com/sun/codemodel/JDoLoop.java
index bb5be4d..7b648a7 100644
--- a/codemodel/src/main/java/com/sun/codemodel/JDoLoop.java
+++ b/codemodel/src/main/java/com/sun/codemodel/JDoLoop.java
@@ -55,7 +55,7 @@ public class JDoLoop implements JStatement {
/**
* JBlock of statements which makes up body of this Do statement
*/
- private JBlock body = null;
+ private JStatement body = null;
/**
* Construct a Do statment
@@ -65,14 +65,20 @@ public class JDoLoop implements JStatement {
}
public JBlock body() {
- if (body == null) body = new JBlock();
- return body;
+ if (body == null || !(body instanceof JBlock)) {
+ body = new JBlock();
+ }
+ return (JBlock) body;
+ }
+
+ public void setBody(JStatement stmt) {
+ this.body = stmt;
}
public void state(JFormatter f) {
f.p("do");
if (body != null)
- f.g(body);
+ f.s(body);
else
f.p("{ }");
diff --git a/codemodel/src/main/java/com/sun/codemodel/JExpr.java b/codemodel/src/main/java/com/sun/codemodel/JExpr.java
index 068f1cb..1c432f1 100644
--- a/codemodel/src/main/java/com/sun/codemodel/JExpr.java
+++ b/codemodel/src/main/java/com/sun/codemodel/JExpr.java
@@ -37,10 +37,8 @@
* only if the new code is made subject to such option by the copyright
* holder.
*/
-
package com.sun.codemodel;
-
/**
* Factory methods that generate various {@link JExpression}s.
*/
@@ -49,7 +47,8 @@ public abstract class JExpr {
/**
* This class is not instanciable.
*/
- private JExpr() { }
+ private JExpr() {
+ }
public static JExpressionStatement assign(JAssignmentTarget lhs, JExpression rhs) {
return new JAssignment(lhs, rhs);
@@ -59,33 +58,61 @@ public static JExpressionStatement assignPlus(JAssignmentTarget lhs, JExpression
return new JAssignment(lhs, rhs, "+");
}
- public static JExpressionStatement assignMinus(JAssignmentTarget lhs, JExpression rhs) {
- return new JAssignment(lhs, rhs, "-");
- }
+ public static JExpressionStatement assignMinus(JAssignmentTarget lhs, JExpression rhs) {
+ return new JAssignment(lhs, rhs, "-");
+ }
+
+ public static JExpressionStatement assignTimes(JAssignmentTarget lhs, JExpression rhs) {
+ return new JAssignment(lhs, rhs, "*");
+ }
+
+ public static JExpressionStatement assignDivide(JAssignmentTarget lhs, JExpression rhs) {
+ return new JAssignment(lhs, rhs, "/");
+ }
+
+ public static JExpressionStatement assignMod(JAssignmentTarget lhs, JExpression rhs) {
+ return new JAssignment(lhs, rhs, "%");
+ }
+
+ public static JExpressionStatement assignShl(JAssignmentTarget lhs, JExpression rhs) {
+ return new JAssignment(lhs, rhs, "<<");
+ }
+
+ public static JExpressionStatement assignShr(JAssignmentTarget lhs, JExpression rhs) {
+ return new JAssignment(lhs, rhs, ">>");
+ }
+
+ public static JExpressionStatement assignUshr(JAssignmentTarget lhs, JExpression rhs) {
+ return new JAssignment(lhs, rhs, ">>>");
+ }
- public static JExpressionStatement assignTimes(JAssignmentTarget lhs, JExpression rhs) {
- return new JAssignment(lhs, rhs, "*");
- }
+ public static JExpressionStatement assignAnd(JAssignmentTarget lhs, JExpression rhs) {
+ return new JAssignment(lhs, rhs, "&");
+ }
- public static JExpressionStatement assignDivide(JAssignmentTarget lhs, JExpression rhs) {
- return new JAssignment(lhs, rhs, "/");
- }
+ public static JExpressionStatement assignOr(JAssignmentTarget lhs, JExpression rhs) {
+ return new JAssignment(lhs, rhs, "|");
+ }
+
+ public static JExpressionStatement assignXor(JAssignmentTarget lhs, JExpression rhs) {
+ return new JAssignment(lhs, rhs, "^");
+ }
- public static JExpressionStatement incr(final JExpression expression) {
- return new JExpressionStatementWrapper(JOp.incr(expression));
- }
+ public static JExpressionStatement incr(final JExpression expression) {
+ return new JExpressionStatementWrapper(JOp.incr(expression));
+ }
- public static JStatement preincr(final JExpression expression) {
- return new JExpressionStatementWrapper(JOp.preincr(expression));
- }
+ public static JExpressionStatement preincr(final JExpression expression) {
+ return new JExpressionStatementWrapper(JOp.preincr(expression));
+ }
- public static JStatement decr(final JExpression expression) {
- return new JExpressionStatementWrapper(JOp.decr(expression));
- }
+ public static JExpressionStatement decr(final JExpression expression) {
+ return new JExpressionStatementWrapper(JOp.decr(expression));
+ }
- public static JStatement predecr(final JExpression expression) {
- return new JExpressionStatementWrapper(JOp.predecr(expression));
- }
+ public static JExpressionStatement predecr(final JExpression expression) {
+ return new JExpressionStatementWrapper(JOp.predecr(expression));
+ }
public static JInvocation _new(JClass c) {
return new JInvocation(c);
@@ -94,13 +121,13 @@ public static JInvocation _new(JClass c) {
public static JInvocation _new(JType t) {
return new JInvocation(t);
}
-
+
public static JInvocation invoke(String method) {
- return new JInvocation((JExpression)null, method);
+ return new JInvocation((JExpression) null, method);
}
-
+
public static JInvocation invoke(JMethod method) {
- return new JInvocation((JExpression)null,method);
+ return new JInvocation((JExpression) null, method);
}
public static JInvocation invoke(JExpression lhs, JMethod method) {
@@ -112,11 +139,11 @@ public static JInvocation invoke(JExpression lhs, String method) {
}
public static JFieldRef ref(String field) {
- return new JFieldRef((JExpression)null, field);
+ return new JFieldRef((JExpression) null, field);
}
public static JFieldRef ref(JExpression lhs, JVar field) {
- return new JFieldRef(lhs,field);
+ return new JFieldRef(lhs, field);
}
public static JFieldRef ref(JExpression lhs, String field) {
@@ -124,20 +151,49 @@ public static JFieldRef ref(JExpression lhs, String field) {
}
public static JFieldRef refthis(String field) {
- return new JFieldRef(null, field, true);
+ return new JFieldRef(null, field, true);
}
public static JExpression dotclass(final JClass cl) {
return new JExpressionImpl() {
- public void generate(JFormatter f) {
- JClass c;
- if(cl instanceof JNarrowedClass)
- c = ((JNarrowedClass)cl).basis;
- else
- c = cl;
- f.g(c).p(".class");
+ public void generate(JFormatter f) {
+ JClass c;
+ if (cl instanceof JNarrowedClass) {
+ c = ((JNarrowedClass) cl).basis;
+ } else {
+ c = cl;
+ }
+ f.g(c).p(".class");
+ }
+ };
+ }
+
+ public static JExpression dotthis(final JClass cl) {
+ return new JExpressionImpl() {
+ public void generate(JFormatter f) {
+ JClass c;
+ if (cl instanceof JNarrowedClass) {
+ c = ((JNarrowedClass) cl).basis;
+ } else {
+ c = cl;
}
- };
+ f.g(c).p(".this");
+ }
+ };
+ }
+
+ public static JExpression dotsuper(final JClass cl) {
+ return new JExpressionImpl() {
+ public void generate(JFormatter f) {
+ JClass c;
+ if (cl instanceof JNarrowedClass) {
+ c = ((JNarrowedClass) cl).basis;
+ } else {
+ c = cl;
+ }
+ f.g(c).p(".super");
+ }
+ };
}
public static JArrayCompRef component(JExpression lhs, JExpression index) {
@@ -149,14 +205,14 @@ public static JCast cast(JType type, JExpression expr) {
}
public static JArray newArray(JType type) {
- return newArray(type,null);
+ return newArray(type, null);
}
/**
* Generates {@code new T[size]}.
*
* @param type
- * The type of the array component. 'T' or {@code new T[size]}.
+ * The type of the array component. 'T' or {@code new T[size]}.
*/
public static JArray newArray(JType type, JExpression size) {
// you cannot create an array whose component type is a generic
@@ -167,40 +223,44 @@ public static JArray newArray(JType type, JExpression size) {
* Generates {@code new T[size]}.
*
* @param type
- * The type of the array component. 'T' or {@code new T[size]}.
+ * The type of the array component. 'T' or {@code new T[size]}.
*/
public static JArray newArray(JType type, int size) {
- return newArray(type,lit(size));
+ return newArray(type, lit(size));
}
-
-
+
private static final JExpression __this = new JAtom("this");
+
/**
* Returns a reference to "this", an implicit reference
* to the current object.
*/
- public static JExpression _this() { return __this; }
+ public static JExpression _this() {
+ return __this;
+ }
private static final JExpression __super = new JAtom("super");
+
/**
* Returns a reference to "super", an implicit reference
* to the super class.
*/
- public static JExpression _super() { return __super; }
-
-
- /* -- Literals -- */
+ public static JExpression _super() {
+ return __super;
+ }
+ /* -- Literals -- */
private static final JExpression __null = new JAtom("null");
+
public static JExpression _null() {
return __null;
}
-
+
/**
* Boolean constant that represents true
*/
public static final JExpression TRUE = new JAtom("true");
-
+
/**
* Boolean constant that represents false
*/
@@ -209,7 +269,7 @@ public static JExpression _null() {
public static JExpression lit(boolean b) {
return b ? TRUE : FALSE;
}
-
+
public static JExpression lit(int n) {
return new JAtom(Integer.toString(n));
}
@@ -219,49 +279,35 @@ public static JExpression lit(long n) {
}
public static JExpression lit(float f) {
- if (f == Float.NEGATIVE_INFINITY)
- {
- return new JAtom("java.lang.Float.NEGATIVE_INFINITY");
- }
- else if (f == Float.POSITIVE_INFINITY)
- {
- return new JAtom("java.lang.Float.POSITIVE_INFINITY");
- }
- else if (Float.isNaN(f))
- {
- return new JAtom("java.lang.Float.NaN");
- }
- else
- {
- return new JAtom(Float.toString(f) + "F");
- }
+ if (f == Float.NEGATIVE_INFINITY) {
+ return new JAtom("java.lang.Float.NEGATIVE_INFINITY");
+ } else if (f == Float.POSITIVE_INFINITY) {
+ return new JAtom("java.lang.Float.POSITIVE_INFINITY");
+ } else if (Float.isNaN(f)) {
+ return new JAtom("java.lang.Float.NaN");
+ } else {
+ return new JAtom(Float.toString(f) + "F");
+ }
}
public static JExpression lit(double d) {
- if (d == Double.NEGATIVE_INFINITY)
- {
- return new JAtom("java.lang.Double.NEGATIVE_INFINITY");
- }
- else if (d == Double.POSITIVE_INFINITY)
- {
- return new JAtom("java.lang.Double.POSITIVE_INFINITY");
- }
- else if (Double.isNaN(d))
- {
- return new JAtom("java.lang.Double.NaN");
- }
- else
- {
- return new JAtom(Double.toString(d) + "D");
- }
+ if (d == Double.NEGATIVE_INFINITY) {
+ return new JAtom("java.lang.Double.NEGATIVE_INFINITY");
+ } else if (d == Double.POSITIVE_INFINITY) {
+ return new JAtom("java.lang.Double.POSITIVE_INFINITY");
+ } else if (Double.isNaN(d)) {
+ return new JAtom("java.lang.Double.NaN");
+ } else {
+ return new JAtom(Double.toString(d) + "D");
+ }
}
static final String charEscape = "\b\t\n\f\r\"\'\\";
- static final String charMacro = "btnfr\"'\\";
-
+ static final String charMacro = "btnfr\"'\\";
+
/**
* Escapes the given string, then surrounds it by the specified
- * quotation mark.
+ * quotation mark.
*/
public static String quotify(char quote, String s) {
int n = s.length();
@@ -270,8 +316,8 @@ public static String quotify(char quote, String s) {
for (int i = 0; i < n; i++) {
char c = s.charAt(i);
int j = charEscape.indexOf(c);
- if(j>=0) {
- if((quote=='"' && c=='\'') || (quote=='\'' && c=='"')) {
+ if (j >= 0) {
+ if ((quote == '"' && c == '\'') || (quote == '\'' && c == '"')) {
sb.append(c);
} else {
sb.append('\\');
@@ -286,12 +332,13 @@ public static String quotify(char quote, String s) {
// the escaping here (regardless of the actual file encoding)
//
// see bug
- if( c<0x20 || 0x7E
*
* This method can be used as a short-cut to create a JExpression.
* For example, instead of _a.gt(_b), you can write
- * it as: JExpr.direct("a>b").
- *
+ * it as: {@code JExpr.direct("a>b")}.
+ *
*
* Be warned that there is a danger in using this method,
* as it obfuscates the object model.
*/
- public static JExpression direct( final String source ) {
- return new JExpressionImpl(){
- public void generate( JFormatter f ) {
+ public static JExpression direct(final String source) {
+ if ((source == null) || source.isEmpty()) {
+ throw new RuntimeException("DUDE!");
+ }
+ return new JExpressionImpl() {
+ public void generate(JFormatter f) {
f.p('(').p(source).p(')');
}
};
}
- static class JExpressionStatementWrapper extends JExpressionImpl implements JExpressionStatement {
- final JExpression expression;
+ static class JExpressionStatementWrapper extends JExpressionImpl implements JExpressionStatement {
- JExpressionStatementWrapper(JExpression expression) {
- this.expression = expression;
- }
+ final JExpression expression;
- public void generate(JFormatter f) {
- expression.generate(f);
- }
+ JExpressionStatementWrapper(JExpression expression) {
+ this.expression = expression;
+ }
- public void state(JFormatter f) {
- expression.generate(f);
- f.p(';').nl();
- }
- }
-}
\ No newline at end of file
+ public void generate(JFormatter f) {
+ expression.generate(f);
+ }
+
+ public void state(JFormatter f) {
+ expression.generate(f);
+ f.p(';').nl();
+ }
+ }
+}
diff --git a/codemodel/src/main/java/com/sun/codemodel/JExprProxy.java b/codemodel/src/main/java/com/sun/codemodel/JExprProxy.java
new file mode 100644
index 0000000..05546fc
--- /dev/null
+++ b/codemodel/src/main/java/com/sun/codemodel/JExprProxy.java
@@ -0,0 +1,29 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.sun.codemodel;
+
+import com.sun.codemodel.JGenProxy.Resolver;
+
+/**
+ *
+ * @author lkroll
+ */
+public class JExprProxy extends JExpressionImpl {
+
+ private JExpression proxee = null;
+ private final Resolver resolver;
+
+ public JExprProxy(Resolver resolver) {
+ this.resolver = resolver;
+ }
+
+ public void generate(JFormatter f) {
+ if (proxee == null) {
+ proxee = resolver.resolve();
+ }
+ f.g(proxee);
+ }
+}
diff --git a/codemodel/src/main/java/com/sun/codemodel/JExpression.java b/codemodel/src/main/java/com/sun/codemodel/JExpression.java
index 57d52ac..99efc52 100644
--- a/codemodel/src/main/java/com/sun/codemodel/JExpression.java
+++ b/codemodel/src/main/java/com/sun/codemodel/JExpression.java
@@ -122,12 +122,12 @@ public interface JExpression extends JGenerable {
JExpression shl(JExpression right);
/**
- * Returns "[this]>>[right]"
+ * Returns "[this]<<[right]"
*/
JExpression shr(JExpression right);
/**
- * Returns "[this]>>>[right]"
+ * Returns "[this]<<<[right]"
*/
JExpression shrz(JExpression right);
@@ -169,6 +169,14 @@ public interface JExpression extends JGenerable {
* Arguments shall be added to the returned {@link JInvocation} object.
*/
JInvocation invoke(String method);
+
+// /**
+// * Return [this].new [id]
+// *
+// * Arguments shall be added to the returned {@link JInvocation} object.
+// */
+// JInvocation _new(String id);
+
JFieldRef ref(JVar field);
JFieldRef ref(String field);
JArrayCompRef component(JExpression index);
diff --git a/codemodel/src/main/java/com/sun/codemodel/JExpressionImpl.java b/codemodel/src/main/java/com/sun/codemodel/JExpressionImpl.java
index 5d50095..8a329f9 100644
--- a/codemodel/src/main/java/com/sun/codemodel/JExpressionImpl.java
+++ b/codemodel/src/main/java/com/sun/codemodel/JExpressionImpl.java
@@ -37,19 +37,19 @@
* only if the new code is made subject to such option by the copyright
* holder.
*/
-
package com.sun.codemodel;
/**
* Provides default implementations for {@link JExpression}.
*/
-public abstract class JExpressionImpl implements JExpression
-{
+public abstract class JExpressionImpl implements JExpression {
+
//
//
// from JOp
//
//
+
public final JExpression minus() {
return JOp.minus(this);
}
@@ -69,17 +69,17 @@ public final JExpression incr() {
return JOp.incr(this);
}
- public final JExpression preincr() {
- return JOp.preincr(this);
- }
+ public final JExpression preincr() {
+ return JOp.preincr(this);
+ }
public final JExpression decr() {
return JOp.decr(this);
}
- public final JExpression predecr() {
- return JOp.predecr(this);
- }
+ public final JExpression predecr() {
+ return JOp.predecr(this);
+ }
public final JExpression plus(JExpression right) {
return JOp.plus(this, right);
diff --git a/codemodel/src/main/java/com/sun/codemodel/JField.java b/codemodel/src/main/java/com/sun/codemodel/JField.java
new file mode 100644
index 0000000..41f69ea
--- /dev/null
+++ b/codemodel/src/main/java/com/sun/codemodel/JField.java
@@ -0,0 +1,14 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.sun.codemodel;
+
+/**
+ *
+ * @author lkroll
+ */
+public interface JField extends JExpression, JAssignmentTarget {
+
+}
diff --git a/codemodel/src/main/java/com/sun/codemodel/JFieldProxy.java b/codemodel/src/main/java/com/sun/codemodel/JFieldProxy.java
new file mode 100644
index 0000000..b4bf65b
--- /dev/null
+++ b/codemodel/src/main/java/com/sun/codemodel/JFieldProxy.java
@@ -0,0 +1,72 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.sun.codemodel;
+
+/**
+ *
+ * @author lkroll
+ */
+public class JFieldProxy extends JExpressionImpl implements JField {
+
+ private JField proxee = null;
+ private final String name;
+ private final FieldResolver resolver;
+
+ public JFieldProxy(String name, FieldResolver resolver) {
+ this.name = name;
+ this.resolver = resolver;
+ }
+
+ public boolean isResolved() {
+ if (proxee == null) {
+ proxee = resolver.resolveField(name);
+ }
+ return proxee != null;
+ }
+
+ public void setProxee(JField ref) {
+ if (ref instanceof JFieldProxy) {
+ throw new RuntimeException("Building endless proxy hierarchies is not a good idea!");
+ }
+ this.proxee = ref;
+ }
+
+ public void generate(JFormatter f) {
+ if (isResolved()) {
+ f.g(proxee);
+ } else {
+ throw new UnresolvedFieldException(name);
+ }
+ }
+
+ public JExpression assign(JExpression rhs) {
+ return JExpr.assign(this, rhs);
+ }
+
+ public JExpression assignPlus(JExpression rhs) {
+ return JExpr.assignPlus(this, rhs);
+ }
+
+ public static interface FieldResolver {
+
+ public JField resolveField(String name);
+ }
+
+ public static class UnresolvedFieldException extends RuntimeException {
+
+ private final String name;
+
+ private UnresolvedFieldException(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getMessage() {
+ return "Proxied field " + name + " has not been resolved, yet";
+ }
+
+ }
+}
diff --git a/codemodel/src/main/java/com/sun/codemodel/JFieldRef.java b/codemodel/src/main/java/com/sun/codemodel/JFieldRef.java
index eccc9ef..149c95e 100644
--- a/codemodel/src/main/java/com/sun/codemodel/JFieldRef.java
+++ b/codemodel/src/main/java/com/sun/codemodel/JFieldRef.java
@@ -45,7 +45,7 @@
* Field Reference
*/
-public class JFieldRef extends JExpressionImpl implements JAssignmentTarget {
+public class JFieldRef extends JExpressionImpl implements JField {
/**
* Object expression upon which this field will be accessed, or
* null for the implicit 'this'.
diff --git a/codemodel/src/main/java/com/sun/codemodel/JForEach.java b/codemodel/src/main/java/com/sun/codemodel/JForEach.java
index 8dcdc19..7ce460e 100644
--- a/codemodel/src/main/java/com/sun/codemodel/JForEach.java
+++ b/codemodel/src/main/java/com/sun/codemodel/JForEach.java
@@ -37,7 +37,6 @@
* only if the new code is made subject to such option by the copyright
* holder.
*/
-
package com.sun.codemodel;
/**
@@ -49,42 +48,47 @@
*/
public final class JForEach implements JStatement {
- private final JType type;
- private final String var;
- private JBlock body = null; // lazily created
- private final JExpression collection;
+ private final JType type;
+ private final String var;
+ private JStatement body = null; // lazily created
+ private final JExpression collection;
private final JVar loopVar;
- public JForEach(JType vartype, String variable, JExpression collection) {
+ public JForEach(JType vartype, String variable, JExpression collection) {
- this.type = vartype;
- this.var = variable;
- this.collection = collection;
+ this.type = vartype;
+ this.var = variable;
+ this.collection = collection;
loopVar = new JVar(JMods.forVar(JMod.NONE), type, var, collection);
}
-
/**
* Returns a reference to the loop variable.
*/
- public JVar var() {
- return loopVar;
- }
+ public JVar var() {
+ return loopVar;
+ }
- public JBlock body() {
- if (body == null)
- body = new JBlock();
- return body;
- }
+ public JBlock body() {
+ if (body == null || !(body instanceof JBlock)) {
+ body = new JBlock();
+ }
+ return (JBlock) body;
+ }
+
+ public void setBody(JStatement stmt) {
+ this.body = stmt;
+ }
- public void state(JFormatter f) {
- f.p("for (");
- f.g(type).id(var).p(": ").g(collection);
- f.p(')');
- if (body != null)
- f.g(body).nl();
- else
- f.p(';').nl();
- }
+ public void state(JFormatter f) {
+ f.p("for (");
+ f.g(type).id(var).p(": ").g(collection);
+ f.p(')');
+ if (body != null) {
+ f.s(body).nl();
+ } else {
+ f.p(';').nl();
+ }
+ }
}
diff --git a/codemodel/src/main/java/com/sun/codemodel/JForLoop.java b/codemodel/src/main/java/com/sun/codemodel/JForLoop.java
index ec2d2c5..0f9ac52 100644
--- a/codemodel/src/main/java/com/sun/codemodel/JForLoop.java
+++ b/codemodel/src/main/java/com/sun/codemodel/JForLoop.java
@@ -53,7 +53,7 @@ public class JForLoop implements JStatement {
private List