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.*;
3639 public boolean importAccessible(Symbol sym, PackageSymbol packge) {
3640 try {
3641 int flags = (int)(sym.flags() & AccessFlags);
3642 switch (flags) {
3643 default:
3644 case PUBLIC:
3645 return true;
3646 case PRIVATE:
3647 return false;
3648 case 0:
3649 case PROTECTED:
3650 return sym.packge() == packge;
3651 }
3652 } catch (ClassFinder.BadClassFile err) {
3653 throw err;
3654 } catch (CompletionFailure ex) {
3655 return false;
3656 }
3657 }
3658
3659 }
|
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.tree.*;
41 import com.sun.tools.javac.util.*;
42 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
43 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
44 import com.sun.tools.javac.util.List;
45
46 import com.sun.tools.javac.code.Lint;
47 import com.sun.tools.javac.code.Lint.LintCategory;
48 import com.sun.tools.javac.code.Scope.WriteableScope;
49 import com.sun.tools.javac.code.Type.*;
50 import com.sun.tools.javac.code.Symbol.*;
51 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
52 import com.sun.tools.javac.comp.Infer.FreeTypeListener;
53 import com.sun.tools.javac.tree.JCTree.*;
54
55 import static com.sun.tools.javac.code.Flags.*;
3641 public boolean importAccessible(Symbol sym, PackageSymbol packge) {
3642 try {
3643 int flags = (int)(sym.flags() & AccessFlags);
3644 switch (flags) {
3645 default:
3646 case PUBLIC:
3647 return true;
3648 case PRIVATE:
3649 return false;
3650 case 0:
3651 case PROTECTED:
3652 return sym.packge() == packge;
3653 }
3654 } catch (ClassFinder.BadClassFile err) {
3655 throw err;
3656 } catch (CompletionFailure ex) {
3657 return false;
3658 }
3659 }
3660
3661 public void checkUnexportedInApi(Env<AttrContext> env, JCClassDecl check) {
3662 JCCompilationUnit toplevel = env.toplevel;
3663
3664 if ( toplevel.modle == syms.unnamedModule
3665 || toplevel.modle == syms.noModule
3666 || (check.sym.flags() & COMPOUND) != 0) {
3667 return ;
3668 }
3669
3670 ExportsDirective currentExport = findExport(toplevel.packge);
3671
3672 if ( currentExport == null //not exported
3673 || currentExport.modules != null) //don't check classes in qualified export
3674 return ;
3675
3676 new TreeScanner() {
3677 Lint lint = env.info.lint;
3678 boolean inSuperType;
3679
3680 @Override public void visitBlock(JCBlock tree) {
3681 }
3682 @Override public void visitMethodDef(JCMethodDecl tree) {
3683 if (!isAPISymbol(tree.sym))
3684 return;
3685 lint = lint.augment(tree.sym);
3686 if (lint.isEnabled(LintCategory.UNEXPORTED_IN_API)) {
3687 super.visitMethodDef(tree);
3688 }
3689 }
3690 @Override
3691 public void visitVarDef(JCVariableDecl tree) {
3692 if (!isAPISymbol(tree.sym) && tree.sym.owner.kind != MTH)
3693 return;
3694 lint = lint.augment(tree.sym);
3695 if (lint.isEnabled(LintCategory.UNEXPORTED_IN_API)) {
3696 scan(tree.mods);
3697 scan(tree.vartype);
3698 }
3699 }
3700 @Override
3701 public void visitClassDef(JCClassDecl tree) {
3702 if (tree != check)
3703 return ;
3704
3705 if (!isAPISymbol(tree.sym))
3706 return ;
3707
3708 lint = lint.augment(tree.sym);
3709 if (lint.isEnabled(LintCategory.UNEXPORTED_IN_API)) {
3710 scan(tree.mods);
3711 scan(tree.typarams);
3712 try {
3713 inSuperType = true;
3714 scan(tree.extending);
3715 scan(tree.implementing);
3716 } finally {
3717 inSuperType = false;
3718 }
3719 scan(tree.defs);
3720 }
3721 }
3722 @Override
3723 public void visitTypeApply(JCTypeApply tree) {
3724 scan(tree.clazz);
3725 boolean oldInSuperType = inSuperType;
3726 try {
3727 inSuperType = false;
3728 scan(tree.arguments);
3729 } finally {
3730 inSuperType = oldInSuperType;
3731 }
3732 }
3733 @Override
3734 public void visitIdent(JCIdent tree) {
3735 Symbol sym = TreeInfo.symbol(tree);
3736 if (sym.kind == TYP && !sym.type.hasTag(TYPEVAR)) {
3737 checkVisible(tree.pos(), sym, toplevel.packge, inSuperType);
3738 }
3739 }
3740
3741 @Override
3742 public void visitSelect(JCFieldAccess tree) {
3743 Symbol sym = TreeInfo.symbol(tree);
3744 Symbol sitesym = TreeInfo.symbol(tree.selected);
3745 if (sym.kind == TYP && sitesym.kind == PCK) {
3746 checkVisible(tree.pos(), sym, toplevel.packge, inSuperType);
3747 } else {
3748 super.visitSelect(tree);
3749 }
3750 }
3751
3752 @Override
3753 public void visitAnnotation(JCAnnotation tree) {
3754 if (tree.attribute.type.tsym.getAnnotation(java.lang.annotation.Documented.class) != null)
3755 super.visitAnnotation(tree);
3756 }
3757
3758 }.scan(check);
3759 }
3760 //where:
3761 private ExportsDirective findExport(PackageSymbol pack) {
3762 for (ExportsDirective d : pack.modle.exports) {
3763 if (d.packge == pack)
3764 return d;
3765 }
3766
3767 return null;
3768 }
3769 private boolean isAPISymbol(Symbol sym) {
3770 while (sym.kind != PCK) {
3771 if ((sym.flags() & Flags.PUBLIC) == 0 && (sym.flags() & Flags.PROTECTED) == 0) {
3772 return false;
3773 }
3774 sym = sym.owner;
3775 }
3776 return true;
3777 }
3778 private void checkVisible(DiagnosticPosition pos, Symbol what, PackageSymbol inPackage, boolean inSuperType) {
3779 if (!isAPISymbol(what) && !inSuperType) { //package private/private element
3780 log.warning(pos, "inaccessible.in.api");
3781 return ;
3782 }
3783
3784 PackageSymbol whatPackage = what.packge();
3785 ExportsDirective whatExport = findExport(whatPackage);
3786 ExportsDirective inExport = findExport(inPackage);
3787
3788 if (whatExport == null) { //package not exported:
3789 log.warning(pos, "unexported.in.api");
3790 return ;
3791 }
3792
3793 if (whatExport.modules != null) {
3794 if (inExport.modules == null || !whatExport.modules.containsAll(inExport.modules)) {
3795 log.warning(pos, "unexported.in.api.qualified");
3796 }
3797 }
3798
3799 if (whatPackage.modle != inPackage.modle && whatPackage.modle != syms.java_base) {
3800 //check that relativeTo.modle requires public what.modle, somehow:
3801 List<ModuleSymbol> todo = List.of(inPackage.modle);
3802
3803 while (todo.nonEmpty()) {
3804 ModuleSymbol current = todo.head;
3805 todo = todo.tail;
3806 if (current == whatPackage.modle)
3807 return ; //OK
3808 for (RequiresDirective req : current.requires) {
3809 if (req.isPublic()) {
3810 todo = todo.prepend(req.module);
3811 }
3812 }
3813 }
3814
3815 log.warning(pos, "unexported.in.api.not.required.public");
3816 }
3817 }
3818 }
|