langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
changeset 27857 7e913a535736
parent 27224 228abfa87080
child 28459 48a68a485760
equal deleted inserted replaced
27856:d4711a6931e2 27857:7e913a535736
    26 package com.sun.tools.javac.comp;
    26 package com.sun.tools.javac.comp;
    27 
    27 
    28 import java.util.*;
    28 import java.util.*;
    29 
    29 
    30 import javax.tools.JavaFileManager;
    30 import javax.tools.JavaFileManager;
    31 import javax.tools.JavaFileObject;
       
    32 
    31 
    33 import com.sun.tools.javac.code.*;
    32 import com.sun.tools.javac.code.*;
    34 import com.sun.tools.javac.code.Attribute.Compound;
    33 import com.sun.tools.javac.code.Attribute.Compound;
    35 import com.sun.tools.javac.jvm.*;
    34 import com.sun.tools.javac.jvm.*;
    36 import com.sun.tools.javac.tree.*;
    35 import com.sun.tools.javac.tree.*;
    38 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    37 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    39 import com.sun.tools.javac.util.List;
    38 import com.sun.tools.javac.util.List;
    40 
    39 
    41 import com.sun.tools.javac.code.Lint;
    40 import com.sun.tools.javac.code.Lint;
    42 import com.sun.tools.javac.code.Lint.LintCategory;
    41 import com.sun.tools.javac.code.Lint.LintCategory;
       
    42 import com.sun.tools.javac.code.Scope.CompoundScope;
    43 import com.sun.tools.javac.code.Scope.NamedImportScope;
    43 import com.sun.tools.javac.code.Scope.NamedImportScope;
    44 import com.sun.tools.javac.code.Scope.WriteableScope;
    44 import com.sun.tools.javac.code.Scope.WriteableScope;
    45 import com.sun.tools.javac.code.Type.*;
    45 import com.sun.tools.javac.code.Type.*;
    46 import com.sun.tools.javac.code.Symbol.*;
    46 import com.sun.tools.javac.code.Symbol.*;
    47 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
    47 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
  3413         if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
  3413         if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
  3414             log.error(pos, "name.clash.same.erasure", sym1, sym2);
  3414             log.error(pos, "name.clash.same.erasure", sym1, sym2);
  3415         }
  3415         }
  3416     }
  3416     }
  3417 
  3417 
       
  3418     /**Check that types imported through the ordinary imports don't clash with types imported
       
  3419      * by other (static or ordinary) imports. Note that two static imports may import two clashing
       
  3420      * types without an error on the imports.
       
  3421      * @param toplevel       The toplevel tree for which the test should be performed.
       
  3422      */
       
  3423     void checkImportsUnique(JCCompilationUnit toplevel) {
       
  3424         WriteableScope ordinallyImportedSoFar = WriteableScope.create(toplevel.packge);
       
  3425         WriteableScope staticallyImportedSoFar = WriteableScope.create(toplevel.packge);
       
  3426         WriteableScope topLevelScope = toplevel.toplevelScope;
       
  3427 
       
  3428         for (JCTree def : toplevel.defs) {
       
  3429             if (!def.hasTag(IMPORT))
       
  3430                 continue;
       
  3431 
       
  3432             JCImport imp = (JCImport) def;
       
  3433 
       
  3434             if (imp.importScope == null)
       
  3435                 continue;
       
  3436 
       
  3437             for (Symbol sym : imp.importScope.getSymbols(sym -> sym.kind == TYP)) {
       
  3438                 if (imp.isStatic()) {
       
  3439                     checkUniqueImport(imp.pos(), ordinallyImportedSoFar, staticallyImportedSoFar, topLevelScope, sym, true);
       
  3440                     staticallyImportedSoFar.enter(sym);
       
  3441                 } else {
       
  3442                     checkUniqueImport(imp.pos(), ordinallyImportedSoFar, staticallyImportedSoFar, topLevelScope, sym, false);
       
  3443                     ordinallyImportedSoFar.enter(sym);
       
  3444                 }
       
  3445             }
       
  3446 
       
  3447             imp.importScope = null;
       
  3448         }
       
  3449     }
       
  3450 
  3418     /** Check that single-type import is not already imported or top-level defined,
  3451     /** Check that single-type import is not already imported or top-level defined,
  3419      *  but make an exception for two single-type imports which denote the same type.
  3452      *  but make an exception for two single-type imports which denote the same type.
  3420      *  @param pos           Position for error reporting.
  3453      *  @param pos                     Position for error reporting.
  3421      *  @param toplevel      The file in which in the check is performed.
  3454      *  @param ordinallyImportedSoFar  A Scope containing types imported so far through
  3422      *  @param sym           The symbol.
  3455      *                                 ordinary imports.
  3423      */
  3456      *  @param staticallyImportedSoFar A Scope containing types imported so far through
  3424     boolean checkUniqueImport(DiagnosticPosition pos, JCCompilationUnit toplevel, Symbol sym) {
  3457      *                                 static imports.
  3425         return checkUniqueImport(pos, toplevel, sym, false);
  3458      *  @param topLevelScope           The current file's top-level Scope
  3426     }
  3459      *  @param sym                     The symbol.
  3427 
  3460      *  @param staticImport            Whether or not this was a static import
  3428     /** Check that static single-type import is not already imported or top-level defined,
  3461      */
  3429      *  but make an exception for two single-type imports which denote the same type.
  3462     private boolean checkUniqueImport(DiagnosticPosition pos, Scope ordinallyImportedSoFar,
  3430      *  @param pos           Position for error reporting.
  3463                                       Scope staticallyImportedSoFar, Scope topLevelScope,
  3431      *  @param toplevel      The file in which in the check is performed.
  3464                                       Symbol sym, boolean staticImport) {
  3432      *  @param sym           The symbol.
  3465         Filter<Symbol> duplicates = candidate -> candidate != sym && !candidate.type.isErroneous();
  3433      */
  3466         Symbol clashing = ordinallyImportedSoFar.findFirst(sym.name, duplicates);
  3434     boolean checkUniqueStaticImport(DiagnosticPosition pos, JCCompilationUnit toplevel, Symbol sym) {
  3467         if (clashing == null && !staticImport) {
  3435         return checkUniqueImport(pos, toplevel, sym, true);
  3468             clashing = staticallyImportedSoFar.findFirst(sym.name, duplicates);
  3436     }
  3469         }
  3437 
  3470         if (clashing != null) {
  3438     /** Check that single-type import is not already imported or top-level defined,
  3471             if (staticImport)
  3439      *  but make an exception for two single-type imports which denote the same type.
  3472                 log.error(pos, "already.defined.static.single.import", clashing);
  3440      *  @param pos           Position for error reporting.
  3473             else
  3441      *  @param toplevel      The file in which in the check is performed.
  3474                 log.error(pos, "already.defined.single.import", clashing);
  3442      *  @param sym           The symbol.
  3475             return false;
  3443      *  @param staticImport  Whether or not this was a static import
  3476         }
  3444      */
  3477         clashing = topLevelScope.findFirst(sym.name, duplicates);
  3445     private boolean checkUniqueImport(DiagnosticPosition pos, JCCompilationUnit toplevel, Symbol sym, boolean staticImport) {
  3478         if (clashing != null) {
  3446         NamedImportScope namedImportScope = toplevel.namedImportScope;
  3479             log.error(pos, "already.defined.this.unit", clashing);
  3447         WriteableScope topLevelScope = toplevel.toplevelScope;
  3480             return false;
  3448 
       
  3449         for (Symbol byName : namedImportScope.getSymbolsByName(sym.name)) {
       
  3450             // is encountered class entered via a class declaration?
       
  3451             boolean isClassDecl = namedImportScope.getOrigin(byName) == topLevelScope;
       
  3452             if ((isClassDecl || sym != byName) &&
       
  3453                 sym.kind == byName.kind &&
       
  3454                 sym.name != names.error &&
       
  3455                 (!staticImport || !namedImportScope.isStaticallyImported(byName))) {
       
  3456                 if (!byName.type.isErroneous()) {
       
  3457                     if (!isClassDecl) {
       
  3458                         if (staticImport)
       
  3459                             log.error(pos, "already.defined.static.single.import", byName);
       
  3460                         else
       
  3461                         log.error(pos, "already.defined.single.import", byName);
       
  3462                     }
       
  3463                     else if (sym != byName)
       
  3464                         log.error(pos, "already.defined.this.unit", byName);
       
  3465                 }
       
  3466                 return false;
       
  3467             }
       
  3468         }
  3481         }
  3469         return true;
  3482         return true;
  3470     }
  3483     }
  3471 
  3484 
  3472     /** Check that a qualified name is in canonical form (for import decls).
  3485     /** Check that a qualified name is in canonical form (for import decls).
  3568             final JCFieldAccess select = (JCFieldAccess) imp.qualid;
  3581             final JCFieldAccess select = (JCFieldAccess) imp.qualid;
  3569             final Symbol origin;
  3582             final Symbol origin;
  3570             if (select.name == names.asterisk || (origin = TreeInfo.symbol(select.selected)) == null || origin.kind != TYP)
  3583             if (select.name == names.asterisk || (origin = TreeInfo.symbol(select.selected)) == null || origin.kind != TYP)
  3571                 continue;
  3584                 continue;
  3572 
  3585 
  3573             JavaFileObject prev = log.useSource(toplevel.sourcefile);
  3586             TypeSymbol site = (TypeSymbol) TreeInfo.symbol(select.selected);
  3574             try {
  3587             if (!checkTypeContainsImportableElement(site, site, toplevel.packge, select.name, new HashSet<Symbol>())) {
  3575                 TypeSymbol site = (TypeSymbol) TreeInfo.symbol(select.selected);
  3588                 log.error(imp.pos(), "cant.resolve.location",
  3576                 if (!checkTypeContainsImportableElement(site, site, toplevel.packge, select.name, new HashSet<Symbol>())) {
  3589                           KindName.STATIC,
  3577                     log.error(imp.pos(), "cant.resolve.location",
  3590                           select.name, List.<Type>nil(), List.<Type>nil(),
  3578                               KindName.STATIC,
  3591                           Kinds.typeKindName(TreeInfo.symbol(select.selected).type),
  3579                               select.name, List.<Type>nil(), List.<Type>nil(),
  3592                           TreeInfo.symbol(select.selected).type);
  3580                               Kinds.typeKindName(TreeInfo.symbol(select.selected).type),
       
  3581                               TreeInfo.symbol(select.selected).type);
       
  3582                 }
       
  3583             } finally {
       
  3584                 log.useSource(prev);
       
  3585             }
  3593             }
  3586         }
  3594         }
  3587     }
  3595     }
  3588 
  3596 
  3589     private boolean checkTypeContainsImportableElement(TypeSymbol tsym, TypeSymbol origin, PackageSymbol packge, Name name, Set<Symbol> processed) {
  3597     private boolean checkTypeContainsImportableElement(TypeSymbol tsym, TypeSymbol origin, PackageSymbol packge, Name name, Set<Symbol> processed) {