mirror of https://github.com/apache/openjpa.git
OPENJPA-1386: Improve handling of imports that can hide each other
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@883846 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
0635172cbb
commit
5d765ea05b
|
@ -55,10 +55,10 @@ public class SourceCode {
|
||||||
public static final String DOT = ".";
|
public static final String DOT = ".";
|
||||||
public static final String EQUAL = "=";
|
public static final String EQUAL = "=";
|
||||||
public static final String QUOTE = "\"";
|
public static final String QUOTE = "\"";
|
||||||
// public static final String NEWLINE = "\r\n";
|
|
||||||
private static final String[] BRACKET_BLOCK = {"{", "}"};
|
private static final Delimiter BLOCK_DELIMITER = new Delimiter("{}");
|
||||||
private static final String[] BRACKET_ARGS = {"(", ")"};
|
private static final Delimiter ARGS_DELIMITER = new Delimiter("()");
|
||||||
private static final String[] BRACKET_PARAMS = {"<", ">"};
|
private static final Delimiter PARAMS_DELIMITER = new Delimiter("<>");
|
||||||
|
|
||||||
private List<Comment> comments;
|
private List<Comment> comments;
|
||||||
private final Package pkg;
|
private final Package pkg;
|
||||||
|
@ -71,7 +71,7 @@ public class SourceCode {
|
||||||
* class name.
|
* class name.
|
||||||
*/
|
*/
|
||||||
public SourceCode(String c) {
|
public SourceCode(String c) {
|
||||||
ClassName name = new ClassName(c);
|
ClassName name = getOrCreateImport(c);
|
||||||
this.cls = new Class(c);
|
this.cls = new Class(c);
|
||||||
this.pkg = new Package(name.getPackageName());
|
this.pkg = new Package(name.getPackageName());
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,15 @@ public class SourceCode {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean addImport(ClassName name) {
|
/**
|
||||||
|
* Adds import to this source code. Adding an import may force the given class name
|
||||||
|
* to use its full name if it is hidden by other imports.
|
||||||
|
*
|
||||||
|
* @param name a ClassName instance
|
||||||
|
* @return true if the import is added. ClassName starting with <code>java.lang.</code>
|
||||||
|
* is not added.
|
||||||
|
*/
|
||||||
|
private boolean addImport(ClassName name) {
|
||||||
String pkgName = name.getPackageName();
|
String pkgName = name.getPackageName();
|
||||||
if ("java.lang".equals(pkgName))
|
if ("java.lang".equals(pkgName))
|
||||||
return false;
|
return false;
|
||||||
|
@ -108,6 +116,27 @@ public class SourceCode {
|
||||||
return imports.add(new Import(name));
|
return imports.add(new Import(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the class name instance for the given fully-qualified class name.
|
||||||
|
* If the given class name is already imported, then use the existing instance.
|
||||||
|
* Otherwise, creates a new instance and adds it to list of imports.
|
||||||
|
*
|
||||||
|
* @see #addImport(ClassName)
|
||||||
|
* @see ClassName
|
||||||
|
*
|
||||||
|
* @param name fully-qualified name of a class
|
||||||
|
* @return an existing class name instance or a new one.
|
||||||
|
*/
|
||||||
|
ClassName getOrCreateImport(String name) {
|
||||||
|
for (Import i : imports) {
|
||||||
|
if (i.name.getFullName().equals(name))
|
||||||
|
return i.name;
|
||||||
|
}
|
||||||
|
ClassName imp = new ClassName(name);
|
||||||
|
addImport(imp);
|
||||||
|
return imp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public SourceCode addComment(boolean inline, String... lines) {
|
public SourceCode addComment(boolean inline, String... lines) {
|
||||||
if (lines == null)
|
if (lines == null)
|
||||||
|
@ -178,23 +207,24 @@ public class SourceCode {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void writeList(PrintWriter out, String header, List<?> list) {
|
static void writeList(PrintWriter out, String header, List<?> list) {
|
||||||
writeList(out, header, list, new String[]{BLANK, BLANK}, false);
|
writeList(out, header, list, new Delimiter(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void writeList(PrintWriter out, String header, List<?> list,
|
static void writeList(PrintWriter out, String header, List<?> list,
|
||||||
String[] bracket, boolean writeEmpty) {
|
Delimiter bracket, boolean writeEmpty) {
|
||||||
if (list == null || list.isEmpty()) {
|
if (list == null || list.isEmpty()) {
|
||||||
if (writeEmpty)
|
if (writeEmpty)
|
||||||
out.append(bracket[0]+bracket[1]);
|
out.append(bracket.start)
|
||||||
|
.append(bracket.end);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
out.append(header);
|
out.append(header);
|
||||||
out.append(bracket[0]);
|
out.append(bracket.start);
|
||||||
for (int i=0; i<list.size(); i++) {
|
for (int i=0; i<list.size(); i++) {
|
||||||
out.append(list.get(i).toString());
|
out.append(list.get(i).toString());
|
||||||
if (i!=list.size()-1) out.append(COMMA);
|
if (i!=list.size()-1) out.append(COMMA);
|
||||||
}
|
}
|
||||||
out.append(bracket[1]);
|
out.append(bracket.end);
|
||||||
}
|
}
|
||||||
|
|
||||||
static String capitalize(String s) {
|
static String capitalize(String s) {
|
||||||
|
@ -268,7 +298,7 @@ public class SourceCode {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Element<T> addParameter(String param) {
|
public Element<T> addParameter(String param) {
|
||||||
params.add(new ClassName(param));
|
params.add(getOrCreateImport(param));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,17 +364,17 @@ public class SourceCode {
|
||||||
private Set<Method> methods = new TreeSet<Method>();
|
private Set<Method> methods = new TreeSet<Method>();
|
||||||
|
|
||||||
public Class(String name) {
|
public Class(String name) {
|
||||||
super(name, new ClassName(name));
|
super(name, getOrCreateImport(name));
|
||||||
makePublic();
|
makePublic();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class setSuper(String s) {
|
public Class setSuper(String s) {
|
||||||
superCls = new ClassName(s);
|
superCls = getOrCreateImport(s);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class addInterface(String s) {
|
public Class addInterface(String s) {
|
||||||
interfaces.add(new ClassName(s));
|
interfaces.add(getOrCreateImport(s));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,7 +401,7 @@ public class SourceCode {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Field addField(String name, String type) {
|
public Field addField(String name, String type) {
|
||||||
return addField(name, new ClassName(type));
|
return addField(name, getOrCreateImport(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Field addField(String f, ClassName type) {
|
public Field addField(String f, ClassName type) {
|
||||||
|
@ -388,7 +418,7 @@ public class SourceCode {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Method addMethod(String m, String retType) {
|
public Method addMethod(String m, String retType) {
|
||||||
return addMethod(m, new ClassName(retType));
|
return addMethod(m, getOrCreateImport(retType));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Method addMethod(String m, ClassName retType) {
|
protected Method addMethod(String m, ClassName retType) {
|
||||||
|
@ -396,7 +426,7 @@ public class SourceCode {
|
||||||
throw new IllegalArgumentException(_loc.get(
|
throw new IllegalArgumentException(_loc.get(
|
||||||
"src-invalid-method",m).toString());
|
"src-invalid-method",m).toString());
|
||||||
}
|
}
|
||||||
Method method = new Method(this, m, retType);
|
Method method = new Method(m, retType);
|
||||||
if (!methods.add(method))
|
if (!methods.add(method))
|
||||||
throw new IllegalArgumentException(_loc.get(
|
throw new IllegalArgumentException(_loc.get(
|
||||||
"src-duplicate-method", method, this).toString());
|
"src-duplicate-method", method, this).toString());
|
||||||
|
@ -409,16 +439,16 @@ public class SourceCode {
|
||||||
out.append("abstract ");
|
out.append("abstract ");
|
||||||
out.print("class ");
|
out.print("class ");
|
||||||
out.print(type.simpleName);
|
out.print(type.simpleName);
|
||||||
writeList(out, BLANK, params, BRACKET_PARAMS, false);
|
writeList(out, BLANK, params, PARAMS_DELIMITER, false);
|
||||||
if (superCls != null)
|
if (superCls != null)
|
||||||
out.print(" extends " + superCls + SPACE);
|
out.print(" extends " + superCls + SPACE);
|
||||||
writeList(out, "implements ", interfaces);
|
writeList(out, "implements ", interfaces);
|
||||||
out.println(SPACE + BRACKET_BLOCK[0]);
|
out.println(SPACE + BLOCK_DELIMITER.start);
|
||||||
for (Field field:fields)
|
for (Field field:fields)
|
||||||
field.write(out, 1);
|
field.write(out, 1);
|
||||||
for (Method method:methods)
|
for (Method method:methods)
|
||||||
method.write(out, 1);
|
method.write(out, 1);
|
||||||
out.println(BRACKET_BLOCK[1]);
|
out.println(BLOCK_DELIMITER.end);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -482,7 +512,7 @@ public class SourceCode {
|
||||||
if (isVolatile) out.print("volatile ");
|
if (isVolatile) out.print("volatile ");
|
||||||
if (isTransient) out.print("transient ");
|
if (isTransient) out.print("transient ");
|
||||||
out.print(type);
|
out.print(type);
|
||||||
writeList(out, BLANK, params, BRACKET_PARAMS, false);
|
writeList(out, BLANK, params, PARAMS_DELIMITER, false);
|
||||||
out.println(SPACE + name + SEMICOLON);
|
out.println(SPACE + name + SEMICOLON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,19 +531,16 @@ public class SourceCode {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Method extends Element<Method> {
|
class Method extends Element<Method> {
|
||||||
private final Class owner;
|
|
||||||
private boolean isAbstract;
|
private boolean isAbstract;
|
||||||
private List<Argument<ClassName,String>> args =
|
private List<Argument<ClassName,String>> args = new ArrayList<Argument<ClassName,String>>();
|
||||||
new ArrayList<Argument<ClassName,String>>();
|
|
||||||
private List<String> codeLines = new ArrayList<String>();
|
private List<String> codeLines = new ArrayList<String>();
|
||||||
|
|
||||||
Method(Class owner, String n, String t) {
|
Method(String n, String t) {
|
||||||
this(owner, n, new ClassName(t));
|
this(n, getOrCreateImport(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Method(Class owner, String name, ClassName returnType) {
|
public Method(String name, ClassName returnType) {
|
||||||
super(name, returnType);
|
super(name, returnType);
|
||||||
this.owner = owner;
|
|
||||||
makePublic();
|
makePublic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,18 +578,18 @@ public class SourceCode {
|
||||||
super.write(out, tab);
|
super.write(out, tab);
|
||||||
if (isAbstract) out.append("abstract ");
|
if (isAbstract) out.append("abstract ");
|
||||||
out.print(type + SPACE + name);
|
out.print(type + SPACE + name);
|
||||||
writeList(out, BLANK, args, BRACKET_ARGS, true);
|
writeList(out, BLANK, args, ARGS_DELIMITER, true);
|
||||||
if (isAbstract) {
|
if (isAbstract) {
|
||||||
out.println(SEMICOLON);
|
out.println(SEMICOLON);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
out.println(SPACE + BRACKET_BLOCK[0]);
|
out.println(SPACE + BLOCK_DELIMITER.start);
|
||||||
for (String line : codeLines) {
|
for (String line : codeLines) {
|
||||||
tab(out, tab+1);
|
tab(out, tab+1);
|
||||||
out.println(line);
|
out.println(line);
|
||||||
}
|
}
|
||||||
tab(out, tab);
|
tab(out, tab);
|
||||||
out.println(BRACKET_BLOCK[1]);
|
out.println(BLOCK_DELIMITER.end);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean equals(Object other) {
|
public boolean equals(Object other) {
|
||||||
|
@ -595,7 +622,7 @@ public class SourceCode {
|
||||||
String pkg = name.getPackageName();
|
String pkg = name.getPackageName();
|
||||||
if (pkg.length() == 0 || pkg.equals(getPackage().name))
|
if (pkg.length() == 0 || pkg.equals(getPackage().name))
|
||||||
return;
|
return;
|
||||||
out.println("import "+ name.getName() + SEMICOLON);
|
out.println("import "+ name.getFullName() + SEMICOLON);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean equals(Object other) {
|
public boolean equals(Object other) {
|
||||||
|
@ -653,12 +680,12 @@ public class SourceCode {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Annotation addArgument(String key, String[] vs) {
|
public Annotation addArgument(String key, String[] vs) {
|
||||||
StringBuffer tmp = new StringBuffer(BRACKET_BLOCK[0]);
|
StringBuffer tmp = new StringBuffer(BLOCK_DELIMITER.start);
|
||||||
for (int i=0; i < vs.length; i++) {
|
for (int i=0; i < vs.length; i++) {
|
||||||
tmp.append(quote(vs[i]));
|
tmp.append(quote(vs[i]));
|
||||||
tmp.append(i != vs.length-1 ? COMMA : BLANK);
|
tmp.append(i != vs.length-1 ? COMMA : BLANK);
|
||||||
}
|
}
|
||||||
tmp.append(BRACKET_BLOCK[1]);
|
tmp.append(BLOCK_DELIMITER.end);
|
||||||
return addArgument(key, tmp.toString(), false);
|
return addArgument(key, tmp.toString(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -670,7 +697,7 @@ public class SourceCode {
|
||||||
public void write(PrintWriter out, int tab) {
|
public void write(PrintWriter out, int tab) {
|
||||||
tab(out, tab);
|
tab(out, tab);
|
||||||
out.println("@"+name);
|
out.println("@"+name);
|
||||||
writeList(out, BLANK, args, BRACKET_ARGS, false);
|
writeList(out, BLANK, args, ARGS_DELIMITER, false);
|
||||||
out.println();
|
out.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -732,11 +759,10 @@ public class SourceCode {
|
||||||
/**
|
/**
|
||||||
* Represents fully-qualified name of a Java type.
|
* Represents fully-qualified name of a Java type.
|
||||||
*
|
*
|
||||||
* Constructing a name adds it to the list of imports for the enclosing
|
* NOTE: Do not construct directly unless necessary.
|
||||||
* SourceCode.
|
* @see SourceCode#getOrCreateImport(String)
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
class ClassName implements Comparable<ClassName> {
|
private class ClassName implements Comparable<ClassName> {
|
||||||
public final String fullName;
|
public final String fullName;
|
||||||
public final String simpleName;
|
public final String simpleName;
|
||||||
public final String pkgName;
|
public final String pkgName;
|
||||||
|
@ -756,13 +782,12 @@ public class SourceCode {
|
||||||
throw new IllegalArgumentException(_loc.get("src-invalid-type",
|
throw new IllegalArgumentException(_loc.get("src-invalid-type",
|
||||||
name).toString());
|
name).toString());
|
||||||
}
|
}
|
||||||
addImport(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets fully qualified name of this receiver.
|
* Gets fully qualified name of this receiver.
|
||||||
*/
|
*/
|
||||||
public String getName() {
|
public String getFullName() {
|
||||||
return fullName + arrayMarker;
|
return fullName + arrayMarker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,6 +859,25 @@ public class SourceCode {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class Delimiter {
|
||||||
|
final char start;
|
||||||
|
final char end;
|
||||||
|
|
||||||
|
public Delimiter() {
|
||||||
|
this((char)0, (char)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Delimiter(String pair) {
|
||||||
|
this(pair.charAt(0), pair.charAt(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Delimiter(char start, char end) {
|
||||||
|
super();
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static {
|
static {
|
||||||
reserved.add("abstract");
|
reserved.add("abstract");
|
||||||
reserved.add("continue");
|
reserved.add("continue");
|
||||||
|
|
Loading…
Reference in New Issue