Coverage Report - com.sun.tools.javafx.comp.JavafxAttr
 
Classes in this File Line Coverage Branch Coverage Complexity
JavafxAttr
73%
1231/1675
56%
845/1522
0
JavafxAttr$Sequenceness
100%
4/4
N/A
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.ArrayList;
 32  
 import java.util.Set;
 33  
 import javax.lang.model.element.ElementKind;
 34  
 import javax.tools.JavaFileObject;
 35  
 
 36  
 import com.sun.javafx.api.tree.ForExpressionInClauseTree;
 37  
 import com.sun.javafx.api.tree.InterpolateValueTree;
 38  
 import com.sun.javafx.api.tree.TypeTree.Cardinality;
 39  
 import com.sun.tools.javac.code.*;
 40  
 import static com.sun.tools.javac.code.Flags.*;
 41  
 import static com.sun.tools.javac.code.Flags.ANNOTATION;
 42  
 import static com.sun.tools.javac.code.Flags.BLOCK;
 43  
 import static com.sun.tools.javac.code.Kinds.*;
 44  
 import static com.sun.tools.javac.code.Kinds.ERRONEOUS;
 45  
 import com.sun.tools.javac.code.Symbol.*;
 46  
 import com.sun.tools.javac.code.Type.*;
 47  
 import static com.sun.tools.javac.code.TypeTags.*;
 48  
 import static com.sun.tools.javac.code.TypeTags.WILDCARD;
 49  
 import com.sun.tools.javac.comp.*;
 50  
 import com.sun.tools.javac.jvm.ByteCodes;
 51  
 import com.sun.tools.javac.jvm.Target;
 52  
 import com.sun.tools.javac.tree.JCTree;
 53  
 import com.sun.tools.javac.tree.JCTree.*;
 54  
 import com.sun.tools.javac.tree.TreeInfo;
 55  
 import com.sun.tools.javac.util.*;
 56  
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 57  
 import com.sun.tools.javafx.code.*;
 58  
 import com.sun.tools.javafx.tree.*;
 59  
 import com.sun.tools.javafx.util.MsgSym;
 60  
 
 61  
 /** This is the main context-dependent analysis phase in GJC. It
 62  
  *  encompasses name resolution, type checking and constant folding as
 63  
  *  subtasks. Some subtasks involve auxiliary classes.
 64  
  *  @see Check
 65  
  *  @see Resolve
 66  
  *  @see ConstFold
 67  
  *  @see Infer
 68  
  *
 69  
  * This class is interleaved with {@link JavafxMemberEnter}, which is used
 70  
  * to enter declarations into a local scope.
 71  
  *
 72  
  *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
 73  
  *  you write code that depends on this, you do so at your own risk.
 74  
  *  This code and its internal interfaces are subject to change or
 75  
  *  deletion without notice.</b>
 76  
  */
 77  12
 public class JavafxAttr extends JCTree.Visitor implements JavafxVisitor {
 78  12
     protected static final Context.Key<JavafxAttr> javafxAttrKey =
 79  
         new Context.Key<JavafxAttr>();
 80  
 
 81  
     /*
 82  
      * modules imported by context
 83  
      */
 84  
     private final JavafxDefs defs;
 85  
     private final Name.Table names;
 86  
     private final Log log;
 87  
     private final JavafxResolve rs;
 88  
     private final JavafxSymtab syms;
 89  
     private final JavafxCheck chk;
 90  
     private final JavafxMemberEnter memberEnter;
 91  
     private final JavafxTreeMaker make;
 92  
     private final ConstFold cfolder;
 93  
     private final JavafxEnter enter;
 94  
     private final Target target;
 95  
     private final JavafxTypes types;
 96  
     private final Annotate annotate;
 97  
 
 98  
     /*
 99  
      * other instance information
 100  
      */
 101  
     private final Name numberTypeName;
 102  
     private final Name integerTypeName;
 103  
     private final Name booleanTypeName;
 104  
     private final Name stringTypeName;
 105  
     private final Name voidTypeName;  // possibly temporary
 106  
     private final Source source;
 107  
     
 108  
     //TODO: this should be switche to false when the workspace is ready
 109  
     private static final boolean allowOldStyleTriggers = false;
 110  
 
 111  399
     Map<JavafxVarSymbol, JFXVar> varSymToTree = new HashMap<JavafxVarSymbol, JFXVar>();
 112  
     
 113  
     public static JavafxAttr instance(Context context) {
 114  1197
         JavafxAttr instance = context.get(javafxAttrKey);
 115  1197
         if (instance == null)
 116  399
             instance = new JavafxAttr(context);
 117  1197
         return instance;
 118  
     }
 119  
 
 120  399
     protected JavafxAttr(Context context) {    
 121  399
         context.put(javafxAttrKey, this);
 122  
 
 123  399
         defs = JavafxDefs.instance(context);
 124  399
         syms = (JavafxSymtab)JavafxSymtab.instance(context);
 125  399
         names = Name.Table.instance(context);
 126  399
         log = Log.instance(context);
 127  399
         rs = JavafxResolve.instance(context);
 128  399
         chk = JavafxCheck.instance(context);
 129  399
         memberEnter = JavafxMemberEnter.instance(context);
 130  399
         make = (JavafxTreeMaker)JavafxTreeMaker.instance(context);
 131  399
         enter = JavafxEnter.instance(context);
 132  399
         cfolder = ConstFold.instance(context);
 133  399
         target = Target.instance(context);
 134  399
         types = JavafxTypes.instance(context);
 135  399
         annotate = Annotate.instance(context);
 136  
 
 137  399
         Options options = Options.instance(context);
 138  
 
 139  399
         source = Source.instance(context);
 140  399
         allowGenerics = source.allowGenerics();
 141  399
         allowVarargs = source.allowVarargs();
 142  399
         allowEnums = source.allowEnums();
 143  399
         allowBoxing = source.allowBoxing();
 144  399
         allowCovariantReturns = source.allowCovariantReturns();
 145  399
         allowAnonOuterThis = source.allowAnonOuterThis();
 146  399
         relax = (options.get("-retrofit") != null ||
 147  
                  options.get("-relax") != null);
 148  
         
 149  399
         numberTypeName  = names.fromString("Number");
 150  399
         integerTypeName = names.fromString("Integer");
 151  399
         booleanTypeName = names.fromString("Boolean");
 152  399
         stringTypeName = names.fromString("String");
 153  399
         voidTypeName = names.fromString("Void");
 154  399
     }
 155  
     /** Switch: relax some constraints for retrofit mode.
 156  
      */
 157  
 // JavaFX change
 158  
     protected
 159  
 // JavaFX change
 160  
     boolean relax;
 161  
 
 162  
 // Javafx change
 163  
     protected
 164  
 // Javafx change
 165  
     /** Switch: support generics?
 166  
      */
 167  
     boolean allowGenerics;
 168  
 
 169  
     /** Switch: allow variable-arity methods.
 170  
      */
 171  
 // Javafx change
 172  
     protected
 173  
 // Javafx change
 174  
     boolean allowVarargs;
 175  
 
 176  
 // Javafx change
 177  
     protected
 178  
 // Javafx change
 179  
     /** Switch: support enums?
 180  
      */
 181  
     boolean allowEnums;
 182  
 
 183  
 // Javafx change
 184  
     protected
 185  
 // Javafx change
 186  
     /** Switch: support boxing and unboxing?
 187  
      */
 188  
     boolean allowBoxing;
 189  
 
 190  
 // Javafx change
 191  
     protected
 192  
 // Javafx change
 193  
     /** Switch: support covariant result types?
 194  
      */
 195  
     boolean allowCovariantReturns;
 196  
 
 197  
 // Javafx change
 198  
     protected
 199  
 // Javafx change
 200  
     /** Switch: allow references to surrounding object from anonymous
 201  
      * objects during constructor call?
 202  
      */
 203  
     boolean allowAnonOuterThis;
 204  
 
 205  36
     public enum Sequenceness {
 206  9
         DISALLOWED,
 207  9
         PERMITTED, 
 208  9
         REQUIRED
 209  
     }
 210  
 
 211  
     /** Check kind and type of given tree against protokind and prototype.
 212  
      *  If check succeeds, store type in tree and return it.
 213  
      *  If check fails, store errType in tree and return it.
 214  
      *  No checks are performed if the prototype is a method type.
 215  
      *  Its not necessary in this case since we know that kind and type
 216  
      *  are correct.
 217  
      *
 218  
      *  @param tree     The tree whose kind and type is checked
 219  
      *  @param owntype  The computed type of the tree
 220  
      *  @param ownkind  The computed kind of the tree
 221  
      *  @param pkind    The expected kind (or: protokind) of the tree
 222  
      *  @param pt       The expected type (or: prototype) of the tree
 223  
      */
 224  
     protected
 225  
     Type check(JCTree tree, Type owntype, int ownkind, int pkind, Type pt, Sequenceness pSequenceness) {
 226  40409
         if (owntype != null && owntype != syms.javafx_UnspecifiedType && owntype.tag != ERROR && pt.tag != METHOD && pt.tag != FORALL) {
 227  
 //        if (owntype.tag != ERROR && pt.tag != METHOD && pt.tag != FORALL) {
 228  37037
             if ((pkind & VAL) != 0 && ownkind == MTH) {
 229  9
                 ownkind = VAL;
 230  9
                 if (owntype instanceof MethodType)
 231  9
                     owntype = syms.makeFunctionType((MethodType) owntype);
 232  
                 }
 233  37037
             if ((ownkind & ~pkind) == 0) {
 234  37037
                 owntype = chk.checkType(tree.pos(), owntype, pt, pSequenceness);
 235  
             } else {
 236  0
                 log.error(tree.pos(), MsgSym.MESSAGE_UNEXPECTED_TYPE,
 237  
                           Resolve.kindNames(pkind),
 238  
                           Resolve.kindName(ownkind));
 239  0
                 owntype = syms.errType;
 240  
             }
 241  
         }
 242  40409
         tree.type = owntype;
 243  40409
         return owntype;
 244  
     }
 245  
 
 246  
     /** Is this symbol a type?
 247  
      */
 248  
     static boolean isType(Symbol sym) {
 249  21875
         return sym != null && sym.kind == TYP;
 250  
     }
 251  
     
 252  
     /** The current `this' symbol.
 253  
      *  @param env    The current environment.
 254  
      */
 255  
     Symbol thisSym(DiagnosticPosition pos, JavafxEnv<JavafxAttrContext> env) {
 256  0
         return rs.resolveSelf(pos, env, env.enclClass.sym, names._this);
 257  
     }
 258  
    
 259  
 /* ************************************************************************
 260  
  * Visitor methods
 261  
  *************************************************************************/
 262  
 
 263  
     /** Visitor argument: the current environment.
 264  
      */
 265  
     JavafxEnv<JavafxAttrContext> env;
 266  
 
 267  
     /** Visitor argument: the currently expected proto-kind.
 268  
      */
 269  
     int pkind;
 270  
 
 271  
     /** Visitor argument: the currently expected proto-type.
 272  
      */
 273  
     Type pt;
 274  
 
 275  
     /** Visitor argument: is a sequence permitted
 276  
      */
 277  
     Sequenceness pSequenceness;
 278  
 
 279  
     /** Visitor result: the computed type.
 280  
      */
 281  
     Type result;
 282  
     
 283  
     /** Visitor method: attribute a tree, catching any completion failure
 284  
      *  exceptions. Return the tree's type.
 285  
      *
 286  
      *  @param tree    The tree to be visited.
 287  
      *  @param env     The environment visitor argument.
 288  
      *  @param pkind   The protokind visitor argument.
 289  
      *  @param pt      The prototype visitor argument.
 290  
      */
 291  
     Type attribTree(JCTree tree, JavafxEnv<JavafxAttrContext> env, int pkind, Type pt) {
 292  13548
         return attribTree(tree, env, pkind, pt, pSequenceness);
 293  
     }
 294  
     
 295  
     Type attribTree(JCTree tree, JavafxEnv<JavafxAttrContext> env, int pkind, Type pt, Sequenceness pSequenceness) {
 296  53683
         JavafxEnv<JavafxAttrContext> prevEnv = this.env;
 297  53683
         int prevPkind = this.pkind;
 298  53683
         Type prevPt = this.pt;
 299  53683
         Sequenceness prevSequenceness = this.pSequenceness;
 300  
         try {
 301  53683
             this.env = env;
 302  53683
             this.pkind = pkind;
 303  53683
             this.pt = pt;
 304  53683
             this.pSequenceness = pSequenceness;
 305  53683
             tree.accept(this);
 306  53671
             return result;
 307  0
         } catch (CompletionFailure ex) {
 308  0
             tree.type = syms.errType;
 309  0
             return chk.completionError(tree.pos(), ex);
 310  
         } finally {
 311  53683
             this.env = prevEnv;
 312  53683
             this.pkind = prevPkind;
 313  53683
             this.pt = prevPt;
 314  53683
             this.pSequenceness = prevSequenceness;
 315  
         }
 316  
     }
 317  
 
 318  
     /** Derived visitor method: attribute an expression tree.
 319  
      */
 320  
     public Type attribExpr(JCTree tree, JavafxEnv<JavafxAttrContext> env, Type pt, Sequenceness pSequenceness) {
 321  0
         return attribTree(tree, env, VAL, pt.tag != ERROR ? pt : Type.noType, pt.tag != ERROR ? pSequenceness : Sequenceness.PERMITTED);
 322  
     }
 323  
 
 324  
     /** Derived visitor method: attribute an expression tree.  
 325  
      *  allow a sequence is no proto-type is specified, the proto-type is a seqeunce,
 326  
      *  or the proto-type is an error.
 327  
      */
 328  
     public Type attribExpr(JCTree tree, JavafxEnv<JavafxAttrContext> env, Type pt) {
 329  13691
         return attribTree(tree, env, VAL, pt.tag != ERROR ? pt : Type.noType, 
 330  
                 (pt.tag == ERROR || pt == Type.noType)? 
 331  
                         Sequenceness.PERMITTED :  
 332  
                         types.isSequence(pt)? Sequenceness.REQUIRED : Sequenceness.DISALLOWED);
 333  
     }
 334  
 
 335  
     /** Derived visitor method: attribute an expression tree with
 336  
      *  no constraints on the computed type.
 337  
      */
 338  
     Type attribExpr(JCTree tree, JavafxEnv<JavafxAttrContext> env) {
 339  8715
         return attribTree(tree, env, VAL, Type.noType, Sequenceness.PERMITTED);
 340  
     }
 341  
 
 342  
     /** Derived visitor method: attribute a type tree.
 343  
      */
 344  
     Type attribType(JCTree tree, JavafxEnv<JavafxAttrContext> env) {
 345  6550
         Type localResult = attribTree(tree, env, TYP, Type.noType, Sequenceness.DISALLOWED);
 346  6550
         return localResult;
 347  
     }
 348  
 
 349  
     /** Derived visitor method: attribute a statement or definition tree.
 350  
      */
 351  
     public Type attribStat(JCTree tree, JavafxEnv<JavafxAttrContext> env) {
 352  2690
         return attribTree(tree, env, NIL, Type.noType, Sequenceness.DISALLOWED);
 353  
     }
 354  
     
 355  
     public Type attribVar(JFXVar tree, JavafxEnv<JavafxAttrContext> env) {
 356  1438
         memberEnter.memberEnter(tree, env);
 357  1438
         return attribTree(tree, env, NIL, Type.noType, Sequenceness.DISALLOWED);
 358  
     }
 359  
 
 360  
     /** Attribute a list of expressions, returning a list of types.
 361  
      */
 362  
     List<Type> attribExprs(List<JCExpression> trees, JavafxEnv<JavafxAttrContext> env, Type pt) {
 363  0
         ListBuffer<Type> ts = new ListBuffer<Type>();
 364  0
         for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
 365  0
             ts.append(attribExpr(l.head, env, pt));
 366  0
         return ts.toList();
 367  
     }
 368  
     
 369  
     /** Attribute the arguments in a method call, returning a list of types.
 370  
      */
 371  
     List<Type> attribArgs(List<JCExpression> trees, JavafxEnv<JavafxAttrContext> env) {
 372  641
         ListBuffer<Type> argtypes = new ListBuffer<Type>();
 373  739
         for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
 374  98
             argtypes.append(chk.checkNonVoid(
 375  
                 l.head.pos(), types.upperBound(attribTree(l.head, env, VAL, Infer.anyPoly))));
 376  641
         return argtypes.toList();
 377  
     }
 378  
 
 379  
     /** Does tree represent a static reference to an identifier?
 380  
      *  It is assumed that tree is either a SELECT or an IDENT.
 381  
      *  We have to weed out selects from non-type names here.
 382  
      *  @param tree    The candidate tree.
 383  
      */
 384  
     boolean isStaticReference(JCTree tree) {
 385  0
         if (tree.getTag() == JCTree.SELECT) {
 386  0
             Symbol lsym = TreeInfo.symbol(((JCFieldAccess) tree).selected);
 387  0
             if (lsym == null || lsym.kind != TYP) {
 388  0
                 return false;
 389  
             }
 390  
         }
 391  0
         return true;
 392  
     }
 393  
 
 394  
     /** Attribute a list of statements, returning nothing.
 395  
      */
 396  
     <T extends JCTree> void attribStats(List<T> trees, JavafxEnv<JavafxAttrContext> env) {
 397  1332
         for (List<T> l = trees; l.nonEmpty(); l = l.tail)
 398  390
             attribStat(l.head, env);
 399  942
     }
 400  
 
 401  
 // Javafx change
 402  
     protected
 403  
 // Javafx change
 404  
     /** Attribute a type argument list, returning a list of types.
 405  
      */
 406  
     List<Type> attribTypes(List<JCExpression> trees, JavafxEnv<JavafxAttrContext> env) {
 407  3327
         ListBuffer<Type> argtypes = new ListBuffer<Type>();
 408  3327
         for (List<JCExpression> l = trees; l.nonEmpty(); l = l.tail)
 409  0
             argtypes.append(chk.checkRefType(l.head.pos(), attribType(l.head, env)));
 410  3327
         return argtypes.toList();
 411  
     }
 412  
 
 413  
     /**
 414  
      * Attribute type variables (of generic classes or methods).
 415  
      * Compound types are attributed later in attribBounds.
 416  
      * @param typarams the type variables to enter
 417  
      * @param env      the current environment
 418  
      */
 419  
     void attribTypeVariables(List<JCTypeParameter> typarams, JavafxEnv<JavafxAttrContext> env) {
 420  702
         for (JCTypeParameter tvar : typarams) {
 421  0
             TypeVar a = (TypeVar)tvar.type;
 422  0
             if (!tvar.bounds.isEmpty()) {
 423  0
                 List<Type> bounds = List.of(attribType(tvar.bounds.head, env));
 424  0
                 for (JCExpression bound : tvar.bounds.tail)
 425  0
                     bounds = bounds.prepend(attribType(bound, env));
 426  0
                 types.setBounds(a, bounds.reverse());
 427  0
             } else {
 428  
                 // if no bounds are given, assume a single bound of
 429  
                 // java.lang.Object.
 430  0
                 types.setBounds(a, List.of(syms.objectType));
 431  
             }
 432  0
         }
 433  702
         for (JCTypeParameter tvar : typarams)
 434  0
             chk.checkNonCyclic(tvar.pos(), (TypeVar)tvar.type);
 435  702
         attribStats(typarams, env);
 436  702
     }
 437  
     
 438  
     void attribBounds(List<JCTypeParameter> typarams) {
 439  670
         for (JCTypeParameter typaram : typarams) {
 440  0
             Type bound = typaram.type.getUpperBound();
 441  0
             if (bound != null && bound.tsym instanceof ClassSymbol) {
 442  0
                 ClassSymbol c = (ClassSymbol)bound.tsym;
 443  0
                 if ((c.flags_field & COMPOUND) != 0) {
 444  0
                     assert (c.flags_field & UNATTRIBUTED) != 0 : c;
 445  0
                     attribClass(typaram.pos(), null, c);
 446  
                 }
 447  
             }
 448  0
         }
 449  670
     }
 450  
 
 451  
     /**
 452  
      * Attribute the type references in a list of annotations.
 453  
      */
 454  
     void attribAnnotationTypes(List<JCAnnotation> annotations,
 455  
                                JavafxEnv<JavafxAttrContext> env) {
 456  702
         for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
 457  0
             JCAnnotation a = al.head;
 458  0
             attribType(a.annotationType, env);
 459  
         }
 460  702
     }
 461  
 
 462  
     /** Attribute type reference in an `extends' or `implements' clause.
 463  
      *
 464  
      *  @param tree              The tree making up the type reference.
 465  
      *  @param env               The environment current at the reference.
 466  
      *  @param classExpected     true if only a class is expected here.
 467  
      *  @param interfaceExpected true if only an interface is expected here.
 468  
      */
 469  
     Type attribBase(JCTree tree,
 470  
                     JavafxEnv<JavafxAttrContext> env,
 471  
                     boolean classExpected,
 472  
                     boolean interfaceExpected,
 473  
                     boolean checkExtensible) {
 474  26
         Type t = attribType(tree, env);
 475  26
         return checkBase(t, tree, env, classExpected, interfaceExpected, checkExtensible);
 476  
     }
 477  
 
 478  
     Type checkBase(Type t,
 479  
                    JCTree tree,
 480  
                    JavafxEnv<JavafxAttrContext> env,
 481  
                    boolean classExpected,
 482  
                    boolean interfaceExpected,
 483  
                    boolean checkExtensible) {
 484  26
         if (t.tag == TYPEVAR && !classExpected && !interfaceExpected) {
 485  
             // check that type variable is already visible
 486  0
             if (t.getUpperBound() == null) {
 487  0
                 log.error(tree.pos(), MsgSym.MESSAGE_ILLEGAL_FORWARD_REF);
 488  0
                 return syms.errType;
 489  
             }
 490  
         } else {
 491  26
             t = chk.checkClassType(tree.pos(), t, checkExtensible|!allowGenerics);
 492  
         }
 493  26
         if (interfaceExpected && (t.tsym.flags() & INTERFACE) == 0) {
 494  0
             log.error(tree.pos(), MsgSym.MESSAGE_INTF_EXPECTED_HERE);
 495  
             // return errType is necessary since otherwise there might
 496  
             // be undetected cycles which cause attribution to loop
 497  0
             return syms.errType;
 498  26
         } else if (checkExtensible &&
 499  
                    classExpected &&
 500  
                    (t.tsym.flags() & INTERFACE) != 0) {
 501  0
             log.error(tree.pos(), MsgSym.MESSAGE_NO_INTF_EXPECTED_HERE);
 502  0
             return syms.errType;
 503  
         }
 504  26
         if (checkExtensible &&
 505  
             ((t.tsym.flags() & FINAL) != 0)) {
 506  0
             log.error(tree.pos(),
 507  
                       MsgSym.MESSAGE_CANNOT_INHERIT_FROM_FINAL, t.tsym);
 508  
         }
 509  26
         chk.checkNonCyclic(tree.pos(), t);
 510  26
         return t;
 511  
     }
 512  
 
 513  
     JavafxEnv<JavafxAttrContext> newLocalEnv(JCTree tree) {
 514  763
         JavafxEnv<JavafxAttrContext> localEnv =
 515  
                 env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));
 516  763
         localEnv.outer = env;
 517  763
         localEnv.info.scope.owner = new MethodSymbol(BLOCK, names.empty, null, env.enclClass.sym);
 518  763
         return localEnv;
 519  
     }
 520  
 
 521  
     @Override
 522  
     public void visitTypeCast(JCTypeCast tree) {
 523  121
         Type clazztype = attribType(tree.clazz, env);
 524  121
         Type exprtype = attribExpr(tree.expr, env, Infer.anyPoly);
 525  121
         if (clazztype.isPrimitive() && ! exprtype.isPrimitive())
 526  11
             clazztype = types.boxedClass(clazztype).type;
 527  121
         Type owntype = chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
 528  121
         if (exprtype.constValue() != null)
 529  0
             owntype = cfolder.coerce(exprtype, owntype);
 530  121
         result = check(tree, capture(owntype), VAL, pkind, pt, Sequenceness.DISALLOWED);
 531  121
     }
 532  
 
 533  
     @Override
 534  
     public void visitTypeTest(JCInstanceOf tree) {
 535  37
         Type exprtype = chk.checkNullOrRefType(
 536  
             tree.expr.pos(), attribExpr(tree.expr, env));
 537  37
         Type clazztype = chk.checkReifiableReferenceType(
 538  
             tree.clazz.pos(), attribType(tree.clazz, env));
 539  37
         chk.checkCastable(tree.expr.pos(), exprtype, clazztype);
 540  37
         result = check(tree, syms.booleanType, VAL, pkind, pt, Sequenceness.DISALLOWED);
 541  37
     }
 542  
 
 543  
     @Override
 544  
     public void visitIndexed(JCArrayAccess tree) {
 545  0
         assert false : "This tree should not exist";
 546  0
     }
 547  
 
 548  
     @Override
 549  
     public void visitIdent(JCIdent tree) {
 550  
         Symbol sym;
 551  12853
         boolean varArgs = false;
 552  
 
 553  
         // Find symbol
 554  12853
         if (tree.sym != null && tree.sym.kind != VAR) {
 555  1437
             sym = tree.sym;
 556  
         } else {
 557  11416
             sym = rs.resolveIdent(tree.pos(), env, tree.name, pkind, pt);
 558  
         }
 559  12853
         tree.sym = sym;
 560  12853
         sym.complete();
 561  12853
         if (sym.type == null) {
 562  0
             log.error(tree.pos(), MsgSym.MESSAGE_JAVAFX_TYPE_INFER_CYCLE, tree.name);
 563  0
             sym.type = syms.objectType;
 564  
         }
 565  
 
 566  
         // (1) Also find the environment current for the class where
 567  
         //     sym is defined (`symEnv').
 568  
         // Only for pre-tiger versions (1.4 and earlier):
 569  
         // (2) Also determine whether we access symbol out of an anonymous
 570  
         //     class in a this or super call.  This is illegal for instance
 571  
         //     members since such classes don't carry a this$n link.
 572  
         //     (`noOuterThisPath').
 573  12853
         JavafxEnv<JavafxAttrContext> symEnv = env;
 574  12853
         boolean noOuterThisPath = false;
 575  12853
         if (env.enclClass.sym.owner.kind != PCK && // we are in an inner class
 576  
             (sym.kind & (VAR | MTH | TYP)) != 0 &&
 577  
             sym.owner.kind == TYP &&
 578  
             tree.name != names._this && tree.name != names._super) {
 579  
 
 580  
             // Find environment in which identifier is defined.
 581  1611
             while (symEnv.outer != null &&
 582  
                    !sym.isMemberOf(symEnv.enclClass.sym, types)) {
 583  776
                 if ((symEnv.enclClass.sym.flags() & NOOUTERTHIS) != 0)
 584  0
                     noOuterThisPath = !allowAnonOuterThis;
 585  776
                 symEnv = symEnv.outer;
 586  
             }
 587  
         }
 588  
 
 589  
         // If symbol is a variable, ...
 590  12853
         if (sym.kind == VAR) {
 591  6954
             VarSymbol v = (VarSymbol)sym;
 592  
 
 593  
             // ..., evaluate its initializer, if it has one, and check for
 594  
             // illegal forward reference.
 595  6954
             checkInit(tree, env, v, false);
 596  
 
 597  
             // If we are expecting a variable (as opposed to a value), check
 598  
             // that the variable is assignable in the current environment.
 599  6954
             if (pkind == VAR)
 600  1231
                 checkAssignable(tree.pos(), v, null, env);
 601  
         }
 602  
 
 603  
         // In a constructor body,
 604  
         // if symbol is a field or instance method, check that it is
 605  
         // not accessed before the supertype constructor is called.
 606  12853
         if ((symEnv.info.isSelfCall || noOuterThisPath) &&
 607  
             (sym.kind & (VAR | MTH)) != 0 &&
 608  
             sym.owner.kind == TYP &&
 609  
             (sym.flags() & STATIC) == 0) {
 610  0
             chk.earlyRefError(tree.pos(), sym.kind == VAR ? sym : thisSym(tree.pos(), env));
 611  
         }
 612  12853
         JavafxEnv<JavafxAttrContext> env1 = env;
 613  12853
         if (sym.kind != ERR && sym.owner != null && sym.owner != env1.enclClass.sym) {
 614  
             // If the found symbol is inaccessible, then it is
 615  
             // accessed through an enclosing instance.  Locate this
 616  
             // enclosing instance:
 617  33441
             while (env1.outer != null && !rs.isAccessible(env, env1.enclClass.sym.type, sym))
 618  23286
                 env1 = env1.outer;
 619  
         }
 620  12853
         result = checkId(tree, env1.enclClass.sym.type, sym, env, pkind, pt, pSequenceness, varArgs);
 621  12853
     }
 622  
     
 623  
     @Override
 624  
     public void visitSelect(JCFieldAccess tree) {
 625  
         // Determine the expected kind of the qualifier expression.
 626  7961
         int skind = 0;
 627  7961
         if (tree.name == names._this || tree.name == names._super ||
 628  
             tree.name == names._class)
 629  
         {
 630  0
             skind = TYP;
 631  
         } else {
 632  7961
             if ((pkind & PCK) != 0) skind = skind | PCK;
 633  7961
             if ((pkind & TYP) != 0) skind = skind | TYP | PCK;
 634  7961
             if ((pkind & (VAL | MTH)) != 0) skind = skind | VAL | TYP;
 635  
         }
 636  
 
 637  
         // Attribute the qualifier expression, and determine its symbol (if any).
 638  7961
         Type site = attribTree(tree.selected, env, skind, Infer.anyPoly);
 639  7961
         if ((pkind & (PCK | TYP)) == 0)
 640  3178
             site = capture(site); // Capture field access
 641  
 
 642  
         // don't allow T.class T[].class, etc
 643  7961
         if (skind == TYP) {
 644  0
             Type elt = site;
 645  0
             while (elt.tag == ARRAY)
 646  0
                 elt = ((ArrayType)elt).elemtype;
 647  0
             if (elt.tag == TYPEVAR) {
 648  0
                 log.error(tree.pos(), MsgSym.MESSAGE_TYPE_VAR_CANNOT_BE_DEREF);
 649  0
                 result = syms.errType;
 650  0
                 return;
 651  
             }
 652  
         }
 653  
 
 654  
         // If qualifier symbol is a type or `super', assert `selectSuper'
 655  
         // for the selection. This is relevant for determining whether
 656  
         // protected symbols are accessible.
 657  7961
         Symbol sitesym = TreeInfo.symbol(tree.selected);
 658  7961
         boolean selectSuperPrev = env.info.selectSuper;
 659  7961
         env.info.selectSuper =
 660  
             sitesym != null &&
 661  
             sitesym.name == names._super;
 662  
 
 663  
         // If selected expression is polymorphic, strip
 664  
         // type parameters and remember in env.info.tvars, so that
 665  
         // they can be added later (in Attr.checkId and Infer.instantiateMethod).
 666  7961
         if (tree.selected.type.tag == FORALL) {
 667  0
             ForAll pstype = (ForAll)tree.selected.type;
 668  0
             env.info.tvars = pstype.tvars;
 669  0
             site = tree.selected.type = pstype.qtype;
 670  
         }
 671  
 
 672  
         // Determine the symbol represented by the selection.
 673  7961
         env.info.varArgs = false;
 674  7961
         if (sitesym instanceof ClassSymbol &&
 675  
                 env.enclClass.sym.isSubClass(sitesym, types))
 676  3
             env.info.selectSuper = true;
 677  7961
         Symbol sym = selectSym(tree, site, env, pt, pkind);
 678  7961
         sym.complete();
 679  7961
         if (sym.exists() && !isType(sym) && (pkind & (PCK | TYP)) != 0) {
 680  1579
             site = capture(site);
 681  1579
             sym = selectSym(tree, site, env, pt, pkind);
 682  
         }
 683  7961
         boolean varArgs = env.info.varArgs;
 684  7961
         tree.sym = sym;
 685  
 
 686  7961
         if (sym.type == null) {
 687  1
             log.error(tree.pos(), MsgSym.MESSAGE_JAVAFX_TYPE_INFER_CYCLE, sym.name);
 688  1
             sym.type = syms.objectType;
 689  
         }
 690  
 
 691  7961
         if (site.tag == TYPEVAR && !isType(sym) && sym.kind != ERR)
 692  0
             site = capture(site.getUpperBound());
 693  
 
 694  
         // If that symbol is a variable, ...
 695  7961
         if (sym.kind == VAR) {
 696  2311
             VarSymbol v = (VarSymbol)sym;
 697  
 
 698  
             // ..., evaluate its initializer, if it has one, and check for
 699  
             // illegal forward reference.
 700  2311
             checkInit(tree, env, v, true);
 701  
 
 702  
             // If we are expecting a variable (as opposed to a value), check
 703  
             // that the variable is assignable in the current environment.
 704  2311
             if (pkind == VAR)
 705  198
                 checkAssignable(tree.pos(), v, tree.selected, env);
 706  
         }
 707  
 
 708  
         // Disallow selecting a type from an expression
 709  7961
         if (isType(sym) && (sitesym==null || (sitesym.kind&(TYP|PCK)) == 0)) {
 710  0
             tree.type = check(tree.selected, pt,
 711  
                               sitesym == null ? VAL : sitesym.kind, TYP|PCK, pt, pSequenceness);
 712  
         }
 713  
 
 714  7961
         if (isType(sitesym)) {
 715  2047
             if (sym.name == names._this) {
 716  
                 // If `C' is the currently compiled class, check that
 717  
                 // C.this' does not appear in a call to a super(...)
 718  0
                 if (env.info.isSelfCall &&
 719  
                     site.tsym == env.enclClass.sym) {
 720  0
                     chk.earlyRefError(tree.pos(), sym);
 721  
                 }
 722  
             }
 723  
         }
 724  
 
 725  
         // If we are selecting an instance member via a `super', ...
 726  7961
         if (env.info.selectSuper && (sym.flags() & STATIC) == 0) {
 727  
 
 728  
             // Check that super-qualified symbols are not abstract (JLS)
 729  11
             rs.checkNonAbstract(tree.pos(), sym);
 730  
 
 731  11
             if (site.isRaw()) {
 732  
                 // Determine argument types for site.
 733  0
                 Type site1 = types.asSuper(env.enclClass.sym.type, site.tsym);
 734  0
                 if (site1 != null) site = site1;
 735  
             }
 736  
         }
 737  
 
 738  7961
         env.info.selectSuper = selectSuperPrev;
 739  7961
         result = checkId(tree, site, sym, env, pkind, pt, pSequenceness, varArgs);
 740  7961
         env.info.tvars = List.nil();
 741  7961
     }
 742  
     //where
 743  
         /** Determine symbol referenced by a Select expression,
 744  
          *
 745  
          *  @param tree   The select tree.
 746  
          *  @param site   The type of the selected expression,
 747  
          *  @param env    The current environment.
 748  
          *  @param pt     The current prototype.
 749  
          *  @param pkind  The expected kind(s) of the Select expression.
 750  
          */
 751  
     @SuppressWarnings("fallthrough")
 752  
         private Symbol selectSym(JCFieldAccess tree,
 753  
                                  Type site,
 754  
                                  JavafxEnv<JavafxAttrContext> env,
 755  
                                  Type pt,
 756  
                                  int pkind) {
 757  9540
             DiagnosticPosition pos = tree.pos();
 758  9540
             Name name = tree.name;
 759  
 
 760  9540
             switch (site.tag) {
 761  
             case PACKAGE:
 762  3226
                 return rs.access(
 763  
                     rs.findIdentInPackage(env, site.tsym, name, pkind),
 764  
                     pos, site, name, true);
 765  
             case ARRAY:
 766  
             case CLASS:
 767  6284
                 if (pt.tag == METHOD || pt.tag == FORALL) {
 768  2413
                     return rs.resolveQualifiedMethod(pos, env, site, name, pt);
 769  3871
                 } else if (name == names._this || name == names._super) {
 770  0
                     return rs.resolveSelf(pos, env, site.tsym, name);
 771  3871
                 } else if (name == names._class) {
 772  
                     // In this case, we have already made sure in
 773  
                     // visitSelect that qualifier expression is a type.
 774  0
                     Type t = syms.classType;
 775  0
                     List<Type> typeargs = allowGenerics
 776  
                         ? List.of(types.erasure(site))
 777  
                         : List.<Type>nil();
 778  0
                     t = new ClassType(t.getEnclosingType(), typeargs, t.tsym);
 779  0
                     return new VarSymbol(
 780  
                         STATIC | PUBLIC | FINAL, names._class, t, site.tsym);
 781  
                 } else {
 782  
                     // We are seeing a plain identifier as selector.
 783  3871
                     Symbol sym = rs.findIdentInType(env, site, name, pkind);
 784  3871
                     if ((pkind & ERRONEOUS) == 0)
 785  3871
                         sym = rs.access(sym, pos, site, name, true);
 786  3871
                     return sym;
 787  
                 }
 788  
             case WILDCARD:
 789  0
                 throw new AssertionError(tree);
 790  
             case TYPEVAR:
 791  
                 // Normally, site.getUpperBound() shouldn't be null.
 792  
                 // It should only happen during memberEnter/attribBase
 793  
                 // when determining the super type which *must* be
 794  
                 // done before attributing the type variables.  In
 795  
                 // other words, we are seeing this illegal program:
 796  
                 // class B<T> extends A<T.foo> {}
 797  0
                 Symbol sym = (site.getUpperBound() != null)
 798  
                     ? selectSym(tree, capture(site.getUpperBound()), env, pt, pkind)
 799  
                     : null;
 800  0
                 if (sym == null || isType(sym)) {
 801  0
                     log.error(pos, MsgSym.MESSAGE_TYPE_VAR_CANNOT_BE_DEREF);
 802  0
                     return syms.errSymbol;
 803  
                 } else {
 804  0
                     return sym;
 805  
                 }
 806  
             case ERROR:
 807  
                 // preserve identifier names through errors
 808  1
                 return new ErrorType(name, site.tsym).tsym;
 809  
             case INT:
 810  
             case DOUBLE:
 811  
             case BOOLEAN:
 812  29
                 if (pt.tag == METHOD || pt.tag == FORALL) {
 813  29
                     Type boxedSite = types.boxedClass(site).type;
 814  29
                     return rs.resolveQualifiedMethod(pos, env, boxedSite, name, pt);
 815  
                 } 
 816  
                 // Fall through to default
 817  
             default:
 818  
                 // The qualifier expression is of a primitive type -- only
 819  
                 // .class is allowed for these.
 820  0
                 if (name == names._class) {
 821  
                     // In this case, we have already made sure in Select that
 822  
                     // qualifier expression is a type.
 823  0
                     Type t = syms.classType;
 824  0
                     Type arg = types.boxedClass(site).type;
 825  0
                     t = new ClassType(t.getEnclosingType(), List.of(arg), t.tsym);
 826  0
                     return new VarSymbol(
 827  
                         STATIC | PUBLIC | FINAL, names._class, t, site.tsym);
 828  
                 } else {
 829  0
                     log.error(pos, MsgSym.MESSAGE_CANNOT_DEREF, site);
 830  0
                     return syms.errSymbol;
 831  
                 }
 832  
             }
 833  
         }
 834  
 
 835  
 
 836  
     @Override
 837  
     public void visitParens(JCParens tree) {
 838  0
         Type owntype = attribTree(tree.expr, env, pkind, pt);
 839  0
         result = check(tree, owntype, pkind, pkind, pt, pSequenceness);
 840  0
         Symbol sym = TreeInfo.symbol(tree);
 841  0
         if (sym != null && (sym.kind&(TYP|PCK)) != 0)
 842  0
             log.error(tree.pos(), MsgSym.MESSAGE_ILLEGAL_START_OF_TYPE);
 843  0
     }
 844  
 
 845  
     @Override
 846  
     public void visitAssign(JCAssign tree) {
 847  
 // Javafx change        Type owntype = attribTree(tree.lhs, env.dup(tree), VAR, Type.noType);
 848  
 // Javafx change        Type capturedType = capture(owntype);
 849  
 // Javafx change        attribExpr(tree.rhs, env, owntype);
 850  
 // Javafx change        result = check(tree, capturedType, VAL, pkind, pt);
 851  
         
 852  910
         Type owntype = null;
 853  910
         JavafxEnv<JavafxAttrContext> dupEnv = env.dup(tree);
 854  910
         dupEnv.outer = env;
 855  910
         owntype = attribTree(tree.lhs, dupEnv, VAR, Type.noType);
 856  910
         boolean hasLhsType = false;
 857  910
         if (owntype == null || owntype == syms.javafx_UnspecifiedType) {
 858  0
             owntype = attribExpr(tree.rhs, env, Type.noType);
 859  0
             hasLhsType = false;
 860  
         }
 861  
         else {
 862  910
             hasLhsType = true;
 863  
         }
 864  
         
 865  910
         Symbol lhsSym = JavafxTreeInfo.symbol(tree.lhs);
 866  910
         Type capturedType = capture(owntype);
 867  
         
 868  910
         if (hasLhsType) {
 869  910
             attribExpr(tree.rhs, dupEnv, owntype);
 870  
         }
 871  
         else {
 872  0
             if (tree.lhs.getTag() == JCTree.SELECT) {
 873  0
                 JCFieldAccess fa = (JCFieldAccess)tree.lhs;
 874  0
                 fa.type = owntype;
 875  0
             }
 876  0
             else if (tree.lhs.getTag() == JCTree.IDENT) {
 877  0
                 JCIdent id = (JCIdent)tree.lhs;
 878  0
                 id.type = owntype;
 879  
             }
 880  
             
 881  0
             attribTree(tree.lhs, dupEnv, VAR, owntype);
 882  0
             lhsSym.type = owntype;
 883  
         }
 884  910
         lhsSym.flags_field |= JavafxFlags.ASSIGNED_TO;        
 885  910
         result = check(tree, capturedType, VAL, pkind, pt, pSequenceness);
 886  
 
 887  910
         if (tree.rhs != null && tree.lhs.getTag() == JCTree.IDENT) {
 888  752
             JFXVar lhsVar = varSymToTree.get(lhsSym);
 889  752
             if (lhsVar != null && (lhsVar.getJFXType() instanceof JFXTypeUnknown)) {
 890  523
                 if (lhsVar.type == null ||
 891  
                         lhsVar.type == syms.javafx_AnyType/* ??? */ ||
 892  
                         lhsVar.type == syms.javafx_UnspecifiedType) {
 893  2
                     if (tree.rhs.type != null && lhsVar.type != tree.rhs.type) {
 894  2
                         lhsVar.type = lhsSym.type = tree.rhs.type;
 895  2
                         JCExpression jcExpr = make.at(tree.pos()).Ident(lhsSym);
 896  2
                         lhsVar.setJFXType(make.at(tree.pos()).TypeClass(jcExpr, lhsVar.getJFXType().getCardinality()));
 897  
                     }
 898  
                 }
 899  
             }
 900  
         }
 901  910
     }
 902  
     
 903  
     @Override
 904  
     public void visitVarDef(JCVariableDecl tree) {
 905  0
         assert false : "SHOULD NOT REACH HERE";
 906  0
     }
 907  
 
 908  
     public void finishVar(JFXVar tree, JavafxEnv<JavafxAttrContext> env) {
 909  3276
         VarSymbol v = tree.sym;
 910  3276
         Type declType = attribType(tree.getJFXType(), env);
 911  3276
         if (declType != syms.javafx_UnspecifiedType) {
 912  1873
             result = tree.type = v.type = declType;
 913  
         }
 914  
         // Check that the variable's declared type is well-formed.
 915  
 //        chk.validate(tree.vartype);
 916  
 
 917  
         // The info.lint field in the envs stored in enter.typeEnvs is deliberately uninitialized,
 918  
         // because the annotations were not available at the time the env was created. Therefore,
 919  
         // we look up the environment chain for the first enclosing environment for which the
 920  
         // lint value is set. Typically, this is the parent env, but might be further if there
 921  
         // are any envs created as a result of TypeParameter nodes.
 922  3276
         JavafxEnv<JavafxAttrContext> lintEnv = env;
 923  3557
         while (lintEnv.info.lint == null)
 924  281
             lintEnv = lintEnv.next;
 925  3276
         Lint lint = lintEnv.info.lint.augment(v.attributes_field, v.flags());
 926  3276
         Lint prevLint = chk.setLint(lint);
 927  3276
         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
 928  
               
 929  
         try {
 930  3276
             chk.checkDeprecatedAnnotation(tree.pos(), v);
 931  
 
 932  
             Type initType;
 933  3276
             if (tree.init != null) {
 934  
                 // Attribute initializer in a new environment.
 935  
                 // Check that initializer conforms to variable's declared type.
 936  1482
                 Scope initScope = new Scope(new MethodSymbol(BLOCK, v.name, null, env.enclClass.sym));
 937  1482
                 initScope.next = env.info.scope;
 938  1482
                 JavafxEnv<JavafxAttrContext> initEnv =
 939  
                     env.dup(tree, env.info.dup(initScope));
 940  1482
                 initEnv.outer = env;
 941  1482
                 initEnv.info.lint = lint;
 942  1482
                 if ((tree.getModifiers().flags & STATIC) != 0)
 943  42
                     initEnv.info.staticLevel++;
 944  
 
 945  
                 // In order to catch self-references, we set the variable's
 946  
                 // declaration position to maximal possible value, effectively
 947  
                 // marking the variable as undefined.
 948  1482
                 v.pos = Position.MAXPOS;
 949  1482
                 initType = attribExpr(tree.init, initEnv, declType);
 950  1479
                 initType = chk.checkNonVoid(tree.pos(), initType);
 951  1479
                 chk.checkType(tree.pos(), initType, declType, Sequenceness.DISALLOWED);
 952  1479
                 if (initType == syms.botType
 953  
                         || initType == syms.unreachableType)
 954  1
                     initType = syms.objectType;
 955  1478
                 else if (initType.isPrimitive()
 956  
                          &&  initType != syms.javafx_NumberType
 957  
                          &&  initType != syms.javafx_IntegerType
 958  
                          &&  initType != syms.javafx_BooleanType)
 959  5
                     initType = types.boxedClass(initType).type;
 960  1473
                 else if (types.isArray(initType)) {
 961  7
                     initType = types.elemtype(initType);
 962  7
                     if (initType.isPrimitive()) {
 963  1
                         if (initType == syms.shortType ||
 964  
                                 initType == syms.byteType)
 965  1
                             initType = syms.javafx_IntegerType;
 966  0
                         else if (initType == syms.floatType)
 967  0
                             initType = syms.javafx_NumberType;
 968  0
                         else if (initType == syms.charType ||
 969  
                                 initType == syms.longType)
 970  0
                             initType = types.boxedClass(initType).type;
 971  
                     }
 972  7
                     initType = types.sequenceType(initType);
 973  
                 }
 974  1479
             }
 975  1794
             else if (tree.type != null)
 976  1675
                 initType = tree.type;
 977  
             else
 978  119
                 initType = syms.objectType;  // nothing to go on, so we assume Object
 979  3273
             if (declType == syms.javafx_UnspecifiedType && v.type == null)
 980  1398
                 result = tree.type = v.type = initType;
 981  3273
             chk.validateAnnotations(tree.mods.annotations, v);
 982  
         }
 983  
         finally {
 984  3276
             chk.setLint(prevLint);
 985  3276
             log.useSource(prev);
 986  3273
         }
 987  3273
     }
 988  
 
 989  
          
 990  
     @Override
 991  
     public void visitVar(JFXVar tree) {
 992  3276
         Symbol sym = tree.sym;
 993  3276
         sym.complete();
 994  
         
 995  3273
         JFXOnReplace onReplace = tree.getOnReplace();
 996  3273
         if (onReplace != null) {
 997  120
             JFXVar oldValue = onReplace.getOldValue();
 998  120
             if (oldValue != null && oldValue.type == null) {
 999  61
                     oldValue.type =  tree.type;
 1000  
             }
 1001  
             
 1002  120
             JFXVar newElements = onReplace.getNewElements();
 1003  120
             if (newElements != null && newElements.type == null)
 1004  28
                 newElements.type = tree.type;
 1005  
               
 1006  
 
 1007  120
             if (env.info.scope.owner.kind == TYP) {
 1008  
                     // var is a static;
 1009  
                     // let the owner of the environment be a freshly
 1010  
                     // created BLOCK-method.
 1011  113
                     long flags = tree.getModifiers().flags;
 1012  113
                     JavafxEnv<JavafxAttrContext> localEnv = newLocalEnv(tree);
 1013  113
                     if ((flags & STATIC) != 0) {
 1014  0
                         localEnv.info.staticLevel++;
 1015  
                     }
 1016  113
                     attribStat(onReplace, localEnv);
 1017  113
             } else {
 1018  
                     // Create a new local environment with a local scope.
 1019  7
                     JavafxEnv<JavafxAttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
 1020  7
                     attribStat(onReplace, localEnv);
 1021  7
                     localEnv.info.scope.leave();
 1022  
             }
 1023  
            
 1024  
         }
 1025  3273
     }
 1026  
     
 1027  
     /**
 1028  
      * OK, this is a not really "finish" as in the completer, at least not now.
 1029  
      * But it does finish the attribution of the override by attributing the
 1030  
      * default initialization.
 1031  
      * 
 1032  
      * @param tree
 1033  
      * @param env
 1034  
      */
 1035  
     public void finishOverrideAttribute(JFXOverrideAttribute tree, JavafxEnv<JavafxAttrContext> env) {
 1036  9
         VarSymbol v = tree.sym;
 1037  9
         Type declType = tree.getId().type;
 1038  9
         result = tree.type = declType;
 1039  
 
 1040  
         // The info.lint field in the envs stored in enter.typeEnvs is deliberately uninitialized,
 1041  
         // because the annotations were not available at the time the env was created. Therefore,
 1042  
         // we look up the environment chain for the first enclosing environment for which the
 1043  
         // lint value is set. Typically, this is the parent env, but might be further if there
 1044  
         // are any envs created as a result of TypeParameter nodes.
 1045  9
         JavafxEnv<JavafxAttrContext> lintEnv = env;
 1046  9
         while (lintEnv.info.lint == null) {
 1047  0
             lintEnv = lintEnv.next;
 1048  
         }
 1049  9
         Lint lint = lintEnv.info.lint.augment(v.attributes_field, v.flags());
 1050  9
         Lint prevLint = chk.setLint(lint);
 1051  9
         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
 1052  
 
 1053  
         try {
 1054  9
             if (tree.getInitializer() != null) {
 1055  
                 // Attribute initializer in a new environment/
 1056  
                 // Check that initializer conforms to variable's declared type.
 1057  9
                 Scope initScope = new Scope(new MethodSymbol(BLOCK, v.name, null, env.enclClass.sym));
 1058  9
                 initScope.next = env.info.scope;
 1059  9
                 JavafxEnv<JavafxAttrContext> initEnv =
 1060  
                     env.dup(tree, env.info.dup(initScope));
 1061  9
                 initEnv.outer = env;
 1062  
                
 1063  
                 // In order to catch self-references, we set the variable's
 1064  
                 // declaration position to maximal possible value, effectively
 1065  
                 // marking the variable as undefined.
 1066  9
                 v.pos = Position.MAXPOS;
 1067  
 
 1068  9
                 attribExpr(tree.getInitializer(), initEnv, declType);
 1069  
             }
 1070  
         } finally {
 1071  9
             chk.setLint(prevLint);
 1072  9
             log.useSource(prev);
 1073  9
         }
 1074  9
     }
 1075  
 
 1076  
     @Override
 1077  
     public void visitOverrideAttribute(JFXOverrideAttribute tree) {
 1078  
         //TODO: handle static triggers
 1079  9
         JCIdent id = tree.getId();
 1080  9
         JFXOnReplace onr = tree.getOnReplace();
 1081  
 
 1082  
         // let the owner of the environment be a freshly
 1083  
         // created BLOCK-method.
 1084  9
         JavafxEnv<JavafxAttrContext> localEnv = newLocalEnv(tree);
 1085  
 
 1086  9
         Type type = attribExpr(id, localEnv);
 1087  9
         tree.type = type;
 1088  9
         Symbol sym = id.sym;
 1089  
 
 1090  9
         if (onr != null) {
 1091  6
             attribStat(onr, localEnv);
 1092  6
             JFXVar oldValue = onr.getOldValue();
 1093  6
             if (oldValue != null && oldValue.type == null) {
 1094  0
                 oldValue.type = type;
 1095  
             }
 1096  6
             JFXVar newElements = onr.getNewElements();
 1097  6
             if (newElements != null && newElements.type == null) {
 1098  0
                 newElements.type = type;
 1099  
             }
 1100  
         }
 1101  
 
 1102  
         // Must reference an attribute
 1103  9
         if (sym.kind != VAR) {
 1104  0
             log.error(id.pos(), MsgSym.MESSAGE_JAVAFX_MUST_BE_AN_ATTRIBUTE, id.name);
 1105  
         } else {
 1106  9
             VarSymbol v = (VarSymbol) sym;
 1107  9
             tree.sym = v;
 1108  9
             finishOverrideAttribute(tree, env);
 1109  
         }
 1110  9
     }
 1111  
     
 1112  
     /*
 1113  
     public void visitAbstractOnChange(JFXAbstractOnChange tree) {
 1114  
         if (tree.getIndex() != null) {
 1115  
             tree.getIndex().mods.flags |= Flags.FINAL;
 1116  
             attribVar(tree.getIndex(), env);
 1117  
             tree.getIndex().sym.type = syms.intType;
 1118  
         }
 1119  
         JFXVar oldValue = tree.getOldValue();
 1120  
         if (oldValue != null) {
 1121  
             oldValue.mods.flags |= Flags.FINAL;
 1122  
             attribVar(oldValue, env);  
 1123  
         }
 1124  
         attribStat(tree.getBody(), env);
 1125  
     }
 1126  
     */
 1127  
     
 1128  
     @Override
 1129  
     public void visitOnReplace(JFXOnReplace tree) {
 1130  126
         JFXVar lastIndex = tree.getLastIndex();
 1131  126
         if (lastIndex != null) {
 1132  21
             lastIndex.mods.flags |= Flags.FINAL;
 1133  21
             attribVar(lastIndex, env);
 1134  21
             lastIndex.sym.type = syms.intType;
 1135  
         }
 1136  126
         JFXVar newElements = tree.getNewElements();
 1137  126
         if (newElements != null) {
 1138  28
             newElements.mods.flags |= Flags.FINAL;
 1139  28
             attribVar(newElements, env); 
 1140  
         }
 1141  
         
 1142  126
         JFXVar firstIndex = tree.getFirstIndex();
 1143  126
         if (firstIndex != null) {
 1144  21
             firstIndex.mods.flags |= Flags.FINAL;
 1145  21
             attribVar(firstIndex, env);
 1146  21
             firstIndex.sym.type = syms.intType;
 1147  
         }
 1148  
         
 1149  126
         JFXVar oldValue = tree.getOldValue();
 1150  126
         if (oldValue != null) {
 1151  61
             oldValue.mods.flags |= Flags.FINAL;
 1152  61
             attribVar(oldValue, env);  
 1153  
         }
 1154  126
         attribStat(tree.getBody(), env);
 1155  126
     }
 1156  
  
 1157  
     
 1158  
     
 1159  399
     ArrayList<JFXForExpressionInClause> forClauses = null;
 1160  
     
 1161  
     @Override
 1162  
     public void visitForExpression(JFXForExpression tree) {
 1163  198
         JavafxEnv<JavafxAttrContext> forExprEnv =
 1164  
             env.dup(tree, env.info.dup(env.info.scope.dup()));
 1165  
         
 1166  198
         if (forClauses == null)
 1167  72
             forClauses = new ArrayList<JFXForExpressionInClause>();
 1168  198
         int forClausesOldSize = forClauses.size();
 1169  
         
 1170  198
         for (ForExpressionInClauseTree cl : tree.getInClauses()) {
 1171  206
             JFXForExpressionInClause clause = (JFXForExpressionInClause)cl;
 1172  206
             forClauses.add(clause);
 1173  206
             Type exprType = types.upperBound(attribExpr((JCExpression)clause.getSequenceExpression(), forExprEnv));
 1174  206
             if (clause.getVar() != null &&
 1175  
                 clause.getVar().getJFXType() instanceof JFXTypeUnknown &&
 1176  
                 exprType.allparams() != null && exprType.allparams().nonEmpty()) {
 1177  201
                 Type sequenceType = types.upperBound(exprType.allparams().last());
 1178  201
                 clause.getVar().setJFXType(make.TypeClass(make.Ident(sequenceType.tsym), Cardinality.SINGLETON));
 1179  201
                 clause.getVar().type = sequenceType;
 1180  
             }
 1181  206
             attribVar(clause.getVar(), forExprEnv);
 1182  206
             chk.checkNonVoid(((JCTree)clause).pos(), exprType);
 1183  
             Type elemtype;
 1184  
             // must implement Sequence<T>?
 1185  206
             Type base = types.asSuper(exprType, syms.javafx_SequenceType.tsym);
 1186  206
             if (base == null) {
 1187  5
                 elemtype = exprType;
 1188  
             } else {
 1189  201
                 List<Type> iterableParams = base.allparams();
 1190  201
                 if (iterableParams.isEmpty()) {
 1191  0
                     elemtype = syms.errType;
 1192  
                 } else {
 1193  201
                     elemtype = types.upperBound(iterableParams.last());
 1194  
                 }
 1195  
             }
 1196  206
             if (elemtype == syms.errType) {
 1197  0
                 log.error(((JCTree)(clause.getSequenceExpression())).pos(), MsgSym.MESSAGE_FOREACH_NOT_APPLICABLE_TO_TYPE);
 1198  206
             } else if (elemtype == syms.botType || elemtype == syms.unreachableType) {
 1199  2
                 elemtype = syms.objectType;
 1200  
             } else {
 1201  
                 // if it is a primitive type, unbox it
 1202  204
                 Type unboxed = types.unboxedType(elemtype);
 1203  204
                 if (unboxed != Type.noType) {
 1204  153
                     elemtype = unboxed;
 1205  
                 }
 1206  
             }
 1207  
             //TODO: this is certainly wrong
 1208  206
             clause.getVar().type = elemtype;
 1209  206
             clause.getVar().sym.type = elemtype;
 1210  
 
 1211  206
             chk.checkType(clause.getSequenceExpression().pos(), elemtype, clause.var.sym.type, Sequenceness.DISALLOWED);
 1212  
 
 1213  206
             if (clause.getWhereExpression() != null) {
 1214  36
                 attribExpr(clause.getWhereExpression(), env, syms.booleanType);
 1215  
             }
 1216  206
         }
 1217  
 
 1218  198
         forExprEnv.tree = tree; // before, we were not in loop!
 1219  198
         attribExpr(tree.getBodyExpression(), forExprEnv);
 1220  
 
 1221  198
         Type bodyType = tree.getBodyExpression().type;
 1222  198
         Type owntype = (bodyType == null || bodyType == syms.voidType)?
 1223  
             syms.voidType :
 1224  
             types.isSequence(bodyType) ?
 1225  
             bodyType :
 1226  
             types.sequenceType(bodyType);
 1227  404
         while (forClauses.size() > forClausesOldSize)
 1228  206
             forClauses.remove(forClauses.size()-1);
 1229  198
         forExprEnv.info.scope.leave();
 1230  198
         result = check(tree, owntype, VAL, pkind, pt, pSequenceness);
 1231  198
     }
 1232  
     
 1233  
     @Override
 1234  
     public void visitForExpressionInClause(JFXForExpressionInClause that) {
 1235  0
         assert false : "should not reach here";
 1236  0
     }
 1237  
 
 1238  
     public void visitIndexof(JFXIndexof tree) {
 1239  28
         for (int n = forClauses == null ? 0 : forClauses.size(); ; ) {
 1240  29
             if (--n < 0) {
 1241  0
                  log.error(tree.pos(), MsgSym.MESSAGE_JAVAFX_INDEXOF_NOT_FOUND, tree.fname);
 1242  0
                  break;
 1243  
             }
 1244  29
             JFXForExpressionInClause clause = forClauses.get(n);
 1245  29
             if (clause.getVar().getName() == tree.fname) {
 1246  28
                 tree.clause = clause;
 1247  28
                 clause.setIndexUsed(true);
 1248  28
                 break;
 1249  
             }
 1250  1
         }
 1251  28
         result = check(tree, syms.javafx_IntegerType, VAL,
 1252  
                 pkind, pt, pSequenceness);
 1253  28
     }
 1254  
 
 1255  
     @Override
 1256  
     public void visitSkip(JCSkip tree) {
 1257  0
         result = null;
 1258  0
     }
 1259  
 
 1260  
     public void visitBindExpression(JFXBindExpression tree) {
 1261  0
          Type owntype = attribTree(tree.getExpression(), env, VAL, pt);
 1262  0
          result = check(tree, owntype, pkind, pkind, pt, pSequenceness);
 1263  0
     }
 1264  
 
 1265  
     @Override
 1266  
     public void visitBlock(JCBlock tree) {
 1267  240
         if (env.info.scope.owner.kind == TYP) {
 1268  
             // Block is a static or instance initializer;
 1269  
             // let the owner of the environment be a freshly
 1270  
             // created BLOCK-method.
 1271  0
             JavafxEnv<JavafxAttrContext> localEnv = newLocalEnv(tree);
 1272  0
             if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
 1273  0
             memberEnter.memberEnter(tree.stats, localEnv);
 1274  0
             attribStats(tree.stats, localEnv);
 1275  0
         } else {
 1276  
             // Create a new local environment with a local scope.
 1277  240
             JavafxEnv<JavafxAttrContext> localEnv =
 1278  
                 env.dup(tree, env.info.dup(env.info.scope.dup()));
 1279  240
             localEnv.outer = env;
 1280  240
             memberEnter.memberEnter(tree.stats, localEnv);
 1281  240
             attribStats(tree.stats, localEnv);
 1282  240
             localEnv.info.scope.leave();
 1283  
         }
 1284  240
         result = null;
 1285  240
     }
 1286  
 
 1287  
     @Override
 1288  
     public void visitBlockExpression(JFXBlockExpression tree) {
 1289  
         // Create a new local environment with a local scope.
 1290  1926
         Scope localScope = new Scope(env.info.scope.owner);
 1291  1926
         localScope.next = env.info.scope;
 1292  1926
         JavafxEnv<JavafxAttrContext> localEnv =
 1293  
                 env.dup(tree, env.info.dup(localScope));
 1294  1926
         localEnv.outer = env;
 1295  
 
 1296  1926
         if (env.tree instanceof JFXFunctionDefinition &&
 1297  
                 env.enclClass.runMethod == env.tree) {
 1298  385
             env.enclClass.runBodyScope = localEnv.info.scope;
 1299  
         }
 1300  
         else
 1301  1541
             localEnv.info.scope.owner = new MethodSymbol(BLOCK, names.empty, null, env.enclClass.sym);
 1302  1926
         memberEnter.memberEnter(tree.stats, localEnv);
 1303  1926
         boolean canReturn = true;
 1304  1926
         boolean unreachableReported = false;
 1305  6402
         for (List<JCStatement> l = tree.stats; l.nonEmpty(); l = l.tail) {
 1306  4479
             if (! canReturn && ! unreachableReported) {
 1307  0
                 unreachableReported = true;
 1308  0
                 log.error(l.head.pos(), MsgSym.MESSAGE_UNREACHABLE_STMT);
 1309  
             }
 1310  4479
             Type stype = attribTree(l.head, localEnv,
 1311  
                     NIL, Type.noType, Sequenceness.DISALLOWED);
 1312  4476
             if (stype == syms.unreachableType)
 1313  213
                 canReturn = false;
 1314  
         }
 1315  1923
         Type owntype = null;
 1316  1923
         if (tree.value != null) {
 1317  1328
             if (! canReturn && ! unreachableReported)
 1318  0
                 log.error(tree.value.pos(), MsgSym.MESSAGE_UNREACHABLE_STMT);
 1319  1328
             owntype = attribExpr(tree.value, localEnv);
 1320  
         }
 1321  1923
         if (owntype == null) {
 1322  595
             JCStatement lastStat = tree.stats.last();
 1323  595
             if (lastStat != null) { 
 1324  469
                 if (lastStat.getTag() == JCTree.RETURN &&
 1325  
                         ((JCReturn)lastStat).expr != null) {
 1326  189
                     owntype = ((JCReturn)lastStat).expr.type;
 1327  
                 }
 1328  
                 
 1329  
             }
 1330  
             
 1331  595
             if (owntype == null) {
 1332  406
                 owntype = syms.voidType;
 1333  
             }
 1334  
         }
 1335  1923
         if (! canReturn)
 1336  213
             owntype = syms.unreachableType;
 1337  1923
         result = check(tree, owntype, VAL, pkind, pt, pSequenceness);
 1338  1923
         localEnv.info.scope.leave();
 1339  1923
     }
 1340  
 
 1341  
     @Override
 1342  
     public void visitDoLoop(JCDoWhileLoop tree) {
 1343  0
         attribStat(tree.body, env.dup(tree));
 1344  0
         attribExpr(tree.cond, env, syms.booleanType);
 1345  0
         result = null;
 1346  0
     }
 1347  
 
 1348  
     @Override
 1349  
     public void visitWhileLoop(JCWhileLoop tree) {
 1350  11
         attribExpr(tree.cond, env, syms.booleanType);
 1351  11
         attribStat(tree.body, env.dup(tree));
 1352  11
         result = null;
 1353  11
     }
 1354  
 
 1355  
     @Override
 1356  
     public void visitForLoop(JCForLoop tree) {
 1357  0
         assert false;
 1358  0
     }
 1359  
 
 1360  
     @Override
 1361  
     public void visitForeachLoop(JCEnhancedForLoop tree) {
 1362  0
         assert false;
 1363  0
     }
 1364  
 
 1365  
     @Override
 1366  
     public void visitLabelled(JCLabeledStatement tree) {
 1367  0
         assert false;
 1368  0
     }
 1369  
 
 1370  
     @Override
 1371  
     public void visitSwitch(JCSwitch tree) {
 1372  0
         assert false;
 1373  0
     }
 1374  
 
 1375  
     @Override
 1376  
     public void visitNewArray(JCNewArray tree) {
 1377  0
         assert false;
 1378  0
     }
 1379  
 
 1380  
     
 1381  
     @Override
 1382  
     public void visitNewClass(JCNewClass tree) {
 1383  0
         assert false : "remove me"; 
 1384  0
     }
 1385  
     
 1386  
     @Override
 1387  
     public void visitInstanciate(JFXInstanciate tree) {
 1388  641
         Type owntype = syms.errType;
 1389  
 
 1390  
         // The local environment of a class creation is
 1391  
         // a new environment nested in the current one.
 1392  641
         JavafxEnv<JavafxAttrContext> localEnv = newLocalEnv(tree);
 1393  
 
 1394  641
         List<JFXVar> vars = tree.getLocalvars();
 1395  641
         memberEnter.memberEnter(vars, localEnv);
 1396  649
         for (List<JFXVar> l = vars; l.nonEmpty(); l = l.tail)
 1397  8
             attribExpr(l.head, localEnv);
 1398  
 
 1399  
         // The anonymous inner class definition of the new expression,
 1400  
         // if one is defined by it.
 1401  641
         JFXClassDeclaration cdef = tree.getClassBody();
 1402  
 
 1403  
         // If enclosing class is given, attribute it, and
 1404  
         // complete class name to be fully qualified
 1405  641
         JCExpression clazz = tree.getIdentifier(); // Class field following new
 1406  
 
 1407  
         // Attribute clazz expression and store
 1408  
         // symbol + type back into the attributed tree.
 1409  641
         Type clazztype = chk.checkClassType(
 1410  
             clazz.pos(), attribType(clazz, env), true);
 1411  641
         chk.validate(clazz);
 1412  641
         if (!clazztype.tsym.isInterface() &&
 1413  
                    clazztype.getEnclosingType().tag == CLASS) {
 1414  
             // Check for the existence of an apropos outer instance
 1415  0
             rs.resolveImplicitThis(tree.pos(), env, clazztype);
 1416  
         }
 1417  
 
 1418  
         // Attribute constructor arguments.
 1419  641
         List<Type> argtypes = attribArgs(tree.getArgs(), localEnv);
 1420  
 
 1421  
         // If we have made no mistakes in the class type...
 1422  641
         if (clazztype.tag == CLASS) {
 1423  
             // Check that class is not abstract
 1424  641
             if (cdef == null &&
 1425  
                 (clazztype.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) {
 1426  0
                 log.error(tree.pos(), MsgSym.MESSAGE_ABSTRACT_CANNOT_BE_INSTANTIATED,
 1427  
                           clazztype.tsym);
 1428  641
             } else if (cdef != null && clazztype.tsym.isInterface()) {
 1429  
                 // Check that no constructor arguments are given to
 1430  
                 // anonymous classes implementing an interface
 1431  12
                 if (!argtypes.isEmpty())
 1432  0
                     log.error(tree.getArgs().head.pos(), MsgSym.MESSAGE_ANON_CLASS_IMPL_INTF_NO_ARGS);
 1433  
 
 1434  
 
 1435  
                 // Error recovery: pretend no arguments were supplied.
 1436  12
                 argtypes = List.nil();
 1437  
             }
 1438  
 
 1439  
             // Resolve the called constructor under the assumption
 1440  
             // that we are referring to a superclass instance of the
 1441  
             // current instance (JLS ???).
 1442  
             else {
 1443  629
                 localEnv.info.selectSuper = cdef != null;
 1444  629
                 localEnv.info.varArgs = false;
 1445  
 
 1446  629
                 if (! types.isJFXClass(clazztype.tsym))
 1447  83
                     tree.constructor = rs.resolveConstructor(
 1448  
                         tree.pos(), localEnv, clazztype, argtypes, null);
 1449  
                 /**
 1450  
                 List<Type> emptyTypeargtypes = List.<Type>nil();
 1451  
                 tree.constructor = rs.resolveConstructor(
 1452  
                     tree.pos(), localEnv, clazztype, argtypes, emptyTypeargtypes);
 1453  
                 Type ctorType = checkMethod(clazztype,
 1454  
                                             tree.constructor,
 1455  
                                             localEnv,
 1456  
                                             tree.getArguments(),
 1457  
                                             argtypes,
 1458  
                                             emptyTypeargtypes,
 1459  
                                             localEnv.info.varArgs);
 1460  
                 if (localEnv.info.varArgs)
 1461  
                     assert ctorType.isErroneous();
 1462  
                  * ***/
 1463  
 
 1464  
             }
 1465  
 
 1466  641
             if (cdef != null) {
 1467  
                 // We are seeing an anonymous class instance creation.
 1468  
                 // In this case, the class instance creation
 1469  
                 // expression
 1470  
                 //
 1471  
                 //    E.new <typeargs1>C<typargs2>(args) { ... }
 1472  
                 //
 1473  
                 // is represented internally as
 1474  
                 //
 1475  
                 //    E . new <typeargs1>C<typargs2>(args) ( class <empty-name> { ... } )  .
 1476  
                 //
 1477  
                 // This expression is then *transformed* as follows:
 1478  
                 //
 1479  
                 // (1) add a STATIC flag to the class definition
 1480  
                 //     if the current environment is static
 1481  
                 // (2) add an extends or implements clause
 1482  
                 // (3) add a constructor.
 1483  
                 //
 1484  
                 // For instance, if C is a class, and ET is the type of E,
 1485  
                 // the expression
 1486  
                 //
 1487  
                 //    E.new <typeargs1>C<typargs2>(args) { ... }
 1488  
                 //
 1489  
                 // is translated to (where X is a fresh name and typarams is the
 1490  
                 // parameter list of the super constructor):
 1491  
                 //
 1492  
                 //   new <typeargs1>X(<*nullchk*>E, args) where
 1493  
                 //     X extends C<typargs2> {
 1494  
                 //       <typarams> X(ET e, args) {
 1495  
                 //         e.<typeargs1>super(args)
 1496  
                 //       }
 1497  
                 //       ...
 1498  
                 //     }
 1499  
 //               if (JavafxResolve.isStatic(env)) cdef.mods.flags |= STATIC;
 1500  
                 
 1501  
                 // always need to be static, because they will have generated static members
 1502  26
                 cdef.mods.flags |= STATIC;
 1503  
 
 1504  
 //              now handled in class processing                
 1505  
 //                if (clazztype.tsym.isInterface()) {
 1506  
 //                    cdef.implementing = List.of(clazz);
 1507  
 //                } else {
 1508  
 //                    cdef.extending = clazz;
 1509  
 //                }
 1510  
 
 1511  26
                 if (cdef.sym == null)
 1512  0
                     enter.classEnter(cdef, env);
 1513  
                 
 1514  26
                  attribStat(cdef, localEnv);                 
 1515  26
                  attribClass(cdef.pos(), null, cdef.sym);
 1516  
 
 1517  
                 // Reassign clazztype and recompute constructor.
 1518  26
                 clazztype = cdef.sym.type;
 1519  26
                 Symbol sym = rs.resolveConstructor(
 1520  
                     tree.pos(), localEnv, clazztype, argtypes,
 1521  
                     List.<Type>nil(), true, false);
 1522  
                 
 1523  26
                 tree.constructor = sym;
 1524  
             }
 1525  
 
 1526  
 //         if (tree.constructor != null && tree.constructor.kind == MTH)
 1527  641
               owntype = clazz.type;  // this give declared type, where clazztype would give anon type
 1528  
         }
 1529  
 
 1530  641
         for (JFXObjectLiteralPart localPt : tree.getParts()) {
 1531  736
             JFXObjectLiteralPart part = (JFXObjectLiteralPart)localPt;
 1532  736
             Symbol memberSym = rs.findIdentInType(env, clazz.type, part.name, VAR);
 1533  736
             memberSym = rs.access(memberSym, localPt.pos(), clazz.type, part.name, true);
 1534  736
             memberSym.complete();
 1535  736
             attribExpr(part.getExpression(), localEnv, memberSym.type);
 1536  736
             part.type = memberSym.type;
 1537  736
             part.sym = memberSym;
 1538  736
         }
 1539  
 
 1540  641
         result = check(tree, owntype, VAL, pkind, pt, pSequenceness);
 1541  641
         localEnv.info.scope.leave();
 1542  641
     }
 1543  
 
 1544  
     /** Make an attributed null check tree.
 1545  
      */
 1546  
     public JCExpression makeNullCheck(JCExpression arg) {
 1547  
         // optimization: X.this is never null; skip null check
 1548  0
         Name name = TreeInfo.name(arg);
 1549  0
         if (name == names._this || name == names._super) return arg;
 1550  
 
 1551  0
         int optag = JCTree.NULLCHK;
 1552  0
         JCUnary tree = make.at(arg.pos).Unary(optag, arg);
 1553  0
         tree.operator = syms.nullcheck;
 1554  0
         tree.type = arg.type;
 1555  0
         return tree;
 1556  
     }
 1557  
 
 1558  
     @Override
 1559  
     public void visitClassDef(JCClassDecl tree) {
 1560  0
         assert false : "Should never reach here";
 1561  0
     }
 1562  
 
 1563  
     @Override
 1564  
     public void visitMethodDef(JCMethodDecl tree) {
 1565  0
         assert false : "Should never reach here";
 1566  0
     }
 1567  
     
 1568  
     @Override
 1569  
     public void visitFunctionValue(JFXFunctionValue tree) {
 1570  174
         Scope enclScope = JavafxEnter.enterScope(env);
 1571  174
         JFXFunctionDefinition def = new JFXFunctionDefinition(make.Modifiers(Flags.SYNTHETIC), defs.lambdaName, tree);
 1572  174
         tree.definition = def;
 1573  174
         MethodSymbol m = new MethodSymbol(SYNTHETIC, def.name, null, env.enclClass.sym);
 1574  
         // m.flags_field = chk.checkFlags(def.pos(), def.mods.flags, m, def);
 1575  174
         def.sym = m;
 1576  174
         finishOperationDefinition(def, env);
 1577  174
         result = tree.type = syms.makeFunctionType((MethodType) def.type);
 1578  174
     }
 1579  
     
 1580  
     @Override
 1581  
     public void visitFunctionDefinition(JFXFunctionDefinition tree) {
 1582  1307
         MethodSymbol m = tree.sym;
 1583  1307
         m.complete();
 1584  1304
     }
 1585  
 
 1586  
     /** Search super-clases for a parameter type in a matching method.
 1587  
      * The idea is that when a formal parameter isn't specified in a class
 1588  
      * function, see if there is a method with the same name in a superclass,
 1589  
      * and use that method's parameter type.  If there are multiple methods
 1590  
      * in super-classes that all have the same name and argument count,
 1591  
      * the parameter types have to be the same in all of them.
 1592  
      * @param csym Class to search.
 1593  
      * @param name Name of matching methods.
 1594  
      * @param paramCount Number of parameters of matching methods.
 1595  
      * @param paramNum The parameter number we're concerned about,
 1596  
      *    or -1 if we're searching for the return type.
 1597  
      * @return The found type.  Null is we found no match.
 1598  
      *   Notype if we found an ambiguity.
 1599  
      */
 1600  
     Type searchSupersForParamType (ClassSymbol c, Name name, int paramCount, int paramNum) {
 1601  1162
         Type found = null;
 1602  
         
 1603  1162
         for (Scope.Entry e = c.members().lookup(name);
 1604  1570
                  e.scope != null;
 1605  408
                  e = e.next()) {
 1606  408
             if ((e.sym.kind & MTH) == 0 ||
 1607  
                         (e.sym.flags_field & (STATIC|SYNTHETIC)) != 0)
 1608  66
                 continue;
 1609  342
             Type mt = types.memberType(c.type, e.sym);
 1610  342
             if (mt == null)
 1611  315
                 continue;
 1612  27
             List<Type> formals = mt.getParameterTypes();
 1613  27
             if (formals.size() != paramCount)
 1614  20
                 continue;
 1615  7
             Type t = paramNum >= 0 ? formals.get(paramNum) : mt.getReturnType();
 1616  7
             if (t == Type.noType) 
 1617  0
                 return t;
 1618  7
             if (found == null)
 1619  7
                 found = t;
 1620  0
             else if (t != null && found != t)
 1621  0
                 return Type.noType;
 1622  
         }
 1623  
  
 1624  1162
         Type st = types.supertype(c.type);
 1625  1162
         if (st.tag == CLASS) {
 1626  612
             Type t = searchSupersForParamType((ClassSymbol)st.tsym, name, paramCount, paramNum);
 1627  612
             if (t == Type.noType) 
 1628  0
                 return t;
 1629  612
             if (found == null)
 1630  606
                 found = t;
 1631  6
             else if (t != null && found != t)
 1632  0
                 return Type.noType;
 1633  
         }
 1634  1162
         for (List<Type> l = types.interfaces(c.type);
 1635  1218
                      l.nonEmpty();
 1636  56
                      l = l.tail) {
 1637  56
             Type t = searchSupersForParamType((ClassSymbol)l.head.tsym, name, paramCount, paramNum);
 1638  56
             if (t == Type.noType) 
 1639  0
                 return t;
 1640  56
             if (found == null)
 1641  53
                 found = t;
 1642  3
             else if (t != null && found != t)
 1643  0
                 return Type.noType;
 1644  
         }
 1645  1162
         return found;
 1646  
     }
 1647  
     
 1648  
     public void finishOperationDefinition(JFXFunctionDefinition tree, JavafxEnv<JavafxAttrContext> env) {
 1649  1240
         MethodSymbol m = tree.sym;
 1650  1240
         JFXFunctionValue opVal = tree.operation;
 1651  1240
         JavafxEnv<JavafxAttrContext> localEnv = memberEnter.methodEnv(tree, env);
 1652  
         Type returnType;
 1653  
         // Create a new environment with local scope
 1654  
         // for attributing the method.
 1655  
 
 1656  1240
         JavafxEnv<JavafxAttrContext> lintEnv = env;
 1657  1383
         while (lintEnv.info.lint == null)
 1658  143
             lintEnv = lintEnv.next;
 1659  
 
 1660  1240
         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
 1661  1240
         Lint lint = lintEnv.info.lint.augment(m.attributes_field, m.flags());
 1662  1240
         Lint prevLint = chk.setLint(lint);
 1663  
         try {
 1664  1240
             chk.checkDeprecatedAnnotation(tree.pos(), m);
 1665  
 
 1666  1240
             localEnv.info.lint = lint;
 1667  
 
 1668  1240
             ClassSymbol owner = env.enclClass.sym;
 1669  1240
             if ((owner.flags() & ANNOTATION) != 0 &&
 1670  
                 tree.operation.funParams.nonEmpty())
 1671  0
                 log.error(tree.operation.funParams.head.pos(),
 1672  
                           MsgSym.MESSAGE_INTF_ANNOTATION_MEMBERS_CANNOT_HAVE_PARAMS);
 1673  
 
 1674  
             // Attribute all value parameters.
 1675  1240
             ListBuffer<Type> argbuf = new ListBuffer<Type>();
 1676  1240
             List<Type> pparam = null;
 1677  1240
             MethodType mtype = null;
 1678  1240
             if (pt.tag == TypeTags.METHOD || pt instanceof FunctionType) {
 1679  23
                 mtype = pt.asMethodType();
 1680  23
                 pparam = mtype.getParameterTypes();
 1681  
             }
 1682  1240
             int paramNum = 0;
 1683  1240
             List<JFXVar> params = tree.getParameters();
 1684  1240
             int paramCount = params.size();
 1685  2341
             for (List<JFXVar> l = params; l.nonEmpty(); l = l.tail) {
 1686  1101
                 JFXVar pvar = l.head;
 1687  
                 Type type;
 1688  1101
                 if (pparam != null && pparam.nonEmpty()) {
 1689  9
                     type = pparam.head;
 1690  9
                     pparam = pparam.tail;
 1691  
                 }
 1692  
                 else {
 1693  1092
                     type = syms.objectType;
 1694  1092
                     if (pvar.getJFXType() instanceof JFXTypeUnknown) {
 1695  13
                         Type t = searchSupersForParamType (owner, m.name, paramCount, paramNum);
 1696  13
                         if (t == Type.noType)
 1697  0
                             log.warning(pvar.pos(), MsgSym.MESSAGE_JAVAFX_AMBIGUOUS_PARAM_TYPE_FROM_SUPER);
 1698  13
                         else if (t != null)
 1699  0
                             type = t;
 1700  
                     }
 1701  
                 }
 1702  1101
                 pvar.type = type;
 1703  1101
                 type = attribVar(pvar, localEnv);
 1704  1101
                 argbuf.append(type);
 1705  1101
                 paramNum++;
 1706  
             }
 1707  1240
             returnType = syms.unknownType;
 1708  1240
             if (opVal.getJFXReturnType().getTag() != JavafxTag.TYPEUNKNOWN)
 1709  739
                 returnType = attribType(tree.getJFXReturnType(), localEnv);
 1710  501
             else if (mtype != null) {
 1711  20
                 Type mrtype = mtype.getReturnType();
 1712  20
                 if (mrtype != null && mrtype.tag != TypeTags.NONE)
 1713  20
                     returnType = mrtype;
 1714  20
             } else {
 1715  
                 // If we made use of the parameter types to select a matching
 1716  
                 // method, we could presumably get a non-ambiguoys return type.
 1717  
                 // But this is pretty close, in practice.
 1718  481
                 Type t = searchSupersForParamType (owner, m.name, paramCount, -1);
 1719  481
                 if (t == Type.noType)
 1720  0
                     log.warning(tree.pos(), MsgSym.MESSAGE_JAVAFX_AMBIGUOUS_RETURN_TYPE_FROM_SUPER);
 1721  481
                 else if (t != null)
 1722  7
                     returnType = t;
 1723  
             }
 1724  1240
             if (returnType == syms.javafx_java_lang_VoidType)
 1725  0
                 returnType = syms.voidType;
 1726  1240
             mtype = new MethodType(argbuf.toList(),
 1727  
                                     returnType, // may be unknownType
 1728  
                                     List.<Type>nil(),
 1729  
                                     syms.methodClass);
 1730  1240
             m.type = mtype;
 1731  
 
 1732  1240
             if (tree.getBodyExpression() == null) {
 1733  
                 // Empty bodies are only allowed for
 1734  
                 // abstract, native, or interface methods, or for methods
 1735  
                 // in a retrofit signature class.
 1736  10
                 if ((owner.flags() & INTERFACE) == 0 &&
 1737  
                     (tree.mods.flags & (ABSTRACT | NATIVE)) == 0 &&
 1738  
                     !relax)
 1739  0
                     log.error(tree.pos(), MsgSym.MESSAGE_MISSING_METH_BODY_OR_DECL_ABSTRACT);
 1740  10
                 else if (returnType == syms.unknownType)
 1741  
                     // no body, can't infer, assume Any
 1742  
                     // FIXME Should this be Void or an error?
 1743  0
                     returnType = syms.javafx_AnyType;
 1744  1230
             } else if ((owner.flags() & INTERFACE) != 0) {
 1745  0
                 log.error(tree.getBodyExpression().pos(), MsgSym.MESSAGE_INTF_METH_CANNOT_HAVE_BODY);
 1746  1230
             } else if ((tree.mods.flags & ABSTRACT) != 0) {
 1747  0
                 log.error(tree.pos(), MsgSym.MESSAGE_ABSTRACT_METH_CANNOT_HAVE_BODY);
 1748  1230
             } else if ((tree.mods.flags & NATIVE) != 0) {
 1749  0
                 log.error(tree.pos(), MsgSym.MESSAGE_NATIVE_METH_CANNOT_HAVE_BODY);
 1750  
             } else {
 1751  1230
                 JFXBlockExpression body = opVal.getBodyExpression();
 1752  1230
                 if (body.value == null && returnType == syms.unknownType) {
 1753  172
                     JCStatement last = body.stats.last();
 1754  172
                     if (last instanceof JCReturn) {
 1755  9
                         ListBuffer<JCStatement> rstats =
 1756  
                                 new ListBuffer<JCStatement>();
 1757  9
                         for (List<JCStatement> l = body.stats;
 1758  14
                              l.tail.tail != null;
 1759  5
                              l = l.tail) {
 1760  5
                             rstats.append(l.head);
 1761  
                         }
 1762  9
                         body.stats = rstats.toList();
 1763  9
                         body.value = ((JCReturn) last).expr;  
 1764  
                     }
 1765  
                 }
 1766  
                 // Attribute method bodyExpression
 1767  1230
                 Type typeToCheck = returnType;
 1768  1230
                 if(tree.name == defs.runMethodName) {
 1769  385
                     typeToCheck = Type.noType;
 1770  
                 }
 1771  845
                 else if (returnType == syms.voidType) {
 1772  94
                     typeToCheck = Type.noType;
 1773  
                 }
 1774  
                 
 1775  1230
                 Type bodyType = attribExpr(body, localEnv, typeToCheck); // Special hading for the JavafxDefs.runMethodName method. Its body is empty at this point.
 1776  1227
                 if (body.value == null) {
 1777  505
                     if (returnType == syms.unknownType)
 1778  163
                         returnType = syms.javafx_VoidType; //TODO: this is wrong if there is a return statement
 1779  
                 } else {
 1780  722
                     if (returnType == syms.unknownType)
 1781  311
                         returnType = bodyType == syms.unreachableType ? syms.javafx_VoidType : bodyType;
 1782  411
                     else if (returnType != syms.javafx_VoidType && tree.getName() != defs.runMethodName)
 1783  98
                         chk.checkType(tree.pos(), bodyType, returnType, Sequenceness.DISALLOWED);       
 1784  
                 }
 1785  
             }
 1786  1237
             localEnv.info.scope.leave();
 1787  
 
 1788  1237
             mtype.restype = returnType;
 1789  1237
             result = tree.type = mtype;
 1790  
 
 1791  
             // If we override any other methods, check that we do so properly.
 1792  
             // JLS ???
 1793  1237
             if (m.owner instanceof ClassSymbol) {
 1794  
                 // Fix primitive/number types so overridden Java methods will have the correct types.
 1795  1237
                 fixOverride(tree, m);
 1796  1237
                 chk.checkOverride(tree, m);
 1797  
             }
 1798  
         }
 1799  
         finally {
 1800  1240
             chk.setLint(prevLint);
 1801  1240
             log.useSource(prev);
 1802  1237
         }
 1803  
 
 1804  
         // mark the method varargs, if necessary
 1805  
         // if (isVarArgs) m.flags_field |= Flags.VARARGS;
 1806  
 
 1807  
         // Set the inferred types in the MethodType.argtypes and in correct symbols in MethodSymbol
 1808  1237
         List<VarSymbol> paramSyms = List.<VarSymbol>nil();
 1809  1237
         List<Type> paramTypes = List.<Type>nil();
 1810  1237
         for (JFXVar var : tree.getParameters()) {
 1811  1098
             paramSyms = paramSyms.append(var.sym);
 1812  1098
             paramTypes = paramTypes.append(var.type);
 1813  
         }
 1814  
         
 1815  1237
         m.params = paramSyms;
 1816  1237
         if (m.type != null && m.type instanceof MethodType) {
 1817  1237
            ((MethodType)m.type).argtypes = paramTypes;
 1818  
         }
 1819  1237
     }
 1820  
 
 1821  
     @Override
 1822  
     public void visitSynchronized(JCSynchronized tree) {
 1823  0
         chk.checkRefType(tree.pos(), attribExpr(tree.lock, env));
 1824  0
         attribStat(tree.body, env);
 1825  0
         result = null;
 1826  0
     }
 1827  
 
 1828  
     @Override
 1829  
     public void visitTry(JCTry tree) {
 1830  
         // Attribute body
 1831  24
         attribStat(tree.body, env.dup(tree, env.info.dup()));
 1832  
 
 1833  
         // Attribute catch clauses
 1834  59
         for (List<JCCatch> l = tree.catchers; l.nonEmpty(); l = l.tail) {
 1835  35
             JCCatch c = l.head;
 1836  35
             JavafxEnv<JavafxAttrContext> catchEnv =
 1837  
                 env.dup(c, env.info.dup(env.info.scope.dup()));
 1838  35
             memberEnter.memberEnter(c.param, env);
 1839  35
             if (c.param.type == null)
 1840  35
                 c.param.sym.type = c.param.type = syms.throwableType;
 1841  35
             Type ctype = attribStat((JFXVar) c.param, catchEnv);
 1842  35
             if (c.param.type.tsym.kind == Kinds.VAR) {
 1843  0
                 c.param.sym.setData(ElementKind.EXCEPTION_PARAMETER);
 1844  
             }
 1845  
 //uses vartype            
 1846  
 //            chk.checkType(c.param.vartype.pos(),
 1847  
 //                          chk.checkClassType(c.param.vartype.pos(), ctype),
 1848  
 //                          syms.throwableType);
 1849  35
             attribStat(c.body, catchEnv);
 1850  35
             catchEnv.info.scope.leave();
 1851  
         }
 1852  
 
 1853  
         // Attribute finalizer
 1854  24
         if (tree.finalizer != null) attribStat(tree.finalizer, env);
 1855  24
         result = null;
 1856  24
     }
 1857  
 
 1858  
     @Override
 1859  
     public void visitConditional(JCConditional tree) {
 1860  466
         attribExpr(tree.cond, env, syms.booleanType);
 1861  466
         attribTree(tree.truepart, env, VAL, pt, pSequenceness);
 1862  
         Type falsepartType;
 1863  466
         if (tree.falsepart == null) {
 1864  164
             falsepartType = syms.voidType;
 1865  
         } else {
 1866  302
             falsepartType = attribTree(tree.falsepart, env, VAL, pt, pSequenceness);
 1867  
             {   //TODO: ...
 1868  
                 // A kludge, which can go away if we change things so that
 1869  
                 // the compiler and runtime accepts null and [] equivalently.
 1870  
                 // Well, actually, look at JFXC-925.
 1871  
                 // Also, in a bind context, we need to know th etype of null
 1872  302
                 if (tree.truepart instanceof JFXSequenceEmpty
 1873  
                         || tree.truepart.type.tag == BOT)
 1874  3
                     tree.truepart.type = falsepartType;
 1875  299
                 else if (tree.falsepart instanceof JFXSequenceEmpty
 1876  
                         || falsepartType.tag == BOT)
 1877  7
                     falsepartType = tree.falsepart.type = tree.truepart.type;
 1878  
             }
 1879  
         }
 1880  466
         result = check(tree,
 1881  
                        capture(condType(tree.pos(), tree.cond.type,
 1882  
                                         tree.truepart.type, falsepartType)),
 1883  
                        VAL, pkind, pt, pSequenceness);
 1884  466
     }
 1885  
     //where
 1886  
         /** Compute the type of a conditional expression, after
 1887  
          *  checking that it exists. See Spec 15.25.
 1888  
          *
 1889  
          *  @param pos      The source position to be used for
 1890  
          *                  error diagnostics.
 1891  
          *  @param condtype The type of the expression's condition.
 1892  
          *  @param type1 The type of the expression's then-part.
 1893  
          *  @param type2 The type of the expression's else-part.
 1894  
          */
 1895  
         private Type condType(DiagnosticPosition pos,
 1896  
                               Type condtype,
 1897  
                               Type thentype,
 1898  
                               Type elsetype) {
 1899  466
             Type ctype = unionType(pos, thentype, elsetype);
 1900  
 
 1901  
             // If condition and both arms are numeric constants,
 1902  
             // evaluate at compile-time.
 1903  466
             return ((condtype.constValue() != null) &&
 1904  
                     (thentype.constValue() != null) &&
 1905  
                     (elsetype.constValue() != null))
 1906  
                 ? cfolder.coerce(condtype.isTrue()?thentype:elsetype, ctype)
 1907  
                 : ctype;
 1908  
         }
 1909  
         /** Compute the type of a conditional expression, after
 1910  
          *  checking that it exists.  Does not take into
 1911  
          *  account the special case where condition and both arms
 1912  
          *  are constants.
 1913  
          *
 1914  
          *  @param pos      The source position to be used for error
 1915  
          *                  diagnostics.
 1916  
          *  @param condtype The type of the expression's condition.
 1917  
          *  @param type1 The type of the expression's then-part.
 1918  
          *  @param type2 The type of the expression's else-part.
 1919  
          */
 1920  
         private Type unionType(DiagnosticPosition pos,
 1921  
                                Type type1, Type type2) {
 1922  1582
             if (type1 == syms.unreachableType)
 1923  28
                 return type2;
 1924  1554
             if (type2 == syms.unreachableType)
 1925  3
                 return type1;
 1926  1551
             if (type1 == type2)
 1927  1256
                 return type1;
 1928  295
             if (type1.tag == VOID || type2.tag == VOID)
 1929  233
                 return syms.voidType;
 1930  
 
 1931  62
             boolean isSequence1 = types.isSequence(type1);
 1932  62
             boolean isSequence2 = types.isSequence(type2);
 1933  62
             if (isSequence1 || isSequence2) {
 1934  19
                 if (isSequence1)
 1935  16
                     type1 = types.elementType(type1);
 1936  19
                 if (isSequence2)
 1937  19
                     type2 = types.elementType(type2);
 1938  19
                 Type union = unionType(pos, type1, type2);
 1939  19
                 return union.tag == ERROR ? union : types.sequenceType(union);
 1940  
             }
 1941  
             // If same type, that is the result
 1942  43
             if (types.isSameType(type1, type2))
 1943  5
                 return type1.baseType();
 1944  
 
 1945  38
             Type thenUnboxed = (!allowBoxing || type1.isPrimitive())
 1946  
                 ? type1 : types.unboxedType(type1);
 1947  38
             Type elseUnboxed = (!allowBoxing || type2.isPrimitive())
 1948  
                 ? type2 : types.unboxedType(type2);
 1949  
 
 1950  
             // Otherwise, if both arms can be converted to a numeric
 1951  
             // type, return the least numeric type that fits both arms
 1952  
             // (i.e. return larger of the two, or return int if one
 1953  
             // arm is short, the other is char).
 1954  38
             if (thenUnboxed.isPrimitive() && elseUnboxed.isPrimitive()) {
 1955  
                 // If one arm has an integer subrange type (i.e., byte,
 1956  
                 // short, or char), and the other is an integer constant
 1957  
                 // that fits into the subrange, return the subrange type.
 1958  4
                 if (thenUnboxed.tag < INT && elseUnboxed.tag == INT &&
 1959  
                     types.isAssignable(elseUnboxed, thenUnboxed))
 1960  0
                     return thenUnboxed.baseType();
 1961  4
                 if (elseUnboxed.tag < INT && thenUnboxed.tag == INT &&
 1962  
                     types.isAssignable(thenUnboxed, elseUnboxed))
 1963  0
                     return elseUnboxed.baseType();
 1964  
 
 1965  28
                 for (int i = BYTE; i < VOID; i++) {
 1966  28
                     Type candidate = syms.typeOfTag[i];
 1967  28
                     if (types.isSubtype(thenUnboxed, candidate) &&
 1968  
                         types.isSubtype(elseUnboxed, candidate))
 1969  4
                         return candidate;
 1970  
                 }
 1971  
             }
 1972  
 
 1973  
             // Those were all the cases that could result in a primitive
 1974  34
             if (allowBoxing) {
 1975  34
                 type1 = syms.boxIfNeeded(type1);
 1976  34
                 type2 = syms.boxIfNeeded(type2);
 1977  
             }
 1978  
 
 1979  34
             if (types.isSubtype(type1, type2))
 1980  9
                 return type2.baseType();
 1981  25
             if (types.isSubtype(type2, type1))
 1982  2
                 return type1.baseType();
 1983  
 
 1984  23
             if (!allowBoxing) {
 1985  0
                 log.error(pos, MsgSym.MESSAGE_NEITHER_CONDITIONAL_SUBTYPE,
 1986  
                           type1, type2);
 1987  0
                 return type1.baseType();
 1988  
             }
 1989  
 
 1990  
             // both are known to be reference types.  The result is
 1991  
             // lub(type1,type2). This cannot fail, as it will
 1992  
             // always be possible to infer "Object" if nothing better.
 1993  23
             return types.lub(type1.baseType(), type2.baseType());
 1994  
         }
 1995  
 
 1996  
     @Override
 1997  
     public void visitIf(JCIf tree) {
 1998  0
         attribExpr(tree.cond, env, syms.booleanType);
 1999  0
         attribStat(tree.thenpart, env);
 2000  0
         if (tree.elsepart != null)
 2001  0
             attribStat(tree.elsepart, env);
 2002  0
         chk.checkEmptyIf(tree);
 2003  0
         result = null;
 2004  0
     }
 2005  
 
 2006  
     @Override
 2007  
     public void visitExec(JCExpressionStatement tree) {
 2008  3041
         Type type = attribExpr(tree.expr, env);
 2009  3041
         result = type == syms.unreachableType ? type : null;
 2010  3041
     }
 2011  
 
 2012  
     @Override
 2013  
     public void visitBreak(JCBreak tree) {
 2014  5
         tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env);
 2015  5
         result = null;
 2016  5
     }
 2017  
 
 2018  
     @Override
 2019  
     public void visitContinue(JCContinue tree) {
 2020  3
         tree.target = findJumpTarget(tree.pos(), tree.getTag(), tree.label, env);
 2021  3
         result = null;
 2022  3
     }
 2023  
     //where
 2024  
         /** Return the target of a break or continue statement, if it exists,
 2025  
          *  report an error if not.
 2026  
          *  Note: The target of a labelled break or continue is the
 2027  
          *  (non-labelled) statement tree referred to by the label,
 2028  
          *  not the tree representing the labelled statement itself.
 2029  
          *
 2030  
          *  @param pos     The position to be used for error diagnostics
 2031  
          *  @param tag     The tag of the jump statement. This is either
 2032  
          *                 Tree.BREAK or Tree.CONTINUE.
 2033  
          *  @param label   The label of the jump statement, or null if no
 2034  
          *                 label is given.
 2035  
          *  @param env     The environment current at the jump statement.
 2036  
          */
 2037  
         private JCTree findJumpTarget(DiagnosticPosition pos,
 2038  
                                     int tag,
 2039  
                                     Name label,
 2040  
                                     JavafxEnv<JavafxAttrContext> env) {
 2041  
             // Search environments outwards from the point of jump.
 2042  8
             JavafxEnv<JavafxAttrContext> env1 = env;
 2043  
             LOOP:
 2044  23
             while (env1 != null) {
 2045  23
                 switch (env1.tree.getTag()) {
 2046  
                 case JCTree.LABELLED:
 2047  0
                     JCLabeledStatement labelled = (JCLabeledStatement)env1.tree;
 2048  0
                     if (label == labelled.label) {
 2049  
                         // If jump is a continue, check that target is a loop.
 2050  0
                         if (tag == JCTree.CONTINUE) {
 2051  0
                             if (labelled.body.getTag() != JCTree.DOLOOP &&
 2052  
                                 labelled.body.getTag() != JCTree.WHILELOOP)
 2053  0
                                 log.error(pos, MsgSym.MESSAGE_NOT_LOOP_LABEL, label);
 2054  
                             // Found labelled statement target, now go inwards
 2055  
                             // to next non-labelled tree.
 2056  0
                             return TreeInfo.referencedStatement(labelled);
 2057  
                         } else {
 2058  0
                             return labelled;
 2059  
                         }
 2060  
                     }
 2061  
                     break;
 2062  
                 case JCTree.WHILELOOP:
 2063  
                 case JavafxTag.FOR_EXPRESSION:
 2064  8
                     if (label == null) return env1.tree;
 2065  
                     break;
 2066  
                 case JCTree.SWITCH:
 2067  0
                     if (label == null && tag == JCTree.BREAK) return env1.tree;
 2068  
                     break;
 2069  
                 case JCTree.METHODDEF:
 2070  
                 case JCTree.CLASSDEF:
 2071  0
                     break LOOP;
 2072  
                 default:
 2073  
                 }
 2074  15
                 env1 = env1.next;
 2075  
             }
 2076  0
             if (label != null)
 2077  0
                 log.error(pos, MsgSym.MESSAGE_UNDEF_LABEL, label);
 2078  0
             else if (tag == JCTree.CONTINUE)
 2079  0
                 log.error(pos, MsgSym.MESSAGE_CONT_OUTSIDE_LOOP);
 2080  
             else
 2081  0
                 log.error(pos, MsgSym.MESSAGE_BREAK_OUTSIDE_SWITCH_LOOP);
 2082  0
             return null;
 2083  
         }
 2084  
 
 2085  
     @Override
 2086  
     public void visitReturn(JCReturn tree) {
 2087  190
         if (env.enclMethod == null) {
 2088  0
             log.error(tree.pos(), MsgSym.MESSAGE_RETURN_OUTSIDE_METH);
 2089  
 
 2090  
         } else {
 2091  
             // Attribute return expression, if it exists, and check that
 2092  
             // it conforms to result type of enclosing method.
 2093  190
             Symbol m = env.enclMethod.sym;
 2094  190
             Type rtype = m.type.getReturnType();
 2095  190
             if (rtype == null)
 2096  0
                 log.error(tree.pos(), MsgSym.MESSAGE_JAVAFX_CANNOT_INFER_RETURN_TYPE);
 2097  190
             else if (rtype.tag == VOID) {
 2098  1
                     if (tree.expr != null)
 2099  0
                         log.error(tree.expr.pos(),
 2100  
                                   MsgSym.MESSAGE_CANNOT_RET_VAL_FROM_METH_DECL_VOID);
 2101  189
                 } else if (tree.expr == null) {
 2102  0
                     log.error(tree.pos(), MsgSym.MESSAGE_MISSING_RET_VAL);
 2103  
                 } else {
 2104  189
                     attribExpr(tree.expr, env, m.type.getReturnType());
 2105  
                 }
 2106  
         }
 2107  
 
 2108  190
         result = syms.unreachableType;
 2109  190
     }
 2110  
 
 2111  
     @Override
 2112  
     public void visitThrow(JCThrow tree) {
 2113  24
         attribExpr(tree.expr, env, syms.throwableType);
 2114  24
         result = syms.unreachableType;
 2115  24
     }
 2116  
 
 2117  
     @Override
 2118  
     public void visitAssert(JCAssert tree) {
 2119  0
         attribExpr(tree.cond, env, syms.booleanType);
 2120  0
         if (tree.detail != null) {
 2121  0
             chk.checkNonVoid(tree.detail.pos(), attribExpr(tree.detail, env));
 2122  
         }
 2123  0
         result = null;
 2124  0
     }
 2125  
     
 2126  
     void searchParameterTypes (JCExpression meth, Type[] paramTypes) {
 2127  
         // FUTURE: Search for matching overloaded methods/functions that
 2128  
         // would be a match for meth, and number of arguments==paramTypes.length.
 2129  
         // If all the candidates have the same type for parameter # i,
 2130  
         // set paramTypes[i] to that type.
 2131  
         // Otherwise, leave paramTypes[i]==null.
 2132  3327
     }
 2133  
 
 2134  
     @Override
 2135  
     public void visitApply(JCMethodInvocation tree) {
 2136  
         // The local environment of a method application is
 2137  
         // a new environment nested in the current one.
 2138  3327
         JavafxEnv<JavafxAttrContext> localEnv = env.dup(tree, env.info.dup());
 2139  
 
 2140  
         // The types of the actual method type arguments.
 2141  
         List<Type> typeargtypes;
 2142  
 
 2143  3327
         Name methName = JavafxTreeInfo.name(tree.meth);
 2144  
         
 2145  3327
         int argcount = tree.args.size();
 2146  
         
 2147  3327
         Type[] paramTypes = new Type[argcount];
 2148  3327
         searchParameterTypes(tree.meth, paramTypes);
 2149  
         
 2150  3327
         ListBuffer<Type> argtypebuffer = new ListBuffer<Type>();
 2151  3327
         int i = 0;
 2152  6950
         for (List<JCExpression> l = tree.args; l.nonEmpty(); l = l.tail, i++) {
 2153  3623
             Type argtype = paramTypes[i];
 2154  3623
             if (argtype != null)
 2155  0
                 attribExpr(l.head, env, argtype);
 2156  
             else
 2157  3623
                 argtype = chk.checkNonVoid(l.head.pos(),
 2158  
                         types.upperBound(attribTree(l.head, env, VAL, Infer.anyPoly)));
 2159  3623
             argtypebuffer.append(argtype);
 2160  
         }
 2161  3327
         List<Type> argtypes = argtypebuffer.toList();
 2162  
         
 2163  3327
         typeargtypes = attribTypes(tree.typeargs, localEnv);
 2164  
 
 2165  
             // ... and attribute the method using as a prototype a methodtype
 2166  
             // whose formal argument types is exactly the list of actual
 2167  
             // arguments (this will also set the method symbol).
 2168  3327
             Type mpt = new MethodType(argtypes, pt, null, syms.methodClass);
 2169  3327
             if (typeargtypes.nonEmpty()) mpt = new ForAll(typeargtypes, mpt);
 2170  3327
             localEnv.info.varArgs = false;
 2171  3327
             Type mtype = attribExpr(tree.meth, localEnv, mpt);
 2172  3327
             if (localEnv.info.varArgs)
 2173  4
                 assert mtype.isErroneous() || tree.varargsElement != null;
 2174  
 
 2175  
             // Compute the result type.
 2176  3327
             Type restype = mtype.getReturnType();
 2177  3327
             if (restype == syms.unknownType) {
 2178  0
                 log.error(tree.meth.pos(), MsgSym.MESSAGE_JAVAFX_FUNC_TYPE_INFER_CYCLE, methName);
 2179  0
                 restype = syms.objectType;
 2180  
             }
 2181  
             // as a special case, array.clone() has a result that is
 2182  
             // the same as static type of the array being cloned
 2183  3327
             if (tree.meth.getTag() == JCTree.SELECT &&
 2184  
                 allowCovariantReturns &&
 2185  
                 methName == names.clone &&
 2186  
                 types.isArray(((JCFieldAccess) tree.meth).selected.type))
 2187  0
                 restype = ((JCFieldAccess) tree.meth).selected.type;
 2188  
 
 2189  
             // as a special case, x.getClass() has type Class<? extends |X|>
 2190  3327
             if (allowGenerics &&
 2191  
                 methName == names.getClass && tree.args.isEmpty()) {
 2192  7
                 Type qualifier = (tree.meth.getTag() == JCTree.SELECT)
 2193  
                     ? ((JCFieldAccess) tree.meth).selected.type
 2194  
                     : env.enclClass.sym.type;
 2195  7
                 qualifier = syms.boxIfNeeded(qualifier);
 2196  7
                 restype = new
 2197  
                     ClassType(restype.getEnclosingType(),
 2198  
                               List.<Type>of(new WildcardType(types.erasure(qualifier),
 2199  
                                                                BoundKind.EXTENDS,
 2200  
                                                                syms.boundClass)),
 2201  
                               restype.tsym);
 2202  
             }
 2203  
 
 2204  3327
             if (restype == null) {
 2205  0
                 log.error(tree,
 2206  
                          MsgSym.MESSAGE_JAVAFX_NOT_A_FUNC,
 2207  
                          mtype,
 2208  
                          typeargtypes,
 2209  
                          Type.toString(argtypes));
 2210  0
                 tree.type = pt;
 2211  0
                 result = pt;
 2212  
             }
 2213  
             else {
 2214  
             // Check that value of resulting type is admissible in the
 2215  
             // current context.  Also, capture the return type
 2216  3327
                 result = check(tree, capture(restype), VAL, pkind, pt, pSequenceness);
 2217  
             }
 2218  
 
 2219  3327
         chk.validate(tree.typeargs);
 2220  3327
     }
 2221  
     
 2222  
     @Override
 2223  
     public void visitAssignop(JCAssignOp tree) {
 2224  
         // Attribute arguments.
 2225  38
         Type owntype = attribTree(tree.lhs, env, VAR, Type.noType);
 2226  38
         Type operand = attribExpr(tree.rhs, env);
 2227  
 
 2228  
         // Fix types of numeric arguments with non -specified type.
 2229  38
         Symbol lhsSym = TreeInfo.symbol(tree.lhs);
 2230  38
         if (lhsSym != null && tree.lhs instanceof JCExpression &&
 2231  
                 (lhsSym.type == null || lhsSym.type == Type.noType || lhsSym.type == syms.javafx_AnyType)) {
 2232  1
             JFXVar lhsVarTree = varSymToTree.get(lhsSym);
 2233  1
             owntype = setBinaryTypes(tree.getTag(), (JCExpression)tree.lhs, lhsVarTree, lhsSym.type, lhsSym);
 2234  
         }
 2235  
 
 2236  38
         Symbol rhsSym = TreeInfo.symbol(tree.rhs);
 2237  38
         if (rhsSym != null  && tree.rhs instanceof JCExpression &&
 2238  
                 (rhsSym.type == null || rhsSym.type == Type.noType || rhsSym.type == syms.javafx_AnyType)) {
 2239  0
             JFXVar rhsVarTree = varSymToTree.get(rhsSym);
 2240  0
             operand = setBinaryTypes(tree.getTag(), (JCExpression)tree.rhs, rhsVarTree, rhsSym.type, rhsSym);
 2241  
         }
 2242  
 
 2243  
         // Find operator.
 2244  38
         Symbol operator = tree.operator = rs.resolveBinaryOperator(
 2245  
             tree.pos(), tree.getTag() - JCTree.ASGOffset, env,
 2246  
             owntype, operand);
 2247  
 
 2248  38
         if (operator.kind == MTH) {
 2249  38
             chk.checkOperator(tree.pos(),
 2250  
                               (OperatorSymbol)operator,
 2251  
                               tree.getTag() - JCTree.ASGOffset,
 2252  
                               owntype,
 2253  
                               operand);
 2254  38
             if (types.isSameType(operator.type.getReturnType(), syms.stringType)) {
 2255  
                 // String assignment; make sure the lhs is a string
 2256  0
                 chk.checkType(tree.lhs.pos(),
 2257  
                               owntype,
 2258  
                               syms.stringType, Sequenceness.DISALLOWED);
 2259  
             } else {
 2260  38
                 chk.checkDivZero(tree.rhs.pos(), operator, operand);
 2261  38
                 chk.checkCastable(tree.rhs.pos(),
 2262  
                                   operator.type.getReturnType(),
 2263  
                                   owntype);
 2264  
             }
 2265  
         }
 2266  38
         if (tree.lhs instanceof JCIdent)
 2267  34
             ((JCIdent) (tree.lhs)).sym.flags_field |= JavafxFlags.ASSIGNED_TO;
 2268  38
         result = check(tree, owntype, VAL, pkind, pt, pSequenceness);
 2269  
 
 2270  38
         if (lhsSym != null && tree.rhs != null) {
 2271  34
             JFXVar lhsVar = varSymToTree.get(lhsSym);
 2272  34
             if (lhsVar != null && (lhsVar.getJFXType() instanceof JFXTypeUnknown)) {
 2273  24
                 if ((lhsVar.type == null || lhsVar.type == syms.javafx_AnyType)) {
 2274  0
                     if (tree.rhs.type != null && lhsVar.type != tree.rhs.type) {
 2275  0
                         lhsVar.type = lhsSym.type = tree.rhs.type;
 2276  0
                         JCExpression jcExpr = make.at(tree.pos()).Ident(lhsSym);
 2277  0
                         lhsVar.setJFXType(make.at(tree.pos()).TypeClass(jcExpr, lhsVar.getJFXType().getCardinality()));
 2278  
                     }
 2279  
                 }
 2280  
             }
 2281  
         }
 2282  38
     }
 2283  
 
 2284  
     @Override
 2285  
     public void visitUnary(JCUnary tree) {
 2286  700
         switch (tree.getTag()) {
 2287  
             case JavafxTag.SIZEOF: {
 2288  201
                 attribExpr(tree.arg, env);
 2289  201
                 result = check(tree, syms.javafx_IntegerType, VAL, pkind, pt, pSequenceness);
 2290  201
                 return;
 2291  
             }
 2292  
             case JavafxTag.REVERSE: {
 2293  67
                 Type argtype = chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env));
 2294  67
                 result = check(tree, argtype, VAL, pkind, pt, pSequenceness);
 2295  67
                 return;
 2296  
             }
 2297  
         }
 2298  
         // Attribute arguments.
 2299  432
         Type argtype = (JCTree.PREINC <= tree.getTag() && tree.getTag() <= JCTree.POSTDEC)
 2300  
             ? attribTree(tree.arg, env, VAR, Type.noType)
 2301  
             : chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env));
 2302  432
         Symbol sym =  rs.resolveUnaryOperator(tree.pos(), tree.getTag(), env, argtype);
 2303  432
         Type owntype = syms.errType;
 2304  432
         if (sym instanceof OperatorSymbol) {
 2305  
             // Find operator.
 2306  432
             Symbol operator = tree.operator = sym;
 2307  432
             if (operator.kind == MTH) {
 2308  432
                 owntype = (JCTree.PREINC <= tree.getTag() && tree.getTag() <= JCTree.POSTDEC)
 2309  
                     ? tree.arg.type
 2310  
                     : operator.type.getReturnType();
 2311  
                 
 2312  
             /*** no constants or folding
 2313  
                 int opc = ((OperatorSymbol)operator).opcode;
 2314  
                 
 2315  
                 // If the argument is constant, fold it.
 2316  
                 if (argtype.constValue() != null) {
 2317  
                     Type ctype = cfolder.fold1(opc, argtype);
 2318  
                     if (ctype != null) {
 2319  
                         owntype = cfolder.coerce(ctype, owntype);
 2320  
                         
 2321  
                         // Remove constant types from arguments to
 2322  
                         // conserve space. The parser will fold concatenations
 2323  
                         // of string literals; the code here also
 2324  
                         // gets rid of intermediate results when some of the
 2325  
                         // operands are constant identifiers.
 2326  
                         if (tree.arg.type.tsym == syms.stringType.tsym) {
 2327  
                             tree.arg.type = syms.stringType;
 2328  
                         }
 2329  
                     }
 2330  
                 }
 2331  
             *****/
 2332  
             }
 2333  432
         } else {
 2334  0
             owntype = sym.type.getReturnType();
 2335  
         }
 2336  432
         result = check(tree, owntype, VAL, pkind, pt, pSequenceness);
 2337  432
     }
 2338  
 
 2339  
     private Type setBinaryTypes(int opcode, JCExpression tree, JFXVar var, Type type, Symbol treeSym) {
 2340  20
         Type newType = type;
 2341  20
         JCExpression jcExpression = null;
 2342  
         // boolean type
 2343  20
         if (opcode == JCTree.OR ||
 2344  
             opcode == JCTree.AND) {
 2345  0
             newType = syms.javafx_BooleanType; 
 2346  0
             jcExpression = make.at(tree.pos()).Ident(syms.javafx_BooleanType.tsym);
 2347  
         }
 2348  
         // Integer type
 2349  20
         else if (opcode == JCTree.BITOR ||
 2350  
                  opcode == JCTree.BITXOR ||
 2351  
                  opcode == JCTree.BITAND ||
 2352  
                  opcode == JCTree.SL ||
 2353  
                  opcode == JCTree.SR ||
 2354  
                  opcode == JCTree.USR ||
 2355  
                  opcode == JCTree.MOD ||
 2356  
                  opcode == JCTree.BITOR_ASG ||
 2357  
                  opcode == JCTree.BITXOR_ASG ||
 2358  
                  opcode == JCTree.BITAND_ASG ||
 2359  
                  opcode == JCTree.SL_ASG ||
 2360  
                  opcode == JCTree.SR_ASG ||
 2361  
                  opcode == JCTree.USR_ASG ||
 2362  
                  opcode == JCTree.MOD_ASG) {
 2363  0
             newType = syms.javafx_IntegerType; 
 2364  0
             jcExpression = make.at(tree.pos()).Ident(syms.javafx_IntegerType.tsym);
 2365  
         }
 2366  
         // Number type
 2367  20
         else if (opcode == JCTree.LT ||
 2368  
                  opcode == JCTree.GT ||
 2369  
                  opcode == JCTree.LE ||
 2370  
                  opcode == JCTree.GE ||
 2371  
                  opcode == JCTree.PLUS ||
 2372  
                  opcode == JCTree.MINUS ||
 2373  
                  opcode == JCTree.MUL ||
 2374  
                  opcode == JCTree.DIV ||
 2375  
                  opcode == JCTree.PLUS_ASG ||
 2376  
                  opcode == JCTree.MINUS_ASG ||
 2377  
                  opcode == JCTree.MUL_ASG ||
 2378  
                  opcode == JCTree.DIV_ASG) {
 2379  12
             newType = syms.javafx_NumberType; 
 2380  12
             jcExpression = make.at(tree.pos()).Ident(syms.javafx_NumberType.tsym);
 2381  
         }
 2382  
 
 2383  20
         if (tree != null) {
 2384  20
             tree.setType(newType);
 2385  20
             treeSym.type = newType;
 2386  
         }
 2387  
         
 2388  20
         if (var != null) {
 2389  20
             var.setType(newType);
 2390  20
             JFXType jfxType = make.at(tree.pos()).TypeClass(jcExpression, Cardinality.SINGLETON);
 2391  20
             jfxType.type = newType;
 2392  20
             var.setJFXType(jfxType);
 2393  20
             var.vartype = jfxType;
 2394  20
             var.sym.type = newType;
 2395  
         }
 2396  
         
 2397  20
         return newType;
 2398  
     }
 2399  
     
 2400  
     @Override
 2401  
     public void visitBinary(JCBinary tree) {
 2402  
         // Attribute arguments.
 2403  1100
         Type left = chk.checkNonVoid(tree.lhs.pos(), attribExpr(tree.lhs, env));
 2404  1100
         Type right = chk.checkNonVoid(tree.rhs.pos(), attribExpr(tree.rhs, env));
 2405  
 
 2406  1100
         if (left == syms.javafx_UnspecifiedType) {
 2407  0
             left = setEffectiveExpressionType(tree.lhs, newTypeFromType(getEffectiveExpressionType(right)));
 2408  
         }
 2409  1100
         else if (right == syms.javafx_UnspecifiedType) {
 2410  0
             right = setEffectiveExpressionType(tree.rhs, newTypeFromType(getEffectiveExpressionType(left)));
 2411  
         }
 2412  
  
 2413  
         // Fix types of numeric arguments with non -specified type.
 2414  1100
         boolean lhsSet = false;
 2415  
 
 2416  1100
         Symbol lhsSym = TreeInfo.symbol(tree.lhs);
 2417  1100
         if (lhsSym != null && tree.lhs instanceof JCExpression &&
 2418  
                 (lhsSym.type == null || lhsSym.type == Type.noType || lhsSym.type == syms.javafx_AnyType)) {
 2419  9
             JFXVar lhsVarTree = varSymToTree.get(lhsSym);
 2420  9
             left = setBinaryTypes(tree.getTag(), (JCExpression)tree.lhs, lhsVarTree, lhsSym.type, lhsSym);
 2421  9
             lhsSet = true;
 2422  
         }
 2423  
 
 2424  1100
         Symbol rhsSym = TreeInfo.symbol(tree.rhs);
 2425  1100
         if (rhsSym != null  && ((tree.rhs instanceof JCExpression &&
 2426  
                 (rhsSym.type == null || rhsSym.type == Type.noType || rhsSym.type == syms.javafx_AnyType))) || (lhsSet && lhsSym == rhsSym)) {
 2427  10
             JFXVar rhsVarTree = varSymToTree.get(rhsSym);
 2428  10
             right = setBinaryTypes(tree.getTag(), (JCExpression)tree.rhs, rhsVarTree, rhsSym.type, rhsSym);
 2429  
         }
 2430  
 
 2431  1100
         Symbol sym = 
 2432  
             rs.resolveBinaryOperator(tree.pos(), tree.getTag(), env, left, right);
 2433  1100
         Type owntype = syms.errType;
 2434  1100
         if (sym instanceof OperatorSymbol) {
 2435  
             // Find operator.
 2436  1093
             Symbol operator = tree.operator = sym;
 2437  
                 
 2438  1093
             if (operator.kind == MTH) {
 2439  1093
                 owntype = operator.type.getReturnType();
 2440  1093
                 int opc = chk.checkOperator(tree.lhs.pos(),
 2441  
                                             (OperatorSymbol)operator,
 2442  
                                             tree.getTag(),
 2443  
                                             left,
 2444  
                                             right);
 2445  
                 
 2446  
                 // If both arguments are constants, fold them.
 2447  1093
                 if (left.constValue() != null && right.constValue() != null) {
 2448  0
                     Type ctype = cfolder.fold2(opc, left, right);
 2449  0
                     if (ctype != null) {
 2450  0
                         owntype = cfolder.coerce(ctype, owntype);
 2451  
                         
 2452  
                         // Remove constant types from arguments to
 2453  
                         // conserve space. The parser will fold concatenations
 2454  
                         // of string literals; the code here also
 2455  
                         // gets rid of intermediate results when some of the
 2456  
                         // operands are constant identifiers.
 2457  0
                         if (tree.lhs.type.tsym == syms.stringType.tsym) {
 2458  0
                             tree.lhs.type = syms.stringType;
 2459  
                         }
 2460  0
                         if (tree.rhs.type.tsym == syms.stringType.tsym) {
 2461  0
                             tree.rhs.type = syms.stringType;
 2462  
                         }
 2463  
                     }
 2464  
                 }
 2465  
                 
 2466  
                 // Check that argument types of a reference ==, != are
 2467  
                 // castable to each other, (JLS???).
 2468  1093
                 if ((opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne)) {
 2469  241
                     if (!types.isCastable(left, right, new Warner(tree.pos()))) {
 2470  0
                         boolean isError = true;
 2471  0
                         if (right.tsym != null && right.tsym instanceof JavafxClassSymbol) {
 2472  0
                             ListBuffer<Type> supertypes = ListBuffer.<Type>lb();
 2473  0
                             Set superSet = new HashSet<Type>();
 2474  0
                             supertypes.append(right);
 2475  0
                             superSet.add(right);
 2476  
                             
 2477  0
                             types.getSupertypes(right.tsym, supertypes, superSet);
 2478  0
                             for (Type baseType : supertypes) {
 2479  0
                                 if (types.isCastable(left, baseType, new Warner(tree.pos()))){
 2480  0
                                     isError = false;
 2481  0
                                     break;
 2482  
                                 }
 2483  
                             }
 2484  
                         }
 2485  
                         
 2486  0
                         if (isError) {
 2487  0
                             log.error(tree.pos(), MsgSym.MESSAGE_INCOMPARABLE_TYPES, left, right);
 2488  
                         }
 2489  
                     }
 2490  
                 }
 2491  1093
                 chk.checkDivZero(tree.rhs.pos(), operator, right);
 2492  
             }
 2493  1093
         } else {
 2494  7
             owntype = sym.type.getReturnType();
 2495  
         }
 2496  1100
         result = check(tree, owntype, VAL, pkind, pt, pSequenceness);
 2497  1100
     }
 2498  
     
 2499  
     @Override
 2500  
     public void visitLiteral(JCLiteral tree) {
 2501  8196
         if (tree.typetag == TypeTags.BOT && types.isSequence(pt))
 2502  3
             result = tree.type = pt;
 2503  
         else
 2504  8193
             result = check(
 2505  
                 tree, litType(tree.typetag, pt), VAL, pkind, pt, pSequenceness);
 2506  8196
     }
 2507  
     //where
 2508  
     /** Return the type of a literal with given type tag.
 2509  
      */
 2510  
     Type litType(int tag, Type pt) {
 2511  8193
         return (tag == TypeTags.CLASS) ? syms.stringType : // a class literal can only be a String
 2512  
             (tag == TypeTags.BOT && pt.tag == TypeTags.CLASS) ? pt : // for null, make the type the expected type
 2513  
                 syms.typeOfTag[tag];
 2514  
     }
 2515  
 
 2516  
     @Override
 2517  
     public void visitTypeIdent(JCPrimitiveTypeTree tree) {
 2518  0
         result = check(tree, syms.typeOfTag[tree.typetag], TYP, pkind, pt, pSequenceness);
 2519  0
     }
 2520  
 
 2521  
     @Override
 2522  
     public void visitTypeArray(JCArrayTypeTree tree) {
 2523  0
          assert false : "This tree should not exist";
 2524  0
     }
 2525  
 
 2526  
     /** Visitor method for parameterized types.
 2527  
      *  Bound checking is left until later, since types are attributed
 2528  
      *  before supertype structure is completely known
 2529  
      */
 2530  
     @Override
 2531  
     public void visitTypeApply(JCTypeApply tree) {
 2532  0
         Type owntype = syms.errType;
 2533  
 
 2534  
         // Attribute functor part of application and make sure it's a class.
 2535  0
         Type clazztype = chk.checkClassType(tree.clazz.pos(), attribType(tree.clazz, env));
 2536  
 
 2537  
         // Attribute type parameters
 2538  0
         List<Type> actuals = attribTypes(tree.arguments, env);
 2539  
 
 2540  0
         if (clazztype.tag == CLASS) {
 2541  0
             List<Type> formals = clazztype.tsym.type.getTypeArguments();
 2542  
 
 2543  0
             if (actuals.length() == formals.length()) {
 2544  0
                 List<Type> a = actuals;
 2545  0
                 List<Type> f = formals;
 2546  0
                 while (a.nonEmpty()) {
 2547  0
                     a.head = a.head.withTypeVar(f.head);
 2548  0
                     a = a.tail;
 2549  0
                     f = f.tail;
 2550  
                 }
 2551  
                 // Compute the proper generic outer
 2552  0
                 Type clazzOuter = clazztype.getEnclosingType();
 2553  0
                 if (clazzOuter.tag == CLASS) {
 2554  
                     Type site;
 2555  0
                     if (tree.clazz.getTag() == JCTree.IDENT) {
 2556  0
                         site = env.enclClass.sym.type;
 2557  0
                     } else if (tree.clazz.getTag() == JCTree.SELECT) {
 2558  0
                         site = ((JCFieldAccess) tree.clazz).selected.type;
 2559  0
                     } else throw new AssertionError(""+tree);
 2560  0
                     if (clazzOuter.tag == CLASS && site != clazzOuter) {
 2561  0
                         if (site.tag == CLASS)
 2562  0
                             site = types.asOuterSuper(site, clazzOuter.tsym);
 2563  0
                         if (site == null)
 2564  0
                             site = types.erasure(clazzOuter);
 2565  0
                         clazzOuter = site;
 2566  
                     }
 2567  
                 }
 2568  0
                 owntype = new ClassType(clazzOuter, actuals, clazztype.tsym);
 2569  0
             } else {
 2570  0
                 if (formals.length() != 0) {
 2571  0
                     log.error(tree.pos(), MsgSym.MESSAGE_WRONG_NUMBER_TYPE_ARGS,
 2572  
                               Integer.toString(formals.length()));
 2573  
                 } else {
 2574  0
                     log.error(tree.pos(), MsgSym.MESSAGE_TYPE_DOES_NOT_TAKE_PARAMS, clazztype.tsym);
 2575  
                 }
 2576  0
                 owntype = syms.errType;
 2577  
             }
 2578  
         }
 2579  0
         result = check(tree, owntype, TYP, pkind, pt, pSequenceness);
 2580  0
     }
 2581  
 
 2582  
     @Override
 2583  
     public void visitTypeParameter(JCTypeParameter tree) {
 2584  0
         assert false;
 2585  0
     }
 2586  
 
 2587  
     @Override
 2588  
     public void visitWildcard(JCWildcard tree) {
 2589  0
         assert false;
 2590  0
     }
 2591  
 
 2592  
     @Override
 2593  
     public void visitAnnotation(JCAnnotation tree) {
 2594  0
         log.error(tree.pos(), MsgSym.MESSAGE_ANNOTATION_NOT_VALID_FOR_TYPE, pt);
 2595  0
         result = tree.type = syms.errType;
 2596  0
     }
 2597  
 
 2598  
     @Override
 2599  
     public void visitErroneous(JCErroneous tree) {
 2600  0
         if (tree.errs != null)
 2601  0
             for (JCTree err : tree.errs)
 2602  0
                 attribTree(err, env, ERR, pt);
 2603  0
         result = tree.type = syms.errType;
 2604  0
     }
 2605  
 
 2606  
      @Override
 2607  
      public void visitTree(JCTree tree) {
 2608  0
          if (tree instanceof JFXBlockExpression)
 2609  0
              visitBlockExpression((JFXBlockExpression) tree);
 2610  
          else
 2611  0
              super.visitTree(tree);
 2612  0
     }
 2613  
 
 2614  
     /** Main method: attribute class definition associated with given class symbol.
 2615  
      *  reporting completion failures at the given position.
 2616  
      *  @param pos The source position at which completion errors are to be
 2617  
      *             reported.
 2618  
      *  @param c   The class symbol whose definition will be attributed.
 2619  
      */
 2620  
     public void attribClass(DiagnosticPosition pos, JFXClassDeclaration tree, ClassSymbol c) {
 2621  
         try {
 2622  702
             annotate.flush();
 2623  702
             attribClass(tree, c);
 2624  0
         } catch (CompletionFailure ex) {
 2625  0
             chk.completionError(pos, ex);
 2626  699
         }
 2627  699
     }
 2628  
 
 2629  
     /** Attribute class definition associated with given class symbol.
 2630  
      *  @param c   The class symbol whose definition will be attributed.
 2631  
      */
 2632  
     void attribClass(JFXClassDeclaration tree, ClassSymbol c) throws CompletionFailure {
 2633  1979
         if (c.type.tag == ERROR) return;
 2634  
 
 2635  
         // Check for cycles in the inheritance graph, which can arise from
 2636  
         // ill-formed class files.
 2637  1973
         chk.checkNonCyclic(null, c.type);
 2638  
 
 2639  1973
         Type st = types.supertype(c.type);
 2640  1973
         if ((c.flags_field & Flags.COMPOUND) == 0) {
 2641  
             // First, attribute superclass.
 2642  1973
             if (st.tag == CLASS)
 2643  1017
                 attribClass(null, (ClassSymbol)st.tsym);
 2644  
 
 2645  
             // Next attribute owner, if it is a class.
 2646  1973
             if (c.owner.kind == TYP && c.owner.type.tag == CLASS)
 2647  260
                 attribClass(null, (ClassSymbol)c.owner);
 2648  
         }
 2649  
 
 2650  1973
         if (tree != null) {
 2651  670
             attribSupertypes(tree, c);
 2652  
         }
 2653  
         
 2654  
         // The previous operations might have attributed the current class
 2655  
         // if there was a cycle. So we test first whether the class is still
 2656  
         // UNATTRIBUTED.
 2657  1973
         if ((c.flags_field & UNATTRIBUTED) != 0) {
 2658  670
             c.flags_field &= ~UNATTRIBUTED;
 2659  
 
 2660  
             // Get environment current at the point of class definition.
 2661  670
             JavafxEnv<JavafxAttrContext> localEnv = enter.typeEnvs.get(c);
 2662  
 
 2663  
             // The info.lint field in the envs stored in enter.typeEnvs is deliberately uninitialized,
 2664  
             // because the annotations were not available at the time the env was created. Therefore,
 2665  
             // we look up the environment chain for the first enclosing environment for which the
 2666  
             // lint value is set. Typically, this is the parent env, but might be further if there
 2667  
             // are any envs created as a result of TypeParameter nodes.
 2668  670
             JavafxEnv<JavafxAttrContext> lintEnv = localEnv;
 2669  1340
             while (lintEnv.info.lint == null)
 2670  670
                 lintEnv = lintEnv.next;
 2671  
 
 2672  
             // Having found the enclosing lint value, we can initialize the lint value for this class
 2673  670
             localEnv.info.lint = lintEnv.info.lint.augment(c.attributes_field, c.flags());
 2674  
 
 2675  670
             Lint prevLint = chk.setLint(localEnv.info.lint);
 2676  670
             JavaFileObject prev = log.useSource(c.sourcefile);
 2677  
 
 2678  
             try {
 2679  
                 // java.lang.Enum may not be subclassed by a non-enum
 2680  670
                 if (st.tsym == syms.enumSym &&
 2681  
                     ((c.flags_field & (Flags.ENUM|Flags.COMPOUND)) == 0))
 2682  0
                     log.error(localEnv.tree.pos(), MsgSym.MESSAGE_ENUM_NO_SUBCLASSING);
 2683  
 
 2684  
                 // Enums may not be extended by source-level classes
 2685  670
                 if (st.tsym != null &&
 2686  
                     ((st.tsym.flags_field & Flags.ENUM) != 0) &&
 2687  
                     ((c.flags_field & Flags.ENUM) == 0) &&
 2688  
                     !target.compilerBootstrap(c)) {
 2689  0
                     log.error(localEnv.tree.pos(), MsgSym.MESSAGE_ENUM_TYPES_NOT_EXTENSIBLE);
 2690  
                 }
 2691  670
                 attribClassBody(localEnv, c);
 2692  
 
 2693  667
                 chk.checkDeprecatedAnnotation(localEnv.tree.pos(), c);
 2694  
             } finally {
 2695  670
                 log.useSource(prev);
 2696  670
                 chk.setLint(prevLint);
 2697  667
             }
 2698  
 
 2699  
         }
 2700  1970
     }
 2701  
 
 2702  
     /** Clones a type without copiyng constant values
 2703  
      * @param t the type that needs to be cloned.
 2704  
      * @return  the cloned type with no cloned constants.
 2705  
      */
 2706  
     public Type newTypeFromType(Type t) {
 2707  0
         if (t == null) return null;
 2708  0
         switch (t.tag) {
 2709  
             case BYTE:
 2710  0
                 return syms.byteType;
 2711  
             case CHAR:
 2712  0
                 return syms.charType;
 2713  
             case SHORT:
 2714  0
                 return syms.shortType;
 2715  
             case INT:
 2716  0
                 return syms.intType;
 2717  
             case LONG:
 2718  0
                 return syms.longType;
 2719  
             case FLOAT:
 2720  0
                 return syms.floatType;
 2721  
             case DOUBLE:
 2722  0
                 return syms.doubleType;
 2723  
             case BOOLEAN:
 2724  0
                 return syms.booleanType;
 2725  
             case VOID:
 2726  0
                 return syms.voidType;
 2727  
             default:
 2728  0
                 return t;
 2729  
         }
 2730  
     }
 2731  
     
 2732  
     /**
 2733  
      * Gets the effective type of a type. If MethodType - the return type,
 2734  
      * otherwise the passed in type.
 2735  
      */
 2736  
     private Type getEffectiveExpressionType(Type type) {
 2737  0
         if (type.tag == TypeTags.METHOD) {
 2738  0
             return type.getReturnType();
 2739  
         }
 2740  
         
 2741  0
         return type;
 2742  
     }
 2743  
 
 2744  
     /**
 2745  
      * Sets the effective type of an expression. If MethodType - the return type,
 2746  
      * otherwise the whole type of the expression is set.
 2747  
      */
 2748  
     private Type setEffectiveExpressionType(JCExpression expression, Type type) {
 2749  0
         if (expression.type.tag == TypeTags.METHOD) {
 2750  0
             ((MethodType)expression.type).restype = type;
 2751  
         }
 2752  
         else {
 2753  0
             expression.type = type;
 2754  
         }
 2755  
 
 2756  0
         return expression.type;
 2757  
     }
 2758  
 
 2759  
 // Begin JavaFX trees
 2760  
     @Override
 2761  
     public void visitClassDeclaration(JFXClassDeclaration tree) {
 2762  
         // Local classes have not been entered yet, so we need to do it now:
 2763  291
         if ((env.info.scope.owner.kind & (VAR | MTH)) != 0)
 2764  26
             enter.classEnter(tree, env);
 2765  
 
 2766  291
         ClassSymbol c = tree.sym;
 2767  291
         if (c == null) {
 2768  
             // exit in case something drastic went wrong during enter.
 2769  0
             result = null;
 2770  
         } else {
 2771  
             // make sure class has been completed:
 2772  291
             c.complete();
 2773  
 
 2774  
             // If this class appears as an anonymous class
 2775  
             // in a superclass constructor call where
 2776  
             // no explicit outer instance is given,
 2777  
             // disable implicit outer instance from being passed.
 2778  
             // (This would be an illegal access to "this before super").
 2779  291
             if (env.info.isSelfCall &&
 2780  
                 env.tree.getTag() == JCTree.NEWCLASS &&
 2781  
                 ((JCNewClass) env.tree).encl == null)
 2782  
             {
 2783  0
                 c.flags_field |= NOOUTERTHIS;
 2784  
             }
 2785  
 
 2786  291
             attribSupertypes(tree, c);
 2787  
             
 2788  291
             attribClass(tree.pos(), tree, c);
 2789  
             
 2790  291
             result = tree.type = c.type;
 2791  
         }
 2792  
         
 2793  291
         types.addFxClass(c, tree);
 2794  291
     }
 2795  
     
 2796  
     private void attribSupertypes(JFXClassDeclaration tree, ClassSymbol c) {
 2797  961
         JavafxClassSymbol javafxClassSymbol = null;
 2798  961
         if (c instanceof JavafxClassSymbol) {
 2799  961
             javafxClassSymbol = (JavafxClassSymbol)c;
 2800  
         }
 2801  
 
 2802  961
         Symbol javaSupertypeSymbol = null;
 2803  961
         boolean addToSuperTypes = true;
 2804  
 
 2805  961
         for (JCExpression superClass : tree.getSupertypes()) {
 2806  233
             Type supType = null;
 2807  233
             Symbol supSym = TreeInfo.symbol(superClass);
 2808  233
             if (supSym == null)  {
 2809  0
                 supType = attribType(superClass, env);
 2810  
             }
 2811  
             else {
 2812  233
                 supType = supSym.type;
 2813  
             }
 2814  233
             if (supType != null && !supType.isInterface() && 
 2815  
                     !types.isJFXClass(supType.tsym) && 
 2816  
                     !supType.isPrimitive() &&
 2817  
                     javafxClassSymbol.type instanceof ClassType) {
 2818  25
                 if (javaSupertypeSymbol == null) {
 2819  25
                     javaSupertypeSymbol = supType.tsym;
 2820  
                     // Verify there is a non-parametric constructor.
 2821  25
                     boolean hasNonParamCtor = true; // If there is no non-param constr we will create one later.
 2822  25
                     for (Scope.Entry e1 = javaSupertypeSymbol.members().elems;
 2823  493
                              e1 != null;
 2824  468
                              e1 = e1.sibling) {
 2825  493
                             Symbol s1 = e1.sym;
 2826  493
                             if (s1 != null &&
 2827  
                                     s1.name == names.init &&
 2828  
                                     s1.kind == Kinds.MTH) {
 2829  56
                                 MethodType mtype = ((MethodSymbol)s1).type.asMethodType();
 2830  56
                                 if (mtype != null && mtype.getParameterTypes().isEmpty()) {
 2831  25
                                     hasNonParamCtor = true;
 2832  25
                                     break;
 2833  
                                 }
 2834  
                                 else {
 2835  31
                                     hasNonParamCtor = false;
 2836  
                                 }
 2837  
                             }
 2838  
                     }
 2839  
 
 2840  25
                     if (hasNonParamCtor) {
 2841  25
                         ((ClassType)javafxClassSymbol.type).supertype_field = javaSupertypeSymbol.type;
 2842  25
                         addToSuperTypes = false;
 2843  
                     }
 2844  
                     else {
 2845  0
                         log.error(superClass.pos(), MsgSym.MESSAGE_JAVAFX_BASE_JAVA_CLASS_NON_PAPAR_CTOR, supType.tsym.name);
 2846  
 
 2847  
                     }
 2848  25
                 }
 2849  
                 else {
 2850  
                     // We are already extending one Java class. No more than one is allowed. Report an error.
 2851  0
                     log.error(superClass.pos(), MsgSym.MESSAGE_JAVAFX_ONLY_ONE_BASE_JAVA_CLASS_ALLOWED, supType.tsym.name);
 2852  
                 }
 2853  
             }
 2854  
 
 2855  233
             if (addToSuperTypes && 
 2856  
                     supType != null && 
 2857  
                     javafxClassSymbol != null) {
 2858  208
                 javafxClassSymbol.addSuperType(supType);
 2859  
             }
 2860  233
             addToSuperTypes = true;
 2861  233
         }
 2862  
 
 2863  961
     }
 2864  
     
 2865  
     @Override
 2866  
     public void visitInitDefinition(JFXInitDefinition that) {
 2867  30
         Symbol symOwner = env.info.scope.owner;
 2868  
         try {
 2869  30
             MethodType mt = new MethodType(List.<Type>nil(), syms.voidType, List.<Type>nil(), (TypeSymbol)symOwner);
 2870  30
             that.sym = new MethodSymbol(0L, defs.initDefName, mt, symOwner);
 2871  30
             env.info.scope.owner = that.sym;
 2872  30
             ((JCBlock)that.getBody()).accept(this);
 2873  
         }
 2874  
         finally {
 2875  30
             env.info.scope.owner = symOwner;
 2876  30
         }
 2877  30
     }
 2878  
 
 2879  
     public void visitPostInitDefinition(JFXPostInitDefinition that) {
 2880  10
         Symbol symOwner = env.info.scope.owner;
 2881  
         try {
 2882  10
             MethodType mt = new MethodType(List.<Type>nil(), syms.voidType, List.<Type>nil(), (TypeSymbol)symOwner);
 2883  10
             that.sym = new MethodSymbol(0L, defs.postInitDefName, mt, symOwner);
 2884  10
             env.info.scope.owner = that.sym;
 2885  10
             ((JCBlock)that.getBody()).accept(this);
 2886  
         }
 2887  
         finally {
 2888  10
             env.info.scope.owner = symOwner;
 2889  10
         }
 2890  10
     }
 2891  
 
 2892  
     @Override
 2893  
     public void visitSequenceEmpty(JFXSequenceEmpty tree) {
 2894  54
         boolean isSeq = false;
 2895  54
         if (pt.tag != NONE && pt != syms.javafx_UnspecifiedType && !(isSeq = types.isSequence(pt)) && pSequenceness == Sequenceness.DISALLOWED) {
 2896  0
             log.error(tree.pos(), MsgSym.MESSAGE_ARRAY_REQ_BUT_FOUND, pt); //TODO: msg
 2897  0
             result = syms.errType;
 2898  
         } else {
 2899  54
             Type owntype = pt.tag == NONE || pt.tag == UNKNOWN ? syms.botType :
 2900  
                     isSeq ? pt : types.sequenceType(pt);
 2901  54
             result = check(tree, owntype, VAL, pkind, Type.noType, pSequenceness);
 2902  
         }
 2903  54
     }
 2904  
     
 2905  
     @Override
 2906  
     public void visitSequenceRange(JFXSequenceRange tree) {
 2907  212
         Type lowerType =  attribExpr(tree.getLower(), env);        
 2908  212
         Type upperType = attribExpr(tree.getUpper(), env);
 2909  212
         Type stepType = tree.getStepOrNull() == null? syms.javafx_IntegerType : attribExpr(tree.getStepOrNull(), env);
 2910  212
         boolean allInt = true;
 2911  212
         if (lowerType != syms.javafx_IntegerType) {
 2912  6
             allInt = false;
 2913  6
             if (lowerType != syms.javafx_NumberType) {
 2914  1
                 log.error(tree.getLower().pos(), MsgSym.MESSAGE_JAVAFX_RANGE_START_INT_OR_NUMBER); 
 2915  
             }
 2916  
         }
 2917  212
         if (upperType != syms.javafx_IntegerType) {
 2918  11
             allInt = false;
 2919  11
             if (upperType != syms.javafx_NumberType) {
 2920  1
                 log.error(tree.getLower().pos(), MsgSym.MESSAGE_JAVAFX_RANGE_END_INT_OR_NUMBER); 
 2921  
             }
 2922  
         }
 2923  212
         if (stepType != syms.javafx_IntegerType) {
 2924  7
             allInt = false;
 2925  7
             if (stepType != syms.javafx_NumberType) {
 2926  1
                 log.error(tree.getStepOrNull().pos(), MsgSym.MESSAGE_JAVAFX_RANGE_STEP_INT_OR_NUMBER); 
 2927  
             }
 2928  
         }
 2929  212
                 if (tree.getLower().getTag() == JCTree.LITERAL && tree.getUpper().getTag() == JCTree.LITERAL 
 2930  
                 && (tree.getStepOrNull() == null || tree.getStepOrNull().getTag() == JCTree.LITERAL)) {
 2931  133
             chk.warnEmptyRangeLiteral(tree.pos(), (JCLiteral)tree.getLower(), (JCLiteral)tree.getUpper(), (JCLiteral)tree.getStepOrNull(), tree.isExclusive());
 2932  
                 }
 2933  209
         Type owntype = types.sequenceType(allInt? syms.javafx_IntegerType : syms.javafx_NumberType);
 2934  209
         result = check(tree, owntype, VAL, pkind, pt, pSequenceness);
 2935  209
     }
 2936  
     
 2937  
     @Override
 2938  
     public void visitSequenceExplicit(JFXSequenceExplicit tree) {
 2939  398
         Type elemType = null;
 2940  398
         Type expected = pt;
 2941  398
         if (types.isSequence(expected))
 2942  152
             expected = types.elementType(expected);
 2943  398
         for (JCExpression expr : tree.getItems()) {
 2944  1495
                 Type itemType = attribTree(expr, env, VAL,
 2945  
                         expected, Sequenceness.PERMITTED);
 2946  1495
                 if (itemType.tag == NONE || itemType.tag == ERROR) {
 2947  0
                     continue;
 2948  
                 }
 2949  1495
                 if (types.isSequence(itemType)) {
 2950  83
                     itemType = types.elementType(itemType);
 2951  
                 }
 2952  1495
                 if (elemType == null)
 2953  398
                     elemType = itemType;
 2954  
                 else
 2955  1097
                     elemType = unionType(tree, itemType, elemType);
 2956  1495
             }
 2957  398
         Type owntype = types.sequenceType(elemType);
 2958  398
         result = check(tree, owntype, VAL, pkind, pt, pSequenceness);
 2959  398
         if (owntype == result && pt.tag != NONE && pt != syms.javafx_UnspecifiedType) {
 2960  153
             expected = types.sequenceType(expected);
 2961  153
             result = tree.type = expected;
 2962  
         }
 2963  398
     }
 2964  
 
 2965  
     @Override
 2966  
     public void visitSequenceSlice(JFXSequenceSlice tree) {
 2967  31
         JCExpression seq = tree.getSequence();
 2968  31
         Type seqType = attribExpr(seq, env);
 2969  
 
 2970  31
         attribExpr(tree.getFirstIndex(), env, syms.javafx_IntegerType);
 2971  31
         if (tree.getLastIndex() != null) {
 2972  19
             attribExpr(tree.getLastIndex(), env, syms.javafx_IntegerType);
 2973  
         }
 2974  31
         result = check(tree, seqType, VAR, pkind, pt, pSequenceness);
 2975  31
     }
 2976  
     
 2977  
     @Override
 2978  
     public void visitSequenceIndexed(JFXSequenceIndexed tree) {
 2979  454
         JCExpression seq = tree.getSequence();
 2980  454
         Type seqType = attribExpr(seq, env);
 2981  
 
 2982  454
         attribExpr(tree.getIndex(), env, syms.javafx_IntegerType);
 2983  
         Type owntype;
 2984  454
         if (seqType.tag == TypeTags.ARRAY) {
 2985  0
             owntype = ((ArrayType)seqType).elemtype;
 2986  
         }
 2987  
         else {
 2988  454
             owntype = chk.checkSequenceElementType(seq, seqType);
 2989  
         }
 2990  454
         result = check(tree, owntype, VAR, pkind, pt, pSequenceness);
 2991  454
     }
 2992  
     
 2993  
     @Override
 2994  
     public void visitSequenceInsert(JFXSequenceInsert tree) {
 2995  186
         JCExpression seq = tree.getSequence();
 2996  186
         Type seqType = attribTree(seq, env, VAR, Type.noType, Sequenceness.REQUIRED);
 2997  186
         attribExpr(tree.getElement(), env, seqType);
 2998  186
         if (tree.getPosition() != null) {
 2999  87
             attribExpr(tree.getPosition(), env, syms.javafx_IntegerType);
 3000  
         }
 3001  186
         result = null;
 3002  186
     }
 3003  
     
 3004  
     @Override
 3005  
     public void visitSequenceDelete(JFXSequenceDelete tree) {
 3006  123
         JCExpression seq = tree.getSequence();
 3007  123
         if (tree.getElement() == null) {
 3008  98
             if (seq instanceof JFXSequenceIndexed) { 
 3009  
                 // delete seq[index];
 3010  38
                 JFXSequenceIndexed si = (JFXSequenceIndexed)seq;
 3011  38
                 JCExpression seqseq = si.getSequence();
 3012  38
                 JCExpression index = si.getIndex();
 3013  38
                 attribTree(seqseq, env, VAR, Type.noType, Sequenceness.REQUIRED); 
 3014  38
                 attribExpr(index, env, syms.javafx_IntegerType);
 3015  38
             } else if (seq instanceof JFXSequenceSlice) { 
 3016  
                 // delete seq[first..last];
 3017  35
                 JFXSequenceSlice slice = (JFXSequenceSlice)seq;
 3018  35
                 JCExpression seqseq = slice.getSequence();
 3019  35
                 JCExpression first = slice.getFirstIndex();
 3020  35
                 JCExpression last = slice.getLastIndex();
 3021  35
                 attribTree(seqseq, env, VAR, Type.noType, Sequenceness.REQUIRED); 
 3022  35
                 attribExpr(first, env, syms.javafx_IntegerType);
 3023  35
                 if (last != null) {
 3024  25
                     attribExpr(last, env, syms.javafx_IntegerType);
 3025  
                 }
 3026  35
             } else {
 3027  
                 // delete seq;   // that is, all the elements
 3028  25
                 attribTree(seq, env, VAR, Type.noType, Sequenceness.REQUIRED); 
 3029  
             }
 3030  
         } else {
 3031  25
             Type seqType = attribTree(seq, env, VAR, Type.noType, Sequenceness.REQUIRED); 
 3032  25
             attribExpr(tree.getElement(), env,
 3033  
                     chk.checkSequenceElementType(seq.pos(), seqType));
 3034  
         }
 3035  123
         result = null;
 3036  123
     }
 3037  
     
 3038  
     @Override
 3039  
     public void visitStringExpression(JFXStringExpression tree) {
 3040  741
         List<JCExpression> parts = tree.getParts();
 3041  741
         attribExpr(parts.head, env, syms.javafx_StringType);
 3042  741
         parts = parts.tail;
 3043  1909
         while (parts.nonEmpty()) {
 3044  
             // First the format specifier:
 3045  1168
             attribExpr(parts.head, env, syms.javafx_StringType);
 3046  1168
             parts = parts.tail;
 3047  
             // Next the enclosed expression:
 3048  1168
             chk.checkNonVoid(parts.head.pos(), attribExpr(parts.head, env, Type.noType));
 3049  1168
             parts = parts.tail;
 3050  
             // Next the following string literal part:
 3051  1168
             attribExpr(parts.head, env, syms.javafx_StringType);
 3052  1168
             parts = parts.tail;
 3053  
         }
 3054  741
         result = check(tree, syms.javafx_StringType, VAL, pkind, pt, pSequenceness);
 3055  741
     }
 3056  
     
 3057  
     @Override
 3058  
     public void visitSetAttributeToObjectBeingInitialized(JFXSetAttributeToObjectBeingInitialized that) {
 3059  0
     }
 3060  
     
 3061  
     @Override
 3062  
     public void visitObjectLiteralPart(JFXObjectLiteralPart that) {
 3063  0
         assert false : "should not reach here";
 3064  0
         result = syms.errType;
 3065  0
     }  
 3066  
     
 3067  
     @Override
 3068  
     public void visitTypeAny(JFXTypeAny tree) {
 3069  0
         assert false : "MUST IMPLEMENT";
 3070  0
     }
 3071  
     
 3072  
     @Override
 3073  
     public void visitTypeClass(JFXTypeClass tree) {
 3074  2795
         Type type = null;
 3075  2795
         JCExpression classNameExpr = ((JFXTypeClass) tree).getClassName();
 3076  2795
         if (classNameExpr instanceof JCIdent) {
 3077  2321
             Name className = ((JCIdent) classNameExpr).getName();
 3078  2321
             if (className == numberTypeName) {
 3079  149
                 type = syms.javafx_NumberType;
 3080  2172
             } else if (className == integerTypeName) {
 3081  752
                 type = syms.javafx_IntegerType;
 3082  1420
             } else if (className == booleanTypeName) {
 3083  201
                 type = syms.javafx_BooleanType;
 3084  1219
             } else if (className == voidTypeName) {
 3085  84
                 type = syms.javafx_VoidType;
 3086  1135
             } else if (className == stringTypeName) {
 3087  804
                 type = syms.javafx_StringType;
 3088  
             }
 3089  
         }
 3090  2795
         if (type == null) {
 3091  805
             type = attribType(classNameExpr, env);
 3092  
         }
 3093  2795
         type = sequenceType(type, tree.getCardinality());
 3094  2795
         tree.type = type;
 3095  2795
         result = type;
 3096  2795
     }
 3097  
     
 3098  
     @Override
 3099  
     public void visitTypeFunctional(JFXTypeFunctional tree) {
 3100  33
         Type restype = attribType(tree.restype, env);
 3101  33
         if (restype == syms.unknownType)
 3102  3
             restype = syms.voidType;
 3103  33
         Type rtype = restype == syms.voidType ? syms.javafx_java_lang_VoidType
 3104  
                 : new WildcardType(syms.boxIfNeeded(restype), BoundKind.EXTENDS, syms.boundClass);
 3105  33
         ListBuffer<Type> typarams = new ListBuffer<Type>();
 3106  33
         ListBuffer<Type> argtypes = new ListBuffer<Type>();
 3107  33
         typarams.append(rtype);
 3108  33
         int nargs = 0;
 3109  33
         for (JFXType param : (List<JFXType>)tree.params) {
 3110  28
             Type argtype = attribType(param, env);
 3111  28
             argtypes.append(argtype);
 3112  28
             Type ptype = syms.boxIfNeeded(argtype);
 3113  28
             ptype = new WildcardType(ptype, BoundKind.SUPER, syms.boundClass);
 3114  28
             typarams.append(ptype);
 3115  28
             nargs++;
 3116  28
         }
 3117  33
         MethodType mtype = new MethodType(argtypes.toList(), restype, null, syms.methodClass);
 3118  33
         FunctionType ftype = syms.makeFunctionType(typarams.toList(), mtype);
 3119  33
         Type type = sequenceType(ftype, tree.getCardinality());
 3120  33
         tree.type = type;
 3121  33
         result = type; 
 3122  33
     }
 3123  
     
 3124  
     @Override
 3125  
     public void visitTypeUnknown(JFXTypeUnknown tree) {
 3126  1406
         result = tree.type = syms.javafx_UnspecifiedType;
 3127  1406
     }
 3128  
 
 3129  
     Type sequenceType(Type elemType, Cardinality cardinality) {
 3130  2828
         return cardinality == cardinality.ANY 
 3131  
                 ? types.sequenceType(elemType)
 3132  
                 : elemType;
 3133  
     }
 3134  
 
 3135  
         /** Determine type of identifier or select expression and check that
 3136  
          *  (1) the referenced symbol is not deprecated
 3137  
          *  (2) the symbol's type is safe (@see checkSafe)
 3138  
          *  (3) if symbol is a variable, check that its type and kind are
 3139  
          *      compatible with the prototype and protokind.
 3140  
          *  (4) if symbol is an instance field of a raw type,
 3141  
          *      which is being assigned to, issue an unchecked warning if its
 3142  
          *      type changes under erasure.
 3143  
          *  (5) if symbol is an instance method of a raw type, issue an
 3144  
          *      unchecked warning if its argument types change under erasure.
 3145  
          *  If checks succeed:
 3146  
          *    If symbol is a constant, return its constant type
 3147  
          *    else if symbol is a method, return its result type
 3148  
          *    otherwise return its type.
 3149  
          *  Otherwise return errType.
 3150  
          *
 3151  
          *  @param tree       The syntax tree representing the identifier
 3152  
          *  @param site       If this is a select, the type of the selected
 3153  
          *                    expression, otherwise the type of the current class.
 3154  
          *  @param sym        The symbol representing the identifier.
 3155  
          *  @param env        The current environment.
 3156  
          *  @param pkind      The set of expected kinds.
 3157  
          *  @param pt         The expected type.
 3158  
          */
 3159  
         Type checkId(JCTree tree,
 3160  
                      Type site,
 3161  
                      Symbol sym,
 3162  
                      JavafxEnv<JavafxAttrContext> env,
 3163  
                      int pkind,
 3164  
                      Type pt,
 3165  
                      Sequenceness pSequenceness,
 3166  
                      boolean useVarargs) {
 3167  20814
             if (pt.isErroneous()) return syms.errType;
 3168  
             Type owntype; // The computed type of this identifier occurrence.
 3169  20813
             switch (sym.kind) {
 3170  
             case TYP:
 3171  
                 // For types, the computed type equals the symbol's type,
 3172  
                 // except for two situations:
 3173  4353
                 owntype = sym.type;
 3174  4353
                 if (owntype.tag == CLASS) {
 3175  4353
                     Type ownOuter = owntype.getEnclosingType();
 3176  
 
 3177  
                     // (a) If the symbol's type is parameterized, erase it
 3178  
                     // because no type parameters were given.
 3179  
                     // We recover generic outer type later in visitTypeApply.
 3180  4353
                     if (owntype.tsym.type.getTypeArguments().nonEmpty()) {
 3181  41
                         owntype = types.erasure(owntype);
 3182  
                     }
 3183  
 
 3184  
                     // (b) If the symbol's type is an inner class, then
 3185  
                     // we have to interpret its outer type as a superclass
 3186  
                     // of the site type. Example:
 3187  
                     //
 3188  
                     // class Tree<A> { class Visitor { ... } }
 3189  
                     // class PointTree extends Tree<Point> { ... }
 3190  
                     // ...PointTree.Visitor...
 3191  
                     //
 3192  
                     // Then the type of the last expression above is
 3193  
                     // Tree<Point>.Visitor.
 3194  4312
                     else if (ownOuter.tag == CLASS && site != ownOuter) {
 3195  0
                         Type normOuter = site;
 3196  0
                         if (normOuter.tag == CLASS)
 3197  0
                             normOuter = types.asEnclosingSuper(site, ownOuter.tsym);
 3198  0
                         if (normOuter == null) // perhaps from an import
 3199  0
                             normOuter = types.erasure(ownOuter);
 3200  0
                         if (normOuter != ownOuter)
 3201  0
                             owntype = new ClassType(
 3202  
                                 normOuter, List.<Type>nil(), owntype.tsym);
 3203  
                     }
 3204  4353
                 }
 3205  
                 break;
 3206  
             case VAR:
 3207  9265
                 VarSymbol v = (VarSymbol)sym;
 3208  
                 // Test (4): if symbol is an instance field of a raw type,
 3209  
                 // which is being assigned to, issue an unchecked warning if
 3210  
                 // its type changes under erasure.
 3211  9265
                 if (allowGenerics &&
 3212  
                     pkind == VAR &&
 3213  
                     v.owner.kind == TYP &&
 3214  
                     (v.flags() & STATIC) == 0 &&
 3215  
                     (site.tag == CLASS || site.tag == TYPEVAR)) {
 3216  484
                     Type s = types.asOuterSuper(site, v.owner);
 3217  484
                     if (s != null &&
 3218  
                         s.isRaw() &&
 3219  
                         !types.isSameType(v.type, v.erasure(types))) {
 3220  0
                         chk.warnUnchecked(tree.pos(),
 3221  
                                           MsgSym.MESSAGE_UNCHECKED_ASSIGN_TO_VAR,
 3222  
                                           v, s);
 3223  
                     }
 3224  
                 }
 3225  
                 // The computed type of a variable is the type of the
 3226  
                 // variable symbol, taken as a member of the site type.
 3227  9265
                 owntype = (sym.owner.kind == TYP &&
 3228  
                            sym.name != names._this && sym.name != names._super)
 3229  
                     ? types.memberType(site, sym)
 3230  
                     : sym.type;
 3231  
 
 3232  9265
                 if (env.info.tvars.nonEmpty()) {
 3233  0
                     Type owntype1 = new ForAll(env.info.tvars, owntype);
 3234  0
                     for (List<Type> l = env.info.tvars; l.nonEmpty(); l = l.tail)
 3235  0
                         if (!owntype.contains(l.head)) {
 3236  0
                             log.error(tree.pos(), MsgSym.MESSAGE_UNDETERMINDED_TYPE, owntype1);
 3237  0
                             owntype1 = syms.errType;
 3238  
                         }
 3239  0
                     owntype = owntype1;
 3240  
                 }
 3241  
 
 3242  
                 // If the variable is a constant, record constant value in
 3243  
                 // computed type.
 3244  
                 //if (v.getConstValue() != null && isStaticReference(tree))
 3245  
                 //    owntype = owntype.constType(v.getConstValue());
 3246  
 
 3247  9265
                 if (pkind == VAL) {
 3248  5212
                     owntype = capture(owntype); // capture "names as expressions"
 3249  
                 }
 3250  
                 break;
 3251  
             case MTH: {
 3252  3288
                 owntype = sym.type;
 3253  
                 // This is probably wrong now that we have function expressions.
 3254  
                 // Instead, we should checkMethod in visitApply.
 3255  
                 // In that case we should also handle FunctionType. FIXME.
 3256  3288
                 if (pt instanceof MethodType || pt instanceof ForAll) {
 3257  3279
                     JCMethodInvocation app = (JCMethodInvocation)env.tree;
 3258  3279
                     owntype = checkMethod(site, sym, env, app.args,
 3259  
                                       pt.getParameterTypes(), pt.getTypeArguments(),
 3260  
                                       env.info.varArgs);
 3261  3279
                 }
 3262  
                 break;
 3263  
             }
 3264  
             case PCK: case ERR:
 3265  3907
                 owntype = sym.type;
 3266  3907
                 break;
 3267  
             default:
 3268  0
                 throw new AssertionError("unexpected kind: " + sym.kind +
 3269  
                                          " in tree " + tree);
 3270  
             }
 3271  
 
 3272  
             // Test (1): emit a `deprecation' warning if symbol is deprecated.
 3273  
             // (for constructors, the error was given when the constructor was
 3274  
             // resolved)
 3275  20813
             if (sym.name != names.init &&
 3276  
                 (sym.flags() & DEPRECATED) != 0 &&
 3277  
                 (env.info.scope.owner.flags() & DEPRECATED) == 0 &&
 3278  
                 sym.outermostClass() != env.info.scope.owner.outermostClass())
 3279  0
                 chk.warnDeprecated(tree.pos(), sym);
 3280  
 
 3281  20813
             if ((sym.flags() & PROPRIETARY) != 0)
 3282  0
                 log.strictWarning(tree.pos(), MsgSym.MESSAGE_SUN_PROPRIETARY, sym);
 3283  
 
 3284  
             // Test (3): if symbol is a variable, check that its type and
 3285  
             // kind are compatible with the prototype and protokind.
 3286  20813
             return check(tree, owntype, sym.kind, pkind, pt, pSequenceness);
 3287  
         }
 3288  
 
 3289  
         /** Check that variable is initialized and evaluate the variable's
 3290  
          *  initializer, if not yet done. Also check that variable is not
 3291  
          *  referenced before it is defined.
 3292  
          *  @param tree    The tree making up the variable reference.
 3293  
          *  @param env     The current environment.
 3294  
          *  @param v       The variable's symbol.
 3295  
          */
 3296  
         private void checkInit(JCTree tree,
 3297  
                                JavafxEnv<JavafxAttrContext> env,
 3298  
                                VarSymbol v,
 3299  
                                boolean onlyWarning) {
 3300  
 //          System.err.println(v + " " + ((v.flags() & STATIC) != 0) + " " +
 3301  
 //                             tree.pos + " " + v.pos + " " +
 3302  
 //                             Resolve.isStatic(env));//DEBUG
 3303  
 
 3304  
             // A forward reference is diagnosed if the declaration position
 3305  
             // of the variable is greater than the current tree position
 3306  
             // and the tree and variable definition occur in the same class
 3307  
             // definition.  Note that writes don't count as references.
 3308  
             // This check applies only to class and instance
 3309  
             // variables.  Local variables follow different scope rules,
 3310  
             // and are subject to definite assignment checking.
 3311  9265
             if (v.pos > tree.pos &&
 3312  
                 v.owner.kind == TYP &&
 3313  
                 canOwnInitializer(env.info.scope.owner) &&
 3314  
                 v.owner == env.info.scope.owner.enclClass() &&
 3315  
                 ((v.flags() & STATIC) != 0) == JavafxResolve.isStatic(env) &&
 3316  
                 (env.tree.getTag() != JCTree.ASSIGN ||
 3317  
                  TreeInfo.skipParens(((JCAssign) env.tree).lhs) != tree)) {
 3318  
 // Javafx change
 3319  
                 // In JXF is OK to forward reference an attribute even if it's not initialized yet!
 3320  
 //                if (!onlyWarning || isNonStaticEnumField(v)) {
 3321  
 //                    log.error(tree.pos(), "illegal.forward.ref");
 3322  
 //                
 3323  
 //                } else if (useBeforeDeclarationWarning) {
 3324  
 //                    log.warning(tree.pos(), "forward.ref", v);
 3325  
 //                }
 3326  
 // Javafx change end
 3327  
             }
 3328  
 
 3329  9265
             v.getConstValue(); // ensure initializer is evaluated
 3330  
 
 3331  9265
             checkEnumInitializer(tree, env, v);
 3332  9265
         }
 3333  
 
 3334  
     /** Is given blank final variable assignable, i.e. in a scope where it
 3335  
      *  may be assigned to even though it is final?
 3336  
      *  @param v      The blank final variable.
 3337  
      *  @param env    The current environment.
 3338  
      */
 3339  
     boolean isAssignableAsBlankFinal(VarSymbol v, JavafxEnv<JavafxAttrContext> env) {
 3340  0
         Symbol owner = env.info.scope.owner;
 3341  
            // owner refers to the innermost variable, method or
 3342  
            // initializer block declaration at this point.
 3343  0
         return
 3344  
             v.owner == owner
 3345  
             ||
 3346  
             ((owner.name == names.init ||    // i.e. we are in a constructor
 3347  
               owner.kind == VAR ||           // i.e. we are in a variable initializer
 3348  
               (owner.flags() & BLOCK) != 0)  // i.e. we are in an initializer block
 3349  
              &&
 3350  
              v.owner == owner.owner
 3351  
              &&
 3352  
              ((v.flags() & STATIC) != 0) == JavafxResolve.isStatic(env));
 3353  
     }
 3354  
 
 3355  
     /** Check that variable can be assigned to.
 3356  
      *  @param pos    The current source code position.
 3357  
      *  @param v      The assigned varaible
 3358  
      *  @param base   If the variable is referred to in a Select, the part
 3359  
      *                to the left of the `.', null otherwise.
 3360  
      *  @param env    The current environment.
 3361  
      */
 3362  
     void checkAssignable(DiagnosticPosition pos, VarSymbol v, JCTree base, JavafxEnv<JavafxAttrContext> env) {
 3363  
         //TODO: for attributes they are always final -- this should really be checked in JavafxClassReader
 3364  1429
         if ((v.flags() & FINAL) != 0 && !types.isJFXClass(v.owner) &&
 3365  
             ((v.flags() & HASINIT) != 0
 3366  
              ||
 3367  
              !((base == null ||
 3368  
                (base.getTag() == JCTree.IDENT && TreeInfo.name(base) == names._this)) &&
 3369  
                isAssignableAsBlankFinal(v, env)))) {
 3370  0
             log.error(pos, MsgSym.MESSAGE_CANNOT_ASSIGN_VAL_TO_FINAL_VAR, v);
 3371  
         }
 3372  1429
     }
 3373  
 
 3374  
         /**
 3375  
          * Check for illegal references to static members of enum.  In
 3376  
          * an enum type, constructors and initializers may not
 3377  
          * reference its static members unless they are constant.
 3378  
          *
 3379  
          * @param tree    The tree making up the variable reference.
 3380  
          * @param env     The current environment.
 3381  
          * @param v       The variable's symbol.
 3382  
          * @see JLS 3rd Ed. (8.9 Enums)
 3383  
          */
 3384  
         private void checkEnumInitializer(JCTree tree, JavafxEnv<JavafxAttrContext> env, VarSymbol v) {
 3385  
             // JLS 3rd Ed.:
 3386  
             //
 3387  
             // "It is a compile-time error to reference a static field
 3388  
             // of an enum type that is not a compile-time constant
 3389  
             // (15.28) from constructors, instance initializer blocks,
 3390  
             // or instance variable initializer expressions of that
 3391  
             // type. It is a compile-time error for the constructors,
 3392  
             // instance initializer blocks, or instance variable
 3393  
             // initializer expressions of an enum constant e to refer
 3394  
             // to itself or to an enum constant of the same type that
 3395  
             // is declared to the right of e."
 3396  9265
             if (isNonStaticEnumField(v)) {
 3397  0
                 ClassSymbol enclClass = env.info.scope.owner.enclClass();
 3398  
 
 3399  0
                 if (enclClass == null || enclClass.owner == null)
 3400  0
                     return;
 3401  
 
 3402  
                 // See if the enclosing class is the enum (or a
 3403  
                 // subclass thereof) declaring v.  If not, this
 3404  
                 // reference is OK.
 3405  0
                 if (v.owner != enclClass && !types.isSubtype(enclClass.type, v.owner.type))
 3406  0
                     return;
 3407  
 
 3408  
                 // If the reference isn't from an initializer, then
 3409  
                 // the reference is OK.
 3410  0
                 if (!JavafxResolve.isInitializer(env))
 3411  0
                     return;
 3412  
 
 3413  0
                 log.error(tree.pos(), MsgSym.MESSAGE_ILLEGAL_ENUM_STATIC_REF);
 3414  
             }
 3415  9265
         }
 3416  
 
 3417  
         private boolean isNonStaticEnumField(VarSymbol v) {
 3418  9265
             return Flags.isEnum(v.owner) && Flags.isStatic(v) && !Flags.isConstant(v);
 3419  
         }
 3420  
 
 3421  
         /** Can the given symbol be the owner of code which forms part
 3422  
          *  if class initialization? This is the case if the symbol is
 3423  
          *  a type or field, or if the symbol is the synthetic method.
 3424  
          *  owning a block.
 3425  
          */
 3426  
         private boolean canOwnInitializer(Symbol sym) {
 3427  1271
             return
 3428  
                 (sym.kind & (VAR | TYP)) != 0 ||
 3429  
                 (sym.kind == MTH && (sym.flags() & BLOCK) != 0);
 3430  
         }
 3431  
 
 3432  399
     Warner noteWarner = new Warner();
 3433  
 
 3434  
     /**
 3435  
      * Check that method arguments conform to its instantation.
 3436  
      **/
 3437  
     public Type checkMethod(Type site,
 3438  
                             Symbol sym,
 3439  
                             JavafxEnv<JavafxAttrContext> env,
 3440  
                             final List<JCExpression> argtrees,
 3441  
                             List<Type> argtypes,
 3442  
                             List<Type> typeargtypes,
 3443  
                             boolean useVarargs) {
 3444  
         // Test (5): if symbol is an instance method of a raw type, issue
 3445  
         // an unchecked warning if its argument types change under erasure.
 3446  3279
         if (allowGenerics &&
 3447  
             (sym.flags() & STATIC) == 0 &&
 3448  
             (site.tag == CLASS || site.tag == TYPEVAR)) {
 3449  2469
             Type s = types.asOuterSuper(site, sym.owner);
 3450  2469
             if (s != null && s.isRaw() &&
 3451  
                 !types.isSameTypes(sym.type.getParameterTypes(),
 3452  
                                    sym.erasure(types).getParameterTypes())) {
 3453  8
                 chk.warnUnchecked(env.tree.pos(),
 3454  
                                   MsgSym.MESSAGE_UNCHECKED_CALL_MBR_OF_RAW_TYPE,
 3455  
                                   sym, s);
 3456  
             }
 3457  
         }
 3458  
 
 3459  
         // Compute the identifier's instantiated type.
 3460  
         // For methods, we need to compute the instance type by
 3461  
         // Resolve.instantiate from the symbol's type as well as
 3462  
         // any type arguments and value arguments.
 3463  3279
         noteWarner.warned = false;
 3464  3279
         Type owntype = rs.instantiate(env,
 3465  
                                       site,
 3466  
                                       sym,
 3467  
                                       argtypes,
 3468  
                                       typeargtypes,
 3469  
                                       true,
 3470  
                                       useVarargs,
 3471  
                                       noteWarner);
 3472  3279
         boolean warned = noteWarner.warned;
 3473  
 
 3474  
         // If this fails, something went wrong; we should not have
 3475  
         // found the identifier in the first place.
 3476  3279
         if (owntype == null) {
 3477  0
             if (!pt.isErroneous())
 3478  0
                 log.error(env.tree.pos(),
 3479  
                           MsgSym.MESSAGE_INTERNAL_ERROR_CANNOT_INSTANTIATE,
 3480  
                           sym, site,
 3481  
                           Type.toString(pt.getParameterTypes()));
 3482  0
             owntype = syms.errType;
 3483  
         } else {
 3484  
             // System.out.println("call   : " + env.tree);
 3485  
             // System.out.println("method : " + owntype);
 3486  
             // System.out.println("actuals: " + argtypes);
 3487  3279
             List<Type> formals = owntype.getParameterTypes();
 3488  3279
             Type last = useVarargs ? formals.last() : null;
 3489  3279
             if (sym.name==names.init &&
 3490  
                 sym.owner == syms.enumSym)
 3491  0
                 formals = formals.tail.tail;
 3492  3279
             List<JCExpression> args = argtrees;
 3493  6844
             while (formals.head != last) {
 3494  3565
                 JCTree arg = args.head;
 3495  3565
                 Warner warn = chk.convertWarner(arg.pos(), arg.type, formals.head);
 3496  3565
                 assertConvertible(arg, arg.type, formals.head, warn);
 3497  3565
                 warned |= warn.warned;
 3498  3565
                 args = args.tail;
 3499  3565
                 formals = formals.tail;
 3500  3565
             }
 3501  3279
             if (useVarargs) {
 3502  1
                 Type varArg = types.elemtype(last);
 3503  5
                 while (args.tail != null) {
 3504  4
                     JCTree arg = args.head;
 3505  4
                     Warner warn = chk.convertWarner(arg.pos(), arg.type, varArg);
 3506  4
                     assertConvertible(arg, arg.type, varArg, warn);
 3507  4
                     warned |= warn.warned;
 3508  4
                     args = args.tail;
 3509  4
                 }
 3510  1
             } else if ((sym.flags() & VARARGS) != 0 && allowVarargs) {
 3511  
                 // non-varargs call to varargs method
 3512  0
                 Type varParam = owntype.getParameterTypes().last();
 3513  0
                 Type lastArg = argtypes.last();
 3514  0
                 if (types.isSubtypeUnchecked(lastArg, types.elemtype(varParam)) &&
 3515  
                     !types.isSameType(types.erasure(varParam), types.erasure(lastArg)))
 3516  0
                     log.warning(argtrees.last().pos(), MsgSym.MESSAGE_INEXACT_NON_VARARGS_CALL,
 3517  
                                 types.elemtype(varParam),
 3518  
                                 varParam);
 3519  
             }
 3520  
 
 3521  3279
             if (warned && sym.type.tag == FORALL) {
 3522  0
                 String typeargs = "";
 3523  0
                 if (typeargtypes != null && typeargtypes.nonEmpty()) {
 3524  0
                     typeargs = "<" + Type.toString(typeargtypes) + ">";
 3525  
                 }
 3526  0
                 chk.warnUnchecked(env.tree.pos(),
 3527  
                                   MsgSym.MESSAGE_UNCHECKED_METH_INVOCATION_APPLIED,
 3528  
                                   sym,
 3529  
                                   sym.location(),
 3530  
                                   typeargs,
 3531  
                                   Type.toString(argtypes));
 3532  0
                 owntype = new MethodType(owntype.getParameterTypes(),
 3533  
                                          types.erasure(owntype.getReturnType()),
 3534  
                                          owntype.getThrownTypes(),
 3535  
                                          syms.methodClass);
 3536  
             }
 3537  3279
             if (useVarargs) {
 3538  1
                 JCTree tree = env.tree;
 3539  1
                 Type argtype = owntype.getParameterTypes().last();
 3540  1
                 if (!types.isReifiable(argtype))
 3541  0
                     chk.warnUnchecked(env.tree.pos(),
 3542  
                                       MsgSym.MESSAGE_UNCHECKED_GENERIC_ARRAY_CREATION,
 3543  
                                       argtype);
 3544  1
                 Type elemtype = types.elemtype(argtype);
 3545  1
                 switch (tree.getTag()) {
 3546  
                 case JCTree.APPLY:
 3547  1
                     ((JCMethodInvocation) tree).varargsElement = elemtype;
 3548  1
                     break;
 3549  
                 case JCTree.NEWCLASS:
 3550  0
                     ((JCNewClass) tree).varargsElement = elemtype;
 3551  0
                     break;
 3552  
                 default:
 3553  0
                     throw new AssertionError(""+tree);
 3554  
                 }
 3555  
             }
 3556  
         }
 3557  3279
         return owntype;
 3558  
     }
 3559  
 
 3560  
     private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) {
 3561  3569
         if (types.isConvertible(actual, formal, warn))
 3562  3569
             return;
 3563  
 
 3564  0
         if (formal.isCompound()
 3565  
             && types.isSubtype(actual, types.supertype(formal))
 3566  
             && types.isSubtypeUnchecked(actual, types.interfaces(formal), warn))
 3567  0
             return;
 3568  
 
 3569  
         if (false) {
 3570  
             // TODO: make assertConvertible work
 3571  
             chk.typeError(tree.pos(), JCDiagnostic.fragment(MsgSym.MESSAGE_INCOMPATIBLE_TYPES), actual, formal);
 3572  
             throw new AssertionError("Tree: " + tree
 3573  
                                      + " actual:" + actual
 3574  
                                      + " formal: " + formal);
 3575  
         }
 3576  0
     }
 3577  
 
 3578  
     @Override
 3579  
     public void visitImport(JCImport tree) {
 3580  
         // nothing to do
 3581  0
     }
 3582  
 
 3583  
     /** Finish the attribution of a class. */
 3584  
     public void attribClassBody(JavafxEnv<JavafxAttrContext> env, ClassSymbol c) {
 3585  670
         JFXClassDeclaration tree = (JFXClassDeclaration)env.tree;
 3586  670
         assert c == tree.sym;
 3587  
 
 3588  
         // Validate annotations
 3589  670
         chk.validateAnnotations(tree.mods.annotations, c);
 3590  
 
 3591  
         // Validate type parameters, supertype and interfaces.
 3592  670
         attribBounds(tree.getEmptyTypeParameters());
 3593  670
         chk.validateTypeParams(tree.getEmptyTypeParameters());
 3594  670
         chk.validate(tree.getSupertypes());
 3595  
 
 3596  
         // Check that class does not import the same parameterized interface
 3597  
         // with two different argument lists.
 3598  670
         chk.checkClassBounds(tree.pos(), c.type);
 3599  
 
 3600  670
         tree.type = c.type;
 3601  
 
 3602  670
         boolean assertsEnabled = false;
 3603  670
         assert assertsEnabled = true;
 3604  670
         if (assertsEnabled) {
 3605  631
             for (List<JCTypeParameter> l = tree.getEmptyTypeParameters();
 3606  631
                  l.nonEmpty(); l = l.tail)
 3607  0
                 assert env.info.scope.lookup(l.head.name).scope != null;
 3608  
         }
 3609  
 
 3610  
         // Check that a generic class doesn't extend Throwable
 3611  670
         if (!c.type.allparams().isEmpty() && types.isSubtype(c.type, syms.throwableType))
 3612  0
             log.error(tree.getExtending().head.pos(), MsgSym.MESSAGE_GENERIC_THROWABLE);
 3613  
 
 3614  2580
         for (List<JCTree> l = tree.getMembers(); l.nonEmpty(); l = l.tail) {
 3615  
             // Attribute declaration
 3616  1913
             attribStat(l.head, env);
 3617  
             // Check that declarations in inner classes are not static (JLS 8.1.2)
 3618  
             // Make an exception for static constants.
 3619  
             // Javafx allows that.
 3620  
 //            if (c.owner.kind != PCK &&
 3621  
 //                ((c.flags() & STATIC) == 0 || c.name == names.empty) &&
 3622  
 //                (TreeInfo.flags(l.head) & (STATIC | INTERFACE)) != 0) {
 3623  
 //                Symbol sym = null;
 3624  
 //                if (l.head.getTag() == JCTree.VARDEF) sym = ((JCVariableDecl) l.head).sym;
 3625  
 //                if (sym == null ||
 3626  
 //                    sym.kind != VAR ||
 3627  
 //                    ((VarSymbol) sym).getConstValue() == null)
 3628  
 //                    log.error(l.head.pos(), "icls.cant.have.static.decl");
 3629  
 //            }
 3630  
         }
 3631  
 
 3632  
         // If this is a non-abstract class, check that it has no abstract
 3633  
         // methods or unimplemented methods of an implemented interface.
 3634  667
         if ((c.flags() & (ABSTRACT | INTERFACE)) == 0) {
 3635  650
             if (!relax)
 3636  650
                 chk.checkAllDefined(tree.pos(), c);
 3637  
         }
 3638  
 
 3639  667
         if ((c.flags() & ANNOTATION) != 0) {
 3640  0
             if (tree.getImplementing().nonEmpty())
 3641  0
                 log.error(tree.getImplementing().head.pos(),
 3642  
                           MsgSym.MESSAGE_CANNOT_EXTEND_INTERFACE_ANNOTATION);
 3643  0
             if (tree.getEmptyTypeParameters().nonEmpty())
 3644  0
                 log.error(tree.getEmptyTypeParameters().head.pos(),
 3645  
                           MsgSym.MESSAGE_INTF_ANNOTATION_CANNOT_HAVE_TYPE_PARAMS);
 3646  
         } else {
 3647  
             // Check that all extended classes and interfaces
 3648  
             // are compatible (i.e. no two define methods with same arguments
 3649  
             // yet different return types).  (JLS 8.4.6.3)
 3650  667
             chk.checkCompatibleSupertypes(tree.pos(), c.type);
 3651  
         }
 3652  
 
 3653  
         // Check that all methods which implement some
 3654  
         // method conform to the method they implement.
 3655  667
         chk.checkImplementations(tree);
 3656  
 
 3657  667
         Scope enclScope = JavafxEnter.enterScope(env);
 3658  2577
         for (List<JCTree> l = tree.getMembers(); l.nonEmpty(); l = l.tail) {
 3659  1910
             if (l.head instanceof JFXFunctionDefinition)
 3660  1063
                 chk.checkUnique(l.head.pos(), ((JFXFunctionDefinition) l.head).sym, enclScope);
 3661  
         }
 3662  
 
 3663  
         // Check for cycles among non-initial constructors.
 3664  667
         chk.checkCyclicConstructors(tree);
 3665  
 
 3666  
         // Check for cycles among annotation elements.
 3667  667
         chk.checkNonCyclicElements(tree);
 3668  
 
 3669  
         // Check for proper use of serialVersionUID
 3670  667
         if (env.info.lint.isEnabled(Lint.LintCategory.SERIAL) &&
 3671  
             isSerializable(c) &&
 3672  
             (c.flags() & Flags.ENUM) == 0 &&
 3673  
             (c.flags() & ABSTRACT) == 0) {
 3674  0
             checkSerialVersionUID(tree, c);
 3675  
         }
 3676  667
     }
 3677  
         // where
 3678  
         /** check if a class is a subtype of Serializable, if that is available. */
 3679  
         private boolean isSerializable(ClassSymbol c) {
 3680  
             try {
 3681  0
                 syms.serializableType.complete();
 3682  
             }
 3683  0
             catch (CompletionFailure e) {
 3684  0
                 return false;
 3685  0
             }
 3686  0
             return types.isSubtype(c.type, syms.serializableType);
 3687  
         }
 3688  
 
 3689  
         /** Check that an appropriate serialVersionUID member is defined. */
 3690  
         private void checkSerialVersionUID(JFXClassDeclaration tree, ClassSymbol c) {
 3691  
 
 3692  
             // check for presence of serialVersionUID
 3693  0
             Scope.Entry e = c.members().lookup(names.serialVersionUID);
 3694  0
             while (e.scope != null && e.sym.kind != VAR) e = e.next();
 3695  0
             if (e.scope == null) {
 3696  0
                 log.warning(tree.pos(), MsgSym.MESSAGE_MISSING_SVUID, c);
 3697  0
                 return;
 3698  
             }
 3699  
 
 3700  
             // check that it is static final
 3701  0
             VarSymbol svuid = (VarSymbol)e.sym;
 3702  0
             if ((svuid.flags() & (STATIC | FINAL)) !=
 3703  
                 (STATIC | FINAL))
 3704  0
                 log.warning(TreeInfo.diagnosticPositionFor(svuid, tree), MsgSym.MESSAGE_IMPROPER_SVUID, c);
 3705  
 
 3706  
             // check that it is long
 3707  0
             else if (svuid.type.tag != TypeTags.LONG)
 3708  0
                 log.warning(TreeInfo.diagnosticPositionFor(svuid, tree), MsgSym.MESSAGE_LONG_SVUID, c);
 3709  
 
 3710  
             // check constant
 3711  0
             else if (svuid.getConstValue() == null)
 3712  0
                 log.warning(TreeInfo.diagnosticPositionFor(svuid, tree), MsgSym.MESSAGE_CONSTANT_SVUID, c);
 3713  0
         }
 3714  
 
 3715  
     protected Type capture(Type type) {
 3716  14793
         Type ctype = types.capture(type);
 3717  14793
         if (type instanceof FunctionType)
 3718  70
             ctype = new FunctionType((FunctionType) type);
 3719  14793
         return ctype;
 3720  
     }
 3721  
     
 3722  
     public void clearCaches() {
 3723  377
         varSymToTree = null;
 3724  377
     }
 3725  
 
 3726  
     void fixOverride(JFXFunctionDefinition tree, MethodSymbol m) {
 3727  1237
         ClassSymbol origin = (ClassSymbol)m.owner;
 3728  1237
         if ((origin.flags() & ENUM) != 0 && names.finalize.equals(m.name))
 3729  0
             if (m.overrides(syms.enumFinalFinalize, origin, types, false)) {
 3730  0
                 log.error(tree.pos(), MsgSym.MESSAGE_ENUM_NO_FINALIZE);
 3731  0
                 return;
 3732  
             }
 3733  
 
 3734  1237
         ListBuffer<Type> supertypes = ListBuffer.<Type>lb();
 3735  1237
         Set superSet = new HashSet<Type>();
 3736  1237
         types.getSupertypes(origin, supertypes, superSet);
 3737  
 
 3738  1237
         for (Type t : supertypes) {
 3739  1673
             if (t.tag == CLASS) {
 3740  1673
                 TypeSymbol c = t.tsym;
 3741  1673
                 Scope.Entry e = c.members().lookup(m.name);
 3742  1678
                 while (e.scope != null) {
 3743  126
                     e.sym.complete();
 3744  126
                     if (m.overrides(e.sym, origin, types, false))
 3745  121
                         if (fixOverride(tree, m, (MethodSymbol)e.sym, origin)) 
 3746  121
                             break;
 3747  5
                     e = e.next();
 3748  
                 }
 3749  1673
             }
 3750  
         }
 3751  1237
     }
 3752  
 
 3753  
 // Javafx modification
 3754  
 public
 3755  
 // Javafx modification
 3756  
     boolean fixOverride(JFXFunctionDefinition tree,
 3757  
                        MethodSymbol m,
 3758  
                        MethodSymbol other,
 3759  
                        ClassSymbol origin) {
 3760  
 
 3761  121
         Type mt = types.memberType(origin.type, m);
 3762  121
         Type ot = types.memberType(origin.type, other);
 3763  
         // Error if overriding result type is different
 3764  
         // (or, in the case of generics mode, not a subtype) of
 3765  
         // overridden result type. We have to rename any type parameters
 3766  
         // before comparing types.
 3767  121
         List<Type> mtvars = mt.getTypeArguments();
 3768  121
         List<Type> otvars = ot.getTypeArguments();
 3769  121
         Type mtres = mt.getReturnType();
 3770  121
         Type otres = types.subst(ot.getReturnType(), otvars, mtvars);
 3771  
 
 3772  121
         boolean resultTypesOK =
 3773  
             types.returnTypeSubstitutable(mt, ot, otres, null);
 3774  121
         if (!resultTypesOK) {
 3775  2
             if (!source.allowCovariantReturns() &&
 3776  
                 m.owner != origin &&
 3777  
                 m.owner.isSubClass(other.owner, types)) {
 3778  
                 // allow limited interoperability with covariant returns
 3779  
             }
 3780  
             else {
 3781  2
                 Type setReturnType = null;
 3782  2
                 int typeTag = -1;
 3783  2
                 if (mtres == syms.javafx_NumberType && otres == syms.floatType) {
 3784  2
                     setReturnType = syms.floatType;
 3785  2
                     typeTag = TypeTags.FLOAT;
 3786  
                 }
 3787  0
                 else if ((mtres == syms.javafx_IntegerType || mtres == syms.javafx_NumberType) && otres == syms.byteType) {
 3788  0
                     setReturnType = syms.byteType;
 3789  0
                     typeTag = TypeTags.BYTE;
 3790  
                 }
 3791  0
                 else if ((mtres == syms.javafx_IntegerType || mtres == syms.javafx_NumberType) && otres == syms.charType) {
 3792  0
                     setReturnType = syms.charType;
 3793  0
                     typeTag = TypeTags.CHAR;
 3794  
                 }
 3795  0
                 else if ((mtres == syms.javafx_IntegerType || mtres == syms.javafx_NumberType) && otres == syms.shortType) {
 3796  0
                     setReturnType = syms.shortType;
 3797  0
                     typeTag = TypeTags.SHORT;
 3798  
                 }
 3799  0
                 else if ((mtres == syms.javafx_IntegerType || mtres == syms.javafx_NumberType) && otres == syms.longType) {
 3800  0
                     setReturnType = syms.longType;
 3801  0
                     typeTag = TypeTags.LONG;
 3802  
                 }
 3803  
 
 3804  2
                 if (setReturnType != null) {
 3805  2
                     JFXType oldType = tree.operation.getJFXReturnType();
 3806  2
                     tree.operation.rettype = make.TypeClass(make.TypeIdent(typeTag), oldType.getCardinality());
 3807  2
                     if (mt instanceof MethodType) {
 3808  2
                         ((MethodType)mt).restype = setReturnType;
 3809  
                     }
 3810  
                     
 3811  2
                     if (tree.type != null && tree.type instanceof MethodType) {
 3812  2
                         ((MethodType)tree.type).restype = setReturnType;
 3813  
                     }
 3814  
                 }
 3815  
             }
 3816  
         }
 3817  
 
 3818  121
         return true;
 3819  
     }
 3820  
 
 3821  
     public void visitTimeLiteral(JFXTimeLiteral tree) {
 3822  22
         result = check(tree, syms.javafx_DurationType, VAL, pkind, pt, pSequenceness);
 3823  22
     }
 3824  
 
 3825  
     public void visitInterpolate(JFXInterpolate tree) {
 3826  0
         throw new Error();
 3827  
         /*
 3828  
         tree.getVariable().accept(this);
 3829  
         for (InterpolateValueTree t : tree.getInterpolateValues()) {
 3830  
             checkInterpolationValue((JFXInterpolateValue)t, tree.getVariable());
 3831  
         }
 3832  
         Type owntype = tree.getVariable().type;
 3833  
         result = check(tree, owntype, VAL, pkind, pt, pSequenceness);
 3834  
         */
 3835  
     }
 3836  
 
 3837  
     public void visitInterpolateValue(JFXInterpolateValue tree) {
 3838  5
         attribExpr(tree.attribute, env);
 3839  5
         attribExpr(tree.value, env, tree.attribute.type);
 3840  5
         if (tree.interpolation != null)
 3841  1
             attribExpr(tree.interpolation, env);
 3842  5
         result = check(tree, syms.javafx_KeyValueType, VAL, pkind, pt, pSequenceness);
 3843  5
     }
 3844  
 
 3845  
     /*
 3846  
     private void checkInterpolationValue(JFXInterpolateValue tree, JCExpression var) {
 3847  
         final Type targetType;
 3848  
         if (tree.getAttribute() != null) {
 3849  
             JCExpression t = tree.getAttribute();
 3850  
             JavafxEnv<JavafxAttrContext> localEnv = newLocalEnv(tree);
 3851  
             Name attribute = names.fromString(t.toString());
 3852  
             Symbol memberSym = rs.findIdentInType(env, var.type, attribute, VAR);
 3853  
             memberSym = rs.access(memberSym, t.pos(), var.type, attribute, true);
 3854  
             memberSym.complete();
 3855  
             t.type = memberSym.type;
 3856  
             t.sym = memberSym;
 3857  
             targetType = t.type;
 3858  
         } else
 3859  
             targetType = var.type;
 3860  
         Type valueType = attribExpr(tree.getValue(), env, Infer.anyPoly);
 3861  
 
 3862  
         Type interpolateType = syms.errType;
 3863  
         if (types.isAssignable(valueType, syms.javafx_ColorType)) {
 3864  
             interpolateType = syms.javafx_ColorInterpolatorType;
 3865  
         } else if (types.isAssignable(valueType, syms.javafx_NumberType) || 
 3866  
                    types.isAssignable(valueType, syms.javafx_IntegerType)) {
 3867  
             interpolateType = syms.javafx_NumberInterpolatorType;
 3868  
         } else {
 3869  
             log.error(tree.pos(), "unexpected.type", Resolve.kindNames(pkind), Resolve.kindName(pkind));
 3870  
             interpolateType = syms.errType;
 3871  
         }
 3872  
         tree.type = interpolateType;
 3873  
         result = tree.type;
 3874  
     }
 3875  
     */
 3876  
     
 3877  
     public void visitKeyFrameLiteral(JFXKeyFrameLiteral tree) {
 3878  0
         throw new UnsupportedOperationException("Not supported yet.");
 3879  
     }
 3880  
 }