This commit is contained in:
Tim Bell 2009-10-07 14:14:45 -07:00
commit c824fc2f7a
66 changed files with 7664 additions and 1417 deletions

@ -286,10 +286,10 @@
jarclasspath="javadoc.jar doclets.jar javac.jar"/>
</target>
<target name="build-javah" depends="build-javadoc">
<target name="build-javah" depends="build-javac">
<build-tool name="javah"
includes="${javah.includes}"
jarclasspath="javadoc.jar doclets.jar javac.jar"/>
jarclasspath="javac.jar"/>
</target>
<target name="build-classes-javah" depends="build-classes-javadoc">

@ -201,7 +201,7 @@ public class Apt extends ListBuffer<Env<AttrContext>> {
computeAnnotationSet(param, annotationSet);
if (symbol.members() != null) {
for(Scope.Entry e: symbol.members().table)
for(Scope.Entry e = symbol.members().elems; e != null; e = e.sibling)
computeAnnotationSet(e.sym, annotationSet);
}
}

@ -67,15 +67,15 @@ public class SourcePositionImpl implements SourcePosition {
public String toString() {
int ln = line();
return (ln == Position.NOPOS)
? sourcefile.toString()
: sourcefile + ":" + ln;
? sourcefile.getName()
: sourcefile.getName() + ":" + ln;
}
/**
* {@inheritDoc}
*/
public File file() {
return new File(sourcefile.toString());
return new File(sourcefile.toUri());
}
/**

@ -34,6 +34,7 @@ import java.net.URISyntaxException;
import java.nio.charset.CharsetDecoder;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.NestingKind;
import javax.tools.FileObject;
import javax.tools.JavaFileObject;
import static javax.tools.JavaFileObject.Kind.*;
@ -49,33 +50,15 @@ public abstract class BaseFileObject implements JavaFileObject {
this.fileManager = fileManager;
}
public JavaFileObject.Kind getKind() {
String n = getName();
if (n.endsWith(CLASS.extension))
return CLASS;
else if (n.endsWith(SOURCE.extension))
return SOURCE;
else if (n.endsWith(HTML.extension))
return HTML;
else
return OTHER;
}
/** Return a short name for the object, such as for use in raw diagnostics
*/
public abstract String getShortName();
@Override
public String toString() {
return getPath();
return getClass().getSimpleName() + "[" + getName() + "]";
}
/** @deprecated see bug 6410637 */
@Deprecated
public String getPath() {
return getName();
}
/** @deprecated see bug 6410637 */
@Deprecated
abstract public String getName();
public NestingKind getNestingKind() { return null; }
public Modifier getAccessLevel() { return null; }
@ -90,6 +73,17 @@ public abstract class BaseFileObject implements JavaFileObject {
protected abstract String inferBinaryName(Iterable<? extends File> path);
protected static JavaFileObject.Kind getKind(String filename) {
if (filename.endsWith(CLASS.extension))
return CLASS;
else if (filename.endsWith(SOURCE.extension))
return SOURCE;
else if (filename.endsWith(HTML.extension))
return HTML;
else
return OTHER;
}
protected static String removeExtension(String fileName) {
int lastDot = fileName.lastIndexOf(".");
return (lastDot == -1 ? fileName : fileName.substring(0, lastDot));
@ -115,6 +109,17 @@ public abstract class BaseFileObject implements JavaFileObject {
}
}
/** Return the last component of a presumed hierarchical URI.
* From the scheme specific part of the URI, it returns the substring
* after the last "/" if any, or everything if no "/" is found.
*/
public static String getSimpleName(FileObject fo) {
URI uri = fo.toUri();
String s = uri.getSchemeSpecificPart();
return s.substring(s.lastIndexOf("/") + 1); // safe when / not found
}
/** The file manager that created this JavaFileObject. */
protected final JavacFileManager fileManager;
}

@ -1116,36 +1116,6 @@ public class JavacFileManager implements StandardJavaFileManager {
throw new IllegalArgumentException("Invalid relative path: " + file);
}
@SuppressWarnings("deprecation") // bug 6410637
public static String getJavacFileName(FileObject file) {
if (file instanceof BaseFileObject)
return ((BaseFileObject)file).getPath();
URI uri = file.toUri();
String scheme = uri.getScheme();
if (scheme == null || scheme.equals("file") || scheme.equals("jar"))
return uri.getPath();
else
return uri.toString();
}
@SuppressWarnings("deprecation") // bug 6410637
public static String getJavacBaseFileName(FileObject file) {
if (file instanceof BaseFileObject)
return ((BaseFileObject)file).getName();
URI uri = file.toUri();
String scheme = uri.getScheme();
if (scheme == null || scheme.equals("file") || scheme.equals("jar")) {
String path = uri.getPath();
if (path == null)
return null;
if (scheme != null && scheme.equals("jar"))
path = path.substring(path.lastIndexOf('!') + 1);
return path.substring(path.lastIndexOf('/') + 1);
} else {
return uri.toString();
}
}
private static <T> T nullCheck(T o) {
o.getClass(); // null check
return o;

@ -68,98 +68,38 @@ class RegularFileObject extends BaseFileObject {
this.f = f;
}
@Override
public URI toUri() {
return f.toURI().normalize();
}
@Override
public String getName() {
return f.getPath();
}
@Override
public String getShortName() {
return name;
}
@Override
public JavaFileObject.Kind getKind() {
return getKind(name);
}
@Override
public InputStream openInputStream() throws IOException {
return new FileInputStream(f);
}
@Override
protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors);
}
public OutputStream openOutputStream() throws IOException {
ensureParentDirectoriesExist();
return new FileOutputStream(f);
}
public Writer openWriter() throws IOException {
ensureParentDirectoriesExist();
return new OutputStreamWriter(new FileOutputStream(f), fileManager.getEncodingName());
}
@Override
protected String inferBinaryName(Iterable<? extends File> path) {
String fPath = f.getPath();
//System.err.println("RegularFileObject " + file + " " +r.getPath());
for (File dir: path) {
//System.err.println("dir: " + dir);
String dPath = dir.getPath();
if (dPath.length() == 0)
dPath = System.getProperty("user.dir");
if (!dPath.endsWith(File.separator))
dPath += File.separator;
if (fPath.regionMatches(true, 0, dPath, 0, dPath.length())
&& new File(fPath.substring(0, dPath.length())).equals(new File(dPath))) {
String relativeName = fPath.substring(dPath.length());
return removeExtension(relativeName).replace(File.separatorChar, '.');
}
}
return null;
}
private void ensureParentDirectoriesExist() throws IOException {
if (!hasParents) {
File parent = f.getParentFile();
if (parent != null && !parent.exists()) {
if (!parent.mkdirs()) {
if (!parent.exists() || !parent.isDirectory()) {
throw new IOException("could not create parent directories");
}
}
}
hasParents = true;
}
}
@Deprecated
public String getName() {
return name;
}
public boolean isNameCompatible(String cn, JavaFileObject.Kind kind) {
cn.getClass();
// null check
if (kind == Kind.OTHER && getKind() != kind) {
return false;
}
String n = cn + kind.extension;
if (name.equals(n)) {
return true;
}
if (name.equalsIgnoreCase(n)) {
try {
// allow for Windows
return f.getCanonicalFile().getName().equals(n);
} catch (IOException e) {
}
}
return false;
}
@Deprecated
@Override
public String getPath() {
return f.getPath();
}
public long getLastModified() {
return f.lastModified();
}
public boolean delete() {
return f.delete();
}
public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
CharBuffer cb = fileManager.getCachedContent(this);
if (cb == null) {
@ -183,6 +123,82 @@ class RegularFileObject extends BaseFileObject {
return cb;
}
@Override
public Writer openWriter() throws IOException {
ensureParentDirectoriesExist();
return new OutputStreamWriter(new FileOutputStream(f), fileManager.getEncodingName());
}
@Override
public long getLastModified() {
return f.lastModified();
}
@Override
public boolean delete() {
return f.delete();
}
@Override
protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors);
}
@Override
protected String inferBinaryName(Iterable<? extends File> path) {
String fPath = f.getPath();
//System.err.println("RegularFileObject " + file + " " +r.getPath());
for (File dir: path) {
//System.err.println("dir: " + dir);
String dPath = dir.getPath();
if (dPath.length() == 0)
dPath = System.getProperty("user.dir");
if (!dPath.endsWith(File.separator))
dPath += File.separator;
if (fPath.regionMatches(true, 0, dPath, 0, dPath.length())
&& new File(fPath.substring(0, dPath.length())).equals(new File(dPath))) {
String relativeName = fPath.substring(dPath.length());
return removeExtension(relativeName).replace(File.separatorChar, '.');
}
}
return null;
}
@Override
public boolean isNameCompatible(String cn, JavaFileObject.Kind kind) {
cn.getClass();
// null check
if (kind == Kind.OTHER && getKind() != kind) {
return false;
}
String n = cn + kind.extension;
if (name.equals(n)) {
return true;
}
if (name.equalsIgnoreCase(n)) {
try {
// allow for Windows
return f.getCanonicalFile().getName().equals(n);
} catch (IOException e) {
}
}
return false;
}
private void ensureParentDirectoriesExist() throws IOException {
if (!hasParents) {
File parent = f.getParentFile();
if (parent != null && !parent.exists()) {
if (!parent.mkdirs()) {
if (!parent.exists() || !parent.isDirectory()) {
throw new IOException("could not create parent directories");
}
}
}
hasParents = true;
}
}
@Override
public boolean equals(Object other) {
if (!(other instanceof RegularFileObject)) {
@ -200,8 +216,4 @@ class RegularFileObject extends BaseFileObject {
public int hashCode() {
return f.hashCode();
}
public URI toUri() {
return f.toURI().normalize();
}
}

@ -95,7 +95,7 @@ public class SymbolArchive extends ZipArchive {
@Override
protected String inferBinaryName(Iterable<? extends File> path) {
String entryName = getZipEntryName();
String entryName = entry.getName();
String prefix = ((SymbolArchive) zarch).prefix.path;
if (entryName.startsWith(prefix))
entryName = entryName.substring(prefix.length());

@ -147,51 +147,37 @@ public class ZipArchive implements Archive {
this.entry = entry;
}
public URI toUri() {
File zipFile = new File(zarch.zdir.getName());
return createJarUri(zipFile, entry.getName());
}
@Override
public String getName() {
return zarch.zdir.getName() + "(" + entry.getName() + ")";
}
@Override
public String getShortName() {
return new File(zarch.zdir.getName()).getName() + "(" + entry + ")";
}
@Override
public JavaFileObject.Kind getKind() {
return getKind(entry.getName());
}
@Override
public InputStream openInputStream() throws IOException {
return zarch.zdir.getInputStream(entry);
}
@Override
public OutputStream openOutputStream() throws IOException {
throw new UnsupportedOperationException();
}
@Override
protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors);
}
public Writer openWriter() throws IOException {
throw new UnsupportedOperationException();
}
@Deprecated
public String getName() {
return name;
}
public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
cn.getClass();
// null check
if (k == Kind.OTHER && getKind() != k) {
return false;
}
return name.equals(cn + k.extension);
}
@Deprecated
@Override
public String getPath() {
return zarch.zdir.getName() + "(" + entry + ")";
}
public long getLastModified() {
return entry.getTime();
}
public boolean delete() {
throw new UnsupportedOperationException();
}
public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
CharBuffer cb = fileManager.getCachedContent(this);
if (cb == null) {
@ -215,6 +201,42 @@ public class ZipArchive implements Archive {
return cb;
}
@Override
public Writer openWriter() throws IOException {
throw new UnsupportedOperationException();
}
@Override
public long getLastModified() {
return entry.getTime();
}
@Override
public boolean delete() {
throw new UnsupportedOperationException();
}
@Override
protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors);
}
@Override
protected String inferBinaryName(Iterable<? extends File> path) {
String entryName = entry.getName();
return removeExtension(entryName).replace('/', '.');
}
@Override
public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
cn.getClass();
// null check
if (k == Kind.OTHER && getKind() != k) {
return false;
}
return name.equals(cn + k.extension);
}
@Override
public boolean equals(Object other) {
if (!(other instanceof ZipFileObject)) {
@ -228,25 +250,6 @@ public class ZipArchive implements Archive {
public int hashCode() {
return zarch.zdir.hashCode() + name.hashCode();
}
public String getZipName() {
return zarch.zdir.getName();
}
public String getZipEntryName() {
return entry.getName();
}
public URI toUri() {
File zipFile = new File(getZipName());
return createJarUri(zipFile, entry.getName());
}
@Override
protected String inferBinaryName(Iterable<? extends File> path) {
String entryName = getZipEntryName();
return removeExtension(entryName).replace('/', '.');
}
}
}

@ -123,88 +123,41 @@ public class ZipFileIndexArchive implements Archive {
this.zipName = zipFileName;
}
public InputStream openInputStream() throws IOException {
@Override
public URI toUri() {
return createJarUri(zipName, getPrefixedEntryName());
}
@Override
public String getName() {
return zipName + "(" + getPrefixedEntryName() + ")";
}
@Override
public String getShortName() {
return zipName.getName() + "(" + entry.getName() + ")";
}
@Override
public JavaFileObject.Kind getKind() {
return getKind(entry.getName());
}
@Override
public InputStream openInputStream() throws IOException {
if (inputStream == null) {
inputStream = new ByteArrayInputStream(read());
assert entry != null; // see constructor
inputStream = new ByteArrayInputStream(zfIndex.read(entry));
}
return inputStream;
}
@Override
protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors);
}
public OutputStream openOutputStream() throws IOException {
throw new UnsupportedOperationException();
}
public Writer openWriter() throws IOException {
throw new UnsupportedOperationException();
}
/** @deprecated see bug 6410637 */
@Deprecated
public String getName() {
return name;
}
public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
cn.getClass(); // null check
if (k == Kind.OTHER && getKind() != k)
return false;
return name.equals(cn + k.extension);
}
/** @deprecated see bug 6410637 */
@Deprecated
@Override
public String getPath() {
return zipName + "(" + entry.getName() + ")";
}
public long getLastModified() {
return entry.getLastModified();
}
public boolean delete() {
throw new UnsupportedOperationException();
}
@Override
public boolean equals(Object other) {
if (!(other instanceof ZipFileIndexFileObject))
return false;
ZipFileIndexFileObject o = (ZipFileIndexFileObject) other;
return entry.equals(o.entry);
}
@Override
public int hashCode() {
return zipName.hashCode() + (name.hashCode() << 10);
}
public String getZipName() {
return zipName.getPath();
}
public String getZipEntryName() {
return entry.getName();
}
public URI toUri() {
if (zfIndex.symbolFilePrefix != null)
return createJarUri(zipName, zfIndex.symbolFilePrefix.path + entry.getName());
else
return createJarUri(zipName, entry.getName());
}
private byte[] read() throws IOException {
assert entry != null; // see constructor
return zfIndex.read(entry);
}
public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
CharBuffer cb = fileManager.getCachedContent(this);
if (cb == null) {
@ -227,9 +180,29 @@ public class ZipFileIndexArchive implements Archive {
return cb;
}
@Override
public Writer openWriter() throws IOException {
throw new UnsupportedOperationException();
}
@Override
public long getLastModified() {
return entry.getLastModified();
}
@Override
public boolean delete() {
throw new UnsupportedOperationException();
}
@Override
protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
return fileManager.getDecoder(fileManager.getEncodingName(), ignoreEncodingErrors);
}
@Override
protected String inferBinaryName(Iterable<? extends File> path) {
String entryName = getZipEntryName();
String entryName = entry.getName();
if (zfIndex.symbolFilePrefix != null) {
String prefix = zfIndex.symbolFilePrefix.path;
if (entryName.startsWith(prefix))
@ -237,6 +210,34 @@ public class ZipFileIndexArchive implements Archive {
}
return removeExtension(entryName).replace('/', '.');
}
@Override
public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
cn.getClass(); // null check
if (k == Kind.OTHER && getKind() != k)
return false;
return name.equals(cn + k.extension);
}
@Override
public boolean equals(Object other) {
if (!(other instanceof ZipFileIndexFileObject))
return false;
ZipFileIndexFileObject o = (ZipFileIndexFileObject) other;
return entry.equals(o.entry);
}
@Override
public int hashCode() {
return zipName.hashCode() + (name.hashCode() << 10);
}
private String getPrefixedEntryName() {
if (zfIndex.symbolFilePrefix != null)
return zfIndex.symbolFilePrefix.path + entry.getName();
else
return entry.getName();
}
}
}

@ -2563,38 +2563,73 @@ public class ClassReader implements Completer {
this.flatname = flatname;
}
public InputStream openInputStream() {
throw new UnsupportedOperationException();
@Override
public URI toUri() {
try {
return new URI(null, name.toString(), null);
} catch (URISyntaxException e) {
throw new CannotCreateUriError(name.toString(), e);
}
}
public OutputStream openOutputStream() {
throw new UnsupportedOperationException();
}
public Reader openReader() {
throw new UnsupportedOperationException();
}
public Writer openWriter() {
throw new UnsupportedOperationException();
}
/** @deprecated see bug 6410637 */
@Deprecated
@Override
public String getName() {
return name.toString();
}
@Override
public String getShortName() {
return getName();
}
@Override
public JavaFileObject.Kind getKind() {
return getKind(getName());
}
@Override
public InputStream openInputStream() {
throw new UnsupportedOperationException();
}
@Override
public OutputStream openOutputStream() {
throw new UnsupportedOperationException();
}
@Override
public CharBuffer getCharContent(boolean ignoreEncodingErrors) {
throw new UnsupportedOperationException();
}
@Override
public Reader openReader(boolean ignoreEncodingErrors) {
throw new UnsupportedOperationException();
}
@Override
public Writer openWriter() {
throw new UnsupportedOperationException();
}
@Override
public long getLastModified() {
throw new UnsupportedOperationException();
}
@Override
public boolean delete() {
throw new UnsupportedOperationException();
}
public CharBuffer getCharContent(boolean ignoreEncodingErrors) {
throw new UnsupportedOperationException();
@Override
protected String inferBinaryName(Iterable<? extends File> path) {
return flatname.toString();
}
@Override
public boolean isNameCompatible(String simpleName, JavaFileObject.Kind kind) {
return true; // fail-safe mode
}
@Override
@ -2609,27 +2644,5 @@ public class ClassReader implements Completer {
public int hashCode() {
return name.hashCode();
}
public boolean isNameCompatible(String simpleName, JavaFileObject.Kind kind) {
return true; // fail-safe mode
}
public URI toUri() {
try {
return new URI(null, name.toString(), null);
} catch (URISyntaxException e) {
throw new CannotCreateUriError(name.toString(), e);
}
}
@Override
public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
throw new UnsupportedOperationException();
}
@Override
protected String inferBinaryName(Iterable<? extends File> path) {
return flatname.toString();
}
}
}

@ -36,6 +36,7 @@ import javax.tools.JavaFileObject;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.file.BaseFileObject;
import com.sun.tools.javac.util.*;
import static com.sun.tools.javac.code.BoundKind.*;
@ -1685,13 +1686,8 @@ public class ClassWriter extends ClassFile {
// the last possible moment because the sourcefile may be used
// elsewhere in error diagnostics. Fixes 4241573.
//databuf.appendChar(c.pool.put(c.sourcefile));
String filename = c.sourcefile.toString();
int sepIdx = filename.lastIndexOf(File.separatorChar);
// Allow '/' as separator on all platforms, e.g., on Win32.
int slashIdx = filename.lastIndexOf('/');
if (slashIdx > sepIdx) sepIdx = slashIdx;
if (sepIdx >= 0) filename = filename.substring(sepIdx + 1);
databuf.appendChar(c.pool.put(names.fromString(filename)));
String simpleName = BaseFileObject.getSimpleName(c.sourcefile);
databuf.appendChar(c.pool.put(names.fromString(simpleName)));
endAttr(alenIdx);
acount++;
}

