14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.tools.javac.comp;
27
28 import java.util.*;
29
30 import javax.tools.JavaFileManager;
31
32 import com.sun.tools.javac.code.*;
33 import com.sun.tools.javac.code.Attribute.Compound;
34 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
35 import com.sun.tools.javac.jvm.*;
36 import com.sun.tools.javac.resources.CompilerProperties.Errors;
37 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
38 import com.sun.tools.javac.tree.*;
39 import com.sun.tools.javac.util.*;
40 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
41 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
42 import com.sun.tools.javac.util.List;
43
44 import com.sun.tools.javac.code.Lint;
45 import com.sun.tools.javac.code.Lint.LintCategory;
46 import com.sun.tools.javac.code.Scope.WriteableScope;
47 import com.sun.tools.javac.code.Type.*;
48 import com.sun.tools.javac.code.Symbol.*;
49 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
50 import com.sun.tools.javac.comp.Infer.FreeTypeListener;
51 import com.sun.tools.javac.tree.JCTree.*;
52
53 import static com.sun.tools.javac.code.Flags.*;
54 import static com.sun.tools.javac.code.Flags.ANNOTATION;
55 import static com.sun.tools.javac.code.Flags.SYNCHRONIZED;
56 import static com.sun.tools.javac.code.Kinds.*;
57 import static com.sun.tools.javac.code.Kinds.Kind.*;
3652 public boolean importAccessible(Symbol sym, PackageSymbol packge) {
3653 try {
3654 int flags = (int)(sym.flags() & AccessFlags);
3655 switch (flags) {
3656 default:
3657 case PUBLIC:
3658 return true;
3659 case PRIVATE:
3660 return false;
3661 case 0:
3662 case PROTECTED:
3663 return sym.packge() == packge;
3664 }
3665 } catch (ClassFinder.BadClassFile err) {
3666 throw err;
3667 } catch (CompletionFailure ex) {
3668 return false;
3669 }
3670 }
3671
3672 }
|
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.tools.javac.comp;
27
28 import java.util.*;
29
30 import javax.tools.JavaFileManager;
31
32 import com.sun.tools.javac.code.*;
33 import com.sun.tools.javac.code.Attribute.Compound;
34 import com.sun.tools.javac.code.Directive.ExportsDirective;
35 import com.sun.tools.javac.code.Directive.RequiresDirective;
36 import com.sun.tools.javac.comp.Annotate.AnnotationTypeMetadata;
37 import com.sun.tools.javac.jvm.*;
38 import com.sun.tools.javac.resources.CompilerProperties.Errors;
39 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
40 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
41 import com.sun.tools.javac.tree.*;
42 import com.sun.tools.javac.util.*;
43 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
44 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
45 import com.sun.tools.javac.util.List;
46
47 import com.sun.tools.javac.code.Lint;
48 import com.sun.tools.javac.code.Lint.LintCategory;
49 import com.sun.tools.javac.code.Scope.WriteableScope;
50 import com.sun.tools.javac.code.Type.*;
51 import com.sun.tools.javac.code.Symbol.*;
52 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
53 import com.sun.tools.javac.comp.Infer.FreeTypeListener;
54 import com.sun.tools.javac.tree.JCTree.*;
55
56 import static com.sun.tools.javac.code.Flags.*;
57 import static com.sun.tools.javac.code.Flags.ANNOTATION;
58 import static com.sun.tools.javac.code.Flags.SYNCHRONIZED;
59 import static com.sun.tools.javac.code.Kinds.*;
60 import static com.sun.tools.javac.code.Kinds.Kind.*;
3655 public boolean importAccessible(Symbol sym, PackageSymbol packge) {
3656 try {
3657 int flags = (int)(sym.flags() & AccessFlags);
3658 switch (flags) {
3659 default:
3660 case PUBLIC:
3661 return true;
3662 case PRIVATE:
3663 return false;
3664 case 0:
3665 case PROTECTED:
3666 return sym.packge() == packge;
3667 }
3668 } catch (ClassFinder.BadClassFile err) {
3669 throw err;
3670 } catch (CompletionFailure ex) {
3671 return false;
3672 }
3673 }
3674
3675 public void checkLeaksNotAccessible(Env<AttrContext> env, JCClassDecl check) {
3676 JCCompilationUnit toplevel = env.toplevel;
3677
3678 if ( toplevel.modle == syms.unnamedModule
3679 || toplevel.modle == syms.noModule
3680 || (check.sym.flags() & COMPOUND) != 0) {
3681 return ;
3682 }
3683
3684 ExportsDirective currentExport = findExport(toplevel.packge);
3685
3686 if ( currentExport == null //not exported
3687 || currentExport.modules != null) //don't check classes in qualified export
3688 return ;
3689
3690 new TreeScanner() {
3691 Lint lint = env.info.lint;
3692 boolean inSuperType;
3693
3694 @Override
3695 public void visitBlock(JCBlock tree) {
3696 }
3697 @Override
3698 public void visitMethodDef(JCMethodDecl tree) {
3699 if (!isAPISymbol(tree.sym))
3700 return;
3701 Lint prevLint = lint;
3702 try {
3703 lint = lint.augment(tree.sym);
3704 if (lint.isEnabled(LintCategory.EXPORTS)) {
3705 super.visitMethodDef(tree);
3706 }
3707 } finally {
3708 lint = prevLint;
3709 }
3710 }
3711 @Override
3712 public void visitVarDef(JCVariableDecl tree) {
3713 if (!isAPISymbol(tree.sym) && tree.sym.owner.kind != MTH)
3714 return;
3715 Lint prevLint = lint;
3716 try {
3717 lint = lint.augment(tree.sym);
3718 if (lint.isEnabled(LintCategory.EXPORTS)) {
3719 scan(tree.mods);
3720 scan(tree.vartype);
3721 }
3722 } finally {
3723 lint = prevLint;
3724 }
3725 }
3726 @Override
3727 public void visitClassDef(JCClassDecl tree) {
3728 if (tree != check)
3729 return ;
3730
3731 if (!isAPISymbol(tree.sym))
3732 return ;
3733
3734 Lint prevLint = lint;
3735 try {
3736 lint = lint.augment(tree.sym);
3737 if (lint.isEnabled(LintCategory.EXPORTS)) {
3738 scan(tree.mods);
3739 scan(tree.typarams);
3740 try {
3741 inSuperType = true;
3742 scan(tree.extending);
3743 scan(tree.implementing);
3744 } finally {
3745 inSuperType = false;
3746 }
3747 scan(tree.defs);
3748 }
3749 } finally {
3750 lint = prevLint;
3751 }
3752 }
3753 @Override
3754 public void visitTypeApply(JCTypeApply tree) {
3755 scan(tree.clazz);
3756 boolean oldInSuperType = inSuperType;
3757 try {
3758 inSuperType = false;
3759 scan(tree.arguments);
3760 } finally {
3761 inSuperType = oldInSuperType;
3762 }
3763 }
3764 @Override
3765 public void visitIdent(JCIdent tree) {
3766 Symbol sym = TreeInfo.symbol(tree);
3767 if (sym.kind == TYP && !sym.type.hasTag(TYPEVAR)) {
3768 checkVisible(tree.pos(), sym, toplevel.packge, inSuperType);
3769 }
3770 }
3771
3772 @Override
3773 public void visitSelect(JCFieldAccess tree) {
3774 Symbol sym = TreeInfo.symbol(tree);
3775 Symbol sitesym = TreeInfo.symbol(tree.selected);
3776 if (sym.kind == TYP && sitesym.kind == PCK) {
3777 checkVisible(tree.pos(), sym, toplevel.packge, inSuperType);
3778 } else {
3779 super.visitSelect(tree);
3780 }
3781 }
3782
3783 @Override
3784 public void visitAnnotation(JCAnnotation tree) {
3785 if (tree.attribute.type.tsym.getAnnotation(java.lang.annotation.Documented.class) != null)
3786 super.visitAnnotation(tree);
3787 }
3788
3789 }.scan(check);
3790 }
3791 //where:
3792 private ExportsDirective findExport(PackageSymbol pack) {
3793 for (ExportsDirective d : pack.modle.exports) {
3794 if (d.packge == pack)
3795 return d;
3796 }
3797
3798 return null;
3799 }
3800 private boolean isAPISymbol(Symbol sym) {
3801 while (sym.kind != PCK) {
3802 if ((sym.flags() & Flags.PUBLIC) == 0 && (sym.flags() & Flags.PROTECTED) == 0) {
3803 return false;
3804 }
3805 sym = sym.owner;
3806 }
3807 return true;
3808 }
3809 private void checkVisible(DiagnosticPosition pos, Symbol what, PackageSymbol inPackage, boolean inSuperType) {
3810 if (!isAPISymbol(what) && !inSuperType) { //package private/private element
3811 log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessible(kindName(what), what, what.packge().modle));
3812 return ;
3813 }
3814
3815 PackageSymbol whatPackage = what.packge();
3816 ExportsDirective whatExport = findExport(whatPackage);
3817 ExportsDirective inExport = findExport(inPackage);
3818
3819 if (whatExport == null) { //package not exported:
3820 log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleUnexported(kindName(what), what, what.packge().modle));
3821 return ;
3822 }
3823
3824 if (whatExport.modules != null) {
3825 if (inExport.modules == null || !whatExport.modules.containsAll(inExport.modules)) {
3826 log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleUnexportedQualified(kindName(what), what, what.packge().modle));
3827 }
3828 }
3829
3830 if (whatPackage.modle != inPackage.modle && whatPackage.modle != syms.java_base) {
3831 //check that relativeTo.modle requires public what.modle, somehow:
3832 List<ModuleSymbol> todo = List.of(inPackage.modle);
3833
3834 while (todo.nonEmpty()) {
3835 ModuleSymbol current = todo.head;
3836 todo = todo.tail;
3837 if (current == whatPackage.modle)
3838 return ; //OK
3839 for (RequiresDirective req : current.requires) {
3840 if (req.isPublic()) {
3841 todo = todo.prepend(req.module);
3842 }
3843 }
3844 }
3845
3846 log.warning(LintCategory.EXPORTS, pos, Warnings.LeaksNotAccessibleNotRequiredPublic(kindName(what), what, what.packge().modle));
3847 }
3848 }
3849 }
|