# HG changeset patch # User lana # Date 1331323166 28800 # Node ID 08a3425f39f829502ca0ddbfb2d051c31710cb19 # Parent a1af4b95c287c49678d87d8dee3f874d7daa9889# Parent 97bec6ab1227727f41fbc80136ba889c1040d084 Merge diff -r a1af4b95c287 -r 08a3425f39f8 .hgignore --- a/.hgignore Thu Mar 08 20:35:26 2012 -0800 +++ b/.hgignore Fri Mar 09 11:59:26 2012 -0800 @@ -2,3 +2,4 @@ ^dist/ /nbproject/private/ ^.hgtip +.DS_Store diff -r a1af4b95c287 -r 08a3425f39f8 make/build.xml --- a/make/build.xml Thu Mar 08 20:35:26 2012 -0800 +++ b/make/build.xml Fri Mar 09 11:59:26 2012 -0800 @@ -862,7 +862,8 @@ source="${boot.javac.source}" target="${boot.javac.target}" executable="${boot.java.home}/bin/javac" - srcdir="${make.tools.dir}/CompileProperties" + srcdir="${make.tools.dir}" + includes="compileproperties/* anttasks/CompileProperties*" destdir="${build.toolclasses.dir}/" classpath="${ant.core.lib}" bootclasspath="${boot.java.home}/jre/lib/rt.jar" @@ -870,7 +871,7 @@ @@ -880,7 +881,8 @@ source="${boot.javac.source}" target="${boot.javac.target}" executable="${boot.java.home}/bin/javac" - srcdir="${make.tools.dir}/GenStubs" + srcdir="${make.tools.dir}" + includes="genstubs/* anttasks/GenStubs*" destdir="${build.toolclasses.dir}/" classpath="${ant.core.lib}" includeantruntime="false"> @@ -888,7 +890,7 @@ diff -r a1af4b95c287 -r 08a3425f39f8 make/jprt.properties --- a/make/jprt.properties Thu Mar 08 20:35:26 2012 -0800 +++ b/make/jprt.properties Fri Mar 09 11:59:26 2012 -0800 @@ -39,6 +39,7 @@ solaris_x64_5.10-{product|fastdebug}, \ linux_i586_2.6-{product|fastdebug}, \ linux_x64_2.6-{product|fastdebug}, \ + macosx_x64_10.7-{product|fastdebug}, \ windows_i586_5.1-{product|fastdebug}, \ windows_x64_5.2-{product|fastdebug} @@ -50,6 +51,7 @@ solaris_x64_5.10-product-c2-TESTNAME, \ linux_i586_2.6-product-{c1|c2}-TESTNAME, \ linux_x64_2.6-product-c2-TESTNAME, \ + macosx_x64_10.7-product-c2-TESTNAME, \ windows_i586_5.1-product-c1-TESTNAME, \ windows_x64_5.2-product-c2-TESTNAME @@ -60,3 +62,18 @@ # Directories to be excluded from the source bundles jprt.bundle.exclude.src.dirs=build dist webrev +# Test target list (no fastdebug & limited c2 testing) +jprt.my.test.target.set= \ + solaris_sparc_5.10-product-c1-TESTNAME, \ + solaris_sparcv9_5.10-product-c2-TESTNAME, \ + solaris_i586_5.10-product-c1-TESTNAME, \ + solaris_x64_5.10-product-c2-TESTNAME, \ + linux_i586_2.6-product-{c1|c2}-TESTNAME, \ + linux_x64_2.6-product-c2-TESTNAME, \ + macosx_x64_10.7-product-c2-TESTNAME, \ + windows_i586_5.1-product-c1-TESTNAME, \ + windows_x64_5.2-product-c2-TESTNAME + +# Default test targets +jprt.make.rule.test.targets= \ + ${jprt.my.test.target.set:TESTNAME=jtreg} diff -r a1af4b95c287 -r 08a3425f39f8 make/netbeans/langtools/build.xml --- a/make/netbeans/langtools/build.xml Thu Mar 08 20:35:26 2012 -0800 +++ b/make/netbeans/langtools/build.xml Fri Mar 09 11:59:26 2012 -0800 @@ -261,7 +261,8 @@ - diff -r a1af4b95c287 -r 08a3425f39f8 make/tools/CompileProperties/CompileProperties.java --- a/make/tools/CompileProperties/CompileProperties.java Thu Mar 08 20:35:26 2012 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,402 +0,0 @@ -/* - * Copyright (c) 2002, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Properties; - -/** Translates a .properties file into a .java file containing the - * definition of a java.util.Properties subclass which can then be - * compiled with javac.

