src/share/classes/com/sun/tools/javac/comp/Check.java

changeset 690
0c1ef2af7a8e
parent 639
a75770c0d7f6
child 700
7b413ac1a720
     1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Sat Sep 18 09:56:23 2010 -0700
     1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Sat Sep 18 14:24:09 2010 -0700
     1.3 @@ -60,6 +60,7 @@
     1.4      private final Names names;
     1.5      private final Log log;
     1.6      private final Symtab syms;
     1.7 +    private final Enter enter;
     1.8      private final Infer infer;
     1.9      private final Types types;
    1.10      private final JCDiagnostic.Factory diags;
    1.11 @@ -86,6 +87,7 @@
    1.12          names = Names.instance(context);
    1.13          log = Log.instance(context);
    1.14          syms = Symtab.instance(context);
    1.15 +        enter = Enter.instance(context);
    1.16          infer = Infer.instance(context);
    1.17          this.types = Types.instance(context);
    1.18          diags = JCDiagnostic.Factory.instance(context);
    1.19 @@ -1727,6 +1729,113 @@
    1.20              return undef;
    1.21          }
    1.22  
    1.23 +    void checkNonCyclicDecl(JCClassDecl tree) {
    1.24 +        CycleChecker cc = new CycleChecker();
    1.25 +        cc.scan(tree);
    1.26 +        if (!cc.errorFound && !cc.partialCheck) {
    1.27 +            tree.sym.flags_field |= ACYCLIC;
    1.28 +        }
    1.29 +    }
    1.30 +
    1.31 +    class CycleChecker extends TreeScanner {
    1.32 +
    1.33 +        List<Symbol> seenClasses = List.nil();
    1.34 +        boolean errorFound = false;
    1.35 +        boolean partialCheck = false;
    1.36 +
    1.37 +        private void checkSymbol(DiagnosticPosition pos, Symbol sym) {
    1.38 +            if (sym != null && sym.kind == TYP) {
    1.39 +                Env<AttrContext> classEnv = enter.getEnv((TypeSymbol)sym);
    1.40 +                if (classEnv != null) {
    1.41 +                    DiagnosticSource prevSource = log.currentSource();
    1.42 +                    try {
    1.43 +                        log.useSource(classEnv.toplevel.sourcefile);
    1.44 +                        scan(classEnv.tree);
    1.45 +                    }
    1.46 +                    finally {
    1.47 +                        log.useSource(prevSource.getFile());
    1.48 +                    }
    1.49 +                } else if (sym.kind == TYP) {
    1.50 +                    checkClass(pos, sym, List.<JCTree>nil());
    1.51 +                }
    1.52 +            } else {
    1.53 +                //not completed yet
    1.54 +                partialCheck = true;
    1.55 +            }
    1.56 +        }
    1.57 +
    1.58 +        @Override
    1.59 +        public void visitSelect(JCFieldAccess tree) {
    1.60 +            super.visitSelect(tree);
    1.61 +            checkSymbol(tree.pos(), tree.sym);
    1.62 +        }
    1.63 +
    1.64 +        @Override
    1.65 +        public void visitIdent(JCIdent tree) {
    1.66 +            checkSymbol(tree.pos(), tree.sym);
    1.67 +        }
    1.68 +
    1.69 +        @Override
    1.70 +        public void visitTypeApply(JCTypeApply tree) {
    1.71 +            scan(tree.clazz);
    1.72 +        }
    1.73 +
    1.74 +        @Override
    1.75 +        public void visitTypeArray(JCArrayTypeTree tree) {
    1.76 +            scan(tree.elemtype);
    1.77 +        }
    1.78 +
    1.79 +        @Override
    1.80 +        public void visitClassDef(JCClassDecl tree) {
    1.81 +            List<JCTree> supertypes = List.nil();
    1.82 +            if (tree.getExtendsClause() != null) {
    1.83 +                supertypes = supertypes.prepend(tree.getExtendsClause());
    1.84 +            }
    1.85 +            if (tree.getImplementsClause() != null) {
    1.86 +                for (JCTree intf : tree.getImplementsClause()) {
    1.87 +                    supertypes = supertypes.prepend(intf);
    1.88 +                }
    1.89 +            }
    1.90 +            checkClass(tree.pos(), tree.sym, supertypes);
    1.91 +        }
    1.92 +
    1.93 +        void checkClass(DiagnosticPosition pos, Symbol c, List<JCTree> supertypes) {
    1.94 +            if ((c.flags_field & ACYCLIC) != 0)
    1.95 +                return;
    1.96 +            if (seenClasses.contains(c)) {
    1.97 +                errorFound = true;
    1.98 +                noteCyclic(pos, (ClassSymbol)c);
    1.99 +            } else if (!c.type.isErroneous()) {
   1.100 +                try {
   1.101 +                    seenClasses = seenClasses.prepend(c);
   1.102 +                    if (c.type.tag == CLASS) {
   1.103 +                        if (supertypes.nonEmpty()) {
   1.104 +                            scan(supertypes);
   1.105 +                        }
   1.106 +                        else {
   1.107 +                            ClassType ct = (ClassType)c.type;
   1.108 +                            if (ct.supertype_field == null ||
   1.109 +                                    ct.interfaces_field == null) {
   1.110 +                                //not completed yet
   1.111 +                                partialCheck = true;
   1.112 +                                return;
   1.113 +                            }
   1.114 +                            checkSymbol(pos, ct.supertype_field.tsym);
   1.115 +                            for (Type intf : ct.interfaces_field) {
   1.116 +                                checkSymbol(pos, intf.tsym);
   1.117 +                            }
   1.118 +                        }
   1.119 +                        if (c.owner.kind == TYP) {
   1.120 +                            checkSymbol(pos, c.owner);
   1.121 +                        }
   1.122 +                    }
   1.123 +                } finally {
   1.124 +                    seenClasses = seenClasses.tail;
   1.125 +                }
   1.126 +            }
   1.127 +        }
   1.128 +    }
   1.129 +
   1.130      /** Check for cyclic references. Issue an error if the
   1.131       *  symbol of the type referred to has a LOCKED flag set.
   1.132       *

mercurial