提交 06dede83 编写于 作者: O ohrstrom

7153951: Add new lint option -Xlint:auxiliaryclass

Reviewed-by: jjg, mcimadamore, forax
上级 5e89ded1
......@@ -258,6 +258,12 @@ public class Flags {
*/
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
......
......@@ -128,6 +128,13 @@ public class Lint
* Categories of warnings that can be generated by the compiler.
*/
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.
*/
......
......@@ -3050,6 +3050,7 @@ public class Attr extends JCTree.Visitor {
// 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
......
......@@ -27,6 +27,7 @@ package com.sun.tools.javac.comp;
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 @@ public class Check {
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 @@ public class Check {
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 @@ public class Check {
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;
......
......@@ -1022,11 +1022,13 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
// 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 {
......
......@@ -1018,6 +1018,15 @@ public class ClassReader implements Completer {
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;
}
}
},
......
......@@ -1847,6 +1847,11 @@ compiler.misc.varargs.argument.mismatch=\
#####
# 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=\
......
/*
* 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;
}
/*
* 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 {
}
/*
* 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;
}
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
/*
* 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;
}
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
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
/*
* 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 {
}
/*
* 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 {
}
/*
* 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;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册