- * - * Usage: java CompileProperties [path to .properties file] [path to .java file to be output] [super class] - * - * Infers the package by looking at the common suffix of the two - * inputs, eliminating "classes" from it. - * - * @author Scott Violet - * @author Kenneth Russell - */ - -public class CompileProperties { - - public static void main(String[] args) { - CompileProperties cp = new CompileProperties(); - boolean ok = cp.run(args); - if ( !ok ) { - System.exit(1); - } - } - - static interface Log { - void info(String msg); - void verbose(String msg); - void error(String msg, Exception e); - } - - private String propfiles[]; - private String outfiles[] ; - private String supers[] ; - private int compileCount = 0; - private boolean quiet = false; - private Log log; - - public void setLog(Log log) { - this.log = log; - } - - public boolean run(String[] args) { - if (log == null) { - log = new Log() { - public void error(String msg, Exception e) { - System.err.println("ERROR: CompileProperties: " + msg); - if ( e != null ) { - System.err.println("EXCEPTION: " + e.toString()); - e.printStackTrace(); - } - } - public void info(String msg) { - System.out.println(msg); - } - public void verbose(String msg) { - if (!quiet) - System.out.println(msg); - } - }; - } - - boolean ok = true; - /* Original usage */ - if (args.length == 2 && args[0].charAt(0) != '-' ) { - ok = createFile(args[0], args[1], "java.util.ListResourceBundle"); - } else if (args.length == 3) { - ok = createFile(args[0], args[1], args[2]); - } else if (args.length == 0) { - usage(log); - ok = false; - } else { - /* New batch usage */ - ok = parseOptions(args); - if ( ok && compileCount == 0 ) { - log.error("options parsed but no files to compile", null); - ok = false; - } - /* Need at least one file. */ - if ( !ok ) { - usage(log); - } else { - /* Process files */ - for ( int i = 0; i < compileCount && ok ; i++ ) { - ok = createFile(propfiles[i], outfiles[i], supers[i]); - } - } - } - return ok; - } - - private boolean parseOptions(String args[]) { - boolean ok = true; - if ( compileCount > 0 ) { - String new_propfiles[] = new String[compileCount + args.length]; - String new_outfiles[] = new String[compileCount + args.length]; - String new_supers[] = new String[compileCount + args.length]; - System.arraycopy(propfiles, 0, new_propfiles, 0, compileCount); - System.arraycopy(outfiles, 0, new_outfiles, 0, compileCount); - System.arraycopy(supers, 0, new_supers, 0, compileCount); - propfiles = new_propfiles; - outfiles = new_outfiles; - supers = new_supers; - } else { - propfiles = new String[args.length]; - outfiles = new String[args.length]; - supers = new String[args.length]; - } - - for ( int i = 0; i < args.length ; i++ ) { - if ( "-compile".equals(args[i]) && i+3 < args.length ) { - propfiles[compileCount] = args[++i]; - outfiles[compileCount] = args[++i]; - supers[compileCount] = args[++i]; - compileCount++; - } else if ( "-optionsfile".equals(args[i]) && i+1 < args.length ) { - String filename = args[++i]; - FileInputStream finput = null; - byte contents[] = null; - try { - finput = new FileInputStream(filename); - int byteCount = finput.available(); - if ( byteCount <= 0 ) { - log.error("The -optionsfile file is empty", null); - ok = false; - } else { - contents = new byte[byteCount]; - int bytesRead = finput.read(contents); - if ( byteCount != bytesRead ) { - log.error("Cannot read all of -optionsfile file", null); - ok = false; - } - } - } catch ( IOException e ) { - log.error("cannot open " + filename, e); - ok = false; - } - if ( finput != null ) { - try { - finput.close(); - } catch ( IOException e ) { - ok = false; - log.error("cannot close " + filename, e); - } - } - if ( ok = true && contents != null ) { - String tokens[] = (new String(contents)).split("\\s+"); - if ( tokens.length > 0 ) { - ok = parseOptions(tokens); - } - } - if ( !ok ) { - break; - } - } else if ( "-quiet".equals(args[i]) ) { - quiet = true; - } else { - log.error("argument error", null); - ok = false; - } - } - return ok; - } - - private boolean createFile(String propertiesPath, String outputPath, - String superClass) { - boolean ok = true; - log.verbose("parsing: " + propertiesPath); - Properties p = new Properties(); - try { - p.load(new FileInputStream(propertiesPath)); - } catch ( FileNotFoundException e ) { - ok = false; - log.error("Cannot find file " + propertiesPath, e); - } catch ( IOException e ) { - ok = false; - log.error("IO error on file " + propertiesPath, e); - } - if ( ok ) { - String packageName = inferPackageName(propertiesPath, outputPath); - log.verbose("inferred package name: " + packageName); - List sortedKeys = new ArrayList(); - for ( Object key : p.keySet() ) { - sortedKeys.add((String)key); - } - Collections.sort(sortedKeys); - Iterator keys = sortedKeys.iterator(); - - StringBuffer data = new StringBuffer(); - - while (keys.hasNext()) { - String key = keys.next(); - data.append(" { \"" + escape(key) + "\", \"" + - escape((String)p.get(key)) + "\" },\n"); - } - - // Get class name from java filename, not the properties filename. - // (zh_TW properties might be used to create zh_HK files) - File file = new File(outputPath); - String name = file.getName(); - int dotIndex = name.lastIndexOf('.'); - String className; - if (dotIndex == -1) { - className = name; - } else { - className = name.substring(0, dotIndex); - } - - String packageString = ""; - if (packageName != null && !packageName.equals("")) { - packageString = "package " + packageName + ";\n\n"; - } - - Writer writer = null; - try { - writer = new BufferedWriter( - new OutputStreamWriter(new FileOutputStream(outputPath), "8859_1")); - MessageFormat format = new MessageFormat(FORMAT); - writer.write(format.format(new Object[] { packageString, className, superClass, data })); - } catch ( IOException e ) { - ok = false; - log.error("IO error writing to file " + outputPath, e); - } - if ( writer != null ) { - try { - writer.flush(); - } catch ( IOException e ) { - ok = false; - log.error("IO error flush " + outputPath, e); - } - try { - writer.close(); - } catch ( IOException e ) { - ok = false; - log.error("IO error close " + outputPath, e); - } - } - log.verbose("wrote: " + outputPath); - } - return ok; - } - - private static void usage(Log log) { - log.info("usage:"); - log.info(" java CompileProperties path_to_properties_file path_to_java_output_file [super_class]"); - log.info(" -OR-"); - log.info(" java CompileProperties {-compile path_to_properties_file path_to_java_output_file super_class} -or- -optionsfile filename"); - log.info(""); - log.info("Example:"); - log.info(" java CompileProperties -compile test.properties test.java java.util.ListResourceBundle"); - log.info(" java CompileProperties -optionsfile option_file"); - log.info("option_file contains: -compile test.properties test.java java.util.ListResourceBundle"); - } - - private static String escape(String theString) { - // This is taken from Properties.saveConvert with changes for Java strings - int len = theString.length(); - StringBuffer outBuffer = new StringBuffer(len*2); - - for(int x=0; x 0x007e)) { - outBuffer.append('\\'); - outBuffer.append('u'); - outBuffer.append(toHex((aChar >> 12) & 0xF)); - outBuffer.append(toHex((aChar >> 8) & 0xF)); - outBuffer.append(toHex((aChar >> 4) & 0xF)); - outBuffer.append(toHex( aChar & 0xF)); - } else { - if (specialSaveChars.indexOf(aChar) != -1) { - outBuffer.append('\\'); - } - outBuffer.append(aChar); - } - } - } - return outBuffer.toString(); - } - - private static String inferPackageName(String inputPath, String outputPath) { - // Normalize file names - inputPath = new File(inputPath).getPath(); - outputPath = new File(outputPath).getPath(); - // Split into components - String sep; - if (File.separatorChar == '\\') { - sep = "\\\\"; - } else { - sep = File.separator; - } - String[] inputs = inputPath.split(sep); - String[] outputs = outputPath.split(sep); - // Match common names, eliminating first "classes" entry from - // each if present - int inStart = 0; - int inEnd = inputs.length - 2; - int outEnd = outputs.length - 2; - int i = inEnd; - int j = outEnd; - while (i >= 0 && j >= 0) { - if (!inputs[i].equals(outputs[j]) || - (inputs[i].equals("gensrc") && inputs[j].equals("gensrc"))) { - ++i; - ++j; - break; - } - --i; - --j; - } - String result; - if (i < 0 || j < 0 || i >= inEnd || j >= outEnd) { - result = ""; - } else { - if (inputs[i].equals("classes") && outputs[j].equals("classes")) { - ++i; - } - inStart = i; - StringBuffer buf = new StringBuffer(); - for (i = inStart; i <= inEnd; i++) { - buf.append(inputs[i]); - if (i < inEnd) { - buf.append('.'); - } - } - result = buf.toString(); - } - return result; - } - - private static final String FORMAT = - "{0}" + - "public final class {1} extends {2} '{'\n" + - " protected final Object[][] getContents() '{'\n" + - " return new Object[][] '{'\n" + - "{3}" + - " };\n" + - " }\n" + - "}\n"; - - // This comes from Properties - private static char toHex(int nibble) { - return hexDigit[(nibble & 0xF)]; - } - - // This comes from Properties - private static final char[] hexDigit = { - '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' - }; - - // Note: different from that in Properties - private static final String specialSaveChars = "\""; -} diff -r a1af4b95c287 -r 08a3425f39f8 make/tools/CompileProperties/CompilePropertiesTask.java --- a/make/tools/CompileProperties/CompilePropertiesTask.java Thu Mar 08 20:35:26 2012 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2007, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.DirectoryScanner; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.taskdefs.MatchingTask; - -public class CompilePropertiesTask extends MatchingTask { - public void setSrcDir(File srcDir) { - this.srcDir = srcDir; - } - - public void setDestDir(File destDir) { - this.destDir = destDir; - } - - public void setSuperclass(String superclass) { - this.superclass = superclass; - } - - @Override - public void execute() { - CompileProperties.Log log = new CompileProperties.Log() { - public void error(String msg, Exception e) { - log(msg, Project.MSG_ERR); - } - public void info(String msg) { - log(msg, Project.MSG_INFO); - } - public void verbose(String msg) { - log(msg, Project.MSG_VERBOSE); - } - }; - List mainOpts = new ArrayList(); - int count = 0; - DirectoryScanner s = getDirectoryScanner(srcDir); - for (String path: s.getIncludedFiles()) { - if (path.endsWith(".properties")) { - String destPath = - path.substring(0, path.length() - ".properties".length()) + - ".java"; - File srcFile = new File(srcDir, path); - File destFile = new File(destDir, destPath); - // Arguably, the comparison in the next line should be ">", not ">=" - // but that assumes the resolution of the last modified time is fine - // grained enough; in practice, it is better to use ">=". - if (destFile.exists() && destFile.lastModified() >= srcFile.lastModified()) - continue; - destFile.getParentFile().mkdirs(); - mainOpts.add("-compile"); - mainOpts.add(srcFile.getPath()); - mainOpts.add(destFile.getPath()); - mainOpts.add(superclass); - count++; - } - } - if (mainOpts.size() > 0) { - log("Generating " + count + " resource files to " + destDir, Project.MSG_INFO); - CompileProperties cp = new CompileProperties(); - cp.setLog(log); - boolean ok = cp.run(mainOpts.toArray(new String[mainOpts.size()])); - if (!ok) - throw new BuildException("CompileProperties failed."); - } - } - - private File srcDir; - private File destDir; - private String superclass = "java.util.ListResourceBundle"; -} diff -r a1af4b95c287 -r 08a3425f39f8 make/tools/GenStubs/GenStubs.java --- a/make/tools/GenStubs/GenStubs.java Thu Mar 08 20:35:26 2012 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,448 +0,0 @@ -/* - * Copyright (c) 2009, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.io.*; -import java.util.*; -import javax.tools.JavaFileObject; -import javax.tools.StandardJavaFileManager; -import javax.tools.StandardLocation; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.DirectoryScanner; -import org.apache.tools.ant.taskdefs.MatchingTask; -import org.apache.tools.ant.types.Path; -import org.apache.tools.ant.types.Reference; - - -import com.sun.source.tree.CompilationUnitTree; -import com.sun.source.util.JavacTask; -import com.sun.tools.javac.api.JavacTool; -import com.sun.tools.javac.code.Flags; -import com.sun.tools.javac.code.TypeTags; -import com.sun.tools.javac.tree.JCTree; -import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; -import com.sun.tools.javac.tree.JCTree.JCFieldAccess; -import com.sun.tools.javac.tree.JCTree.JCIdent; -import com.sun.tools.javac.tree.JCTree.JCImport; -import com.sun.tools.javac.tree.JCTree.JCLiteral; -import com.sun.tools.javac.tree.JCTree.JCMethodDecl; -import com.sun.tools.javac.tree.JCTree.JCModifiers; -import com.sun.tools.javac.tree.JCTree.JCVariableDecl; -import com.sun.tools.javac.tree.Pretty; -import com.sun.tools.javac.tree.TreeMaker; -import com.sun.tools.javac.tree.TreeScanner; -import com.sun.tools.javac.tree.TreeTranslator; -import com.sun.tools.javac.util.Context; -import com.sun.tools.javac.util.ListBuffer; -import com.sun.tools.javac.util.Name; -import javax.tools.JavaFileManager; - -/** - * Generate stub source files by removing implementation details from input files. - * - * This is a special purpose stub generator, specific to the needs of generating - * stub files for JDK 7 API that are needed to compile langtools files that depend - * on that API. The stub generator works by removing as much of the API source code - * as possible without affecting the public signature, in order to reduce the - * transitive closure of the API being referenced. The resulting stubs can be - * put on the langtools sourcepath with -implicit:none to compile the langtools - * files that depend on the JDK 7 API. - * - * Usage: - * genstubs -s -sourcepath - * - * The specified class names are looked up on the sourcepath, and corresponding - * stubs are written to the source output directory. - * - * Classes are parsed into javac ASTs, then processed with a javac TreeTranslator - * to remove implementation details, and written out in the source output directory. - * Documentation comments and annotations are removed. Method bodies are removed - * and methods are marked native. Private and package-private field definitions - * have their initializers replace with 0, 0.0, false, null as appropriate. - * - * An Ant task, Main$Ant is also provided. Files are specified with an implicit - * fileset, using srcdir as a base directory. The set of files to be included - * is specified with an includes attribute or nested set. However, - * unlike a normal fileset, an empty includes attribute means "no files" instead - * of "all files". The Ant task also accepts "fork=true" and classpath attribute - * or nested element to run GenStubs in a separate VM with the specified - * path. This is likely necessary if a JDK 7 parser is required to read the - * JDK 7 input files. - */ - -public class GenStubs { - static class Fault extends Exception { - private static final long serialVersionUID = 0; - Fault(String message) { - super(message); - } - Fault(String message, Throwable cause) { - super(message); - initCause(cause); - } - } - - public static void main(String[] args) { - boolean ok = new GenStubs().run(args); - if (!ok) - System.exit(1); - } - - boolean run(String... args) { - File outdir = null; - String sourcepath = null; - List classes = new ArrayList(); - for (ListIterator iter = Arrays.asList(args).listIterator(); iter.hasNext(); ) { - String arg = iter.next(); - if (arg.equals("-s") && iter.hasNext()) - outdir = new File(iter.next()); - else if (arg.equals("-sourcepath") && iter.hasNext()) - sourcepath = iter.next(); - else if (arg.startsWith("-")) - throw new IllegalArgumentException(arg); - else { - classes.add(arg); - while (iter.hasNext()) - classes.add(iter.next()); - } - } - - return run(sourcepath, outdir, classes); - } - - boolean run(String sourcepath, File outdir, List classes) { - //System.err.println("run: sourcepath:" + sourcepath + " outdir:" + outdir + " classes:" + classes); - if (sourcepath == null) - throw new IllegalArgumentException("sourcepath not set"); - if (outdir == null) - throw new IllegalArgumentException("source output dir not set"); - - JavacTool tool = JavacTool.create(); - StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); - - try { - fm.setLocation(StandardLocation.SOURCE_OUTPUT, Collections.singleton(outdir)); - fm.setLocation(StandardLocation.SOURCE_PATH, splitPath(sourcepath)); - List files = new ArrayList(); - for (String c: classes) { - JavaFileObject fo = fm.getJavaFileForInput( - StandardLocation.SOURCE_PATH, c, JavaFileObject.Kind.SOURCE); - if (fo == null) - error("class not found: " + c); - else - files.add(fo); - } - - JavacTask t = tool.getTask(null, fm, null, null, null, files); - Iterable trees = t.parse(); - for (CompilationUnitTree tree: trees) { - makeStub(fm, tree); - } - } catch (IOException e) { - error("IO error " + e, e); - } - - return (errors == 0); - } - - void makeStub(StandardJavaFileManager fm, CompilationUnitTree tree) throws IOException { - CompilationUnitTree tree2 = new StubMaker().translate(tree); - CompilationUnitTree tree3 = new ImportCleaner(fm).removeRedundantImports(tree2); - - String className = fm.inferBinaryName(StandardLocation.SOURCE_PATH, tree.getSourceFile()); - JavaFileObject fo = fm.getJavaFileForOutput(StandardLocation.SOURCE_OUTPUT, - className, JavaFileObject.Kind.SOURCE, null); - // System.err.println("Writing " + className + " to " + fo.getName()); - Writer out = fo.openWriter(); - try { - new Pretty(out, true).printExpr((JCTree) tree3); - } finally { - out.close(); - } - } - - List splitPath(String path) { - List list = new ArrayList(); - for (String p: path.split(File.pathSeparator)) { - if (p.length() > 0) - list.add(new File(p)); - } - return list; - } - - void error(String message) { - System.err.println(message); - errors++; - } - - void error(String message, Throwable cause) { - error(message); - } - - int errors; - - class StubMaker extends TreeTranslator { - CompilationUnitTree translate(CompilationUnitTree tree) { - return super.translate((JCCompilationUnit) tree); - } - - /** - * compilation units: remove javadoc comments - * -- required, in order to remove @deprecated tags, since we - * (separately) remove all annotations, including @Deprecated - */ - public void visitTopLevel(JCCompilationUnit tree) { - super.visitTopLevel(tree); - tree.docComments = Collections.emptyMap(); - } - - /** - * methods: remove method bodies, make methods native - */ - @Override - public void visitMethodDef(JCMethodDecl tree) { - tree.mods = translate(tree.mods); - tree.restype = translate(tree.restype); - tree.typarams = translateTypeParams(tree.typarams); - tree.params = translateVarDefs(tree.params); - tree.thrown = translate(tree.thrown); - if (tree.restype != null && tree.body != null) { - tree.mods.flags |= Flags.NATIVE; - tree.body = null; - } - result = tree; - } - - /** - * modifiers: remove annotations - */ - @Override - public void visitModifiers(JCModifiers tree) { - tree.annotations = com.sun.tools.javac.util.List.nil(); - result = tree; - } - - /** - * field definitions: replace initializers with 0, 0.0, false etc - * when possible -- i.e. leave public, protected initializers alone - */ - @Override - public void visitVarDef(JCVariableDecl tree) { - tree.mods = translate(tree.mods); - tree.vartype = translate(tree.vartype); - if (tree.init != null) { - if ((tree.mods.flags & (Flags.PUBLIC | Flags.PROTECTED)) != 0) - tree.init = translate(tree.init); - else { - String t = tree.vartype.toString(); - if (t.equals("boolean")) - tree.init = new JCLiteral(TypeTags.BOOLEAN, 0) { }; - else if (t.equals("byte")) - tree.init = new JCLiteral(TypeTags.BYTE, 0) { }; - else if (t.equals("char")) - tree.init = new JCLiteral(TypeTags.CHAR, 0) { }; - else if (t.equals("double")) - tree.init = new JCLiteral(TypeTags.DOUBLE, 0.d) { }; - else if (t.equals("float")) - tree.init = new JCLiteral(TypeTags.FLOAT, 0.f) { }; - else if (t.equals("int")) - tree.init = new JCLiteral(TypeTags.INT, 0) { }; - else if (t.equals("long")) - tree.init = new JCLiteral(TypeTags.LONG, 0) { }; - else if (t.equals("short")) - tree.init = new JCLiteral(TypeTags.SHORT, 0) { }; - else - tree.init = new JCLiteral(TypeTags.BOT, null) { }; - } - } - result = tree; - } - } - - class ImportCleaner extends TreeScanner { - private Set names = new HashSet(); - private TreeMaker m; - - ImportCleaner(JavaFileManager fm) { - // ImportCleaner itself doesn't require a filemanager, but instantiating - // a TreeMaker does, indirectly (via ClassReader, sigh) - Context c = new Context(); - c.put(JavaFileManager.class, fm); - m = TreeMaker.instance(c); - } - - CompilationUnitTree removeRedundantImports(CompilationUnitTree t) { - JCCompilationUnit tree = (JCCompilationUnit) t; - tree.accept(this); - ListBuffer defs = new ListBuffer(); - for (JCTree def: tree.defs) { - if (def.getTag() == JCTree.IMPORT) { - JCImport imp = (JCImport) def; - if (imp.qualid.getTag() == JCTree.SELECT) { - JCFieldAccess qualid = (JCFieldAccess) imp.qualid; - if (!qualid.name.toString().equals("*") - && !names.contains(qualid.name)) { - continue; - } - } - } - defs.add(def); - } - return m.TopLevel(tree.packageAnnotations, tree.pid, defs.toList()); - } - - @Override - public void visitImport(JCImport tree) { } // ignore names found in imports - - @Override - public void visitIdent(JCIdent tree) { - names.add(tree.name); - } - - @Override - public void visitSelect(JCFieldAccess tree) { - super.visitSelect(tree); - names.add(tree.name); - } - } - - //---------- Ant Invocation ------------------------------------------------ - - public static class Ant extends MatchingTask { - private File srcDir; - private File destDir; - private boolean fork; - private Path classpath; - private String includes; - - public void setSrcDir(File dir) { - this.srcDir = dir; - } - - public void setDestDir(File dir) { - this.destDir = dir; - } - - public void setFork(boolean v) { - this.fork = v; - } - - public void setClasspath(Path cp) { - if (classpath == null) - classpath = cp; - else - classpath.append(cp); - } - - public Path createClasspath() { - if (classpath == null) { - classpath = new Path(getProject()); - } - return classpath.createPath(); - } - - public void setClasspathRef(Reference r) { - createClasspath().setRefid(r); - } - - public void setIncludes(String includes) { - super.setIncludes(includes); - this.includes = includes; - } - - @Override - public void execute() { - if (includes != null && includes.trim().isEmpty()) - return; - - DirectoryScanner s = getDirectoryScanner(srcDir); - String[] files = s.getIncludedFiles(); -// System.err.println("Ant.execute: srcDir " + srcDir); -// System.err.println("Ant.execute: destDir " + destDir); -// System.err.println("Ant.execute: files " + Arrays.asList(files)); - - files = filter(srcDir, destDir, files); - if (files.length == 0) - return; - System.out.println("Generating " + files.length + " stub files to " + destDir); - - List classNames = new ArrayList(); - for (String file: files) { - classNames.add(file.replaceAll(".java$", "").replace('/', '.')); - } - - if (!fork) { - GenStubs m = new GenStubs(); - boolean ok = m.run(srcDir.getPath(), destDir, classNames); - if (!ok) - throw new BuildException("genstubs failed"); - } else { - List cmd = new ArrayList(); - String java_home = System.getProperty("java.home"); - cmd.add(new File(new File(java_home, "bin"), "java").getPath()); - if (classpath != null) - cmd.add("-Xbootclasspath/p:" + classpath); - cmd.add(GenStubs.class.getName()); - cmd.add("-sourcepath"); - cmd.add(srcDir.getPath()); - cmd.add("-s"); - cmd.add(destDir.getPath()); - cmd.addAll(classNames); - //System.err.println("GenStubs exec " + cmd); - ProcessBuilder pb = new ProcessBuilder(cmd); - pb.redirectErrorStream(true); - try { - Process p = pb.start(); - BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream())); - try { - String line; - while ((line = in.readLine()) != null) - System.out.println(line); - } finally { - in.close(); - } - int rc = p.waitFor(); - if (rc != 0) - throw new BuildException("genstubs failed"); - } catch (IOException e) { - throw new BuildException("genstubs failed", e); - } catch (InterruptedException e) { - throw new BuildException("genstubs failed", e); - } - } - } - - String[] filter(File srcDir, File destDir, String[] files) { - List results = new ArrayList(); - for (String f: files) { - long srcTime = new File(srcDir, f).lastModified(); - long destTime = new File(destDir, f).lastModified(); - if (srcTime > destTime) - results.add(f); - } - return results.toArray(new String[results.size()]); - } - } -} diff -r a1af4b95c287 -r 08a3425f39f8 make/tools/SelectTool/SelectToolTask.java --- a/make/tools/SelectTool/SelectToolTask.java Thu Mar 08 20:35:26 2012 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; -import java.awt.event.ItemEvent; -import java.awt.event.ItemListener; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Reader; -import java.io.Writer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Properties; -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JComboBox; -import javax.swing.JDialog; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JTextField; - -import javax.swing.SwingUtilities; -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.Task; - -/** - * Task to allow the user to control langtools tools built when using NetBeans. - * - * There are two primary modes. - * 1) Property mode. In this mode, property names are provided to get values - * that may be specified by the user, either directly in a GUI dialog, or - * read from a properties file. If the GUI dialog is invoked, values may - * optionally be set for future use. - * 2) Setup mode. In this mode, no property names are provided, and the GUI - * is invoked to allow the user to set or reset values for use in property mode. - */ -public class SelectToolTask extends Task { - /** - * Set the location of the private properties file used to keep the retain - * user preferences for this repository. - */ - public void setPropertyFile(File propertyFile) { - this.propertyFile = propertyFile; - } - - /** - * Set the name of the property which will be set to the name of the - * selected tool, if any. If no tool is selected, the property will - * remain unset. - */ - public void setToolProperty(String toolProperty) { - this.toolProperty = toolProperty; - } - - /** - * Set the name of the property which will be set to the execution args of the - * selected tool, if any. The args default to an empty string. - */ - public void setArgsProperty(String argsProperty) { - this.argsProperty = argsProperty; - } - - /** - * Specify whether or not to pop up a dialog if the user has not specified - * a default value for a property. - */ - public void setAskIfUnset(boolean askIfUnset) { - this.askIfUnset = askIfUnset; - } - - @Override - public void execute() { - Project p = getProject(); - - Properties props = readProperties(propertyFile); - toolName = props.getProperty("tool.name"); - if (toolName != null) { - toolArgs = props.getProperty(toolName + ".args", ""); - } - - if (toolProperty == null || - askIfUnset && (toolName == null - || (argsProperty != null && toolArgs == null))) { - showGUI(props); - } - - // finally, return required values, if any - if (toolProperty != null && !(toolName == null || toolName.equals(""))) { - p.setProperty(toolProperty, toolName); - - if (argsProperty != null && toolArgs != null) - p.setProperty(argsProperty, toolArgs); - } - } - - void showGUI(Properties fileProps) { - Properties guiProps = new Properties(fileProps); - JOptionPane p = createPane(guiProps); - p.createDialog("Select Tool").setVisible(true); - - toolName = (String) toolChoice.getSelectedItem(); - toolArgs = argsField.getText(); - - if (defaultCheck.isSelected()) { - if (toolName.equals("")) { - fileProps.remove("tool.name"); - } else { - fileProps.put("tool.name", toolName); - fileProps.put(toolName + ".args", toolArgs); - } - writeProperties(propertyFile, fileProps); - } - } - - JOptionPane createPane(final Properties props) { - JPanel body = new JPanel(new GridBagLayout()); - GridBagConstraints lc = new GridBagConstraints(); - lc.insets.right = 10; - lc.insets.bottom = 3; - GridBagConstraints fc = new GridBagConstraints(); - fc.anchor = GridBagConstraints.WEST; - fc.gridx = 1; - fc.gridwidth = GridBagConstraints.REMAINDER; - fc.insets.bottom = 3; - - JLabel toolLabel = new JLabel("Tool:"); - body.add(toolLabel, lc); - String[] toolChoices = { "apt", "javac", "javadoc", "javah", "javap" }; - if (true || toolProperty == null) { - // include empty value in setup mode - List l = new ArrayList(Arrays.asList(toolChoices)); - l.add(0, ""); - toolChoices = l.toArray(new String[l.size()]); - } - toolChoice = new JComboBox(toolChoices); - if (toolName != null) - toolChoice.setSelectedItem(toolName); - toolChoice.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - String tn = (String) e.getItem(); - argsField.setText(getDefaultArgsForTool(props, tn)); - if (toolProperty != null) - okButton.setEnabled(!tn.equals("")); - } - }); - body.add(toolChoice, fc); - - argsField = new JTextField(getDefaultArgsForTool(props, toolName), 40); - if (toolProperty == null || argsProperty != null) { - JLabel argsLabel = new JLabel("Args:"); - body.add(argsLabel, lc); - body.add(argsField, fc); - argsField.addFocusListener(new FocusListener() { - public void focusGained(FocusEvent e) { - } - public void focusLost(FocusEvent e) { - String toolName = (String) toolChoice.getSelectedItem(); - if (toolName.length() > 0) - props.put(toolName + ".args", argsField.getText()); - } - }); - } - - defaultCheck = new JCheckBox("Set as default"); - if (toolProperty == null) - defaultCheck.setSelected(true); - else - body.add(defaultCheck, fc); - - final JOptionPane p = new JOptionPane(body); - okButton = new JButton("OK"); - okButton.setEnabled(toolProperty == null || (toolName != null && !toolName.equals(""))); - okButton.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - JDialog d = (JDialog) SwingUtilities.getAncestorOfClass(JDialog.class, p); - d.setVisible(false); - } - }); - p.setOptions(new Object[] { okButton }); - - return p; - } - - Properties readProperties(File file) { - Properties p = new Properties(); - if (file != null && file.exists()) { - Reader in = null; - try { - in = new BufferedReader(new FileReader(file)); - p.load(in); - in.close(); - } catch (IOException e) { - throw new BuildException("error reading property file", e); - } finally { - if (in != null) { - try { - in.close(); - } catch (IOException e) { - throw new BuildException("cannot close property file", e); - } - } - } - } - return p; - } - - void writeProperties(File file, Properties p) { - if (file != null) { - Writer out = null; - try { - File dir = file.getParentFile(); - if (dir != null && !dir.exists()) - dir.mkdirs(); - out = new BufferedWriter(new FileWriter(file)); - p.store(out, "langtools properties"); - out.close(); - } catch (IOException e) { - throw new BuildException("error writing property file", e); - } finally { - if (out != null) { - try { - out.close(); - } catch (IOException e) { - throw new BuildException("cannot close property file", e); - } - } - } - } - } - - String getDefaultArgsForTool(Properties props, String tn) { - return (tn == null || tn.equals("")) ? "" : props.getProperty(tn + ".args", ""); - } - - // Ant task parameters - private boolean askIfUnset; - private String toolProperty; - private String argsProperty; - private File propertyFile; - - // GUI components - private JComboBox toolChoice; - private JTextField argsField; - private JCheckBox defaultCheck; - private JButton okButton; - - // Result values for the client - private String toolName; - private String toolArgs; -} diff -r a1af4b95c287 -r 08a3425f39f8 make/tools/anttasks/CompilePropertiesTask.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/tools/anttasks/CompilePropertiesTask.java Fri Mar 09 11:59:26 2012 -0800 @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2007, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package anttasks; + +import compileproperties.CompileProperties; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.MatchingTask; + +public class CompilePropertiesTask extends MatchingTask { + public void setSrcDir(File srcDir) { + this.srcDir = srcDir; + } + + public void setDestDir(File destDir) { + this.destDir = destDir; + } + + public void setSuperclass(String superclass) { + this.superclass = superclass; + } + + @Override + public void execute() { + CompileProperties.Log log = new CompileProperties.Log() { + public void error(String msg, Exception e) { + log(msg, Project.MSG_ERR); + } + public void info(String msg) { + log(msg, Project.MSG_INFO); + } + public void verbose(String msg) { + log(msg, Project.MSG_VERBOSE); + } + }; + List mainOpts = new ArrayList(); + int count = 0; + DirectoryScanner s = getDirectoryScanner(srcDir); + for (String path: s.getIncludedFiles()) { + if (path.endsWith(".properties")) { + String destPath = + path.substring(0, path.length() - ".properties".length()) + + ".java"; + File srcFile = new File(srcDir, path); + File destFile = new File(destDir, destPath); + // Arguably, the comparison in the next line should be ">", not ">=" + // but that assumes the resolution of the last modified time is fine + // grained enough; in practice, it is better to use ">=". + if (destFile.exists() && destFile.lastModified() >= srcFile.lastModified()) + continue; + destFile.getParentFile().mkdirs(); + mainOpts.add("-compile"); + mainOpts.add(srcFile.getPath()); + mainOpts.add(destFile.getPath()); + mainOpts.add(superclass); + count++; + } + } + if (mainOpts.size() > 0) { + log("Generating " + count + " resource files to " + destDir, Project.MSG_INFO); + CompileProperties cp = new CompileProperties(); + cp.setLog(log); + boolean ok = cp.run(mainOpts.toArray(new String[mainOpts.size()])); + if (!ok) + throw new BuildException("CompileProperties failed."); + } + } + + private File srcDir; + private File destDir; + private String superclass = "java.util.ListResourceBundle"; +} diff -r a1af4b95c287 -r 08a3425f39f8 make/tools/anttasks/GenStubsTask.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/tools/anttasks/GenStubsTask.java Fri Mar 09 11:59:26 2012 -0800 @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2009, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package anttasks; + +import genstubs.GenStubs; + +import java.io.*; +import java.util.*; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.taskdefs.MatchingTask; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.types.Reference; + +/** + * Files are specified with an implicit fileset, using srcdir as a base directory. + * The set of files to be included is specified with an includes attribute or + * nested set. However, unlike a normal fileset, an empty includes attribute + * means "no files" instead of "all files". The Ant task also accepts "fork=true" and + * classpath attribute or nested element to run GenStubs in a separate VM + * with the specified path. This is likely necessary if a JDK 7 parser is required to read the + * JDK 7 input files. + */ +public class GenStubsTask extends MatchingTask { + private File srcDir; + private File destDir; + private boolean fork; + private Path classpath; + private String includes; + + public void setSrcDir(File dir) { + this.srcDir = dir; + } + + public void setDestDir(File dir) { + this.destDir = dir; + } + + public void setFork(boolean v) { + this.fork = v; + } + + public void setClasspath(Path cp) { + if (classpath == null) + classpath = cp; + else + classpath.append(cp); + } + + public Path createClasspath() { + if (classpath == null) { + classpath = new Path(getProject()); + } + return classpath.createPath(); + } + + public void setClasspathRef(Reference r) { + createClasspath().setRefid(r); + } + + public void setIncludes(String includes) { + super.setIncludes(includes); + this.includes = includes; + } + + @Override + public void execute() { + if (includes != null && includes.trim().isEmpty()) + return; + + DirectoryScanner s = getDirectoryScanner(srcDir); + String[] files = s.getIncludedFiles(); +// System.err.println("Ant.execute: srcDir " + srcDir); +// System.err.println("Ant.execute: destDir " + destDir); +// System.err.println("Ant.execute: files " + Arrays.asList(files)); + + files = filter(srcDir, destDir, files); + if (files.length == 0) + return; + System.out.println("Generating " + files.length + " stub files to " + destDir); + + List classNames = new ArrayList(); + for (String file: files) { + classNames.add(file.replaceAll(".java$", "").replace('/', '.')); + } + + if (!fork) { + GenStubs m = new GenStubs(); + boolean ok = m.run(srcDir.getPath(), destDir, classNames); + if (!ok) + throw new BuildException("genstubs failed"); + } else { + List cmd = new ArrayList(); + String java_home = System.getProperty("java.home"); + cmd.add(new File(new File(java_home, "bin"), "java").getPath()); + if (classpath != null) + cmd.add("-Xbootclasspath/p:" + classpath); + cmd.add(GenStubs.class.getName()); + cmd.add("-sourcepath"); + cmd.add(srcDir.getPath()); + cmd.add("-s"); + cmd.add(destDir.getPath()); + cmd.addAll(classNames); + //System.err.println("GenStubs exec " + cmd); + ProcessBuilder pb = new ProcessBuilder(cmd); + pb.redirectErrorStream(true); + try { + Process p = pb.start(); + BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream())); + try { + String line; + while ((line = in.readLine()) != null) + System.out.println(line); + } finally { + in.close(); + } + int rc = p.waitFor(); + if (rc != 0) + throw new BuildException("genstubs failed"); + } catch (IOException e) { + throw new BuildException("genstubs failed", e); + } catch (InterruptedException e) { + throw new BuildException("genstubs failed", e); + } + } + } + + String[] filter(File srcDir, File destDir, String[] files) { + List results = new ArrayList(); + for (String f: files) { + long srcTime = new File(srcDir, f).lastModified(); + long destTime = new File(destDir, f).lastModified(); + if (srcTime > destTime) + results.add(f); + } + return results.toArray(new String[results.size()]); + } +} diff -r a1af4b95c287 -r 08a3425f39f8 make/tools/anttasks/SelectToolTask.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/tools/anttasks/SelectToolTask.java Fri Mar 09 11:59:26 2012 -0800 @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2008, 2009, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package anttasks; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTextField; + +import javax.swing.SwingUtilities; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; + +/** + * Task to allow the user to control langtools tools built when using NetBeans. + * + * There are two primary modes. + * 1) Property mode. In this mode, property names are provided to get values + * that may be specified by the user, either directly in a GUI dialog, or + * read from a properties file. If the GUI dialog is invoked, values may + * optionally be set for future use. + * 2) Setup mode. In this mode, no property names are provided, and the GUI + * is invoked to allow the user to set or reset values for use in property mode. + */ +public class SelectToolTask extends Task { + /** + * Set the location of the private properties file used to keep the retain + * user preferences for this repository. + */ + public void setPropertyFile(File propertyFile) { + this.propertyFile = propertyFile; + } + + /** + * Set the name of the property which will be set to the name of the + * selected tool, if any. If no tool is selected, the property will + * remain unset. + */ + public void setToolProperty(String toolProperty) { + this.toolProperty = toolProperty; + } + + /** + * Set the name of the property which will be set to the execution args of the + * selected tool, if any. The args default to an empty string. + */ + public void setArgsProperty(String argsProperty) { + this.argsProperty = argsProperty; + } + + /** + * Specify whether or not to pop up a dialog if the user has not specified + * a default value for a property. + */ + public void setAskIfUnset(boolean askIfUnset) { + this.askIfUnset = askIfUnset; + } + + @Override + public void execute() { + Project p = getProject(); + + Properties props = readProperties(propertyFile); + toolName = props.getProperty("tool.name"); + if (toolName != null) { + toolArgs = props.getProperty(toolName + ".args", ""); + } + + if (toolProperty == null || + askIfUnset && (toolName == null + || (argsProperty != null && toolArgs == null))) { + showGUI(props); + } + + // finally, return required values, if any + if (toolProperty != null && !(toolName == null || toolName.equals(""))) { + p.setProperty(toolProperty, toolName); + + if (argsProperty != null && toolArgs != null) + p.setProperty(argsProperty, toolArgs); + } + } + + void showGUI(Properties fileProps) { + Properties guiProps = new Properties(fileProps); + JOptionPane p = createPane(guiProps); + p.createDialog("Select Tool").setVisible(true); + + toolName = (String) toolChoice.getSelectedItem(); + toolArgs = argsField.getText(); + + if (defaultCheck.isSelected()) { + if (toolName.equals("")) { + fileProps.remove("tool.name"); + } else { + fileProps.put("tool.name", toolName); + fileProps.put(toolName + ".args", toolArgs); + } + writeProperties(propertyFile, fileProps); + } + } + + JOptionPane createPane(final Properties props) { + JPanel body = new JPanel(new GridBagLayout()); + GridBagConstraints lc = new GridBagConstraints(); + lc.insets.right = 10; + lc.insets.bottom = 3; + GridBagConstraints fc = new GridBagConstraints(); + fc.anchor = GridBagConstraints.WEST; + fc.gridx = 1; + fc.gridwidth = GridBagConstraints.REMAINDER; + fc.insets.bottom = 3; + + JLabel toolLabel = new JLabel("Tool:"); + body.add(toolLabel, lc); + String[] toolChoices = { "apt", "javac", "javadoc", "javah", "javap" }; + if (true || toolProperty == null) { + // include empty value in setup mode + List l = new ArrayList(Arrays.asList(toolChoices)); + l.add(0, ""); + toolChoices = l.toArray(new String[l.size()]); + } + toolChoice = new JComboBox(toolChoices); + if (toolName != null) + toolChoice.setSelectedItem(toolName); + toolChoice.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + String tn = (String) e.getItem(); + argsField.setText(getDefaultArgsForTool(props, tn)); + if (toolProperty != null) + okButton.setEnabled(!tn.equals("")); + } + }); + body.add(toolChoice, fc); + + argsField = new JTextField(getDefaultArgsForTool(props, toolName), 40); + if (toolProperty == null || argsProperty != null) { + JLabel argsLabel = new JLabel("Args:"); + body.add(argsLabel, lc); + body.add(argsField, fc); + argsField.addFocusListener(new FocusListener() { + public void focusGained(FocusEvent e) { + } + public void focusLost(FocusEvent e) { + String toolName = (String) toolChoice.getSelectedItem(); + if (toolName.length() > 0) + props.put(toolName + ".args", argsField.getText()); + } + }); + } + + defaultCheck = new JCheckBox("Set as default"); + if (toolProperty == null) + defaultCheck.setSelected(true); + else + body.add(defaultCheck, fc); + + final JOptionPane p = new JOptionPane(body); + okButton = new JButton("OK"); + okButton.setEnabled(toolProperty == null || (toolName != null && !toolName.equals(""))); + okButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + JDialog d = (JDialog) SwingUtilities.getAncestorOfClass(JDialog.class, p); + d.setVisible(false); + } + }); + p.setOptions(new Object[] { okButton }); + + return p; + } + + Properties readProperties(File file) { + Properties p = new Properties(); + if (file != null && file.exists()) { + Reader in = null; + try { + in = new BufferedReader(new FileReader(file)); + p.load(in); + in.close(); + } catch (IOException e) { + throw new BuildException("error reading property file", e); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + throw new BuildException("cannot close property file", e); + } + } + } + } + return p; + } + + void writeProperties(File file, Properties p) { + if (file != null) { + Writer out = null; + try { + File dir = file.getParentFile(); + if (dir != null && !dir.exists()) + dir.mkdirs(); + out = new BufferedWriter(new FileWriter(file)); + p.store(out, "langtools properties"); + out.close(); + } catch (IOException e) { + throw new BuildException("error writing property file", e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException e) { + throw new BuildException("cannot close property file", e); + } + } + } + } + } + + String getDefaultArgsForTool(Properties props, String tn) { + return (tn == null || tn.equals("")) ? "" : props.getProperty(tn + ".args", ""); + } + + // Ant task parameters + private boolean askIfUnset; + private String toolProperty; + private String argsProperty; + private File propertyFile; + + // GUI components + private JComboBox toolChoice; + private JTextField argsField; + private JCheckBox defaultCheck; + private JButton okButton; + + // Result values for the client + private String toolName; + private String toolArgs; +} diff -r a1af4b95c287 -r 08a3425f39f8 make/tools/compileproperties/CompileProperties.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/tools/compileproperties/CompileProperties.java Fri Mar 09 11:59:26 2012 -0800 @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2002, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compileproperties; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; + +/** Translates a .properties file into a .java file containing the + * definition of a java.util.Properties subclass which can then be + * compiled with javac.

+ * + * Usage: java CompileProperties [path to .properties file] [path to .java file to be output] [super class] + * + * Infers the package by looking at the common suffix of the two + * inputs, eliminating "classes" from it. + * + * @author Scott Violet + * @author Kenneth Russell + */ + +public class CompileProperties { + + public static void main(String[] args) { + CompileProperties cp = new CompileProperties(); + boolean ok = cp.run(args); + if ( !ok ) { + System.exit(1); + } + } + + public static interface Log { + void info(String msg); + void verbose(String msg); + void error(String msg, Exception e); + } + + private String propfiles[]; + private String outfiles[] ; + private String supers[] ; + private int compileCount = 0; + private boolean quiet = false; + public Log log; + + public void setLog(Log log) { + this.log = log; + } + + public boolean run(String[] args) { + if (log == null) { + log = new Log() { + public void error(String msg, Exception e) { + System.err.println("ERROR: CompileProperties: " + msg); + if ( e != null ) { + System.err.println("EXCEPTION: " + e.toString()); + e.printStackTrace(); + } + } + public void info(String msg) { + System.out.println(msg); + } + public void verbose(String msg) { + if (!quiet) + System.out.println(msg); + } + }; + } + + boolean ok = true; + /* Original usage */ + if (args.length == 2 && args[0].charAt(0) != '-' ) { + ok = createFile(args[0], args[1], "java.util.ListResourceBundle"); + } else if (args.length == 3) { + ok = createFile(args[0], args[1], args[2]); + } else if (args.length == 0) { + usage(log); + ok = false; + } else { + /* New batch usage */ + ok = parseOptions(args); + if ( ok && compileCount == 0 ) { + log.error("options parsed but no files to compile", null); + ok = false; + } + /* Need at least one file. */ + if ( !ok ) { + usage(log); + } else { + /* Process files */ + for ( int i = 0; i < compileCount && ok ; i++ ) { + ok = createFile(propfiles[i], outfiles[i], supers[i]); + } + } + } + return ok; + } + + private boolean parseOptions(String args[]) { + boolean ok = true; + if ( compileCount > 0 ) { + String new_propfiles[] = new String[compileCount + args.length]; + String new_outfiles[] = new String[compileCount + args.length]; + String new_supers[] = new String[compileCount + args.length]; + System.arraycopy(propfiles, 0, new_propfiles, 0, compileCount); + System.arraycopy(outfiles, 0, new_outfiles, 0, compileCount); + System.arraycopy(supers, 0, new_supers, 0, compileCount); + propfiles = new_propfiles; + outfiles = new_outfiles; + supers = new_supers; + } else { + propfiles = new String[args.length]; + outfiles = new String[args.length]; + supers = new String[args.length]; + } + + for ( int i = 0; i < args.length ; i++ ) { + if ( "-compile".equals(args[i]) && i+3 < args.length ) { + propfiles[compileCount] = args[++i]; + outfiles[compileCount] = args[++i]; + supers[compileCount] = args[++i]; + compileCount++; + } else if ( "-optionsfile".equals(args[i]) && i+1 < args.length ) { + String filename = args[++i]; + FileInputStream finput = null; + byte contents[] = null; + try { + finput = new FileInputStream(filename); + int byteCount = finput.available(); + if ( byteCount <= 0 ) { + log.error("The -optionsfile file is empty", null); + ok = false; + } else { + contents = new byte[byteCount]; + int bytesRead = finput.read(contents); + if ( byteCount != bytesRead ) { + log.error("Cannot read all of -optionsfile file", null); + ok = false; + } + } + } catch ( IOException e ) { + log.error("cannot open " + filename, e); + ok = false; + } + if ( finput != null ) { + try { + finput.close(); + } catch ( IOException e ) { + ok = false; + log.error("cannot close " + filename, e); + } + } + if ( ok = true && contents != null ) { + String tokens[] = (new String(contents)).split("\\s+"); + if ( tokens.length > 0 ) { + ok = parseOptions(tokens); + } + } + if ( !ok ) { + break; + } + } else if ( "-quiet".equals(args[i]) ) { + quiet = true; + } else { + log.error("argument error", null); + ok = false; + } + } + return ok; + } + + private boolean createFile(String propertiesPath, String outputPath, + String superClass) { + boolean ok = true; + log.verbose("parsing: " + propertiesPath); + Properties p = new Properties(); + try { + p.load(new FileInputStream(propertiesPath)); + } catch ( FileNotFoundException e ) { + ok = false; + log.error("Cannot find file " + propertiesPath, e); + } catch ( IOException e ) { + ok = false; + log.error("IO error on file " + propertiesPath, e); + } + if ( ok ) { + String packageName = inferPackageName(propertiesPath, outputPath); + log.verbose("inferred package name: " + packageName); + List sortedKeys = new ArrayList(); + for ( Object key : p.keySet() ) { + sortedKeys.add((String)key); + } + Collections.sort(sortedKeys); + Iterator keys = sortedKeys.iterator(); + + StringBuffer data = new StringBuffer(); + + while (keys.hasNext()) { + String key = keys.next(); + data.append(" { \"" + escape(key) + "\", \"" + + escape((String)p.get(key)) + "\" },\n"); + } + + // Get class name from java filename, not the properties filename. + // (zh_TW properties might be used to create zh_HK files) + File file = new File(outputPath); + String name = file.getName(); + int dotIndex = name.lastIndexOf('.'); + String className; + if (dotIndex == -1) { + className = name; + } else { + className = name.substring(0, dotIndex); + } + + String packageString = ""; + if (packageName != null && !packageName.equals("")) { + packageString = "package " + packageName + ";\n\n"; + } + + Writer writer = null; + try { + writer = new BufferedWriter( + new OutputStreamWriter(new FileOutputStream(outputPath), "8859_1")); + MessageFormat format = new MessageFormat(FORMAT); + writer.write(format.format(new Object[] { packageString, className, superClass, data })); + } catch ( IOException e ) { + ok = false; + log.error("IO error writing to file " + outputPath, e); + } + if ( writer != null ) { + try { + writer.flush(); + } catch ( IOException e ) { + ok = false; + log.error("IO error flush " + outputPath, e); + } + try { + writer.close(); + } catch ( IOException e ) { + ok = false; + log.error("IO error close " + outputPath, e); + } + } + log.verbose("wrote: " + outputPath); + } + return ok; + } + + private static void usage(Log log) { + log.info("usage:"); + log.info(" java CompileProperties path_to_properties_file path_to_java_output_file [super_class]"); + log.info(" -OR-"); + log.info(" java CompileProperties {-compile path_to_properties_file path_to_java_output_file super_class} -or- -optionsfile filename"); + log.info(""); + log.info("Example:"); + log.info(" java CompileProperties -compile test.properties test.java java.util.ListResourceBundle"); + log.info(" java CompileProperties -optionsfile option_file"); + log.info("option_file contains: -compile test.properties test.java java.util.ListResourceBundle"); + } + + private static String escape(String theString) { + // This is taken from Properties.saveConvert with changes for Java strings + int len = theString.length(); + StringBuffer outBuffer = new StringBuffer(len*2); + + for(int x=0; x 0x007e)) { + outBuffer.append('\\'); + outBuffer.append('u'); + outBuffer.append(toHex((aChar >> 12) & 0xF)); + outBuffer.append(toHex((aChar >> 8) & 0xF)); + outBuffer.append(toHex((aChar >> 4) & 0xF)); + outBuffer.append(toHex( aChar & 0xF)); + } else { + if (specialSaveChars.indexOf(aChar) != -1) { + outBuffer.append('\\'); + } + outBuffer.append(aChar); + } + } + } + return outBuffer.toString(); + } + + private static String inferPackageName(String inputPath, String outputPath) { + // Normalize file names + inputPath = new File(inputPath).getPath(); + outputPath = new File(outputPath).getPath(); + // Split into components + String sep; + if (File.separatorChar == '\\') { + sep = "\\\\"; + } else { + sep = File.separator; + } + String[] inputs = inputPath.split(sep); + String[] outputs = outputPath.split(sep); + // Match common names, eliminating first "classes" entry from + // each if present + int inStart = 0; + int inEnd = inputs.length - 2; + int outEnd = outputs.length - 2; + int i = inEnd; + int j = outEnd; + while (i >= 0 && j >= 0) { + if (!inputs[i].equals(outputs[j]) || + (inputs[i].equals("gensrc") && inputs[j].equals("gensrc"))) { + ++i; + ++j; + break; + } + --i; + --j; + } + String result; + if (i < 0 || j < 0 || i >= inEnd || j >= outEnd) { + result = ""; + } else { + if (inputs[i].equals("classes") && outputs[j].equals("classes")) { + ++i; + } + inStart = i; + StringBuffer buf = new StringBuffer(); + for (i = inStart; i <= inEnd; i++) { + buf.append(inputs[i]); + if (i < inEnd) { + buf.append('.'); + } + } + result = buf.toString(); + } + return result; + } + + private static final String FORMAT = + "{0}" + + "public final class {1} extends {2} '{'\n" + + " protected final Object[][] getContents() '{'\n" + + " return new Object[][] '{'\n" + + "{3}" + + " };\n" + + " }\n" + + "}\n"; + + // This comes from Properties + private static char toHex(int nibble) { + return hexDigit[(nibble & 0xF)]; + } + + // This comes from Properties + private static final char[] hexDigit = { + '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' + }; + + // Note: different from that in Properties + private static final String specialSaveChars = "\""; +} diff -r a1af4b95c287 -r 08a3425f39f8 make/tools/genstubs/GenStubs.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/make/tools/genstubs/GenStubs.java Fri Mar 09 11:59:26 2012 -0800 @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2009, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package genstubs; + +import java.io.*; +import java.util.*; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.StandardLocation; + +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.util.JavacTask; +import com.sun.tools.javac.api.JavacTool; +import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.code.TypeTags; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.tree.JCTree.JCFieldAccess; +import com.sun.tools.javac.tree.JCTree.JCIdent; +import com.sun.tools.javac.tree.JCTree.JCImport; +import com.sun.tools.javac.tree.JCTree.JCLiteral; +import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCModifiers; +import com.sun.tools.javac.tree.JCTree.JCVariableDecl; +import com.sun.tools.javac.tree.Pretty; +import com.sun.tools.javac.tree.TreeMaker; +import com.sun.tools.javac.tree.TreeScanner; +import com.sun.tools.javac.tree.TreeTranslator; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.ListBuffer; +import com.sun.tools.javac.util.Name; +import javax.tools.JavaFileManager; + +/** + * Generate stub source files by removing implementation details from input files. + * + * This is a special purpose stub generator, specific to the needs of generating + * stub files for JDK 7 API that are needed to compile langtools files that depend + * on that API. The stub generator works by removing as much of the API source code + * as possible without affecting the public signature, in order to reduce the + * transitive closure of the API being referenced. The resulting stubs can be + * put on the langtools sourcepath with -implicit:none to compile the langtools + * files that depend on the JDK 7 API. + * + * Usage: + * genstubs -s -sourcepath + * + * The specified class names are looked up on the sourcepath, and corresponding + * stubs are written to the source output directory. + * + * Classes are parsed into javac ASTs, then processed with a javac TreeTranslator + * to remove implementation details, and written out in the source output directory. + * Documentation comments and annotations are removed. Method bodies are removed + * and methods are marked native. Private and package-private field definitions + * have their initializers replace with 0, 0.0, false, null as appropriate. + */ + +public class GenStubs { + static class Fault extends Exception { + private static final long serialVersionUID = 0; + Fault(String message) { + super(message); + } + Fault(String message, Throwable cause) { + super(message); + initCause(cause); + } + } + + public static void main(String[] args) { + boolean ok = new GenStubs().run(args); + if (!ok) + System.exit(1); + } + + public boolean run(String... args) { + File outdir = null; + String sourcepath = null; + List classes = new ArrayList(); + for (ListIterator iter = Arrays.asList(args).listIterator(); iter.hasNext(); ) { + String arg = iter.next(); + if (arg.equals("-s") && iter.hasNext()) + outdir = new File(iter.next()); + else if (arg.equals("-sourcepath") && iter.hasNext()) + sourcepath = iter.next(); + else if (arg.startsWith("-")) + throw new IllegalArgumentException(arg); + else { + classes.add(arg); + while (iter.hasNext()) + classes.add(iter.next()); + } + } + + return run(sourcepath, outdir, classes); + } + + public boolean run(String sourcepath, File outdir, List classes) { + //System.err.println("run: sourcepath:" + sourcepath + " outdir:" + outdir + " classes:" + classes); + if (sourcepath == null) + throw new IllegalArgumentException("sourcepath not set"); + if (outdir == null) + throw new IllegalArgumentException("source output dir not set"); + + JavacTool tool = JavacTool.create(); + StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null); + + try { + fm.setLocation(StandardLocation.SOURCE_OUTPUT, Collections.singleton(outdir)); + fm.setLocation(StandardLocation.SOURCE_PATH, splitPath(sourcepath)); + List files = new ArrayList(); + for (String c: classes) { + JavaFileObject fo = fm.getJavaFileForInput( + StandardLocation.SOURCE_PATH, c, JavaFileObject.Kind.SOURCE); + if (fo == null) + error("class not found: " + c); + else + files.add(fo); + } + + JavacTask t = tool.getTask(null, fm, null, null, null, files); + Iterable trees = t.parse(); + for (CompilationUnitTree tree: trees) { + makeStub(fm, tree); + } + } catch (IOException e) { + error("IO error " + e, e); + } + + return (errors == 0); + } + + void makeStub(StandardJavaFileManager fm, CompilationUnitTree tree) throws IOException { + CompilationUnitTree tree2 = new StubMaker().translate(tree); + CompilationUnitTree tree3 = new ImportCleaner(fm).removeRedundantImports(tree2); + + String className = fm.inferBinaryName(StandardLocation.SOURCE_PATH, tree.getSourceFile()); + JavaFileObject fo = fm.getJavaFileForOutput(StandardLocation.SOURCE_OUTPUT, + className, JavaFileObject.Kind.SOURCE, null); + // System.err.println("Writing " + className + " to " + fo.getName()); + Writer out = fo.openWriter(); + try { + new Pretty(out, true).printExpr((JCTree) tree3); + } finally { + out.close(); + } + } + + List splitPath(String path) { + List list = new ArrayList(); + for (String p: path.split(File.pathSeparator)) { + if (p.length() > 0) + list.add(new File(p)); + } + return list; + } + + void error(String message) { + System.err.println(message); + errors++; + } + + void error(String message, Throwable cause) { + error(message); + } + + int errors; + + class StubMaker extends TreeTranslator { + CompilationUnitTree translate(CompilationUnitTree tree) { + return super.translate((JCCompilationUnit) tree); + } + + /** + * compilation units: remove javadoc comments + * -- required, in order to remove @deprecated tags, since we + * (separately) remove all annotations, including @Deprecated + */ + public void visitTopLevel(JCCompilationUnit tree) { + super.visitTopLevel(tree); + tree.docComments = Collections.emptyMap(); + } + + /** + * methods: remove method bodies, make methods native + */ + @Override + public void visitMethodDef(JCMethodDecl tree) { + tree.mods = translate(tree.mods); + tree.restype = translate(tree.restype); + tree.typarams = translateTypeParams(tree.typarams); + tree.params = translateVarDefs(tree.params); + tree.thrown = translate(tree.thrown); + if (tree.restype != null && tree.body != null) { + tree.mods.flags |= Flags.NATIVE; + tree.body = null; + } + result = tree; + } + + /** + * modifiers: remove annotations + */ + @Override + public void visitModifiers(JCModifiers tree) { + tree.annotations = com.sun.tools.javac.util.List.nil(); + result = tree; + } + + /** + * field definitions: replace initializers with 0, 0.0, false etc + * when possible -- i.e. leave public, protected initializers alone + */ + @Override + public void visitVarDef(JCVariableDecl tree) { + tree.mods = translate(tree.mods); + tree.vartype = translate(tree.vartype); + if (tree.init != null) { + if ((tree.mods.flags & (Flags.PUBLIC | Flags.PROTECTED)) != 0) + tree.init = translate(tree.init); + else { + String t = tree.vartype.toString(); + if (t.equals("boolean")) + tree.init = new JCLiteral(TypeTags.BOOLEAN, 0) { }; + else if (t.equals("byte")) + tree.init = new JCLiteral(TypeTags.BYTE, 0) { }; + else if (t.equals("char")) + tree.init = new JCLiteral(TypeTags.CHAR, 0) { }; + else if (t.equals("double")) + tree.init = new JCLiteral(TypeTags.DOUBLE, 0.d) { }; + else if (t.equals("float")) + tree.init = new JCLiteral(TypeTags.FLOAT, 0.f) { }; + else if (t.equals("int")) + tree.init = new JCLiteral(TypeTags.INT, 0) { }; + else if (t.equals("long")) + tree.init = new JCLiteral(TypeTags.LONG, 0) { }; + else if (t.equals("short")) + tree.init = new JCLiteral(TypeTags.SHORT, 0) { }; + else + tree.init = new JCLiteral(TypeTags.BOT, null) { }; + } + } + result = tree; + } + } + + class ImportCleaner extends TreeScanner { + private Set names = new HashSet(); + private TreeMaker m; + + ImportCleaner(JavaFileManager fm) { + // ImportCleaner itself doesn't require a filemanager, but instantiating + // a TreeMaker does, indirectly (via ClassReader, sigh) + Context c = new Context(); + c.put(JavaFileManager.class, fm); + m = TreeMaker.instance(c); + } + + CompilationUnitTree removeRedundantImports(CompilationUnitTree t) { + JCCompilationUnit tree = (JCCompilationUnit) t; + tree.accept(this); + ListBuffer defs = new ListBuffer(); + for (JCTree def: tree.defs) { + if (def.getTag() == JCTree.Tag.IMPORT) { + JCImport imp = (JCImport) def; + if (imp.qualid.getTag() == JCTree.Tag.SELECT) { + JCFieldAccess qualid = (JCFieldAccess) imp.qualid; + if (!qualid.name.toString().equals("*") + && !names.contains(qualid.name)) { + continue; + } + } + } + defs.add(def); + } + return m.TopLevel(tree.packageAnnotations, tree.pid, defs.toList()); + } + + @Override + public void visitImport(JCImport tree) { } // ignore names found in imports + + @Override + public void visitIdent(JCIdent tree) { + names.add(tree.name); + } + + @Override + public void visitSelect(JCFieldAccess tree) { + super.visitSelect(tree); + names.add(tree.name); + } + } +} diff -r a1af4b95c287 -r 08a3425f39f8 src/share/classes/com/sun/tools/javac/code/Symbol.java --- a/src/share/classes/com/sun/tools/javac/code/Symbol.java Thu Mar 08 20:35:26 2012 -0800 +++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java Fri Mar 09 11:59:26 2012 -0800 @@ -1235,7 +1235,7 @@ // if origin is derived from a raw type, we might have missed // an implementation because we do not know enough about instantiations. // in this case continue with the supertype as origin. - if (types.isDerivedRaw(origin.type)) + if (types.isDerivedRaw(origin.type) && !origin.isInterface()) return implementation(types.supertype(origin.type).tsym, types, checkResult); else return null; diff -r a1af4b95c287 -r 08a3425f39f8 src/share/classes/com/sun/tools/javac/comp/Attr.java --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Mar 08 20:35:26 2012 -0800 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Mar 09 11:59:26 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012, 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 @@ -199,16 +199,15 @@ * @param tree The tree whose kind and type is checked * @param owntype The computed type of the tree * @param ownkind The computed kind of the tree - * @param pkind The expected kind (or: protokind) of the tree - * @param pt The expected type (or: prototype) of the tree + * @param resultInfo The expected result of the tree */ - Type check(JCTree tree, Type owntype, int ownkind, int pkind, Type pt) { - if (owntype.tag != ERROR && pt.tag != METHOD && pt.tag != FORALL) { - if ((ownkind & ~pkind) == 0) { - owntype = chk.checkType(tree.pos(), owntype, pt, errKey); + Type check(JCTree tree, Type owntype, int ownkind, ResultInfo resultInfo) { + if (owntype.tag != ERROR && resultInfo.pt.tag != METHOD && resultInfo.pt.tag != FORALL) { + if ((ownkind & ~resultInfo.pkind) == 0) { + owntype = chk.checkType(tree.pos(), owntype, resultInfo.pt, errKey); } else { log.error(tree.pos(), "unexpected.type", - kindNames(pkind), + kindNames(resultInfo.pkind), kindName(ownkind)); owntype = types.createErrorType(owntype); } @@ -333,7 +332,16 @@ public Type attribType(JCTree node, TypeSymbol sym) { Env env = enter.typeEnvs.get(sym); Env localEnv = env.dup(node, env.info.dup()); - return attribTree(node, localEnv, Kinds.TYP, Type.noType); + return attribTree(node, localEnv, unknownTypeInfo); + } + + public Type attribImportQualifier(JCImport tree, Env env) { + // Attribute qualifying package or class. + JCFieldAccess s = (JCFieldAccess)tree.qualid; + return attribTree(s.selected, + env, + new ResultInfo(tree.staticImport ? TYP : (TYP | PCK), + Type.noType)); } public Env attribExprToTree(JCTree expr, Env env, JCTree tree) { @@ -386,6 +394,28 @@ } } + static class ResultInfo { + int pkind; + Type pt; + + ResultInfo(int pkind, Type pt) { + this.pkind = pkind; + this.pt = pt; + } + } + + private final ResultInfo statInfo = new ResultInfo(NIL, Type.noType); + private final ResultInfo varInfo = new ResultInfo(VAR, Type.noType); + private final ResultInfo unknownExprInfo = new ResultInfo(VAL, Type.noType); + private final ResultInfo unknownTypeInfo = new ResultInfo(TYP, Type.noType); + + Type pt() { + return resultInfo.pt; + } + + int pkind() { + return resultInfo.pkind; + } /* ************************************************************************ * Visitor methods @@ -395,13 +425,9 @@ */ Env env; - /** Visitor argument: the currently expected proto-kind. + /** Visitor argument: the currently expected attribution result. */ - int pkind; - - /** Visitor argument: the currently expected proto-type. - */ - Type pt; + ResultInfo resultInfo; /** Visitor argument: the error key to be generated when a type error occurs */ @@ -416,22 +442,19 @@ * * @param tree The tree to be visited. * @param env The environment visitor argument. - * @param pkind The protokind visitor argument. - * @param pt The prototype visitor argument. + * @param resultInfo The result info visitor argument. */ - Type attribTree(JCTree tree, Env env, int pkind, Type pt) { - return attribTree(tree, env, pkind, pt, "incompatible.types"); + private Type attribTree(JCTree tree, Env env, ResultInfo resultInfo) { + return attribTree(tree, env, resultInfo, "incompatible.types"); } - Type attribTree(JCTree tree, Env env, int pkind, Type pt, String errKey) { + private Type attribTree(JCTree tree, Env env, ResultInfo resultInfo, String errKey) { Env prevEnv = this.env; - int prevPkind = this.pkind; - Type prevPt = this.pt; + ResultInfo prevResult = this.resultInfo; String prevErrKey = this.errKey; try { this.env = env; - this.pkind = pkind; - this.pt = pt; + this.resultInfo = resultInfo; this.errKey = errKey; tree.accept(this); if (tree == breakTree) @@ -442,8 +465,7 @@ return chk.completionError(tree.pos(), ex); } finally { this.env = prevEnv; - this.pkind = prevPkind; - this.pt = prevPt; + this.resultInfo = prevResult; this.errKey = prevErrKey; } } @@ -451,18 +473,18 @@ /** Derived visitor method: attribute an expression tree. */ public Type attribExpr(JCTree tree, Env env, Type pt) { - return attribTree(tree, env, VAL, pt.tag != ERROR ? pt : Type.noType); + return attribExpr(tree, env, pt, "incompatible.types"); } public Type attribExpr(JCTree tree, Env env, Type pt, String key) { - return attribTree(tree, env, VAL, pt.tag != ERROR ? pt : Type.noType, key); + return attribTree(tree, env, new ResultInfo(VAL, pt.tag != ERROR ? pt : Type.noType), key); } /** Derived visitor method: attribute an expression tree with * no constraints on the computed type. */ Type attribExpr(JCTree tree, Env env) { - return attribTree(tree, env, VAL, Type.noType); + return attribTree(tree, env, unknownExprInfo); } /** Derived visitor method: attribute a type tree. @@ -475,14 +497,14 @@ /** Derived visitor method: attribute a type tree. */ Type attribType(JCTree tree, Env env, Type pt) { - Type result = attribTree(tree, env, TYP, pt); + Type result = attribTree(tree, env, new ResultInfo(TYP, pt)); return result; } /** Derived visitor method: attribute a statement or definition tree. */ public Type attribStat(JCTree tree, Env env) { - return attribTree(tree, env, NIL, Type.noType); + return attribTree(tree, env, statInfo); } /** Attribute a list of expressions, returning a list of types. @@ -507,7 +529,7 @@ ListBuffer argtypes = new ListBuffer(); for (List l = trees; l.nonEmpty(); l = l.tail) argtypes.append(chk.checkNonVoid( - l.head.pos(), types.upperBound(attribTree(l.head, env, VAL, Infer.anyPoly)))); + l.head.pos(), types.upperBound(attribExpr(l.head, env, Infer.anyPoly)))); return argtypes.toList(); } @@ -1181,7 +1203,7 @@ result = check(tree, capture(condType(tree.pos(), tree.cond.type, tree.truepart.type, tree.falsepart.type)), - VAL, pkind, pt); + VAL, resultInfo); } //where /** Compute the type of a conditional expression, after @@ -1500,8 +1522,8 @@ // ...and check that it is legal in the current context. // (this will also set the tree's type) Type mpt = newMethTemplate(argtypes, typeargtypes); - checkId(tree.meth, site, sym, localEnv, MTH, - mpt, tree.varargsElement != null); + checkId(tree.meth, site, sym, localEnv, new ResultInfo(MTH, mpt), + tree.varargsElement != null); } // Otherwise, `site' is an error type and we do nothing } @@ -1518,8 +1540,6 @@ Type mpt = newMethTemplate(argtypes, typeargtypes); localEnv.info.varArgs = false; Type mtype = attribExpr(tree.meth, localEnv, mpt); - if (localEnv.info.varArgs) - Assert.check(mtype.isErroneous() || tree.varargsElement != null); // Compute the result type. Type restype = mtype.getReturnType(); @@ -1552,7 +1572,10 @@ // Check that value of resulting type is admissible in the // current context. Also, capture the return type - result = check(tree, capture(restype), VAL, pkind, pt); + result = check(tree, capture(restype), VAL, resultInfo); + + if (localEnv.info.varArgs) + Assert.check(result.isErroneous() || tree.varargsElement != null); } chk.validate(tree.typeargs, localEnv); } @@ -1627,7 +1650,6 @@ // Attribute clazz expression and store // symbol + type back into the attributed tree. Type clazztype = attribType(clazz, env); - Pair mapping = getSyntheticScopeMapping(clazztype); clazztype = chk.checkDiamond(tree, clazztype); chk.validate(clazz, localEnv); if (tree.encl != null) { @@ -1654,7 +1676,7 @@ List typeargtypes = attribTypes(tree.typeargs, localEnv); if (TreeInfo.isDiamond(tree) && !clazztype.isErroneous()) { - clazztype = attribDiamond(localEnv, tree, clazztype, mapping, argtypes, typeargtypes); + clazztype = attribDiamond(localEnv, tree, clazztype, argtypes, typeargtypes); clazz.type = clazztype; } else if (allowDiamondFinder && tree.def == null && @@ -1671,7 +1693,6 @@ inferred = attribDiamond(localEnv, tree, clazztype, - mapping, argtypes, typeargtypes); } @@ -1682,7 +1703,7 @@ if (inferred != null && !inferred.isErroneous() && inferred.tag == CLASS && - types.isAssignable(inferred, pt.tag == NONE ? clazztype : pt, Warner.noWarnings)) { + types.isAssignable(inferred, pt().tag == NONE ? clazztype : pt(), Warner.noWarnings)) { String key = types.isSameType(clazztype, inferred) ? "diamond.redundant.args" : "diamond.redundant.args.1"; @@ -1732,7 +1753,7 @@ tree.pos(), rsEnv, clazztype, argtypes, typeargtypes); tree.constructorType = tree.constructor.type.isErroneous() ? syms.errType : - checkMethod(clazztype, + checkConstructor(clazztype, tree.constructor, rsEnv, tree.args, @@ -1807,7 +1828,7 @@ tree.constructorType = syms.errType; } else { - tree.constructorType = checkMethod(clazztype, + tree.constructorType = checkConstructor(clazztype, tree.constructor, localEnv, tree.args, @@ -1820,19 +1841,17 @@ if (tree.constructor != null && tree.constructor.kind == MTH) owntype = clazztype; } - result = check(tree, owntype, VAL, pkind, pt); + result = check(tree, owntype, VAL, resultInfo); chk.validate(tree.typeargs, localEnv); } Type attribDiamond(Env env, JCNewClass tree, Type clazztype, - Pair mapping, List argtypes, List typeargtypes) { if (clazztype.isErroneous() || - clazztype.isInterface() || - mapping == erroneousMapping) { + clazztype.isInterface()) { //if the type of the instance creation expression is erroneous, //or if it's an interface, or if something prevented us to form a valid //mapping, return the (possibly erroneous) type unchanged @@ -1841,27 +1860,22 @@ //dup attribution environment and augment the set of inference variables Env localEnv = env.dup(tree); - localEnv.info.tvars = clazztype.tsym.type.getTypeArguments(); + + ClassType site = new ClassType(clazztype.getEnclosingType(), + clazztype.tsym.type.getTypeArguments(), + clazztype.tsym); //if the type of the instance creation expression is a class type //apply method resolution inference (JLS 15.12.2.7). The return type //of the resolved constructor will be a partially instantiated type - ((ClassSymbol) clazztype.tsym).members_field = mapping.snd; - Symbol constructor; - try { - constructor = rs.resolveDiamond(tree.pos(), + Symbol constructor = rs.resolveDiamond(tree.pos(), localEnv, - clazztype, + site, argtypes, typeargtypes); - } finally { - ((ClassSymbol) clazztype.tsym).members_field = mapping.fst; - } + if (constructor.kind == MTH) { - ClassType ct = new ClassType(clazztype.getEnclosingType(), - clazztype.tsym.type.getTypeArguments(), - clazztype.tsym); - clazztype = checkMethod(ct, + clazztype = checkMethod(site, constructor, localEnv, tree.args, @@ -1872,13 +1886,13 @@ clazztype = syms.errType; } - if (clazztype.tag == FORALL && !pt.isErroneous()) { + if (clazztype.tag == FORALL && !pt().isErroneous()) { //if the resolved constructor's return type has some uninferred //type-variables, infer them using the expected type and declared //bounds (JLS 15.12.2.8). try { clazztype = infer.instantiateExpr((ForAll) clazztype, - pt.tag == NONE ? syms.objectType : pt, + pt().tag == NONE ? syms.objectType : pt(), Warner.noWarnings); } catch (Infer.InferenceException ex) { //an error occurred while inferring uninstantiated type-variables @@ -1893,42 +1907,6 @@ true); } - /** Creates a synthetic scope containing fake generic constructors. - * Assuming that the original scope contains a constructor of the kind: - * Foo(X x, Y y), where X,Y are class type-variables declared in Foo, - * the synthetic scope is added a generic constructor of the kind: - * Foo(X x, Y y). This is crucial in order to enable diamond - * inference. The inferred return type of the synthetic constructor IS - * the inferred type for the diamond operator. - */ - private Pair getSyntheticScopeMapping(Type ctype) { - if (ctype.tag != CLASS) { - return erroneousMapping; - } - - Pair mapping = - new Pair(ctype.tsym.members(), new Scope(ctype.tsym)); - - //for each constructor in the original scope, create a synthetic constructor - //whose return type is the type of the class in which the constructor is - //declared, and insert it into the new scope. - for (Scope.Entry e = mapping.fst.lookup(names.init); - e.scope != null; - e = e.next()) { - Type synthRestype = new ClassType(ctype.getEnclosingType(), - ctype.tsym.type.getTypeArguments(), - ctype.tsym); - MethodSymbol synhConstr = new MethodSymbol(e.sym.flags(), - names.init, - types.createMethodTypeWithReturn(e.sym.type, synthRestype), - e.sym.owner); - mapping.snd.enter(synhConstr); - } - return mapping; - } - - private final Pair erroneousMapping = new Pair(null, null); - /** Make an attributed null check tree. */ public JCExpression makeNullCheck(JCExpression arg) { @@ -1957,14 +1935,14 @@ } else { // we are seeing an untyped aggregate { ... } // this is allowed only if the prototype is an array - if (pt.tag == ARRAY) { - elemtype = types.elemtype(pt); + if (pt().tag == ARRAY) { + elemtype = types.elemtype(pt()); } else { - if (pt.tag != ERROR) { + if (pt().tag != ERROR) { log.error(tree.pos(), "illegal.initializer.for.type", - pt); + pt()); } - elemtype = types.createErrorType(pt); + elemtype = types.createErrorType(pt()); } } if (tree.elems != null) { @@ -1973,7 +1951,7 @@ } if (!types.isReifiable(elemtype)) log.error(tree.pos(), "generic.array.creation"); - result = check(tree, owntype, VAL, pkind, pt); + result = check(tree, owntype, VAL, resultInfo); } @Override @@ -1987,23 +1965,23 @@ } public void visitParens(JCParens tree) { - Type owntype = attribTree(tree.expr, env, pkind, pt); - result = check(tree, owntype, pkind, pkind, pt); + Type owntype = attribTree(tree.expr, env, resultInfo); + result = check(tree, owntype, pkind(), resultInfo); Symbol sym = TreeInfo.symbol(tree); if (sym != null && (sym.kind&(TYP|PCK)) != 0) log.error(tree.pos(), "illegal.start.of.type"); } public void visitAssign(JCAssign tree) { - Type owntype = attribTree(tree.lhs, env.dup(tree), VAR, Type.noType); + Type owntype = attribTree(tree.lhs, env.dup(tree), varInfo); Type capturedType = capture(owntype); attribExpr(tree.rhs, env, owntype); - result = check(tree, capturedType, VAL, pkind, pt); + result = check(tree, capturedType, VAL, resultInfo); } public void visitAssignop(JCAssignOp tree) { // Attribute arguments. - Type owntype = attribTree(tree.lhs, env, VAR, Type.noType); + Type owntype = attribTree(tree.lhs, env, varInfo); Type operand = attribExpr(tree.rhs, env); // Find operator. Symbol operator = tree.operator = rs.resolveBinaryOperator( @@ -2023,13 +2001,13 @@ operator.type.getReturnType(), owntype); } - result = check(tree, owntype, VAL, pkind, pt); + result = check(tree, owntype, VAL, resultInfo); } public void visitUnary(JCUnary tree) { // Attribute arguments. Type argtype = (tree.getTag().isIncOrDecUnaryOp()) - ? attribTree(tree.arg, env, VAR, Type.noType) + ? attribTree(tree.arg, env, varInfo) : chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env)); // Find operator. @@ -2061,7 +2039,7 @@ } } } - result = check(tree, owntype, VAL, pkind, pt); + result = check(tree, owntype, VAL, resultInfo); } public void visitBinary(JCBinary tree) { @@ -2114,7 +2092,7 @@ chk.checkDivZero(tree.rhs.pos(), operator, right); } - result = check(tree, owntype, VAL, pkind, pt); + result = check(tree, owntype, VAL, resultInfo); } public void visitTypeCast(JCTypeCast tree) { @@ -2127,7 +2105,7 @@ Type owntype = chk.checkCastable(tree.expr.pos(), exprtype, clazztype); if (exprtype.constValue() != null) owntype = cfolder.coerce(exprtype, owntype); - result = check(tree, capture(owntype), VAL, pkind, pt); + result = check(tree, capture(owntype), VAL, resultInfo); } public void visitTypeTest(JCInstanceOf tree) { @@ -2137,7 +2115,7 @@ tree.clazz.pos(), attribType(tree.clazz, env)); chk.validate(tree.clazz, env, false); chk.checkCastable(tree.expr.pos(), exprtype, clazztype); - result = check(tree, syms.booleanType, VAL, pkind, pt); + result = check(tree, syms.booleanType, VAL, resultInfo); } public void visitIndexed(JCArrayAccess tree) { @@ -2148,8 +2126,8 @@ owntype = types.elemtype(atype); else if (atype.tag != ERROR) log.error(tree.pos(), "array.req.but.found", atype); - if ((pkind & VAR) == 0) owntype = capture(owntype); - result = check(tree, owntype, VAR, pkind, pt); + if ((pkind() & VAR) == 0) owntype = capture(owntype); + result = check(tree, owntype, VAR, resultInfo); } public void visitIdent(JCIdent tree) { @@ -2157,16 +2135,16 @@ boolean varArgs = false; // Find symbol - if (pt.tag == METHOD || pt.tag == FORALL) { + if (pt().tag == METHOD || pt().tag == FORALL) { // If we are looking for a method, the prototype `pt' will be a // method type with the type of the call's arguments as parameters. env.info.varArgs = false; - sym = rs.resolveMethod(tree.pos(), env, tree.name, pt.getParameterTypes(), pt.getTypeArguments()); + sym = rs.resolveMethod(tree.pos(), env, tree.name, pt().getParameterTypes(), pt().getTypeArguments()); varArgs = env.info.varArgs; } else if (tree.sym != null && tree.sym.kind != VAR) { sym = tree.sym; } else { - sym = rs.resolveIdent(tree.pos(), env, tree.name, pkind); + sym = rs.resolveIdent(tree.pos(), env, tree.name, pkind()); } tree.sym = sym; @@ -2213,7 +2191,7 @@ // If we are expecting a variable (as opposed to a value), check // that the variable is assignable in the current environment. - if (pkind == VAR) + if (pkind() == VAR) checkAssignable(tree.pos(), v, null, env); } @@ -2234,7 +2212,7 @@ while (env1.outer != null && !rs.isAccessible(env, env1.enclClass.sym.type, sym)) env1 = env1.outer; } - result = checkId(tree, env1.enclClass.sym.type, sym, env, pkind, pt, varArgs); + result = checkId(tree, env1.enclClass.sym.type, sym, env, resultInfo, varArgs); } public void visitSelect(JCFieldAccess tree) { @@ -2245,14 +2223,14 @@ { skind = TYP; } else { - if ((pkind & PCK) != 0) skind = skind | PCK; - if ((pkind & TYP) != 0) skind = skind | TYP | PCK; - if ((pkind & (VAL | MTH)) != 0) skind = skind | VAL | TYP; + if ((pkind() & PCK) != 0) skind = skind | PCK; + if ((pkind() & TYP) != 0) skind = skind | TYP | PCK; + if ((pkind() & (VAL | MTH)) != 0) skind = skind | VAL | TYP; } // Attribute the qualifier expression, and determine its symbol (if any). - Type site = attribTree(tree.selected, env, skind, Infer.anyPoly); - if ((pkind & (PCK | TYP)) == 0) + Type site = attribTree(tree.selected, env, new ResultInfo(skind, Infer.anyPoly)); + if ((pkind() & (PCK | TYP)) == 0) site = capture(site); // Capture field access // don't allow T.class T[].class, etc @@ -2287,10 +2265,10 @@ // Determine the symbol represented by the selection. env.info.varArgs = false; - Symbol sym = selectSym(tree, sitesym, site, env, pt, pkind); - if (sym.exists() && !isType(sym) && (pkind & (PCK | TYP)) != 0) { + Symbol sym = selectSym(tree, sitesym, site, env, resultInfo); + if (sym.exists() && !isType(sym) && (pkind() & (PCK | TYP)) != 0) { site = capture(site); - sym = selectSym(tree, sitesym, site, env, pt, pkind); + sym = selectSym(tree, sitesym, site, env, resultInfo); } boolean varArgs = env.info.varArgs; tree.sym = sym; @@ -2310,7 +2288,7 @@ // If we are expecting a variable (as opposed to a value), check // that the variable is assignable in the current environment. - if (pkind == VAR) + if (pkind() == VAR) checkAssignable(tree.pos(), v, tree.selected, env); } @@ -2326,8 +2304,8 @@ // Disallow selecting a type from an expression if (isType(sym) && (sitesym==null || (sitesym.kind&(TYP|PCK)) == 0)) { - tree.type = check(tree.selected, pt, - sitesym == null ? VAL : sitesym.kind, TYP|PCK, pt); + tree.type = check(tree.selected, pt(), + sitesym == null ? VAL : sitesym.kind, new ResultInfo(TYP|PCK, pt())); } if (isType(sitesym)) { @@ -2367,7 +2345,7 @@ } env.info.selectSuper = selectSuperPrev; - result = checkId(tree, site, sym, env, pkind, pt, varArgs); + result = checkId(tree, site, sym, env, resultInfo, varArgs); env.info.tvars = List.nil(); } //where @@ -2376,34 +2354,25 @@ * @param tree The select tree. * @param site The type of the selected expression, * @param env The current environment. - * @param pt The current prototype. - * @param pkind The expected kind(s) of the Select expression. + * @param resultInfo The current result. */ private Symbol selectSym(JCFieldAccess tree, - Type site, - Env env, - Type pt, - int pkind) { - return selectSym(tree, site.tsym, site, env, pt, pkind); - } - private Symbol selectSym(JCFieldAccess tree, Symbol location, Type site, Env env, - Type pt, - int pkind) { + ResultInfo resultInfo) { DiagnosticPosition pos = tree.pos(); Name name = tree.name; switch (site.tag) { case PACKAGE: return rs.access( - rs.findIdentInPackage(env, site.tsym, name, pkind), + rs.findIdentInPackage(env, site.tsym, name, resultInfo.pkind), pos, location, site, name, true); case ARRAY: case CLASS: - if (pt.tag == METHOD || pt.tag == FORALL) { + if (resultInfo.pt.tag == METHOD || resultInfo.pt.tag == FORALL) { return rs.resolveQualifiedMethod( - pos, env, location, site, name, pt.getParameterTypes(), pt.getTypeArguments()); + pos, env, location, site, name, resultInfo.pt.getParameterTypes(), resultInfo.pt.getTypeArguments()); } else if (name == names._this || name == names._super) { return rs.resolveSelf(pos, env, site.tsym, name); } else if (name == names._class) { @@ -2418,8 +2387,8 @@ STATIC | PUBLIC | FINAL, names._class, t, site.tsym); } else { // We are seeing a plain identifier as selector. - Symbol sym = rs.findIdentInType(env, site, name, pkind); - if ((pkind & ERRONEOUS) == 0) + Symbol sym = rs.findIdentInType(env, site, name, resultInfo.pkind); + if ((resultInfo.pkind & ERRONEOUS) == 0) sym = rs.access(sym, pos, location, site, name, true); return sym; } @@ -2433,7 +2402,7 @@ // other words, we are seeing this illegal program: // class B extends A {} Symbol sym = (site.getUpperBound() != null) - ? selectSym(tree, location, capture(site.getUpperBound()), env, pt, pkind) + ? selectSym(tree, location, capture(site.getUpperBound()), env, resultInfo) : null; if (sym == null) { log.error(pos, "type.var.cant.be.deref"); @@ -2487,17 +2456,15 @@ * expression, otherwise the type of the current class. * @param sym The symbol representing the identifier. * @param env The current environment. - * @param pkind The set of expected kinds. - * @param pt The expected type. + * @param resultInfo The expected result */ Type checkId(JCTree tree, Type site, Symbol sym, Env env, - int pkind, - Type pt, + ResultInfo resultInfo, boolean useVarargs) { - if (pt.isErroneous()) return types.createErrorType(site); + if (resultInfo.pt.isErroneous()) return types.createErrorType(site); Type owntype; // The computed type of this identifier occurrence. switch (sym.kind) { case TYP: @@ -2542,7 +2509,7 @@ // which is being assigned to, issue an unchecked warning if // its type changes under erasure. if (allowGenerics && - pkind == VAR && + resultInfo.pkind == VAR && v.owner.kind == TYP && (v.flags() & STATIC) == 0 && (site.tag == CLASS || site.tag == TYPEVAR)) { @@ -2577,14 +2544,14 @@ if (v.getConstValue() != null && isStaticReference(tree)) owntype = owntype.constType(v.getConstValue()); - if (pkind == VAL) { + if (resultInfo.pkind == VAL) { owntype = capture(owntype); // capture "names as expressions" } break; case MTH: { JCMethodInvocation app = (JCMethodInvocation)env.tree; owntype = checkMethod(site, sym, env, app.args, - pt.getParameterTypes(), pt.getTypeArguments(), + resultInfo.pt.getParameterTypes(), resultInfo.pt.getTypeArguments(), env.info.varArgs); break; } @@ -2607,7 +2574,7 @@ // Test (3): if symbol is a variable, check that its type and // kind are compatible with the prototype and protokind. - return check(tree, owntype, sym.kind, pkind, pt); + return check(tree, owntype, sym.kind, resultInfo); } /** Check that variable is initialized and evaluate the variable's @@ -2720,7 +2687,7 @@ Warner noteWarner = new Warner(); /** - * Check that method arguments conform to its instantation. + * Check that method arguments conform to its instantiation. **/ public Type checkMethod(Type site, Symbol sym, @@ -2757,112 +2724,44 @@ true, useVarargs, noteWarner); - boolean warned = noteWarner.hasNonSilentLint(LintCategory.UNCHECKED); + + boolean unchecked = noteWarner.hasNonSilentLint(LintCategory.UNCHECKED); // If this fails, something went wrong; we should not have // found the identifier in the first place. if (owntype == null) { - if (!pt.isErroneous()) + if (!pt().isErroneous()) log.error(env.tree.pos(), - "internal.error.cant.instantiate", - sym, site, - Type.toString(pt.getParameterTypes())); + "internal.error.cant.instantiate", + sym, site, + Type.toString(pt().getParameterTypes())); owntype = types.createErrorType(site); + return types.createErrorType(site); + } else if (owntype.getReturnType().tag == FORALL && !unchecked) { + return owntype; } else { - // System.out.println("call : " + env.tree); - // System.out.println("method : " + owntype); - // System.out.println("actuals: " + argtypes); - List formals = owntype.getParameterTypes(); - Type last = useVarargs ? formals.last() : null; - if (sym.name==names.init && - sym.owner == syms.enumSym) - formals = formals.tail.tail; - List args = argtrees; - while (formals.head != last) { - JCTree arg = args.head; - Warner warn = chk.convertWarner(arg.pos(), arg.type, formals.head); - assertConvertible(arg, arg.type, formals.head, warn); - warned |= warn.hasNonSilentLint(LintCategory.UNCHECKED); - args = args.tail; - formals = formals.tail; - } - if (useVarargs) { - Type varArg = types.elemtype(last); - while (args.tail != null) { - JCTree arg = args.head; - Warner warn = chk.convertWarner(arg.pos(), arg.type, varArg); - assertConvertible(arg, arg.type, varArg, warn); - warned |= warn.hasNonSilentLint(LintCategory.UNCHECKED); - args = args.tail; - } - } else if ((sym.flags() & VARARGS) != 0 && allowVarargs) { - // non-varargs call to varargs method - Type varParam = owntype.getParameterTypes().last(); - Type lastArg = argtypes.last(); - if (types.isSubtypeUnchecked(lastArg, types.elemtype(varParam)) && - !types.isSameType(types.erasure(varParam), types.erasure(lastArg))) - log.warning(argtrees.last().pos(), "inexact.non-varargs.call", - types.elemtype(varParam), - varParam); - } - - if (warned && sym.type.tag == FORALL) { - chk.warnUnchecked(env.tree.pos(), - "unchecked.meth.invocation.applied", - kindName(sym), - sym.name, - rs.methodArguments(sym.type.getParameterTypes()), - rs.methodArguments(argtypes), - kindName(sym.location()), - sym.location()); - owntype = new MethodType(owntype.getParameterTypes(), - types.erasure(owntype.getReturnType()), - types.erasure(owntype.getThrownTypes()), - syms.methodClass); - } - if (useVarargs) { - JCTree tree = env.tree; - Type argtype = owntype.getParameterTypes().last(); - if (owntype.getReturnType().tag != FORALL || warned) { - chk.checkVararg(env.tree.pos(), owntype.getParameterTypes(), sym); - } - Type elemtype = types.elemtype(argtype); - switch (tree.getTag()) { - case APPLY: - ((JCMethodInvocation) tree).varargsElement = elemtype; - break; - case NEWCLASS: - ((JCNewClass) tree).varargsElement = elemtype; - break; - default: - throw new AssertionError(""+tree); - } - } + return chk.checkMethod(owntype, sym, env, argtrees, argtypes, useVarargs, unchecked); } + } + + /** + * Check that constructor arguments conform to its instantiation. + **/ + public Type checkConstructor(Type site, + Symbol sym, + Env env, + final List argtrees, + List argtypes, + List typeargtypes, + boolean useVarargs) { + Type owntype = checkMethod(site, sym, env, argtrees, argtypes, typeargtypes, useVarargs); + chk.checkType(env.tree.pos(), owntype.getReturnType(), syms.voidType); return owntype; } - private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) { - if (types.isConvertible(actual, formal, warn)) - return; - - if (formal.isCompound() - && types.isSubtype(actual, types.supertype(formal)) - && types.isSubtypeUnchecked(actual, types.interfaces(formal), warn)) - return; - - if (false) { - // TODO: make assertConvertible work - chk.typeError(tree.pos(), diags.fragment("incompatible.types"), actual, formal); - throw new AssertionError("Tree: " + tree - + " actual:" + actual - + " formal: " + formal); - } - } - public void visitLiteral(JCLiteral tree) { result = check( - tree, litType(tree.typetag).constType(tree.value), VAL, pkind, pt); + tree, litType(tree.typetag).constType(tree.value), VAL, resultInfo); } //where /** Return the type of a literal with given type tag. @@ -2872,13 +2771,13 @@ } public void visitTypeIdent(JCPrimitiveTypeTree tree) { - result = check(tree, syms.typeOfTag[tree.typetag], TYP, pkind, pt); + result = check(tree, syms.typeOfTag[tree.typetag], TYP, resultInfo); } public void visitTypeArray(JCArrayTypeTree tree) { Type etype = attribType(tree.elemtype, env); Type type = new ArrayType(etype, syms.arrayClass); - result = check(tree, type, TYP, pkind, pt); + result = check(tree, type, TYP, resultInfo); } /** Visitor method for parameterized types. @@ -2936,7 +2835,7 @@ owntype = types.createErrorType(tree.type); } } - result = check(tree, owntype, TYP, pkind, pt); + result = check(tree, owntype, TYP, resultInfo); } public void visitTypeUnion(JCTypeUnion tree) { @@ -2973,7 +2872,7 @@ all_multicatchTypes.append(ctype); } } - Type t = check(tree, types.lub(multicatchTypes.toList()), TYP, pkind, pt); + Type t = check(tree, types.lub(multicatchTypes.toList()), TYP, resultInfo); if (t.tag == CLASS) { List alternatives = ((all_multicatchTypes == null) ? multicatchTypes : all_multicatchTypes).toList(); @@ -3059,18 +2958,18 @@ result = check(tree, new WildcardType(chk.checkRefType(tree.pos(), type), tree.kind.kind, syms.boundClass), - TYP, pkind, pt); + TYP, resultInfo); } public void visitAnnotation(JCAnnotation tree) { - log.error(tree.pos(), "annotation.not.valid.for.type", pt); + log.error(tree.pos(), "annotation.not.valid.for.type", pt()); result = tree.type = syms.errType; } public void visitErroneous(JCErroneous tree) { if (tree.errs != null) for (JCTree err : tree.errs) - attribTree(err, env, ERR, pt); + attribTree(err, env, new ResultInfo(ERR, pt())); result = tree.type = syms.errType; } diff -r a1af4b95c287 -r 08a3425f39f8 src/share/classes/com/sun/tools/javac/comp/Check.java --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Thu Mar 08 20:35:26 2012 -0800 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Mar 09 11:59:26 2012 -0800 @@ -63,6 +63,7 @@ private final Names names; private final Log log; + private final Resolve rs; private final Symtab syms; private final Enter enter; private final Infer infer; @@ -95,6 +96,7 @@ names = Names.instance(context); log = Log.instance(context); + rs = Resolve.instance(context); syms = Symtab.instance(context); enter = Enter.instance(context); infer = Infer.instance(context); @@ -106,6 +108,7 @@ Source source = Source.instance(context); allowGenerics = source.allowGenerics(); + allowVarargs = source.allowVarargs(); allowAnnotations = source.allowAnnotations(); allowCovariantReturns = source.allowCovariantReturns(); allowSimplifiedVarargs = source.allowSimplifiedVarargs(); @@ -137,6 +140,10 @@ */ boolean allowGenerics; + /** Switch: varargs enabled? + */ + boolean allowVarargs; + /** Switch: annotations enabled? */ boolean allowAnnotations; @@ -525,16 +532,16 @@ * @param a The type that should be bounded by bs. * @param bs The bound. */ - private boolean checkExtends(Type a, TypeVar bs) { + private boolean checkExtends(Type a, Type bound) { if (a.isUnbound()) { return true; } else if (a.tag != WILDCARD) { a = types.upperBound(a); - return types.isSubtype(a, bs.bound); + return types.isSubtype(a, bound); } else if (a.isExtendsBound()) { - return types.isCastable(bs.getUpperBound(), types.upperBound(a), Warner.noWarnings); + return types.isCastable(bound, types.upperBound(a), Warner.noWarnings); } else if (a.isSuperBound()) { - return !types.notSoftSubtype(types.lowerBound(a), bs.getUpperBound()); + return !types.notSoftSubtype(types.lowerBound(a), bound); } return true; } @@ -743,22 +750,103 @@ (s.flags() & (STATIC | FINAL)) != 0); } - /** - * Check that vararg method call is sound - * @param pos Position to be used for error reporting. - * @param argtypes Actual arguments supplied to vararg method. - */ - void checkVararg(DiagnosticPosition pos, List argtypes, Symbol msym) { - Type argtype = argtypes.last(); - if (!types.isReifiable(argtype) && - (!allowSimplifiedVarargs || - msym.attribute(syms.trustMeType.tsym) == null || - !isTrustMeAllowedOnMethod(msym))) { - warnUnchecked(pos, - "unchecked.generic.array.creation", - argtype); + Type checkMethod(Type owntype, + Symbol sym, + Env env, + final List argtrees, + List argtypes, + boolean useVarargs, + boolean unchecked) { + // System.out.println("call : " + env.tree); + // System.out.println("method : " + owntype); + // System.out.println("actuals: " + argtypes); + List formals = owntype.getParameterTypes(); + Type last = useVarargs ? formals.last() : null; + if (sym.name==names.init && + sym.owner == syms.enumSym) + formals = formals.tail.tail; + List args = argtrees; + while (formals.head != last) { + JCTree arg = args.head; + Warner warn = convertWarner(arg.pos(), arg.type, formals.head); + assertConvertible(arg, arg.type, formals.head, warn); + args = args.tail; + formals = formals.tail; } + if (useVarargs) { + Type varArg = types.elemtype(last); + while (args.tail != null) { + JCTree arg = args.head; + Warner warn = convertWarner(arg.pos(), arg.type, varArg); + assertConvertible(arg, arg.type, varArg, warn); + args = args.tail; + } + } else if ((sym.flags() & VARARGS) != 0 && allowVarargs) { + // non-varargs call to varargs method + Type varParam = owntype.getParameterTypes().last(); + Type lastArg = argtypes.last(); + if (types.isSubtypeUnchecked(lastArg, types.elemtype(varParam)) && + !types.isSameType(types.erasure(varParam), types.erasure(lastArg))) + log.warning(argtrees.last().pos(), "inexact.non-varargs.call", + types.elemtype(varParam), varParam); + } + if (unchecked) { + warnUnchecked(env.tree.pos(), + "unchecked.meth.invocation.applied", + kindName(sym), + sym.name, + rs.methodArguments(sym.type.getParameterTypes()), + rs.methodArguments(argtypes), + kindName(sym.location()), + sym.location()); + owntype = new MethodType(owntype.getParameterTypes(), + types.erasure(owntype.getReturnType()), + types.erasure(owntype.getThrownTypes()), + syms.methodClass); + } + if (useVarargs) { + JCTree tree = env.tree; + Type argtype = owntype.getParameterTypes().last(); + if (!types.isReifiable(argtype) && + (!allowSimplifiedVarargs || + sym.attribute(syms.trustMeType.tsym) == null || + !isTrustMeAllowedOnMethod(sym))) { + warnUnchecked(env.tree.pos(), + "unchecked.generic.array.creation", + argtype); + } + Type elemtype = types.elemtype(argtype); + switch (tree.getTag()) { + case APPLY: + ((JCMethodInvocation) tree).varargsElement = elemtype; + break; + case NEWCLASS: + ((JCNewClass) tree).varargsElement = elemtype; + break; + default: + throw new AssertionError(""+tree); + } + } + return owntype; } + //where + private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) { + if (types.isConvertible(actual, formal, warn)) + return; + + if (formal.isCompound() + && types.isSubtype(actual, types.supertype(formal)) + && types.isSubtypeUnchecked(actual, types.interfaces(formal), warn)) + return; + + if (false) { + // TODO: make assertConvertible work + typeError(tree.pos(), diags.fragment("incompatible.types"), actual, formal); + throw new AssertionError("Tree: " + tree + + " actual:" + actual + + " formal: " + formal); + } + } /** * Check that type 't' is a valid instantiation of a generic class @@ -776,18 +864,16 @@ List actuals = type.allparams(); List args = type.getTypeArguments(); List forms = type.tsym.type.getTypeArguments(); - ListBuffer tvars_buf = new ListBuffer(); + ListBuffer bounds_buf = new ListBuffer(); // For matching pairs of actual argument types `a' and // formal type parameters with declared bound `b' ... while (args.nonEmpty() && forms.nonEmpty()) { // exact type arguments needs to know their // bounds (for upper and lower bound - // calculations). So we create new TypeVars with - // bounds substed with actuals. - tvars_buf.append(types.substBound(((TypeVar)forms.head), - formals, - actuals)); + // calculations). So we create new bounds where + // type-parameters are replaced with actuals argument types. + bounds_buf.append(types.subst(forms.head.getUpperBound(), formals, actuals)); args = args.tail; forms = forms.tail; } @@ -804,32 +890,30 @@ } args = type.getTypeArguments(); - List tvars = tvars_buf.toList(); + List bounds = bounds_buf.toList(); - while (args.nonEmpty() && tvars.nonEmpty()) { - Type actual = types.subst(args.head, - type.tsym.type.getTypeArguments(), - tvars_buf.toList()); + while (args.nonEmpty() && bounds.nonEmpty()) { + Type actual = args.head; if (!isTypeArgErroneous(actual) && - !tvars.head.getUpperBound().isErroneous() && - !checkExtends(actual, (TypeVar)tvars.head)) { + !bounds.head.isErroneous() && + !checkExtends(actual, bounds.head)) { return args.head; } args = args.tail; - tvars = tvars.tail; + bounds = bounds.tail; } args = type.getTypeArguments(); - tvars = tvars_buf.toList(); + bounds = bounds_buf.toList(); for (Type arg : types.capture(type).getTypeArguments()) { if (arg.tag == TYPEVAR && arg.getUpperBound().isErroneous() && - !tvars.head.getUpperBound().isErroneous() && + !bounds.head.isErroneous() && !isTypeArgErroneous(args.head)) { return args.head; } - tvars = tvars.tail; + bounds = bounds.tail; args = args.tail; } @@ -2492,7 +2576,7 @@ if (enableSunApiLintControl) warnSunApi(pos, "sun.proprietary", s); else - log.strictWarning(pos, "sun.proprietary", s); + log.mandatoryWarning(pos, "sun.proprietary", s); } }); } diff -r a1af4b95c287 -r 08a3425f39f8 src/share/classes/com/sun/tools/javac/comp/Infer.java --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java Thu Mar 08 20:35:26 2012 -0800 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java Fri Mar 09 11:59:26 2012 -0800 @@ -385,7 +385,6 @@ final Warner warn) throws InferenceException { //-System.err.println("instantiateMethod(" + tvars + ", " + mt + ", " + argtypes + ")"); //DEBUG List undetvars = Type.map(tvars, fromTypeVarFun); - //final List capturedArgs = types.capture(argtypes); final List capturedArgs = rs.checkRawArgumentsAcceptable(env, undetvars, argtypes, mt.getParameterTypes(), @@ -445,16 +444,20 @@ return List.nil(); } @Override - void check(List inferred, Types types) throws NoInstanceException { + void instantiateReturnType(Type restype, List inferred, Types types) throws NoInstanceException { + Type owntype = new MethodType(types.subst(getParameterTypes(), tvars, inferred), + restype, + types.subst(getThrownTypes(), tvars, inferred), + qtype.tsym); // check that actuals conform to inferred formals - checkArgumentsAcceptable(env, capturedArgs, getParameterTypes(), allowBoxing, useVarargs, warn); + warn.clear(); + checkArgumentsAcceptable(env, capturedArgs, owntype.getParameterTypes(), allowBoxing, useVarargs, warn); // check that inferred bounds conform to their bounds checkWithinBounds(all_tvars, types.subst(inferredTypes, tvars, inferred), warn); - if (useVarargs) { - chk.checkVararg(env.tree.pos(), getParameterTypes(), msym); - } - }}; + qtype = chk.checkMethod(owntype, msym, env, TreeInfo.args(env.tree), capturedArgs, useVarargs, warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)); + } + }; } else { // check that actuals conform to inferred formals @@ -520,16 +523,7 @@ return qtype.map(f); } - void instantiateReturnType(Type restype, List inferred, Types types) throws NoInstanceException { - //update method type with newly inferred type-arguments - qtype = new MethodType(types.subst(getParameterTypes(), tvars, inferred), - restype, - types.subst(UninferredMethodType.this.getThrownTypes(), tvars, inferred), - UninferredMethodType.this.qtype.tsym); - check(inferred, types); - } - - abstract void check(List inferred, Types types) throws NoInstanceException; + abstract void instantiateReturnType(Type restype, List inferred, Types types); abstract List getConstraints(TypeVar tv, ConstraintKind ck); @@ -544,7 +538,7 @@ if (rs.verboseResolutionMode.contains(VerboseResolutionMode.DEFERRED_INST)) { log.note(pos, "deferred.method.inst", msym, UninferredMethodType.this.qtype, newRestype); } - return newRestype; + return UninferredMethodType.this.qtype.getReturnType(); } @Override public List getConstraints(TypeVar tv, ConstraintKind ck) { diff -r a1af4b95c287 -r 08a3425f39f8 src/share/classes/com/sun/tools/javac/comp/MemberEnter.java --- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Thu Mar 08 20:35:26 2012 -0800 +++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Fri Mar 09 11:59:26 2012 -0800 @@ -529,24 +529,17 @@ // process the non-static imports and the static imports of types. public void visitImport(JCImport tree) { - JCTree imp = tree.qualid; + JCFieldAccess imp = (JCFieldAccess)tree.qualid; Name name = TreeInfo.name(imp); - TypeSymbol p; // Create a local environment pointing to this tree to disable // effects of other imports in Resolve.findGlobalType Env localEnv = env.dup(tree); - // Attribute qualifying package or class. - JCFieldAccess s = (JCFieldAccess) imp; - p = attr. - attribTree(s.selected, - localEnv, - tree.staticImport ? TYP : (TYP | PCK), - Type.noType).tsym; + TypeSymbol p = attr.attribImportQualifier(tree, localEnv).tsym; if (name == names.asterisk) { // Import on demand. - chk.checkCanonical(s.selected); + chk.checkCanonical(imp.selected); if (tree.staticImport) importStaticAll(tree.pos, p, env); else @@ -555,7 +548,7 @@ // Named type import. if (tree.staticImport) { importNamedStatic(tree.pos(), p, name, localEnv); - chk.checkCanonical(s.selected); + chk.checkCanonical(imp.selected); } else { TypeSymbol c = attribImportType(imp, localEnv).tsym; chk.checkCanonical(imp); diff -r a1af4b95c287 -r 08a3425f39f8 src/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Mar 08 20:35:26 2012 -0800 +++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Mar 09 11:59:26 2012 -0800 @@ -29,6 +29,7 @@ import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Symbol.*; +import com.sun.tools.javac.comp.Resolve.MethodResolutionContext.Candidate; import com.sun.tools.javac.jvm.*; import com.sun.tools.javac.tree.*; import com.sun.tools.javac.tree.JCTree.*; @@ -39,10 +40,9 @@ import java.util.Arrays; import java.util.Collection; +import java.util.EnumMap; import java.util.EnumSet; -import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; @@ -84,6 +84,58 @@ Scope polymorphicSignatureScope; + protected Resolve(Context context) { + context.put(resolveKey, this); + syms = Symtab.instance(context); + + varNotFound = new + SymbolNotFoundError(ABSENT_VAR); + wrongMethod = new + InapplicableSymbolError(); + wrongMethods = new + InapplicableSymbolsError(); + methodNotFound = new + SymbolNotFoundError(ABSENT_MTH); + typeNotFound = new + SymbolNotFoundError(ABSENT_TYP); + + names = Names.instance(context); + log = Log.instance(context); + chk = Check.instance(context); + infer = Infer.instance(context); + reader = ClassReader.instance(context); + treeinfo = TreeInfo.instance(context); + types = Types.instance(context); + diags = JCDiagnostic.Factory.instance(context); + Source source = Source.instance(context); + boxingEnabled = source.allowBoxing(); + varargsEnabled = source.allowVarargs(); + Options options = Options.instance(context); + debugResolve = options.isSet("debugresolve"); + verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options); + Target target = Target.instance(context); + allowMethodHandles = target.hasMethodHandles(); + polymorphicSignatureScope = new Scope(syms.noSymbol); + + inapplicableMethodException = new InapplicableMethodException(diags); + } + + /** error symbols, which are returned when resolution fails + */ + private final SymbolNotFoundError varNotFound; + private final InapplicableSymbolError wrongMethod; + private final InapplicableSymbolsError wrongMethods; + private final SymbolNotFoundError methodNotFound; + private final SymbolNotFoundError typeNotFound; + + public static Resolve instance(Context context) { + Resolve instance = context.get(resolveKey); + if (instance == null) + instance = new Resolve(context); + return instance; + } + + // enum VerboseResolutionMode { SUCCESS("success"), FAILURE("failure"), @@ -119,56 +171,74 @@ } } - public static Resolve instance(Context context) { - Resolve instance = context.get(resolveKey); - if (instance == null) - instance = new Resolve(context); - return instance; + void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site, + List argtypes, List typeargtypes, Symbol bestSoFar) { + boolean success = bestSoFar.kind < ERRONEOUS; + + if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) { + return; + } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) { + return; + } + + if (bestSoFar.name == names.init && + bestSoFar.owner == syms.objectType.tsym && + !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) { + return; //skip diags for Object constructor resolution + } else if (site == syms.predefClass.type && + !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) { + return; //skip spurious diags for predef symbols (i.e. operators) + } else if (currentResolutionContext.internalResolution && + !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) { + return; + } + + int pos = 0; + int mostSpecificPos = -1; + ListBuffer subDiags = ListBuffer.lb(); + for (Candidate c : currentResolutionContext.candidates) { + if (currentResolutionContext.step != c.step || + (c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) || + (!c.isApplicable() && !verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE))) { + continue; + } else { + subDiags.append(c.isApplicable() ? + getVerboseApplicableCandidateDiag(pos, c.sym, c.mtype) : + getVerboseInapplicableCandidateDiag(pos, c.sym, c.details)); + if (c.sym == bestSoFar) + mostSpecificPos = pos; + pos++; + } + } + String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1"; + JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name, + site.tsym, mostSpecificPos, currentResolutionContext.step, + methodArguments(argtypes), methodArguments(typeargtypes)); + JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, subDiags.toList()); + log.report(d); } - protected Resolve(Context context) { - context.put(resolveKey, this); - syms = Symtab.instance(context); + JCDiagnostic getVerboseApplicableCandidateDiag(int pos, Symbol sym, Type inst) { + JCDiagnostic subDiag = null; + if (inst.getReturnType().tag == FORALL) { + Type diagType = types.createMethodTypeWithReturn(inst.asMethodType(), + ((ForAll)inst.getReturnType()).qtype); + subDiag = diags.fragment("partial.inst.sig", diagType); + } else if (sym.type.tag == FORALL) { + subDiag = diags.fragment("full.inst.sig", inst.asMethodType()); + } - varNotFound = new - SymbolNotFoundError(ABSENT_VAR); - wrongMethod = new - InapplicableSymbolError(syms.errSymbol); - wrongMethods = new - InapplicableSymbolsError(syms.errSymbol); - methodNotFound = new - SymbolNotFoundError(ABSENT_MTH); - typeNotFound = new - SymbolNotFoundError(ABSENT_TYP); + String key = subDiag == null ? + "applicable.method.found" : + "applicable.method.found.1"; - names = Names.instance(context); - log = Log.instance(context); - chk = Check.instance(context); - infer = Infer.instance(context); - reader = ClassReader.instance(context); - treeinfo = TreeInfo.instance(context); - types = Types.instance(context); - diags = JCDiagnostic.Factory.instance(context); - Source source = Source.instance(context); - boxingEnabled = source.allowBoxing(); - varargsEnabled = source.allowVarargs(); - Options options = Options.instance(context); - debugResolve = options.isSet("debugresolve"); - verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options); - Target target = Target.instance(context); - allowMethodHandles = target.hasMethodHandles(); - polymorphicSignatureScope = new Scope(syms.noSymbol); - - inapplicableMethodException = new InapplicableMethodException(diags); + return diags.fragment(key, pos, sym, subDiag); } - /** error symbols, which are returned when resolution fails - */ - final SymbolNotFoundError varNotFound; - final InapplicableSymbolError wrongMethod; - final InapplicableSymbolsError wrongMethods; - final SymbolNotFoundError methodNotFound; - final SymbolNotFoundError typeNotFound; + JCDiagnostic getVerboseInapplicableCandidateDiag(int pos, Symbol sym, JCDiagnostic subDiag) { + return diags.fragment("not.applicable.method.found", pos, sym, subDiag); + } + // /* ************************************************************************ * Identifier resolution @@ -804,17 +874,18 @@ try { Type mt = rawInstantiate(env, site, sym, argtypes, typeargtypes, allowBoxing, useVarargs, Warner.noWarnings); - if (!operator) addVerboseApplicableCandidateDiag(sym ,mt); + if (!operator) + currentResolutionContext.addApplicableCandidate(sym, mt); } catch (InapplicableMethodException ex) { - if (!operator) addVerboseInapplicableCandidateDiag(sym, ex.getDiagnostic()); + if (!operator) + currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic()); switch (bestSoFar.kind) { case ABSENT_MTH: - return wrongMethod.setWrongSym(sym, ex.getDiagnostic()); + return wrongMethod; case WRONG_MTH: if (operator) return bestSoFar; - wrongMethods.addCandidate(currentStep, wrongMethod.sym, wrongMethod.explanation); case WRONG_MTHS: - return wrongMethods.addCandidate(currentStep, sym, ex.getDiagnostic()); + return wrongMethods; default: return bestSoFar; } @@ -823,40 +894,12 @@ return (bestSoFar.kind == ABSENT_MTH) ? new AccessError(env, site, sym) : bestSoFar; - } + } return (bestSoFar.kind > AMBIGUOUS) ? sym : mostSpecific(sym, bestSoFar, env, site, allowBoxing && operator, useVarargs); } - //where - void addVerboseApplicableCandidateDiag(Symbol sym, Type inst) { - if (!verboseResolutionMode.contains(VerboseResolutionMode.APPLICABLE)) - return; - - JCDiagnostic subDiag = null; - if (inst.getReturnType().tag == FORALL) { - Type diagType = types.createMethodTypeWithReturn(inst.asMethodType(), - ((ForAll)inst.getReturnType()).qtype); - subDiag = diags.fragment("partial.inst.sig", diagType); - } else if (sym.type.tag == FORALL) { - subDiag = diags.fragment("full.inst.sig", inst.asMethodType()); - } - - String key = subDiag == null ? - "applicable.method.found" : - "applicable.method.found.1"; - - verboseResolutionCandidateDiags.put(sym, - diags.fragment(key, verboseResolutionCandidateDiags.size(), sym, subDiag)); - } - - void addVerboseInapplicableCandidateDiag(Symbol sym, JCDiagnostic subDiag) { - if (!verboseResolutionMode.contains(VerboseResolutionMode.INAPPLICABLE)) - return; - verboseResolutionCandidateDiags.put(sym, - diags.fragment("not.applicable.method.found", verboseResolutionCandidateDiags.size(), sym, subDiag)); - } /* Return the most specific of the two methods for a call, * given that both are accessible and applicable. @@ -1054,7 +1097,6 @@ boolean allowBoxing, boolean useVarargs, boolean operator) { - verboseResolutionCandidateDiags.clear(); Symbol bestSoFar = methodNotFound; bestSoFar = findMethod(env, site, @@ -1127,37 +1169,6 @@ } return bestSoFar; } - //where - void reportVerboseResolutionDiagnostic(DiagnosticPosition dpos, Name name, Type site, List argtypes, List typeargtypes, Symbol bestSoFar) { - boolean success = bestSoFar.kind < ERRONEOUS; - - if (success && !verboseResolutionMode.contains(VerboseResolutionMode.SUCCESS)) { - return; - } else if (!success && !verboseResolutionMode.contains(VerboseResolutionMode.FAILURE)) { - return; - } - - if (bestSoFar.name == names.init && - bestSoFar.owner == syms.objectType.tsym && - !verboseResolutionMode.contains(VerboseResolutionMode.OBJECT_INIT)) { - return; //skip diags for Object constructor resolution - } else if (site == syms.predefClass.type && !verboseResolutionMode.contains(VerboseResolutionMode.PREDEF)) { - return; //skip spurious diags for predef symbols (i.e. operators) - } else if (internalResolution && !verboseResolutionMode.contains(VerboseResolutionMode.INTERNAL)) { - return; - } - - int pos = 0; - for (Symbol s : verboseResolutionCandidateDiags.keySet()) { - if (s == bestSoFar) break; - pos++; - } - String key = success ? "verbose.resolve.multi" : "verbose.resolve.multi.1"; - JCDiagnostic main = diags.note(log.currentSource(), dpos, key, name, site.tsym, pos, currentStep, - methodArguments(argtypes), methodArguments(typeargtypes)); - JCDiagnostic d = new JCDiagnostic.MultilineDiagnostic(main, List.from(verboseResolutionCandidateDiags.values().toArray(new JCDiagnostic[verboseResolutionCandidateDiags.size()]))); - log.report(d); - } /** Find unqualified method matching given name, type and value arguments. * @param env The current environment. @@ -1591,32 +1602,33 @@ Name name, List argtypes, List typeargtypes) { - Symbol sym = startResolution(); - List steps = methodResolutionSteps; - while (steps.nonEmpty() && - steps.head.isApplicable(boxingEnabled, varargsEnabled) && - sym.kind >= ERRONEOUS) { - currentStep = steps.head; - sym = findFun(env, name, argtypes, typeargtypes, - steps.head.isBoxingRequired, - env.info.varArgs = steps.head.isVarargsRequired); - methodResolutionCache.put(steps.head, sym); - steps = steps.tail; + MethodResolutionContext prevResolutionContext = currentResolutionContext; + try { + currentResolutionContext = new MethodResolutionContext(); + Symbol sym = methodNotFound; + List steps = methodResolutionSteps; + while (steps.nonEmpty() && + steps.head.isApplicable(boxingEnabled, varargsEnabled) && + sym.kind >= ERRONEOUS) { + currentResolutionContext.step = steps.head; + sym = findFun(env, name, argtypes, typeargtypes, + steps.head.isBoxingRequired, + env.info.varArgs = steps.head.isVarargsRequired); + currentResolutionContext.resolutionCache.put(steps.head, sym); + steps = steps.tail; + } + if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error + MethodResolutionPhase errPhase = + currentResolutionContext.firstErroneousResolutionPhase(); + sym = access(currentResolutionContext.resolutionCache.get(errPhase), + pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes); + env.info.varArgs = errPhase.isVarargsRequired; + } + return sym; } - if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error - MethodResolutionPhase errPhase = - firstErroneousResolutionPhase(); - sym = access(methodResolutionCache.get(errPhase), - pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes); - env.info.varArgs = errPhase.isVarargsRequired; + finally { + currentResolutionContext = prevResolutionContext; } - return sym; - } - - private Symbol startResolution() { - wrongMethod.clear(); - wrongMethods.clear(); - return methodNotFound; } /** Resolve a qualified method identifier @@ -1636,40 +1648,53 @@ Symbol resolveQualifiedMethod(DiagnosticPosition pos, Env env, Symbol location, Type site, Name name, List argtypes, List typeargtypes) { - Symbol sym = startResolution(); - List steps = methodResolutionSteps; - while (steps.nonEmpty() && - steps.head.isApplicable(boxingEnabled, varargsEnabled) && - sym.kind >= ERRONEOUS) { - currentStep = steps.head; - sym = findMethod(env, site, name, argtypes, typeargtypes, - steps.head.isBoxingRequired(), - env.info.varArgs = steps.head.isVarargsRequired(), false); - methodResolutionCache.put(steps.head, sym); - steps = steps.tail; - } - if (sym.kind >= AMBIGUOUS) { - if (site.tsym.isPolymorphicSignatureGeneric()) { - //polymorphic receiver - synthesize new method symbol + return resolveQualifiedMethod(new MethodResolutionContext(), pos, env, location, site, name, argtypes, typeargtypes); + } + private Symbol resolveQualifiedMethod(MethodResolutionContext resolveContext, + DiagnosticPosition pos, Env env, + Symbol location, Type site, Name name, List argtypes, + List typeargtypes) { + MethodResolutionContext prevResolutionContext = currentResolutionContext; + try { + currentResolutionContext = resolveContext; + Symbol sym = methodNotFound; + List steps = methodResolutionSteps; + while (steps.nonEmpty() && + steps.head.isApplicable(boxingEnabled, varargsEnabled) && + sym.kind >= ERRONEOUS) { + currentResolutionContext.step = steps.head; + sym = findMethod(env, site, name, argtypes, typeargtypes, + steps.head.isBoxingRequired(), + env.info.varArgs = steps.head.isVarargsRequired(), false); + currentResolutionContext.resolutionCache.put(steps.head, sym); + steps = steps.tail; + } + if (sym.kind >= AMBIGUOUS) { + if (site.tsym.isPolymorphicSignatureGeneric()) { + //polymorphic receiver - synthesize new method symbol + env.info.varArgs = false; + sym = findPolymorphicSignatureInstance(env, + site, name, null, argtypes); + } + else { + //if nothing is found return the 'first' error + MethodResolutionPhase errPhase = + currentResolutionContext.firstErroneousResolutionPhase(); + sym = access(currentResolutionContext.resolutionCache.get(errPhase), + pos, location, site, name, true, argtypes, typeargtypes); + env.info.varArgs = errPhase.isVarargsRequired; + } + } else if (allowMethodHandles && sym.isPolymorphicSignatureGeneric()) { + //non-instantiated polymorphic signature - synthesize new method symbol env.info.varArgs = false; sym = findPolymorphicSignatureInstance(env, - site, name, null, argtypes); + site, name, (MethodSymbol)sym, argtypes); } - else { - //if nothing is found return the 'first' error - MethodResolutionPhase errPhase = - firstErroneousResolutionPhase(); - sym = access(methodResolutionCache.get(errPhase), - pos, location, site, name, true, argtypes, typeargtypes); - env.info.varArgs = errPhase.isVarargsRequired; - } - } else if (allowMethodHandles && sym.isPolymorphicSignatureGeneric()) { - //non-instantiated polymorphic signature - synthesize new method symbol - env.info.varArgs = false; - sym = findPolymorphicSignatureInstance(env, - site, name, (MethodSymbol)sym, argtypes); + return sym; } - return sym; + finally { + currentResolutionContext = prevResolutionContext; + } } /** Find or create an implicit method of exactly the given type (after erasure). @@ -1726,19 +1751,14 @@ Type site, Name name, List argtypes, List typeargtypes) { - boolean prevInternal = internalResolution; - try { - internalResolution = true; - Symbol sym = resolveQualifiedMethod( - pos, env, site.tsym, site, name, argtypes, typeargtypes); - if (sym.kind == MTH) return (MethodSymbol)sym; - else throw new FatalError( - diags.fragment("fatal.err.cant.locate.meth", - name)); - } - finally { - internalResolution = prevInternal; - } + MethodResolutionContext resolveContext = new MethodResolutionContext(); + resolveContext.internalResolution = true; + Symbol sym = resolveQualifiedMethod(resolveContext, pos, env, site.tsym, + site, name, argtypes, typeargtypes); + if (sym.kind == MTH) return (MethodSymbol)sym; + else throw new FatalError( + diags.fragment("fatal.err.cant.locate.meth", + name)); } /** Resolve constructor. @@ -1755,25 +1775,40 @@ Type site, List argtypes, List typeargtypes) { - Symbol sym = startResolution(); - List steps = methodResolutionSteps; - while (steps.nonEmpty() && - steps.head.isApplicable(boxingEnabled, varargsEnabled) && - sym.kind >= ERRONEOUS) { - currentStep = steps.head; - sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, - steps.head.isBoxingRequired(), - env.info.varArgs = steps.head.isVarargsRequired()); - methodResolutionCache.put(steps.head, sym); - steps = steps.tail; + return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes); + } + private Symbol resolveConstructor(MethodResolutionContext resolveContext, + DiagnosticPosition pos, + Env env, + Type site, + List argtypes, + List typeargtypes) { + MethodResolutionContext prevResolutionContext = currentResolutionContext; + try { + currentResolutionContext = resolveContext; + Symbol sym = methodNotFound; + List steps = methodResolutionSteps; + while (steps.nonEmpty() && + steps.head.isApplicable(boxingEnabled, varargsEnabled) && + sym.kind >= ERRONEOUS) { + currentResolutionContext.step = steps.head; + sym = findConstructor(pos, env, site, argtypes, typeargtypes, + steps.head.isBoxingRequired(), + env.info.varArgs = steps.head.isVarargsRequired()); + currentResolutionContext.resolutionCache.put(steps.head, sym); + steps = steps.tail; + } + if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error + MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase(); + sym = access(currentResolutionContext.resolutionCache.get(errPhase), + pos, site, names.init, true, argtypes, typeargtypes); + env.info.varArgs = errPhase.isVarargsRequired(); + } + return sym; } - if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error - MethodResolutionPhase errPhase = firstErroneousResolutionPhase(); - sym = access(methodResolutionCache.get(errPhase), - pos, site, names.init, true, argtypes, typeargtypes); - env.info.varArgs = errPhase.isVarargsRequired(); + finally { + currentResolutionContext = prevResolutionContext; } - return sym; } /** Resolve constructor using diamond inference. @@ -1791,38 +1826,82 @@ Type site, List argtypes, List typeargtypes) { - Symbol sym = startResolution(); - List steps = methodResolutionSteps; - while (steps.nonEmpty() && - steps.head.isApplicable(boxingEnabled, varargsEnabled) && - sym.kind >= ERRONEOUS) { - currentStep = steps.head; - sym = resolveConstructor(pos, env, site, argtypes, typeargtypes, - steps.head.isBoxingRequired(), - env.info.varArgs = steps.head.isVarargsRequired()); - methodResolutionCache.put(steps.head, sym); - steps = steps.tail; + MethodResolutionContext prevResolutionContext = currentResolutionContext; + try { + currentResolutionContext = new MethodResolutionContext(); + Symbol sym = methodNotFound; + List steps = methodResolutionSteps; + while (steps.nonEmpty() && + steps.head.isApplicable(boxingEnabled, varargsEnabled) && + sym.kind >= ERRONEOUS) { + currentResolutionContext.step = steps.head; + sym = findDiamond(env, site, argtypes, typeargtypes, + steps.head.isBoxingRequired(), + env.info.varArgs = steps.head.isVarargsRequired()); + currentResolutionContext.resolutionCache.put(steps.head, sym); + steps = steps.tail; + } + if (sym.kind >= AMBIGUOUS) { + final JCDiagnostic details = sym.kind == WRONG_MTH ? + currentResolutionContext.candidates.head.details : + null; + Symbol errSym = new ResolveError(WRONG_MTH, "diamond error") { + @Override + JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, + Symbol location, Type site, Name name, List argtypes, List typeargtypes) { + String key = details == null ? + "cant.apply.diamond" : + "cant.apply.diamond.1"; + return diags.create(dkind, log.currentSource(), pos, key, + diags.fragment("diamond", site.tsym), details); + } + }; + MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase(); + sym = access(errSym, pos, site, names.init, true, argtypes, typeargtypes); + env.info.varArgs = errPhase.isVarargsRequired(); + } + return sym; } - if (sym.kind >= AMBIGUOUS) { - final JCDiagnostic details = sym.kind == WRONG_MTH ? - ((InapplicableSymbolError)sym).explanation : - null; - Symbol errSym = new ResolveError(WRONG_MTH, "diamond error") { - @Override - JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, - Symbol location, Type site, Name name, List argtypes, List typeargtypes) { - String key = details == null ? - "cant.apply.diamond" : - "cant.apply.diamond.1"; - return diags.create(dkind, log.currentSource(), pos, key, - diags.fragment("diamond", site.tsym), details); - } - }; - MethodResolutionPhase errPhase = firstErroneousResolutionPhase(); - sym = access(errSym, pos, site, names.init, true, argtypes, typeargtypes); - env.info.varArgs = errPhase.isVarargsRequired(); + finally { + currentResolutionContext = prevResolutionContext; } - return sym; + } + + /** This method scans all the constructor symbol in a given class scope - + * assuming that the original scope contains a constructor of the kind: + * Foo(X x, Y y), where X,Y are class type-variables declared in Foo, + * a method check is executed against the modified constructor type: + * Foo(X x, Y y). This is crucial in order to enable diamond + * inference. The inferred return type of the synthetic constructor IS + * the inferred type for the diamond operator. + */ + private Symbol findDiamond(Env env, + Type site, + List argtypes, + List typeargtypes, + boolean allowBoxing, + boolean useVarargs) { + Symbol bestSoFar = methodNotFound; + for (Scope.Entry e = site.tsym.members().lookup(names.init); + e.scope != null; + e = e.next()) { + //- System.out.println(" e " + e.sym); + if (e.sym.kind == MTH && + (e.sym.flags_field & SYNTHETIC) == 0) { + List oldParams = e.sym.type.tag == FORALL ? + ((ForAll)e.sym.type).tvars : + List.nil(); + Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams), + types.createMethodTypeWithReturn(e.sym.type.asMethodType(), site)); + bestSoFar = selectBest(env, site, argtypes, typeargtypes, + new MethodSymbol(e.sym.flags(), names.init, constrType, site.tsym), + bestSoFar, + allowBoxing, + useVarargs, + false); + } + } + return bestSoFar; } /** Resolve constructor. @@ -1841,10 +1920,25 @@ List typeargtypes, boolean allowBoxing, boolean useVarargs) { + MethodResolutionContext prevResolutionContext = currentResolutionContext; + try { + currentResolutionContext = new MethodResolutionContext(); + return findConstructor(pos, env, site, argtypes, typeargtypes, allowBoxing, useVarargs); + } + finally { + currentResolutionContext = prevResolutionContext; + } + } + + Symbol findConstructor(DiagnosticPosition pos, Env env, + Type site, List argtypes, + List typeargtypes, + boolean allowBoxing, + boolean useVarargs) { Symbol sym = findMethod(env, site, - names.init, argtypes, - typeargtypes, allowBoxing, - useVarargs, false); + names.init, argtypes, + typeargtypes, allowBoxing, + useVarargs, false); chk.checkDeprecated(pos, env.info.scope.owner, sym); return sym; } @@ -1860,8 +1954,9 @@ Type site, List argtypes, List typeargtypes) { - Symbol sym = resolveConstructor( - pos, env, site, argtypes, typeargtypes); + MethodResolutionContext resolveContext = new MethodResolutionContext(); + resolveContext.internalResolution = true; + Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes); if (sym.kind == MTH) return (MethodSymbol)sym; else throw new FatalError( diags.fragment("fatal.err.cant.locate.ctor", site)); @@ -1875,15 +1970,21 @@ */ Symbol resolveOperator(DiagnosticPosition pos, JCTree.Tag optag, Env env, List argtypes) { - startResolution(); - Name name = treeinfo.operatorName(optag); - Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes, - null, false, false, true); - if (boxingEnabled && sym.kind >= WRONG_MTHS) - sym = findMethod(env, syms.predefClass.type, name, argtypes, - null, true, false, true); - return access(sym, pos, env.enclClass.sym.type, name, - false, argtypes, null); + MethodResolutionContext prevResolutionContext = currentResolutionContext; + try { + currentResolutionContext = new MethodResolutionContext(); + Name name = treeinfo.operatorName(optag); + Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes, + null, false, false, true); + if (boxingEnabled && sym.kind >= WRONG_MTHS) + sym = findMethod(env, syms.predefClass.type, name, argtypes, + null, true, false, true); + return access(sym, pos, env.enclClass.sym.type, name, + false, argtypes, null); + } + finally { + currentResolutionContext = prevResolutionContext; + } } /** Resolve operator. @@ -1996,9 +2097,10 @@ * ResolveError classes, indicating error situations when accessing symbols ****************************************************************************/ - public void logAccessError(Env env, JCTree tree, Type type) { - AccessError error = new AccessError(env, type.getEnclosingType(), type.tsym); - logResolveError(error, tree.pos(), type.getEnclosingType().tsym, type.getEnclosingType(), null, null, null); + //used by TransTypes when checking target type of synthetic cast + public void logAccessErrorInternal(Env env, JCTree tree, Type type) { + AccessError error = new AccessError(env, env.enclClass.type, type.tsym); + logResolveError(error, tree.pos(), env.enclClass.sym, env.enclClass.type, null, null, null); } //where private void logResolveError(ResolveError error, @@ -2227,34 +2329,24 @@ * (either a method, a constructor or an operand) is not applicable * given an actual arguments/type argument list. */ - class InapplicableSymbolError extends InvalidSymbolError { + class InapplicableSymbolError extends ResolveError { - /** An auxiliary explanation set in case of instantiation errors. */ - JCDiagnostic explanation; - - InapplicableSymbolError(Symbol sym) { - super(WRONG_MTH, sym, "inapplicable symbol error"); + InapplicableSymbolError() { + super(WRONG_MTH, "inapplicable symbol error"); } - /** Update sym and explanation and return this. - */ - InapplicableSymbolError setWrongSym(Symbol sym, JCDiagnostic explanation) { - this.sym = sym; - if (this.sym == sym && explanation != null) - this.explanation = explanation; //update the details - return this; - } - - /** Update sym and return this. - */ - InapplicableSymbolError setWrongSym(Symbol sym) { - this.sym = sym; - return this; + protected InapplicableSymbolError(int kind, String debugName) { + super(kind, debugName); } @Override public String toString() { - return super.toString() + " explanation=" + explanation; + return super.toString(); + } + + @Override + public boolean exists() { + return true; } @Override @@ -2279,27 +2371,40 @@ key, name, first, second); } else { - Symbol ws = sym.asMemberOf(site, types); + Candidate c = errCandidate(); + Symbol ws = c.sym.asMemberOf(site, types); return diags.create(dkind, log.currentSource(), pos, - "cant.apply.symbol" + (explanation != null ? ".1" : ""), + "cant.apply.symbol" + (c.details != null ? ".1" : ""), kindName(ws), ws.name == names.init ? ws.owner.name : ws.name, methodArguments(ws.type.getParameterTypes()), methodArguments(argtypes), kindName(ws.owner), ws.owner.type, - explanation); + c.details); } } - void clear() { - explanation = null; - } - @Override public Symbol access(Name name, TypeSymbol location) { return types.createErrorType(name, location, syms.errSymbol.type).tsym; } + + protected boolean shouldReport(Candidate c) { + return !c.isApplicable() && + (((c.sym.flags() & VARARGS) != 0 && c.step == VARARITY) || + (c.sym.flags() & VARARGS) == 0 && c.step == (boxingEnabled ? BOX : BASIC)); + } + + private Candidate errCandidate() { + for (Candidate c : currentResolutionContext.candidates) { + if (shouldReport(c)) { + return c; + } + } + Assert.error(); + return null; + } } /** @@ -2307,11 +2412,9 @@ * (either methods, constructors or operands) is not applicable * given an actual arguments/type argument list. */ - class InapplicableSymbolsError extends ResolveError { + class InapplicableSymbolsError extends InapplicableSymbolError { - private List candidates = List.nil(); - - InapplicableSymbolsError(Symbol sym) { + InapplicableSymbolsError() { super(WRONG_MTHS, "inapplicable symbols"); } @@ -2323,7 +2426,7 @@ Name name, List argtypes, List typeargtypes) { - if (candidates.nonEmpty()) { + if (currentResolutionContext.candidates.nonEmpty()) { JCDiagnostic err = diags.create(dkind, log.currentSource(), pos, @@ -2341,68 +2444,24 @@ //where List candidateDetails(Type site) { List details = List.nil(); - for (Candidate c : candidates) - details = details.prepend(c.getDiagnostic(site)); + for (Candidate c : currentResolutionContext.candidates) { + if (!shouldReport(c)) continue; + JCDiagnostic detailDiag = diags.fragment("inapplicable.method", + Kinds.kindName(c.sym), + c.sym.location(site, types), + c.sym.asMemberOf(site, types), + c.details); + details = details.prepend(detailDiag); + } return details.reverse(); } - Symbol addCandidate(MethodResolutionPhase currentStep, Symbol sym, JCDiagnostic details) { - Candidate c = new Candidate(currentStep, sym, details); - if (c.isValid() && !candidates.contains(c)) - candidates = candidates.append(c); - return this; - } - - void clear() { - candidates = List.nil(); - } - private Name getName() { - Symbol sym = candidates.head.sym; + Symbol sym = currentResolutionContext.candidates.head.sym; return sym.name == names.init ? sym.owner.name : sym.name; } - - private class Candidate { - - final MethodResolutionPhase step; - final Symbol sym; - final JCDiagnostic details; - - private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details) { - this.step = step; - this.sym = sym; - this.details = details; - } - - JCDiagnostic getDiagnostic(Type site) { - return diags.fragment("inapplicable.method", - Kinds.kindName(sym), - sym.location(site, types), - sym.asMemberOf(site, types), - details); - } - - @Override - public boolean equals(Object o) { - if (o instanceof Candidate) { - Symbol s1 = this.sym; - Symbol s2 = ((Candidate)o).sym; - if ((s1 != s2 && - (s1.overrides(s2, s1.owner.type.tsym, types, false) || - (s2.overrides(s1, s2.owner.type.tsym, types, false)))) || - ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner)) - return true; - } - return false; - } - - boolean isValid() { - return (((sym.flags() & VARARGS) != 0 && step == VARARITY) || - (sym.flags() & VARARGS) == 0 && step == (boxingEnabled ? BOX : BASIC)); - } - } } /** @@ -2563,29 +2622,91 @@ } } - private Map methodResolutionCache = - new HashMap(MethodResolutionPhase.values().length); - - private Map verboseResolutionCandidateDiags = - new LinkedHashMap(); - final List methodResolutionSteps = List.of(BASIC, BOX, VARARITY); - private MethodResolutionPhase currentStep = null; + /** + * A resolution context is used to keep track of intermediate results of + * overload resolution, such as list of method that are not applicable + * (used to generate more precise diagnostics) and so on. Resolution contexts + * can be nested - this means that when each overload resolution routine should + * work within the resolution context it created. + */ + class MethodResolutionContext { - private boolean internalResolution = false; + private List candidates = List.nil(); - private MethodResolutionPhase firstErroneousResolutionPhase() { - MethodResolutionPhase bestSoFar = BASIC; - Symbol sym = methodNotFound; - List steps = methodResolutionSteps; - while (steps.nonEmpty() && - steps.head.isApplicable(boxingEnabled, varargsEnabled) && - sym.kind >= WRONG_MTHS) { - sym = methodResolutionCache.get(steps.head); - bestSoFar = steps.head; - steps = steps.tail; + private Map resolutionCache = + new EnumMap(MethodResolutionPhase.class); + + private MethodResolutionPhase step = null; + + private boolean internalResolution = false; + + private MethodResolutionPhase firstErroneousResolutionPhase() { + MethodResolutionPhase bestSoFar = BASIC; + Symbol sym = methodNotFound; + List steps = methodResolutionSteps; + while (steps.nonEmpty() && + steps.head.isApplicable(boxingEnabled, varargsEnabled) && + sym.kind >= WRONG_MTHS) { + sym = resolutionCache.get(steps.head); + bestSoFar = steps.head; + steps = steps.tail; + } + return bestSoFar; } - return bestSoFar; + + void addInapplicableCandidate(Symbol sym, JCDiagnostic details) { + Candidate c = new Candidate(currentResolutionContext.step, sym, details, null); + if (!candidates.contains(c)) + candidates = candidates.append(c); + } + + void addApplicableCandidate(Symbol sym, Type mtype) { + Candidate c = new Candidate(currentResolutionContext.step, sym, null, mtype); + candidates = candidates.append(c); + } + + /** + * This class represents an overload resolution candidate. There are two + * kinds of candidates: applicable methods and inapplicable methods; + * applicable methods have a pointer to the instantiated method type, + * while inapplicable candidates contain further details about the + * reason why the method has been considered inapplicable. + */ + class Candidate { + + final MethodResolutionPhase step; + final Symbol sym; + final JCDiagnostic details; + final Type mtype; + + private Candidate(MethodResolutionPhase step, Symbol sym, JCDiagnostic details, Type mtype) { + this.step = step; + this.sym = sym; + this.details = details; + this.mtype = mtype; + } + + @Override + public boolean equals(Object o) { + if (o instanceof Candidate) { + Symbol s1 = this.sym; + Symbol s2 = ((Candidate)o).sym; + if ((s1 != s2 && + (s1.overrides(s2, s1.owner.type.tsym, types, false) || + (s2.overrides(s1, s2.owner.type.tsym, types, false)))) || + ((s1.isConstructor() || s2.isConstructor()) && s1.owner != s2.owner)) + return true; + } + return false; + } + + boolean isApplicable() { + return mtype != null; + } + } } + + MethodResolutionContext currentResolutionContext = null; } diff -r a1af4b95c287 -r 08a3425f39f8 src/share/classes/com/sun/tools/javac/comp/TransTypes.java --- a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Thu Mar 08 20:35:26 2012 -0800 +++ b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Fri Mar 09 11:59:26 2012 -0800 @@ -107,7 +107,7 @@ make.at(tree.pos); if (!types.isSameType(tree.type, target)) { if (!resolve.isAccessible(env, target.tsym)) - resolve.logAccessError(env, tree, target); + resolve.logAccessErrorInternal(env, tree, target); tree = make.TypeCast(make.Type(target), tree).setType(target); } make.pos = oldpos; diff -r a1af4b95c287 -r 08a3425f39f8 src/share/classes/com/sun/tools/javac/tree/TreeInfo.java --- a/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Thu Mar 08 20:35:26 2012 -0800 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Fri Mar 09 11:59:26 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2012, 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 @@ -102,6 +102,16 @@ setOpname(MOD, "%", names); } + public static List args(JCTree t) { + switch (t.getTag()) { + case APPLY: + return ((JCMethodInvocation)t).args; + case NEWCLASS: + return ((JCNewClass)t).args; + default: + return null; + } + } /** Return name of operator with given tree tag. */ diff -r a1af4b95c287 -r 08a3425f39f8 test/Makefile --- a/test/Makefile Thu Mar 08 20:35:26 2012 -0800 +++ b/test/Makefile Fri Mar 09 11:59:26 2012 -0800 @@ -36,6 +36,14 @@ ARCH=i586 endif endif +ifeq ($(OSNAME), Darwin) + PLATFORM = bsd + JT_PLATFORM = linux + ARCH = $(shell uname -m) + ifeq ($(ARCH), i386) + ARCH=i586 + endif +endif ifeq ($(OSNAME), Windows_NT) # MKS PLATFORM=windows @@ -251,6 +259,7 @@ # JTREG_REFERENCE # (Optional) reference results (e.g. work, report or summary.txt) # +jtreg_tests: jtreg-tests jtreg-tests: check-jtreg FRC @rm -f -r $(JTREG_OUTPUT_DIR)/JTwork $(JTREG_OUTPUT_DIR)/JTreport \ $(JTREG_OUTPUT_DIR)/diff.html $(JTREG_OUTPUT_DIR)/status.txt diff -r a1af4b95c287 -r 08a3425f39f8 test/jprt.config --- a/test/jprt.config Thu Mar 08 20:35:26 2012 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,159 +0,0 @@ -#!echo "This is not a shell script" -############################################################################# -# Copyright (c) 2006, 2007, 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. -############################################################################# -# -# JPRT shell configuration for testing. -# -# Input environment variables: -# Windows Only: -# PATH -# ROOTDIR -# -# Output variable settings: -# make Full path to GNU make -# -# Output environment variables: -# PATH -# -############################################################################# - -############################################################################# -# Error -error() # message -{ - echo "ERROR: $1" - exit 6 -} -# Directory must exist -dirMustExist() # dir name -{ - if [ ! -d "$1" ] ; then - error "Directory for $2 does not exist: $1" - fi -} -# File must exist -fileMustExist() # dir name -{ - if [ ! -f "$1" ] ; then - error "File for $2 does not exist: $1" - fi -} -############################################################################# - -# Should be set by JPRT as the 3 basic inputs -slashjava="${ALT_SLASH_JAVA}" -if [ "${slashjava}" = "" ] ; then - slashjava=/java -fi - -# Check input -dirMustExist "${slashjava}" ALT_SLASH_JAVA - -# Uses 'uname -s', but only expect SunOS or Linux, assume Windows otherwise. -osname=`uname -s` -if [ "${osname}" = SunOS ] ; then - - # SOLARIS: Sparc or X86 - osarch=`uname -p` - if [ "${osarch}" = sparc ] ; then - solaris_arch=sparc - else - solaris_arch=i386 - fi - - # Add basic solaris system paths - path4sdk=/usr/ccs/bin:/usr/ccs/lib:/usr/bin:/bin:/usr/sfw/bin - - # Find GNU make - make=/usr/sfw/bin/gmake - if [ ! -f ${make} ] ; then - make=/opt/sfw/bin/gmake - if [ ! -f ${make} ] ; then - make=${slashjava}/devtools/${solaris_arch}/bin/gnumake - fi - fi - fileMustExist "${make}" make - - # File creation mask - umask 002 - -elif [ "${osname}" = Linux ] ; then - - # Add basic paths - path4sdk=/usr/bin:/bin:/usr/sbin:/sbin - - # Find GNU make - make=/usr/bin/make - fileMustExist "${make}" make - - umask 002 - -else - - # Windows: Differs on CYGWIN vs. MKS. - - # We need to determine if we are running a CYGWIN shell or an MKS shell - # (if uname isn't available, then it will be unix_toolset=unknown) - unix_toolset=unknown - if [ "`uname -a | fgrep Cygwin`" = "" -a -d "${ROOTDIR}" ] ; then - # We kind of assume ROOTDIR is where MKS is and it's ok - unix_toolset=MKS - mkshome=`dosname -s "${ROOTDIR}"` - # Most unix utilities are in the mksnt directory of ROOTDIR - unixcommand_path="${mkshome}/mksnt" - path4sdk="${unixcommand_path}" - devtools_path="${slashjava}/devtools/win32/bin" - path4sdk="${devtools_path};${path4sdk}" - # Find GNU make - make="${devtools_path}/gnumake.exe" - fileMustExist "${make}" make - elif [ "`uname -a | fgrep Cygwin`" != "" -a -f /bin/cygpath ] ; then - # For CYGWIN, uname will have "Cygwin" in it, and /bin/cygpath should exist - unix_toolset=CYGWIN - # Most unix utilities are in the /usr/bin - unixcommand_path="/usr/bin" - path4sdk="${unixcommand_path}" - # Find GNU make - make="${unixcommand_path}/make.exe" - fileMustExist "${make}" make - else - echo "WARNING: Cannot figure out if this is MKS or CYGWIN" - fi - - - # For windows, it's hard to know where the system is, so we just add this - # to PATH. - slash_path="`echo ${path4sdk} | sed -e 's@\\\\@/@g' -e 's@//@/@g' -e 's@/$@@' -e 's@/;@;@g'`" - path4sdk="${slash_path};${PATH}" - - # Convert path4sdk to cygwin style - if [ "${unix_toolset}" = CYGWIN ] ; then - path4sdk="`/usr/bin/cygpath -p ${path4sdk}`" - fi - -fi - -# Export PATH setting -PATH="${path4sdk}" -export PATH - diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/4846262/Test.sh --- a/test/tools/javac/4846262/Test.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javac/4846262/Test.sh Fri Mar 09 11:59:26 2012 -0800 @@ -44,7 +44,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux ) + SunOS | Linux | Darwin ) FS="/" ;; CYGWIN* ) diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/6302184/T6302184.sh --- a/test/tools/javac/6302184/T6302184.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javac/6302184/T6302184.sh Fri Mar 09 11:59:26 2012 -0800 @@ -41,7 +41,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux ) + SunOS | Linux | Darwin ) FS="/" ;; CYGWIN* ) diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/7132880/T7132880.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/7132880/T7132880.java Fri Mar 09 11:59:26 2012 -0800 @@ -0,0 +1,60 @@ +/* + * @test /nodynamiccopyright/ + * @bug 7132880 + * @summary Resolve should support nested resolution contexts + * @compile/fail/ref=T7132880.out -XDrawDiagnostics T7132880.java + */ +class Outer { + void m1(String s) { } + void m2(int i1, int i2) { } + + class Inner { + void test() { + //ok - no method named 'm' in Inner - hence, class to search is Outer + m1(""); + } + } + + class Inner1 { + void m1(Integer i) { } + + void test() { + //error - Inner1 defines an incompatible method - hence, class to search is Inner1 + m1(""); + } + } + + class Inner2 { + private void m1(Integer i) { } + private void m1(Double d) { } + + void test() { + //error - Inner2 defines multiple incompatible methods - hence, class to search is Inner2 + m1(""); + } + } + + class Inner3 { + private void m2(Object o, int i) { } + private void m2(int i, Object o) { } + + void test() { + //error - Inner3 defines multiple ambiguous methods - hence, class to search is Inner3 + m2(1, 1); + } + } + + class Inner4 extends Inner2 { + void test() { + //ok - Inner2 defines multiple incompatible inaccessible methods - hence, class to search is Outer + m1(""); + } + } + + class Inner5 extends Inner3 { + void test() { + //ok - Inner3 defines multiple inaccessible ambiguous methods - hence, class to search is Outer + m2(1, 1); + } + } +} diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/7132880/T7132880.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/7132880/T7132880.out Fri Mar 09 11:59:26 2012 -0800 @@ -0,0 +1,4 @@ +T7132880.java:23:12: compiler.err.cant.apply.symbol.1: kindname.method, m1, java.lang.Integer, java.lang.String, kindname.class, Outer.Inner1, (compiler.misc.no.conforming.assignment.exists: java.lang.String, java.lang.Integer) +T7132880.java:33:12: compiler.err.cant.apply.symbols: kindname.method, m1, java.lang.String,{(compiler.misc.inapplicable.method: kindname.method, Outer.Inner2, m1(java.lang.Double), (compiler.misc.no.conforming.assignment.exists: java.lang.String, java.lang.Double)),(compiler.misc.inapplicable.method: kindname.method, Outer.Inner2, m1(java.lang.Integer), (compiler.misc.no.conforming.assignment.exists: java.lang.String, java.lang.Integer))} +T7132880.java:43:12: compiler.err.ref.ambiguous: m2, kindname.method, m2(java.lang.Object,int), Outer.Inner3, kindname.method, m2(int,java.lang.Object), Outer.Inner3 +3 errors diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/ClassPathTest/ClassPathTest.sh --- a/test/tools/javac/ClassPathTest/ClassPathTest.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javac/ClassPathTest/ClassPathTest.sh Fri Mar 09 11:59:26 2012 -0800 @@ -56,7 +56,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux | CYGWIN* ) + SunOS | Linux | Darwin | CYGWIN* ) FS="/" ;; Windows* ) diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/ExtDirs/ExtDirs.sh --- a/test/tools/javac/ExtDirs/ExtDirs.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javac/ExtDirs/ExtDirs.sh Fri Mar 09 11:59:26 2012 -0800 @@ -54,7 +54,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux ) + SunOS | Linux | Darwin ) PS=":" FS="/" ;; diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/MissingInclude.sh --- a/test/tools/javac/MissingInclude.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javac/MissingInclude.sh Fri Mar 09 11:59:26 2012 -0800 @@ -47,7 +47,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux | CYGWIN* ) + SunOS | Linux | Darwin | CYGWIN* ) FS="/" ;; Windows* ) diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/ProtectedInnerClass/ProtectedInnerClass.sh --- a/test/tools/javac/ProtectedInnerClass/ProtectedInnerClass.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javac/ProtectedInnerClass/ProtectedInnerClass.sh Fri Mar 09 11:59:26 2012 -0800 @@ -52,7 +52,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux ) + SunOS | Linux | Darwin ) PS=":" FS="/" ;; diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/T5090006/compiler.sh --- a/test/tools/javac/T5090006/compiler.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javac/T5090006/compiler.sh Fri Mar 09 11:59:26 2012 -0800 @@ -47,7 +47,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux | CYGWIN* ) + SunOS | Linux | Darwin | CYGWIN* ) FS="/" ;; Windows* ) diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/constDebug/ConstDebug.sh --- a/test/tools/javac/constDebug/ConstDebug.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javac/constDebug/ConstDebug.sh Fri Mar 09 11:59:26 2012 -0800 @@ -47,7 +47,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux ) + SunOS | Linux | Darwin ) PS=":" FS="/" ;; diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/fatalErrors/NoJavaLang.sh --- a/test/tools/javac/fatalErrors/NoJavaLang.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javac/fatalErrors/NoJavaLang.sh Fri Mar 09 11:59:26 2012 -0800 @@ -48,7 +48,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux ) + SunOS | Linux | Darwin ) FS="/" ;; CYGWIN* ) diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/generics/6723444/T6723444.out --- a/test/tools/javac/generics/6723444/T6723444.out Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javac/generics/6723444/T6723444.out Fri Mar 09 11:59:26 2012 -0800 @@ -1,5 +1,5 @@ -T6723444.java:42:9: compiler.err.unreported.exception.need.to.catch.or.throw: X2 -T6723444.java:43:9: compiler.err.unreported.exception.need.to.catch.or.throw: X2 +T6723444.java:42:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable +T6723444.java:43:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable T6723444.java:45:32: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable T6723444.java:46:17: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable T6723444.java:48:9: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/generics/7151070/T7151070.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/7151070/T7151070.java Fri Mar 09 11:59:26 2012 -0800 @@ -0,0 +1,25 @@ +/* + * @test /nodynamiccopyright/ + * @bug 7151070 + * @summary NullPointerException in Resolve.isAccessible + * @compile/fail/ref=T7151070.out -XDrawDiagnostics T7151070.java + */ + +class T7151070a { + private static class PrivateCls { } + public static class PublicCls extends PrivateCls { } + + public void m(PrivateCls p) { } +} + +class T7151070b { + public void test(Test obj, T7151070a outer) { + outer.m(obj.get()); + } + + public static class Test { + public T get() { + return null; + } + } +} diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/generics/7151070/T7151070.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/7151070/T7151070.out Fri Mar 09 11:59:26 2012 -0800 @@ -0,0 +1,2 @@ +T7151070.java:17:24: compiler.err.report.access: T7151070a.PrivateCls, private, T7151070a +1 error diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/generics/7151802/T7151802.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/7151802/T7151802.java Fri Mar 09 11:59:26 2012 -0800 @@ -0,0 +1,43 @@ +/* + * @test /nodynamiccopyright/ + * @bug 7151802 + * @summary compiler update caused sqe test failed + * @compile/fail/ref=T7151802.out -Werror -Xlint:unchecked -XDrawDiagnostics T7151802.java + */ +class T7151802 { + static class Foo { } + + static class SubFoo extends Foo { } + + //generic - bound - arg - non-slilent + > void get1(Z fz) { } + void test1(Foo foo) { get1(foo); } + + //generic - bound - arg - silent + > void get2(Z fz) { } + void test2(Foo foo) { get2(foo); } + + //generic - nobound - arg - non-slilent + void get3(Foo fz) { } + void test(Foo foo) { get3(foo); } + + //generic - nobound - arg - slilent + void get4(Foo fz) { } + void test4(Foo foo) { get4(foo); } + + //generic - bound - ret - non-slilent + > Z get5() { return null; } + void test5() { SubFoo sf = get5(); } + + //generic - bound - ret - slilent + static > Z get6() { return null; } + void test6() { SubFoo sf = get6(); } + + //nogeneric - nobound - arg - non-slilent + void get7(Foo fz) { } + void test7(Foo foo) { get7(foo); } + + //nogeneric - nobound - arg - slilent + static void get8(Foo fz) { } + void test8(Foo foo) { get8(foo); } +} diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/generics/7151802/T7151802.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/7151802/T7151802.out Fri Mar 09 11:59:26 2012 -0800 @@ -0,0 +1,9 @@ +T7151802.java:14:31: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get1, Z, T7151802.Foo, kindname.class, T7151802 +T7151802.java:22:31: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo +T7151802.java:22:30: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get3, T7151802.Foo, T7151802.Foo, kindname.class, T7151802 +T7151802.java:30:36: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get5, compiler.misc.no.args, compiler.misc.no.args, kindname.class, T7151802 +T7151802.java:38:32: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), T7151802.Foo, T7151802.Foo +T7151802.java:38:31: compiler.warn.unchecked.meth.invocation.applied: kindname.method, get7, T7151802.Foo, T7151802.Foo, kindname.class, T7151802 +- compiler.err.warnings.and.werror +1 error +6 warnings diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/generics/rawOverride/T7148556.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/rawOverride/T7148556.java Fri Mar 09 11:59:26 2012 -0800 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012, 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 7148556 + * @summary Implementing a generic interface causes a public clone() to become inaccessible + * @compile T7148556.java + */ + +class T7148556 { + + interface A extends Cloneable { + public Object clone(); + } + + interface B extends A, java.util.List { } + + void test(B b) { + b.clone(); + } +} diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/generics/typevars/T7148242.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/generics/typevars/T7148242.java Fri Mar 09 11:59:26 2012 -0800 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2009, 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 7148242 + * @summary Regression: valid code rejected during generic type well-formedness check + * @compile T7148242.java + */ +class T7148242 { + static abstract class A, I2 extends Pair> { + abstract A test(); + } + static class Pair { } +} diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/innerClassFile/Driver.sh --- a/test/tools/javac/innerClassFile/Driver.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javac/innerClassFile/Driver.sh Fri Mar 09 11:59:26 2012 -0800 @@ -53,7 +53,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux | CYGWIN* ) + SunOS | Linux | Darwin | CYGWIN* ) FS="/" ;; Windows* ) diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/javazip/Test.sh --- a/test/tools/javac/javazip/Test.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javac/javazip/Test.sh Fri Mar 09 11:59:26 2012 -0800 @@ -41,7 +41,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux ) + SunOS | Linux | Darwin ) FS="/" SCR=`pwd` ;; diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/links/links.sh --- a/test/tools/javac/links/links.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javac/links/links.sh Fri Mar 09 11:59:26 2012 -0800 @@ -53,7 +53,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux ) + SunOS | Linux | Darwin ) NULL=/dev/null PS=":" FS="/" diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/newlines/Newlines.sh --- a/test/tools/javac/newlines/Newlines.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javac/newlines/Newlines.sh Fri Mar 09 11:59:26 2012 -0800 @@ -50,7 +50,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux | CYGWIN* ) + SunOS | Linux | Darwin | CYGWIN* ) FS="/" ;; Windows* ) diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/stackmap/T4955930.sh --- a/test/tools/javac/stackmap/T4955930.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javac/stackmap/T4955930.sh Fri Mar 09 11:59:26 2012 -0800 @@ -41,7 +41,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux | CYGWIN* ) + SunOS | Linux | Darwin | CYGWIN* ) FS="/" ;; Windows_95 | Windows_98 | Windows_NT ) diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javac/unicode/SupplementaryJavaID6.sh --- a/test/tools/javac/unicode/SupplementaryJavaID6.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javac/unicode/SupplementaryJavaID6.sh Fri Mar 09 11:59:26 2012 -0800 @@ -55,7 +55,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux ) + SunOS | Linux | Darwin ) if [ -d /usr/lib/locale/en_US.UTF-8 -o -d /usr/lib/locale/en_US.utf8 ] then ENV="env LANG=en_US.UTF-8" diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javah/6257087/foo.sh --- a/test/tools/javah/6257087/foo.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javah/6257087/foo.sh Fri Mar 09 11:59:26 2012 -0800 @@ -41,7 +41,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux ) + SunOS | Linux | Darwin ) PS=":" FS="/" ;; diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javah/ConstMacroTest.sh --- a/test/tools/javah/ConstMacroTest.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javah/ConstMacroTest.sh Fri Mar 09 11:59:26 2012 -0800 @@ -56,7 +56,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux ) + SunOS | Linux | Darwin ) PS=":" FS="/" ;; diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javah/MissingParamClassTest.sh --- a/test/tools/javah/MissingParamClassTest.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javah/MissingParamClassTest.sh Fri Mar 09 11:59:26 2012 -0800 @@ -58,7 +58,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux | CYGWIN* ) + SunOS | Linux | Darwin | CYGWIN* ) PS=":" FS="/" ;; diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javah/ReadOldClass.sh --- a/test/tools/javah/ReadOldClass.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javah/ReadOldClass.sh Fri Mar 09 11:59:26 2012 -0800 @@ -43,7 +43,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux | CYGWIN* ) + SunOS | Linux | Darwin | CYGWIN* ) PS=":" FS="/" ;; diff -r a1af4b95c287 -r 08a3425f39f8 test/tools/javap/pathsep.sh --- a/test/tools/javap/pathsep.sh Thu Mar 08 20:35:26 2012 -0800 +++ b/test/tools/javap/pathsep.sh Fri Mar 09 11:59:26 2012 -0800 @@ -40,7 +40,7 @@ # set platform-dependent variables OS=`uname -s` case "$OS" in - SunOS | Linux | CYGWIN* ) + SunOS | Linux | Darwin | CYGWIN* ) FS="/" ;; Windows* )