@ -2236,7 +2236,7 @@ public class JavacParser implements Parser {
/* AnnotationValue = ConditionalExpression
* | Annotation
* | "{" [ AnnotationValue { "," AnnotationValue } ] "}"
* | "{" [ AnnotationValue { "," AnnotationValue } ] [","] "}"
*/
JCExpression annotationValue() {
int pos;
@ -2253,7 +2253,7 @@ public class JavacParser implements Parser {
buf.append(annotationValue());
while (S.token() == COMMA) {
S.nextToken();
if (S.token() == RPAREN) break;
if (S.token() == RBRACE) break;
buf.append(annotationValue());
}
}

@ -42,8 +42,8 @@ import com.sun.tools.javac.code.Printer;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Type.CapturedType;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.file.BaseFileObject;
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*;
/**
@ -133,8 +133,15 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
}
public String formatSource(JCDiagnostic d, boolean fullname, Locale l) {
assert (d.getSource() != null);
return fullname ? d.getSourceName() : d.getSource().getName();
JavaFileObject fo = d.getSource();
if (fo == null)
throw new IllegalArgumentException(); // d should have source set
if (fullname)
return fo.getName();
else if (fo instanceof BaseFileObject)
return ((BaseFileObject) fo).getShortName();
else
return BaseFileObject.getSimpleName(fo);
}
/**
@ -182,7 +189,7 @@ public abstract class AbstractDiagnosticFormatter implements DiagnosticFormatter
return printer.visit((Symbol)arg, l);
}
else if (arg instanceof JavaFileObject) {
return JavacFileManager.getJavacBaseFileName((JavaFileObject)arg);
return ((JavaFileObject)arg).getName();
}
else if (arg instanceof Formattable) {
return ((Formattable)arg).toString(l, messages);

@ -83,16 +83,28 @@ public class Constants {
*/
public static String format(Object value) {
if (value instanceof Byte) return formatByte((Byte) value);
if (value instanceof Short) return formatShort((Short) value);
if (value instanceof Long) return formatLong((Long) value);
if (value instanceof Float) return formatFloat((Float) value);
if (value instanceof Double) return formatDouble((Double) value);
if (value instanceof Character) return formatChar((Character) value);
if (value instanceof String) return formatString((String) value);
return value + "";
if (value instanceof Integer ||
value instanceof Boolean) return value.toString();
else
throw new IllegalArgumentException("Argument is not a primitive type or a string; it " +
((value == null) ?
"is a null value." :
"has class " +
value.getClass().getName()) + "." );
}
private static String formatByte(byte b) {
return String.format("0x%02x", b);
return String.format("(byte)0x%02x", b);
}
private static String formatShort(short s) {
return String.format("(short)%d", s);
}
private static String formatLong(long lng) {

@ -239,9 +239,9 @@ public class Convert {
case '\"': return "\\\"";
case '\\': return "\\\\";
default:
return (ch > 127 || isPrintableAscii(ch))
return (isPrintableAscii(ch))
? String.valueOf(ch)
: String.format("\\%03o", (int) ch);
: String.format("\\u%04x", (int) ch);
}
}

@ -69,10 +69,6 @@ public class DiagnosticSource {
return fileObject;
}
public CharSequence getName() {
return JavacFileManager.getJavacBaseFileName(fileObject);
}
/** Return the one-based line number associated with a given pos
* for the current source file. Zero is returned if no line exists
* for the given position.

@ -32,7 +32,6 @@ import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.api.DiagnosticFormatter;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.tree.JCTree;
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*;
@ -353,15 +352,6 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
return source.getFile();
}
/**
* Get the name of the source file referred to by this diagnostic.
* @return the name of the source referred to with this diagnostic, or null if none
*/
public String getSourceName() {
JavaFileObject s = getSource();
return s == null ? null : JavacFileManager.getJavacFileName(s);
}
/**
* Get the source referred to by this diagnostic.
* @return the source referred to with this diagnostic, or null if none
@ -437,6 +427,7 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
/**
* Return the standard presentation of this diagnostic.
*/
@Override
public String toString() {
return defaultFormatter.format(this,Locale.getDefault());
}

@ -33,7 +33,6 @@ import java.util.Set;
import javax.tools.DiagnosticListener;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.api.DiagnosticFormatter;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
@ -428,7 +427,7 @@ public class Log extends AbstractLog {
JavaFileObject file = source.getFile();
if (file != null)
printLines(errWriter,
JavacFileManager.getJavacFileName(file) + ":" +
file.getName() + ":" +
line + ": " + msg);
printErrLine(pos, errWriter);
}

@ -30,6 +30,7 @@ import java.util.Locale;
import com.sun.tools.javac.api.DiagnosticFormatter.Configuration.*;
import com.sun.tools.javac.api.Formattable;
import com.sun.tools.javac.file.BaseFileObject;
import com.sun.tools.javac.util.AbstractDiagnosticFormatter.SimpleConfiguration;
import static com.sun.tools.javac.api.DiagnosticFormatter.PositionKind.*;
@ -109,6 +110,8 @@ public final class RawDiagnosticFormatter extends AbstractDiagnosticFormatter {
String s;
if (arg instanceof Formattable)
s = arg.toString();
else if (arg instanceof BaseFileObject)
s = ((BaseFileObject) arg).getShortName();
else
s = super.formatArgument(diag, arg, null);
if (arg instanceof JCDiagnostic)

@ -95,7 +95,7 @@ public class SourcePositionImpl implements SourcePosition {
public String toString() {
// Backwards compatibility hack. ZipFileObjects use the format
// zipfile(zipentry) but javadoc has been using zipfile/zipentry
String fn = filename.toString();
String fn = filename.getName();
if (fn.endsWith(")")) {
int paren = fn.lastIndexOf("(");
if (paren != -1)

@ -27,15 +27,32 @@ package com.sun.tools.javah;
import java.io.UnsupportedEncodingException;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import com.sun.javadoc.*;
import java.io.*;
import java.util.Stack;
import java.util.Vector;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.FileObject;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;
/**
* An abstraction for generating support files required by native methods.
@ -43,31 +60,39 @@ import java.util.Arrays;
* original writing, this interface is rich enough to support JNI and the
* old 1.0-style native method interface.
*
* <p><b>This is NOT part of any API supported by Sun Microsystems.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*
* @author Sucheta Dambalkar(Revised)
*/
public abstract class Gen {
protected String lineSep = System.getProperty("line.separator");
RootDoc root;
protected ProcessingEnvironment processingEnvironment;
protected Types types;
protected Elements elems;
protected Mangle mangler;
protected Util util;
protected Gen(Util util) {
this.util = util;
}
/*
* List of classes for which we must generate output.
*/
protected ClassDoc[] classes;
protected Set<TypeElement> classes;
static private final boolean isWindows =
System.getProperty("os.name").startsWith("Windows");
public Gen(RootDoc root){
this.root = root;
}
/**
* Override this abstract method, generating content for the named
* class into the outputstream.
*/
protected abstract void write(OutputStream o, ClassDoc clazz)
throws ClassNotFoundException;
protected abstract void write(OutputStream o, TypeElement clazz) throws Util.Exit;
/**
* Override this method to provide a list of #include statements
@ -78,31 +103,29 @@ public abstract class Gen {
/*
* Output location.
*/
protected String outDir;
protected String outFile;
protected JavaFileManager fileManager;
protected JavaFileObject outFile;
public void setOutDir(String outDir) {
/* Check important, otherwise concatenation of two null strings
* produces the "nullnull" String.
*/
if (outDir != null) {
this.outDir = outDir + System.getProperty("file.separator");
File d = new File(outDir);
if (!d.exists())
if (!d.mkdirs())
Util.error("cant.create.dir", d.toString());
}
public void setFileManager(JavaFileManager fm) {
fileManager = fm;
}
public void setOutFile(String outFile) {
public void setOutFile(JavaFileObject outFile) {
this.outFile = outFile;
}
public void setClasses(ClassDoc[] classes) {
public void setClasses(Set<TypeElement> classes) {
this.classes = classes;
}
void setProcessingEnvironment(ProcessingEnvironment pEnv) {
processingEnvironment = pEnv;
elems = pEnv.getElementUtils();
types = pEnv.getTypeUtils();
mangler = new Mangle(elems, types);
}
/*
* Smartness with generated files.
*/
@ -116,12 +139,11 @@ public abstract class Gen {
* We explicitly need to write ASCII files because that is what C
* compilers understand.
*/
protected PrintWriter wrapWriter(OutputStream o) {
protected PrintWriter wrapWriter(OutputStream o) throws Util.Exit {
try {
return new
PrintWriter(new OutputStreamWriter(o, "ISO8859_1"), true);
return new PrintWriter(new OutputStreamWriter(o, "ISO8859_1"), true);
} catch (UnsupportedEncodingException use) {
Util.bug("encoding.iso8859_1.not.found");
util.bug("encoding.iso8859_1.not.found");
return null; /* dead code */
}
}
@ -133,26 +155,25 @@ public abstract class Gen {
* Buffer size chosen as an approximation from a single sampling of:
* expr `du -sk` / `ls *.h | wc -l`
*/
public void run() throws IOException, ClassNotFoundException {
public void run() throws IOException, ClassNotFoundException, Util.Exit {
int i = 0;
if (outFile != null) {
/* Everything goes to one big file... */
ByteArrayOutputStream bout = new ByteArrayOutputStream(8192);
writeFileTop(bout); /* only once */
for (i = 0; i < classes.length; i++) {
write(bout, classes[i]);
for (TypeElement t: classes) {
write(bout, t);
}
writeIfChanged(bout.toByteArray(), outFile);
} else {
/* Each class goes to its own file... */
for (i = 0; i < classes.length; i++) {
for (TypeElement t: classes) {
ByteArrayOutputStream bout = new ByteArrayOutputStream(8192);
writeFileTop(bout);
ClassDoc clazz = classes[i];
write(bout, clazz);
writeIfChanged(bout.toByteArray(), getFileName(clazz.qualifiedName()));
write(bout, t);
writeIfChanged(bout.toByteArray(), getFileObject(t.getQualifiedName()));
}
}
}
@ -162,8 +183,7 @@ public abstract class Gen {
* is done if either the file doesn't exist or if the contents are
* different.
*/
private void writeIfChanged(byte[] b, String file) throws IOException {
File f = new File(file);
private void writeIfChanged(byte[] b, FileObject file) throws IOException {
boolean mustWrite = false;
String event = "[No need to update file ";
@ -171,71 +191,80 @@ public abstract class Gen {
mustWrite = true;
event = "[Forcefully writing file ";
} else {
if (!f.exists()) {
mustWrite = true;
event = "[Creating file ";
} else {
int l = (int)f.length();
if (b.length != l) {
InputStream in;
byte[] a;
try {
// regrettably, there's no API to get the length in bytes
// for a FileObject, so we can't short-circuit reading the
// file here
in = file.openInputStream();
a = readBytes(in);
if (!Arrays.equals(a, b)) {
mustWrite = true;
event = "[Overwriting file ";
} else {
/* Lengths are equal, so read it. */
byte[] a = new byte[l];
FileInputStream in = new FileInputStream(f);
if (in.read(a) != l) {
in.close();
/* This can't happen, we already checked the length. */
Util.error("not.enough.bytes", Integer.toString(l),
f.toString());
}
in.close();
while (--l >= 0) {
if (a[l] != b[l]) {
mustWrite = true;
event = "[Overwriting file ";
}
}
}
} catch (FileNotFoundException e) {
mustWrite = true;
event = "[Creating file ";
}
}
if (Util.verbose)
Util.log(event + file + "]");
if (util.verbose)
util.log(event + file + "]");
if (mustWrite) {
OutputStream out = new FileOutputStream(file);
OutputStream out = file.openOutputStream();
out.write(b); /* No buffering, just one big write! */
out.close();
}
}
protected String defineForStatic(ClassDoc c, FieldDoc f){
protected byte[] readBytes(InputStream in) throws IOException {
try {
byte[] array = new byte[in.available() + 1];
int offset = 0;
int n;
while ((n = in.read(array, offset, array.length - offset)) != -1) {
offset += n;
if (offset == array.length)
array = Arrays.copyOf(array, array.length * 2);
}
String cnamedoc = c.qualifiedName();
String fnamedoc = f.name();
return Arrays.copyOf(array, offset);
} finally {
in.close();
}
}
String cname = Mangle.mangle(cnamedoc, Mangle.Type.CLASS);
String fname = Mangle.mangle(fnamedoc, Mangle.Type.FIELDSTUB);
protected String defineForStatic(TypeElement c, VariableElement f)
throws Util.Exit {
CharSequence cnamedoc = c.getQualifiedName();
CharSequence fnamedoc = f.getSimpleName();
if (!f.isStatic())
Util.bug("tried.to.define.non.static");
String cname = mangler.mangle(cnamedoc, Mangle.Type.CLASS);
String fname = mangler.mangle(fnamedoc, Mangle.Type.FIELDSTUB);
if (f.isFinal()) {
if (!f.getModifiers().contains(Modifier.STATIC))
util.bug("tried.to.define.non.static");
if (f.getModifiers().contains(Modifier.FINAL)) {
Object value = null;
value = f.constantValue();
value = f.getConstantValue();
if (value != null) { /* so it is a ConstantExpression */
String constString = null;
if ((value instanceof Integer)
|| (value instanceof Byte)
|| (value instanceof Character)
|| (value instanceof Short)
|| (value instanceof Boolean)) {
/* covers byte, boolean, char, short, int */
if(value instanceof Boolean)
constString = (value.toString() == "true") ? "1L" : "0L";
else
constString = value.toString() + "L";
|| (value instanceof Short)) {
/* covers byte, short, int */
constString = value.toString() + "L";
} else if (value instanceof Boolean) {
constString = ((Boolean) value) ? "1L" : "0L";
} else if (value instanceof Character) {
Character ch = (Character) value;
constString = String.valueOf(((int) ch) & 0xffff) + "L";
} else if (value instanceof Long) {
// Visual C++ supports the i64 suffix, not LL.
if (isWindows)
@ -294,24 +323,19 @@ public abstract class Gen {
/*
* File name and file preamble related operations.
*/
protected void writeFileTop(OutputStream o) {
protected void writeFileTop(OutputStream o) throws Util.Exit {
PrintWriter pw = wrapWriter(o);
pw.println("/* DO NOT EDIT THIS FILE - it is machine generated */" + lineSep +
getIncludes());
}
protected String baseFileName(String clazz) {
StringBuffer f =
new StringBuffer(Mangle.mangle(clazz,
Mangle.Type.CLASS));
if (outDir != null) {
f.insert(0, outDir);
}
return f.toString();
protected String baseFileName(CharSequence className) {
return mangler.mangle(className, Mangle.Type.CLASS);
}
protected String getFileName(String clazz) {
return baseFileName(clazz) + getFileSuffix();
protected FileObject getFileObject(CharSequence className) throws IOException {
String name = baseFileName(className) + getFileSuffix();
return fileManager.getFileForOutput(StandardLocation.SOURCE_OUTPUT, "", name, null);
}
protected String getFileSuffix() {
@ -322,26 +346,39 @@ public abstract class Gen {
* Including super classes' fields.
*/
FieldDoc[] getAllFields(ClassDoc subclazz)
throws ClassNotFoundException {
Vector<FieldDoc> fields = new Vector<FieldDoc>();
ClassDoc cd = null;
Stack<Object> s = new Stack<Object>();
List<VariableElement> getAllFields(TypeElement subclazz) {
List<VariableElement> fields = new ArrayList<VariableElement>();
TypeElement cd = null;
Stack<TypeElement> s = new Stack<TypeElement>();
cd = subclazz;
while (true) {
s.push(cd);
ClassDoc c = cd.superclass();
TypeElement c = (TypeElement) (types.asElement(cd.getSuperclass()));
if (c == null)
break;
cd = c;
}
while (!s.empty()) {
cd = (ClassDoc)s.pop();
fields.addAll(Arrays.asList(cd.fields()));
cd = s.pop();
fields.addAll(ElementFilter.fieldsIn(cd.getEnclosedElements()));
}
return fields.toArray(new FieldDoc[fields.size()]);
return fields;
}
// c.f. MethodDoc.signature
String signature(ExecutableElement e) {
StringBuffer sb = new StringBuffer("(");
String sep = "";
for (VariableElement p: e.getParameters()) {
sb.append(sep);
sb.append(types.erasure(p.asType()).toString());
sep = ",";
}
sb.append(")");
return sb.toString();
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2006-2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,32 +23,18 @@
* have any questions.
*/
package com.sun.tools.javac.file;
import javax.tools.FileObject;
package com.sun.tools.javah;
/**
* Provides an easy migration to JSR 199 v3.3. The class is
* deprecated as we should remove it as soon as possible.
*
* <p><b>This is NOT part of any API supported by Sun Microsystems.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*
* @author Peter von der Ah\u00e9
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
* you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
@Deprecated
public class Old199 {
private Old199() {}
public static String getPath(FileObject jfo) {
return JavacFileManager.getJavacFileName(jfo);
public class InternalError extends Error {
private static final long serialVersionUID = 8411861562497165022L;
InternalError(String msg, Throwable cause) {
super("Internal error: " + msg);
initCause(cause);
}
public static String getName(FileObject jfo) {
return JavacFileManager.getJavacBaseFileName(jfo);
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,95 +27,98 @@ package com.sun.tools.javah;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Vector;
import java.util.Enumeration;
import com.sun.javadoc.*;
import java.util.ArrayList;
import java.util.List;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementFilter;
/**
* Header file generator for JNI.
*
* <p><b>This is NOT part of any API supported by Sun Microsystems.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*
* @author Sucheta Dambalkar(Revised)
*/
public class JNI extends Gen {
public JNI(RootDoc root){
super(root);
JNI(Util util) {
super(util);
}
public String getIncludes() {
return "#include <jni.h>";
}
public void write(OutputStream o, ClassDoc clazz)
throws ClassNotFoundException {
String cname = Mangle.mangle(clazz.qualifiedName(), Mangle.Type.CLASS);
public void write(OutputStream o, TypeElement clazz) throws Util.Exit {
String cname = mangler.mangle(clazz.getQualifiedName(), Mangle.Type.CLASS);
PrintWriter pw = wrapWriter(o);
pw.println(guardBegin(cname));
pw.println(cppGuardBegin());
/* Write statics. */
FieldDoc[] classfields = getAllFields(clazz);
List<VariableElement> classfields = getAllFields(clazz);
for (int i = 0; i < classfields.length; i++) {
if (!classfields[i].isStatic())
for (VariableElement v: classfields) {
if (!v.getModifiers().contains(Modifier.STATIC))
continue;
String s = null;
s = defineForStatic(clazz, classfields[i]);
s = defineForStatic(clazz, v);
if (s != null) {
pw.println(s);
}
}
/* Write methods. */
MethodDoc[] classmethods = clazz.methods();
for (int i = 0; i < classmethods.length; i++) {
if(classmethods[i].isNative()){
MethodDoc md = classmethods[i];
Type mtr = classmethods[i].returnType();
String sig = md.signature();
TypeSignature newtypesig = new TypeSignature(root);
String methodName = md.name();
List<ExecutableElement> classmethods = ElementFilter.methodsIn(clazz.getEnclosedElements());
for (ExecutableElement md: classmethods) {
if(md.getModifiers().contains(Modifier.NATIVE)){
TypeMirror mtr = types.erasure(md.getReturnType());
String sig = signature(md);
TypeSignature newtypesig = new TypeSignature(elems);
CharSequence methodName = md.getSimpleName();
boolean longName = false;
for (int j = 0; j < classmethods.length; j++) {
if ((classmethods[j] != md)
&& (methodName.equals(classmethods[j].name()))
&& (classmethods[j].isNative()))
for (ExecutableElement md2: classmethods) {
if ((md2 != md)
&& (methodName.equals(md2.getSimpleName()))
&& (md2.getModifiers().contains(Modifier.NATIVE)))
longName = true;
}
pw.println("/*");
pw.println(" * Class: " + cname);
pw.println(" * Method: " +
Mangle.mangle(methodName, Mangle.Type.FIELDSTUB));
mangler.mangle(methodName, Mangle.Type.FIELDSTUB));
pw.println(" * Signature: " + newtypesig.getTypeSignature(sig, mtr));
pw.println(" */");
pw.println("JNIEXPORT " + jniType(mtr) +
" JNICALL " +
Mangle.mangleMethod(md, root,clazz,
mangler.mangleMethod(md, clazz,
(longName) ?
Mangle.Type.METHOD_JNI_LONG :
Mangle.Type.METHOD_JNI_SHORT));
pw.print(" (JNIEnv *, ");
Parameter[] paramargs = md.parameters();
Type []args =new Type[ paramargs.length];
for(int p = 0; p < paramargs.length; p++){
args[p] = paramargs[p].type();
List<? extends VariableElement> paramargs = md.getParameters();
List<TypeMirror> args = new ArrayList<TypeMirror>();
for (VariableElement p: paramargs) {
args.add(types.erasure(p.asType()));
}
if (md.isStatic())
if (md.getModifiers().contains(Modifier.STATIC))
pw.print("jclass");
else
pw.print("jobject");
if (args.length > 0)
pw.print(", ");
for (int j = 0; j < args.length; j++) {
pw.print(jniType(args[j]));
if (j != (args.length - 1)) {
pw.print(", ");
}
for (TypeMirror arg: args) {
pw.print(", ");
pw.print(jniType(arg));
}
pw.println(");" + lineSep);
}
@ -125,42 +128,54 @@ public class JNI extends Gen {
}
protected final String jniType(Type t){
protected final String jniType(TypeMirror t) throws Util.Exit {
TypeElement throwable = elems.getTypeElement("java.lang.Throwable");
TypeElement jClass = elems.getTypeElement("java.lang.Class");
TypeElement jString = elems.getTypeElement("java.lang.String");
Element tclassDoc = types.asElement(t);
String elmT = t.typeName();
ClassDoc throwable = root.classNamed("java.lang.Throwable");
ClassDoc jClass = root.classNamed("java.lang.Class");
ClassDoc tclassDoc = t.asClassDoc();
if((t.dimension()).indexOf("[]") != -1){
if((t.dimension().indexOf("[][]") != -1)
|| (tclassDoc != null)) return "jobjectArray";
else if(elmT.equals("boolean"))return "jbooleanArray";
else if(elmT.equals("byte"))return "jbyteArray";
else if(elmT.equals("char"))return "jcharArray";
else if(elmT.equals("short"))return "jshortArray";
else if(elmT.equals("int"))return "jintArray";
else if(elmT.equals("long"))return "jlongArray";
else if(elmT.equals("float"))return "jfloatArray";
else if(elmT.equals("double"))return "jdoubleArray";
}else{
if(elmT.equals("void"))return "void";
else if(elmT.equals("String"))return "jstring";
else if(elmT.equals("boolean"))return "jboolean";
else if(elmT.equals("byte"))return "jbyte";
else if(elmT.equals("char"))return "jchar";
else if(elmT.equals("short"))return "jshort";
else if(elmT.equals("int"))return "jint";
else if(elmT.equals("long"))return "jlong";
else if(elmT.equals("float"))return "jfloat";
else if(elmT.equals("double"))return "jdouble";
else if(tclassDoc != null){
if(tclassDoc.subclassOf(throwable)) return "jthrowable";
else if(tclassDoc.subclassOf(jClass)) return "jclass";
else return "jobject";
switch (t.getKind()) {
case ARRAY: {
TypeMirror ct = ((ArrayType) t).getComponentType();
switch (ct.getKind()) {
case BOOLEAN: return "jbooleanArray";
case BYTE: return "jbyteArray";
case CHAR: return "jcharArray";
case SHORT: return "jshortArray";
case INT: return "jintArray";
case LONG: return "jlongArray";
case FLOAT: return "jfloatArray";
case DOUBLE: return "jdoubleArray";
case ARRAY:
case DECLARED: return "jobjectArray";
default: throw new Error(ct.toString());
}
}
case VOID: return "void";
case BOOLEAN: return "jboolean";
case BYTE: return "jbyte";
case CHAR: return "jchar";
case SHORT: return "jshort";
case INT: return "jint";
case LONG: return "jlong";
case FLOAT: return "jfloat";
case DOUBLE: return "jdouble";
case DECLARED: {
if (tclassDoc.equals(jString))
return "jstring";
else if (types.isAssignable(t, throwable.asType()))
return "jthrowable";
else if (types.isAssignable(t, jClass.asType()))
return "jclass";
else
return "jobject";
}
}
Util.bug("jni.unknown.type");
util.bug("jni.unknown.type");
return null; /* dead code. */
}
}

@ -0,0 +1,63 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.tools.javah;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import javax.tools.DiagnosticListener;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.util.Context;
/**
* javah's implementation of JavaFileManager.
*
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
* you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
class JavahFileManager extends JavacFileManager {
private JavahFileManager(Context context, Charset charset) {
super(context, true, charset);
setIgnoreSymbolFile(true);
}
static JavahFileManager create(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) {
Context javac_context = new Context();
if (dl != null)
javac_context.put(DiagnosticListener.class, dl);
javac_context.put(com.sun.tools.javac.util.Log.outKey, log);
return new JavahFileManager(javac_context, null);
}
void setIgnoreSymbolFile(boolean b) {
ignoreSymbolFile = b;
}
}

@ -0,0 +1,724 @@
/*
* Copyright 2002-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.tools.javah;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVisitor;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.SimpleTypeVisitor6;
import javax.lang.model.util.Types;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticListener;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
/**
* Javah generates support files for native methods.
* Parse commandline options & Invokes javadoc to execute those commands.
*
* <p><b>This is NOT part of any API supported by Sun Microsystems.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*
* @author Sucheta Dambalkar
* @author Jonathan Gibbons
*/
public class JavahTask implements NativeHeaderTool.NativeHeaderTask {
public class BadArgs extends Exception {
private static final long serialVersionUID = 1479361270874789045L;
BadArgs(String key, Object... args) {
super(JavahTask.this.getMessage(key, args));
this.key = key;
this.args = args;
}
BadArgs showUsage(boolean b) {
showUsage = b;
return this;
}
final String key;
final Object[] args;
boolean showUsage;
}
static abstract class Option {
Option(boolean hasArg, String... aliases) {
this.hasArg = hasArg;
this.aliases = aliases;
}
boolean isHidden() {
return false;
}
boolean matches(String opt) {
for (String a: aliases) {
if (a.equals(opt))
return true;
}
return false;
}
boolean ignoreRest() {
return false;
}
abstract void process(JavahTask task, String opt, String arg) throws BadArgs;
final boolean hasArg;
final String[] aliases;
}
static abstract class HiddenOption extends Option {
HiddenOption(boolean hasArg, String... aliases) {
super(hasArg, aliases);
}
@Override
boolean isHidden() {
return true;
}
}
static Option[] recognizedOptions = {
new Option(true, "-o") {
void process(JavahTask task, String opt, String arg) {
task.ofile = new File(arg);
}
},
new Option(true, "-d") {
void process(JavahTask task, String opt, String arg) {
task.odir = new File(arg);
}
},
new HiddenOption(true, "-td") {
void process(JavahTask task, String opt, String arg) {
// ignored; for backwards compatibility
}
},
new HiddenOption(false, "-stubs") {
void process(JavahTask task, String opt, String arg) {
// ignored; for backwards compatibility
}
},
new Option(false, "-v", "-verbose") {
void process(JavahTask task, String opt, String arg) {
task.verbose = true;
}
},
new Option(false, "-help", "--help", "-?") {
void process(JavahTask task, String opt, String arg) {
task.help = true;
}
},
new HiddenOption(false, "-trace") {
void process(JavahTask task, String opt, String arg) {
task.trace = true;
}
},
new Option(false, "-version") {
void process(JavahTask task, String opt, String arg) {
task.version = true;
}
},
new HiddenOption(false, "-fullversion") {
void process(JavahTask task, String opt, String arg) {
task.fullVersion = true;
}
},
new Option(false, "-jni") {
void process(JavahTask task, String opt, String arg) {
task.jni = true;
}
},
new Option(false, "-force") {
void process(JavahTask task, String opt, String arg) {
task.force = true;
}
},
new HiddenOption(false, "-Xnew") {
void process(JavahTask task, String opt, String arg) {
// we're already using the new javah
}
},
new HiddenOption(false, "-old") {
void process(JavahTask task, String opt, String arg) {
task.old = true;
}
},
new HiddenOption(false, "-llni", "-Xllni") {
void process(JavahTask task, String opt, String arg) {
task.llni = true;
}
},
new HiddenOption(false, "-llnidouble") {
void process(JavahTask task, String opt, String arg) {
task.llni = true;
task.doubleAlign = true;
}
},
};
JavahTask() {
}
JavahTask(Writer out,
JavaFileManager fileManager,
DiagnosticListener<? super JavaFileObject> diagnosticListener,
Iterable<String> options,
Iterable<String> classes) {
this();
this.log = getPrintWriterForWriter(out);
this.fileManager = fileManager;
this.diagnosticListener = diagnosticListener;
try {
handleOptions(options, false);
} catch (BadArgs e) {
throw new IllegalArgumentException(e.getMessage());
}
this.classes = new ArrayList<String>();
for (String classname: classes) {
classname.getClass(); // null-check
this.classes.add(classname);
}
}
public void setLocale(Locale locale) {
if (locale == null)
locale = Locale.getDefault();
task_locale = locale;
}
public void setLog(PrintWriter log) {
this.log = log;
}
public void setLog(OutputStream s) {
setLog(getPrintWriterForStream(s));
}
static PrintWriter getPrintWriterForStream(OutputStream s) {
return new PrintWriter(s, true);
}
static PrintWriter getPrintWriterForWriter(Writer w) {
if (w == null)
return getPrintWriterForStream(null);
else if (w instanceof PrintWriter)
return (PrintWriter) w;
else
return new PrintWriter(w, true);
}
public void setDiagnosticListener(DiagnosticListener<? super JavaFileObject> dl) {
diagnosticListener = dl;
}
public void setDiagnosticListener(OutputStream s) {
setDiagnosticListener(getDiagnosticListenerForStream(s));
}
private DiagnosticListener<JavaFileObject> getDiagnosticListenerForStream(OutputStream s) {
return getDiagnosticListenerForWriter(getPrintWriterForStream(s));
}
private DiagnosticListener<JavaFileObject> getDiagnosticListenerForWriter(Writer w) {
final PrintWriter pw = getPrintWriterForWriter(w);
return new DiagnosticListener<JavaFileObject> () {
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
pw.print(getMessage("err.prefix"));
pw.print(" ");
}
pw.println(diagnostic.getMessage(null));
}
};
}
int run(String[] args) {
try {
handleOptions(args);
boolean ok = run();
return ok ? 0 : 1;
} catch (BadArgs e) {
diagnosticListener.report(createDiagnostic(e.key, e.args));
return 1;
} catch (InternalError e) {
diagnosticListener.report(createDiagnostic("err.internal.error", e.getMessage()));
return 1;
} finally {
log.flush();
}
}
public void handleOptions(String[] args) throws BadArgs {
handleOptions(Arrays.asList(args), true);
}
private void handleOptions(Iterable<String> args, boolean allowClasses) throws BadArgs {
if (log == null) {
log = getPrintWriterForStream(System.out);
if (diagnosticListener == null)
diagnosticListener = getDiagnosticListenerForStream(System.err);
} else {
if (diagnosticListener == null)
diagnosticListener = getDiagnosticListenerForWriter(log);
}
if (fileManager == null)
fileManager = getDefaultFileManager(diagnosticListener, log);
Iterator<String> iter = args.iterator();
if (!iter.hasNext())
help = true;
while (iter.hasNext()) {
String arg = iter.next();
if (arg.startsWith("-"))
handleOption(arg, iter);
else if (allowClasses) {
if (classes == null)
classes = new ArrayList<String>();
classes.add(arg);
while (iter.hasNext())
classes.add(iter.next());
} else
throw new BadArgs("err.unknown.option", arg).showUsage(true);
}
if ((classes == null || classes.size() == 0) &&
!(help || version || fullVersion)) {
throw new BadArgs("err.no.classes.specified");
}
if (jni && llni)
throw new BadArgs("jni.llni.mixed");
if (odir != null && ofile != null)
throw new BadArgs("dir.file.mixed");
}
private void handleOption(String name, Iterator<String> rest) throws BadArgs {
for (Option o: recognizedOptions) {
if (o.matches(name)) {
if (o.hasArg) {
if (rest.hasNext())
o.process(this, name, rest.next());
else
throw new BadArgs("err.missing.arg", name).showUsage(true);
} else
o.process(this, name, null);
if (o.ignoreRest()) {
while (rest.hasNext())
rest.next();
}
return;
}
}
if (fileManager.handleOption(name, rest))
return;
throw new BadArgs("err.unknown.option", name).showUsage(true);
}
public Boolean call() {
return run();
}
public boolean run() throws Util.Exit {
Util util = new Util(log, diagnosticListener);
if (help) {
showHelp();
return true;
}
if (version || fullVersion) {
showVersion(fullVersion);
return true;
}
util.verbose = verbose;
Gen g;
if (llni)
g = new LLNI(doubleAlign, util);
else {
// if (stubs)
// throw new BadArgs("jni.no.stubs");
g = new JNI(util);
}
if (ofile != null) {
if (!(fileManager instanceof StandardJavaFileManager)) {
diagnosticListener.report(createDiagnostic("err.cant.use.option.for.fm", "-o"));
return false;
}
Iterable<? extends JavaFileObject> iter =
((StandardJavaFileManager) fileManager).getJavaFileObjectsFromFiles(Collections.singleton(ofile));
JavaFileObject fo = iter.iterator().next();
g.setOutFile(fo);
} else {
if (odir != null) {
if (!(fileManager instanceof StandardJavaFileManager)) {
diagnosticListener.report(createDiagnostic("err.cant.use.option.for.fm", "-d"));
return false;
}
if (!odir.exists())
if (!odir.mkdirs())
util.error("cant.create.dir", odir.toString());
try {
((StandardJavaFileManager) fileManager).setLocation(StandardLocation.CLASS_OUTPUT, Collections.singleton(odir));
} catch (IOException e) {
Object msg = e.getLocalizedMessage();
if (msg == null) {
msg = e;
}
diagnosticListener.report(createDiagnostic("err.ioerror", odir, msg));
return false;
}
}
g.setFileManager(fileManager);
}
/*
* Force set to false will turn off smarts about checking file
* content before writing.
*/
g.setForce(force);
if (fileManager instanceof JavahFileManager)
((JavahFileManager) fileManager).setIgnoreSymbolFile(true);
JavaCompiler c = ToolProvider.getSystemJavaCompiler();
List<String> opts = Arrays.asList("-proc:only");
CompilationTask t = c.getTask(log, fileManager, diagnosticListener, opts, internalize(classes), null);
JavahProcessor p = new JavahProcessor(g);
t.setProcessors(Collections.singleton(p));
boolean ok = t.call();
if (p.exit != null)
throw new Util.Exit(p.exit);
return ok;
}
private List<String> internalize(List<String> classes) {
List<String> l = new ArrayList<String>();
for (String c: classes) {
l.add(c.replace('$', '.'));
}
return l;
}
private List<File> pathToFiles(String path) {
List<File> files = new ArrayList<File>();
for (String f: path.split(File.pathSeparator)) {
if (f.length() > 0)
files.add(new File(f));
}
return files;
}
static StandardJavaFileManager getDefaultFileManager(final DiagnosticListener<? super JavaFileObject> dl, PrintWriter log) {
return JavahFileManager.create(dl, log);
}
private void showHelp() {
log.println(getMessage("main.usage", progname));
for (Option o: recognizedOptions) {
if (o.isHidden())
continue;
String name = o.aliases[0].substring(1); // there must always be at least one name
log.println(getMessage("main.opt." + name));
}
String[] fmOptions = { "-classpath", "-bootclasspath" };
for (String o: fmOptions) {
if (fileManager.isSupportedOption(o) == -1)
continue;
String name = o.substring(1);
log.println(getMessage("main.opt." + name));
}
log.println(getMessage("main.usage.foot"));
}
private void showVersion(boolean full) {
log.println(version(full ? "full" : "release"));
}
private static final String versionRBName = "com.sun.tools.javah.resources.version";
private static ResourceBundle versionRB;
private String version(String key) {
// key=version: mm.nn.oo[-milestone]
// key=full: mm.mm.oo[-milestone]-build
if (versionRB == null) {
try {
versionRB = ResourceBundle.getBundle(versionRBName);
} catch (MissingResourceException e) {
return getMessage("version.resource.missing", System.getProperty("java.version"));
}
}
try {
return versionRB.getString(key);
}
catch (MissingResourceException e) {
return getMessage("version.unknown", System.getProperty("java.version"));
}
}
private Diagnostic<JavaFileObject> createDiagnostic(final String key, final Object... args) {
return new Diagnostic<JavaFileObject>() {
public Kind getKind() {
return Diagnostic.Kind.ERROR;
}
public JavaFileObject getSource() {
return null;
}
public long getPosition() {
return Diagnostic.NOPOS;
}
public long getStartPosition() {
return Diagnostic.NOPOS;
}
public long getEndPosition() {
return Diagnostic.NOPOS;
}
public long getLineNumber() {
return Diagnostic.NOPOS;
}
public long getColumnNumber() {
return Diagnostic.NOPOS;
}
public String getCode() {
return key;
}
public String getMessage(Locale locale) {
return JavahTask.this.getMessage(locale, key, args);
}
};
}
private String getMessage(String key, Object... args) {
return getMessage(task_locale, key, args);
}
private String getMessage(Locale locale, String key, Object... args) {
if (bundles == null) {
// could make this a HashMap<Locale,SoftReference<ResourceBundle>>
// and for efficiency, keep a hard reference to the bundle for the task
// locale
bundles = new HashMap<Locale, ResourceBundle>();
}
if (locale == null)
locale = Locale.getDefault();
ResourceBundle b = bundles.get(locale);
if (b == null) {
try {
b = ResourceBundle.getBundle("com.sun.tools.javah.resources.l10n", locale);
bundles.put(locale, b);
} catch (MissingResourceException e) {
throw new InternalError("Cannot find javah resource bundle for locale " + locale, e);
}
}
try {
return MessageFormat.format(b.getString(key), args);
} catch (MissingResourceException e) {
return key;
//throw new InternalError(e, key);
}
}
File ofile;
File odir;
String bootcp;
String usercp;
List<String> classes;
boolean verbose;
boolean help;
boolean trace;
boolean version;
boolean fullVersion;
boolean jni;
boolean llni;
boolean doubleAlign;
boolean force;
boolean old;
PrintWriter log;
JavaFileManager fileManager;
DiagnosticListener<? super JavaFileObject> diagnosticListener;
Locale task_locale;
Map<Locale, ResourceBundle> bundles;
private static final String progname = "javah";
@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_7)
class JavahProcessor extends AbstractProcessor {
JavahProcessor(Gen g) {
this.g = g;
}
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Messager messager = processingEnv.getMessager();
Set<TypeElement> classes = getAllClasses(ElementFilter.typesIn(roundEnv.getRootElements()));
if (classes.size() > 0) {
checkMethodParameters(classes);
g.setProcessingEnvironment(processingEnv);
g.setClasses(classes);
try {
g.run();
} catch (ClassNotFoundException cnfe) {
messager.printMessage(Diagnostic.Kind.ERROR, getMessage("class.not.found", cnfe.getMessage()));
} catch (IOException ioe) {
messager.printMessage(Diagnostic.Kind.ERROR, getMessage("io.exception", ioe.getMessage()));
} catch (Util.Exit e) {
exit = e;
}
}
return true;
}
private Set<TypeElement> getAllClasses(Set<? extends TypeElement> classes) {
Set<TypeElement> allClasses = new LinkedHashSet<TypeElement>();
getAllClasses0(classes, allClasses);
return allClasses;
}
private void getAllClasses0(Iterable<? extends TypeElement> classes, Set<TypeElement> allClasses) {
for (TypeElement c: classes) {
allClasses.add(c);
getAllClasses0(ElementFilter.typesIn(c.getEnclosedElements()), allClasses);
}
}
// 4942232:
// check that classes exist for all the parameters of native methods
private void checkMethodParameters(Set<TypeElement> classes) {
Types types = processingEnv.getTypeUtils();
for (TypeElement te: classes) {
for (ExecutableElement ee: ElementFilter.methodsIn(te.getEnclosedElements())) {
for (VariableElement ve: ee.getParameters()) {
TypeMirror tm = ve.asType();
checkMethodParametersVisitor.visit(tm, types);
}
}
}
}
private TypeVisitor<Void,Types> checkMethodParametersVisitor =
new SimpleTypeVisitor6<Void,Types>() {
@Override
public Void visitArray(ArrayType t, Types types) {
visit(t.getComponentType(), types);
return null;
}
@Override
public Void visitDeclared(DeclaredType t, Types types) {
t.asElement().getKind(); // ensure class exists
for (TypeMirror st: types.directSupertypes(t))
visit(st, types);
return null;
}
};
private Gen g;
private Util.Exit exit;
}
}

@ -0,0 +1,84 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.tools.javah;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.Locale;
import java.util.Set;
import javax.lang.model.SourceVersion;
import javax.tools.DiagnosticListener;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
/*
* <p><b>This is NOT part of any API supported by Sun Microsystems.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*/
public class JavahTool implements NativeHeaderTool {
public NativeHeaderTask getTask(Writer out,
JavaFileManager fileManager,
DiagnosticListener<? super JavaFileObject> diagnosticListener,
Iterable<String> options,
Iterable<String> classes) {
return new JavahTask(out, fileManager, diagnosticListener, options, classes);
}
public StandardJavaFileManager getStandardFileManager(DiagnosticListener<? super JavaFileObject> diagnosticListener, Locale locale, Charset charset) {
return JavahTask.getDefaultFileManager(diagnosticListener, null);
}
public int run(InputStream in, OutputStream out, OutputStream err, String... arguments) {
JavahTask t = new JavahTask(
JavahTask.getPrintWriterForStream(out),
null,
null,
Arrays.asList(arguments),
null);
return (t.run() ? 0 : 1);
}
public Set<SourceVersion> getSourceVersions() {
return EnumSet.allOf(SourceVersion.class);
}
public int isSupportedOption(String option) {
JavahTask.Option[] options = JavahTask.recognizedOptions;
for (int i = 0; i < options.length; i++) {
if (options[i].matches(option))
return (options[i].hasArg ? 1 : 0);
}
return -1;
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,49 +26,65 @@
package com.sun.tools.javah;
import java.io.File;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Hashtable;
import com.sun.javadoc.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
/*
* @author Sucheta Dambalkar(Revised)
*/
import java.util.Set;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVisitor;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.SimpleTypeVisitor6;
/*
* <p><b>This is NOT part of any API supported by Sun Microsystems.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*
* @author Sucheta Dambalkar(Revised)
*/
public class LLNI extends Gen {
protected final char pathChar = File.separatorChar;
protected final char innerDelim = '$'; /* For inner classes */
protected Hashtable<Object, Object> doneHandleTypes;
MemberDoc []fields;
MemberDoc [] methods;
protected Set<String> doneHandleTypes;
List<VariableElement> fields;
List<ExecutableElement> methods;
private boolean doubleAlign;
private int padFieldNum = 0;
LLNI(boolean doubleAlign, RootDoc root) {
super(root);
LLNI(boolean doubleAlign, Util util) {
super(util);
this.doubleAlign = doubleAlign;
}
protected String getIncludes() {
return "";
}
protected void write(OutputStream o, ClassDoc clazz)
throws ClassNotFoundException {
String cname = mangleClassName(clazz.qualifiedName());
protected void write(OutputStream o, TypeElement clazz) throws Util.Exit {
String cname = mangleClassName(clazz.getQualifiedName().toString());
PrintWriter pw = wrapWriter(o);
fields = clazz.fields();
methods = clazz.methods();
fields = ElementFilter.fieldsIn(clazz.getEnclosedElements());
methods = ElementFilter.methodsIn(clazz.getEnclosedElements());
generateDeclsForClass(pw, clazz, cname);
// FIXME check if errors occurred on the PrintWriter and throw exception if so
}
protected void generateDeclsForClass(PrintWriter pw,
ClassDoc clazz, String cname)
throws ClassNotFoundException {
doneHandleTypes = new Hashtable<Object, Object>();
TypeElement clazz, String cname) throws Util.Exit {
doneHandleTypes = new HashSet<String>();
/* The following handle types are predefined in "typedefs.h". Suppress
inclusion in the output by generating them "into the blue" here. */
genHandleType(null, "java.lang.Class");
@ -79,7 +95,7 @@ public class LLNI extends Gen {
genHandleType(null, "java.lang.ThreadGroup");
genHandleType(null, "java.lang.Throwable");
pw.println("/* LLNI Header for class " + clazz.qualifiedName() + " */" + lineSep);
pw.println("/* LLNI Header for class " + clazz.getQualifiedName() + " */" + lineSep);
pw.println("#ifndef _Included_" + cname);
pw.println("#define _Included_" + cname);
pw.println("#include \"typedefs.h\"");
@ -94,8 +110,8 @@ public class LLNI extends Gen {
protected void genHandleType(PrintWriter pw, String clazzname) {
String cname = mangleClassName(clazzname);
if (!doneHandleTypes.containsKey(cname)) {
doneHandleTypes.put(cname, cname);
if (!doneHandleTypes.contains(cname)) {
doneHandleTypes.add(cname);
if (pw != null) {
pw.println("#ifndef DEFINED_" + cname);
pw.println(" #define DEFINED_" + cname);
@ -107,31 +123,29 @@ public class LLNI extends Gen {
protected String mangleClassName(String s) {
return s.replace('.', '_')
.replace(pathChar, '_')
.replace('/', '_')
.replace(innerDelim, '_');
}
protected void forwardDecls(PrintWriter pw, ClassDoc clazz)
throws ClassNotFoundException {
ClassDoc clazzfield = null;
if (clazz.qualifiedName().equals("java.lang.Object"))
protected void forwardDecls(PrintWriter pw, TypeElement clazz) {
TypeElement object = elems.getTypeElement("java.lang.Object");
if (clazz.equals(object))
return;
genHandleType(pw, clazz.qualifiedName());
ClassDoc superClass = clazz.superclass();
if(superClass != null){
String superClassName = superClass.qualifiedName();
genHandleType(pw, clazz.getQualifiedName().toString());
TypeElement superClass = (TypeElement) (types.asElement(clazz.getSuperclass()));
if (superClass != null) {
String superClassName = superClass.getQualifiedName().toString();
forwardDecls(pw, superClass);
}
for (int i = 0; i < fields.length; i++) {
FieldDoc field = (FieldDoc)fields[i];
for (VariableElement field: fields) {
if (!field.isStatic()) {
Type t = field.type();
String tname = t.qualifiedTypeName();
TypeSignature newTypeSig = new TypeSignature(root);
if (!field.getModifiers().contains(Modifier.STATIC)) {
TypeMirror t = types.erasure(field.asType());
TypeSignature newTypeSig = new TypeSignature(elems);
String tname = newTypeSig.qualifiedTypeName(t);
String sig = newTypeSig.getTypeSignature(tname);
if (sig.charAt(0) != '[')
@ -139,13 +153,12 @@ public class LLNI extends Gen {
}
}
for (int i = 0; i < methods.length; i++) {
MethodDoc method = (MethodDoc)methods[i];
for (ExecutableElement method: methods) {
if (method.isNative()) {
Type retType = method.returnType();
String typesig = method.signature();
TypeSignature newTypeSig = new TypeSignature(root);
if (method.getModifiers().contains(Modifier.NATIVE)) {
TypeMirror retType = types.erasure(method.getReturnType());
String typesig = signature(method);
TypeSignature newTypeSig = new TypeSignature(elems);
String sig = newTypeSig.getTypeSignature(typesig, retType);
if (sig.charAt(0) != '[')
@ -173,10 +186,9 @@ public class LLNI extends Gen {
}
protected void structSectionForClass(PrintWriter pw,
ClassDoc jclazz, String cname)
throws ClassNotFoundException {
TypeElement jclazz, String cname) {
String jname = jclazz.qualifiedName();
String jname = jclazz.getQualifiedName().toString();
if (cname.equals("java_lang_Object")) {
pw.println("/* struct java_lang_Object is defined in typedefs.h. */");
@ -207,8 +219,8 @@ public class LLNI extends Gen {
public boolean bottomMost;
public boolean printedOne = false;
FieldDefsRes(ClassDoc clazz, FieldDefsRes parent, boolean bottomMost) {
this.className = clazz.qualifiedName();
FieldDefsRes(TypeElement clazz, FieldDefsRes parent, boolean bottomMost) {
this.className = clazz.getQualifiedName().toString();
this.parent = parent;
this.bottomMost = bottomMost;
int byteSize = 0;
@ -218,9 +230,8 @@ public class LLNI extends Gen {
}
/* Returns "true" iff added a field. */
private boolean doField(FieldDefsRes res, FieldDoc field,
String cname, boolean padWord)
throws ClassNotFoundException {
private boolean doField(FieldDefsRes res, VariableElement field,
String cname, boolean padWord) {
String fieldDef = addStructMember(field, cname, padWord);
if (fieldDef != null) {
@ -242,16 +253,14 @@ public class LLNI extends Gen {
return false;
}
private int doTwoWordFields(FieldDefsRes res, ClassDoc clazz,
int offset, String cname, boolean padWord)
throws ClassNotFoundException {
private int doTwoWordFields(FieldDefsRes res, TypeElement clazz,
int offset, String cname, boolean padWord) {
boolean first = true;
FieldDoc[] fields = clazz.fields();
List<VariableElement> fields = ElementFilter.fieldsIn(clazz.getEnclosedElements());
for (int i = 0; i <fields.length; i++) {
FieldDoc field = fields[i];
String tc =field.type().typeName();
boolean twoWords = (tc.equals("long") || tc.equals("double"));
for (VariableElement field: fields) {
TypeKind tk = field.asType().getKind();
boolean twoWords = (tk == TypeKind.LONG || tk == TypeKind.DOUBLE);
if (twoWords && doField(res, field, cname, first && padWord)) {
offset += 8; first = false;
}
@ -259,22 +268,21 @@ public class LLNI extends Gen {
return offset;
}
protected String fieldDefs(ClassDoc clazz, String cname)
throws ClassNotFoundException {
String fieldDefs(TypeElement clazz, String cname) {
FieldDefsRes res = fieldDefs(clazz, cname, true);
return res.s;
}
protected FieldDefsRes fieldDefs(ClassDoc clazz, String cname,
boolean bottomMost)
throws ClassNotFoundException {
FieldDefsRes fieldDefs(TypeElement clazz, String cname,
boolean bottomMost){
FieldDefsRes res;
int offset;
boolean didTwoWordFields = false;
ClassDoc superclazz = clazz.superclass();
TypeElement superclazz = (TypeElement) types.asElement(clazz.getSuperclass());
if (superclazz != null) {
String supername = superclazz.qualifiedName();
String supername = superclazz.getQualifiedName().toString();
res = new FieldDefsRes(clazz,
fieldDefs(superclazz, cname, false),
bottomMost);
@ -284,18 +292,17 @@ public class LLNI extends Gen {
offset = 0;
}
FieldDoc[] fields = clazz.fields();
List<VariableElement> fields = ElementFilter.fieldsIn(clazz.getEnclosedElements());
for (int i = 0; i < fields.length; i++) {
FieldDoc field = fields[i];
for (VariableElement field: fields) {
if (doubleAlign && !didTwoWordFields && (offset % 8) == 0) {
offset = doTwoWordFields(res, clazz, offset, cname, false);
didTwoWordFields = true;
}
String tc = field.type().typeName();
boolean twoWords = (tc.equals("long") ||tc.equals("double"));
TypeKind tk = field.asType().getKind();
boolean twoWords = (tk == TypeKind.LONG || tk == TypeKind.DOUBLE);
if (!doubleAlign || !twoWords) {
if (doField(res, field, cname, false)) offset += 4;
@ -313,19 +320,19 @@ public class LLNI extends Gen {
}
/* OVERRIDE: This method handles instance fields */
protected String addStructMember(FieldDoc member, String cname,
boolean padWord)
throws ClassNotFoundException {
protected String addStructMember(VariableElement member, String cname,
boolean padWord) {
String res = null;
if (member.isStatic()) {
if (member.getModifiers().contains(Modifier.STATIC)) {
res = addStaticStructMember(member, cname);
// if (res == null) /* JNI didn't handle it, print comment. */
// res = " /* Inaccessible static: " + member + " */" + lineSep;
} else {
TypeMirror mt = types.erasure(member.asType());
if (padWord) res = " java_int padWord" + padFieldNum++ + ";" + lineSep;
res = " " + llniType(member.type(), false, false) + " " + llniFieldName(member);
if (isLongOrDouble(member.type())) res = res + "[2]";
res = " " + llniType(mt, false, false) + " " + llniFieldName(member);
if (isLongOrDouble(mt)) res = res + "[2]";
res = res + ";" + lineSep;
}
return res;
@ -337,36 +344,42 @@ public class LLNI extends Gen {
/*
* This method only handles static final fields.
*/
protected String addStaticStructMember(FieldDoc field, String cname)
throws ClassNotFoundException {
protected String addStaticStructMember(VariableElement field, String cname) {
String res = null;
Object exp = null;
if (!field.isStatic())
if (!field.getModifiers().contains(Modifier.STATIC))
return res;
if (!field.isFinal())
if (!field.getModifiers().contains(Modifier.FINAL))
return res;
exp = field.constantValue();
exp = field.getConstantValue();
if (exp != null) {
/* Constant. */
String cn = cname + "_" + field.name();
String cn = cname + "_" + field.getSimpleName();
String suffix = null;
long val = 0;
/* Can only handle int, long, float, and double fields. */
if (exp instanceof Integer) {
if (exp instanceof Byte
|| exp instanceof Short
|| exp instanceof Integer) {
suffix = "L";
val = ((Integer)exp).intValue();
val = ((Number)exp).intValue();
}
if (exp instanceof Long) {
else if (exp instanceof Long) {
// Visual C++ supports the i64 suffix, not LL
suffix = isWindows ? "i64" : "LL";
val = ((Long)exp).longValue();
}
if (exp instanceof Float) suffix = "f";
if (exp instanceof Double) suffix = "";
else if (exp instanceof Float) suffix = "f";
else if (exp instanceof Double) suffix = "";
else if (exp instanceof Character) {
suffix = "L";
Character ch = (Character) exp;
val = ((int) ch) & 0xffff;
}
if (suffix != null) {
// Some compilers will generate a spurious warning
// for the integer constants for Integer.MIN_VALUE
@ -376,9 +389,12 @@ public class LLNI extends Gen {
res = " #undef " + cn + lineSep
+ " #define " + cn
+ " (" + (val + 1) + suffix + "-1)" + lineSep;
} else if (suffix.equals("L") || suffix.endsWith("LL")) {
res = " #undef " + cn + lineSep
+ " #define " + cn + " " + val + suffix + lineSep;
} else {
res = " #undef " + cn + lineSep
+ " #define " + cn + " "+ exp.toString() + suffix + lineSep;
+ " #define " + cn + " " + exp + suffix + lineSep;
}
}
}
@ -386,8 +402,8 @@ public class LLNI extends Gen {
}
protected void methodSectionForClass(PrintWriter pw,
ClassDoc clazz, String cname)
throws ClassNotFoundException {
TypeElement clazz, String cname)
throws Util.Exit {
String methods = methodDecls(clazz, cname);
if (methods.length() != 0) {
@ -402,81 +418,77 @@ public class LLNI extends Gen {
}
}
protected String methodDecls(ClassDoc clazz, String cname)
throws ClassNotFoundException {
protected String methodDecls(TypeElement clazz, String cname) throws Util.Exit {
String res = "";
for (int i = 0; i < methods.length; i++) {
MethodDoc method = (MethodDoc)methods[i];
if (method.isNative())
for (ExecutableElement method: methods) {
if (method.getModifiers().contains(Modifier.NATIVE))
res = res + methodDecl(method, clazz, cname);
}
return res;
}
protected String methodDecl(MethodDoc method,
ClassDoc clazz, String cname)
throws ClassNotFoundException {
protected String methodDecl(ExecutableElement method,
TypeElement clazz, String cname)
throws Util.Exit {
String res = null;
Type retType = method.returnType();
String typesig = method.signature();
TypeSignature newTypeSig = new TypeSignature(root);
TypeMirror retType = types.erasure(method.getReturnType());
String typesig = signature(method);
TypeSignature newTypeSig = new TypeSignature(elems);
String sig = newTypeSig.getTypeSignature(typesig, retType);
boolean longName = needLongName(method, clazz);
if (sig.charAt(0) != '(')
Util.error("invalid.method.signature", sig);
util.error("invalid.method.signature", sig);
res = "JNIEXPORT " + jniType(retType) + " JNICALL" + lineSep + jniMethodName(method, cname, longName)
+ "(JNIEnv *, " + cRcvrDecl(method, cname);
Parameter[] params = method.parameters();
Type argTypes[] = new Type[params.length];
for(int p = 0; p < params.length; p++){
argTypes[p] = params[p].type();
List<? extends VariableElement> params = method.getParameters();
List<TypeMirror> argTypes = new ArrayList<TypeMirror>();
for (VariableElement p: params){
argTypes.add(types.erasure(p.asType()));
}
/* It would have been nice to include the argument names in the
declaration, but there seems to be a bug in the "BinaryField"
class, causing the getArguments() method to return "null" for
most (non-constructor) methods. */
for (int i = 0; i < argTypes.length; i++)
res = res + ", " + jniType(argTypes[i]);
for (TypeMirror argType: argTypes)
res = res + ", " + jniType(argType);
res = res + ");" + lineSep;
return res;
}
protected final boolean needLongName(MethodDoc method,
ClassDoc clazz)
throws ClassNotFoundException {
String methodName = method.name();
for (int i = 0; i < methods.length; i++) {
MethodDoc memberMethod = (MethodDoc) methods[i];
protected final boolean needLongName(ExecutableElement method,
TypeElement clazz) {
Name methodName = method.getSimpleName();
for (ExecutableElement memberMethod: methods) {
if ((memberMethod != method) &&
memberMethod.isNative() && (methodName == memberMethod.name()))
memberMethod.getModifiers().contains(Modifier.NATIVE) &&
(methodName.equals(memberMethod.getSimpleName())))
return true;
}
return false;
}
protected final String jniMethodName(MethodDoc method, String cname,
protected final String jniMethodName(ExecutableElement method, String cname,
boolean longName) {
String res = "Java_" + cname + "_" + method.name();
String res = "Java_" + cname + "_" + method.getSimpleName();
if (longName) {
Type mType = method.returnType();
Parameter[] params = method.parameters();
Type argTypes[] = new Type[params.length];
for(int p = 0; p < params.length; p++){
argTypes[p] = params[p].type();
TypeMirror mType = types.erasure(method.getReturnType());
List<? extends VariableElement> params = method.getParameters();
List<TypeMirror> argTypes = new ArrayList<TypeMirror>();
for (VariableElement param: params) {
argTypes.add(types.erasure(param.asType()));
}
res = res + "__";
for (int i = 0; i < argTypes.length; i++){
Type t = argTypes[i];
String tname = t.typeName();
TypeSignature newTypeSig = new TypeSignature(root);
for (TypeMirror t: argTypes) {
String tname = t.toString();
TypeSignature newTypeSig = new TypeSignature(elems);
String sig = newTypeSig.getTypeSignature(tname);
res = res + nameToIdentifier(sig);
}
@ -484,88 +496,143 @@ public class LLNI extends Gen {
return res;
}
protected final String jniType(Type t) {
String elmT =t.typeName();
if (t.dimension().indexOf("[]") != -1) {
if(elmT.equals("boolean"))return "jbooleanArray";
else if(elmT.equals("byte"))return "jbyteArray";
else if(elmT.equals("char"))return "jcharArray";
else if(elmT.equals("short"))return "jshortArray";
else if(elmT.equals("int"))return "jintArray";
else if(elmT.equals("long"))return "jlongArray";
else if(elmT.equals("float"))return "jfloatArray";
else if(elmT.equals("double"))return "jdoubleArray";
else if((t.dimension().indexOf("[][]") != -1) || (t.asClassDoc() != null)) return "jobjectArray";
} else {
if(elmT.equals("void"))return "void";
else if(elmT.equals("boolean"))return "jboolean";
else if(elmT.equals("byte"))return "jbyte";
else if(elmT.equals("char"))return "jchar";
else if(elmT.equals("short"))return "jshort";
else if(elmT.equals("int"))return "jint";
else if(elmT.equals("long"))return "jlong";
else if(elmT.equals("float"))return "jfloat";
else if(elmT.equals("double"))return "jdouble";
else if (t.asClassDoc() != null) {
if (elmT.equals("String"))
// copied from JNI.java
protected final String jniType(TypeMirror t) throws Util.Exit {
TypeElement throwable = elems.getTypeElement("java.lang.Throwable");
TypeElement jClass = elems.getTypeElement("java.lang.Class");
TypeElement jString = elems.getTypeElement("java.lang.String");
Element tclassDoc = types.asElement(t);
switch (t.getKind()) {
case ARRAY: {
TypeMirror ct = ((ArrayType) t).getComponentType();
switch (ct.getKind()) {
case BOOLEAN: return "jbooleanArray";
case BYTE: return "jbyteArray";
case CHAR: return "jcharArray";
case SHORT: return "jshortArray";
case INT: return "jintArray";
case LONG: return "jlongArray";
case FLOAT: return "jfloatArray";
case DOUBLE: return "jdoubleArray";
case ARRAY:
case DECLARED: return "jobjectArray";
default: throw new Error(ct.toString());
}
}
case VOID: return "void";
case BOOLEAN: return "jboolean";
case BYTE: return "jbyte";
case CHAR: return "jchar";
case SHORT: return "jshort";
case INT: return "jint";
case LONG: return "jlong";
case FLOAT: return "jfloat";
case DOUBLE: return "jdouble";
case DECLARED: {
if (tclassDoc.equals(jString))
return "jstring";
else if (t.asClassDoc().subclassOf(root.classNamed("java.lang.Class")))
else if (types.isAssignable(t, throwable.asType()))
return "jthrowable";
else if (types.isAssignable(t, jClass.asType()))
return "jclass";
else
return "jobject";
}
}
Util.bug("jni.unknown.type");
util.bug("jni.unknown.type");
return null; /* dead code. */
}
protected String llniType(Type t, boolean handleize, boolean longDoubleOK) {
protected String llniType(TypeMirror t, boolean handleize, boolean longDoubleOK) {
String res = null;
String elmt = t.typeName();
if (t.dimension().indexOf("[]") != -1) {
if((t.dimension().indexOf("[][]") != -1)
|| (t.asClassDoc() != null)) res = "IArrayOfRef";
else if(elmt.equals("boolean")) res = "IArrayOfBoolean";
else if(elmt.equals("byte")) res = "IArrayOfByte";
else if(elmt.equals("char")) res = "IArrayOfChar";
else if(elmt.equals("int")) res = "IArrayOfInt";
else if(elmt.equals("long")) res = "IArrayOfLong";
else if(elmt.equals("float")) res = "IArrayOfFloat";
else if(elmt.equals("double")) res = "IArrayOfDouble";
if (!handleize) res = "DEREFERENCED_" + res;
} else {
if(elmt.equals("void")) res = "void";
else if( (elmt.equals("boolean")) || (elmt.equals("byte"))
||(elmt.equals("char")) || (elmt.equals("short"))
|| (elmt.equals("int"))) res = "java_int";
else if(elmt.equals("long")) res = longDoubleOK
? "java_long" : "val32 /* java_long */";
else if(elmt.equals("float")) res = "java_float";
else if(elmt.equals("double")) res = res = longDoubleOK
? "java_double" : "val32 /* java_double */";
else if(t.asClassDoc() != null) {
res = "I" + mangleClassName(t.asClassDoc().qualifiedName());
switch (t.getKind()) {
case ARRAY: {
TypeMirror ct = ((ArrayType) t).getComponentType();
switch (ct.getKind()) {
case BOOLEAN: res = "IArrayOfBoolean"; break;
case BYTE: res = "IArrayOfByte"; break;
case CHAR: res = "IArrayOfChar"; break;
case SHORT: res = "IArrayOfShort"; break;
case INT: res = "IArrayOfInt"; break;
case LONG: res = "IArrayOfLong"; break;
case FLOAT: res = "IArrayOfFloat"; break;
case DOUBLE: res = "IArrayOfDouble"; break;
case ARRAY:
case DECLARED: res = "IArrayOfRef"; break;
default: throw new Error(ct.getKind() + " " + ct);
}
if (!handleize) res = "DEREFERENCED_" + res;
break;
}
case VOID:
res = "void";
break;
case BOOLEAN:
case BYTE:
case CHAR:
case SHORT:
case INT:
res = "java_int" ;
break;
case LONG:
res = longDoubleOK ? "java_long" : "val32 /* java_long */";
break;
case FLOAT:
res = "java_float";
break;
case DOUBLE:
res = longDoubleOK ? "java_double" : "val32 /* java_double */";
break;
case DECLARED:
TypeElement e = (TypeElement) types.asElement(t);
res = "I" + mangleClassName(e.getQualifiedName().toString());
if (!handleize) res = "DEREFERENCED_" + res;
break;
default:
throw new Error(t.getKind() + " " + t); // FIXME
}
return res;
}
protected final String cRcvrDecl(MemberDoc field, String cname) {
return (field.isStatic() ? "jclass" : "jobject");
protected final String cRcvrDecl(Element field, String cname) {
return (field.getModifiers().contains(Modifier.STATIC) ? "jclass" : "jobject");
}
protected String maskName(String s) {
return "LLNI_mask(" + s + ")";
}
protected String llniFieldName(MemberDoc field) {
return maskName(field.name());
protected String llniFieldName(VariableElement field) {
return maskName(field.getSimpleName().toString());
}
protected final boolean isLongOrDouble(Type t) {
String tc = t.typeName();
return (tc.equals("long") || tc.equals("double"));
protected final boolean isLongOrDouble(TypeMirror t) {
TypeVisitor<Boolean,Void> v = new SimpleTypeVisitor6<Boolean,Void>() {
public Boolean defaultAction(TypeMirror t, Void p){
return false;
}
public Boolean visitArray(ArrayType t, Void p) {
return visit(t.getComponentType(), p);
}
public Boolean visitPrimitive(PrimitiveType t, Void p) {
TypeKind tk = t.getKind();
return (tk == TypeKind.LONG || tk == TypeKind.DOUBLE);
}
};
return v.visit(t, null);
}
/* Do unicode to ansi C identifier conversion.
@ -602,3 +669,4 @@ public class LLNI extends Gen {
return false;
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,134 +23,39 @@
* have any questions.
*/
package com.sun.tools.javah;
import java.io.*;
import java.io.PrintWriter;
/**
* Javah generates support files for native methods.
* Parse commandline options & Invokes javadoc to execute those commands.
* Main entry point.
*
* @author Sucheta Dambalkar
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
* you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class Main{
/*
* Parse arguments given for javah to give proper error messages.
public class Main {
/**
* Main entry point for the launcher.
* Note: This method calls System.exit.
* @param args command line arguments
*/
public static void main(String[] args){
if (args.length == 0) {
Util.usage(1);
}
for ( int i = 0; i < args.length; i++) {
if (args[i].equals("-o")) {
i++;
if(i >= args.length){
Util.usage(1);
}else if(args[i].charAt(0) == '-'){
Util.error("no.outputfile.specified");
}else if((i+1) >= args.length){
Util.error("no.classes.specified");
}
} else if (args[i].equals("-d")) {
i++;
if(i >= args.length){
Util.usage(1);
}else if(args[i].charAt(0) == '-') {
Util.error("no.outputdir.specified");
}else if((i+1) >= args.length){
Util.error("no.classes.specified");
}
} else if (args[i].equals("-td")) {
/* Ignored. Generate tmp files to memory. */
i++;
if (i == args.length)
Util.usage(1);
} else if (args[i].equals("-stubs")) {
if((i+1) >= args.length){
Util.error("no.classes.specified");
}
} else if (args[i].equals("-v") || args[i].equals("-verbose")) {
if((i+1) >= args.length){
Util.error("no.classes.specified");
}
args[i] = "-verbose";
} else if ((args[i].equals("-help")) || (args[i].equals("--help"))
|| (args[i].equals("-?")) || (args[i].equals("-h"))) {
Util.usage(0);
} else if (args[i].equals("-trace")) {
System.err.println(Util.getText("tracing.not.supported"));
} else if (args[i].equals("-version")) {
if((i+1) >= args.length){
Util.version();
}
} else if (args[i].equals("-jni")) {
if((i+1) >= args.length){
Util.error("no.classes.specified");
}
} else if (args[i].equals("-force")) {
if((i+1) >= args.length){
Util.error("no.classes.specified");
}
} else if (args[i].equals("-Xnew")) {
// we're already using the new javah
} else if (args[i].equals("-old")) {
System.err.println(Util.getText("old.not.supported"));
Util.usage(1);
} else if (args[i].equals("-Xllni")) {
if((i+1) >= args.length){
Util.error("no.classes.specified");
}
} else if (args[i].equals("-llni")) {
if((i+1) >= args.length){
Util.error("no.classes.specified");
}
} else if (args[i].equals("-llniDouble")) {
if((i+1) >= args.length){
Util.error("no.classes.specified");
}
} else if (args[i].equals("-classpath")) {
i++;
if(i >= args.length){
Util.usage(1);
}else if(args[i].charAt(0) == '-') {
Util.error("no.classpath.specified");
}else if((i+1) >= args.length){
Util.error("no.classes.specified");
}
} else if (args[i].equals("-bootclasspath")) {
i++;
if(i >= args.length){
Util.usage(1);
}else if(args[i].charAt(0) == '-'){
Util.error("no.bootclasspath.specified");
}else if((i+1) >= args.length){
Util.error("no.classes.specified");
}
} else if (args[i].charAt(0) == '-') {
Util.error("unknown.option", args[i], null, true);
} else {
//break; /* The rest must be classes. */
}
}
/* Invoke javadoc */
String[] javadocargs = new String[args.length + 2];
int i = 0;
for(; i < args.length; i++) {
javadocargs[i] = args[i];
}
javadocargs[i] = "-private";
i++;
javadocargs[i] = "-Xclasses";
int rc = com.sun.tools.javadoc.Main.execute("javadoc", "com.sun.tools.javah.MainDoclet", javadocargs);
public static void main(String[] args) {
JavahTask t = new JavahTask();
int rc = t.run(args);
System.exit(rc);
}
/**
* Entry point that does <i>not</i> call System.exit.
* @param args command line arguments
* @param out output stream
* @return an exit code. 0 means success, non-zero means an error occurred.
*/
public static int run(String[] args, PrintWriter out) {
JavahTask t = new JavahTask();
t.setLog(out);
return t.run(args);
}
}

@ -1,218 +0,0 @@
/*
* Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.tools.javah;
import com.sun.javadoc.*;
import java.io.*;
/**
* A doclet to parse and execute commandline options.
*
* @author Sucheta Dambalkar(using code from old javap)
*/
public class MainDoclet{
public static String odir = null;
public static String ofile = null;
public static boolean stubs = false;
public static boolean jni = false;
public static boolean llni = false;
public static boolean doubleAlign = false;
public static boolean force = false;
public static String genclass = null;
/**
* Entry point.
*/
public static boolean start(RootDoc root) {
int j = 0;
int k = 0;
/**
* Command line options.
*/
String [][] cmdoptions = root.options();
/**
* Classes specified on command line.
*/
ClassDoc[] classes = root.classes();
/**
* Generator used by javah. Default is JNI.
*/
Gen g = new JNI(root);
validateOptions(cmdoptions);
/*
* Select native interface.
*/
if (jni && llni) Util.error("jni.llni.mixed");
if (llni)
g = new LLNI(doubleAlign, root);
if (g instanceof JNI && stubs) Util.error("jni.no.stubs");
/*
* Arrange for output destination.
*/
if (odir != null && ofile != null)
Util.error("dir.file.mixed");
if (odir != null)
g.setOutDir(odir);
if (ofile != null)
g.setOutFile(ofile);
/*
* Force set to false will turn off smarts about checking file
* content before writing.
*/
g.setForce(force);
/*
* Grab the rest of argv[] ... this must be the classes.
*/
if (classes.length == 0){
Util.error("no.classes.specified");
}
/*
* Set classes.
*/
g.setClasses(classes);
try {
g.run();
} catch (ClassNotFoundException cnfe) {
Util.error("class.not.found", cnfe.getMessage());
} catch (IOException ioe) {
Util.error("io.exception", ioe.getMessage());
}
return true;
}
/**
* Required doclet method.
*/
public static int optionLength(String option) {
if (option.equals("-o")) {
return 2;
} else if(option.equals("-d")){
return 2;
} else if (option.equals("-td")) {
return 1;
} else if (option.equals("-stubs")) {
return 1;
} else if(option.equals("-help")){
return 1;
} else if(option.equals("--help")){
return 1;
} else if(option.equals("-?")){
return 1;
} else if(option.equals("-h")){
return 1;
} else if(option.equals("-trace")){
return 1;
} else if(option.equals("-version")) {
return 1;
} else if(option.equals("-jni")){
return 1;
} else if(option.equals("-force")){
return 1;
} else if(option.equals("-Xllni")){
return 1;
} else if(option.equals("-llni")){
return 1;
} else if(option.equals("-llniDouble")){
return 1;
} else return 0;
}
/**
* Parse the command line options.
*/
public static void validateOptions(String cmdoptions[][]) {
/* Default values for options, overridden by user options. */
String bootcp = System.getProperty("sun.boot.class.path");
String usercp = System.getProperty("env.class.path");
for(int p = 0; p < cmdoptions.length; p++){
if (cmdoptions[p][0].equals("-o")) {
ofile = cmdoptions[p][1];
} else if(cmdoptions[p][0].equals("-d")){
odir = cmdoptions[p][1];
} else if (cmdoptions[p][0].equals("-td")) {
if (p ==cmdoptions.length)
Util.usage(1);
} else if (cmdoptions[p][0].equals("-stubs")) {
stubs = true;
} else if (cmdoptions[p][0].equals("-verbose")) {
Util.verbose = true;
} else if((cmdoptions[p][0].equals("-help"))
|| (cmdoptions[p][0].equals("--help"))
|| (cmdoptions[p][0].equals("-?"))
|| (cmdoptions[p][0].equals("-h"))) {
Util.usage(0);
} else if (cmdoptions[p][0].equals("-trace")) {
System.err.println(Util.getText("tracing.not.supported"));
} else if (cmdoptions[p][0].equals("-version")) {
Util.version();
} else if (cmdoptions[p][0].equals("-jni")) {
jni = true;
} else if (cmdoptions[p][0].equals("-force")) {
force = true;
} else if (cmdoptions[p][0].equals("-Xllni")) {
llni = true;
} else if (cmdoptions[p][0].equals("-llni")) {
llni = true;
} else if (cmdoptions[p][0].equals("-llniDouble")) {
llni = true; doubleAlign = true;
} else if (cmdoptions[p][0].equals("-classpath")) {
usercp = cmdoptions[p][1];
} else if (cmdoptions[p][0].equals("-bootclasspath")) {
bootcp = cmdoptions[p][1];
} else if((cmdoptions[p][0].charAt(0) == '-')
&& (!cmdoptions[p][0].equals("-private"))){
Util.error("unknown.option", cmdoptions[p][0], null, true);
} else {
break; /* The rest must be classes. */
}
}
if (Util.verbose) {
System.err.println("[ Search Path: "
+ bootcp
+ System.getProperty("file.separator")
+ usercp + " ]");
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,22 +26,30 @@
package com.sun.tools.javah;
import com.sun.javadoc.*;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
/**
* A utility for mangling java identifiers into C names. Should make
* this more fine grained and distribute the functionality to the
* generators.
*
* <p><b>This is NOT part of any API supported by Sun Microsystems.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*
* @author Sucheta Dambalkar(Revised)
*/
class Mangle {
public class Mangle {
public static class Type {
public static final int CLASS = 1;
public static final int FIELDSTUB = 2;
public static final int FIELD = 3;
public static final int FIELD = 3;
public static final int JNI = 4;
public static final int SIGNATURE = 5;
public static final int METHOD_JDK_1 = 6;
@ -49,8 +57,15 @@ class Mangle {
public static final int METHOD_JNI_LONG = 8;
};
private Elements elems;
private Types types;
public static final String mangle(String name, int mtype) {
Mangle(Elements elems, Types types) {
this.elems = elems;
this.types = types;
}
public final String mangle(CharSequence name, int mtype) {
StringBuffer result = new StringBuffer(100);
int length = name.length();
@ -98,15 +113,15 @@ class Mangle {
return result.toString();
}
public static String mangleMethod(MethodDoc method, RootDoc root, ClassDoc clazz,
public String mangleMethod(ExecutableElement method, TypeElement clazz,
int mtype) {
StringBuffer result = new StringBuffer(100);
result.append("Java_");
if (mtype == Mangle.Type.METHOD_JDK_1) {
result.append(mangle(clazz.qualifiedName(), Mangle.Type.CLASS));
result.append(mangle(clazz.getQualifiedName(), Mangle.Type.CLASS));
result.append('_');
result.append(mangle(method.name(),
result.append(mangle(method.getSimpleName(),
Mangle.Type.FIELD));
result.append("_stub");
return result.toString();
@ -115,13 +130,13 @@ class Mangle {
/* JNI */
result.append(mangle(getInnerQualifiedName(clazz), Mangle.Type.JNI));
result.append('_');
result.append(mangle(method.name(),
result.append(mangle(method.getSimpleName(),
Mangle.Type.JNI));
if (mtype == Mangle.Type.METHOD_JNI_LONG) {
result.append("__");
String typesig = method.signature();
TypeSignature newTypeSig = new TypeSignature(root);
String sig = newTypeSig.getTypeSignature(typesig, method.returnType());
String typesig = signature(method);
TypeSignature newTypeSig = new TypeSignature(elems);
String sig = newTypeSig.getTypeSignature(typesig, method.getReturnType());
sig = sig.substring(1);
sig = sig.substring(0, sig.lastIndexOf(')'));
sig = sig.replace('/', '.');
@ -131,15 +146,11 @@ class Mangle {
return result.toString();
}
//where
private static String getInnerQualifiedName(ClassDoc clazz) {
ClassDoc encl = clazz.containingClass();
if (encl == null)
return clazz.qualifiedName();
else
return getInnerQualifiedName(encl) + '$' + clazz.simpleTypeName();
private String getInnerQualifiedName(TypeElement clazz) {
return elems.getBinaryName(clazz).toString();
}
public static final String mangleChar(char ch) {
public final String mangleChar(char ch) {
String s = Integer.toHexString(ch);
int nzeros = 5 - s.length();
char[] result = new char[6];
@ -151,6 +162,19 @@ class Mangle {
return new String(result);
}
// Warning: duplicated in Gen
private String signature(ExecutableElement e) {
StringBuffer sb = new StringBuffer();
String sep = "(";
for (VariableElement p: e.getParameters()) {
sb.append(sep);
sb.append(types.erasure(p.asType()).toString());
sep = ",";
}
sb.append(")");
return sb.toString();
}
/* Warning: Intentional ASCII operation. */
private static final boolean isalnum(char ch) {
return ch <= 0x7f && /* quick test */

@ -0,0 +1,147 @@
/*
* Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package com.sun.tools.javah; //javax.tools;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.Locale;
import java.util.concurrent.Callable;
import javax.tools.DiagnosticListener;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.OptionChecker;
import javax.tools.StandardJavaFileManager;
import javax.tools.Tool;
/**
* This class is intended to be put in javax.tools.
*
* @see DiagnosticListener
* @see Diagnostic
* @see JavaFileManager
* @since 1.7
*
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
* you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public interface NativeHeaderTool extends Tool, OptionChecker {
/**
* Creates a future for a native header task with the given
* components and arguments. The task might not have
* completed as described in the NativeHeaderTask interface.
*
* <p>If a file manager is provided, it must be able to handle all
* locations defined in {@link StandardLocation}.
*
* @param out a Writer for additional output from the task;
* use {@code System.err} if {@code null}
* @param fileManager a file manager; if {@code null} use the
* task's standard filemanager
* @param diagnosticListener a diagnostic listener; if {@code
* null} use the compiler's default method for reporting
* diagnostics
* @param options task options, {@code null} means no options
* @param classes class names for which native headers should be generated
* @return an object representing the task to be done
* @throws RuntimeException if an unrecoverable error
* occurred in a user supplied component. The
* {@linkplain Throwable#getCause() cause} will be the error in
* user code.
* @throws IllegalArgumentException if any of the given
* compilation units are of other kind than
* {@linkplain JavaFileObject.Kind#SOURCE source}
*/
NativeHeaderTask getTask(Writer out,
JavaFileManager fileManager,
DiagnosticListener<? super JavaFileObject> diagnosticListener,
Iterable<String> options,
Iterable<String> classes);
/**
* Gets a new instance of the standard file manager implementation
* for this tool. The file manager will use the given diagnostic
* listener for producing any non-fatal diagnostics. Fatal errors
* will be signalled with the appropriate exceptions.
*
* <p>The standard file manager will be automatically reopened if
* it is accessed after calls to {@code flush} or {@code close}.
* The standard file manager must be usable with other tools.
*
* @param diagnosticListener a diagnostic listener for non-fatal
* diagnostics; if {@code null} use the tool's default method
* for reporting diagnostics
* @param locale the locale to apply when formatting diagnostics;
* {@code null} means the {@linkplain Locale#getDefault() default locale}.
* @param charset the character set used for decoding bytes; if
* {@code null} use the platform default
* @return the standard file manager
*/
StandardJavaFileManager getStandardFileManager(
DiagnosticListener<? super JavaFileObject> diagnosticListener,
Locale locale,
Charset charset);
/**
* Interface representing a future for a native header task. The
* task has not yet started. To start the task, call
* the {@linkplain #call call} method.
*
* <p>Before calling the call method, additional aspects of the
* task can be configured, for example, by calling the
* {@linkplain #setLocale setLocale} method.
*/
interface NativeHeaderTask extends Callable<Boolean> {
/**
* Set the locale to be applied when formatting diagnostics and
* other localized data.
*
* @param locale the locale to apply; {@code null} means apply no
* locale
* @throws IllegalStateException if the task has started
*/
void setLocale(Locale locale);
/**
* Performs this native header task. The task may only
* be performed once. Subsequent calls to this method throw
* IllegalStateException.
*
* @return true if and only all the files were processed without errors;
* false otherwise
*
* @throws RuntimeException if an unrecoverable error occurred
* in a user-supplied component. The
* {@linkplain Throwable#getCause() cause} will be the error
* in user code.
* @throws IllegalStateException if called more than once
*/
Boolean call();
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,19 +26,34 @@
package com.sun.tools.javah;
import com.sun.javadoc.*;
import java.io.*;
import java.util.*;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.NoType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.type.TypeVisitor;
import javax.lang.model.util.Elements;
import javax.lang.model.util.SimpleTypeVisitor6;
/**
* Returns internal type signature.
*
* <p><b>This is NOT part of any API supported by Sun Microsystems.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*
* @author Sucheta Dambalkar
*/
public class TypeSignature{
RootDoc root = null;
Elements elems;
/* Signature Characters */
@ -56,8 +71,8 @@ public class TypeSignature{
public TypeSignature(RootDoc root){
this.root = root;
public TypeSignature(Elements elems){
this.elems = elems;
}
/*
@ -70,16 +85,15 @@ public class TypeSignature{
/*
* Returns the type signature of a method according to JVM specs
*/
public String getTypeSignature(String javasignature, Type returnType){
public String getTypeSignature(String javasignature, TypeMirror returnType){
String signature = null; //Java type signature.
String typeSignature = null; //Internal type signature.
Vector<Object> params = new Vector<Object>(); //List of parameters.
List<String> params = new ArrayList<String>(); //List of parameters.
String paramsig = null; //Java parameter signature.
String paramJVMSig = null; //Internal parameter signature.
String returnSig = null; //Java return type signature.
String returnJVMType = null; //Internal return type signature.
String dimension = null; //Array dimension.
int dimensions = 0; //Array dimension.
int startIndex = -1;
int endIndex = -1;
@ -87,28 +101,27 @@ public class TypeSignature{
int i = 0;
// Gets the actual java signature without parentheses.
if(javasignature != null){
if (javasignature != null) {
startIndex = javasignature.indexOf("(");
endIndex = javasignature.indexOf(")");
}
if(((startIndex != -1) && (endIndex != -1))
&&(startIndex+1 < javasignature.length())
&&(endIndex < javasignature.length())) {
if (((startIndex != -1) && (endIndex != -1))
&&(startIndex+1 < javasignature.length())
&&(endIndex < javasignature.length())) {
signature = javasignature.substring(startIndex+1, endIndex);
}
// Separates parameters.
if(signature != null){
if(signature.indexOf(",") != -1){
if (signature != null) {
if (signature.indexOf(",") != -1) {
st = new StringTokenizer(signature, ",");
if(st != null){
if (st != null) {
while (st.hasMoreTokens()) {
params.add(st.nextToken());
}
}
}else {
} else {
params.add(signature);
}
}
@ -117,10 +130,10 @@ public class TypeSignature{
typeSignature = "(";
// Gets indivisual internal parameter signature.
while(params.isEmpty() != true){
paramsig =((String)params.remove(i)).trim();
while (params.isEmpty() != true) {
paramsig = params.remove(i).trim();
paramJVMSig = getParamJVMSignature(paramsig);
if(paramJVMSig != null){
if (paramJVMSig != null) {
typeSignature += paramJVMSig;
}
}
@ -130,36 +143,30 @@ public class TypeSignature{
// Get internal return type signature.
returnJVMType = "";
if(returnType != null){
dimension = returnType.dimension();
if (returnType != null) {
dimensions = dimensions(returnType);
}
if(dimension != null){
//Gets array dimension of return type.
while(dimension.indexOf("[]") != -1){
returnJVMType += "[";
int stindex = dimension.indexOf("]") + 1;
if(stindex <= dimension.length()){
dimension = dimension.substring(stindex);
}else dimension = "";
}
//Gets array dimension of return type.
while (dimensions-- > 0) {
returnJVMType += "[";
}
if(returnType != null){
returnSig = returnType.qualifiedTypeName();
if (returnType != null) {
returnSig = qualifiedTypeName(returnType);
returnJVMType += getComponentType(returnSig);
}else {
} else {
System.out.println("Invalid return type.");
}
typeSignature += returnJVMType;
return typeSignature;
}
/*
* Returns internal signature of a parameter.
*/
private String getParamJVMSignature(String paramsig){
private String getParamJVMSignature(String paramsig) {
String paramJVMSig = "";
String componentType ="";
@ -206,12 +213,13 @@ public class TypeSignature{
else if(componentType.equals("double")) JVMSig += SIG_DOUBLE ;
else {
if(!componentType.equals("")){
ClassDoc classNameDoc = root.classNamed(componentType);
TypeElement classNameDoc = elems.getTypeElement(componentType);
if(classNameDoc == null){
System.out.println("Invalid class type");
System.out.println("Invalid class type for " + componentType);
new Exception().printStackTrace();
}else {
String classname = classNameDoc.qualifiedName();
String classname = classNameDoc.getQualifiedName().toString();
String newclassname = classname.replace('.', '/');
JVMSig += "L";
JVMSig += newclassname;
@ -222,4 +230,43 @@ public class TypeSignature{
}
return JVMSig;
}
int dimensions(TypeMirror t) {
if (t.getKind() != TypeKind.ARRAY)
return 0;
return 1 + dimensions(((ArrayType) t).getComponentType());
}
String qualifiedTypeName(TypeMirror type) {
TypeVisitor<Name, Void> v = new SimpleTypeVisitor6<Name, Void>() {
@Override
public Name visitArray(ArrayType t, Void p) {
return t.getComponentType().accept(this, p);
}
@Override
public Name visitDeclared(DeclaredType t, Void p) {
return ((TypeElement) t.asElement()).getQualifiedName();
}
@Override
public Name visitPrimitive(PrimitiveType t, Void p) {
return elems.getName(t.toString());
}
@Override
public Name visitNoType(NoType t, Void p) {
if (t.getKind() == TypeKind.VOID)
return elems.getName("void");
return defaultAction(t, p);
}
@Override
public Name visitTypeVariable(TypeVariable t, Void p) {
return t.getUpperBound().accept(this, p);
}
};
return v.visit(type).toString();
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -26,12 +26,15 @@
package com.sun.tools.javah;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ResourceBundle;
import java.io.PrintWriter;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.MissingResourceException;
import javax.tools.Diagnostic;
import javax.tools.Diagnostic.Kind;
import javax.tools.DiagnosticListener;
import javax.tools.JavaFileObject;
/**
* Messages, verbose and error handling support.
@ -41,42 +44,70 @@ import java.util.MissingResourceException;
* bug -- Bug has occurred in javah
* fatal -- We can't even find resources, so bail fast, don't localize
*
* <p><b>This is NOT part of any API supported by Sun Microsystems.
* If you write code that depends on this, you do so at your own
* risk. This code and its internal interfaces are subject to change
* or deletion without notice.</b></p>
*/
public class Util {
/** Exit is used to replace the use of System.exit in the original javah.
*/
public static class Exit extends Error {
private static final long serialVersionUID = 430820978114067221L;
Exit(int exitValue) {
this(exitValue, null);
}
Exit(int exitValue, Throwable cause) {
super(cause);
this.exitValue = exitValue;
this.cause = cause;
}
Exit(Exit e) {
this(e.exitValue, e.cause);
}
public final int exitValue;
public final Throwable cause;
}
/*
* Help for verbosity.
*/
public static boolean verbose = false;
public boolean verbose = false;
public static void log(String s) {
System.out.println(s);
public PrintWriter log;
public DiagnosticListener<? super JavaFileObject> dl;
Util(PrintWriter log, DiagnosticListener<? super JavaFileObject> dl) {
this.log = log;
this.dl = dl;
}
public void log(String s) {
log.println(s);
}
/*
* Help for loading localized messages.
*/
private static ResourceBundle m;
private ResourceBundle m;
private static void initMessages() {
private void initMessages() throws Exit {
try {
m=ResourceBundle.getBundle("com.sun.tools.javah.resources.l10n");
m = ResourceBundle.getBundle("com.sun.tools.javah.resources.l10n");
} catch (MissingResourceException mre) {
fatal("Error loading resources. Please file a bug report.", mre);
}
}
public static String getText(String key) {
return getText(key, null, null);
}
private static String getText(String key, String a1, String a2){
private String getText(String key, Object... args) throws Exit {
if (m == null)
initMessages();
try {
return MessageFormat.format(m.getString(key),
new Object[] { a1, a2 });
return MessageFormat.format(m.getString(key), args);
} catch (MissingResourceException e) {
fatal("Key " + key + " not found in resources.", e);
}
@ -86,107 +117,74 @@ public class Util {
/*
* Usage message.
*/
public static void usage(int exitValue) {
if (exitValue == 0) {
System.out.println(getText("usage"));
} else {
System.err.println(getText("usage"));
}
System.exit(exitValue);
public void usage() throws Exit {
log.println(getText("usage"));
}
public static void version() {
System.out.println(getText("javah.version",
public void version() throws Exit {
log.println(getText("javah.version",
System.getProperty("java.version"), null));
System.exit(0);
}
/*
* Failure modes.
*/
public static void bug(String key) {
public void bug(String key) throws Exit {
bug(key, null);
}
public static void bug(String key, Exception e) {
if (e != null)
e.printStackTrace();
System.err.println(getText(key));
System.err.println(getText("bug.report"));
System.exit(11);
public void bug(String key, Exception e) throws Exit {
dl.report(createDiagnostic(Diagnostic.Kind.ERROR, key));
dl.report(createDiagnostic(Diagnostic.Kind.NOTE, "bug.report"));
throw new Exit(11, e);
}
public static void error(String key) {
error(key, null);
public void error(String key, Object... args) throws Exit {
dl.report(createDiagnostic(Diagnostic.Kind.ERROR, key, args));
throw new Exit(15);
}
public static void error(String key, String a1) {
error(key, a1, null);
}
public static void error(String key, String a1, String a2) {
error(key, a1, a2, false);
}
public static void error(String key, String a1, String a2,
boolean showUsage) {
System.err.println("Error: " + getText(key, a1, a2));
if (showUsage)
usage(15);
System.exit(15);
}
private static void fatal(String msg) {
private void fatal(String msg) throws Exit {
fatal(msg, null);
}
private static void fatal(String msg, Exception e) {
if (e != null) {
e.printStackTrace();
}
System.err.println(msg);
System.exit(10);
private void fatal(String msg, Exception e) throws Exit {
dl.report(createDiagnostic(Diagnostic.Kind.ERROR, "", msg));
throw new Exit(10, e);
}
/*
* Support for platform specific things in javah, such as pragma
* directives, exported symbols etc.
*/
static private ResourceBundle platform = null;
/*
* Set when platform has been initialized.
*/
static private boolean platformInit = false;
static String getPlatformString(String key) {
if (!platformInit) {
initPlatform();
platformInit = true;
}
if (platform == null)
return null;
try {
return platform.getString(key);
} catch (MissingResourceException mre) {
return null;
}
}
private static void initPlatform() {
String os = System.getProperty("os.name");
if (os.startsWith("Windows")) {
os = "win32";
} else if (os.indexOf("Linux") >= 0) {
os = "Linux";
}
String arch = System.getProperty("os.arch");
String resname = "com.sun.tools.javah.resources." + os + "_" + arch;
try {
platform=ResourceBundle.getBundle(resname);
} catch (MissingResourceException mre) {
// fatal("Error loading resources. Please file a bug report.", mre);
}
private Diagnostic<JavaFileObject> createDiagnostic(
final Diagnostic.Kind kind, final String code, final Object... args) {
return new Diagnostic<JavaFileObject>() {
public String getCode() {
return code;
}
public long getColumnNumber() {
return Diagnostic.NOPOS;
}
public long getEndPosition() {
return Diagnostic.NOPOS;
}
public Kind getKind() {
return kind;
}
public long getLineNumber() {
return Diagnostic.NOPOS;
}
public String getMessage(Locale locale) {
if (code.length() == 0)
return (String) args[0];
return getText(code, args); // FIXME locale
}
public long getPosition() {
return Diagnostic.NOPOS;
}
public JavaFileObject getSource() {
return null;
}
public long getStartPosition() {
return Diagnostic.NOPOS;
}
};
}
}

@ -1,27 +0,0 @@
#
# Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Sun designates this
# particular file as subject to the "Classpath" exception as provided
# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
pack.pragma.start=\#pragma pack(4)\n
pack.pragma.end=\#pragma pack()\n

@ -1,27 +0,0 @@
#
# Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Sun designates this
# particular file as subject to the "Classpath" exception as provided
# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
pack.pragma.start=\#pragma pack(4)\n
pack.pragma.end=\#pragma pack()\n

@ -1,27 +0,0 @@
#
# Copyright 1998 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Sun designates this
# particular file as subject to the "Classpath" exception as provided
# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
pack.pragma.start=\#pragma pack(4)\n
pack.pragma.end=\#pragma pack()\n

@ -21,47 +21,47 @@
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
#
#
# User errors, command line errors.
#
cant.create.dir=\
The directory {0} could not be create for output.
The directory {0} could not be create for output.
at.args.cant.read=\
Can''t read command line arguments from file {1}.
Can''t read command line arguments from file {1}.
at.args.io.exception=\
The following I/O problem was encountered when processing an @ \
The following I/O problem was encountered when processing an @ \
argument on the command line: {0}.
old.jni.mixed=\
Can''t mix options -jni and -old. Try -help.
Can''t mix options -jni and -old. Try -help.
old.llni.mixed=\
Can''t mix options -old and -llni. Try -help.
Can''t mix options -old and -llni. Try -help.
old.not.supported=\
Option -old not supported by this version of javah.
Option -old not supported by this version of javah.
invalid.method.signature=\
Invalid method signature: {0}
Invalid method signature: {0}
jni.llni.mixed=\
Can''t mix options -jni and -llni. Try -help.
Can''t mix options -jni and -llni. Try -help.
jni.no.stubs=\
JNI does not require stubs, please refer to the JNI documentation.
JNI does not require stubs, please refer to the JNI documentation.
dir.file.mixed=\
Can''t mix options -d and -o. Try -help.
Can''t mix options -d and -o. Try -help.
no.classes.specified=\
No classes were specified on the command line. Try -help.
No classes were specified on the command line. Try -help.
no.outputfile.specified=\
No outputfile was specified on the command line. Try -help.
No outputfile was specified on the command line. Try -help.
no.outputdir.specified=\
No output directory was specified on the command line. Try -help.
No output directory was specified on the command line. Try -help.
no.classpath.specified=\
No classpath was specified on the command line. Try -help.
No classpath was specified on the command line. Try -help.
no.bootclasspath.specified=\
No bootclasspath was specified on the command line. Try -help.
No bootclasspath was specified on the command line. Try -help.
unknown.option=\
{0} is an illegal argument\n
{0} is an illegal argument\n
tracing.not.supported=\
Warning: Tracing is no longer supported. Instead, use\
-verbose:jni option of the virtual machine.
Warning: Tracing is no longer supported. Instead, use\
-verbose:jni option of the virtual machine.
#
# Usage message.
@ -79,11 +79,37 @@ where [options] include:\n\
-jni Generate JNI-style header file (default)\n\t\
-version Print version information\n\t\
-verbose Enable verbose output\n\t\
-force Always write output files\n\
-force Always write output files\n\
\n\
<classes> are specified with their fully qualified names (for\n\
instance, java.lang.Object).\n
main.usage=\
Usage: \n\
\ javah [options] <classes>\n\
where [options] include:
main.opt.o=\
\ -o <file> Output file (only one of -d or -o may be used)
main.opt.d=\
\ -d <dir> Output directory
main.opt.v=\
\ -v -verbose Enable verbose output
main.opt.help=\
\ -h --help -? Print this message
main.opt.version=\
\ -version Print version information
main.opt.jni=\
\ -jni Generate JNI-style header file (default)
main.opt.force=\
\ -force Always write output files
main.opt.classpath=\
\ -classpath <path> Path from which to load classes
main.opt.bootclasspath=\
\ -bootclasspath <path> Path from which to load bootstrap classes
main.usage.foot=\
<classes> are specified with their fully qualified names\n\
(for example, java.lang.Object).
#
# Version string.
#
@ -93,26 +119,35 @@ javah.version=javah version "{0}"
# These should have better diagnostics.
#
super.class.not.found=\
A required super class {0} could not be found.
A required super class {0} could not be found.
class.not.found=\
Class {0} could not be found.
Class {0} could not be found.
io.exception=\
Can''t recover from an I/O error with the following message: \
{0}.
Can''t recover from an I/O error with the following message: \
{0}.
#
# Problems in the guts of javah.
#
encoding.iso8859_1.not.found=\
ISO8859_1 converter was not found for output. This is \
ISO8859_1 converter was not found for output. This is \
probably due to an error in the installation installation.
tried.to.define.non.static=\
Tried to generate #define for non-static field.
Tried to generate #define for non-static field.
jni.unknown.type=\
An unknown type encountered (JNI).
An unknown type encountered (JNI).
unknown.array.type=\
An unknown array type encountered when generating old style headers.
An unknown array type encountered when generating old style headers.
unknown.type.for.field=\
An unknown type encountered when generating old style headers.
An unknown type encountered when generating old style headers.
unknown.type.in.method.signature=\
An unknown type eccountered when generating old style stubs.
An unknown type eccountered when generating old style stubs.
err.prefix=Error:
err.cant.use.option.for.fm=Can't use {0} option with given file manager
err.internal.error=Internal error: {0}
err.ioerror=IO error: {0}
err.missing.arg=value missing for {0}
err.no.classes.specified=no classes specified
err.unknown.option=unknown option: {0}

@ -1,28 +0,0 @@
#
# Copyright 1998 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Sun designates this
# particular file as subject to the "Classpath" exception as provided
# by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
dll.export=__declspec(dllexport)
pack.pragma.start=\#pragma pack(4)\n
pack.pragma.end=\#pragma pack()\n

@ -42,7 +42,7 @@ import javax.tools.Tool;
* @see DiagnosticListener
* @see Diagnostic
* @see JavaFileManager
* @since 1.6
* @since 1.7
*
* <p><b>This is NOT part of any API supported by Sun Microsystems. If
* you write code that depends on this, you do so at your own risk.

@ -27,7 +27,6 @@ package javax.tools;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.CharBuffer;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.NestingKind;

@ -0,0 +1,225 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 4241573
* @summary SourceFile attribute includes full path
*/
import com.sun.tools.classfile.Attribute;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.SourceFile_attribute;
import java.io.*;
import java.util.*;
import java.util.jar.*;
public class T4241573 {
public static void main(String... args) throws Exception {
new T4241573().run();
}
public void run() throws Exception {
// Selection of files to be compiled
File absJar = createJar(new File("abs.jar").getAbsoluteFile(), "j.A");
File relJar = createJar(new File("rel.jar"), "j.R");
File absDir = createDir(new File("abs.dir").getAbsoluteFile(), "d.A");
File relDir = createDir(new File("rel.dir"), "d.R");
File absTestFile = writeFile(new File("AbsTest.java").getAbsoluteFile(), "class AbsTest { class Inner { } }");
File relTestFile = writeFile(new File("RelTest.java"), "class RelTest { class Inner { } }");
File relTest2File = writeFile(new File("p/RelTest2.java"), "package p; class RelTest2 { class Inner { } }");
// This next class references other classes that will be found on the source path
// and which will therefore need to be compiled as well.
File mainFile = writeFile(new File("Main.java"),
"class Main { j.A ja; j.R jr; d.A da; d.R dr; }" +
"");
String sourcePath = createPath(absJar, relJar, absDir, relDir);
File outDir = new File("classes");
outDir.mkdirs();
String[] args = {
"-sourcepath", sourcePath,
"-d", outDir.getPath(),
absTestFile.getPath(),
relTestFile.getPath(),
relTest2File.getPath(),
mainFile.getPath(),
};
System.err.println("compile: " + Arrays.asList(args));
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
int rc = com.sun.tools.javac.Main.compile(args, pw);
pw.close();
if (rc != 0) {
System.err.println(sw.toString());
throw new Exception("unexpected exit from javac: " + rc);
}
Set<File> expect = getFiles(outDir,
"d/A.class", "d/A$Inner.class",
"d/R.class", "d/R$Inner.class",
"j/A.class", "j/A$Inner.class",
"j/R.class", "j/R$Inner.class",
"AbsTest.class", "AbsTest$Inner.class",
"RelTest.class", "RelTest$Inner.class",
"p/RelTest2.class", "p/RelTest2$Inner.class",
"Main.class" );
Set<File> found = findFiles(outDir);
if (!found.equals(expect)) {
if (found.containsAll(expect))
throw new Exception("unexpected files found: " + diff(found, expect));
else if (expect.containsAll(found))
throw new Exception("expected files not found: " + diff(expect, found));
}
for (File f: found)
verifySourceFileAttribute(f);
if (errors > 0)
throw new Exception(errors + " errors occurred");
}
/** Check the SourceFileAttribute is the simple name of the original source file. */
void verifySourceFileAttribute(File f) {
System.err.println("verify: " + f);
try {
ClassFile cf = ClassFile.read(f);
SourceFile_attribute sfa = (SourceFile_attribute) cf.getAttribute(Attribute.SourceFile);
String found = sfa.getSourceFile(cf.constant_pool);
String expect = f.getName().replaceAll("([$.].*)?\\.class", ".java");
if (!expect.equals(found)) {
error("bad value found: " + found + ", expected: " + expect);
}
} catch (Exception e) {
error("error reading " + f +": " + e);
}
}
/** Create a directory containing one or more files. */
File createDir(File dir, String... entries) throws Exception {
if (!dir.mkdirs())
throw new Exception("cannot create directories " + dir);
for (String e: entries) {
writeFile(new File(dir, getPathForEntry(e)), getBodyForEntry(e));
}
return dir;
}
/** Create a jar file containing one or more entries. */
File createJar(File jar, String... entries) throws IOException {
OutputStream out = new FileOutputStream(jar);
try {
JarOutputStream jos = new JarOutputStream(out);
for (String e: entries) {
jos.putNextEntry(new JarEntry(getPathForEntry(e)));
jos.write(getBodyForEntry(e).getBytes());
}
jos.close();
} finally {
out.close();
}
return jar;
}
/** Return the path for an entry given to createDir or createJar. */
String getPathForEntry(String e) {
return e.replace(".", File.separator) + ".java";
}
/** Return the body text for an entry given to createDir or createJar. */
String getBodyForEntry(String e) {
int sep = e.lastIndexOf(".");
String pkgName = e.substring(0, sep);
String className = e.substring(sep + 1);
return "package " + pkgName + "; public class " + className + "{ class Inner { } }";
}
/** Write a file containing the given string. Parent directories are
* created as needed. */
File writeFile(File f, String s) throws IOException {
if (f.getParentFile() != null)
f.getParentFile().mkdirs();
FileWriter out = new FileWriter(f);
try {
out.write(s);
} finally {
out.close();
}
return f;
}
/** Create a path value from a list of directories and jar files. */
String createPath(File... files) {
StringBuilder sb = new StringBuilder();
for (File f: files) {
if (sb.length() > 0)
sb.append(File.pathSeparatorChar);
sb.append(f.getPath());
}
return sb.toString();
}
/** Create a set of files from a base directory and a set of relative paths. */
Set<File> getFiles(File dir, String... paths) {
Set<File> files = new LinkedHashSet<File>();
for (String p: paths)
files.add(new File(dir, p));
return files;
}
/** Find all the files in a directory and its subdirectories. */
Set<File> findFiles(File dir) {
Set<File> files = new LinkedHashSet<File>();
findFiles(dir, files);
return files;
}
// where
void findFiles(File dir, Set<File> files) {
for (File f: dir.listFiles()) {
if (f.isDirectory())
findFiles(f, files);
else
files.add(f);
}
}
/** Return the difference of two sets, a - b. */
<T> Set<T> diff(Set<T> a, Set<T> b) {
if (b.isEmpty())
return a;
Set<T> result = new LinkedHashSet<T>(a);
result.removeAll(b);
return result;
}
/** Report an error. */
void error(String msg) {
System.err.println(msg);
errors++;
}
int errors;
}

@ -25,7 +25,7 @@ public class T6589361 {
for (JavaFileObject file : files) {
// Note: Zip/Jar entry names use '/', not File.separator, but just to be sure,
// we normalize the filename as well.
if (file.toString().replace(File.separatorChar, '/').contains("java/lang/Object.class")) {
if (file.getName().replace(File.separatorChar, '/').contains("java/lang/Object.class")) {
String str = fm.inferBinaryName(StandardLocation.CLASS_PATH, file);
if (!str.equals("java.lang.Object")) {
throw new AssertionError("Error in JavacFileManager.inferBinaryName method!");

@ -261,7 +261,7 @@ public class T6769027 {
enum PositionKind {
NOPOS(Position.NOPOS, "- ", "error: "),
POS(5, "/Test.java:1:6: ", "myfo:/Test.java:1: ");
POS(5, "Test.java:1:6: ", "/Test.java:1: ");
int pos;
String rawOutput;

@ -48,7 +48,7 @@ public class T6705935 {
"java.lang",
Collections.singleton(JavaFileObject.Kind.CLASS),
false)) {
String p = ((BaseFileObject)fo).getPath();
String p = fo.getName();
int bra = p.indexOf("(");
int ket = p.indexOf(")");
//System.err.println(bra + "," + ket + "," + p.length());

@ -0,0 +1,43 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6337964
* @summary javac incorrectly disallows trailing comma in annotation arrays
* @author darcy
* @compile TrailingComma.java
*/
import java.lang.annotation.*;
@interface TestAnnotation {
SuppressWarnings[] value() default {@SuppressWarnings({"",})};
}
@TestAnnotation({@SuppressWarnings(),
@SuppressWarnings({"Beware the ides of March.",}),
@SuppressWarnings({"Look both ways", "Before Crossing",}), })
public class TrailingComma {
}

@ -37,7 +37,7 @@ import static javax.tools.StandardLocation.PLATFORM_CLASS_PATH;
import static javax.tools.StandardLocation.CLASS_PATH;
import static javax.tools.JavaFileObject.Kind.CLASS;
// Limited test while we wait for 6419926
// Limited test while we wait for 6419926: 6419926 is now closed
public class T6411310 extends ToolTester {
@ -45,8 +45,11 @@ public class T6411310 extends ToolTester {
JavaFileObject file = fm.getJavaFileForInput(PLATFORM_CLASS_PATH,
"java.lang.Object",
CLASS);
if (!file.getName().equals("Object.class"))
String fileName = file.getName();
if (!fileName.matches(".*java/lang/Object.class\\)?")) {
System.err.println(fileName);
throw new AssertionError(file);
}
}
public static void main(String... args) throws IOException {

@ -0,0 +1,254 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6410367 6411310
* @summary FileObject should support user-friendly names via getName()
*/
import java.io.*;
import java.util.*;
import java.util.jar.*;
import java.util.zip.*;
import javax.tools.*;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Options;
// Test FileObject.getName returned from JavacFileManager and its support classes.
public class Test {
public static void main(String... args) throws Exception {
new Test().run();
}
Set<String> foundClasses = new TreeSet<String>();
Set<String> foundJars = new TreeSet<String>();
void run() throws Exception {
File rt_jar = findRtJar();
// names for entries to be created in directories and jar files
String[] entries = { "p/A.java", "p/A.class", "p/resources/A-1.html" };
// test various combinations of directories and jar files, intended to
// cover all sources of file objects within JavacFileManager's support classes
test(createFileManager(), createDir("dir", entries), "p", entries);
test(createFileManager(), createDir("a b/dir", entries), "p", entries);
for (boolean useJavaUtilZip: new boolean[] { false, true }) {
test(createFileManager(useJavaUtilZip), createJar("jar", entries), "p", entries);
test(createFileManager(useJavaUtilZip), createJar("jar jar", entries), "p", entries);
for (boolean useSymbolFile: new boolean[] { false, true }) {
test(createFileManager(useJavaUtilZip, useSymbolFile), rt_jar, "java.lang.ref", null);
}
}
if (errors > 0)
throw new Exception(errors + " errors found");
// Verify that we hit all the impl classes we intended
checkCoverage("classes", foundClasses,
"RegularFileObject", "SymbolFileObject", "ZipFileIndexFileObject", "ZipFileObject");
// Verify that we hit the jar files we intended, specifically ct.sym as well as rt.jar
checkCoverage("jar files", foundJars,
"ct.sym", "jar", "jar jar", "rt.jar");
}
// use a new file manager for each test
void test(StandardJavaFileManager fm, File f, String pkg, String[] entries) throws Exception {
System.err.println("Test " + f);
try {
if (f.isDirectory()) {
for (File dir: new File[] { f, f.getAbsoluteFile() }) {
for (String e: entries) {
JavaFileObject fo = fm.getJavaFileObjects(new File(dir, e)).iterator().next();
test(fo, dir, e);
}
}
}
fm.setLocation(StandardLocation.CLASS_PATH, Collections.singleton(f));
fm.setLocation(StandardLocation.SOURCE_PATH, Collections.singleton(f.getAbsoluteFile()));
for (StandardLocation l: EnumSet.of(StandardLocation.CLASS_PATH, StandardLocation.SOURCE_PATH)) {
for (JavaFileObject fo: fm.list(l, pkg, EnumSet.allOf(JavaFileObject.Kind.class), true)) {
// we could use fm.getLocation but the following guarantees we preserve the original filename
File dir = (l == StandardLocation.CLASS_PATH ? f : f.getAbsoluteFile());
char sep = (dir.isDirectory() ? File.separatorChar : '/');
String b = fm.inferBinaryName(l, fo);
String e = fo.getKind().extension;
test(fo, dir, b.replace('.', sep) + e);
}
}
} finally {
fm.close();
}
}
void test(JavaFileObject fo, File dir, String p) {
System.err.println("Test: " + fo);
String expect = dir.isDirectory() ? new File(dir, p).getPath() : (dir.getPath() + "(" + p + ")");
String found = fo.getName();
// if ct.sym is found, replace it with the equivalent rt.jar
String found2 = found.replaceAll("lib([\\\\/])ct.sym\\(META-INF/sym/rt.jar/", "jre$1lib$1rt.jar(");
if (!expect.equals(found2)) {
System.err.println("expected: " + expect);
System.err.println(" found: " + found);
if (!found.equals(found2))
System.err.println(" found2: " + found2);
error("Failed: " + fo);
}
// record the file object class name for coverage checks later
foundClasses.add(fo.getClass().getSimpleName());
if (found.contains("(")) {
// record access to the jar file for coverage checks later
foundJars.add(new File(found.substring(0, found.indexOf("("))).getName());
}
}
void checkCoverage(String label, Set<String> found, String... expect) throws Exception {
Set<String> e = new TreeSet<String>(Arrays.asList(expect));
if (!found.equals(e)) {
e.removeAll(found);
throw new Exception("expected " + label + " not used: " + e);
}
}
JavacFileManager createFileManager() {
return createFileManager(false, false);
}
JavacFileManager createFileManager(boolean useJavaUtilZip) {
return createFileManager(useJavaUtilZip, false);
}
JavacFileManager createFileManager(boolean useJavaUtilZip, boolean useSymbolFile) {
// javac should really not be using system properties like this
// -- it should really be using (hidden) options -- but until then
// take care to leave system properties as we find them, so as not
// to adversely affect other tests that might follow.
String prev = System.getProperty("useJavaUtilZip");
boolean resetProperties = false;
try {
if (useJavaUtilZip) {
System.setProperty("useJavaUtilZip", "true");
resetProperties = true;
} else if (System.getProperty("useJavaUtilZip") != null) {
System.getProperties().remove("useJavaUtilZip");
resetProperties = true;
}
Context c = new Context();
if (!useSymbolFile) {
Options options = Options.instance(c);
options.put("ignore.symbol.file", "true");
}
return new JavacFileManager(c, false, null);
} finally {
if (resetProperties) {
if (prev == null) {
System.getProperties().remove("useJavaUtilZip");
} else {
System.setProperty("useJavaUtilZip", prev);
}
}
}
}
File createDir(String name, String... entries) throws Exception {
File dir = new File(name);
if (!dir.mkdirs())
throw new Exception("cannot create directories " + dir);
for (String e: entries) {
writeFile(new File(dir, e), e);
}
return dir;
}
File createJar(String name, String... entries) throws IOException {
File jar = new File(name);
OutputStream out = new FileOutputStream(jar);
try {
JarOutputStream jos = new JarOutputStream(out);
for (String e: entries) {
jos.putNextEntry(new ZipEntry(e));
jos.write(e.getBytes());
}
jos.close();
} finally {
out.close();
}
return jar;
}
File findRtJar() throws Exception {
File java_home = new File(System.getProperty("java.home"));
if (java_home.getName().equals("jre"))
java_home = java_home.getParentFile();
File rt_jar = new File(new File(new File(java_home, "jre"), "lib"), "rt.jar");
if (!rt_jar.exists())
throw new Exception("can't find rt.jar");
return rt_jar;
}
byte[] read(InputStream in) throws IOException {
byte[] data = new byte[1024];
int offset = 0;
try {
int n;
while ((n = in.read(data, offset, data.length - offset)) != -1) {
offset += n;
if (offset == data.length)
data = Arrays.copyOf(data, 2 * data.length);
}
} finally {
in.close();
}
return Arrays.copyOf(data, offset);
}
void writeFile(File f, String s) throws IOException {
f.getParentFile().mkdirs();
FileWriter out = new FileWriter(f);
try {
out.write(s);
} finally {
out.close();
}
}
void error(String msg) {
System.err.println(msg);
errors++;
}
int errors;
}

@ -46,14 +46,10 @@ public class T6733837 extends ToolTester {
}
public void exec() {
JavaFileObject sfo = new SimpleJavaFileObject(URI.create(""),Kind.SOURCE) {
JavaFileObject sfo = new SimpleJavaFileObject(URI.create("myfo:/Test.java"),Kind.SOURCE) {
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return "\tclass ErroneousWithTab";
}
@Override
public String getName() {
return "RELATIVEPATH";
}
};
StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw);
@ -66,7 +62,7 @@ public class T6733837 extends ToolTester {
throw new Error("Compiler threw an exception");
}
System.err.println(sw.toString());
if (sw.toString().contains("RELATIVEPATH"))
if (!sw.toString().contains("/Test.java"))
throw new Error("Bad source name in diagnostic");
}
}

@ -0,0 +1,29 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* Dummy type to compile.
*/
public class Foo {
}

@ -0,0 +1,143 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6471577 6517779
* @summary Test Elements.getConstantExpression
* @author Joseph D. Darcy
* @build TestGetConstantExpression
* @compile -processor TestGetConstantExpression Foo.java
*/
import java.util.Set;
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import static javax.lang.model.SourceVersion.*;
import javax.lang.model.element.*;
import javax.lang.model.util.*;
import static javax.lang.model.util.ElementFilter.*;
import static javax.tools.Diagnostic.Kind.*;
import static javax.tools.StandardLocation.*;
import java.io.*;
/**
* Test basic workings of Elements.getConstantExpression.
*/
@SupportedAnnotationTypes("*")
public class TestGetConstantExpression extends AbstractProcessor {
private Elements eltUtils;
private Filer filer;
private int round = 1;
/**
* Check expected behavior on classes and packages.
*/
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
int errors = 0;
boolean processingOver = roundEnv.processingOver();
if (!processingOver && round == 1) {
errors += expectIllegalArgumentException(null);
errors += expectIllegalArgumentException(this);
// Generate source code with various constant values and
// make sure it compiles.
try {
PrintWriter pw = new PrintWriter(filer.createSourceFile("ConstantTest").openWriter());
try {
Boolean[] booleans = {true, false};
Byte[] bytes = {Byte.MIN_VALUE, -1, 0, 1, Byte.MAX_VALUE};
Short[] shorts = {Short.MIN_VALUE, -1, 0, 1, Short.MAX_VALUE};
Integer[] ints = {Integer.MIN_VALUE, -1, 0, 1, Integer.MAX_VALUE};
Long[] longs = {Long.MIN_VALUE, -1L, 0L,1L, Long.MAX_VALUE};
Character[] chars = {Character.MIN_VALUE, ' ', '\t', 'a', 'b', 'c', '~', Character.MAX_VALUE};
Float[] floats = {Float.NaN, Float.NEGATIVE_INFINITY, -1.0f, -0.0f, 0.0f, 1.0f, Float.POSITIVE_INFINITY};
Double[] doubles = {Double.NaN, Double.NEGATIVE_INFINITY, -1.0, -0.0, 0.0, 1.0, Double.POSITIVE_INFINITY};
pw.println("class ConstantTest {");
pw.println(String.format(" private static boolean[] booleans = {%s};",
printConstants(booleans)));
pw.println(String.format(" private static byte[] bytes = {%s};",
printConstants(bytes)));
pw.println(String.format(" private static short[] shorts = {%s};",
printConstants(shorts)));
pw.println(String.format(" private static int[] ints = {%s};",
printConstants(ints)));
pw.println(String.format(" private static long[] longs = {%s};",
printConstants(longs)));
pw.println(String.format(" private static char[] chars = {%s};",
printConstants(chars)));
pw.println(String.format(" private static float[] floats = {%s};",
printConstants(floats)));
pw.println(String.format(" private static double[] doubles = {%s};",
printConstants(doubles)));
pw.println("}");
} finally {
pw.close();
}
} catch(IOException io) {
throw new RuntimeException(io);
}
round++;
} else if (processingOver) {
if (errors > 0) {
throw new RuntimeException();
}
}
return true;
}
String printConstants(Object[] constants) {
StringBuilder sb = new StringBuilder();
for(Object o : constants) {
sb.append(eltUtils.getConstantExpression(o));
sb.append(", ");
}
return sb.toString();
}
int expectIllegalArgumentException(Object o) {
String s = "";
try {
s = eltUtils.getConstantExpression(o);
System.err.println("Unexpected string returned: " + s);
return 1;
} catch (IllegalArgumentException iae) {
return 0;
}
}
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
}
public void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
eltUtils = processingEnv.getElementUtils();
filer = processingEnv.getFiler();
}
}

@ -0,0 +1,239 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6572945
* @summary rewrite javah as an annotation processor, instead of as a doclet
* @build TestClass1 TestClass2 TestClass3
* @run main T6572945
*/
import java.io.*;
import java.util.*;
import com.sun.tools.javah.Main;
public class T6572945
{
static File testSrc = new File(System.getProperty("test.src", "."));
static File testClasses = new File(System.getProperty("test.classes", "."));
static boolean isWindows = System.getProperty("os.name").startsWith("Windows");
public static void main(String... args)
throws IOException, InterruptedException
{
boolean ok = new T6572945().run(args);
if (!ok)
throw new Error("Test Failed");
}
public boolean run(String[] args)
throws IOException, InterruptedException
{
if (args.length == 1)
jdk = new File(args[0]);
test("-o", "jni.file.1", "-jni", "TestClass1");
test("-o", "jni.file.2", "-jni", "TestClass1", "TestClass2");
test("-d", "jni.dir.1", "-jni", "TestClass1", "TestClass2");
test("-o", "jni.file.3", "-jni", "TestClass3");
// The following tests are disabled because llni support has been
// discontinued, and because bugs in old javah means that character
// for character testing against output from old javah does not work.
// In fact, the LLNI impl in new javah is actually better than the
// impl in old javah because of a couple of significant bug fixes.
// test("-o", "llni.file.1", "-llni", "TestClass1");
// test("-o", "llni.file.2", "-llni", "TestClass1", "TestClass2");
// test("-d", "llni.dir.1", "-llni", "TestClass1", "TestClass2");
// test("-o", "llni.file.3", "-llni", "TestClass3");
return (errors == 0);
}
void test(String... args)
throws IOException, InterruptedException
{
String[] cp_args = new String[args.length + 2];
cp_args[0] = "-classpath";
cp_args[1] = testClasses.getPath();
System.arraycopy(args, 0, cp_args, 2, args.length);
if (jdk != null)
init(cp_args);
File out = null;
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-o")) {
out = new File(args[++i]);
break;
} else if (args[i].equals("-d")) {
out = new File(args[++i]);
out.mkdirs();
break;
}
}
try {
System.out.println("test: " + Arrays.asList(cp_args));
// // Uncomment and use the following lines to execute javah via the
// // command line -- for example, to run old javah and set up the golden files
// List<String> cmd = new ArrayList<String>();
// File javaHome = new File(System.getProperty("java.home"));
// if (javaHome.getName().equals("jre"))
// javaHome = javaHome.getParentFile();
// File javah = new File(new File(javaHome, "bin"), "javah");
// cmd.add(javah.getPath());
// cmd.addAll(Arrays.asList(cp_args));
// ProcessBuilder pb = new ProcessBuilder(cmd);
// pb.redirectErrorStream(true);
// pb.start();
// Process p = pb.start();
// String line;
// BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
// while ((line = in.readLine()) != null)
// System.err.println(line);
// in.close();
// int rc = p.waitFor();
// Use new javah
PrintWriter err = new PrintWriter(System.err, true);
int rc = Main.run(cp_args, err);
if (rc != 0) {
error("javah failed: rc=" + rc);
return;
}
// The golden files use the LL suffix for long constants, which
// is used on Linux and Solaris. On Windows, the suffix is i64,
// so compare will update the golden files on the fly before the
// final comparison.
compare(new File(new File(testSrc, "gold"), out.getName()), out);
} catch (Throwable t) {
t.printStackTrace();
error("javah threw exception");
}
}
void init(String[] args) throws IOException, InterruptedException {
String[] cmdArgs = new String[args.length + 1];
cmdArgs[0] = new File(new File(jdk, "bin"), "javah").getPath();
System.arraycopy(args, 0, cmdArgs, 1, args.length);
System.out.println("init: " + Arrays.asList(cmdArgs));
ProcessBuilder pb = new ProcessBuilder(cmdArgs);
pb.directory(new File(testSrc, "gold"));
pb.redirectErrorStream(true);
Process p = pb.start();
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = in.readLine()) != null)
System.out.println("javah: " + line);
int rc = p.waitFor();
if (rc != 0)
error("javah: exit code " + rc);
}
/** Compare two directories.
* @param f1 The golden directory
* @param f2 The directory to be compared
*/
void compare(File f1, File f2) {
compare(f1, f2, null);
}
/** Compare two files or directories
* @param f1 The golden directory
* @param f2 The directory to be compared
* @param p An optional path identifying a file within the two directories
*/
void compare(File f1, File f2, String p) {
File f1p = (p == null ? f1 : new File(f1, p));
File f2p = (p == null ? f2 : new File(f2, p));
System.out.println("compare " + f1p + " " + f2p);
if (f1p.isDirectory() && f2p.isDirectory()) {
Set<String> children = new HashSet<String>();
children.addAll(Arrays.asList(f1p.list()));
children.addAll(Arrays.asList(f2p.list()));
for (String c: children) {
compare(f1, f2, new File(p, c).getPath()); // null-safe for p
}
}
else if (f1p.isFile() && f2p.isFile()) {
String s1 = read(f1p);
if (isWindows) {
// f1/s1 is the golden file
// on Windows, long constants use the i64 suffix, not LL
s1 = s1.replaceAll("( [0-9]+)LL\n", "$1i64\n");
}
String s2 = read(f2p);
if (!s1.equals(s2)) {
System.out.println("File: " + f1p + "\n" + s1);
System.out.println("File: " + f2p + "\n" + s2);
error("Files differ: " + f1p + " " + f2p);
}
}
else if (f1p.exists() && !f2p.exists())
error("Only in " + f1 + ": " + p);
else if (f2p.exists() && !f1p.exists())
error("Only in " + f2 + ": " + p);
else
error("Files differ: " + f1p + " " + f2p);
}
private String read(File f) {
try {
BufferedReader in = new BufferedReader(new FileReader(f));
try {
StringBuilder sb = new StringBuilder((int) f.length());
String line;
while ((line = in.readLine()) != null) {
sb.append(line);
sb.append("\n");
}
return sb.toString();
} finally {
try {
in.close();
} catch (IOException e) {
}
}
} catch (IOException e) {
error("error reading " + f + ": " + e);
return "";
}
}
private void error(String msg) {
System.out.println(msg);
errors++;
}
private int errors;
private File jdk;
}

@ -0,0 +1,475 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import java.util.List;
public class TestClass1 {
// simple types
byte b;
short s;
int i;
long l;
float f;
double d;
Object o;
String t;
List<String> g;
// constants
static final byte bc = 0;
static final short sc = 0;
static final int ic = 0;
static final long lc = 0;
static final float fc = 0;
static final double dc = 0;
static final Object oc = null;
static final String tc = "";
static final List<String> gc = null;
// simple arrays
byte[] ba;
short[] sa; // not handled corrected by javah v6
int[] ia;
long[] la;
float[] fa;
double[] da;
Object[] oa;
String[] ta;
List<String>[] ga;
// multidimensional arrays
byte[][] baa;
short[][] saa;
int[][] iaa;
long[][] laa;
float[][] faa;
double[][] daa;
Object[][] oaa;
String[][] taa;
List<String>[] gaa;
// simple Java methods
byte bm() { return 0; }
short sm() { return 0; }
int im() { return 0; }
long lm() { return 0; }
float fm() { return 0; }
double dm() { return 0; }
Object om() { return null; }
String tm() { return ""; }
List<String> gm() { return null; }
void vm() { }
byte[] bam() { return null; }
short[] sam() { return null; }
int[] iam() { return null; }
long[] lam() { return null; }
float[] fam() { return null; }
double[] dam() { return null; }
Object[] oam() { return null; }
String[] tam() { return null; }
List<String>[] gam() { return null; }
byte[][] baam() { return null; }
short[][] saam() { return null; }
int[][] iaam() { return null; }
long[][] laam() { return null; }
float[][] faam() { return null; }
double[][] daam() { return null; }
Object[][] oaam() { return null; }
String[][] taam() { return null; }
List<String>[] gaam() { return null; }
// simple native methods
native byte bmn();
native short smn();
native int imn();
native long lmn();
native float fmn();
native double dmn();
native Object omn();
native String tmn();
native List<String> gmn();
native void vmn();
native byte[] bamn();
native short[] samn();
native int[] iamn();
native long[] lamn();
native float[] famn();
native double[] damn();
native Object[] oamn();
native String[] tamn();
native List<String>[] gamn();
native byte[][] baamn();
native short[][] saamn();
native int[][] iaamn();
native long[][] laamn();
native float[][] faamn();
native double[][] daamn();
native Object[][] oaamn();
native String[][] taamn();
native List<String>[] gaamn();
// overloaded Java methods
byte bm1() { return 0; }
short sm1() { return 0; }
int im1() { return 0; }
long lm1() { return 0; }
float fm1() { return 0; }
double dm1() { return 0; }
Object om1() { return null; }
String tm1() { return ""; }
List<String> gm1() { return null; }
void vm1() { }
byte bm2(int i) { return 0; }
short sm2(int i) { return 0; }
int im2(int i) { return 0; }
long lm2(int i) { return 0; }
float fm2(int i) { return 0; }
double dm2(int i) { return 0; }
Object om2(int i) { return null; }
String tm2(int i) { return ""; }
List<String> gm2(int i) { return null; }
void vm2(int i) { }
// overloaded native methods
native byte bmn1();
native short smn1();
native int imn1();
native long lmn1();
native float fmn1();
native double dmn1();
native Object omn1();
native String tmn1();
native List<String> gmn1();
native void vmn1();
native byte bmn2(int i);
native short smn2(int i);
native int imn2(int i);
native long lmn2(int i);
native float fmn2(int i);
native double dmn2(int i);
native Object omn2(int i);
native String tmn2(int i);
native List<String> gmn2(int i);
native void vmn2(int i);
// arg types for Java methods
void mb(byte b) { }
void ms(short s) { }
void mi(int i) { }
void ml(long l) { }
void mf(float f) { }
void md(double d) { }
void mo(Object o) { }
void mt(String t) { }
void mg(List<String> g) { }
// arg types for native methods
native void mbn(byte b);
native void msn(short s);
native void min(int i);
native void mln(long l);
native void mfn(float f);
native void mdn(double d);
native void mon(Object o);
native void mtn(String t);
native void mgn(List<String> g);
static class Inner1 {
// simple types
byte b;
short s;
int i;
long l;
float f;
double d;
Object o;
String t;
List<String> g;
// constants
static final byte bc = 0;
static final short sc = 0;
static final int ic = 0;
static final long lc = 0;
static final float fc = 0;
static final double dc = 0;
static final Object oc = null;
static final String tc = "";
static final List<String> gc = null;
// simple arrays
byte[] ba;
// short[] sa; // not handled corrected by javah v6
int[] ia;
long[] la;
float[] fa;
double[] da;
Object[] oa;
String[] ta;
List<String>[] ga;
// multidimensional arrays
byte[][] baa;
short[][] saa;
int[][] iaa;
long[][] laa;
float[][] faa;
double[][] daa;
Object[][] oaa;
String[][] taa;
List<String>[] gaa;
// simple Java methods
byte bm() { return 0; }
short sm() { return 0; }
int im() { return 0; }
long lm() { return 0; }
float fm() { return 0; }
double dm() { return 0; }
Object om() { return null; }
String tm() { return ""; }
List<String> gm() { return null; }
void vm() { }
// simple native methods
native byte bmn();
native short smn();
native int imn();
native long lmn();
native float fmn();
native double dmn();
native Object omn();
native String tmn();
native List<String> gmn();
native void vmn();
// overloaded Java methods
byte bm1() { return 0; }
short sm1() { return 0; }
int im1() { return 0; }
long lm1() { return 0; }
float fm1() { return 0; }
double dm1() { return 0; }
Object om1() { return null; }
String tm1() { return ""; }
List<String> gm1() { return null; }
void vm1() { }
byte bm2(int i) { return 0; }
short sm2(int i) { return 0; }
int im2(int i) { return 0; }
long lm2(int i) { return 0; }
float fm2(int i) { return 0; }
double dm2(int i) { return 0; }
Object om2(int i) { return null; }
String tm2(int i) { return ""; }
List<String> gm2(int i) { return null; }
void vm2(int i) { }
// overloaded native methods
native byte bmn1();
native short smn1();
native int imn1();
native long lmn1();
native float fmn1();
native double dmn1();
native Object omn1();
native String tmn1();
native List<String> gmn1();
native void vmn1();
native byte bmn2(int i);
native short smn2(int i);
native int imn2(int i);
native long lmn2(int i);
native float fmn2(int i);
native double dmn2(int i);
native Object omn2(int i);
native String tmn2(int i);
native List<String> gmn2(int i);
native void vmn2(int i);
// arg types for Java methods
void mb(byte b) { }
void ms(short s) { }
void mi(int i) { }
void ml(long l) { }
void mf(float f) { }
void md(double d) { }
void mo(Object o) { }
void mt(String t) { }
void mg(List<String> g) { }
// arg types for native methods
native void mbn(byte b);
native void msn(short s);
native void min(int i);
native void mln(long l);
native void mfn(float f);
native void mdn(double d);
native void mon(Object o);
native void mtn(String t);
native void mgn(List<String> g);
}
class Inner2 {
// simple types
byte b;
short s;
int i;
long l;
float f;
double d;
Object o;
String t;
List<String> g;
// constants
static final byte bc = 0;
static final short sc = 0;
static final int ic = 0;
static final long lc = 0;
static final float fc = 0;
static final double dc = 0;
//static final Object oc = null;
static final String tc = "";
//static final List<String> gc = null;
// simple arrays
byte[] ba;
// short[] sa; // not handled corrected by javah v6
int[] ia;
long[] la;
float[] fa;
double[] da;
Object[] oa;
String[] ta;
List<String>[] ga;
// multidimensional arrays
byte[][] baa;
short[][] saa;
int[][] iaa;
long[][] laa;
float[][] faa;
double[][] daa;
Object[][] oaa;
String[][] taa;
List<String>[] gaa;
// simple Java methods
byte bm() { return 0; }
short sm() { return 0; }
int im() { return 0; }
long lm() { return 0; }
float fm() { return 0; }
double dm() { return 0; }
Object om() { return null; }
String tm() { return ""; }
List<String> gm() { return null; }
void vm() { }
// simple native methods
native byte bmn();
native short smn();
native int imn();
native long lmn();
native float fmn();
native double dmn();
native Object omn();
native String tmn();
native List<String> gmn();
native void vmn();
// overloaded Java methods
byte bm1() { return 0; }
short sm1() { return 0; }
int im1() { return 0; }
long lm1() { return 0; }
float fm1() { return 0; }
double dm1() { return 0; }
Object om1() { return null; }
String tm1() { return ""; }
List<String> gm1() { return null; }
void vm1() { }
byte bm2(int i) { return 0; }
short sm2(int i) { return 0; }
int im2(int i) { return 0; }
long lm2(int i) { return 0; }
float fm2(int i) { return 0; }
double dm2(int i) { return 0; }
Object om2(int i) { return null; }
String tm2(int i) { return ""; }
List<String> gm2(int i) { return null; }
void vm2(int i) { }
// overloaded native methods
native byte bmn1();
native short smn1();
native int imn1();
native long lmn1();
native float fmn1();
native double dmn1();
native Object omn1();
native String tmn1();
native List<String> gmn1();
native void vmn1();
native byte bmn2(int i);
native short smn2(int i);
native int imn2(int i);
native long lmn2(int i);
native float fmn2(int i);
native double dmn2(int i);
native Object omn2(int i);
native String tmn2(int i);
native List<String> gmn2(int i);
native void vmn2(int i);
// arg types for Java methods
void mb(byte b) { }
void ms(short s) { }
void mi(int i) { }
void ml(long l) { }
void mf(float f) { }
void md(double d) { }
void mo(Object o) { }
void mt(String t) { }
void mg(List<String> g) { }
// arg types for native methods
native void mbn(byte b);
native void msn(short s);
native void min(int i);
native void mln(long l);
native void mfn(float f);
native void mdn(double d);
native void mon(Object o);
native void mtn(String t);
native void mgn(List<String> g);
}
}

@ -0,0 +1,33 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
public class TestClass2 {
byte b;
short s;
int i;
long l;
float f;
double d;
Object o;
String t;
}

@ -0,0 +1,51 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
public class TestClass3 {
public int tc3;
public class Inner1 {
public int tc3i1;
public class Inner1A {
public int tc3i1i1a;
}
public class Inner1B {
public int tc3i1i1b;
}
}
public class Inner2 {
public int tc321;
public class Inner2A {
public int tc3i2i2a;
}
public class Inner2B {
public int tc3i2i2b;
}
}
}

@ -0,0 +1,481 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TestClass1 */
#ifndef _Included_TestClass1
#define _Included_TestClass1
#ifdef __cplusplus
extern "C" {
#endif
#undef TestClass1_bc
#define TestClass1_bc 0L
#undef TestClass1_sc
#define TestClass1_sc 0L
#undef TestClass1_ic
#define TestClass1_ic 0L
#undef TestClass1_lc
#define TestClass1_lc 0LL
#undef TestClass1_fc
#define TestClass1_fc 0.0f
#undef TestClass1_dc
#define TestClass1_dc 0.0
/*
* Class: TestClass1
* Method: bmn
* Signature: ()B
*/
JNIEXPORT jbyte JNICALL Java_TestClass1_bmn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: smn
* Signature: ()S
*/
JNIEXPORT jshort JNICALL Java_TestClass1_smn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: imn
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_TestClass1_imn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: lmn
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_TestClass1_lmn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: fmn
* Signature: ()F
*/
JNIEXPORT jfloat JNICALL Java_TestClass1_fmn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: dmn
* Signature: ()D
*/
JNIEXPORT jdouble JNICALL Java_TestClass1_dmn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: omn
* Signature: ()Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_TestClass1_omn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: tmn
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_TestClass1_tmn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: gmn
* Signature: ()Ljava/util/List;
*/
JNIEXPORT jobject JNICALL Java_TestClass1_gmn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: vmn
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_TestClass1_vmn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: bamn
* Signature: ()[B
*/
JNIEXPORT jbyteArray JNICALL Java_TestClass1_bamn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: samn
* Signature: ()[S
*/
JNIEXPORT jshortArray JNICALL Java_TestClass1_samn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: iamn
* Signature: ()[I
*/
JNIEXPORT jintArray JNICALL Java_TestClass1_iamn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: lamn
* Signature: ()[J
*/
JNIEXPORT jlongArray JNICALL Java_TestClass1_lamn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: famn
* Signature: ()[F
*/
JNIEXPORT jfloatArray JNICALL Java_TestClass1_famn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: damn
* Signature: ()[D
*/
JNIEXPORT jdoubleArray JNICALL Java_TestClass1_damn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: oamn
* Signature: ()[Ljava/lang/Object;
*/
JNIEXPORT jobjectArray JNICALL Java_TestClass1_oamn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: tamn
* Signature: ()[Ljava/lang/String;
*/
JNIEXPORT jobjectArray JNICALL Java_TestClass1_tamn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: gamn
* Signature: ()[Ljava/util/List;
*/
JNIEXPORT jobjectArray JNICALL Java_TestClass1_gamn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: baamn
* Signature: ()[[B
*/
JNIEXPORT jobjectArray JNICALL Java_TestClass1_baamn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: saamn
* Signature: ()[[S
*/
JNIEXPORT jobjectArray JNICALL Java_TestClass1_saamn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: iaamn
* Signature: ()[[I
*/
JNIEXPORT jobjectArray JNICALL Java_TestClass1_iaamn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: laamn
* Signature: ()[[J
*/
JNIEXPORT jobjectArray JNICALL Java_TestClass1_laamn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: faamn
* Signature: ()[[F
*/
JNIEXPORT jobjectArray JNICALL Java_TestClass1_faamn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: daamn
* Signature: ()[[D
*/
JNIEXPORT jobjectArray JNICALL Java_TestClass1_daamn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: oaamn
* Signature: ()[[Ljava/lang/Object;
*/
JNIEXPORT jobjectArray JNICALL Java_TestClass1_oaamn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: taamn
* Signature: ()[[Ljava/lang/String;
*/
JNIEXPORT jobjectArray JNICALL Java_TestClass1_taamn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: gaamn
* Signature: ()[Ljava/util/List;
*/
JNIEXPORT jobjectArray JNICALL Java_TestClass1_gaamn
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: bmn1
* Signature: ()B
*/
JNIEXPORT jbyte JNICALL Java_TestClass1_bmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: smn1
* Signature: ()S
*/
JNIEXPORT jshort JNICALL Java_TestClass1_smn1
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: imn1
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_TestClass1_imn1
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: lmn1
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_TestClass1_lmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: fmn1
* Signature: ()F
*/
JNIEXPORT jfloat JNICALL Java_TestClass1_fmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: dmn1
* Signature: ()D
*/
JNIEXPORT jdouble JNICALL Java_TestClass1_dmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: omn1
* Signature: ()Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_TestClass1_omn1
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: tmn1
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_TestClass1_tmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: gmn1
* Signature: ()Ljava/util/List;
*/
JNIEXPORT jobject JNICALL Java_TestClass1_gmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: vmn1
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_TestClass1_vmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1
* Method: bmn2
* Signature: (I)B
*/
JNIEXPORT jbyte JNICALL Java_TestClass1_bmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1
* Method: smn2
* Signature: (I)S
*/
JNIEXPORT jshort JNICALL Java_TestClass1_smn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1
* Method: imn2
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_TestClass1_imn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1
* Method: lmn2
* Signature: (I)J
*/
JNIEXPORT jlong JNICALL Java_TestClass1_lmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1
* Method: fmn2
* Signature: (I)F
*/
JNIEXPORT jfloat JNICALL Java_TestClass1_fmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1
* Method: dmn2
* Signature: (I)D
*/
JNIEXPORT jdouble JNICALL Java_TestClass1_dmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1
* Method: omn2
* Signature: (I)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_TestClass1_omn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1
* Method: tmn2
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_TestClass1_tmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1
* Method: gmn2
* Signature: (I)Ljava/util/List;
*/
JNIEXPORT jobject JNICALL Java_TestClass1_gmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1
* Method: vmn2
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_TestClass1_vmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1
* Method: mbn
* Signature: (B)V
*/
JNIEXPORT void JNICALL Java_TestClass1_mbn
(JNIEnv *, jobject, jbyte);
/*
* Class: TestClass1
* Method: msn
* Signature: (S)V
*/
JNIEXPORT void JNICALL Java_TestClass1_msn
(JNIEnv *, jobject, jshort);
/*
* Class: TestClass1
* Method: min
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_TestClass1_min
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1
* Method: mln
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_TestClass1_mln
(JNIEnv *, jobject, jlong);
/*
* Class: TestClass1
* Method: mfn
* Signature: (F)V
*/
JNIEXPORT void JNICALL Java_TestClass1_mfn
(JNIEnv *, jobject, jfloat);
/*
* Class: TestClass1
* Method: mdn
* Signature: (D)V
*/
JNIEXPORT void JNICALL Java_TestClass1_mdn
(JNIEnv *, jobject, jdouble);
/*
* Class: TestClass1
* Method: mon
* Signature: (Ljava/lang/Object;)V
*/
JNIEXPORT void JNICALL Java_TestClass1_mon
(JNIEnv *, jobject, jobject);
/*
* Class: TestClass1
* Method: mtn
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_TestClass1_mtn
(JNIEnv *, jobject, jstring);
/*
* Class: TestClass1
* Method: mgn
* Signature: (Ljava/util/List;)V
*/
JNIEXPORT void JNICALL Java_TestClass1_mgn
(JNIEnv *, jobject, jobject);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,337 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TestClass1_Inner1 */
#ifndef _Included_TestClass1_Inner1
#define _Included_TestClass1_Inner1
#ifdef __cplusplus
extern "C" {
#endif
#undef TestClass1_Inner1_bc
#define TestClass1_Inner1_bc 0L
#undef TestClass1_Inner1_sc
#define TestClass1_Inner1_sc 0L
#undef TestClass1_Inner1_ic
#define TestClass1_Inner1_ic 0L
#undef TestClass1_Inner1_lc
#define TestClass1_Inner1_lc 0LL
#undef TestClass1_Inner1_fc
#define TestClass1_Inner1_fc 0.0f
#undef TestClass1_Inner1_dc
#define TestClass1_Inner1_dc 0.0
/*
* Class: TestClass1_Inner1
* Method: bmn
* Signature: ()B
*/
JNIEXPORT jbyte JNICALL Java_TestClass1_00024Inner1_bmn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: smn
* Signature: ()S
*/
JNIEXPORT jshort JNICALL Java_TestClass1_00024Inner1_smn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: imn
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_TestClass1_00024Inner1_imn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: lmn
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_TestClass1_00024Inner1_lmn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: fmn
* Signature: ()F
*/
JNIEXPORT jfloat JNICALL Java_TestClass1_00024Inner1_fmn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: dmn
* Signature: ()D
*/
JNIEXPORT jdouble JNICALL Java_TestClass1_00024Inner1_dmn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: omn
* Signature: ()Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_TestClass1_00024Inner1_omn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: tmn
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_TestClass1_00024Inner1_tmn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: gmn
* Signature: ()Ljava/util/List;
*/
JNIEXPORT jobject JNICALL Java_TestClass1_00024Inner1_gmn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: vmn
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner1_vmn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: bmn1
* Signature: ()B
*/
JNIEXPORT jbyte JNICALL Java_TestClass1_00024Inner1_bmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: smn1
* Signature: ()S
*/
JNIEXPORT jshort JNICALL Java_TestClass1_00024Inner1_smn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: imn1
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_TestClass1_00024Inner1_imn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: lmn1
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_TestClass1_00024Inner1_lmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: fmn1
* Signature: ()F
*/
JNIEXPORT jfloat JNICALL Java_TestClass1_00024Inner1_fmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: dmn1
* Signature: ()D
*/
JNIEXPORT jdouble JNICALL Java_TestClass1_00024Inner1_dmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: omn1
* Signature: ()Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_TestClass1_00024Inner1_omn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: tmn1
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_TestClass1_00024Inner1_tmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: gmn1
* Signature: ()Ljava/util/List;
*/
JNIEXPORT jobject JNICALL Java_TestClass1_00024Inner1_gmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: vmn1
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner1_vmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner1
* Method: bmn2
* Signature: (I)B
*/
JNIEXPORT jbyte JNICALL Java_TestClass1_00024Inner1_bmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner1
* Method: smn2
* Signature: (I)S
*/
JNIEXPORT jshort JNICALL Java_TestClass1_00024Inner1_smn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner1
* Method: imn2
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_TestClass1_00024Inner1_imn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner1
* Method: lmn2
* Signature: (I)J
*/
JNIEXPORT jlong JNICALL Java_TestClass1_00024Inner1_lmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner1
* Method: fmn2
* Signature: (I)F
*/
JNIEXPORT jfloat JNICALL Java_TestClass1_00024Inner1_fmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner1
* Method: dmn2
* Signature: (I)D
*/
JNIEXPORT jdouble JNICALL Java_TestClass1_00024Inner1_dmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner1
* Method: omn2
* Signature: (I)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_TestClass1_00024Inner1_omn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner1
* Method: tmn2
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_TestClass1_00024Inner1_tmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner1
* Method: gmn2
* Signature: (I)Ljava/util/List;
*/
JNIEXPORT jobject JNICALL Java_TestClass1_00024Inner1_gmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner1
* Method: vmn2
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner1_vmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner1
* Method: mbn
* Signature: (B)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner1_mbn
(JNIEnv *, jobject, jbyte);
/*
* Class: TestClass1_Inner1
* Method: msn
* Signature: (S)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner1_msn
(JNIEnv *, jobject, jshort);
/*
* Class: TestClass1_Inner1
* Method: min
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner1_min
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner1
* Method: mln
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner1_mln
(JNIEnv *, jobject, jlong);
/*
* Class: TestClass1_Inner1
* Method: mfn
* Signature: (F)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner1_mfn
(JNIEnv *, jobject, jfloat);
/*
* Class: TestClass1_Inner1
* Method: mdn
* Signature: (D)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner1_mdn
(JNIEnv *, jobject, jdouble);
/*
* Class: TestClass1_Inner1
* Method: mon
* Signature: (Ljava/lang/Object;)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner1_mon
(JNIEnv *, jobject, jobject);
/*
* Class: TestClass1_Inner1
* Method: mtn
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner1_mtn
(JNIEnv *, jobject, jstring);
/*
* Class: TestClass1_Inner1
* Method: mgn
* Signature: (Ljava/util/List;)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner1_mgn
(JNIEnv *, jobject, jobject);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,337 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TestClass1_Inner2 */
#ifndef _Included_TestClass1_Inner2
#define _Included_TestClass1_Inner2
#ifdef __cplusplus
extern "C" {
#endif
#undef TestClass1_Inner2_bc
#define TestClass1_Inner2_bc 0L
#undef TestClass1_Inner2_sc
#define TestClass1_Inner2_sc 0L
#undef TestClass1_Inner2_ic
#define TestClass1_Inner2_ic 0L
#undef TestClass1_Inner2_lc
#define TestClass1_Inner2_lc 0LL
#undef TestClass1_Inner2_fc
#define TestClass1_Inner2_fc 0.0f
#undef TestClass1_Inner2_dc
#define TestClass1_Inner2_dc 0.0
/*
* Class: TestClass1_Inner2
* Method: bmn
* Signature: ()B
*/
JNIEXPORT jbyte JNICALL Java_TestClass1_00024Inner2_bmn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: smn
* Signature: ()S
*/
JNIEXPORT jshort JNICALL Java_TestClass1_00024Inner2_smn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: imn
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_TestClass1_00024Inner2_imn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: lmn
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_TestClass1_00024Inner2_lmn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: fmn
* Signature: ()F
*/
JNIEXPORT jfloat JNICALL Java_TestClass1_00024Inner2_fmn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: dmn
* Signature: ()D
*/
JNIEXPORT jdouble JNICALL Java_TestClass1_00024Inner2_dmn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: omn
* Signature: ()Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_TestClass1_00024Inner2_omn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: tmn
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_TestClass1_00024Inner2_tmn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: gmn
* Signature: ()Ljava/util/List;
*/
JNIEXPORT jobject JNICALL Java_TestClass1_00024Inner2_gmn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: vmn
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner2_vmn
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: bmn1
* Signature: ()B
*/
JNIEXPORT jbyte JNICALL Java_TestClass1_00024Inner2_bmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: smn1
* Signature: ()S
*/
JNIEXPORT jshort JNICALL Java_TestClass1_00024Inner2_smn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: imn1
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_TestClass1_00024Inner2_imn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: lmn1
* Signature: ()J
*/
JNIEXPORT jlong JNICALL Java_TestClass1_00024Inner2_lmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: fmn1
* Signature: ()F
*/
JNIEXPORT jfloat JNICALL Java_TestClass1_00024Inner2_fmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: dmn1
* Signature: ()D
*/
JNIEXPORT jdouble JNICALL Java_TestClass1_00024Inner2_dmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: omn1
* Signature: ()Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_TestClass1_00024Inner2_omn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: tmn1
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_TestClass1_00024Inner2_tmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: gmn1
* Signature: ()Ljava/util/List;
*/
JNIEXPORT jobject JNICALL Java_TestClass1_00024Inner2_gmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: vmn1
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner2_vmn1
(JNIEnv *, jobject);
/*
* Class: TestClass1_Inner2
* Method: bmn2
* Signature: (I)B
*/
JNIEXPORT jbyte JNICALL Java_TestClass1_00024Inner2_bmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner2
* Method: smn2
* Signature: (I)S
*/
JNIEXPORT jshort JNICALL Java_TestClass1_00024Inner2_smn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner2
* Method: imn2
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_TestClass1_00024Inner2_imn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner2
* Method: lmn2
* Signature: (I)J
*/
JNIEXPORT jlong JNICALL Java_TestClass1_00024Inner2_lmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner2
* Method: fmn2
* Signature: (I)F
*/
JNIEXPORT jfloat JNICALL Java_TestClass1_00024Inner2_fmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner2
* Method: dmn2
* Signature: (I)D
*/
JNIEXPORT jdouble JNICALL Java_TestClass1_00024Inner2_dmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner2
* Method: omn2
* Signature: (I)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_TestClass1_00024Inner2_omn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner2
* Method: tmn2
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_TestClass1_00024Inner2_tmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner2
* Method: gmn2
* Signature: (I)Ljava/util/List;
*/
JNIEXPORT jobject JNICALL Java_TestClass1_00024Inner2_gmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner2
* Method: vmn2
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner2_vmn2
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner2
* Method: mbn
* Signature: (B)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner2_mbn
(JNIEnv *, jobject, jbyte);
/*
* Class: TestClass1_Inner2
* Method: msn
* Signature: (S)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner2_msn
(JNIEnv *, jobject, jshort);
/*
* Class: TestClass1_Inner2
* Method: min
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner2_min
(JNIEnv *, jobject, jint);
/*
* Class: TestClass1_Inner2
* Method: mln
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner2_mln
(JNIEnv *, jobject, jlong);
/*
* Class: TestClass1_Inner2
* Method: mfn
* Signature: (F)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner2_mfn
(JNIEnv *, jobject, jfloat);
/*
* Class: TestClass1_Inner2
* Method: mdn
* Signature: (D)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner2_mdn
(JNIEnv *, jobject, jdouble);
/*
* Class: TestClass1_Inner2
* Method: mon
* Signature: (Ljava/lang/Object;)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner2_mon
(JNIEnv *, jobject, jobject);
/*
* Class: TestClass1_Inner2
* Method: mtn
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner2_mtn
(JNIEnv *, jobject, jstring);
/*
* Class: TestClass1_Inner2
* Method: mgn
* Signature: (Ljava/util/List;)V
*/
JNIEXPORT void JNICALL Java_TestClass1_00024Inner2_mgn
(JNIEnv *, jobject, jobject);
#ifdef __cplusplus
}
#endif
#endif

@ -0,0 +1,13 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TestClass2 */
#ifndef _Included_TestClass2
#define _Included_TestClass2
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,79 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TestClass3 */
#ifndef _Included_TestClass3
#define _Included_TestClass3
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif
/* Header for class TestClass3_Inner2 */
#ifndef _Included_TestClass3_Inner2
#define _Included_TestClass3_Inner2
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif
/* Header for class TestClass3_Inner2_Inner2B */
#ifndef _Included_TestClass3_Inner2_Inner2B
#define _Included_TestClass3_Inner2_Inner2B
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif
/* Header for class TestClass3_Inner2_Inner2A */
#ifndef _Included_TestClass3_Inner2_Inner2A
#define _Included_TestClass3_Inner2_Inner2A
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif
/* Header for class TestClass3_Inner1 */
#ifndef _Included_TestClass3_Inner1
#define _Included_TestClass3_Inner1
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif
/* Header for class TestClass3_Inner1_Inner1B */
#ifndef _Included_TestClass3_Inner1_Inner1B
#define _Included_TestClass3_Inner1_Inner1B
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif
/* Header for class TestClass3_Inner1_Inner1A */
#ifndef _Included_TestClass3_Inner1_Inner1A
#define _Included_TestClass3_Inner1_Inner1A
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif

@ -77,10 +77,7 @@ GENERATED_HEADER_FILE=ParamClassTest.h
rm -f ParamClassTest.class MissingParamClassException.class ParamClassTest.h
rm -f ${TMP1}
cp ${TESTSRC}${FS}ParamClassTest.java .
cp ${TESTSRC}${FS}MissingParamClassException.java .
"${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d . "${TESTSRC}${FS}ParamClassTest.java"
"${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d . "${TESTSRC}${FS}ParamClassTest.java" "${TESTSRC}${FS}MissingParamClassException.java"
# Before running javah remove dependent class file
rm -f MissingParamClassException.class
@ -88,15 +85,12 @@ rm -f MissingParamClassException.class
"${TESTJAVA}${FS}bin${FS}javah" ${TESTTOOLVMOPTS} ParamClassTest 2>${TMP1}
if [ -f $GENERATED_HEADER_FILE ]; then
echo "Failed"
exit 1
echo "1-- Failed: $GENERATED_HEADER_FILE found"
rc=1
fi
if [ ! -f ${TMP1} ]; then
echo "Failed"
exit 1
else
echo "Passed"
exit 0
if [ ! -s ${TMP1} ]; then
echo "1-- Failed: ${TMP1} is empty"
rc=1
fi
# Clean out work dir
@ -104,7 +98,9 @@ rm -f MissingParamClassException.class ParamClassTest.class
rm -f $GENERATED_HEADER_FILE $TMP1
# Re-compile everything
"${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d . ${TESTSRC}${FS}ParamClassTest.java
"${TESTJAVA}${FS}bin${FS}javac" ${TESTTOOLVMOPTS} -d . "${TESTSRC}${FS}ParamClassTest.java" "${TESTSRC}${FS}MissingParamClassException.java"
# Before re-run of javah remove dependent class file Param.class
rm -f Param.class
@ -112,13 +108,17 @@ rm -f Param.class
"${TESTJAVA}${FS}bin${FS}javah" ${TESTTOOLVMOPTS} ParamClassTest 2>${TMP1}
if [ -f $GENERATED_HEADER_FILE ]; then
echo "Failed"
exit 1
echo "2-- Failed: $GENERATED_HEADER_FILE found"
rc=1
fi
if [ ! -f ${TMP1} ]; then
echo "Failed"
exit 1
if [ ! -s ${TMP1} ]; then
echo "2-- Failed: ${TMP1} is empty"
rc=1
fi
if [ "$rc" = "" ]; then
echo Passed
else
echo "Passed"
exit 0
echo Failed
exit 1
fi

@ -0,0 +1,265 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import com.sun.tools.classfile.AccessFlags;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Method;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.LinkedHashSet;
public class CompareTest {
String[][] testCases = {
{ },
{ "-jni" },
// { "-llni" },
};
public static void main(String... args) throws Exception {
new CompareTest().run(args);
}
public void run(String... args) throws Exception {
old_javah_cmd = new File(args[0]);
rt_jar = new File(args[1]);
Set<String> testClasses;
if (args.length > 2) {
testClasses = new LinkedHashSet<String>(Arrays.asList(Arrays.copyOfRange(args, 2, args.length)));
} else
testClasses = getNativeClasses(new JarFile(rt_jar));
for (String[] options: testCases) {
for (String name: testClasses) {
test(Arrays.asList(options), rt_jar, name);
}
}
if (errors == 0)
System.out.println(count + " tests passed");
else
throw new Exception(errors + "/" + count + " tests failed");
}
public void test(List<String> options, File bootclasspath, String className)
throws IOException, InterruptedException {
System.err.println("test: " + options + " " + className);
count++;
testOptions = options;
testClassName = className;
File oldOutDir = initDir(file(new File("old"), className));
int old_rc = old_javah(options, oldOutDir, bootclasspath, className);
File newOutDir = initDir(file(new File("new"), className));
int new_rc = new_javah(options, newOutDir, bootclasspath, className);
if (old_rc != new_rc)
error("return codes differ; old: " + old_rc + ", new: " + new_rc);
compare(oldOutDir, newOutDir);
}
int old_javah(List<String> options, File outDir, File bootclasspath, String className)
throws IOException, InterruptedException {
List<String> cmd = new ArrayList<String>();
cmd.add(old_javah_cmd.getPath());
cmd.addAll(options);
cmd.add("-d");
cmd.add(outDir.getPath());
cmd.add("-bootclasspath");
cmd.add(bootclasspath.getPath());
cmd.add(className);
System.err.println("old_javah: " + cmd);
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
Process p = pb.start();
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
StringBuilder sb = new StringBuilder();
while ((line = in.readLine()) != null) {
sb.append(line);
sb.append("\n");
}
System.err.println("old javah out: " + sb.toString());
return p.waitFor();
}
int new_javah(List<String> options, File outDir, File bootclasspath, String className) {
List<String> args = new ArrayList<String>();
args.addAll(options);
args.add("-d");
args.add(outDir.getPath());
args.add("-bootclasspath");
args.add(bootclasspath.getPath());
args.add(className);
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
int rc = com.sun.tools.javah.Main.run(args.toArray(new String[args.size()]), pw);
pw.close();
System.err.println("new javah out: " + sw.toString());
return rc;
}
Set<String> getNativeClasses(JarFile jar) throws IOException, ConstantPoolException {
System.err.println("getNativeClasses: " + jar.getName());
Set<String> results = new TreeSet<String>();
Enumeration<JarEntry> e = jar.entries();
while (e.hasMoreElements()) {
JarEntry je = e.nextElement();
if (isNativeClass(jar, je)) {
String name = je.getName();
results.add(name.substring(0, name.length() - 6).replace("/", "."));
}
}
return results;
}
boolean isNativeClass(JarFile jar, JarEntry entry) throws IOException, ConstantPoolException {
String name = entry.getName();
if (name.startsWith("META-INF") || !name.endsWith(".class"))
return false;
//String className = name.substring(0, name.length() - 6).replace("/", ".");
//System.err.println("check " + className);
InputStream in = jar.getInputStream(entry);
ClassFile cf = ClassFile.read(in);
for (int i = 0; i < cf.methods.length; i++) {
Method m = cf.methods[i];
if (m.access_flags.is(AccessFlags.ACC_NATIVE)) {
// System.err.println(className);
return true;
}
}
return false;
}
void compare(File f1, File f2) throws IOException {
if (f1.isFile() && f2.isFile())
compareFiles(f1, f2);
else if (f1.isDirectory() && f2.isDirectory())
compareDirectories(f1, f2);
else
error("files differ: "
+ f1 + " (" + getFileType(f1) + "), "
+ f2 + " (" + getFileType(f2) + ")");
}
void compareDirectories(File d1, File d2) throws IOException {
Set<String> list = new TreeSet<String>();
list.addAll(Arrays.asList(d1.list()));
list.addAll(Arrays.asList(d2.list()));
for (String c: list)
compare(new File(d1, c), new File(d2, c));
}
void compareFiles(File f1, File f2) throws IOException {
byte[] c1 = readFile(f1);
byte[] c2 = readFile(f2);
if (!Arrays.equals(c1, c2))
error("files differ: " + f1 + ", " + f2);
}
byte[] readFile(File file) throws IOException {
int size = (int) file.length();
byte[] data = new byte[size];
DataInputStream in = new DataInputStream(new FileInputStream(file));
try {
in.readFully(data);
} finally {
in.close();
}
return data;
}
String getFileType(File f) {
return f.isDirectory() ? "directory"
: f.isFile() ? "file"
: f.exists() ? "other"
: "not found";
}
/**
* Set up an empty directory.
*/
public File initDir(File dir) {
if (dir.exists())
deleteAll(dir);
dir.mkdirs();
return dir;
}
/**
* Delete a file or a directory (including all its contents).
*/
boolean deleteAll(File file) {
if (file.isDirectory()) {
for (File f: file.listFiles())
deleteAll(f);
}
return file.delete();
}
File file(File dir, String... path) {
File f = dir;
for (String p: path)
f = new File(f, p);
return f;
}
/**
* Report an error.
*/
void error(String msg, String... more) {
System.err.println("test: " + testOptions + " " + testClassName);
System.err.println("error: " + msg);
for (String s: more)
System.err.println(s);
errors++;
System.exit(1);
}
File old_javah_cmd;
File rt_jar;
List<String> testOptions;
String testClassName;
int count;
int errors;
}

@ -1,12 +1,11 @@
#!/bin/sh
#
# Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
# Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Sun designates this
# particular file as subject to the "Classpath" exception as provided
# by Sun in the LICENSE file that accompanied this code.
# published by the Free Software Foundation.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@ -21,7 +20,24 @@
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
#
jdk=${1:-/opt/jdk/1.6.0}
javah=${jdk}/bin/javah
rtjar=${jdk}/jre/lib/rt.jar
# compile test
mkdir -p build/compareTest
/opt/jdk/1.7.0/bin/javac -classpath build/classes -d build/compareTest test/tools/javah/compareTest/*.java
# run test
/opt/jdk/1.7.0/bin/java -classpath build/compareTest:build/classes CompareTest $javah $rtjar 2>&1 | tee CompareTest.out
# show diffs for tests that failed
grep 'error:' CompareTest.out | sed -e 's|.*new/||' -e 's/\.h$//' -e 's|_|.|g' > CompareTest.classes.fail
for i in $(cat CompareTest.classes.fail) ; do
/opt/jdk/1.7.0/bin/java -classpath compareTest:build/classes CompareTest $javah $rtjar $i
diff -r old new
done
pack.pragma.start=\#pragma pack(4)\n
pack.pragma.end=\#pragma pack()\n

@ -0,0 +1,86 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import com.sun.tools.classfile.AccessFlags;
import com.sun.tools.classfile.ClassFile;
import com.sun.tools.classfile.ConstantPoolException;
import com.sun.tools.classfile.Method;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
public class FindNativeFiles {
public static void main(String[] args) throws IOException, ConstantPoolException {
new FindNativeFiles().run(args);
}
public void run(String[] args) throws IOException, ConstantPoolException {
JarFile jar = new JarFile(args[0]);
Set<JarEntry> entries = getNativeClasses(jar);
for (JarEntry e: entries) {
String name = e.getName();
String className = name.substring(0, name.length() - 6).replace("/", ".");
System.out.println(className);
}
}
Set<JarEntry> getNativeClasses(JarFile jar) throws IOException, ConstantPoolException {
Set<JarEntry> results = new TreeSet<JarEntry>(new Comparator<JarEntry>() {
public int compare(JarEntry o1, JarEntry o2) {
return o1.getName().compareTo(o2.getName());
}
});
Enumeration<JarEntry> e = jar.entries();
while (e.hasMoreElements()) {
JarEntry je = e.nextElement();
if (isNativeClass(jar, je))
results.add(je);
}
return results;
}
boolean isNativeClass(JarFile jar, JarEntry entry) throws IOException, ConstantPoolException {
String name = entry.getName();
if (name.startsWith("META-INF") || !name.endsWith(".class"))
return false;
//String className = name.substring(0, name.length() - 6).replace("/", ".");
//System.err.println("check " + className);
InputStream in = jar.getInputStream(entry);
ClassFile cf = ClassFile.read(in);
in.close();
for (int i = 0; i < cf.methods.length; i++) {
Method m = cf.methods[i];
if (m.access_flags.is(AccessFlags.ACC_NATIVE)) {
// System.err.println(className);
return true;
}
}
return false;
}
}

@ -0,0 +1,16 @@
test/tools/javah/compareTest/README
This directory contains a program for comparing the output of new javah against the
output of JDK 6 or other older versions of javah.
It cannot be run automatically because of the need for the older version of javah
to compare against.
The test works by scanning a jar file, such as rt.jar, looking for all files with
native methods. It then runs both the old and new versions of javah on those
classes with native methods, and verifies that the results are character-for-character
identical.
To run the test, build langtools, then execute the script in the root langtools
directory, providing the location of the JDK to be tested. The default is
/opt/jdk/1.6.0.