diff --git a/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationProxyMaker.java b/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationProxyMaker.java index 6dae6cd7d817da765a74980bc95b5b688604a7dd..63f1de2483ea62419e23eaa6326f2c909829c59a 100644 --- a/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationProxyMaker.java +++ b/src/share/classes/com/sun/tools/apt/mirror/declaration/AnnotationProxyMaker.java @@ -250,9 +250,13 @@ class AnnotationProxyMaker { /** * Sets "value" to an ExceptionProxy indicating a type mismatch. */ - private void typeMismatch(final Method method, final Attribute attr) { - value = new ExceptionProxy() { + private void typeMismatch(Method method, final Attribute attr) { + class AnnotationTypeMismatchExceptionProxy extends ExceptionProxy { private static final long serialVersionUID = 8473323277815075163L; + transient final Method method; + AnnotationTypeMismatchExceptionProxy(Method method) { + this.method = method; + } public String toString() { return ""; // eg: @Anno(value=) } @@ -260,7 +264,8 @@ class AnnotationProxyMaker { return new AnnotationTypeMismatchException(method, attr.type.toString()); } - }; + } + value = new AnnotationTypeMismatchExceptionProxy(method); } } diff --git a/src/share/classes/com/sun/tools/javac/comp/Infer.java b/src/share/classes/com/sun/tools/javac/comp/Infer.java index b7d28fdaa6f45f47a1c99d3423bcba9e4395a0b7..0e60e5e7fd9718c5cbcfc439ecb16dd41da02b17 100644 --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java @@ -553,12 +553,24 @@ public class Infer { //the enclosing tree E, as follows: if E is a cast, then use the //target type of the cast expression as a return type; if E is an //expression statement, the return type is 'void' - otherwise the - //return type is simply 'Object'. - switch (env.outer.tree.getTag()) { + //return type is simply 'Object'. A correctness check ensures that + //env.next refers to the lexically enclosing environment in which + //the polymorphic signature call environment is nested. + + switch (env.next.tree.getTag()) { case JCTree.TYPECAST: - restype = ((JCTypeCast)env.outer.tree).clazz.type; break; + JCTypeCast castTree = (JCTypeCast)env.next.tree; + restype = (castTree.expr == env.tree) ? + castTree.clazz.type : + syms.objectType; + break; case JCTree.EXEC: - restype = syms.voidType; break; + JCTree.JCExpressionStatement execTree = + (JCTree.JCExpressionStatement)env.next.tree; + restype = (execTree.expr == env.tree) ? + syms.voidType : + syms.objectType; + break; default: restype = syms.objectType; } diff --git a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java index 73fe36cbf7d9794c4b6f63835ad6252966981ff9..340bd42d7844aa32405b412d2151a6f55879fbf9 100644 --- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java +++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java @@ -668,9 +668,9 @@ public class MemberEnter extends JCTree.Visitor implements Completer { public void visitTree(JCTree tree) { } - public void visitErroneous(JCErroneous tree) { - memberEnter(tree.errs, env); + if (tree.errs != null) + memberEnter(tree.errs, env); } public Env getMethodEnv(JCMethodDecl tree, Env env) { diff --git a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java index 7e1996a45d93cc06898cdf022b00897b06575dba..e439e8ed9a9339566b041c1d08a4a2b9c29fc240 100644 --- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java +++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java @@ -511,7 +511,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter { protected boolean shouldStop(CompileState cs) { if (shouldStopPolicy == null) - return (errorCount() > 0); + return (errorCount() > 0 || unrecoverableError()); else return cs.ordinal() > shouldStopPolicy.ordinal(); } diff --git a/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java b/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java index b26f031c2ee15249fafd05f5f0e1230fb87ec6dd..655fbc83ef50bcb20601cabe5ee7385c59666d63 100644 --- a/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java +++ b/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java @@ -250,9 +250,13 @@ public class AnnotationProxyMaker { /** * Sets "value" to an ExceptionProxy indicating a type mismatch. */ - private void typeMismatch(final Method method, final Attribute attr) { - value = new ExceptionProxy() { + private void typeMismatch(Method method, final Attribute attr) { + class AnnotationTypeMismatchExceptionProxy extends ExceptionProxy { static final long serialVersionUID = 269; + transient final Method method; + AnnotationTypeMismatchExceptionProxy(Method method) { + this.method = method; + } public String toString() { return ""; // eg: @Anno(value=) } @@ -260,7 +264,8 @@ public class AnnotationProxyMaker { return new AnnotationTypeMismatchException(method, attr.type.toString()); } - }; + } + value = new AnnotationTypeMismatchExceptionProxy(method); } } diff --git a/src/share/classes/com/sun/tools/javac/model/JavacElements.java b/src/share/classes/com/sun/tools/javac/model/JavacElements.java index e56681a4e4ed73197ea1fadabfba56002a02afdd..62bd0b16e1795ded6d7c09ad305697f0e3825456 100644 --- a/src/share/classes/com/sun/tools/javac/model/JavacElements.java +++ b/src/share/classes/com/sun/tools/javac/model/JavacElements.java @@ -66,32 +66,26 @@ public class JavacElements implements Elements { private Types types; private Enter enter; - private static final Context.Key KEY = - new Context.Key(); - public static JavacElements instance(Context context) { - JavacElements instance = context.get(KEY); - if (instance == null) { + JavacElements instance = context.get(JavacElements.class); + if (instance == null) instance = new JavacElements(context); - context.put(KEY, instance); - } return instance; } /** * Public for use only by JavacProcessingEnvironment */ - // TODO JavacElements constructor should be protected - public JavacElements(Context context) { + protected JavacElements(Context context) { setContext(context); } /** * Use a new context. May be called from outside to update * internal state for a new annotation-processing round. - * This instance is *not* then registered with the new context. */ public void setContext(Context context) { + context.put(JavacElements.class, this); javaCompiler = JavaCompiler.instance(context); syms = Symtab.instance(context); names = Names.instance(context); diff --git a/src/share/classes/com/sun/tools/javac/model/JavacTypes.java b/src/share/classes/com/sun/tools/javac/model/JavacTypes.java index 7499c2d79eeaa118a5d76d4c3dd7e33e1f733feb..5ca201b512980ad912905cfce9ac4d52f517d8f4 100644 --- a/src/share/classes/com/sun/tools/javac/model/JavacTypes.java +++ b/src/share/classes/com/sun/tools/javac/model/JavacTypes.java @@ -47,32 +47,26 @@ public class JavacTypes implements javax.lang.model.util.Types { private Symtab syms; private Types types; - private static final Context.Key KEY = - new Context.Key(); - public static JavacTypes instance(Context context) { - JavacTypes instance = context.get(KEY); - if (instance == null) { + JavacTypes instance = context.get(JavacTypes.class); + if (instance == null) instance = new JavacTypes(context); - context.put(KEY, instance); - } return instance; } /** * Public for use only by JavacProcessingEnvironment */ - // TODO JavacTypes constructor should be protected - public JavacTypes(Context context) { + protected JavacTypes(Context context) { setContext(context); } /** * Use a new context. May be called from outside to update * internal state for a new annotation-processing round. - * This instance is *not* then registered with the new context. */ public void setContext(Context context) { + context.put(JavacTypes.class, this); syms = Symtab.instance(context); types = Types.instance(context); } diff --git a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java index 49ca742a5803a05afa81cfee79c852c6329edd6d..7b7f362413b4dfe23eb2a24916562698a425beda 100644 --- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java +++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java @@ -173,12 +173,12 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea platformAnnotations = initPlatformAnnotations(); foundTypeProcessors = false; - // Initialize services before any processors are initialzied + // Initialize services before any processors are initialized // in case processors use them. filer = new JavacFiler(context); messager = new JavacMessager(context, this); - elementUtils = new JavacElements(context); - typeUtils = new JavacTypes(context); + elementUtils = JavacElements.instance(context); + typeUtils = JavacTypes.instance(context); processorOptions = initProcessorOptions(context); unmatchedProcessorOptions = initUnmatchedProcessorOptions(); messages = JavacMessages.instance(context); @@ -865,8 +865,6 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea this(prev.nextContext(), prev.number+1, prev.compiler.log.nwarnings); this.genClassFiles = prev.genClassFiles; - updateProcessingState(); - List parsedFiles = compiler.parseFiles(newSourceFiles); roots = cleanTrees(prev.roots).appendList(parsedFiles); @@ -1029,15 +1027,6 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea log.reportDeferredDiagnostics(kinds); } - /** Update the processing state for the current context. */ - private void updateProcessingState() { - filer.newRound(context); - messager.newRound(context); - - elementUtils.setContext(context); - typeUtils.setContext(context); - } - /** Print info about this round. */ private void printRoundInfo(boolean lastRound) { if (printRounds || verbose) { @@ -1100,6 +1089,11 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea JavaCompiler nextCompiler = JavaCompiler.instance(next); nextCompiler.initRound(oldCompiler); + filer.newRound(next); + messager.newRound(next); + elementUtils.setContext(next); + typeUtils.setContext(next); + JavacTaskImpl task = context.get(JavacTaskImpl.class); if (task != null) { next.put(JavacTaskImpl.class, task); diff --git a/src/share/classes/com/sun/tools/javah/JNI.java b/src/share/classes/com/sun/tools/javah/JNI.java index f71d4d0283093908f02495d6e00eab3bb3e74e72..91a444eaae9507feb44231541ad05e73a7121a94 100644 --- a/src/share/classes/com/sun/tools/javah/JNI.java +++ b/src/share/classes/com/sun/tools/javah/JNI.java @@ -59,72 +59,76 @@ public class JNI extends Gen { } 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. */ - List classfields = getAllFields(clazz); - - for (VariableElement v: classfields) { - if (!v.getModifiers().contains(Modifier.STATIC)) - continue; - String s = null; - s = defineForStatic(clazz, v); - if (s != null) { - pw.println(s); - } - } - - /* Write methods. */ - List 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 (ExecutableElement md2: classmethods) { - if ((md2 != md) - && (methodName.equals(md2.getSimpleName())) - && (md2.getModifiers().contains(Modifier.NATIVE))) - longName = true; - + try { + String cname = mangler.mangle(clazz.getQualifiedName(), Mangle.Type.CLASS); + PrintWriter pw = wrapWriter(o); + pw.println(guardBegin(cname)); + pw.println(cppGuardBegin()); + + /* Write statics. */ + List classfields = getAllFields(clazz); + + for (VariableElement v: classfields) { + if (!v.getModifiers().contains(Modifier.STATIC)) + continue; + String s = null; + s = defineForStatic(clazz, v); + if (s != null) { + pw.println(s); } - pw.println("/*"); - pw.println(" * Class: " + cname); - pw.println(" * Method: " + - mangler.mangle(methodName, Mangle.Type.FIELDSTUB)); - pw.println(" * Signature: " + newtypesig.getTypeSignature(sig, mtr)); - pw.println(" */"); - pw.println("JNIEXPORT " + jniType(mtr) + - " JNICALL " + - mangler.mangleMethod(md, clazz, - (longName) ? - Mangle.Type.METHOD_JNI_LONG : - Mangle.Type.METHOD_JNI_SHORT)); - pw.print(" (JNIEnv *, "); - List paramargs = md.getParameters(); - List args = new ArrayList(); - for (VariableElement p: paramargs) { - args.add(types.erasure(p.asType())); - } - if (md.getModifiers().contains(Modifier.STATIC)) - pw.print("jclass"); - else - pw.print("jobject"); + } - for (TypeMirror arg: args) { - pw.print(", "); - pw.print(jniType(arg)); + /* Write methods. */ + List 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 (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: " + + mangler.mangle(methodName, Mangle.Type.FIELDSTUB)); + pw.println(" * Signature: " + newtypesig.getTypeSignature(sig, mtr)); + pw.println(" */"); + pw.println("JNIEXPORT " + jniType(mtr) + + " JNICALL " + + mangler.mangleMethod(md, clazz, + (longName) ? + Mangle.Type.METHOD_JNI_LONG : + Mangle.Type.METHOD_JNI_SHORT)); + pw.print(" (JNIEnv *, "); + List paramargs = md.getParameters(); + List args = new ArrayList(); + for (VariableElement p: paramargs) { + args.add(types.erasure(p.asType())); + } + if (md.getModifiers().contains(Modifier.STATIC)) + pw.print("jclass"); + else + pw.print("jobject"); + + for (TypeMirror arg: args) { + pw.print(", "); + pw.print(jniType(arg)); + } + pw.println(");" + lineSep); } - pw.println(");" + lineSep); } + pw.println(cppGuardEnd()); + pw.println(guardEnd(cname)); + } catch (TypeSignature.SignatureException e) { + util.error("jni.sigerror", e.getMessage()); } - pw.println(cppGuardEnd()); - pw.println(guardEnd(cname)); } diff --git a/src/share/classes/com/sun/tools/javah/JavahTask.java b/src/share/classes/com/sun/tools/javah/JavahTask.java index 0e885815dc2bafed51fc9a9f6e3824d0817e37e7..51c290d027ae119c6281c4e65809ab0ea05c975f 100644 --- a/src/share/classes/com/sun/tools/javah/JavahTask.java +++ b/src/share/classes/com/sun/tools/javah/JavahTask.java @@ -46,9 +46,9 @@ import java.util.Set; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.Messager; +import javax.annotation.processing.ProcessingEnvironment; 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; @@ -71,6 +71,9 @@ import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.StandardLocation; import javax.tools.ToolProvider; +import static javax.tools.Diagnostic.Kind.*; + +import com.sun.tools.javac.code.Symbol.CompletionFailure; /** * Javah generates support files for native methods. @@ -173,7 +176,7 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask { } }, - new Option(false, "-help", "--help", "-?") { + new Option(false, "-h", "-help", "--help", "-?") { void process(JavahTask task, String opt, String arg) { task.help = true; } @@ -233,6 +236,15 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask { task.doubleAlign = true; } }, + + new HiddenOption(false) { + boolean matches(String opt) { + return opt.startsWith("-XD"); + } + void process(JavahTask task, String opt, String arg) { + task.javac_extras.add(opt); + } + }, }; JavahTask() { @@ -326,6 +338,8 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask { } catch (InternalError e) { diagnosticListener.report(createDiagnostic("err.internal.error", e.getMessage())); return 1; + } catch (Util.Exit e) { + return e.exitValue; } finally { log.flush(); } @@ -475,7 +489,9 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask { ((JavahFileManager) fileManager).setIgnoreSymbolFile(true); JavaCompiler c = ToolProvider.getSystemJavaCompiler(); - List opts = Arrays.asList("-proc:only"); + List opts = new ArrayList(); + opts.add("-proc:only"); + opts.addAll(javac_extras); CompilationTask t = c.getTask(log, fileManager, diagnosticListener, opts, internalize(classes), null); JavahProcessor p = new JavahProcessor(g); t.setProcessors(Collections.singleton(p)); @@ -642,6 +658,7 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask { boolean doubleAlign; boolean force; boolean old; + Set javac_extras = new LinkedHashSet(); PrintWriter log; JavaFileManager fileManager; @@ -652,30 +669,45 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask { private static final String progname = "javah"; @SupportedAnnotationTypes("*") - @SupportedSourceVersion(SourceVersion.RELEASE_7) class JavahProcessor extends AbstractProcessor { + private Messager messager; + JavahProcessor(Gen g) { this.g = g; } - public boolean process(Set annotations, RoundEnvironment roundEnv) { - Messager messager = processingEnv.getMessager(); - Set classes = getAllClasses(ElementFilter.typesIn(roundEnv.getRootElements())); - if (classes.size() > 0) { - checkMethodParameters(classes); - g.setProcessingEnvironment(processingEnv); - g.setClasses(classes); + @Override + public SourceVersion getSupportedSourceVersion() { + // since this is co-bundled with javac, we can assume it supports + // the latest source version + return SourceVersion.latest(); + } - try { + @Override + public void init(ProcessingEnvironment pEnv) { + super.init(pEnv); + messager = processingEnv.getMessager(); + } + + public boolean process(Set annotations, RoundEnvironment roundEnv) { + try { + Set classes = getAllClasses(ElementFilter.typesIn(roundEnv.getRootElements())); + if (classes.size() > 0) { + checkMethodParameters(classes); + g.setProcessingEnvironment(processingEnv); + g.setClasses(classes); 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; } + } catch (CompletionFailure cf) { + messager.printMessage(ERROR, getMessage("class.not.found", cf.sym.getQualifiedName().toString())); + } catch (ClassNotFoundException cnfe) { + messager.printMessage(ERROR, getMessage("class.not.found", cnfe.getMessage())); + } catch (IOException ioe) { + messager.printMessage(ERROR, getMessage("io.exception", ioe.getMessage())); + } catch (Util.Exit e) { + exit = e; } + return true; } diff --git a/src/share/classes/com/sun/tools/javah/LLNI.java b/src/share/classes/com/sun/tools/javah/LLNI.java index 405eba985327cf9fdbcc0b53f3d3deee660b35a1..111d1a9cc01d64de53ac4c969c9e78ff8cb3474e 100644 --- a/src/share/classes/com/sun/tools/javah/LLNI.java +++ b/src/share/classes/com/sun/tools/javah/LLNI.java @@ -74,16 +74,21 @@ public class LLNI extends Gen { } protected void write(OutputStream o, TypeElement clazz) throws Util.Exit { - String cname = mangleClassName(clazz.getQualifiedName().toString()); - PrintWriter pw = wrapWriter(o); - 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 + try { + String cname = mangleClassName(clazz.getQualifiedName().toString()); + PrintWriter pw = wrapWriter(o); + 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 + } catch (TypeSignature.SignatureException e) { + util.error("llni.sigerror", e.getMessage()); + } } protected void generateDeclsForClass(PrintWriter pw, - TypeElement clazz, String cname) throws Util.Exit { + TypeElement clazz, String cname) + throws TypeSignature.SignatureException, Util.Exit { doneHandleTypes = new HashSet(); /* The following handle types are predefined in "typedefs.h". Suppress inclusion in the output by generating them "into the blue" here. */ @@ -127,7 +132,8 @@ public class LLNI extends Gen { .replace(innerDelim, '_'); } - protected void forwardDecls(PrintWriter pw, TypeElement clazz) { + protected void forwardDecls(PrintWriter pw, TypeElement clazz) + throws TypeSignature.SignatureException { TypeElement object = elems.getTypeElement("java.lang.Object"); if (clazz.equals(object)) return; @@ -403,7 +409,7 @@ public class LLNI extends Gen { protected void methodSectionForClass(PrintWriter pw, TypeElement clazz, String cname) - throws Util.Exit { + throws TypeSignature.SignatureException, Util.Exit { String methods = methodDecls(clazz, cname); if (methods.length() != 0) { @@ -418,7 +424,8 @@ public class LLNI extends Gen { } } - protected String methodDecls(TypeElement clazz, String cname) throws Util.Exit { + protected String methodDecls(TypeElement clazz, String cname) + throws TypeSignature.SignatureException, Util.Exit { String res = ""; for (ExecutableElement method: methods) { @@ -430,7 +437,7 @@ public class LLNI extends Gen { protected String methodDecl(ExecutableElement method, TypeElement clazz, String cname) - throws Util.Exit { + throws TypeSignature.SignatureException, Util.Exit { String res = null; TypeMirror retType = types.erasure(method.getReturnType()); @@ -474,7 +481,8 @@ public class LLNI extends Gen { } protected final String jniMethodName(ExecutableElement method, String cname, - boolean longName) { + boolean longName) + throws TypeSignature.SignatureException { String res = "Java_" + cname + "_" + method.getSimpleName(); if (longName) { diff --git a/src/share/classes/com/sun/tools/javah/Mangle.java b/src/share/classes/com/sun/tools/javah/Mangle.java index 709b00bc9cc223bfbc502e311b31381d58fc3f66..6b3791cdf1e44c553e0a7f0d34bac0d95857b8ad 100644 --- a/src/share/classes/com/sun/tools/javah/Mangle.java +++ b/src/share/classes/com/sun/tools/javah/Mangle.java @@ -114,7 +114,7 @@ public class Mangle { } public String mangleMethod(ExecutableElement method, TypeElement clazz, - int mtype) { + int mtype) throws TypeSignature.SignatureException { StringBuffer result = new StringBuffer(100); result.append("Java_"); diff --git a/src/share/classes/com/sun/tools/javah/TypeSignature.java b/src/share/classes/com/sun/tools/javah/TypeSignature.java index c0ef12815f035b027a650e300892c8862aa04a3d..4613f3cb9dafcb5633eae5f03cbf18706481dd7b 100644 --- a/src/share/classes/com/sun/tools/javah/TypeSignature.java +++ b/src/share/classes/com/sun/tools/javah/TypeSignature.java @@ -51,7 +51,13 @@ import javax.lang.model.util.SimpleTypeVisitor7; * @author Sucheta Dambalkar */ -public class TypeSignature{ +public class TypeSignature { + static class SignatureException extends Exception { + private static final long serialVersionUID = 1L; + SignatureException(String reason) { + super(reason); + } + } Elements elems; @@ -78,14 +84,15 @@ public class TypeSignature{ /* * Returns the type signature of a field according to JVM specs */ - public String getTypeSignature(String javasignature){ + public String getTypeSignature(String javasignature) throws SignatureException { return getParamJVMSignature(javasignature); } /* * Returns the type signature of a method according to JVM specs */ - public String getTypeSignature(String javasignature, TypeMirror returnType){ + public String getTypeSignature(String javasignature, TypeMirror returnType) + throws SignatureException { String signature = null; //Java type signature. String typeSignature = null; //Internal type signature. List params = new ArrayList(); //List of parameters. @@ -166,7 +173,7 @@ public class TypeSignature{ /* * Returns internal signature of a parameter. */ - private String getParamJVMSignature(String paramsig) { + private String getParamJVMSignature(String paramsig) throws SignatureException { String paramJVMSig = ""; String componentType =""; @@ -197,7 +204,7 @@ public class TypeSignature{ /* * Returns internal signature of a component. */ - private String getComponentType(String componentType){ + private String getComponentType(String componentType) throws SignatureException { String JVMSig = ""; @@ -216,8 +223,7 @@ public class TypeSignature{ TypeElement classNameDoc = elems.getTypeElement(componentType); if(classNameDoc == null){ - System.out.println("Invalid class type for " + componentType); - new Exception().printStackTrace(); + throw new SignatureException(componentType); }else { String classname = classNameDoc.getQualifiedName().toString(); String newclassname = classname.replace('.', '/'); diff --git a/src/share/classes/com/sun/tools/javah/resources/l10n.properties b/src/share/classes/com/sun/tools/javah/resources/l10n.properties index 305e275b0544f071a85883f2db0a8a6599a9af82..297e28211467875eea96574d47538ae4353a7967 100644 --- a/src/share/classes/com/sun/tools/javah/resources/l10n.properties +++ b/src/share/classes/com/sun/tools/javah/resources/l10n.properties @@ -45,6 +45,8 @@ jni.llni.mixed=\ Can''t mix options -jni and -llni. Try -help. jni.no.stubs=\ JNI does not require stubs, please refer to the JNI documentation. +jni.sigerror=\ + Cannot determine signature for {0} dir.file.mixed=\ Can''t mix options -d and -o. Try -help. no.classes.specified=\ @@ -94,7 +96,7 @@ main.opt.d=\ \ -d Output directory main.opt.v=\ \ -v -verbose Enable verbose output -main.opt.help=\ +main.opt.h=\ \ -h --help -? Print this message main.opt.version=\ \ -version Print version information diff --git a/test/tools/javac/T6705935.java b/test/tools/javac/T6705935.java index 45e7454d14031ff065fc34838f998a4194b9d9ff..2b5bd8082d1afca052acf0c315691c3f1ffbb600 100644 --- a/test/tools/javac/T6705935.java +++ b/test/tools/javac/T6705935.java @@ -31,6 +31,8 @@ import java.io.*; import java.util.*; import javax.tools.*; import com.sun.tools.javac.file.*; +import com.sun.tools.javac.file.ZipArchive.ZipFileObject; +import com.sun.tools.javac.file.ZipFileIndexArchive.ZipFileIndexFileObject; public class T6705935 { public static void main(String... args) throws Exception { @@ -43,11 +45,22 @@ public class T6705935 { java_home = java_home.getParentFile(); JavaCompiler c = ToolProvider.getSystemJavaCompiler(); - JavaFileManager fm = c.getStandardFileManager(null, null, null); + StandardJavaFileManager fm = c.getStandardFileManager(null, null, null); + //System.err.println("platform class path: " + asList(fm.getLocation(StandardLocation.PLATFORM_CLASS_PATH))); + for (JavaFileObject fo: fm.list(StandardLocation.PLATFORM_CLASS_PATH, "java.lang", Collections.singleton(JavaFileObject.Kind.CLASS), false)) { + test++; + + if (!(fo instanceof ZipFileObject || fo instanceof ZipFileIndexFileObject)) { + System.out.println("Skip " + fo.getClass().getSimpleName() + " " + fo.getName()); + skip++; + continue; + } + + //System.err.println(fo.getName()); String p = fo.getName(); int bra = p.indexOf("("); int ket = p.indexOf(")"); @@ -61,5 +74,26 @@ public class T6705935 { throw new Exception("bad path: " + p); } + + if (test == 0) + throw new Exception("no files found"); + + if (skip == 0) + System.out.println(test + " files found"); + else + System.out.println(test + " files found, " + skip + " files skipped"); + + if (test == skip) + System.out.println("Warning: all files skipped; no platform classes found in zip files."); } + + private List asList(Iterable items) { + List list = new ArrayList(); + for (T item: items) + list.add(item); + return list; + } + + private int skip; + private int test; } diff --git a/test/tools/javac/api/6406133/Erroneous.java b/test/tools/javac/api/6406133/Erroneous.java index ecd230006ff64800f15bc8d192f72775ac307c03..36b8c7c24229de88df291e4a66b37648e36792c0 100644 --- a/test/tools/javac/api/6406133/Erroneous.java +++ b/test/tools/javac/api/6406133/Erroneous.java @@ -1,4 +1,26 @@ +/* + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + @Deprecated -class A { - class A {} +class A extends Missing { } diff --git a/test/tools/javac/diags/CheckExamples.java b/test/tools/javac/diags/CheckExamples.java index f0111a72c030cb47f0bef630ba94c4915c23b76c..5d516f75f8c937b3cbabbd2ae80e44edbd60ad1b 100644 --- a/test/tools/javac/diags/CheckExamples.java +++ b/test/tools/javac/diags/CheckExamples.java @@ -40,7 +40,7 @@ import java.util.*; * compiler.properties bundle. A list of exceptions may be given in the * not-yet.txt file. Entries on the not-yet.txt list should not be * covered by examples. - * When new keys are added to the resource buncle, it is strongly recommended + * When new keys are added to the resource bundle, it is strongly recommended * that corresponding new examples be added here, if at all practical, instead * of simply and lazily being added to the not-yet.txt list. */ diff --git a/test/tools/javac/diags/FileManager.java b/test/tools/javac/diags/FileManager.java index 4132d25557d4cf6d6c30435ef924a32aefb80a27..2019eef6da497fc56e07b4fddc262f10c2f71041 100644 --- a/test/tools/javac/diags/FileManager.java +++ b/test/tools/javac/diags/FileManager.java @@ -177,12 +177,14 @@ public class FileManager } void checkRead() throws IOException { - if (cantRead != null && cantRead.matcher(getName()).matches()) + String canonName = getName().replace(File.separatorChar, '/'); + if (cantRead != null && cantRead.matcher(canonName).matches()) throw new IOException("FileManager: Can't read"); } void checkWrite() throws IOException { - if (cantWrite != null && cantWrite.matcher(getName()).matches()) + String canonName = getName().replace(File.separatorChar, '/'); + if (cantWrite != null && cantWrite.matcher(canonName).matches()) throw new IOException("FileManager: Can't write"); } diff --git a/test/tools/javac/meth/TestCP.java b/test/tools/javac/meth/TestCP.java new file mode 100644 index 0000000000000000000000000000000000000000..bbcb5bf9e39795305abeb169f8164bb038048b6b --- /dev/null +++ b/test/tools/javac/meth/TestCP.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6991980 + * @summary polymorphic signature calls don't share the same CP entries + * @run main TestCP + */ + +import com.sun.tools.classfile.Instruction; +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.Code_attribute; +import com.sun.tools.classfile.ConstantPool.*; +import com.sun.tools.classfile.Method; + +import java.dyn.*; +import java.io.*; + +public class TestCP { + + static class TestClass { + void test(MethodHandle mh) throws Throwable { + Number n = mh.invokeExact("daddy",1,'n'); + n = (Number)mh.invokeExact("bunny",1,'d'); + } + } + + static final String PS_TYPE = "(Ljava/lang/String;IC)Ljava/lang/Number;"; + static final int PS_CALLS_COUNT = 2; + static final String SUBTEST_NAME = TestClass.class.getName() + ".class"; + static final String TEST_METHOD_NAME = "test"; + + public static void main(String... args) throws Exception { + new TestCP().run(); + } + + public void run() throws Exception { + String workDir = System.getProperty("test.classes"); + File compiledTest = new File(workDir, SUBTEST_NAME); + verifyMethodHandleInvocationDescriptors(compiledTest); + } + + void verifyMethodHandleInvocationDescriptors(File f) { + System.err.println("verify: " + f); + try { + int count = 0; + ClassFile cf = ClassFile.read(f); + Method testMethod = null; + for (Method m : cf.methods) { + if (m.getName(cf.constant_pool).equals(TEST_METHOD_NAME)) { + testMethod = m; + break; + } + } + if (testMethod == null) { + throw new Error("Test method not found"); + } + Code_attribute ea = (Code_attribute)testMethod.attributes.get(Attribute.Code); + if (testMethod == null) { + throw new Error("Code attribute for test() method not found"); + } + int instr_count = 0; + int cp_entry = -1; + + for (Instruction i : ea.getInstructions()) { + if (i.getMnemonic().equals("invokevirtual")) { + instr_count++; + if (cp_entry == -1) { + cp_entry = i.getUnsignedShort(1); + } else if (cp_entry != i.getUnsignedShort(1)) { + throw new Error("Unexpected CP entry in polymorphic signature call"); + } + CONSTANT_Methodref_info methRef = + (CONSTANT_Methodref_info)cf.constant_pool.get(cp_entry); + String type = methRef.getNameAndTypeInfo().getType(); + if (!type.equals(PS_TYPE)) { + throw new Error("Unexpected type in polymorphic signature call: " + type); + } + } + } + if (instr_count != PS_CALLS_COUNT) { + throw new Error("Wrong number of polymorphic signature call found: " + instr_count); + } + } catch (Exception e) { + e.printStackTrace(); + throw new Error("error reading " + f +": " + e); + } + } +} diff --git a/test/tools/javac/processing/environment/round/TestContext.java b/test/tools/javac/processing/environment/round/TestContext.java new file mode 100644 index 0000000000000000000000000000000000000000..ddcba25fe806f15b42ce6c65a6be11522e3c2afa --- /dev/null +++ b/test/tools/javac/processing/environment/round/TestContext.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6988836 + * @summary A new JavacElements is created for each round of annotation processing + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestContext + * @compile/process -processor TestContext -XprintRounds TestContext + */ + +import java.io.*; +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.element.*; +import javax.tools.*; +import static javax.tools.Diagnostic.Kind.*; + +import com.sun.source.util.Trees; +import com.sun.tools.javac.api.JavacTrees; +import com.sun.tools.javac.model.JavacElements; +import com.sun.tools.javac.model.JavacTypes; +import com.sun.tools.javac.processing.JavacProcessingEnvironment; +import com.sun.tools.javac.util.Context; + +public class TestContext extends JavacTestingAbstractProcessor { + + Trees treeUtils; + int round = 0; + + @Override + public void init(ProcessingEnvironment pEnv) { + super.init(pEnv); + treeUtils = Trees.instance(processingEnv); + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + round++; + + JavacProcessingEnvironment jpe = (JavacProcessingEnvironment) processingEnv; + Context c = jpe.getContext(); + check(c.get(JavacElements.class), eltUtils); + check(c.get(JavacTypes.class), typeUtils); + check(c.get(JavacTrees.class), treeUtils); + + final int MAXROUNDS = 3; + if (round < MAXROUNDS) + generateSource("Gen" + round); + + return true; + } + + void check(T actual, T expected) { +// messager.printMessage(NOTE, "expect: " + expected); +// messager.printMessage(NOTE, "actual: " + actual); + + if (actual != expected) { + messager.printMessage(ERROR, + "round " + round + " unexpected value for " + expected.getClass().getName() + ": " + actual); + } + } + + void generateSource(String name) { + String text = "class " + name + " { }\n"; + + try (Writer out = filer.createSourceFile(name).openWriter()) { + out.write(text); + } catch (IOException e) { + throw new Error(e); + } + } + +} + diff --git a/test/tools/javac/processing/errors/TestParseErrors/ParseErrors.java b/test/tools/javac/processing/errors/TestParseErrors/ParseErrors.java new file mode 100644 index 0000000000000000000000000000000000000000..9911916f5f96bb61861bab9d6939f5a263633c98 --- /dev/null +++ b/test/tools/javac/processing/errors/TestParseErrors/ParseErrors.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.List; +import java.util.Vector; + +class test { + + public String m(List v, String s ) { + return null; + } + + public String m2(Vector vs, String s) { + return null; + } + + public void m3(testclass, +} + +class testclass { + T t; +} diff --git a/test/tools/javac/processing/errors/TestParseErrors/TestParseErrors.java b/test/tools/javac/processing/errors/TestParseErrors/TestParseErrors.java new file mode 100644 index 0000000000000000000000000000000000000000..bc094f31578cfea5fd25137e87bb6fcd6bf21eb5 --- /dev/null +++ b/test/tools/javac/processing/errors/TestParseErrors/TestParseErrors.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6988407 + * @summary javac crashes running processor on errant code; it used to print error message + * @library ../../../lib + * @build JavacTestingAbstractProcessor TestParseErrors + * @compile/fail/ref=TestParseErrors.out -XDrawDiagnostics -proc:only -processor TestParseErrors ParseErrors.java + */ + +import java.util.*; +import javax.annotation.processing.*; +import javax.lang.model.element.*; + +public class TestParseErrors extends JavacTestingAbstractProcessor { + + public boolean process(Set annotations, + RoundEnvironment roundEnvironment) { + throw new Error("Should not be called"); + } +} diff --git a/test/tools/javac/processing/errors/TestParseErrors/TestParseErrors.out b/test/tools/javac/processing/errors/TestParseErrors/TestParseErrors.out new file mode 100644 index 0000000000000000000000000000000000000000..947e921dd4dfaee95dc950e7cd3fda94510a5506 --- /dev/null +++ b/test/tools/javac/processing/errors/TestParseErrors/TestParseErrors.out @@ -0,0 +1,8 @@ +ParseErrors.java:37:37: compiler.err.expected: token.identifier +ParseErrors.java:38:1: compiler.err.illegal.start.of.type +ParseErrors.java:38:2: compiler.err.expected: ')' +ParseErrors.java:40:6: compiler.err.expected: ';' +ParseErrors.java:40:20: compiler.err.illegal.start.of.type +ParseErrors.java:41:5: compiler.err.expected: '(' +ParseErrors.java:41:8: compiler.err.expected: token.identifier +7 errors diff --git a/test/tools/javadoc/T4994049/FileWithTabs.java b/test/tools/javadoc/T4994049/FileWithTabs.java index 2ac29d48ef3ac6ff271929d75f17afb25552048e..63351a9fe38aef6f44ad944d85f0bfe1360557fd 100644 --- a/test/tools/javadoc/T4994049/FileWithTabs.java +++ b/test/tools/javadoc/T4994049/FileWithTabs.java @@ -22,5 +22,5 @@ */ public class FileWithTabs { - public void tabbedMethod() {} +\tpublic void tabbedMethod() {} } diff --git a/test/tools/javadoc/T4994049/T4994049.java b/test/tools/javadoc/T4994049/T4994049.java index f8017af911465af0c7e6030a3113d3ad30fe399f..17848a141b6f56f724cd51c6050ae8fd5c5ad7fc 100644 --- a/test/tools/javadoc/T4994049/T4994049.java +++ b/test/tools/javadoc/T4994049/T4994049.java @@ -30,7 +30,7 @@ */ import com.sun.javadoc.*; -import java.io.File; +import java.io.*; import static com.sun.tools.javadoc.Main.execute; public class T4994049 extends Doclet { @@ -52,12 +52,47 @@ public class T4994049 extends Doclet { return false; } - public static void main(String... args) { + public static void main(String... args) throws Exception { + File testSrc = new File(System.getProperty("test.src")); + File tmpSrc = new File("tmpSrc"); + initTabs(testSrc, tmpSrc); + for (String file : args) { - File source = new File(System.getProperty("test.src", "."), file); - if (execute("javadoc", "T4994049", T4994049.class.getClassLoader(), - new String[]{source.getPath()} ) != 0) - throw new Error(); + File source = new File(tmpSrc, file); + int rc = execute("javadoc", "T4994049", T4994049.class.getClassLoader(), + new String[]{ source.getPath() } ); + if (rc != 0) + throw new Error("Unexpected return code from javadoc: " + rc); + } + } + + static void initTabs(File from, File to) throws IOException { + for (File f: from.listFiles()) { + File t = new File(to, f.getName()); + if (f.isDirectory()) { + initTabs(f, t); + } else if (f.getName().endsWith(".java")) { + write(t, read(f).replace("\\t", "\t")); + } + } + } + + static String read(File f) throws IOException { + StringBuilder sb = new StringBuilder(); + try (BufferedReader in = new BufferedReader(new FileReader(f))) { + String line; + while ((line = in.readLine()) != null) { + sb.append(line); + sb.append("\n"); + } + } + return sb.toString(); + } + + static void write(File f, String s) throws IOException { + f.getParentFile().mkdirs(); + try (Writer out = new FileWriter(f)) { + out.write(s); } } diff --git a/test/tools/javah/4942232/ParamClassTest.java b/test/tools/javah/4942232/ParamClassTest.java new file mode 100644 index 0000000000000000000000000000000000000000..143ae367e201f8f1bc52a9551e8bddfec72b68b5 --- /dev/null +++ b/test/tools/javah/4942232/ParamClassTest.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +public class ParamClassTest { + static { + System.loadLibrary("Test"); + } + + public native void method(Param s); + + public static void main(String[] a) { + } +} + +class Param { +} diff --git a/test/tools/javah/4942232/Test.java b/test/tools/javah/4942232/Test.java new file mode 100644 index 0000000000000000000000000000000000000000..d108adf846fd8d56c31f2c9baf7c582efbe1c878 --- /dev/null +++ b/test/tools/javah/4942232/Test.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 4942232 + * @summary missing param class processes without error + * @build ParamClassTest Test + * @run main Test + */ + +import java.io.*; +import java.util.*; + +public class Test { + public static void main(String... args) throws Exception { + new Test().run(); + } + + void run() throws Exception { + File testSrc = new File(System.getProperty("test.src")); + File testClasses = new File(System.getProperty("test.classes")); + + // standard use of javah on valid class file + String[] test1Args = { + "-d", mkdir("test1/out").getPath(), + "-classpath", testClasses.getPath(), + "ParamClassTest" + }; + test(test1Args, 0); + + // extended use of javah on valid source file + String[] test2Args = { + "-d", mkdir("test2/out").getPath(), + "-classpath", testSrc.getPath(), + "ParamClassTest" + }; + test(test2Args, 0); + + // javah on class file with missing referents + File test3Classes = mkdir("test3/classes"); + copy(new File(testClasses, "ParamClassTest.class"), test3Classes); + String[] test3Args = { + "-d", mkdir("test3/out").getPath(), + "-classpath", test3Classes.getPath(), + "ParamClassTest" + }; + test(test3Args, 1); + + // javah on source file with missing referents + File test4Src = mkdir("test4/src"); + String paramClassTestSrc = readFile(new File(testSrc, "ParamClassTest.java")); + writeFile(new File(test4Src, "ParamClassTest.java"), + paramClassTestSrc.replaceAll("class Param \\{\\s+\\}", "")); + String[] test4Args = { + "-d", mkdir("test4/out").getPath(), + "-classpath", test4Src.getPath(), + "ParamClassTest" + }; + test(test4Args, 15); + + if (errors > 0) + throw new Exception(errors + " errors occurred"); + } + + void test(String[] args, int expect) { + System.err.println("test: " + Arrays.asList(args)); + int rc = javah(args); + if (rc != expect) + error("Unexpected return code: " + rc + "; expected: " + expect); + } + + int javah(String... args) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + int rc = com.sun.tools.javah.Main.run(args, pw); + pw.close(); + String out = sw.toString(); + if (!out.isEmpty()) + System.err.println(out); + return rc; + } + + File mkdir(String path) { + File f = new File(path); + f.mkdirs(); + return f; + } + + void copy(File from, File to) throws IOException { + if (to.isDirectory()) + to = new File(to, from.getName()); + try (DataInputStream in = new DataInputStream(new FileInputStream(from)); + FileOutputStream out = new FileOutputStream(to)) { + byte[] buf = new byte[(int) from.length()]; + in.readFully(buf); + out.write(buf); + } + } + + String readFile(File f) throws IOException { + try (DataInputStream in = new DataInputStream(new FileInputStream(f))) { + byte[] buf = new byte[(int) f.length()]; + in.readFully(buf); + return new String(buf); + } + } + + void writeFile(File f, String body) throws IOException { + try (FileWriter out = new FileWriter(f)) { + out.write(body); + } + } + + void error(String msg) { + System.err.println(msg); + errors++; + } + + int errors; +} diff --git a/test/tools/javah/TestHelpOpts.java b/test/tools/javah/TestHelpOpts.java new file mode 100644 index 0000000000000000000000000000000000000000..108be057b00e197c8e9390064832580fac249d23 --- /dev/null +++ b/test/tools/javah/TestHelpOpts.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6893932 6990390 + * @summary javah help screen lists -h and -? but does not accept them + */ + +import java.io.*; +import java.util.*; + +public class TestHelpOpts { + public static void main(String... args) throws Exception { + new TestHelpOpts().run(); + } + + void run() throws Exception { + Locale prev = Locale.getDefault(); + try { + Locale.setDefault(Locale.ENGLISH); + + String[] opts = { "-h", "-help", "-?", "--help" }; + for (String opt: opts) + test(opt); + } finally { + Locale.setDefault(prev); + } + + if (errors > 0) + throw new Exception(errors + " errors occurred"); + } + + void test(String opt) { + System.err.println("test " + opt); + String[] args = { opt }; + + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + int rc = com.sun.tools.javah.Main.run(args, pw); + pw.close(); + String out = sw.toString(); + if (!out.isEmpty()) + System.err.println(out); + if (rc != 0) + error("Unexpected exit: rc=" + rc); + + String flat = out.replaceAll("\\s+", " "); // canonicalize whitespace + if (!flat.contains("Usage: javah [options] where [options] include:")) + error("expected text not found"); + if (flat.contains("main.opt")) + error("key not found in resource bundle: " + flat.replaceAll(".*(main.opt.[^ ]*).*", "$1")); + } + + void error(String msg) { + System.err.println(msg); + errors++; + } + + int errors; +}