Coverage Report - com.sun.tools.javafx.comp.JavafxCheck
 
Classes in this File Line Coverage Branch Coverage Complexity
JavafxCheck
49%
415/851
34%
312/923
0
JavafxCheck$1
0%
0/2
N/A
0
JavafxCheck$1SpecialTreeVisitor
0%
0/8
0%
0/6
0
JavafxCheck$ConversionWarner
100%
12/12
50%
1/2
0
JavafxCheck$Validator
17%
8/47
17%
5/30
0
 
 1  
 /*
 2  
  * Copyright 1999-2007 Sun Microsystems, Inc.  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.  Sun designates this
 8  
  * particular file as subject to the "Classpath" exception as provided
 9  
  * by Sun in the LICENSE file that accompanied this code.
 10  
  *
 11  
  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  
  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 22  
  * CA 95054 USA or visit www.sun.com if you need additional information or
 23  
  * have any questions.
 24  
  */
 25  
 
 26  
 package com.sun.tools.javafx.comp;
 27  
 
 28  
 import java.util.HashMap;
 29  
 import java.util.HashSet;
 30  
 import java.util.Map;
 31  
 import java.util.Set;
 32  
 
 33  
 import com.sun.tools.javac.code.*;
 34  
 import static com.sun.tools.javac.code.Flags.*;
 35  
 import static com.sun.tools.javac.code.Flags.ANNOTATION;
 36  
 import static com.sun.tools.javac.code.Flags.SYNCHRONIZED;
 37  
 import static com.sun.tools.javac.code.Kinds.*;
 38  
 import com.sun.tools.javac.code.Lint.LintCategory;
 39  
 import com.sun.tools.javac.code.Symbol.*;
 40  
 import com.sun.tools.javac.code.Type.ClassType;
 41  
 import com.sun.tools.javac.code.Type.ErrorType;
 42  
 import com.sun.tools.javac.code.Type.ForAll;
 43  
 import com.sun.tools.javac.code.Type.TypeVar;
 44  
 import static com.sun.tools.javac.code.TypeTags.*;
 45  
 import static com.sun.tools.javac.code.TypeTags.WILDCARD;
 46  
 import com.sun.tools.javac.comp.Infer;
 47  
 import com.sun.tools.javac.jvm.ByteCodes;
 48  
 import com.sun.tools.javac.jvm.ClassReader;
 49  
 import com.sun.tools.javac.jvm.Target;
 50  
 import com.sun.tools.javac.tree.JCTree;
 51  
 import com.sun.tools.javac.tree.JCTree.*;
 52  
 import com.sun.tools.javac.util.*;
 53  
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 54  
 import com.sun.tools.javafx.code.JavafxClassSymbol;
 55  
 import com.sun.tools.javafx.code.JavafxFlags;
 56  
 import com.sun.tools.javafx.code.JavafxSymtab;
 57  
 import com.sun.tools.javafx.code.JavafxTypes;
 58  
 import static com.sun.tools.javafx.code.JavafxVarSymbol.*;
 59  
 import com.sun.tools.javafx.comp.JavafxAttr.Sequenceness;
 60  
 import com.sun.tools.javafx.tree.JFXClassDeclaration;
 61  
 import com.sun.tools.javafx.tree.JavafxTreeInfo;
 62  
 import com.sun.tools.javafx.tree.JavafxTreeScanner;
 63  
 import com.sun.tools.javafx.util.MsgSym;
 64  
 
 65  
 /** Type checking helper class for the attribution phase.
 66  
  *
 67  
  *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
 68  
  *  you write code that depends on this, you do so at your own risk.
 69  
  *  This code and its internal interfaces are subject to change or
 70  
  *  deletion without notice.</b>
 71  
  */
 72  12
 public class JavafxCheck {
 73  12
     protected static final Context.Key<JavafxCheck> javafxCheckKey =
 74  
         new Context.Key<JavafxCheck>();
 75  
 
 76  
     private final JavafxDefs defs;
 77  
     private final Name.Table names;
 78  
     private final Log log;
 79  
     private final JavafxSymtab syms;
 80  
     private final Infer infer;
 81  
     private final Target target;
 82  
     private final Source source;
 83  
     private final JavafxTypes types;
 84  
     private final boolean skipAnnotations;
 85  
     private final JavafxTreeInfo treeinfo;
 86  
     private final JavafxResolve rs;
 87  
 
 88  
     // The set of lint options currently in effect. It is initialized
 89  
     // from the context, and then is set/reset as needed by Attr as it 
 90  
     // visits all the various parts of the trees during attribution.
 91  
     private Lint lint;
 92  
 
 93  
     public static JavafxCheck instance(Context context) {
 94  2394
         JavafxCheck instance = context.get(javafxCheckKey);
 95  2394
         if (instance == null)
 96  399
             instance = new JavafxCheck(context);
 97  2394
         return instance;
 98  
     }
 99  
 
 100  
     public static void preRegister(final Context context) {
 101  0
         context.put(javafxCheckKey, new Context.Factory<JavafxCheck>() {
 102  
                public JavafxCheck make() {
 103  0
                    return new JavafxCheck(context);
 104  
                }
 105  
         });
 106  0
     }
 107  
 
 108  399
     protected JavafxCheck(Context context) {
 109  399
         context.put(javafxCheckKey, this);
 110  
 
 111  399
         defs = JavafxDefs.instance(context);
 112  399
         names = Name.Table.instance(context);
 113  399
         log = Log.instance(context);
 114  399
         syms = (JavafxSymtab) Symtab.instance(context);
 115  399
         infer = Infer.instance(context);
 116  399
         this.types = JavafxTypes.instance(context);
 117  399
         Options options = Options.instance(context);
 118  399
         target = Target.instance(context);
 119  399
         source = Source.instance(context);
 120  399
         lint = Lint.instance(context);
 121  399
         treeinfo = (JavafxTreeInfo)JavafxTreeInfo.instance(context);
 122  
 
 123  399
         allowGenerics = source.allowGenerics();
 124  399
         allowAnnotations = source.allowAnnotations();
 125  399
         complexInference = options.get("-complexinference") != null;
 126  399
         skipAnnotations = options.get("skipAnnotations") != null;
 127  
 
 128  399
         boolean verboseDeprecated = lint.isEnabled(LintCategory.DEPRECATION);
 129  399
         boolean verboseUnchecked = lint.isEnabled(LintCategory.UNCHECKED);
 130  
 
 131  399
         deprecationHandler = new MandatoryWarningHandler(log,verboseDeprecated, MsgSym.MESSAGEPREFIX_DEPRECATED);
 132  399
         uncheckedHandler = new MandatoryWarningHandler(log, verboseUnchecked, MsgSym.MESSAGEPREFIX_UNCHECKED);
 133  399
         rs = JavafxResolve.instance(context);
 134  399
     }
 135  
 
 136  
 
 137  
     /** Switch: generics enabled?
 138  
      */
 139  
     boolean allowGenerics;
 140  
 
 141  
     /** Switch: annotations enabled?
 142  
      */
 143  
     boolean allowAnnotations;
 144  
 
 145  
     /** Switch: -complexinference option set?
 146  
      */
 147  
     boolean complexInference;
 148  
 
 149  
     /** A table mapping flat names of all compiled classes in this run to their
 150  
      *  symbols; maintained from outside.
 151  
      */
 152  399
     public Map<Name,ClassSymbol> compiled = new HashMap<Name, ClassSymbol>();
 153  
 
 154  
     /** A handler for messages about deprecated usage.
 155  
      */
 156  
     private MandatoryWarningHandler deprecationHandler;
 157  
 
 158  
     /** A handler for messages about unchecked or unsafe usage.
 159  
      */
 160  
     private MandatoryWarningHandler uncheckedHandler;
 161  
 
 162  
 
 163  
 /* *************************************************************************
 164  
  * Errors and Warnings
 165  
  **************************************************************************/
 166  
 // JavaFX change
 167  
     public
 168  
 // JavaFX change
 169  
     Lint setLint(Lint newLint) {
 170  10390
         Lint prev = lint;
 171  10390
         lint = newLint;
 172  10390
         return prev;
 173  
     }
 174  
 
 175  
     /** Warn about deprecated symbol.
 176  
      *  @param pos        Position to be used for error reporting.
 177  
      *  @param sym        The deprecated symbol.
 178  
      */ 
 179  
 // JavaFX change
 180  
     public
 181  
 // JavaFX change
 182  
     void warnDeprecated(DiagnosticPosition pos, Symbol sym) {
 183  0
         if (!lint.isSuppressed(LintCategory.DEPRECATION))
 184  0
             deprecationHandler.report(pos, MsgSym.MESSAGE_HAS_BEEN_DEPRECATED, sym, sym.location());
 185  0
     }
 186  
 
 187  
     /** Warn about unchecked operation.
 188  
      *  @param pos        Position to be used for error reporting.
 189  
      *  @param msg        A string describing the problem.
 190  
      */
 191  
     public void warnUnchecked(DiagnosticPosition pos, String msg, Object... args) {
 192  67
         if (!lint.isSuppressed(LintCategory.UNCHECKED))
 193  0
             uncheckedHandler.report(pos, msg, args);
 194  67
     }
 195  
 
 196  
     /**
 197  
      * Report any deferred diagnostics.
 198  
      */
 199  
     public void reportDeferredDiagnostics() {
 200  378
         deprecationHandler.reportDeferredDiagnostic();
 201  378
         uncheckedHandler.reportDeferredDiagnostic();
 202  378
     }
 203  
 
 204  
 
 205  
     /** Report a failure to complete a class.
 206  
      *  @param pos        Position to be used for error reporting.
 207  
      *  @param ex         The failure to report.
 208  
      */
 209  
     public Type completionError(DiagnosticPosition pos, CompletionFailure ex) {
 210  0
         log.error(pos, MsgSym.MESSAGE_CANNOT_ACCESS, ex.sym, ex.errmsg);
 211  0
         if (ex instanceof ClassReader.BadClassFile) throw new Abort();
 212  0
         else return syms.errType;
 213  
     }
 214  
 
 215  
     /** Report a type error.
 216  
      *  @param pos        Position to be used for error reporting.
 217  
      *  @param problem    A string describing the error.
 218  
      *  @param found      The type that was found.
 219  
      *  @param req        The type that was required.
 220  
      */
 221  
 //JavaFX change
 222  
     public
 223  
 //JavaFX change
 224  
     Type typeError(DiagnosticPosition pos, Object problem, Type found, Type req) {
 225  13
         String foundAsJavaFXType = types.toJavaFXString(found);
 226  13
         String requiredAsJavaFXType = types.toJavaFXString(req);
 227  13
         log.error(pos, MsgSym.MESSAGE_PROB_FOUND_REQ, problem, foundAsJavaFXType, requiredAsJavaFXType);
 228  13
         return syms.errType;
 229  
     }
 230  
 
 231  
     Type typeError(DiagnosticPosition pos, String problem, Type found, Type req, Object explanation) {
 232  0
         String foundAsJavaFXType = types.toJavaFXString(found);
 233  0
         String requiredAsJavaFXType = types.toJavaFXString(req);
 234  0
         log.error(pos, MsgSym.MESSAGE_PROB_FOUND_REQ_1, problem, foundAsJavaFXType, requiredAsJavaFXType, explanation);
 235  0
         return syms.errType;
 236  
     }
 237  
 
 238  
     /** Report an error that wrong type tag was found.
 239  
      *  @param pos        Position to be used for error reporting.
 240  
      *  @param required   An internationalized string describing the type tag
 241  
      *                    required.
 242  
      *  @param found      The type that was found.
 243  
      */
 244  
     Type typeTagError(DiagnosticPosition pos, Object required, Object found) {
 245  3
         Object requiredAsJavaFXType = required;
 246  3
         if (required instanceof Type) {
 247  2
             requiredAsJavaFXType = types.toJavaFXString((Type) requiredAsJavaFXType);
 248  
         }
 249  3
         Object foundAsJavaFXType = found;
 250  3
         if (foundAsJavaFXType instanceof Type) {
 251  3
             foundAsJavaFXType = types.toJavaFXString((Type) foundAsJavaFXType);
 252  
         }
 253  3
         log.error(pos, MsgSym.MESSAGE_TYPE_FOUND_REQ, foundAsJavaFXType, requiredAsJavaFXType);
 254  3
         return syms.errType;
 255  
     }
 256  
 
 257  
     /** Report an error that symbol cannot be referenced before super
 258  
      *  has been called.
 259  
      *  @param pos        Position to be used for error reporting.
 260  
      *  @param sym        The referenced symbol.
 261  
      */
 262  
 // JavaFX change
 263  
     public
 264  
 // JavaFX change
 265  
     void earlyRefError(DiagnosticPosition pos, Symbol sym) {
 266  0
         log.error(pos, MsgSym.MESSAGE_CANNOT_REF_BEFORE_CTOR_CALLED, sym);
 267  0
     }
 268  
 
 269  
     /** Report duplicate declaration error.
 270  
      */
 271  
 // JavaFX change
 272  
     protected
 273  
 // JavaFX change
 274  
     void duplicateError(DiagnosticPosition pos, Symbol sym) {
 275  0
         if (sym.type == null || !sym.type.isErroneous()) {
 276  0
             log.error(pos, MsgSym.MESSAGE_ALREADY_DEFINED, sym, sym.location());
 277  
         }
 278  0
     }
 279  
 
 280  
     /** Report array/varargs duplicate declaration 
 281  
      */
 282  
 // JavaFX change
 283  
     protected
 284  
 // JavaFX change
 285  
     void varargsDuplicateError(DiagnosticPosition pos, Symbol sym1, Symbol sym2) {
 286  0
         if (!sym1.type.isErroneous() && !sym2.type.isErroneous()) {
 287  0
             log.error(pos, MsgSym.MESSAGE_ARRAY_AND_VARARGS, sym1, sym2, sym2.location());
 288  
         }
 289  0
     }
 290  
 
 291  
 /* ************************************************************************
 292  
  * duplicate declaration checking
 293  
  *************************************************************************/
 294  
 
 295  
     /** Check that variable does not hide variable with same name in
 296  
      *        immediately enclosing local scope.
 297  
      *        @param pos             Position for error reporting.
 298  
      *        @param v             The symbol.
 299  
      *        @param s             The scope.
 300  
      */
 301  
 // JavaFX change
 302  
     public
 303  
 // JavaFX change
 304  
     void checkTransparentVar(DiagnosticPosition pos, VarSymbol v, Scope s) {
 305  3283
         if (s.next != null) {
 306  2743
             for (Scope.Entry e = s.next.lookup(v.name);
 307  2743
                  e.scope != null && e.sym.owner == v.owner;
 308  0
                  e = e.next()) {
 309  0
                 if (e.sym.kind == VAR &&
 310  
                     (e.sym.owner.kind & (VAR | MTH)) != 0 &&
 311  
                     v.name != names.error) {
 312  0
                     duplicateError(pos, e.sym);
 313  0
                     return;
 314  
                 }
 315  
             }
 316  
         }
 317  3283
     }
 318  
 
 319  
     /** Check that a class or interface does not hide a class or
 320  
      *        interface with same name in immediately enclosing local scope.
 321  
      *        @param pos             Position for error reporting.
 322  
      *        @param c             The symbol.
 323  
      *        @param s             The scope.
 324  
      */
 325  
 // JavaFX change
 326  
     public
 327  
 // JavaFX change
 328  
     void checkTransparentClass(DiagnosticPosition pos, ClassSymbol c, Scope s) {
 329  26
         if (s.next != null) {
 330  26
             for (Scope.Entry e = s.next.lookup(c.name);
 331  26
                  e.scope != null && e.sym.owner == c.owner;
 332  0
                  e = e.next()) {
 333  0
                 if (e.sym.kind == TYP &&
 334  
                     (e.sym.owner.kind & (VAR | MTH)) != 0 &&
 335  
                     c.name != names.error) {
 336  0
                     duplicateError(pos, e.sym);
 337  0
                     return;
 338  
                 }
 339  
             }
 340  
         }
 341  26
     }
 342  
 
 343  
     /** Check that class does not have the same name as one of
 344  
      *        its enclosing classes, or as a class defined in its enclosing scope.
 345  
      *        return true if class is unique in its enclosing scope.
 346  
      *        @param pos             Position for error reporting.
 347  
      *        @param name             The class name.
 348  
      *        @param s             The enclosing scope.
 349  
      */
 350  
 // JavaFX change
 351  
     public
 352  
 // JavaFX change
 353  
     boolean checkUniqueClassName(DiagnosticPosition pos, Name name, Scope s) {
 354  317
         for (Scope.Entry e = s.lookup(name); e.scope == s; e = e.next()) {
 355  0
             if (e.sym.kind == TYP && e.sym.name != names.error) {
 356  0
                 duplicateError(pos, e.sym);
 357  0
                 return false;
 358  
             }
 359  
         }
 360  1333
         for (Symbol sym = s.owner; sym != null; sym = sym.owner) {
 361  1016
             if (sym.kind == TYP && sym.name == name && sym.name != names.error) {
 362  0
                 duplicateError(pos, sym);
 363  0
                 return true;
 364  
             }
 365  
         }
 366  317
         return true;
 367  
     }
 368  
 
 369  
 /* *************************************************************************
 370  
  * Class name generation
 371  
  **************************************************************************/
 372  
 
 373  
     /** Return name of local class.
 374  
      *  This is of the form    <enclClass> $ n <classname>
 375  
      *  where
 376  
      *    enclClass is the flat name of the enclosing class,
 377  
      *    classname is the simple name of the local class
 378  
      */
 379  
 // JavaFX change
 380  
     public
 381  
 // JavaFX change
 382  
     Name localClassName(ClassSymbol c) {
 383  26
         for (int i=1; ; i++) {
 384  26
             Name flatname = names.
 385  
                 fromString("" + c.owner.enclClass().flatname +
 386  
                            target.syntheticNameChar() + i +
 387  
                            c.name);
 388  26
             if (compiled.get(flatname) == null) return flatname;
 389  
         }
 390  
     }
 391  
 
 392  
 /* *************************************************************************
 393  
  * Type Checking
 394  
  **************************************************************************/
 395  
 
 396  
     private Type deLocationize(Type external) {
 397  77640
         if (external.tag == CLASS) {
 398  25094
             Name flatname = ((ClassSymbol) external.tsym).flatname;
 399  25094
             Type deloc = defs.delocationize(flatname);
 400  25094
             if (deloc != null) {
 401  0
                 throw new AssertionError("At this point we should not have Location(s). This is most likely JavafxReader problem. It should convert all the Location types to the \"real\" types.");
 402  
             }
 403  
         }
 404  77640
         return external;
 405  
     }
 406  
     
 407  
     /** Check that a given type is assignable to a given proto-type.
 408  
      *  If it is, return the type, otherwise return errType.
 409  
      *  @param pos        Position to be used for error reporting.
 410  
      *  @param found      The type that was found.
 411  
      *  @param req        The type that was required.
 412  
      */
 413  
     Type checkType(DiagnosticPosition pos, Type foundRaw, Type reqRaw, Sequenceness pSequenceness) {
 414  38820
         Type req = deLocationize(reqRaw);
 415  38820
         Type found = deLocationize(foundRaw);
 416  38820
         Type realFound = found;
 417  38820
         if (req.tag == ERROR)
 418  0
             return req;
 419  38820
         if (found == syms.unreachableType)
 420  216
             return found;
 421  38604
         if (found.tag == FORALL)
 422  0
             return instantiatePoly(pos, (ForAll)found, req, convertWarner(pos, found, req));
 423  38604
         if (req.tag == NONE || req == syms.javafx_UnspecifiedType)
 424  30811
             return found;
 425  7793
         if (types.isSequence(req)) {  
 426  561
             req = types.elementType(req);
 427  561
             pSequenceness = Sequenceness.REQUIRED;
 428  
         }
 429  7793
         if (types.isSequence(found) || types.isArray(found)) {  
 430  430
             if (pSequenceness != Sequenceness.DISALLOWED) {
 431  429
                 found = types.isSequence(found) ? types.elementType(found) : types.elemtype(found);
 432  
             } else {
 433  1
                 return typeError(pos, JCDiagnostic.fragment(MsgSym.MESSAGE_INCOMPATIBLE_TYPES), found, req);
 434  
             }
 435  
         }
 436  7792
         if (types.isAssignable(found, req, convertWarner(pos, found, req)))
 437  7780
             return realFound;
 438  
 
 439  
         // use the JavafxClassSymbol's supertypes to see if req is in the supertypes of found.
 440  12
         ListBuffer<Type> supertypes = ListBuffer.<Type>lb();
 441  12
         Set<Type> superSet = new HashSet<Type>();
 442  12
         supertypes.append(found);
 443  12
         superSet.add(found);
 444  
 
 445  12
         types.getSupertypes(found.tsym, supertypes, superSet);
 446  
 
 447  12
         for (Type baseType : supertypes) {
 448  18
             if (types.isAssignable(baseType, req, convertWarner(pos, found, req)))
 449  0
                 return realFound;
 450  
         }
 451  
 
 452  12
         if (found.tag <= DOUBLE && req.tag <= DOUBLE)
 453  0
             return typeError(pos, JCDiagnostic.fragment(MsgSym.MESSAGE_POSSIBLE_LOSS_OF_PRECISION), found, req);
 454  12
         if (found.isSuperBound()) {
 455  0
             log.error(pos, MsgSym.MESSAGE_ASSIGNMENT_FROM_SUPER_BOUND, found);
 456  0
             return syms.errType;
 457  
         }
 458  12
         if (req.isExtendsBound()) {
 459  0
             log.error(pos, MsgSym.MESSAGE_ASSIGNMENT_TO_EXTENDS_BOUND, req);
 460  0
             return syms.errType;
 461  
         }
 462  12
         return typeError(pos, JCDiagnostic.fragment(MsgSym.MESSAGE_INCOMPATIBLE_TYPES), found, req);
 463  
     }
 464  
 
 465  
     /** Instantiate polymorphic type to some prototype, unless
 466  
      *  prototype is `anyPoly' in which case polymorphic type
 467  
      *  is returned unchanged.
 468  
      */
 469  
     Type instantiatePoly(DiagnosticPosition pos, ForAll t, Type pt, Warner warn) {
 470  0
         if (pt == Infer.anyPoly && complexInference) {
 471  0
             return t;
 472  0
         } else if (pt == Infer.anyPoly || pt.tag == NONE) {
 473  0
             Type newpt = t.qtype.tag <= VOID ? t.qtype : syms.objectType;
 474  0
             return instantiatePoly(pos, t, newpt, warn);
 475  0
         } else if (pt.tag == ERROR) {
 476  0
             return pt;
 477  
         } else {
 478  
             try {
 479  0
                 return infer.instantiateExpr(t, pt, warn);
 480  0
             } catch (Infer.NoInstanceException ex) {
 481  0
                 if (ex.isAmbiguous) {
 482  0
                     JCDiagnostic d = ex.getDiagnostic();
 483  0
                     log.error(pos,
 484  
                   d!=null ? MsgSym.MESSAGE_UNDETERMINDED_TYPE_1 : MsgSym.MESSAGE_UNDETERMINDED_TYPE,
 485  
                   t, d);
 486  0
                     return syms.errType;
 487  
                 } else {
 488  0
                     JCDiagnostic d = ex.getDiagnostic();
 489  0
                     return typeError(pos,
 490  
                  JCDiagnostic.fragment(d!=null ? MsgSym.MESSAGE_INCOMPATIBLE_TYPES_1 : MsgSym.MESSAGE_INCOMPATIBLE_TYPES, d),
 491  
                  t, pt);
 492  
                 }
 493  
             }
 494  
         }
 495  
     }
 496  
 
 497  
     /** Check that a given type can be cast to a given target type.
 498  
      *  Return the result of the cast.
 499  
      *  @param pos        Position to be used for error reporting.
 500  
      *  @param found      The type that is being cast.
 501  
      *  @param req        The target type of the cast.
 502  
      */
 503  
 // JavaFX change
 504  
     public
 505  
 // JavaFX change
 506  
     Type checkCastable(DiagnosticPosition pos, Type found, Type req) {
 507  196
         if (found.tag == FORALL && found instanceof ForAll) {
 508  0
             instantiatePoly(pos, (ForAll) found, req, castWarner(pos, found, req));
 509  0
             return req;
 510  196
         } else if (types.isCastable(found, req, castWarner(pos, found, req))) {
 511  194
             return req;
 512  
         }
 513  
         // use the JavafxClassSymbol's supertypes to see if req is in the supertypes of found.
 514  2
         else if (found.tsym != null && found.tsym instanceof JavafxClassSymbol) {
 515  2
             ListBuffer<Type> supertypes = ListBuffer.<Type>lb();
 516  2
             Set<Type> superSet = new HashSet<Type>();
 517  2
             supertypes.append(found);
 518  2
             superSet.add(found);
 519  
 
 520  2
             types.getSupertypes(found.tsym, supertypes, superSet);
 521  
 
 522  2
             for (Type baseType : supertypes) {
 523  4
                 if (types.isCastable(baseType, req, castWarner(pos, found, req)))
 524  2
                     return req;
 525  
             }
 526  
         }
 527  
 
 528  0
         if (req.tsym != null && req.tsym instanceof JavafxClassSymbol) {
 529  0
             ListBuffer<Type> supertypes = ListBuffer.<Type>lb();
 530  0
             Set<Type> superSet = new HashSet<Type>();
 531  0
             supertypes.append(req);
 532  0
             superSet.add(req);
 533  
 
 534  0
             types.getSupertypes(req.tsym, supertypes, superSet);
 535  0
             for (Type baseType : supertypes) {
 536  0
                 if (types.isCastable(baseType, found, castWarner(pos, found, req)))
 537  0
                     return req;
 538  
             }
 539  
         }
 540  
         
 541  0
         return typeError(pos,
 542  
             JCDiagnostic.fragment(MsgSym.MESSAGE_INCONVERTIBLE_TYPES),
 543  
             found, req);
 544  
     }
 545  
 //where
 546  
         /** Is type a type variable, or a (possibly multi-dimensional) array of
 547  
          *  type variables?
 548  
          */
 549  
         boolean isTypeVar(Type t) {
 550  0
             return t.tag == TYPEVAR || t.tag == ARRAY && isTypeVar(types.elemtype(t));
 551  
         }
 552  
 
 553  
     /** Check that a type is within some bounds.
 554  
      *
 555  
      *  Used in TypeApply to verify that, e.g., X in V<X> is a valid
 556  
      *  type argument.
 557  
      *  @param pos           Position to be used for error reporting.
 558  
      *  @param a             The type that should be bounded by bs.
 559  
      *  @param bs            The bound.
 560  
      */
 561  
     private void checkExtends(DiagnosticPosition pos, Type a, TypeVar bs) {
 562  0
         if (a.isUnbound()) {
 563  0
             return;
 564  0
         } else if (a.tag != WILDCARD) {
 565  0
             a = types.upperBound(a);
 566  0
             for (List<Type> l = types.getBounds(bs); l.nonEmpty(); l = l.tail) {
 567  0
                 if (!types.isSubtype(a, l.head)) {
 568  0
                     log.error(pos, MsgSym.MESSAGE_NOT_WITHIN_BOUNDS, a);
 569  0
                     return;
 570  
                 }
 571  
             }
 572  0
         } else if (a.isExtendsBound()) {
 573  0
             if (!types.isCastable(bs.getUpperBound(), types.upperBound(a), Warner.noWarnings))
 574  0
                 log.error(pos, MsgSym.MESSAGE_NOT_WITHIN_BOUNDS, a);
 575  0
         } else if (a.isSuperBound()) {
 576  0
             if (types.notSoftSubtype(types.lowerBound(a), bs.getUpperBound()))
 577  0
                 log.error(pos, MsgSym.MESSAGE_NOT_WITHIN_BOUNDS, a);
 578  
         }
 579  0
     }
 580  
 
 581  
 // Javafx change
 582  
     public
 583  
 // Javafx change
 584  
     /** Check that type is different from 'void'.
 585  
      *  @param pos           Position to be used for error reporting.
 586  
      *  @param t             The type to be checked.
 587  
      */
 588  
     Type checkNonVoid(DiagnosticPosition pos, Type t) {
 589  9019
         if (t.tag == VOID) {
 590  1
             log.error(pos, MsgSym.MESSAGE_VOID_NOT_ALLOWED_HERE);
 591  1
             return syms.errType;
 592  
         } else {
 593  9018
             return t;
 594  
         }
 595  
     }
 596  
 
 597  
     /** Check that type is a class or interface type.
 598  
      *  @param pos           Position to be used for error reporting.
 599  
      *  @param t             The type to be checked.
 600  
      */
 601  
 // JavaFX change
 602  
     public
 603  
 // JavaFX change
 604  
     Type checkClassType(DiagnosticPosition pos, Type t) {
 605  667
         if (t.tag != CLASS && t.tag != ERROR)
 606  0
             return typeTagError(pos,
 607  
                                 JCDiagnostic.fragment(MsgSym.MESSAGE_TYPE_REQ_CLASS),
 608  
                                 (t.tag == TYPEVAR)
 609  
                                 ? JCDiagnostic.fragment(MsgSym.MESSAGE_TYPE_PARAMETER, t)
 610  
                                 : t); 
 611  
         else
 612  667
             return t;
 613  
     }
 614  
 
 615  
     /**
 616  
      * Return element type for a sequence type, and report error otherwise.
 617  
      */
 618  
     public Type checkSequenceElementType (DiagnosticPosition pos, Type t) {
 619  479
         if (types.isSequence(t))
 620  477
             return types.elementType(t);
 621  2
         if (t.tag != ERROR) {
 622  2
             return typeTagError(pos, types.sequenceType(syms.unknownType), t);
 623  
         }
 624  0
         return syms.errType;
 625  
     }
 626  
 
 627  
     /** Check that type is a class or interface type.
 628  
      *  @param pos           Position to be used for error reporting.
 629  
      *  @param t             The type to be checked.
 630  
      *  @param noBounds    True if type bounds are illegal here.
 631  
      */
 632  
 // JavaFX change
 633  
     public
 634  
 // JavaFX change
 635  
     Type checkClassType(DiagnosticPosition pos, Type t, boolean noBounds) {
 636  667
         t = checkClassType(pos, t);
 637  667
         if (noBounds && t.isParameterized()) {
 638  0
             List<Type> args = t.getTypeArguments();
 639  0
             while (args.nonEmpty()) {
 640  0
                 if (args.head.tag == WILDCARD)
 641  0
                     return typeTagError(pos,
 642  
                                         Log.getLocalizedString(MsgSym.MESSAGE_TYPE_REQ_EXACT),
 643  
                                         args.head);
 644  0
                 args = args.tail;
 645  
             }
 646  
         }
 647  667
         return t;
 648  
     }
 649  
 
 650  
     /** Check that type is a reifiable class, interface or array type.
 651  
      *  @param pos           Position to be used for error reporting.
 652  
      *  @param t             The type to be checked.
 653  
      */
 654  
 // JavaFX change
 655  
     public
 656  
 // JavaFX change
 657  
     Type checkReifiableReferenceType(DiagnosticPosition pos, Type t) {
 658  37
         if (t.tag != CLASS && t.tag != ARRAY && t.tag != ERROR) {
 659  1
             return typeTagError(pos,
 660  
                                 JCDiagnostic.fragment(MsgSym.MESSAGE_TYPE_REQ_CLASS_ARRAY),
 661  
                                 t);
 662  36
         } else if (!types.isReifiable(t)) {
 663  1
             log.error(pos, MsgSym.MESSAGE_ILLEGAL_GENERIC_TYPE_FOR_INSTOF);
 664  1
             return syms.errType;
 665  
         } else {
 666  35
             return t;
 667  
         }
 668  
     }
 669  
 
 670  
 // Javafx change
 671  
     public
 672  
 // Javafx change
 673  
     /** Check that type is a reference type, i.e. a class, interface or array type
 674  
      *  or a type variable.
 675  
      *  @param pos           Position to be used for error reporting.
 676  
      *  @param t             The type to be checked.
 677  
      */
 678  
     Type checkRefType(DiagnosticPosition pos, Type t) {
 679  0
         switch (t.tag) {
 680  
         case CLASS:
 681  
         case ARRAY:
 682  
         case TYPEVAR:
 683  
         case WILDCARD:
 684  
         case ERROR:
 685  0
             return t;
 686  
         default:
 687  0
             return typeTagError(pos,
 688  
                                 JCDiagnostic.fragment(MsgSym.MESSAGE_TYPE_REQ_REF),
 689  
                                 t);
 690  
         }
 691  
     }
 692  
 
 693  
     /** Check that type is a null or reference type.
 694  
      *  @param pos           Position to be used for error reporting.
 695  
      *  @param t             The type to be checked.
 696  
      */
 697  
 // JavaFX change
 698  
     public
 699  
 // JavaFX change
 700  
     Type checkNullOrRefType(DiagnosticPosition pos, Type t) {
 701  37
         switch (t.tag) {
 702  
         case CLASS:
 703  
         case ARRAY:
 704  
         case TYPEVAR:
 705  
         case WILDCARD:
 706  
         case BOT:
 707  
         case ERROR:
 708  37
             return t;
 709  
         default:
 710  0
             return typeTagError(pos,
 711  
                                 JCDiagnostic.fragment(MsgSym.MESSAGE_TYPE_REQ_REF),
 712  
                                 t);
 713  
         }
 714  
     }
 715  
 
 716  
     /** Check that flag set does not contain elements of two conflicting sets. s
 717  
      *  Return true if it doesn't.
 718  
      *  @param pos           Position to be used for error reporting.
 719  
      *  @param flags         The set of flags to be checked.
 720  
      *  @param set1          Conflicting flags set #1.
 721  
      *  @param set2          Conflicting flags set #2.
 722  
      */
 723  
     boolean checkDisjoint(DiagnosticPosition pos, long flags, long set1, long set2) {
 724  29190
         if ((flags & set1) != 0 && (flags & set2) != 0) {
 725  0
             log.error(pos,
 726  
                       MsgSym.MESSAGE_ILLEGAL_COMBINATION_OF_MODIFIERS,
 727  
                       JavafxTreeInfo.flagNames(JavafxTreeInfo.firstFlag(flags & set1)),
 728  
                       JavafxTreeInfo.flagNames(JavafxTreeInfo.firstFlag(flags & set2)));
 729  0
             return false;
 730  
         } else
 731  29190
             return true;
 732  
     }
 733  
 
 734  
     /** Check that given modifiers are legal for given symbol and
 735  
      *  return modifiers together with any implicit modififiers for that symbol.
 736  
      *  Warning: we can't use flags() here since this method
 737  
      *  is called during class enter, when flags() would cause a premature
 738  
      *  completion.
 739  
      *  @param pos           Position to be used for error reporting.
 740  
      *  @param flags         The set of modifiers given in a definition.
 741  
      *  @param sym           The defined symbol.
 742  
      */
 743  
 // JavaFX change
 744  
     public
 745  
 // JavaFX change
 746  
     long checkFlags(DiagnosticPosition pos, long flags, Symbol sym, JCTree tree) {
 747  
         long mask;
 748  5099
         long implicit = 0;
 749  5099
         switch (sym.kind) {
 750  
         case VAR:
 751  3283
             if (sym.owner.kind != TYP)
 752  2743
                 mask = LocalVarFlags;
 753  540
             else if ((sym.owner.flags_field & INTERFACE) != 0)
 754  0
                 mask = implicit = InterfaceVarFlags;
 755  
             else
 756  540
                 mask = VarFlags;
 757  540
             break;
 758  
         case MTH:
 759  1114
             if (sym.name == names.init) {
 760  0
                 if ((sym.owner.flags_field & ENUM) != 0) { 
 761  
                     // enum constructors cannot be declared public or
 762  
                     // protected and must be implicitly or explicitly
 763  
                     // private
 764  0
                     implicit = PRIVATE;
 765  0
                     mask = PRIVATE;
 766  
                 } else
 767  0
                     mask = ConstructorFlags;
 768  1114
             }  else if ((sym.owner.flags_field & INTERFACE) != 0)
 769  0
                 mask = implicit = InterfaceMethodFlags;
 770  
             else {
 771  1114
                 mask = MethodFlags;
 772  
             }
 773  
             // Imply STRICTFP if owner has STRICTFP set.
 774  1114
             if (((flags|implicit) & Flags.ABSTRACT) == 0)
 775  1104
               implicit |= sym.owner.flags_field & STRICTFP;
 776  
             break;
 777  
         case TYP:
 778  702
             if (sym.isLocal()) {
 779  26
                 mask = LocalClassFlags;
 780  26
                 if (sym.name.len == 0 || true /*allow for all inner classes since they have to be static*/) { // Anonymous class
 781  
                     // Anonymous classes in static methods are themselves static;
 782  
                     // that's why we admit STATIC here.
 783  26
                     mask |= STATIC;
 784  
                     // JLS: Anonymous classes are final.
 785  26
                     implicit |= FINAL;
 786  
                 }
 787  26
                 if ((sym.owner.flags_field & STATIC) == 0 &&
 788  
                     (flags & ENUM) != 0)
 789  0
                     log.error(pos, MsgSym.MESSAGE_ENUMS_MUST_BE_STATIC);
 790  676
             } else if (sym.owner.kind == TYP) {
 791  291
                 mask = MemberClassFlags;
 792  291
                 if (sym.owner.owner.kind == PCK ||
 793  
                     (sym.owner.flags_field & STATIC) != 0)
 794  291
                     mask |= STATIC;
 795  0
                 else if ((flags & ENUM) != 0)
 796  0
                     log.error(pos, MsgSym.MESSAGE_ENUMS_MUST_BE_STATIC);
 797  
                 // Nested interfaces and enums are always STATIC (Spec ???)
 798  291
                 if ((flags & (INTERFACE | ENUM)) != 0 ) implicit = STATIC;
 799  
             } else {
 800  385
                 mask = ClassFlags;
 801  
             }
 802  
             // Interfaces are always ABSTRACT
 803  702
             if ((flags & INTERFACE) != 0) implicit |= ABSTRACT;
 804  
 
 805  702
             if ((flags & ENUM) != 0) {
 806  
                 // enums can't be declared abstract or final
 807  0
                 mask &= ~(ABSTRACT | FINAL);
 808  0
                 implicit |= implicitEnumFinalFlag(tree);
 809  
             }
 810  
             // Imply STRICTFP if owner has STRICTFP set.
 811  702
             implicit |= sym.owner.flags_field & STRICTFP;
 812  702
             break;
 813  
         default:
 814  0
             throw new AssertionError();
 815  
         }
 816  5099
         long illegal = flags & StandardFlags & ~mask;
 817  5099
         if (illegal != 0) {
 818  0
             if ((illegal & INTERFACE) != 0) {
 819  0
                 log.error(pos, MsgSym.MESSAGE_INTF_NOT_ALLOWED_HERE);
 820  0
                 mask |= INTERFACE;
 821  
             }
 822  
             else {
 823  0
                 log.error(pos,
 824  
                           MsgSym.MESSAGE_MOD_NOT_ALLOWED_HERE, JavafxTreeInfo.flagNames(illegal));
 825  
             }
 826  
         }
 827  5099
         else if ((sym.kind == TYP ||
 828  
                   // ISSUE: Disallowing abstract&private is no longer appropriate
 829  
                   // in the presence of inner classes. Should it be deleted here?
 830  
                   checkDisjoint(pos, flags,
 831  
                                 ABSTRACT,
 832  
                                 PRIVATE | STATIC))
 833  
                  &&
 834  
                  checkDisjoint(pos, flags,
 835  
                                ABSTRACT | INTERFACE,
 836  
                                FINAL | NATIVE | SYNCHRONIZED)
 837  
                  &&
 838  
                  checkDisjoint(pos, flags,
 839  
                                PUBLIC,
 840  
                                PRIVATE | PROTECTED)
 841  
                  &&
 842  
                  checkDisjoint(pos, flags,
 843  
                                PRIVATE,
 844  
                                PUBLIC | PROTECTED)
 845  
                  &&
 846  
                  checkDisjoint(pos, flags,
 847  
                                FINAL,
 848  
                                VOLATILE)
 849  
                  &&
 850  
                  (sym.kind == TYP ||
 851  
                   checkDisjoint(pos, flags,
 852  
                                 ABSTRACT | NATIVE,
 853  
                                 STRICTFP))) {
 854  
             // skip
 855  
         }
 856  5099
         return flags & (mask | ~StandardFlags) | implicit;
 857  
     }
 858  
 
 859  
 
 860  
     /** Determine if this enum should be implicitly final.
 861  
      *
 862  
      *  If the enum has no specialized enum contants, it is final.
 863  
      *
 864  
      *  If the enum does have specialized enum contants, it is
 865  
      *  <i>not</i> final.
 866  
      */
 867  
     private long implicitEnumFinalFlag(JCTree tree) {
 868  0
         if (tree.getTag() != JCTree.CLASSDEF) return 0;
 869  
         class SpecialTreeVisitor extends JCTree.Visitor {
 870  
             boolean specialized;
 871  0
             SpecialTreeVisitor() {
 872  0
                 this.specialized = false;
 873  0
             }
 874  
                 
 875  
             @Override
 876  0
             public void visitTree(JCTree tree) { /* no-op */ }
 877  
         
 878  
             @Override
 879  
             public void visitVarDef(JCVariableDecl tree) {
 880  0
                 if ((tree.mods.flags & ENUM) != 0) {
 881  0
                     if (tree.init instanceof JCNewClass &&
 882  
                         ((JCNewClass) tree.init).def != null) {
 883  0
                         specialized = true;
 884  
                     }
 885  
                 }
 886  0
             }
 887  
         }
 888  
 
 889  0
         SpecialTreeVisitor sts = new SpecialTreeVisitor();
 890  0
         JFXClassDeclaration cdef = (JFXClassDeclaration) tree;
 891  0
         for (JCTree localDefs: cdef.getMembers()) {
 892  0
             localDefs.accept(sts);
 893  0
             if (sts.specialized) return 0;
 894  
         }
 895  0
         return FINAL;
 896  
     }
 897  
 
 898  
 /* *************************************************************************
 899  
  * Type Validation
 900  
  **************************************************************************/
 901  
 
 902  
     /** Validate a type expression. That is,
 903  
      *  check that all type arguments of a parametric type are within
 904  
      *  their bounds. This must be done in a second phase after type attributon
 905  
      *  since a class might have a subclass as type parameter bound. E.g:
 906  
      *
 907  
      *  class B<A extends C> { ... }
 908  
      *  class C extends B<C> { ... }
 909  
      *
 910  
      *  and we can't make sure that the bound is already attributed because
 911  
      *  of possible cycles.
 912  
      */
 913  399
     private Validator validator = new Validator();
 914  
 
 915  
     /** Visitor method: Validate a type expression, if it is not null, catching
 916  
      *  and reporting any completion failures.
 917  
      */
 918  
 // JavaFX change
 919  
     public
 920  
 // JavaFX change
 921  
     void validate(JCTree tree) {
 922  
         try {
 923  803
             if (tree != null) tree.accept(validator);
 924  0
         } catch (CompletionFailure ex) {
 925  0
             completionError(tree.pos(), ex);
 926  803
         }
 927  803
     }
 928  
 
 929  
     /** Visitor method: Validate a list of type expressions.
 930  
      */
 931  
 // JavaFX change
 932  
     public
 933  
 // JavaFX change
 934  
     void validate(List<? extends JCTree> trees) {
 935  4121
         for (List<? extends JCTree> l = trees; l.nonEmpty(); l = l.tail)
 936  124
             validate(l.head);
 937  3997
     }
 938  
 
 939  
     /** Visitor method: Validate a list of type parameters.
 940  
      */
 941  
 // Javafx modification
 942  
 public
 943  
 // Javafx modification
 944  
     void validateTypeParams(List<JCTypeParameter> trees) {
 945  670
         for (List<JCTypeParameter> l = trees; l.nonEmpty(); l = l.tail)
 946  0
             validate(l.head);
 947  670
     }
 948  
 
 949  
     /** A visitor class for type validation.
 950  
      */
 951  399
     class Validator extends JavafxTreeScanner {
 952  
 
 953  
         @Override
 954  
         public void visitTypeArray(JCArrayTypeTree tree) {
 955  0
             validate(tree.elemtype);
 956  0
         }
 957  
 
 958  
         @Override
 959  
         public void visitTypeApply(JCTypeApply tree) {
 960  0
             if (tree.type.tag == CLASS) {
 961  0
                 List<Type> formals = tree.type.tsym.type.getTypeArguments();
 962  0
                 List<Type> actuals = tree.type.getTypeArguments();
 963  0
                 List<JCExpression> args = tree.arguments;
 964  0
                 List<Type> forms = formals;
 965  0
                 ListBuffer<TypeVar> tvars_buf = new ListBuffer<TypeVar>();
 966  
 
 967  
                 // For matching pairs of actual argument types `a' and
 968  
                 // formal type parameters with declared bound `b' ...
 969  0
                 while (args.nonEmpty() && forms.nonEmpty()) {
 970  0
                     validate(args.head);
 971  
 
 972  
                     // exact type arguments needs to know their
 973  
                     // bounds (for upper and lower bound
 974  
                     // calculations).  So we create new TypeVars with
 975  
                     // bounds substed with actuals.
 976  0
                     tvars_buf.append(types.substBound(((TypeVar)forms.head),
 977  
                                                       formals,
 978  
                                                       Type.removeBounds(actuals)));
 979  
 
 980  0
                     args = args.tail;
 981  0
                     forms = forms.tail;
 982  
                 }
 983  
 
 984  0
                 args = tree.arguments;
 985  0
                 List<TypeVar> tvars = tvars_buf.toList();
 986  0
                 while (args.nonEmpty() && tvars.nonEmpty()) {
 987  
                     // Let the actual arguments know their bound
 988  0
                     args.head.type.withTypeVar(tvars.head);
 989  0
                     args = args.tail;
 990  0
                     tvars = tvars.tail;
 991  
                 }
 992  
 
 993  0
                 args = tree.arguments;
 994  0
                 tvars = tvars_buf.toList();
 995  0
                 while (args.nonEmpty() && tvars.nonEmpty()) {
 996  0
                     checkExtends(args.head.pos(),
 997  
                                  args.head.type,
 998  
                                  tvars.head);
 999  0
                     args = args.tail;
 1000  0
                     tvars = tvars.tail;
 1001  
                 }
 1002  
 
 1003  
                 // Check that this type is either fully parameterized, or
 1004  
                 // not parameterized at all.
 1005  0
                 if (tree.type.getEnclosingType().isRaw())
 1006  0
                     log.error(tree.pos(), MsgSym.MESSAGE_IMPROPERLY_FORMED_TYPE_INNER_RAW_PARAM);
 1007  0
                 if (tree.clazz.getTag() == JCTree.SELECT)
 1008  0
                     visitSelectInternal((JCFieldAccess)tree.clazz);
 1009  
             }
 1010  0
         }
 1011  
 
 1012  
         @Override
 1013  
         public void visitTypeParameter(JCTypeParameter tree) {
 1014  0
             validate(tree.bounds);
 1015  0
             checkClassBounds(tree.pos(), tree.type);
 1016  0
         }
 1017  
 
 1018  
         @Override
 1019  
         public void visitWildcard(JCWildcard tree) {
 1020  0
             if (tree.inner != null)
 1021  0
                 validate(tree.inner);
 1022  0
         }
 1023  
 
 1024  
         @Override
 1025  
         public void visitSelect(JCFieldAccess tree) {
 1026  74
             if (tree.type.tag == CLASS) {
 1027  38
                 visitSelectInternal(tree);
 1028  
 
 1029  
                 // Check that this type is either fully parameterized, or
 1030  
                 // not parameterized at all.
 1031  38
                 if (tree.selected.type.isParameterized() && tree.type.tsym.type.getTypeArguments().nonEmpty())
 1032  0
                     log.error(tree.pos(), MsgSym.MESSAGE_IMPROPERLY_FORMED_TYPE_PARAM_MISSING);
 1033  
             }
 1034  74
         }
 1035  
         public void visitSelectInternal(JCFieldAccess tree) {
 1036  38
             if (tree.type.getEnclosingType().tag != CLASS &&
 1037  
                 tree.selected.type.isParameterized()) {
 1038  
                 // The enclosing type is not a class, so we are
 1039  
                 // looking at a static member type.  However, the
 1040  
                 // qualifying expression is parameterized.
 1041  0
                 log.error(tree.pos(), MsgSym.MESSAGE_CANNOT_SELECT_STATIC_CLASS_FROM_PARAM_TYPE);
 1042  
             } else {
 1043  
                 // otherwise validate the rest of the expression
 1044  38
                 validate(tree.selected);
 1045  
             }
 1046  38
         }
 1047  
 
 1048  
         /** Default visitor method: do nothing.
 1049  
          */
 1050  
         @Override
 1051  
         public void visitTree(JCTree tree) {
 1052  0
         }
 1053  
     }
 1054  
 
 1055  
 /* *************************************************************************
 1056  
  * Exception checking
 1057  
  **************************************************************************/
 1058  
 
 1059  
     /* The following methods treat classes as sets that contain
 1060  
      * the class itself and all their subclasses
 1061  
      */
 1062  
 
 1063  
     /** Is given type a subtype of some of the types in given list?
 1064  
      */
 1065  
     boolean subset(Type t, List<Type> ts) {
 1066  0
         for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
 1067  0
             if (types.isSubtype(t, l.head)) return true;
 1068  0
         return false;
 1069  
     }
 1070  
 
 1071  
     /** Is given type a subtype or supertype of
 1072  
      *  some of the types in given list?
 1073  
      */
 1074  
     boolean intersects(Type t, List<Type> ts) {
 1075  0
         for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
 1076  0
             if (types.isSubtype(t, l.head) || types.isSubtype(l.head, t)) return true;
 1077  0
         return false;
 1078  
     }
 1079  
 
 1080  
     /** Add type set to given type list, unless it is a subclass of some class
 1081  
      *  in the list.
 1082  
      */
 1083  
     List<Type> incl(Type t, List<Type> ts) {
 1084  0
         return subset(t, ts) ? ts : excl(t, ts).prepend(t);
 1085  
     }
 1086  
 
 1087  
     /** Remove type set from type set list.
 1088  
      */
 1089  
     List<Type> excl(Type t, List<Type> ts) {
 1090  0
         if (ts.isEmpty()) {
 1091  0
             return ts;
 1092  
         } else {
 1093  0
             List<Type> ts1 = excl(t, ts.tail);
 1094  0
             if (types.isSubtype(ts.head, t)) return ts1;
 1095  0
             else if (ts1 == ts.tail) return ts;
 1096  0
             else return ts1.prepend(ts.head);
 1097  
         }
 1098  
     }
 1099  
 
 1100  
     /** Form the union of two type set lists.
 1101  
      */
 1102  
     List<Type> union(List<Type> ts1, List<Type> ts2) {
 1103  0
         List<Type> ts = ts1;
 1104  0
         for (List<Type> l = ts2; l.nonEmpty(); l = l.tail)
 1105  0
             ts = incl(l.head, ts);
 1106  0
         return ts;
 1107  
     }
 1108  
 
 1109  
     /** Form the difference of two type lists.
 1110  
      */
 1111  
     List<Type> diff(List<Type> ts1, List<Type> ts2) {
 1112  0
         List<Type> ts = ts1;
 1113  0
         for (List<Type> l = ts2; l.nonEmpty(); l = l.tail)
 1114  0
             ts = excl(l.head, ts);
 1115  0
         return ts;
 1116  
     }
 1117  
 
 1118  
     /** Form the intersection of two type lists.
 1119  
      */
 1120  
     public List<Type> intersect(List<Type> ts1, List<Type> ts2) {
 1121  0
         List<Type> ts = List.nil();
 1122  0
         for (List<Type> l = ts1; l.nonEmpty(); l = l.tail)
 1123  0
             if (subset(l.head, ts2)) ts = incl(l.head, ts);
 1124  0
         for (List<Type> l = ts2; l.nonEmpty(); l = l.tail)
 1125  0
             if (subset(l.head, ts1)) ts = incl(l.head, ts);
 1126  0
         return ts;
 1127  
     }
 1128  
 
 1129  
     /** Is exc an exception symbol that need not be declared?
 1130  
      */
 1131  
     boolean isUnchecked(ClassSymbol exc) {
 1132  0
         return
 1133  
             exc.kind == ERR ||
 1134  
             exc.isSubClass(syms.errorType.tsym, types) ||
 1135  
             exc.isSubClass(syms.runtimeExceptionType.tsym, types);
 1136  
     }
 1137  
 
 1138  
     /** Is exc an exception type that need not be declared?
 1139  
      */
 1140  
     boolean isUnchecked(Type exc) {
 1141  0
         return
 1142  
             (exc.tag == TYPEVAR) ? isUnchecked(types.supertype(exc)) :
 1143  
             (exc.tag == CLASS) ? isUnchecked((ClassSymbol)exc.tsym) :
 1144  
             exc.tag == BOT;
 1145  
     }
 1146  
 
 1147  
     /** Same, but handling completion failures.
 1148  
      */
 1149  
     boolean isUnchecked(DiagnosticPosition pos, Type exc) {
 1150  
         try {
 1151  0
             return isUnchecked(exc);
 1152  0
         } catch (CompletionFailure ex) {
 1153  0
             completionError(pos, ex);
 1154  0
             return true;
 1155  
         }
 1156  
     }
 1157  
 
 1158  
     /** Is exc handled by given exception list?
 1159  
      */
 1160  
     boolean isHandled(Type exc, List<Type> handled) {
 1161  0
         return isUnchecked(exc) || subset(exc, handled);
 1162  
     }
 1163  
 
 1164  
     /** Return all exceptions in thrown list that are not in handled list.
 1165  
      *  @param thrown     The list of thrown exceptions.
 1166  
      *  @param handled    The list of handled exceptions.
 1167  
      */
 1168  
     List<Type> unHandled(List<Type> thrown, List<Type> handled) {
 1169  180
         List<Type> unhandled = List.nil();
 1170  180
         for (List<Type> l = thrown; l.nonEmpty(); l = l.tail)
 1171  0
             if (!isHandled(l.head, handled)) unhandled = unhandled.prepend(l.head);
 1172  180
         return unhandled;
 1173  
     }
 1174  
 
 1175  
 /* *************************************************************************
 1176  
  * Overriding/Implementation checking
 1177  
  **************************************************************************/
 1178  
 
 1179  
     /** The level of access protection given by a flag set,
 1180  
      *  where PRIVATE is highest and PUBLIC is lowest.
 1181  
      */
 1182  
     static int protection(long flags) {
 1183  0
         switch ((short)(flags & AccessFlags)) {
 1184  0
         case PRIVATE: return 3;
 1185  0
         case PROTECTED: return 1;
 1186  
         default:
 1187  0
         case PUBLIC: return 0;
 1188  0
         case 0: return 2;
 1189  
         }
 1190  
     }
 1191  
 
 1192  
     /** A string describing the access permission given by a flag set.
 1193  
      *  This always returns a space-separated list of Java Keywords.
 1194  
      */
 1195  
     private static String protectionString(long flags) {
 1196  0
         long flags1 = flags & AccessFlags;
 1197  0
         return (flags1 == 0) ? "package" : JavafxTreeInfo.flagNames(flags1);
 1198  
     }
 1199  
 
 1200  
     /** A customized "cannot override" error message.
 1201  
      *  @param m      The overriding method.
 1202  
      *  @param other  The overridden method.
 1203  
      *  @return       An internationalized string.
 1204  
      */
 1205  
     static Object cannotOverride(MethodSymbol m, MethodSymbol other) {
 1206  
         String key;
 1207  0
         if ((other.owner.flags() & INTERFACE) == 0) 
 1208  0
             key = MsgSym.MESSAGE_CANNOT_OVERRIDE;
 1209  0
         else if ((m.owner.flags() & INTERFACE) == 0) 
 1210  0
             key = MsgSym.MESSAGE_CANNOT_IMPLEMENT;
 1211  
         else
 1212  0
             key = MsgSym.MESSAGE_CLASHES_WITH;
 1213  0
         return JCDiagnostic.fragment(key, m, m.location(), other, other.location());
 1214  
     }
 1215  
 
 1216  
     /** A customized "override" warning message.
 1217  
      *  @param m      The overriding method.
 1218  
      *  @param other  The overridden method.
 1219  
      *  @return       An internationalized string.
 1220  
      */
 1221  
     static Object uncheckedOverrides(MethodSymbol m, MethodSymbol other) {
 1222  
         String key;
 1223  0
         if ((other.owner.flags() & INTERFACE) == 0) 
 1224  0
             key = MsgSym.MESSAGE_UNCHECKED_OVERRIDE;
 1225  0
         else if ((m.owner.flags() & INTERFACE) == 0) 
 1226  0
             key = MsgSym.MESSAGE_UNCHECKED_IMPLEMENT;
 1227  
         else 
 1228  0
             key = MsgSym.MESSAGE_UNCHECKED_CLASH_WITH;
 1229  0
         return JCDiagnostic.fragment(key, m, m.location(), other, other.location());
 1230  
     }
 1231  
 
 1232  
     /** A customized "override" warning message.
 1233  
      *  @param m      The overriding method.
 1234  
      *  @param other  The overridden method.
 1235  
      *  @return       An internationalized string.
 1236  
      */
 1237  
     static Object varargsOverrides(MethodSymbol m, MethodSymbol other) {
 1238  
         String key;
 1239  0
         if ((other.owner.flags() & INTERFACE) == 0) 
 1240  0
             key = MsgSym.MESSAGE_VARARGS_OVERRIDE;
 1241  0
         else  if ((m.owner.flags() & INTERFACE) == 0) 
 1242  0
             key = MsgSym.MESSAGE_VARARGS_IMPLEMENT;
 1243  
         else
 1244  0
             key = MsgSym.MESSAGE_VARARGS_CLASH_WITH;
 1245  0
         return JCDiagnostic.fragment(key, m, m.location(), other, other.location());
 1246  
     }
 1247  
 
 1248  
     /** Check that this method conforms with overridden method 'other'.
 1249  
      *  where `origin' is the class where checking started.
 1250  
      *  Complications:
 1251  
      *  (1) Do not check overriding of synthetic methods
 1252  
      *      (reason: they might be final).
 1253  
      *      todo: check whether this is still necessary.
 1254  
      *  (2) Admit the case where an interface proxy throws fewer exceptions
 1255  
      *      than the method it implements. Augment the proxy methods with the
 1256  
      *      undeclared exceptions in this case.
 1257  
      *  (3) When generics are enabled, admit the case where an interface proxy
 1258  
      *            has a result type
 1259  
      *      extended by the result type of the method it implements.
 1260  
      *      Change the proxies result type to the smaller type in this case.
 1261  
      *
 1262  
      *  @param tree         The tree from which positions
 1263  
      *                            are extracted for errors.
 1264  
      *  @param m            The overriding method.
 1265  
      *  @param other        The overridden method.
 1266  
      *  @param origin       The class of which the overriding method
 1267  
      *                            is a member.
 1268  
      */
 1269  
 public
 1270  
     void checkOverride(JCTree tree,
 1271  
                        MethodSymbol m,
 1272  
                        MethodSymbol other,
 1273  
                        ClassSymbol origin) {
 1274  
         // Don't check overriding of synthetic methods or by bridge methods.
 1275  215
         if ((m.flags() & (SYNTHETIC|BRIDGE)) != 0 || (other.flags() & SYNTHETIC) != 0) {
 1276  35
             return;
 1277  
         }
 1278  
 
 1279  
         // Error if static method overrides instance method (JLS 8.4.6.2).
 1280  180
         if ((m.flags() & STATIC) != 0 &&
 1281  
                    (other.flags() & STATIC) == 0) {
 1282  0
             log.error(JavafxTreeInfo.diagnosticPositionFor(m, tree), MsgSym.MESSAGE_OVERRIDE_STATIC,
 1283  
                       cannotOverride(m, other));
 1284  0
             return;
 1285  
         }
 1286  
 
 1287  
         // Error if instance method overrides static or final
 1288  
         // method (JLS 8.4.6.1).
 1289  180
         if ((other.flags() & FINAL) != 0 ||
 1290  
                  (m.flags() & STATIC) == 0 &&
 1291  
                  (other.flags() & STATIC) != 0) {
 1292  0
             log.error(JavafxTreeInfo.diagnosticPositionFor(m, tree), MsgSym.MESSAGE_OVERRIDE_METH,
 1293  
                       cannotOverride(m, other),
 1294  
                       JavafxTreeInfo.flagNames(other.flags() & (FINAL | STATIC)));
 1295  0
             return;
 1296  
         }
 1297  
 
 1298  
         // Error if bound function overrides non-bound.
 1299  180
         if ((other.flags() & JavafxFlags.BOUND) == 0 && (m.flags() & JavafxFlags.BOUND) != 0) {
 1300  0
             log.error(JavafxTreeInfo.diagnosticPositionFor(m, tree), MsgSym.MESSAGE_JAVAFX_BOUND_OVERRIDE_METH,
 1301  
                     cannotOverride(m, other));
 1302  0
             return;
 1303  
         }
 1304  
 
 1305  
         // Error if non-bound function overrides bound.
 1306  180
         if ((other.flags() & JavafxFlags.BOUND) != 0 && (m.flags() & JavafxFlags.BOUND) == 0) {
 1307  0
             log.error(JavafxTreeInfo.diagnosticPositionFor(m, tree), MsgSym.MESSAGE_JAVAFX_NON_BOUND_OVERRIDE_METH,
 1308  
                     cannotOverride(m, other));
 1309  0
             return;
 1310  
         }
 1311  
 
 1312  180
         if ((m.owner.flags() & ANNOTATION) != 0) {
 1313  
                 // handled in validateAnnotationMethod
 1314  0
             return;
 1315  
         }
 1316  
 
 1317  
         // Error if overriding method has weaker access (JLS 8.4.6.3).
 1318  
 /*---------------  Taken out. Javafx doesn't have the JLS 8.4.6.3 rule...
 1319  
         if ((origin.flags() & INTERFACE) == 0 &&
 1320  
                  protection(m.flags()) > protection(other.flags())) {
 1321  
             log.error(JavafxTreeInfo.diagnosticPositionFor(m, tree), "override.weaker.access",
 1322  
                       cannotOverride(m, other),
 1323  
                       protectionString(other.flags()));
 1324  
             return;
 1325  
 
 1326  
         }
 1327  
 ----------------- */
 1328  180
         Type mt = types.memberType(origin.type, m);
 1329  180
         Type ot = types.memberType(origin.type, other);
 1330  
         // Error if overriding result type is different
 1331  
         // (or, in the case of generics mode, not a subtype) of
 1332  
         // overridden result type. We have to rename any type parameters
 1333  
         // before comparing types.
 1334  180
         List<Type> mtvars = mt.getTypeArguments();
 1335  180
         List<Type> otvars = ot.getTypeArguments();
 1336  180
         Type mtres = mt.getReturnType();
 1337  180
         Type otres = types.subst(ot.getReturnType(), otvars, mtvars);
 1338  
 
 1339  180
         overrideWarner.warned = false;
 1340  180
         boolean resultTypesOK =
 1341  
             types.returnTypeSubstitutable(mt, ot, otres, overrideWarner);
 1342  180
         if (!resultTypesOK) {
 1343  0
             if (!source.allowCovariantReturns() &&
 1344  
                 m.owner != origin &&
 1345  
                 m.owner.isSubClass(other.owner, types)) {
 1346  
                 // allow limited interoperability with covariant returns
 1347  
             } else {
 1348  0
                 typeError(JavafxTreeInfo.diagnosticPositionFor(m, tree),
 1349  
                           JCDiagnostic.fragment(MsgSym.MESSAGE_OVERRIDE_INCOMPATIBLE_RET,
 1350  
                                          cannotOverride(m, other)),
 1351  
                           mtres, otres);
 1352  0
                 return;
 1353  
             }
 1354  180
         } else if (overrideWarner.warned) {
 1355  0
             warnUnchecked(JavafxTreeInfo.diagnosticPositionFor(m, tree),
 1356  
                           MsgSym.MESSAGE_PROB_FOUND_REQ,
 1357  
                           JCDiagnostic.fragment(MsgSym.MESSAGE_OVERRIDE_UNCHECKED_RET,
 1358  
                                               uncheckedOverrides(m, other)),
 1359  
                           mtres, otres);
 1360  
         }
 1361  
         
 1362  
         // Error if overriding method throws an exception not reported
 1363  
         // by overridden method.
 1364  180
         List<Type> otthrown = types.subst(ot.getThrownTypes(), otvars, mtvars);
 1365  180
         List<Type> unhandled = unHandled(mt.getThrownTypes(), otthrown);
 1366  180
         if (unhandled.nonEmpty()) {
 1367  0
             log.error(JavafxTreeInfo.diagnosticPositionFor(m, tree),
 1368  
                       MsgSym.MESSAGE_OVERRIDE_METH_DOES_NOT_THROW,
 1369  
                       cannotOverride(m, other),
 1370  
                       unhandled.head);
 1371  0
             return;
 1372  
         }
 1373  
 
 1374  
         // Optional warning if varargs don't agree 
 1375  180
         if ((((m.flags() ^ other.flags()) & Flags.VARARGS) != 0)
 1376  
             && lint.isEnabled(Lint.LintCategory.OVERRIDES)) {
 1377  0
             log.warning(JavafxTreeInfo.diagnosticPositionFor(m, tree),
 1378  
                         ((m.flags() & Flags.VARARGS) != 0)
 1379  
                         ? MsgSym.MESSAGE_OVERRIDE_VARARGS_MISSING
 1380  
                         : MsgSym.MESSAGE_OVERRIDE_VARARGS_EXTRA,
 1381  
                         varargsOverrides(m, other));
 1382  
         } 
 1383  
 
 1384  
         // Warn if instance method overrides bridge method (compiler spec ??)
 1385  180
         if ((other.flags() & BRIDGE) != 0) {
 1386  0
             log.warning(JavafxTreeInfo.diagnosticPositionFor(m, tree), MsgSym.MESSAGE_OVERRIDE_BRIDGE,
 1387  
                         uncheckedOverrides(m, other));
 1388  
         }
 1389  
 
 1390  
         // Warn if a deprecated method overridden by a non-deprecated one.
 1391  180
         if ((other.flags() & DEPRECATED) != 0 
 1392  
             && (m.flags() & DEPRECATED) == 0 
 1393  
             && m.outermostClass() != other.outermostClass()
 1394  
             && !isDeprecatedOverrideIgnorable(other, origin)) {
 1395  0
             warnDeprecated(JavafxTreeInfo.diagnosticPositionFor(m, tree), other);
 1396  
         }
 1397  180
     }
 1398  
     // where
 1399  
         private boolean isDeprecatedOverrideIgnorable(MethodSymbol m, ClassSymbol origin) {
 1400  
             // If the method, m, is defined in an interface, then ignore the issue if the method
 1401  
             // is only inherited via a supertype and also implemented in the supertype,
 1402  
             // because in that case, we will rediscover the issue when examining the method
 1403  
             // in the supertype.
 1404  
             // If the method, m, is not defined in an interface, then the only time we need to
 1405  
             // address the issue is when the method is the supertype implemementation: any other
 1406  
             // case, we will have dealt with when examining the supertype classes
 1407  0
             ClassSymbol mc = m.enclClass();
 1408  0
             Type st = types.supertype(origin.type);
 1409  0
             if (st.tag != CLASS)
 1410  0
                 return true;
 1411  0
             MethodSymbol stimpl = m.implementation((ClassSymbol)st.tsym, types, false);
 1412  
 
 1413  0
             if (mc != null && ((mc.flags() & INTERFACE) != 0)) {
 1414  0
                 List<Type> intfs = types.interfaces(origin.type);
 1415  0
                 return (intfs.contains(mc.type) ? false : (stimpl != null));
 1416  
             }
 1417  
             else
 1418  0
                 return (stimpl != m);
 1419  
         }
 1420  
 
 1421  
 
 1422  
     // used to check if there were any unchecked conversions
 1423  399
     Warner overrideWarner = new Warner();
 1424  
 
 1425  
     /** Check that a class does not inherit two concrete methods
 1426  
      *  with the same signature.
 1427  
      *  @param pos          Position to be used for error reporting.
 1428  
      *  @param site         The class type to be checked.
 1429  
      */
 1430  
     public void checkCompatibleConcretes(DiagnosticPosition pos, Type site) {
 1431  667
         Type sup = types.supertype(site);
 1432  667
         if (sup.tag != CLASS) return;
 1433  
 
 1434  667
         for (Type t1 = sup;
 1435  667
              t1.tsym.type.isParameterized();
 1436  0
              t1 = types.supertype(t1)) {
 1437  0
             for (Scope.Entry e1 = t1.tsym.members().elems;
 1438  0
                  e1 != null;
 1439  0
                  e1 = e1.sibling) {
 1440  0
                 Symbol s1 = e1.sym;
 1441  0
                 if (s1.kind != MTH ||
 1442  
                     (s1.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||
 1443  
                     !s1.isInheritedIn(site.tsym, types) ||
 1444  
                     ((MethodSymbol)s1).implementation(site.tsym,
 1445  
                                                       types,
 1446  
                                                       true) != s1)
 1447  0
                     continue;
 1448  0
                 Type st1 = types.memberType(t1, s1);
 1449  0
                 int s1ArgsLength = st1.getParameterTypes().length();
 1450  0
                 if (st1 == s1.type) continue;
 1451  
 
 1452  0
                 for (Type t2 = sup;
 1453  0
                      t2.tag == CLASS;
 1454  0
                      t2 = types.supertype(t2)) {
 1455  0
                     for (Scope.Entry e2 = t1.tsym.members().lookup(s1.name);
 1456  0
                          e2.scope != null;
 1457  0
                          e2 = e2.next()) {
 1458  0
                         Symbol s2 = e2.sym;
 1459  0
                         if (s2 == s1 ||
 1460  
                             s2.kind != MTH ||
 1461  
                             (s2.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||
 1462  
                             s2.type.getParameterTypes().length() != s1ArgsLength ||
 1463  
                             !s2.isInheritedIn(site.tsym, types) ||
 1464  
                             ((MethodSymbol)s2).implementation(site.tsym,
 1465  
                                                               types,
 1466  
                                                               true) != s2)
 1467  0
                             continue;
 1468  0
                         Type st2 = types.memberType(t2, s2);
 1469  0
                         if (types.overrideEquivalent(st1, st2))
 1470  0
                             log.error(pos, MsgSym.MESSAGE_CONCRETE_INHERITANCE_CONFLICT,
 1471  
                                       s1, t1, s2, t2, sup);
 1472  
                     }
 1473  
                 }
 1474  
             }
 1475  
         }
 1476  667
     }
 1477  
 
 1478  
     /** Check that classes (or interfaces) do not each define an abstract
 1479  
      *  method with same name and arguments but incompatible return types.
 1480  
      *  @param pos          Position to be used for error reporting.
 1481  
      *  @param t1           The first argument type.
 1482  
      *  @param t2           The second argument type.
 1483  
      */
 1484  
     public boolean checkCompatibleAbstracts(DiagnosticPosition pos,
 1485  
                                             Type t1,
 1486  
                                             Type t2) {
 1487  0
         return checkCompatibleAbstracts(pos, t1, t2,
 1488  
                                         types.makeCompoundType(t1, t2));
 1489  
     }
 1490  
 
 1491  
     public boolean checkCompatibleAbstracts(DiagnosticPosition pos,
 1492  
                                             Type t1,
 1493  
                                             Type t2,
 1494  
                                             Type site) {
 1495  11
         Symbol sym = firstIncompatibility(t1, t2, site);
 1496  11
         if (sym != null) {
 1497  0
             log.error(pos, MsgSym.MESSAGE_TYPES_INCOMPATIBLE_DIFF_RET,
 1498  
                       t1, t2, sym.name +
 1499  
                       "(" + types.memberType(t2, sym).getParameterTypes() + ")");
 1500  0
             return false;
 1501  
         }
 1502  11
         return true;
 1503  
     }
 1504  
 
 1505  
     /** Return the first method which is defined with same args
 1506  
      *  but different return types in two given interfaces, or null if none
 1507  
      *  exists.
 1508  
      *  @param t1     The first type.
 1509  
      *  @param t2     The second type.
 1510  
      *  @param site   The most derived type.
 1511  
      *  @returns symbol from t2 that conflicts with one in t1.
 1512  
      */
 1513  
     private Symbol firstIncompatibility(Type t1, Type t2, Type site) {
 1514  11
         Map<TypeSymbol,Type> interfaces1 = new HashMap<TypeSymbol,Type>();
 1515  11
         closure(t1, interfaces1);
 1516  
         Map<TypeSymbol,Type> interfaces2;
 1517  11
         if (t1 == t2)
 1518  0
             interfaces2 = interfaces1;
 1519  
         else
 1520  11
             closure(t2, interfaces1, interfaces2 = new HashMap<TypeSymbol,Type>());
 1521  
 
 1522  11
         for (Type t3 : interfaces1.values()) {
 1523  25
             for (Type t4 : interfaces2.values()) {
 1524  29
                 Symbol s = firstDirectIncompatibility(t3, t4, site);
 1525  29
                 if (s != null) return s;
 1526  29
             }
 1527  
         }
 1528  11
         return null;
 1529  
     }
 1530  
 
 1531  
     /** Compute all the supertypes of t, indexed by type symbol. */
 1532  
     private void closure(Type t, Map<TypeSymbol,Type> typeMap) {
 1533  39
         if (t.tag != CLASS) return;
 1534  28
         if (typeMap.put(t.tsym, t) == null) {
 1535  25
             closure(types.supertype(t), typeMap);
 1536  25
             for (Type i : types.interfaces(t))
 1537  3
                 closure(i, typeMap);
 1538  
         }
 1539  28
     }
 1540  
 
 1541  
     /** Compute all the supertypes of t, indexed by type symbol (except thise in typesSkip). */
 1542  
     private void closure(Type t, Map<TypeSymbol,Type> typesSkip, Map<TypeSymbol,Type> typeMap) {
 1543  28
         if (t.tag != CLASS) return;
 1544  28
         if (typesSkip.get(t.tsym) != null) return;
 1545  13
         if (typeMap.put(t.tsym, t) == null) {
 1546  13
             closure(types.supertype(t), typesSkip, typeMap);
 1547  13
             for (Type i : types.interfaces(t))
 1548  4
                 closure(i, typesSkip, typeMap);
 1549  
         }
 1550  13
     }
 1551  
 
 1552  
     /** Return the first method in t2 that conflicts with a method from t1. */
 1553  
     private Symbol firstDirectIncompatibility(Type t1, Type t2, Type site) {
 1554  265
         for (Scope.Entry e1 = t1.tsym.members().elems; e1 != null; e1 = e1.sibling) {
 1555  236
             Symbol s1 = e1.sym;
 1556  236
             Type st1 = null;
 1557  236
             if (s1.kind != MTH || s1.name == defs.runMethodName ||
 1558  19
                     !s1.isInheritedIn(site.tsym, types)) continue;
 1559  204
             Symbol impl = types.implementation((MethodSymbol)s1, site.tsym, false);
 1560  204
             if (impl != null && (impl.flags() & ABSTRACT) == 0) continue;
 1561  188
             for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name); e2.scope != null; e2 = e2.next()) {
 1562  24
                 Symbol s2 = e2.sym;
 1563  24
                 if (s1 == s2) continue;
 1564  24
                 if (s2.kind != MTH || !s2.isInheritedIn(site.tsym, types)) continue;
 1565  24
                 if (st1 == null) st1 = types.memberType(t1, s1);
 1566  24
                 Type st2 = types.memberType(t2, s2);
 1567  24
                 if (types.overrideEquivalent(st1, st2)) {
 1568  12
                     List<Type> tvars1 = st1.getTypeArguments();
 1569  12
                     List<Type> tvars2 = st2.getTypeArguments();
 1570  12
                     Type rt1 = st1.getReturnType();
 1571  12
                     Type rt2 = types.subst(st2.getReturnType(), tvars2, tvars1);
 1572  12
                     boolean compat =
 1573  
                         types.isSameType(rt1, rt2) ||
 1574  
                         rt1.tag >= CLASS && rt2.tag >= CLASS &&
 1575  
                         (types.covariantReturnType(rt1, rt2, Warner.noWarnings) ||
 1576  
                          types.covariantReturnType(rt2, rt1, Warner.noWarnings));
 1577  12
                     if (!compat) return s2;
 1578  
                 }
 1579  
             }
 1580  
         }
 1581  29
         return null;
 1582  
     }
 1583  
 
 1584  
     /** Check that a given method conforms with any method it overrides.
 1585  
      *  @param tree         The tree from which positions are extracted
 1586  
      *                            for errors.
 1587  
      *  @param m            The overriding method.
 1588  
      */
 1589  
 // JavaFX change
 1590  
     public
 1591  
 // JavaFX change
 1592  
     void checkOverride(JCTree tree, MethodSymbol m) {
 1593  1237
         ClassSymbol origin = (ClassSymbol)m.owner;
 1594  1237
         if ((origin.flags() & ENUM) != 0 && names.finalize.equals(m.name))
 1595  0
             if (m.overrides(syms.enumFinalFinalize, origin, types, false)) {
 1596  0
                 log.error(tree.pos(), MsgSym.MESSAGE_ENUM_NO_FINALIZE);
 1597  0
                 return;
 1598  
             }
 1599  1237
             ListBuffer<Type> supertypes = ListBuffer.<Type>lb();
 1600  1237
             Set<Type> superSet = new HashSet<Type>();
 1601  1237
             types.getSupertypes(origin, supertypes, superSet);
 1602  
 
 1603  1237
         for (Type t : supertypes) {
 1604  1673
             if (t.tag == CLASS) {
 1605  1673
                 TypeSymbol c = t.tsym;
 1606  1673
                 Scope.Entry e = c.members().lookup(m.name);
 1607  1799
                 while (e.scope != null) {
 1608  126
                     e.sym.complete();
 1609  126
                     if (m.overrides(e.sym, origin, types, false))
 1610  121
                         checkOverride(tree, m, (MethodSymbol)e.sym, origin);
 1611  126
                     e = e.next();
 1612  
                 }
 1613  1673
             }
 1614  
         }
 1615  1237
     }
 1616  
 
 1617  
     /** Check that all abstract members of given class have definitions.
 1618  
      *  @param pos          Position to be used for error reporting.
 1619  
      *  @param c            The class.
 1620  
      */
 1621  
 // JavaFX change
 1622  
     public
 1623  
 // JavaFX change
 1624  
     void checkAllDefined(DiagnosticPosition pos, ClassSymbol c) {
 1625  
         try {
 1626  650
             MethodSymbol undef = firstUndef(c, c);
 1627  650
             if (undef != null) {
 1628  0
                 if ((c.flags() & ENUM) != 0 &&
 1629  
                     types.supertype(c.type).tsym == syms.enumSym &&
 1630  
                     (c.flags() & FINAL) == 0) {
 1631  
                     // add the ABSTRACT flag to an enum
 1632  0
                     c.flags_field |= ABSTRACT;
 1633  
                 } else {
 1634  0
                     MethodSymbol undef1 =
 1635  
                         new MethodSymbol(undef.flags(), undef.name,
 1636  
                                          types.memberType(c.type, undef), undef.owner);
 1637  0
                     log.error(pos, MsgSym.MESSAGE_DOES_NOT_OVERRIDE_ABSTRACT,
 1638  
                               c, undef1, undef1.location());
 1639  
                 }
 1640  
             }
 1641  0
         } catch (CompletionFailure ex) {
 1642  0
             completionError(pos, ex);
 1643  650
         }
 1644  650
     }
 1645  
 //where
 1646  
         /** Return first abstract member of class `c' that is not defined
 1647  
          *  in `impl', null if there is none.
 1648  
          */
 1649  
         private MethodSymbol firstUndef(ClassSymbol impl, ClassSymbol c) {
 1650  1489
             MethodSymbol undef = null;
 1651  
             // Do not bother to search in classes that are not abstract,
 1652  
             // since they cannot have abstract members.
 1653  1489
             if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) {
 1654  712
                 Scope s = c.members();
 1655  712
                 for (Scope.Entry e = s.elems;
 1656  3675
                      undef == null && e != null;
 1657  2963
                      e = e.sibling) {
 1658  2963
                     if (e.sym.kind == MTH &&
 1659  
                         (e.sym.flags() & (ABSTRACT|IPROXY)) == ABSTRACT) {
 1660  61
                         MethodSymbol absmeth = (MethodSymbol)e.sym;
 1661  61
                         MethodSymbol implmeth = types.implementation(absmeth, impl, true);
 1662  61
                         if (implmeth == null || implmeth == absmeth) {
 1663  0
                             undef = absmeth;
 1664  
                         }
 1665  
                     }
 1666  
                 }
 1667  712
                 if (undef == null) {
 1668  712
                     Type st = types.supertype(c.type);
 1669  712
                     if (st.tag == CLASS)
 1670  712
                         undef = firstUndef(impl, (ClassSymbol)st.tsym);
 1671  
                 }
 1672  712
                 for (List<Type> l = types.interfaces(c.type);
 1673  839
                      undef == null && l.nonEmpty();
 1674  127
                      l = l.tail) {
 1675  127
                     undef = firstUndef(impl, (ClassSymbol)l.head.tsym);
 1676  
                 }
 1677  
             }
 1678  1489
             return undef;
 1679  
         }
 1680  
 
 1681  
     /** Check for cyclic references. Issue an error if the
 1682  
      *  symbol of the type referred to has a LOCKED flag set.
 1683  
      *
 1684  
      *  @param pos      Position to be used for error reporting.
 1685  
      *  @param t        The type referred to.
 1686  
      */
 1687  
 // JavaFX change
 1688  
     public
 1689  
 // JavaFX change
 1690  
     void checkNonCyclic(DiagnosticPosition pos, Type t) {
 1691  2701
         checkNonCyclicInternal(pos, t);
 1692  2701
     }
 1693  
 
 1694  
 
 1695  
     void checkNonCyclic(DiagnosticPosition pos, TypeVar t) {
 1696  0
         checkNonCyclic1(pos, t, new HashSet<TypeVar>());
 1697  0
     }
 1698  
 
 1699  
     private void checkNonCyclic1(DiagnosticPosition pos, Type t, Set<TypeVar> seen) {
 1700  
         final TypeVar tv;
 1701  0
         if (seen.contains(t)) {
 1702  0
             tv = (TypeVar)t;
 1703  0
             tv.bound = new ErrorType();
 1704  0
             log.error(pos, MsgSym.MESSAGE_CYCLIC_INHERITANCE, t);
 1705  0
         } else if (t.tag == TYPEVAR) {
 1706  0
             tv = (TypeVar)t;
 1707  0
             seen.add(tv);
 1708  0
             for (Type b : types.getBounds(tv))
 1709  0
                 checkNonCyclic1(pos, b, seen);
 1710  
         }
 1711  0
     }
 1712  
 
 1713  
     /** Check for cyclic references. Issue an error if the
 1714  
      *  symbol of the type referred to has a LOCKED flag set.
 1715  
      *
 1716  
      *  @param pos      Position to be used for error reporting.
 1717  
      *  @param t        The type referred to.
 1718  
      *  @returns        True if the check completed on all attributed classes
 1719  
      */
 1720  
     private boolean checkNonCyclicInternal(DiagnosticPosition pos, Type t) {
 1721  6246
         boolean complete = true; // was the check complete?
 1722  
         //- System.err.println("checkNonCyclicInternal("+t+");");//DEBUG
 1723  6246
         Symbol c = t.tsym;
 1724  6246
         if ((c.flags_field & ACYCLIC) != 0) return true;
 1725  
 
 1726  2722
         if ((c.flags_field & LOCKED) != 0) {
 1727  2
             noteCyclic(pos, (ClassSymbol)c);
 1728  2720
         } else if (!c.type.isErroneous()) {
 1729  
             try {
 1730  2720
                 c.flags_field |= LOCKED;
 1731  2720
                 if (c.type.tag == CLASS) {
 1732  2720
                     ClassType clazz = (ClassType)c.type;
 1733  2720
                     if (clazz.interfaces_field != null)
 1734  3145
                         for (List<Type> l=clazz.interfaces_field; l.nonEmpty(); l=l.tail)
 1735  426
                             complete &= checkNonCyclicInternal(pos, l.head);
 1736  2720
                     if (clazz.supertype_field != null) {
 1737  2719
                         Type st = clazz.supertype_field;
 1738  2719
                         if (st != null && st.tag == CLASS)
 1739  2343
                             complete &= checkNonCyclicInternal(pos, st);
 1740  
                     }
 1741  2720
                     if (c.owner.kind == TYP)
 1742  776
                         complete &= checkNonCyclicInternal(pos, c.owner.type);
 1743  
                 }
 1744  
             } finally {
 1745  2720
                 c.flags_field &= ~LOCKED;
 1746  2720
             }
 1747  
         }
 1748  2722
         if (complete)
 1749  2256
             complete = ((c.flags_field & UNATTRIBUTED) == 0) && c.completer == null;
 1750  2722
         if (complete) c.flags_field |= ACYCLIC;
 1751  2722
         return complete;
 1752  
     }
 1753  
 
 1754  
     /** Note that we found an inheritance cycle. */
 1755  
     private void noteCyclic(DiagnosticPosition pos, ClassSymbol c) {
 1756  2
         log.error(pos, MsgSym.MESSAGE_CYCLIC_INHERITANCE, c);
 1757  3
         for (List<Type> l=types.interfaces(c.type); l.nonEmpty(); l=l.tail)
 1758  1
             l.head = new ErrorType((ClassSymbol)l.head.tsym);
 1759  2
         Type st = types.supertype(c.type);
 1760  2
         if (st.tag == CLASS)
 1761  2
             ((ClassType)c.type).supertype_field = new ErrorType((ClassSymbol)st.tsym);
 1762  2
         c.type = new ErrorType(c);
 1763  2
         c.flags_field |= ACYCLIC;
 1764  2
     }
 1765  
 
 1766  
     /** Check that all methods which implement some
 1767  
      *  method conform to the method they implement.
 1768  
      *  @param tree         The class definition whose members are checked.
 1769  
      */
 1770  
 // JavaFX change
 1771  
     public
 1772  
 // JavaFX change
 1773  
     void checkImplementations(JFXClassDeclaration tree) {
 1774  667
         checkImplementations(tree, tree.sym);
 1775  667
     }
 1776  
 //where
 1777  
         /** Check that all methods which implement some
 1778  
          *  method in `ic' conform to the method they implement.
 1779  
          */
 1780  
         void checkImplementations(JFXClassDeclaration tree, ClassSymbol ic) {
 1781  667
             ClassSymbol origin = tree.sym;
 1782  2271
             for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) {
 1783  1604
                 ClassSymbol lc = (ClassSymbol)l.head.tsym;
 1784  1604
                 if ((allowGenerics || origin != lc) && (lc.flags() & ABSTRACT) != 0) {
 1785  5409
                     for (Scope.Entry e=lc.members().elems; e != null; e=e.sibling) {
 1786  5257
                         if (e.sym.kind == MTH &&
 1787  
                             (e.sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) {
 1788  119
                             MethodSymbol absmeth = (MethodSymbol)e.sym;
 1789  119
                             MethodSymbol implmeth = absmeth.implementation(origin, types, false);
 1790  119
                             if (implmeth != null && implmeth != absmeth &&
 1791  
                                 (implmeth.owner.flags() & INTERFACE) ==
 1792  
                                 (origin.flags() & INTERFACE)) {
 1793  
                                 // don't check if implmeth is in a class, yet
 1794  
                                 // origin is an interface. This case arises only
 1795  
                                 // if implmeth is declared in Object. The reason is
 1796  
                                 // that interfaces really don't inherit from
 1797  
                                 // Object it's just that the compiler represents
 1798  
                                 // things that way.
 1799  94
                                 checkOverride(tree, implmeth, absmeth, origin);
 1800  
                             }
 1801  
                         }
 1802  
                     }
 1803  
                 }
 1804  
             }
 1805  667
         }
 1806  
 
 1807  
     /** Check that all abstract methods implemented by a class are
 1808  
      *  mutually compatible.
 1809  
      *  @param pos          Position to be used for error reporting.
 1810  
      *  @param c            The class whose interfaces are checked.
 1811  
      */
 1812  
 // JavaFX change
 1813  
     public
 1814  
 // JavaFX change
 1815  
     void checkCompatibleSupertypes(DiagnosticPosition pos, Type c) {
 1816  667
         List<Type> supertypes = types.interfaces(c);
 1817  667
         Type supertype = types.supertype(c);
 1818  667
         if (supertype.tag == CLASS &&
 1819  
             (supertype.tsym.flags() & ABSTRACT) != 0)
 1820  3
             supertypes = supertypes.prepend(supertype);
 1821  775
         for (List<Type> l = supertypes; l.nonEmpty(); l = l.tail) {
 1822  108
             if (allowGenerics && !l.head.getTypeArguments().isEmpty() &&
 1823  
                 !checkCompatibleAbstracts(pos, l.head, l.head, c))
 1824  0
                 return;
 1825  119
             for (List<Type> m = supertypes; m != l; m = m.tail)
 1826  11
                 if (!checkCompatibleAbstracts(pos, l.head, m.head, c))
 1827  0
                     return;
 1828  
         }
 1829  667
         checkCompatibleConcretes(pos, c);
 1830  667
     }
 1831  
 
 1832  
     /** Check that class c does not implement directly or indirectly
 1833  
      *  the same parameterized interface with two different argument lists.
 1834  
      *  @param pos          Position to be used for error reporting.
 1835  
      *  @param type         The type whose interfaces are checked.
 1836  
      */
 1837  
 // JavaFX change
 1838  
     public
 1839  
 // JavaFX change
 1840  
     void checkClassBounds(DiagnosticPosition pos, Type type) {
 1841  670
         checkClassBounds(pos, new HashMap<TypeSymbol,Type>(), type);
 1842  670
     }
 1843  
 //where
 1844  
         /** Enter all interfaces of type `type' into the hash table `seensofar'
 1845  
          *  with their class symbol as key and their type as value. Make
 1846  
          *  sure no class is entered with two different types.
 1847  
          */
 1848  
         void checkClassBounds(DiagnosticPosition pos,
 1849  
                               Map<TypeSymbol,Type> seensofar,
 1850  
                               Type type) {
 1851  2770
             if (type.isErroneous()) return;
 1852  3010
             for (List<Type> l = types.interfaces(type); l.nonEmpty(); l = l.tail) {
 1853  240
                 Type it = l.head;
 1854  240
                 Type oldit = seensofar.put(it.tsym, it);
 1855  240
                 if (oldit != null) {
 1856  10
                     List<Type> oldparams = oldit.allparams();
 1857  10
                     List<Type> newparams = it.allparams();
 1858  10
                     if (!types.containsTypeEquivalent(oldparams, newparams))
 1859  0
                         log.error(pos, MsgSym.MESSAGE_CANNOT_INHERIT_DIFF_ARG,
 1860  
                                   it.tsym, Type.toString(oldparams),
 1861  
                                   Type.toString(newparams));
 1862  
                 }
 1863  240
                 checkClassBounds(pos, seensofar, it);
 1864  
             }
 1865  2770
             Type st = types.supertype(type);
 1866  2770
             if (st != null) checkClassBounds(pos, seensofar, st);
 1867  2770
         }
 1868  
 
 1869  
     /** Enter interface into into set.
 1870  
      *  If it existed already, issue a "repeated interface" error.
 1871  
      */
 1872  
 // JavaFX change
 1873  
     public
 1874  
 // JavaFX change
 1875  
     void checkNotRepeated(DiagnosticPosition pos, Type it, Set<Type> its) {
 1876  129
         if (its.contains(it))
 1877  0
             log.error(pos, MsgSym.MESSAGE_REPEATED_INTERFACE);
 1878  
         else {
 1879  129
             its.add(it);
 1880  
         }
 1881  129
     }
 1882  
         
 1883  
 /* *************************************************************************
 1884  
  * Check annotations
 1885  
  **************************************************************************/
 1886  
 
 1887  
     /** Annotation types are restricted to primitives, String, an
 1888  
      *  enum, an annotation, Class, Class<?>, Class<? extends
 1889  
      *  Anything>, arrays of the preceding.
 1890  
      */
 1891  
 // Javafx modification
 1892  
 public
 1893  
 // Javafx modification
 1894  
     void validateAnnotationType(JCTree restype) {
 1895  
         // restype may be null if an error occurred, so don't bother validating it
 1896  0
         if (restype != null) {
 1897  0
             validateAnnotationType(restype.pos(), restype.type);
 1898  
         }
 1899  0
     }
 1900  
 
 1901  
     void validateAnnotationType(DiagnosticPosition pos, Type type) {
 1902  0
         if (type.isPrimitive()) return;
 1903  0
         if (types.isSameType(type, syms.stringType)) return;
 1904  0
         if ((type.tsym.flags() & Flags.ENUM) != 0) return;
 1905  0
         if ((type.tsym.flags() & Flags.ANNOTATION) != 0) return;
 1906  0
         if (types.lowerBound(type).tsym == syms.classType.tsym) return;
 1907  0
         if (types.isArray(type) && !types.isArray(types.elemtype(type))) {
 1908  0
             validateAnnotationType(pos, types.elemtype(type));
 1909  0
             return;
 1910  
         }
 1911  0
         log.error(pos, MsgSym.MESSAGE_INVALID_ANNOTATION_MEMBER_TYPE);
 1912  0
     }
 1913  
 
 1914  
     /**
 1915  
      * "It is also a compile-time error if any method declared in an
 1916  
      * annotation type has a signature that is override-equivalent to
 1917  
      * that of any public or protected method declared in class Object
 1918  
      * or in the interface annotation.Annotation."
 1919  
      *
 1920  
      * @jls3 9.6 Annotation Types
 1921  
      */
 1922  
 // Javafx modification
 1923  
 public
 1924  
 // Javafx modification
 1925  
     void validateAnnotationMethod(DiagnosticPosition pos, MethodSymbol m) {
 1926  0
         for (Type sup = syms.annotationType; sup.tag == CLASS; sup = types.supertype(sup)) {
 1927  0
             Scope s = sup.tsym.members();
 1928  0
             for (Scope.Entry e = s.lookup(m.name); e.scope != null; e = e.next()) {
 1929  0
                 if (e.sym.kind == MTH &&
 1930  
                     (e.sym.flags() & (PUBLIC | PROTECTED)) != 0 &&
 1931  
                     types.overrideEquivalent(m.type, e.sym.type))
 1932  0
                     log.error(pos, MsgSym.MESSAGE_INTF_ANNOTATION_MEMBER_CLASH, e.sym, sup);
 1933  
             }
 1934  
         }
 1935  0
     }
 1936  
 
 1937  
     /** Check the annotations of a symbol.
 1938  
      */
 1939  
     public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) {
 1940  3943
         if (skipAnnotations) return;
 1941  3943
         for (JCAnnotation a : annotations)
 1942  0
             validateAnnotation(a, s);
 1943  3943
     }
 1944  
 
 1945  
     /** Check an annotation of a symbol.
 1946  
      */
 1947  
     public void validateAnnotation(JCAnnotation a, Symbol s) {
 1948  0
         validateAnnotation(a);
 1949  
 
 1950  0
         if (!annotationApplicable(a, s))
 1951  0
             log.error(a.pos(), MsgSym.MESSAGE_ANNOTATION_TYPE_NOT_APPLICABLE);
 1952  
 
 1953  0
         if (a.annotationType.type.tsym == syms.overrideType.tsym) {
 1954  0
             if (!isOverrider(s))
 1955  0
                 log.error(a.pos(), MsgSym.MESSAGE_METHOD_DOES_NOT_OVERRIDE_SUPERCLASS);
 1956  
         }
 1957  0
     }
 1958  
 
 1959  
     /** Is s a method symbol that overrides a method in a superclass? */
 1960  
     boolean isOverrider(Symbol s) {
 1961  0
         if (s.kind != MTH || s.isStatic())
 1962  0
             return false;
 1963  0
         MethodSymbol m = (MethodSymbol)s;
 1964  0
         TypeSymbol owner = (TypeSymbol)m.owner;
 1965  0
         for (Type sup : types.closure(owner.type)) {
 1966  0
             if (sup == owner.type)
 1967  0
                 continue; // skip "this"
 1968  0
             Scope scope = sup.tsym.members();
 1969  0
             for (Scope.Entry e = scope.lookup(m.name); e.scope != null; e = e.next()) {
 1970  0
                 if (!e.sym.isStatic() && m.overrides(e.sym, owner, types, true))
 1971  0
                     return true;
 1972  
             }
 1973  0
         }
 1974  0
         return false;
 1975  
     }
 1976  
 
 1977  
     /** Is the annotation applicable to the symbol? */
 1978  
     boolean annotationApplicable(JCAnnotation a, Symbol s) {
 1979  0
         Attribute.Compound atTarget =
 1980  
             a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym);
 1981  0
         if (atTarget == null) return true;
 1982  0
         Attribute atValue = atTarget.member(names.value);
 1983  0
         if (!(atValue instanceof Attribute.Array)) return true; // error recovery
 1984  0
         Attribute.Array arr = (Attribute.Array) atValue;
 1985  0
         for (Attribute app : arr.values) {
 1986  0
             if (!(app instanceof Attribute.Enum)) return true; // recovery
 1987  0
             Attribute.Enum e = (Attribute.Enum) app;
 1988  0
             if (e.value.name == names.TYPE)
 1989  0
                 { if (s.kind == TYP) return true; }
 1990  0
             else if (e.value.name == names.FIELD)
 1991  0
                 { if (s.kind == VAR && s.owner.kind != MTH) return true; }
 1992  0
             else if (e.value.name == names.METHOD)
 1993  0
                 { if (s.kind == MTH && !s.isConstructor()) return true; }
 1994  0
             else if (e.value.name == names.PARAMETER)
 1995  0
                 { if (s.kind == VAR &&
 1996  
                       s.owner.kind == MTH &&
 1997  
                       (s.flags() & PARAMETER) != 0)
 1998  0
                     return true;
 1999  
                 }
 2000  0
             else if (e.value.name == names.CONSTRUCTOR)
 2001  0
                 { if (s.kind == MTH && s.isConstructor()) return true; }
 2002  0
             else if (e.value.name == names.LOCAL_VARIABLE)
 2003  0
                 { if (s.kind == VAR && s.owner.kind == MTH &&
 2004  
                       (s.flags() & PARAMETER) == 0)
 2005  0
                     return true;
 2006  
                 }
 2007  0
             else if (e.value.name == names.ANNOTATION_TYPE)
 2008  0
                 { if (s.kind == TYP && (s.flags() & ANNOTATION) != 0)
 2009  0
                     return true;
 2010  
                 }
 2011  0
             else if (e.value.name == names.PACKAGE)
 2012  0
                 { if (s.kind == PCK) return true; }
 2013  
             else
 2014  0
                 return true; // recovery
 2015  
         }
 2016  0
         return false;
 2017  
     }
 2018  
 
 2019  
     /** Check an annotation value.
 2020  
      */
 2021  
     public void validateAnnotation(JCAnnotation a) {
 2022  0
         if (a.type.isErroneous()) return;
 2023  
 
 2024  
         // collect an inventory of the members
 2025  0
         Set<MethodSymbol> members = new HashSet<MethodSymbol>();
 2026  0
         for (Scope.Entry e = a.annotationType.type.tsym.members().elems;
 2027  0
              e != null;
 2028  0
              e = e.sibling)
 2029  0
             if (e.sym.kind == MTH)
 2030  0
                 members.add((MethodSymbol) e.sym);
 2031  
 
 2032  
         // count them off as they're annotated
 2033  0
         for (JCTree arg : a.args) {
 2034  0
             if (arg.getTag() != JCTree.ASSIGN) continue; // recovery
 2035  0
             JCAssign assign = (JCAssign) arg;
 2036  0
             Symbol m = JavafxTreeInfo.symbol(assign.lhs);
 2037  0
             if (m == null || m.type.isErroneous()) continue;
 2038  0
             if (!members.remove(m))
 2039  0
                 log.error(arg.pos(), MsgSym.MESSAGE_DUPLICATE_ANNOTATION_MEMBER_VALUE,
 2040  
                           m.name, a.type);
 2041  0
             if (assign.rhs.getTag() == ANNOTATION)
 2042  0
                 validateAnnotation((JCAnnotation)assign.rhs);
 2043  0
         }
 2044  
 
 2045  
         // all the remaining ones better have default values
 2046  0
         for (MethodSymbol m : members)
 2047  0
             if (m.defaultValue == null && !m.type.isErroneous())
 2048  0
                 log.error(a.pos(), MsgSym.MESSAGE_ANNOTATION_MISSING_DEFAULT_VALUE, 
 2049  
                           a.type, m.name);
 2050  
 
 2051  
         // special case: java.lang.annotation.Target must not have
 2052  
         // repeated values in its value member
 2053  0
         if (a.annotationType.type.tsym != syms.annotationTargetType.tsym ||
 2054  
             a.args.tail == null)
 2055  0
             return;
 2056  
 
 2057  0
         if (a.args.head.getTag() != JCTree.ASSIGN) return; // error recovery
 2058  0
         JCAssign assign = (JCAssign) a.args.head;
 2059  0
         Symbol m = JavafxTreeInfo.symbol(assign.lhs);
 2060  0
         if (m.name != names.value) return;
 2061  0
         JCTree rhs = assign.rhs;
 2062  0
         if (rhs.getTag() != JCTree.NEWARRAY) return;
 2063  0
         JCNewArray na = (JCNewArray) rhs;
 2064  0
         Set<Symbol> targets = new HashSet<Symbol>();
 2065  0
         for (JCTree elem : na.elems) {
 2066  0
             if (!targets.add(JavafxTreeInfo.symbol(elem))) {
 2067  0
                 log.error(elem.pos(), MsgSym.MESSAGE_REPEATED_ANNOTATION_TARGET);
 2068  
             }
 2069  
         }
 2070  0
     }
 2071  
 
 2072  
 // JavaFX change
 2073  
     public
 2074  
 // JavaFX change
 2075  
     void checkDeprecatedAnnotation(DiagnosticPosition pos, Symbol s) {
 2076  5183
         if (allowAnnotations &&
 2077  
             lint.isEnabled(Lint.LintCategory.DEP_ANN) &&
 2078  
             (s.flags() & DEPRECATED) != 0 &&
 2079  
             !syms.deprecatedType.isErroneous() &&
 2080  
             s.attribute(syms.deprecatedType.tsym) == null) {
 2081  0
             log.warning(pos, MsgSym.MESSAGE_MISSING_DEPRECATED_ANNOTATION);
 2082  
         }
 2083  5183
     }
 2084  
 
 2085  
 /* *************************************************************************
 2086  
  * Check for recursive annotation elements.
 2087  
  **************************************************************************/
 2088  
 
 2089  
     /** Check for cycles in the graph of annotation elements.
 2090  
      */
 2091  
 // JavaFX change
 2092  
     public
 2093  
 // JavaFX change
 2094  
     void checkNonCyclicElements(JFXClassDeclaration tree) {
 2095  667
         if ((tree.sym.flags_field & ANNOTATION) == 0) return;
 2096  0
         assert (tree.sym.flags_field & LOCKED) == 0;
 2097  
         try {
 2098  0
             tree.sym.flags_field |= LOCKED;
 2099  0
             for (JCTree def : tree.getMembers()) {
 2100  0
                 if (def.getTag() != JCTree.METHODDEF) continue;
 2101  0
                 JCMethodDecl meth = (JCMethodDecl)def;
 2102  0
                 checkAnnotationResType(meth.pos(), meth.restype.type);
 2103  0
             }
 2104  
         } finally {
 2105  0
             tree.sym.flags_field &= ~LOCKED;
 2106  0
             tree.sym.flags_field |= ACYCLIC_ANN;
 2107  0
         }
 2108  0
     }
 2109  
 
 2110  
     void checkNonCyclicElementsInternal(DiagnosticPosition pos, TypeSymbol tsym) {
 2111  0
         if ((tsym.flags_field & ACYCLIC_ANN) != 0)
 2112  0
             return;
 2113  0
         if ((tsym.flags_field & LOCKED) != 0) {
 2114  0
             log.error(pos, MsgSym.MESSAGE_CYCLIC_ANNOTATION_ELEMENT);
 2115  0
             return;
 2116  
         }
 2117  
         try {
 2118  0
             tsym.flags_field |= LOCKED;
 2119  0
             for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
 2120  0
                 Symbol s = e.sym;
 2121  0
                 if (s.kind != Kinds.MTH)
 2122  0
                     continue;
 2123  0
                 checkAnnotationResType(pos, ((MethodSymbol)s).type.getReturnType());
 2124  
             }
 2125  
         } finally {
 2126  0
             tsym.flags_field &= ~LOCKED;
 2127  0
             tsym.flags_field |= ACYCLIC_ANN;
 2128  0
         }
 2129  0
     }
 2130  
 
 2131  
     void checkAnnotationResType(DiagnosticPosition pos, Type type) {
 2132  0
         switch (type.tag) {
 2133  
         case TypeTags.CLASS:
 2134  0
             if ((type.tsym.flags() & ANNOTATION) != 0)
 2135  0
                 checkNonCyclicElementsInternal(pos, type.tsym);
 2136  
             break;
 2137  
         case TypeTags.ARRAY:
 2138  0
             checkAnnotationResType(pos, types.elemtype(type));
 2139  0
             break;
 2140  
         default:
 2141  
             break; // int etc
 2142  
         }
 2143  0
     }
 2144  
 
 2145  
 /* *************************************************************************
 2146  
  * Check for cycles in the constructor call graph.
 2147  
  **************************************************************************/
 2148  
 
 2149  
     /** Check for cycles in the graph of constructors calling other
 2150  
      *  constructors.
 2151  
      */
 2152  
 // JavaFX change
 2153  
     public
 2154  
 // JavaFX change
 2155  
     void checkCyclicConstructors(JFXClassDeclaration tree) {
 2156  667
         Map<Symbol,Symbol> callMap = new HashMap<Symbol, Symbol>();
 2157  
 
 2158  
         // enter each constructor this-call into the map
 2159  2577
         for (List<JCTree> l = tree.getMembers(); l.nonEmpty(); l = l.tail) {
 2160  1910
             JCMethodInvocation app = JavafxTreeInfo.firstConstructorCall(l.head);
 2161  1910
             if (app == null) continue;
 2162  0
             JCMethodDecl meth = (JCMethodDecl) l.head;
 2163  0
             if (JavafxTreeInfo.name(app.meth) == names._this) {
 2164  0
                 callMap.put(meth.sym, JavafxTreeInfo.symbol(app.meth));
 2165  
             } else {
 2166  0
                 meth.sym.flags_field |= ACYCLIC;
 2167  
             }
 2168  
         }
 2169  
 
 2170  
         // Check for cycles in the map
 2171  667
         Symbol[] ctors = new Symbol[0];
 2172  667
         ctors = callMap.keySet().toArray(ctors);
 2173  667
         for (Symbol caller : ctors) {
 2174  0
             checkCyclicConstructor(tree, caller, callMap);
 2175  
         }
 2176  667
     }
 2177  
 
 2178  
     /** Look in the map to see if the given constructor is part of a
 2179  
      *  call cycle.
 2180  
      */
 2181  
     private void checkCyclicConstructor(JFXClassDeclaration tree, Symbol ctor,
 2182  
                                         Map<Symbol,Symbol> callMap) {
 2183  0
         if (ctor != null && (ctor.flags_field & ACYCLIC) == 0) {
 2184  0
             if ((ctor.flags_field & LOCKED) != 0) {
 2185  0
                 log.error(JavafxTreeInfo.diagnosticPositionFor(ctor, tree),
 2186  
                           MsgSym.MESSAGE_RECURSIVE_CTOR_INVOCATION);
 2187  
             } else {
 2188  0
                 ctor.flags_field |= LOCKED;
 2189  0
                 checkCyclicConstructor(tree, callMap.remove(ctor), callMap);
 2190  0
                 ctor.flags_field &= ~LOCKED;
 2191  
             }
 2192  0
             ctor.flags_field |= ACYCLIC;
 2193  
         }
 2194  0
     }
 2195  
 
 2196  
 /* *************************************************************************
 2197  
  * Miscellaneous
 2198  
  **************************************************************************/
 2199  
 // Javafx change
 2200  
     public
 2201  
 // Javafx change
 2202  
     /**
 2203  
      * Return the opcode of the operator but emit an error if it is an
 2204  
      * error.
 2205  
      * @param pos        position for error reporting.
 2206  
      * @param operator   an operator
 2207  
      * @param tag        a tree tag
 2208  
      * @param left       type of left hand side
 2209  
      * @param right      type of right hand side
 2210  
      */
 2211  
     int checkOperator(DiagnosticPosition pos,
 2212  
                        OperatorSymbol operator,
 2213  
                        int tag,
 2214  
                        Type left,
 2215  
                        Type right) {
 2216  1131
         if (operator.opcode == ByteCodes.error) {
 2217  0
             log.error(pos,
 2218  
                       MsgSym.MESSAGE_OPERATOR_CANNOT_BE_APPLIED,
 2219  
                       treeinfo.operatorName(tag),
 2220  
                       left + "," + right);
 2221  
         }
 2222  1131
         return operator.opcode;
 2223  
     }
 2224  
 
 2225  
 
 2226  
 // Javafx change
 2227  
     public
 2228  
 // Javafx change
 2229  
     /**
 2230  
      *  Check for division by integer constant zero
 2231  
      *        @param pos             Position for error reporting.
 2232  
      *        @param operator      The operator for the expression
 2233  
      *        @param operand       The right hand operand for the expression
 2234  
      */
 2235  
     void checkDivZero(DiagnosticPosition pos, Symbol operator, Type operand) {
 2236  1131
         if (operand.constValue() != null
 2237  
             && lint.isEnabled(Lint.LintCategory.DIVZERO)
 2238  
             && operand.tag <= LONG
 2239  
             && ((Number) (operand.constValue())).longValue() == 0) {
 2240  0
             int opc = ((OperatorSymbol)operator).opcode;
 2241  0
             if (opc == ByteCodes.idiv || opc == ByteCodes.imod 
 2242  
                 || opc == ByteCodes.ldiv || opc == ByteCodes.lmod) {
 2243  0
                 log.warning(pos, MsgSym.MESSAGE_DIV_ZERO);
 2244  
             }
 2245  
         }
 2246  1131
     }
 2247  
 
 2248  
     /**
 2249  
      * Check for empty statements after if
 2250  
      */
 2251  
 // JavaFX change
 2252  
     public
 2253  
 // JavaFX change
 2254  
     void checkEmptyIf(JCIf tree) {
 2255  0
         if (tree.thenpart.getTag() == JCTree.SKIP && tree.elsepart == null && lint.isEnabled(Lint.LintCategory.EMPTY))
 2256  0
             log.warning(tree.thenpart.pos(), MsgSym.MESSAGE_EMPTY_IF);
 2257  0
     }
 2258  
 
 2259  
     /** Check that symbol is unique in given scope.
 2260  
      *        @param pos             Position for error reporting.
 2261  
      *        @param sym             The symbol.
 2262  
      *        @param s             The scope.
 2263  
      */
 2264  
     public boolean checkUnique(DiagnosticPosition pos, Symbol sym, Scope s) {
 2265  
 // Javafx change
 2266  
 //        if (sym.type.isErroneous())
 2267  4346
         if (sym.type != null && sym.type.isErroneous())
 2268  
 // Javafx change
 2269  1
             return true;
 2270  4345
         if (sym.owner.name == names.any) return false;
 2271  5495
         for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) {
 2272  1150
             sym.complete();
 2273  1150
             if (sym != e.sym &&
 2274  
                 sym.kind == e.sym.kind &&
 2275  
                 sym.name != names.error &&
 2276  
                 (sym.kind != MTH || types.overrideEquivalent(sym.type, e.sym.type))) {
 2277  0
                     if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS))
 2278  0
                     varargsDuplicateError(pos, sym, e.sym);
 2279  
                 else 
 2280  0
                     duplicateError(pos, e.sym);
 2281  0
                 return false;
 2282  
             }
 2283  
         }
 2284  4345
         return true;
 2285  
     }
 2286  
 
 2287  
     /** Check that single-type import is not already imported or top-level defined,
 2288  
      *        but make an exception for two single-type imports which denote the same type.
 2289  
      *        @param pos             Position for error reporting.
 2290  
      *        @param sym             The symbol.
 2291  
      *        @param s             The scope
 2292  
      */
 2293  
 // JavaFX change
 2294  
     public
 2295  
 // JavaFX change
 2296  
     boolean checkUniqueImport(DiagnosticPosition pos, Symbol sym, Scope s) {
 2297  3323
         return checkUniqueImport(pos, sym, s, false);
 2298  
     }
 2299  
 
 2300  
     /** Check that static single-type import is not already imported or top-level defined,
 2301  
      *        but make an exception for two single-type imports which denote the same type.
 2302  
      *        @param pos             Position for error reporting.
 2303  
      *        @param sym             The symbol.
 2304  
      *        @param s             The scope
 2305  
      *  @param staticImport  Whether or not this was a static import
 2306  
      */
 2307  
 // JavaFX change
 2308  
     public
 2309  
 // JavaFX change
 2310  
     boolean checkUniqueStaticImport(DiagnosticPosition pos, Symbol sym, Scope s) {
 2311  0
         return checkUniqueImport(pos, sym, s, true);
 2312  
     }
 2313  
 
 2314  
     /** Check that single-type import is not already imported or top-level defined,
 2315  
      *        but make an exception for two single-type imports which denote the same type.
 2316  
      *        @param pos             Position for error reporting.
 2317  
      *        @param sym             The symbol.
 2318  
      *        @param s             The scope.
 2319  
      *  @param staticImport  Whether or not this was a static import
 2320  
      */
 2321  
     private boolean checkUniqueImport(DiagnosticPosition pos, Symbol sym, Scope s, boolean staticImport) {
 2322  3325
         for (Scope.Entry e = s.lookup(sym.name); e.scope != null; e = e.next()) {
 2323  
             // is encountered class entered via a class declaration?
 2324  2
             boolean isClassDecl = e.scope == s;
 2325  2
             if ((isClassDecl || sym != e.sym) &&
 2326  
                 sym.kind == e.sym.kind &&
 2327  
                 sym.name != names.error) {
 2328  0
                 if (!e.sym.type.isErroneous()) {
 2329  0
                     String what = e.sym.toString();
 2330  0
                     if (!isClassDecl) {
 2331  0
                         if (staticImport)
 2332  0
                             log.error(pos, MsgSym.MESSAGE_ALREADY_DEFINED_STATIC_SINGLE_IMPORT, what);
 2333  
                         else
 2334  0
                             log.error(pos, MsgSym.MESSAGE_ALREADY_DEFINED_SINGLE_IMPORT, what);
 2335  
                     }
 2336  0
                     else if (sym != e.sym)
 2337  0
                         log.error(pos, MsgSym.MESSAGE_ALREADY_DEFINED_THIS_UNIT, what);
 2338  
                 }
 2339  0
                 return false;
 2340  
             }
 2341  
         }
 2342  3323
         return true;
 2343  
     }
 2344  
 
 2345  
     /** Check that a qualified name is in canonical form (for import decls).
 2346  
      */
 2347  
     public void checkCanonical(JCTree tree) {
 2348  668
         if (!isCanonical(tree))
 2349  0
             log.error(tree.pos(), MsgSym.MESSAGE_IMPORT_REQUIRES_CANONICAL,
 2350  
                       JavafxTreeInfo.symbol(tree));
 2351  668
     }
 2352  
         // where
 2353  
         private boolean isCanonical(JCTree tree) {
 2354  1961
             while (tree.getTag() == JCTree.SELECT) {
 2355  1293
                 JCFieldAccess s = (JCFieldAccess) tree;
 2356  1293
                 if (s.sym.owner != JavafxTreeInfo.symbol(s.selected))
 2357  0
                     return false;
 2358  1293
                 tree = s.selected;
 2359  1293
             }
 2360  668
             return true;
 2361  
         }
 2362  
 
 2363  
     private class ConversionWarner extends Warner {
 2364  
         final String key;
 2365  
         final Type found;
 2366  
         final Type expected;
 2367  11579
         public ConversionWarner(DiagnosticPosition pos, String key, Type found, Type expected) {
 2368  11579
             super(pos);
 2369  11579
             this.key = key;
 2370  11579
             this.found = found;
 2371  11579
             this.expected = expected;
 2372  11579
         }
 2373  
 
 2374  
         @Override
 2375  
         public void warnUnchecked() {
 2376  59
             boolean localWarned = this.warned;
 2377  59
             super.warnUnchecked();
 2378  59
             if (localWarned) return; // suppress redundant diagnostics
 2379  59
             Object problem = JCDiagnostic.fragment(key);
 2380  59
             JavafxCheck.this.warnUnchecked(pos(), MsgSym.MESSAGE_PROB_FOUND_REQ, problem, found, expected);
 2381  59
         }
 2382  
     }
 2383  
 
 2384  
     public Warner castWarner(DiagnosticPosition pos, Type found, Type expected) {
 2385  200
         return new ConversionWarner(pos, MsgSym.MESSAGE_UNCHECKED_CAST_TO_TYPE, found, expected);
 2386  
     }
 2387  
 
 2388  
     public Warner convertWarner(DiagnosticPosition pos, Type found, Type expected) {
 2389  11379
         return new ConversionWarner(pos, MsgSym.MESSAGE_UNCHECKED_ASSIGN, found, expected);
 2390  
     }
 2391  
         
 2392  
         public void warnEmptyRangeLiteral(DiagnosticPosition pos, JCLiteral lower, JCLiteral upper, JCLiteral step, boolean isExclusive) {
 2393  133
         double lowerValue = ((Number)lower.getValue()).doubleValue();
 2394  132
         double upperValue = ((Number)upper.getValue()).doubleValue();
 2395  131
         double stepValue = step != null? ((Number)step.getValue()).doubleValue() : 1;
 2396  130
         if ((stepValue > 0 && lowerValue > upperValue)
 2397  
                 || (stepValue < 0 && lowerValue < upperValue)
 2398  
                 || (isExclusive && lowerValue == upperValue)) {
 2399  17
             log.warning(pos, MsgSym.MESSAGE_JAVAFX_RANGE_LITERAL_EMPTY);
 2400  
                 }
 2401  130
         }
 2402  
 }