7153951: Add new lint option -Xlint:auxiliaryclass
Reviewed-by: jjg, mcimadamore, forax
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Wed Oct 31 13:48:15 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Thu Nov 01 10:48:36 2012 +0100
@@ -258,6 +258,12 @@
*/
public static final long DEFAULT = 1L<<43;
+ /**
+ * Flag that marks class as auxiliary, ie a non-public class following
+ * the public class in a source file, that could block implicit compilation.
+ */
+ public static final long AUXILIARY = 1L<<43;
+
/** Modifier masks.
*/
public static final int
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Wed Oct 31 13:48:15 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Thu Nov 01 10:48:36 2012 +0100
@@ -129,6 +129,13 @@
*/
public enum LintCategory {
/**
+ * Warn when code refers to a auxiliary class that is hidden in a source file (ie source file name is
+ * different from the class name, and the type is not properly nested) and the referring code
+ * is not located in the same source file.
+ */
+ AUXILIARYCLASS("auxiliaryclass"),
+
+ /**
* Warn about use of unnecessary casts.
*/
CAST("cast"),
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Wed Oct 31 13:48:15 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Nov 01 10:48:36 2012 +0100
@@ -3050,6 +3050,7 @@
// except for two situations:
owntype = sym.type;
if (owntype.hasTag(CLASS)) {
+ chk.checkForBadAuxiliaryClassAccess(tree.pos(), env, (ClassSymbol)sym);
Type ownOuter = owntype.getEnclosingType();
// (a) If the symbol's type is parameterized, erase it
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Oct 31 13:48:15 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Thu Nov 01 10:48:36 2012 +0100
@@ -27,6 +27,7 @@
import java.util.*;
import java.util.Set;
+import javax.tools.JavaFileManager;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.jvm.*;
@@ -77,6 +78,7 @@
private boolean suppressAbortOnBadClassFile;
private boolean enableSunApiLintControl;
private final TreeInfo treeinfo;
+ private final JavaFileManager fileManager;
// The set of lint options currently in effect. It is initialized
// from the context, and then is set/reset as needed by Attr as it
@@ -109,6 +111,7 @@
Options options = Options.instance(context);
lint = Lint.instance(context);
treeinfo = TreeInfo.instance(context);
+ fileManager = context.get(JavaFileManager.class);
Source source = Source.instance(context);
allowGenerics = source.allowGenerics();
@@ -3230,6 +3233,19 @@
return true;
}
+ /** Check that an auxiliary class is not accessed from any other file than its own.
+ */
+ void checkForBadAuxiliaryClassAccess(DiagnosticPosition pos, Env<AttrContext> env, ClassSymbol c) {
+ if (lint.isEnabled(Lint.LintCategory.AUXILIARYCLASS) &&
+ (c.flags() & AUXILIARY) != 0 &&
+ rs.isAccessible(env, c) &&
+ !fileManager.isSameFile(c.sourcefile, env.toplevel.sourcefile))
+ {
+ log.warning(pos, "auxiliary.class.accessed.from.outside.of.its.source.file",
+ c, c.sourcefile);
+ }
+ }
+
private class ConversionWarner extends Warner {
final String uncheckedKey;
final Type found;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Wed Oct 31 13:48:15 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Thu Nov 01 10:48:36 2012 +0100
@@ -1022,11 +1022,13 @@
// name as a top-level package.
if (checkClash &&
c.owner.kind == PCK && c.owner != syms.unnamedPackage &&
- reader.packageExists(c.fullname))
- {
- log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), c);
- }
-
+ reader.packageExists(c.fullname)) {
+ log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), c);
+ }
+ if (c.owner.kind == PCK && (c.flags_field & PUBLIC) == 0 &&
+ !env.toplevel.sourcefile.isNameCompatible(c.name.toString(),JavaFileObject.Kind.SOURCE)) {
+ c.flags_field |= AUXILIARY;
+ }
} catch (CompletionFailure ex) {
chk.completionError(tree.pos(), ex);
} finally {
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Oct 31 13:48:15 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Thu Nov 01 10:48:36 2012 +0100
@@ -1018,6 +1018,15 @@
ClassSymbol c = (ClassSymbol) sym;
Name n = readName(nextChar());
c.sourcefile = new SourceFileObject(n, c.flatname);
+ // If the class is a toplevel class, originating from a Java source file,
+ // but the class name does not match the file name, then it is
+ // an auxiliary class.
+ String sn = n.toString();
+ if (c.owner.kind == Kinds.PCK &&
+ sn.endsWith(".java") &&
+ !sn.equals(c.name.toString()+".java")) {
+ c.flags_field |= AUXILIARY;
+ }
}
},
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Oct 31 13:48:15 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Nov 01 10:48:36 2012 +0100
@@ -1847,6 +1847,11 @@
#####
+# 0: type, 1: file name
+compiler.warn.auxiliary.class.accessed.from.outside.of.its.source.file=\
+ auxiliary class {0} in {1} should not be accessed from outside its own source file
+
+
## The first argument ({0}) is a "kindname".
# 0: symbol kind, 1: symbol, 2: symbol
compiler.err.abstract.cant.be.accessed.directly=\
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/AuxiliaryClassWarning/ClassUsingAuxiliary.java Thu Nov 01 10:48:36 2012 +0100
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+// key: compiler.warn.auxiliary.class.accessed.from.outside.of.its.source.file
+// options: -Xlint:auxiliaryclass
+
+class ClassUsingAuxiliary {
+ AuxiliaryClass ahem;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/AuxiliaryClassWarning/ClassWithAuxiliary.java Thu Nov 01 10:48:36 2012 +0100
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+class ClassWithAuxiliaryClass {
+}
+
+// Auxiliary class that cannot be found through implicit compilation.
+class AuxiliaryClass {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAnotherAuxiliary.java Thu Nov 01 10:48:36 2012 +0100
@@ -0,0 +1,34 @@
+/*
+ * 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
+ * @compile ClassUsingAnotherAuxiliary.java NotAClassName.java
+ * @compile -Xlint:auxiliaryclass ClassUsingAnotherAuxiliary.java NotAClassName.java
+ * @compile/fail/ref=ClassUsingAnotherAuxiliary.out -XDrawDiagnostics -Werror -Xlint:auxiliaryclass ClassUsingAnotherAuxiliary.java NotAClassName.java
+ */
+
+class ClassUsingAnotherAuxiliary {
+ AnAuxiliaryClass ahem;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAnotherAuxiliary.out Thu Nov 01 10:48:36 2012 +0100
@@ -0,0 +1,4 @@
+ClassUsingAnotherAuxiliary.java:32:5: compiler.warn.auxiliary.class.accessed.from.outside.of.its.source.file: AnAuxiliaryClass, NotAClassName.java
+- compiler.err.warnings.and.werror
+1 error
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAuxiliary.java Thu Nov 01 10:48:36 2012 +0100
@@ -0,0 +1,34 @@
+/*
+ * 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
+ * @clean ClassUsingAuxiliary ClassWithAuxiliary AuxiliaryClass ClassWithAuxiliary$NotAnAuxiliaryClass ClassWithAuxiliary$NotAnAuxiliaryClassEither
+ * @run compile ClassUsingAuxiliary.java ClassWithAuxiliary.java
+ * @run compile/fail/ref=ClassUsingAuxiliary1.out -XDrawDiagnostics -Werror -Xlint:auxiliaryclass ClassUsingAuxiliary.java ClassWithAuxiliary.java
+ * @run compile/fail/ref=ClassUsingAuxiliary2.out -XDrawDiagnostics -Werror -Xlint:auxiliaryclass ClassUsingAuxiliary.java
+ */
+
+class ClassUsingAuxiliary {
+ AuxiliaryClass ahem;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAuxiliary1.out Thu Nov 01 10:48:36 2012 +0100
@@ -0,0 +1,4 @@
+ClassUsingAuxiliary.java:33:5: compiler.warn.auxiliary.class.accessed.from.outside.of.its.source.file: AuxiliaryClass, ClassWithAuxiliary.java
+- compiler.err.warnings.and.werror
+1 error
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassUsingAuxiliary2.out Thu Nov 01 10:48:36 2012 +0100
@@ -0,0 +1,4 @@
+ClassUsingAuxiliary.java:33:5: compiler.warn.auxiliary.class.accessed.from.outside.of.its.source.file: AuxiliaryClass, ClassWithAuxiliary.java
+- compiler.err.warnings.and.werror
+1 error
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/AuxiliaryClass/ClassWithAuxiliary.java Thu Nov 01 10:48:36 2012 +0100
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+public class ClassWithAuxiliary {
+ public static class NotAnAuxiliaryClass { }
+ public class NotAnAuxiliaryClassEither { }
+}
+
+// Auxiliary class that cannot be found through implicit compilation.
+class AuxiliaryClass {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/AuxiliaryClass/NotAClassName.java Thu Nov 01 10:48:36 2012 +0100
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+class AnAuxiliaryClass {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/AuxiliaryClass/SelfClassWithAux.java Thu Nov 01 10:48:36 2012 +0100
@@ -0,0 +1,44 @@
+/*
+ * 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 that an auxiliary class referenced from its own source file,
+ * does not trigger the warning. Such code does not prevent implicit
+ * compilation. Also test that references to inner classes do not trigger the warning.
+ */
+
+/*
+ * @test
+ * @run compile -Werror -Xlint:auxiliaryclass SelfClassWithAux.java ClassWithAuxiliary.java
+ * @run compile -Werror -Xlint:auxiliaryclass SelfClassWithAux.java
+ */
+
+class SelfClassWithAux {
+ Aux aux;
+ ClassWithAuxiliary.NotAnAuxiliaryClass alfa;
+ ClassWithAuxiliary.NotAnAuxiliaryClassEither beta;
+}
+
+class Aux {
+ Aux aux;
+}