1 /*
   2  * Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 6402516
  27  * @summary need Trees.getScope(TreePath)
  28  * @build Checker CheckLocalElements
  29  * @run main CheckLocalElements
  30  */
  31 
  32 import java.util.*;
  33 import com.sun.source.tree.*;
  34 import javax.lang.model.element.*;
  35 import javax.lang.model.util.*;
  36 
  37 /*
  38  * Check the local elements of a scope against the contents of string literals.
  39  */
  40 public class CheckLocalElements extends Checker {
  41     public static void main(String... args) throws Exception {
  42         Checker chk = new CheckLocalElements();
  43         chk.check("TestLocalElements.java");
  44     }
  45 
  46     @Override
  47     protected boolean checkLocal(Scope s, String ref) {
  48         Iterator<? extends Element> elemIter = s.getLocalElements().iterator();
  49         ref = ref.trim();
  50         String[] refs = ref.length() == 0 ? new String[0] : ref.split("[ ]*,[ ]*", -1);
  51         Iterator<String> refIter = Arrays.asList(refs).iterator();
  52         String r = null;
  53 
  54         nextElem:
  55         while (elemIter.hasNext()) {
  56             Element e = elemIter.next();
  57             try {
  58                 if (r == null)
  59                     r = refIter.next();
  60 
  61                 while (r.endsWith(".*")) {
  62                     String encl = getEnclosingName(e);
  63                     String rBase = r.substring(0, r.length() - 2);
  64                     if (encl.equals(rBase) || encl.startsWith(rBase + "."))
  65                         continue nextElem;
  66                     r = refIter.next();
  67                 }
  68 
  69                 if (r.equals("-") && (e.getSimpleName().length() == 0)
  70                     || e.getSimpleName().toString().equals(r)) {
  71                     r = null;
  72                     continue nextElem;
  73                 }
  74 
  75                 error(s, ref, "mismatch: " + e.getSimpleName() + " " + r);
  76                 return false;
  77 
  78             } catch (NoSuchElementException ex) { // from refIter.next()
  79                 error(s, null, "scope has unexpected entry: " + e.getSimpleName());
  80                 return false;
  81             }
  82 
  83         }
  84 
  85         if (refIter.hasNext()) {
  86             error(s, ref, "scope is missing entry: " + refIter.next());
  87             return false;
  88         }
  89 
  90         return true;
  91     }
  92 
  93     private String getEnclosingName(Element e) {
  94         Element encl = e.getEnclosingElement();
  95         return encl == null ? "" : encl.accept(qualNameVisitor, null);
  96     }
  97 
  98     private ElementVisitor<String,Void> qualNameVisitor = new SimpleElementVisitor8<String,Void>() {
  99         protected String defaultAction(Element e, Void ignore) {
 100             return "";
 101         }
 102 
 103         public String visitPackage(PackageElement e, Void ignore) {
 104             return e.getQualifiedName().toString();
 105         }
 106 
 107         public String visitType(TypeElement e, Void ignore) {
 108             return e.getQualifiedName().toString();
 109         }
 110     };
 111 }