Coverage Report - com.sun.tools.javafx.comp.JavafxToJava
 
Classes in this File Line Coverage Branch Coverage Complexity
JavafxToJava
85%
933/1099
73%
432/592
0
JavafxToJava$1
100%
4/4
N/A
0
JavafxToJava$10
75%
12/16
40%
4/10
0
JavafxToJava$11
100%
1/1
N/A
0
JavafxToJava$1FillClassesWithOuters
100%
33/33
88%
23/26
0
JavafxToJava$2
100%
2/2
N/A
0
JavafxToJava$3
60%
9/15
N/A
0
JavafxToJava$4
100%
4/4
N/A
0
JavafxToJava$5
100%
4/4
N/A
0
JavafxToJava$6
81%
46/57
71%
30/42
0
JavafxToJava$7
100%
2/2
N/A
0
JavafxToJava$8
87%
72/83
69%
58/84
0
JavafxToJava$9
97%
30/31
91%
20/22
0
JavafxToJava$FunctionCallTranslator
100%
19/19
89%
57/64
0
JavafxToJava$InstanciateTranslator
100%
59/59
84%
37/44
0
JavafxToJava$StringExpressionTranslator
98%
43/44
91%
20/22
0
JavafxToJava$Translator
100%
9/9
N/A
0
JavafxToJava$TypeCastTranslator
89%
8/9
100%
4/4
0
JavafxToJava$UseSequenceBuilder
92%
23/25
90%
9/10
0
JavafxToJava$Wrapped
100%
3/3
N/A
0
JavafxToJava$Yield
100%
4/4
N/A
0
 
 1  
 /*
 2  
  * Copyright 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  
 package com.sun.tools.javafx.comp;
 26  
 
 27  
 import java.util.HashSet;
 28  
 import java.util.Set;
 29  
 import java.util.regex.Pattern;
 30  
 import javax.lang.model.type.TypeKind;
 31  
 
 32  
 import com.sun.javafx.api.JavafxBindStatus;
 33  
 import com.sun.javafx.api.tree.SequenceSliceTree;
 34  
 import com.sun.tools.javac.code.*;
 35  
 import static com.sun.tools.javac.code.Flags.*;
 36  
 import com.sun.tools.javac.code.Type.*;
 37  
 import com.sun.tools.javac.jvm.Target;
 38  
 import com.sun.tools.javac.tree.JCTree;
 39  
 import com.sun.tools.javac.tree.JCTree.*;
 40  
 import com.sun.tools.javac.tree.TreeInfo;
 41  
 import com.sun.tools.javac.tree.TreeMaker;
 42  
 import com.sun.tools.javac.util.*;
 43  
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 44  
 import com.sun.tools.javafx.code.FunctionType;
 45  
 import com.sun.tools.javafx.code.JavafxFlags;
 46  
 import com.sun.tools.javafx.code.JavafxSymtab;
 47  
 import com.sun.tools.javafx.code.JavafxTypes;
 48  
 import static com.sun.tools.javafx.code.JavafxVarSymbol.*;
 49  
 import static com.sun.tools.javafx.comp.JavafxDefs.*;
 50  
 import com.sun.tools.javafx.comp.JavafxInitializationBuilder.JavafxClassModel;
 51  
 import com.sun.tools.javafx.comp.JavafxAnalyzeClass.TranslatedAttributeInfo;
 52  
 import com.sun.tools.javafx.comp.JavafxAnalyzeClass.TranslatedOverrideAttributeInfo;
 53  
 import com.sun.tools.javafx.comp.JavafxTypeMorpher.TypeMorphInfo;
 54  
 import com.sun.tools.javafx.comp.JavafxTypeMorpher.VarMorphInfo;
 55  
 import com.sun.tools.javafx.tree.*;
 56  
 
 57  
 /**
 58  
  * Translate JavaFX ASTs into Java ASTs
 59  
  * 
 60  
  * @author Robert Field
 61  
  * @author Per Bothner
 62  
  * @author Lubo Litchev
 63  
  */
 64  6241
 public class JavafxToJava extends JavafxTranslationSupport implements JavafxVisitor {
 65  12
     protected static final Context.Key<JavafxToJava> jfxToJavaKey =
 66  
         new Context.Key<JavafxToJava>();
 67  
 
 68  
     /*
 69  
      * the result of translating a tree by a visit method
 70  
      */
 71  
     JCTree result;
 72  
 
 73  
     /*
 74  
      * modules imported by context
 75  
      */
 76  
     private final JavafxToBound toBound;  
 77  
     private final JavafxInitializationBuilder initBuilder;
 78  
     
 79  
     private final JCExpression doNotInitializeMarker;
 80  
     
 81  
     /*
 82  
      * Buffers holding definitions waiting to be prepended to the current list of definitions.
 83  
      * At class or top-level these are the same.  
 84  
      * Within a method (or block) prependToStatements is split off.
 85  
      * They need to be different because anonymous classes need to be declared in the scope of the method,
 86  
      * but interfaces can't be declared here.
 87  
      */
 88  399
     private ListBuffer<JCStatement> prependToDefinitions = null;
 89  399
     private ListBuffer<JCStatement> prependToStatements = null;
 90  
     
 91  399
     private ListBuffer<JCExpression> additionalImports = null;
 92  
 
 93  36
     public enum Wrapped {
 94  12
         InLocation,
 95  12
         InNothing
 96  
     }
 97  
 
 98  399
     Wrapped wrap = Wrapped.InNothing;
 99  
 
 100  
     
 101  
     // for type morphing
 102  53
     enum Yield {
 103  12
         ToExpression,
 104  12
         ToReturnStatement,
 105  12
         ToExecStatement
 106  
     }
 107  
 
 108  
     //TODO: all these should, probably, go into a translation wrap class
 109  399
     Yield yield = Yield.ToExpression;
 110  
     
 111  
     private JavafxEnv<JavafxAttrContext> attrEnv;
 112  
     private Target target;
 113  
 
 114  
     abstract static class Translator {
 115  
 
 116  
         protected DiagnosticPosition diagPos;
 117  
         protected final JavafxToJava toJava;
 118  
         protected final JavafxDefs defs;
 119  
         protected final JavafxTypes types;
 120  
         protected final JavafxSymtab syms;
 121  
 
 122  6769
         Translator(DiagnosticPosition diagPos, JavafxToJava toJava) {
 123  6769
             this.diagPos = diagPos;
 124  6769
             this.toJava = toJava;
 125  6769
             this.defs = toJava.defs;
 126  6769
             this.types = toJava.types;
 127  6769
             this.syms = toJava.syms;
 128  6769
         }
 129  
 
 130  
         protected abstract JCTree doit();
 131  
 
 132  
         protected TreeMaker m() {
 133  18076
             return toJava.make.at(diagPos);
 134  
         }
 135  
 
 136  
         /**
 137  
          * Convert type to JCExpression
 138  
          */
 139  
         protected JCExpression makeExpression(Type type) {
 140  1554
             return toJava.makeTypeTree(diagPos, type, true);
 141  
         }
 142  
     }
 143  
     
 144  
     /*
 145  
      * static information
 146  
      */
 147  
     static final boolean generateNullChecks = true;
 148  
     
 149  
     private static final String sequencesRangeString = "com.sun.javafx.runtime.sequence.Sequences.range";
 150  
     private static final String sequencesRangeExclusiveString = "com.sun.javafx.runtime.sequence.Sequences.rangeExclusive";
 151  
     private static final String sequenceBuilderString = "com.sun.javafx.runtime.sequence.SequenceBuilder";
 152  
     private static final String boundSequenceBuilderString = "com.sun.javafx.runtime.sequence.BoundSequenceBuilder";
 153  
     private static final String toSequenceString = "toSequence";
 154  
     private static final String methodThrowsString = "java.lang.Throwable";
 155  
     private JFXClassDeclaration currentClass;  //TODO: this is redundant with attrEnv.enclClass
 156  
 
 157  
     /** Class symbols for classes that need a reference to the outer class. */
 158  399
     Set<ClassSymbol> hasOuters = new HashSet<ClassSymbol>();
 159  
     
 160  399
     private Set<VarSymbol> locallyBound = new HashSet<VarSymbol>();
 161  
     
 162  12
     private static final Pattern EXTENDED_FORMAT_PATTERN = Pattern.compile("%[<$0-9]*[tT][guwxGUVWXE]");
 163  
     
 164  
     public static JavafxToJava instance(Context context) {
 165  1596
         JavafxToJava instance = context.get(jfxToJavaKey);
 166  1596
         if (instance == null)
 167  399
             instance = new JavafxToJava(context);
 168  1596
         return instance;
 169  
     }
 170  
 
 171  
     protected JavafxToJava(Context context) {
 172  399
         super(context);
 173  
         
 174  399
         context.put(jfxToJavaKey, this);
 175  
 
 176  399
         toBound = JavafxToBound.instance(context);
 177  399
         initBuilder = JavafxInitializationBuilder.instance(context);
 178  399
         target = Target.instance(context);
 179  
         
 180  399
         doNotInitializeMarker = make.Literal(TypeTags.INT, 666);
 181  399
     }
 182  
     
 183  
     /** Visitor method: Translate a single node.
 184  
      */
 185  
     @SuppressWarnings("unchecked")
 186  
     public <T extends JCTree> T translate(T tree) {
 187  
         T ret;
 188  37440
         Yield prevYield = yield;
 189  37440
         yield = Yield.ToExpression; // reset to default
 190  37440
         if (tree == null) {
 191  466
             ret = null;
 192  
         } else {
 193  36974
             tree.accept(this);
 194  36974
             ret = (T)this.result;
 195  36974
             this.result = null;
 196  
         }
 197  37440
         yield = prevYield;
 198  37440
         return ret;
 199  
     }
 200  
     
 201  
     public JCExpression translate(JCExpression tree, Type type) {
 202  5389
         if (tree == null)
 203  0
             return null;
 204  5389
         return convertTranslated(translate(tree), tree.pos(), tree.type, type);
 205  
     }
 206  
     
 207  
     public JCExpression convertTranslated(JCExpression translated, DiagnosticPosition diagPos,
 208  
             Type sourceType, Type type) {
 209  5515
         if (types.isSequence(sourceType) && types.isArray(type)) {
 210  1
             ListBuffer<JCStatement> stats = ListBuffer.lb();
 211  1
             Type elemType = types.elemtype(type);
 212  1
             if (elemType.isPrimitive()) {
 213  0
                 String mname = "toArray";
 214  0
                 if (elemType == syms.floatType)
 215  0
                     mname = "toFloatArray";
 216  0
                 return callExpression(diagPos, makeTypeTree( diagPos,syms.javafx_SequencesType, false),
 217  
                        mname, translated);
 218  
             }
 219  1
             JCVariableDecl tmpVar = makeTmpVar(diagPos, sourceType, translated);
 220  1
             stats.append(tmpVar);
 221  1
             JCVariableDecl arrVar = makeTmpVar(diagPos, "arr", type, 
 222  
                     make.NewArray(makeTypeTree(diagPos, elemType, true),
 223  
                         List.<JCExpression>of(callExpression(diagPos, make.Ident(tmpVar.name), "size")), null));
 224  1
             stats.append(arrVar);
 225  1
             stats.append(callStatement(diagPos, make.Ident(tmpVar.name), "toArray",
 226  
                             List.of(make.Ident(arrVar.name), make.Literal(TypeTags.INT, 0))));
 227  1
             JCIdent ident2 = make.Ident(arrVar.name);
 228  1
             return makeBlockExpression(diagPos, stats, ident2);
 229  
             
 230  
         }
 231  5514
         if (types.isArray(sourceType) && types.isSequence(type)) {
 232  7
             ListBuffer<JCStatement> stats = ListBuffer.lb();
 233  7
             Type elemType = types.elemtype(sourceType);
 234  7
             String mname = "fromArray";
 235  7
             if (elemType.isPrimitive())
 236  1
                 return callExpression(diagPos, makeTypeTree( diagPos,syms.javafx_SequencesType, false),
 237  
                        mname, translated);
 238  
             else {
 239  6
                 List<JCExpression> args = 
 240  
                         List.of(make.at(diagPos).Select(makeTypeTree(diagPos, elemType, true), names._class),
 241  
                         translated);
 242  6
                 return callExpression(diagPos, makeTypeTree( diagPos,syms.javafx_SequencesType, false),
 243  
                        mname, args);
 244  
             }
 245  
         }
 246  5507
         if (types.isSequence(type) && ! types.isSequence(sourceType)) {
 247  35
             return callExpression(diagPos,
 248  
                     makeQualifiedTree(diagPos, "com.sun.javafx.runtime.sequence.Sequences"),
 249  
                     "singleton",
 250  
                     List.of(makeElementClassObject(diagPos, types.elementType(type)),
 251  
                             translated));
 252  
         }        
 253  
 
 254  5472
         if (sourceType == syms.javafx_IntegerType ||
 255  
                 type == syms.javafx_IntegerType) {
 256  1112
             if (sourceType != type && type.isPrimitive()) {
 257  137
                 translated = make.at(diagPos).TypeCast(type, translated);
 258  
             }
 259  
         }
 260  
 
 261  5472
         return translated;
 262  
     }
 263  
 
 264  
     /** Visitor method: translate a list of nodes.
 265  
      */
 266  
     public <T extends JCTree> List<T> translate(List<T> trees) {
 267  4441
         ListBuffer<T> translated = ListBuffer.lb();
 268  4441
         if (trees == null) return null;
 269  7215
         for (List<T> l = trees; l.nonEmpty();  l = l.tail) {
 270  2774
             T tree = translate(l.head);
 271  2774
             if (tree != null) {
 272  2774
                 translated.append( tree );
 273  
             }
 274  
         }
 275  4441
         return translated.toList();
 276  
     }
 277  
     
 278  
      public List<JCExpression> translate(List<JCExpression> trees, List<Type> types) {
 279  100
         ListBuffer<JCExpression> translated = ListBuffer.lb();
 280  100
         if (trees == null) return null;
 281  100
         List<Type> t = types;
 282  197
         for (List<JCExpression> l = trees; l.nonEmpty();  l = l.tail, t = t.tail) {
 283  97
             JCExpression tree = translate(l.head, t.head);
 284  97
             if (tree != null) {
 285  97
                 translated.append( tree );
 286  
             }
 287  
         }
 288  100
         return translated.toList();
 289  
     }
 290  
      
 291  
      /**
 292  
      * Translate a list of statements, 
 293  
      * The purpose of this method is to prepend an anonymous class definition in the correct
 294  
      * scope.  However, that is currently disabled since generated classes define static members
 295  
      * and that isn't allowed by an (unmodified) javac back-end.
 296  
      * */
 297  
     private List<JCStatement> translateStatements(List<JCStatement> stmts) {
 298  580
         ListBuffer<JCStatement> prevPrependToStatements = prependToStatements;
 299  580
         prependToStatements = ListBuffer.lb();
 300  580
         List<JCStatement> translatedStats = translate(stmts);
 301  580
         translatedStats = translatedStats.prependList(prependToStatements.toList());
 302  580
         prependToStatements = prevPrependToStatements;
 303  580
         return translatedStats;
 304  
     }
 305  
     
 306  
     //// Translation with wrap transition
 307  
     
 308  
     public <T extends JCTree> T translate(T tree, Wrapped newState) {
 309  8986
         Wrapped prevWrap = wrap;
 310  8986
         wrap = newState;
 311  8986
         T ret = translate(tree);
 312  8986
         wrap = prevWrap;
 313  8986
         return ret;
 314  
     }
 315  
 
 316  
     JCStatement translateExpressionToStatement(JCExpression expr) {
 317  5953
         assert yield != Yield.ToExpression;
 318  5953
         if (expr == null) {
 319  0
             return null;
 320  
         } else {
 321  5953
             expr.accept(this);
 322  5953
             JCTree ret = this.result;
 323  5953
             this.result = null;
 324  5953
             return ret instanceof JCStatement? 
 325  
                 (JCStatement)ret  // already converted
 326  
                 : toCorrectReturn(expr, (JCExpression)ret );
 327  
         }
 328  
     }
 329  
 
 330  
     JCStatement translateExpressionToStatement(JCExpression expr, Wrapped newState, Type targetType) {
 331  4106
         Wrapped prevWrap = wrap;
 332  4106
         Yield prevYield = yield;
 333  4106
         wrap = newState;
 334  
         JCStatement ret;
 335  4106
         if (targetType == expr.type || targetType==syms.voidType
 336  
                 || targetType == null || expr.type == syms.unreachableType) {
 337  4097
             yield = targetType==syms.voidType? Yield.ToExecStatement : Yield.ToReturnStatement;
 338  4097
             ret = translateExpressionToStatement(expr);
 339  
         } else {
 340  9
             yield = Yield.ToExpression;
 341  9
             ret = make.at(expr).Return(translate(expr, targetType));
 342  
         }
 343  4106
         yield = prevYield;
 344  4106
         wrap = prevWrap;
 345  4106
         return ret;
 346  
     }
 347  
 
 348  
     JCStatement translateExpressionToStatement(JCExpression expr, Type targetType) {
 349  4106
         return translateExpressionToStatement(expr, wrap,  targetType);
 350  
     }
 351  
 
 352  
     void setLocallyBound(VarSymbol vsym) {
 353  45
         locallyBound.add(vsym);
 354  45
     }
 355  
 
 356  
     JCBlock asBlock(JCStatement stmt) {
 357  831
         if (stmt.getTag() == JavafxTag.BLOCK) {
 358  339
             return (JCBlock)stmt;
 359  
         } else {
 360  492
             return make.at(stmt).Block(0L, List.of(stmt));
 361  
         }
 362  
     }
 363  
     
 364  
     JCStatement toCorrectReturn(JCExpression expr, JCExpression translated) {
 365  2290
         switch (yield) {
 366  
             case ToExecStatement:
 367  1921
                 return make.at(expr).Exec( translated );
 368  
             case ToReturnStatement:
 369  369
                 return make.at(expr).Return( translated );
 370  
             case ToExpression:
 371  
             default:
 372  0
                 assert false : "this method should not be called";
 373  0
                 return null;
 374  
         }
 375  
     }
 376  
     
 377  
     public void toJava(JavafxEnv<JavafxAttrContext> attrEnv) {
 378  340
         this.attrEnv = attrEnv;
 379  
         
 380  340
         attrEnv.toplevel = translate(attrEnv.toplevel);
 381  340
     }
 382  
 
 383  
     /**
 384  
      * Fixup up block before translation.
 385  
      * For now this is only done for the run methods's block, and all we do is
 386  
      * convert to static variables that are accessed by other methods or classes.
 387  
      * In the future, I also want to:
 388  
      * (a) pre-allocate variables that need morphing ta the top of the block,
 389  
      * so we can do forward references.
 390  
      * (b) If a variable is final and initialized by an object literal,
 391  
      * invoke the Java constructor first, so we can make cyclic data structures. 
 392  
      * 
 393  
      * @param body The block to mogrify.
 394  
      * @param module If non-null, the module class whose body this is.
 395  
      */
 396  
     public void fixupBlockExpression (JFXBlockExpression body, JFXClassDeclaration module) {
 397  340
         boolean changed = false;
 398  340
         ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
 399  
 
 400  340
         for (JCStatement stat : body.stats) {
 401  2351
             if (stat instanceof JFXVar) {
 402  781
                 JFXVar decl = (JFXVar) stat;
 403  781
                 if ((decl.sym.flags_field & JavafxFlags.INNER_ACCESS) != 0) {
 404  35
                    decl.sym.flags_field |= STATIC;
 405  35
                    changed = true;
 406  35
                    JCExpression init = decl.init;
 407  35
                    decl.sym.owner = module.type.tsym;
 408  35
                    if (init != null) {
 409  33
                         Name name = decl.name;
 410  33
                         make.at(decl);
 411  33
                         JavafxBindStatus bindStatus = decl.getBindStatus();
 412  33
                         if (bindStatus != JavafxBindStatus.UNBOUND)
 413  4
                             init = fxmake.BindExpression(init, bindStatus);
 414  33
                         JCIdent lhs = make.Ident(name);
 415  33
                         lhs.sym = decl.sym;
 416  33
                         stats.append(make.Exec(make.Assign(lhs, init)));
 417  33
                         decl.init = doNotInitializeMarker;
 418  
                     }
 419  35
                    module.setMembers(module.getMembers().prepend(decl));
 420  35
                    continue;
 421  
                 }
 422  
             }
 423  2316
             stats.append(stat);
 424  
         }
 425  340
         if (changed) {
 426  18
             body.stats = stats.toList();
 427  
         }
 428  340
     }
 429  
 
 430  
     /**
 431  
      * Fixup up block before translation.
 432  
      * For now this is only done for the run methods's block, and all we do is
 433  
      * convert to static variables that are accessed by other methods, classes,
 434  
      * or attribute initializers (including those being moved out)
 435  
      * 
 436  
      * @param body The block to mogrify.
 437  
      * @param module If non-null, the module class whose body this is.
 438  
      */
 439  
     /**********************
 440  
     public void fixupBlockExpression (JFXBlockExpression body, JFXClassDeclaration module) {
 441  
         final Map<VarSymbol, JFXVar> toModule = new HashMap<VarSymbol, JFXVar>(); //vars to move to module level
 442  
         final Map<VarSymbol, JFXVar> candidate = new HashMap<VarSymbol, JFXVar>(); //other top-level vars
 443  
         
 444  
         // scanner that moves any top-level var to the module if it is
 445  
         // referenced in the initializer of a var moved to the module
 446  
         final JavafxTreeScanner scanner = new JavafxTreeScanner() {
 447  
 
 448  
             @Override
 449  
             public void visitIdent(JCIdent tree) {
 450  
                 if (tree.sym instanceof VarSymbol) {
 451  
                     VarSymbol vsym = (VarSymbol) tree.sym;
 452  
                     JFXVar usedVar = candidate.get(vsym);
 453  
                     if (usedVar != null) {
 454  
                         candidate.remove(vsym);
 455  
                         toModule.put(vsym, usedVar);
 456  
                         scan(usedVar.getInitializer());
 457  
                     }
 458  
                 }
 459  
             }
 460  
         };
 461  
 
 462  
         // top-level variables that have inner references are marked for moving to the module
 463  
         // all others are candidates for movement
 464  
         for (JCStatement stat : body.stats) {
 465  
             if (stat instanceof JFXVar) {
 466  
                 JFXVar decl = (JFXVar) stat;
 467  
                 if ((decl.sym.flags_field & JavafxFlags.INNER_ACCESS) != 0) {
 468  
                     toModule.put(decl.sym, decl);  // if they have
 469  
                 } else {
 470  
                     candidate.put(decl.sym, decl);
 471  
                 }
 472  
             }
 473  
         }
 474  
         
 475  
         // look for top-level vars referenced in the initializer of those to be moved
 476  
         // clone to avoid concurrent modification
 477  
         for (JFXVar var : toModule.values().toArray(new JFXVar[toModule.values().size()])) {
 478  
             scanner.scan(var);
 479  
         }
 480  
         
 481  
         if (toModule.size() > 0) {
 482  
             // there are variables to move to the module -- move them
 483  
             ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
 484  
             for (JCStatement stat : body.stats) {
 485  
                 JFXVar var;
 486  
                 VarSymbol vsym;
 487  
                 if (stat instanceof JFXVar && toModule.containsKey(vsym = (var = (JFXVar) stat).sym)) {
 488  
                     // this is a variable marked to be moved to the module -- do so
 489  
                     vsym.flags_field |= STATIC;
 490  
                     vsym.owner = module.type.tsym;
 491  
                     module.setMembers(module.getMembers().prepend(var));
 492  
                 } else {
 493  
                     // all other statements remain
 494  
                     stats.append(stat);
 495  
                 }
 496  
             }
 497  
             body.stats = stats.toList();
 498  
         }
 499  
     }
 500  
      * ****/
 501  
 
 502  
     @Override
 503  
     public void visitTopLevel(JCCompilationUnit tree) {
 504  340
         for (JCTree def : tree.defs) {
 505  733
             if (def instanceof JFXClassDeclaration) {
 506  340
                 JFXClassDeclaration cdecl = (JFXClassDeclaration) def;
 507  340
                 JFXFunctionDefinition runMethod = cdecl.runMethod;
 508  340
                 if (runMethod != null) {
 509  340
                     fixupBlockExpression(runMethod.getBodyExpression(), cdecl);
 510  
                 }
 511  733
             }
 512  
         }
 513  
         // add to the hasOuters set the clas symbols for classes that need a reference to the outer class
 514  340
         fillClassesWithOuters(tree);
 515  
         
 516  340
        ListBuffer<JCTree> translatedDefinitions= ListBuffer.lb();
 517  340
        ListBuffer<JCTree> imports= ListBuffer.lb();
 518  340
        additionalImports = ListBuffer.lb();
 519  340
        prependToStatements = prependToDefinitions = ListBuffer.lb();
 520  340
        for (JCTree def : tree.defs) {
 521  733
             if (def.getTag() == JCTree.IMPORT) {
 522  393
                 imports.append(def);
 523  393
                  if (!((JCImport)def).isStatic()) {
 524  393
                     if (((JCImport)def).getQualifiedIdentifier().getTag() == JCTree.SELECT) {
 525  393
                         JCFieldAccess select = (JCFieldAccess)((JCImport)def).getQualifiedIdentifier();
 526  393
                         if (select.name != names.asterisk &&
 527  
                                 types.isCompoundClass(select.sym)) {
 528  18
                            imports.append(make.Import(make.Select(
 529  
                                         translate( select.selected ), 
 530  
                                         names.fromString(select.name.toString() + interfaceSuffix)), 
 531  
                                    false));
 532  
                         }
 533  393
                     }  else if (((JCImport)def).getQualifiedIdentifier().getTag() == JCTree.IDENT) {
 534  0
                         JCIdent ident = (JCIdent)((JCImport)def).getQualifiedIdentifier();
 535  0
                         if (ident.name != names.asterisk &&
 536  
                                 types.isCompoundClass(ident.sym)) {
 537  0
                             imports.append(make.Import(make.Ident(names.fromString(ident.name.toString() + interfaceSuffix)), false));
 538  
                         }
 539  0
                     }
 540  
                 }
 541  
             } else {
 542  
                 // anything but an import
 543  340
                 translatedDefinitions.append( translate(def) );
 544  
             }
 545  
         }
 546  
 
 547  
        // order is imports, any prepends, then the translated non-imports
 548  340
         for (JCTree prepend : prependToDefinitions) {
 549  334
             translatedDefinitions.prepend(prepend);
 550  
         }
 551  
        
 552  340
         for (JCTree prepend : imports) {
 553  411
             translatedDefinitions.prepend(prepend);
 554  
         }
 555  
         
 556  340
         for (JCExpression prepend : additionalImports) {
 557  10
             translatedDefinitions.append(make.Import(prepend, false));
 558  
         }
 559  
 
 560  340
         prependToStatements = prependToDefinitions = null; // shouldn't be used again until the next top level
 561  
 
 562  340
          JCExpression pid = tree.pid;  //translate(tree.pid);
 563  340
         JCCompilationUnit translated = make.at(tree.pos).TopLevel(List.<JCAnnotation>nil(), pid, translatedDefinitions.toList());
 564  340
         translated.sourcefile = tree.sourcefile;
 565  340
         translated.docComments = tree.docComments;
 566  340
         translated.lineMap = tree.lineMap;
 567  340
         translated.flags = tree.flags;
 568  340
         result = translated;
 569  340
    }
 570  
     
 571  
     @Override
 572  
     public void visitClassDeclaration(JFXClassDeclaration tree) {
 573  612
         JFXClassDeclaration prevClass = currentClass;
 574  612
         JFXClassDeclaration prevEnclClass = attrEnv.enclClass;
 575  612
         Wrapped prevWrap = wrap;
 576  612
         wrap = Wrapped.InNothing;
 577  612
         currentClass = tree;
 578  
 
 579  
         try {
 580  612
             DiagnosticPosition diagPos = tree.pos();
 581  
 
 582  612
             attrEnv.enclClass = tree;
 583  
 
 584  612
             ListBuffer<JCStatement> translatedInitBlocks = ListBuffer.lb();
 585  612
             ListBuffer<JCStatement> translatedPostInitBlocks = ListBuffer.lb();
 586  612
             ListBuffer<JCTree> translatedDefs = ListBuffer.lb();
 587  612
             ListBuffer<TranslatedAttributeInfo> attrInfo = ListBuffer.lb();
 588  612
             ListBuffer<TranslatedOverrideAttributeInfo> overrideInfo = ListBuffer.lb();
 589  
 
 590  
            // translate all the definitions that make up the class.
 591  
            // collect any prepended definitions, and prepend then to the tranlations
 592  612
             ListBuffer<JCStatement> prevPrependToDefinitions = prependToDefinitions;
 593  612
             ListBuffer<JCStatement> prevPrependToStatements = prependToStatements;
 594  612
             prependToStatements = prependToDefinitions = ListBuffer.lb();
 595  
             {
 596  612
                 for (JCTree def : tree.getMembers()) {
 597  1859
                     switch(def.getTag()) {
 598  
                         case JavafxTag.INIT_DEF: {
 599  30
                             translatedInitBlocks.append(translate((JCBlock) ((JFXInitDefinition) def).getBody()));
 600  30
                             break;
 601  
                         }
 602  
                         case JavafxTag.POSTINIT_DEF: {
 603  10
                             translatedPostInitBlocks.append(translate((JCBlock) ((JFXPostInitDefinition) def).getBody()));
 604  10
                             break;
 605  
                         }
 606  
                         case JavafxTag.VAR_DEF: {
 607  556
                             JFXVar attrDef = (JFXVar) def;
 608  556
                             boolean isStatic = (attrDef.getModifiers().flags & STATIC) != 0;
 609  556
                             JCStatement init = attrDef.getInitializer()==doNotInitializeMarker? null :
 610  
                                 translateDefinitionalAssignmentToSet(attrDef.pos(), 
 611  
                                 attrDef.getInitializer(), attrDef.getBindStatus(), attrDef.sym,
 612  
                                 isStatic? null : make.Ident(defs.receiverName), FROM_DEFAULT_MILIEU);
 613  556
                             attrInfo.append(new TranslatedAttributeInfo(
 614  
                                     attrDef,
 615  
                                     typeMorpher.varMorphInfo(attrDef.sym),
 616  
                                     init,
 617  
                                     translate(attrDef.getOnReplace())));
 618  
                             //translatedDefs.append(trans);
 619  556
                             break;
 620  
                         }
 621  
                         case JavafxTag.OVERRIDE_ATTRIBUTE_DEF: {
 622  9
                             JFXOverrideAttribute override = (JFXOverrideAttribute) def;
 623  9
                             boolean isStatic = (override.sym.flags() & STATIC) != 0;
 624  
                             JCStatement init;
 625  9
                             if (override.getInitializer() == null) {
 626  0
                                 init = null;
 627  
                             } else {
 628  9
                                 init = translateDefinitionalAssignmentToSet(override.pos(),
 629  
                                     override.getInitializer(), override.getBindStatus(), override.sym,
 630  
                                     isStatic? null : make.Ident(defs.receiverName), 
 631  
                                     FROM_DEFAULT_MILIEU);
 632  
                             }
 633  9
                             overrideInfo.append(new TranslatedOverrideAttributeInfo(
 634  
                                     override,
 635  
                                     typeMorpher.varMorphInfo(override.sym),
 636  
                                     init,
 637  
                                     translate(override.getOnReplace())));
 638  9
                             break;
 639  
                         }
 640  
                        case JavafxTag.FUNCTION_DEF : {
 641  1008
                            JFXFunctionDefinition funcDef = (JFXFunctionDefinition) def;
 642  1008
                            translatedDefs.append(translate(funcDef));
 643  1008
                            break;
 644  
                         }
 645  
                         case JCTree.METHODDEF : {
 646  0
                             assert false : "translated method should never appear in an FX class";
 647  
                             break;
 648  
                         }
 649  
                         default: {
 650  246
                             JCTree tdef =  translate(def);
 651  246
                             if ( tdef != null ) {
 652  246
                                 translatedDefs.append( tdef );
 653  
                             }
 654  
                             break;
 655  
                         }
 656  
                     }
 657  
                 }
 658  
             }
 659  
             // the translated defs have prepends in front
 660  612
             for (JCTree prepend : prependToDefinitions) {
 661  237
                 translatedDefs.prepend(prepend);
 662  
             }
 663  612
             prependToDefinitions = prevPrependToDefinitions ;
 664  612
             prependToStatements = prevPrependToStatements;
 665  
             // WARNING: translate can't be called directly or indirectly after this point in the method, or the prepends won't be included
 666  
 
 667  612
             boolean classOnly = tree.generateClassOnly();
 668  612
             JavafxClassModel model = initBuilder.createJFXClassModel(tree, attrInfo.toList(), overrideInfo.toList());
 669  612
             additionalImports.appendList(model.additionalImports);
 670  
        
 671  612
             boolean classIsFinal = (tree.getModifiers().flags & Flags.FINAL) != 0;
 672  
             
 673  
             // include the interface only once
 674  612
             if (!tree.hasBeenTranslated) {
 675  612
                 if (! classOnly) {
 676  571
                     JCModifiers mods = make.Modifiers(Flags.PUBLIC | Flags.INTERFACE);
 677  571
                     mods = addAccessAnnotationModifiers(diagPos, tree.mods.flags, mods);
 678  
 
 679  571
                     JCClassDecl cInterface = make.ClassDef(mods,
 680  
                             model.interfaceName, List.<JCTypeParameter>nil(), null,
 681  
                             model.interfaces, model.iDefinitions);
 682  
 
 683  571
                     prependToDefinitions.append(cInterface); // prepend to the enclosing class or top-level
 684  
                 }
 685  612
                 tree.hasBeenTranslated = true;
 686  
             }
 687  
             
 688  612
             translatedDefs.appendList(model.additionalClassMembers);
 689  
 
 690  
             {
 691  
                 // Add the userInit$ method
 692  612
                 List<JCVariableDecl> receiverVarDeclList = List.of(makeReceiverParam(tree));
 693  612
                 ListBuffer<JCStatement> initStats = ListBuffer.lb();
 694  
                 // call the superclasses userInit$
 695  612
                 Set<String> dupSet = new HashSet<String>();
 696  612
                 for (JCExpression parent : tree.getExtending()) {
 697  106
                     if (! (parent instanceof JCIdent))
 698  10
                         continue;
 699  96
                     Symbol symbol = expressionSymbol(parent);
 700  96
                     if (types.isJFXClass(symbol)) {
 701  89
                         ClassSymbol cSym = (ClassSymbol) symbol;
 702  89
                         String className = cSym.fullname.toString();
 703  89
                         if (className.endsWith(interfaceSuffix)) {
 704  0
                             className = className.substring(0, className.length() - interfaceSuffix.length());
 705  
                         }
 706  
 
 707  89
                         if (!dupSet.contains(className)) {
 708  89
                             dupSet.add(className);
 709  89
                             List<JCExpression> args1 = List.nil();
 710  89
                             args1 = args1.append(make.TypeCast(makeTypeTree( diagPos,cSym.type, true), make.Ident(defs.receiverName)));
 711  89
                             initStats = initStats.append(callStatement(tree.pos(), makeIdentifier(diagPos, className), initBuilder.userInitName, args1));
 712  
                         }
 713  
                     }
 714  96
                 }
 715  612
                 initStats.appendList(translatedInitBlocks);
 716  
 
 717  612
                 JCBlock userInitBlock = make.Block(0L, initStats.toList());
 718  612
                 translatedDefs.append(make.MethodDef(
 719  
                         make.Modifiers(classIsFinal? Flags.PUBLIC  : Flags.PUBLIC | Flags.STATIC), 
 720  
                         initBuilder.userInitName, 
 721  
                         makeTypeTree( null,syms.voidType), 
 722  
                         List.<JCTypeParameter>nil(), 
 723  
                         receiverVarDeclList, 
 724  
                         List.<JCExpression>nil(), 
 725  
                         userInitBlock, 
 726  
                         null));
 727  
             }
 728  
             {
 729  
                 // Add the userPostInit$ method
 730  612
                 List<JCVariableDecl> receiverVarDeclList = List.of(makeReceiverParam(tree));
 731  612
                 ListBuffer<JCStatement> initStats = ListBuffer.lb();
 732  
                 // call the superclasses postInit$
 733  612
                 Set<String> dupSet = new HashSet<String>();
 734  612
                 for (JCExpression parent : tree.getExtending()) {
 735  106
                     if (! (parent instanceof JCIdent))
 736  10
                         continue;
 737  96
                     Symbol symbol = expressionSymbol(parent);
 738  96
                     if (types.isJFXClass(symbol)) {
 739  89
                         ClassSymbol cSym = (ClassSymbol) symbol;
 740  89
                         String className = cSym.fullname.toString();
 741  89
                         if (className.endsWith(interfaceSuffix)) {
 742  0
                             className = className.substring(0, className.length() - interfaceSuffix.length());
 743  
                         }
 744  
 
 745  89
                         if (!dupSet.contains(className)) {
 746  89
                             dupSet.add(className);
 747  89
                             List<JCExpression> args1 = List.nil();
 748  89
                             args1 = args1.append(make.TypeCast(makeTypeTree( diagPos,cSym.type, true), make.Ident(defs.receiverName)));
 749  89
                             initStats = initStats.append(callStatement(tree.pos(), makeIdentifier(diagPos, className), initBuilder.postInitName, args1));
 750  
                         }
 751  
                     }
 752  96
                 }
 753  612
                 initStats.appendList(translatedPostInitBlocks);
 754  
 
 755  612
                 JCBlock postInitBlock = make.Block(0L, initStats.toList());
 756  612
                 translatedDefs.append(make.MethodDef(
 757  
                         make.Modifiers(classIsFinal? Flags.PUBLIC  : Flags.PUBLIC | Flags.STATIC),
 758  
                         initBuilder.postInitName,
 759  
                         makeTypeTree( null,syms.voidType),
 760  
                         List.<JCTypeParameter>nil(),
 761  
                         receiverVarDeclList,
 762  
                         List.<JCExpression>nil(),
 763  
                         postInitBlock,
 764  
                         null));
 765  
             }
 766  
 
 767  612
             if (tree.isModuleClass) {
 768  
                 // Add main method...
 769  340
                 translatedDefs.append(makeMainMethod(diagPos, tree.getName()));
 770  
             }
 771  
 
 772  
             // build the list of implemented interfaces
 773  
             List<JCExpression> implementing;
 774  612
             if (classOnly) {
 775  41
                 implementing = model.interfaces;
 776  
             }
 777  
             else {
 778  571
                 implementing = List.of(make.Ident(model.interfaceName), makeIdentifier(diagPos, fxObjectString));
 779  
             }
 780  
             
 781  612
             long flags = tree.mods.flags & (Flags.PUBLIC | Flags.PRIVATE | Flags.PROTECTED | Flags.FINAL | Flags.ABSTRACT);
 782  612
             if (tree.sym.owner.kind == Kinds.TYP) {
 783  246
                 flags |= Flags.STATIC;
 784  
             }
 785  
             
 786  
             // make the Java class corresponding to this FX class, and return it
 787  612
             JCClassDecl res = make.at(diagPos).ClassDef(
 788  
                     make.at(diagPos).Modifiers(flags),
 789  
                     tree.getName(),
 790  
                     tree.getEmptyTypeParameters(), 
 791  
                     model.superType==null? null : makeTypeTree( null,model.superType, false),
 792  
                     implementing, 
 793  
                     translatedDefs.toList());
 794  612
             res.sym = tree.sym;
 795  612
             res.type = tree.type;
 796  612
             result = res;
 797  
         }
 798  
         finally {
 799  612
             attrEnv.enclClass = prevEnclClass;
 800  612
             wrap = prevWrap;
 801  
 
 802  612
             currentClass = prevClass;
 803  612
         }
 804  612
     }
 805  
     
 806  
     @Override
 807  
     public void visitInitDefinition(JFXInitDefinition tree) {
 808  0
         assert false : "should be processed by class tree";
 809  0
     }
 810  
 
 811  
     public void visitPostInitDefinition(JFXPostInitDefinition tree) {
 812  0
         assert false : "should be processed by class tree";
 813  0
     }
 814  
 
 815  2
     abstract static class InstanciateTranslator extends Translator {
 816  
 
 817  
         protected final JFXInstanciate tree;
 818  659
         protected ListBuffer<JCStatement> stats = ListBuffer.lb();
 819  
 
 820  
         InstanciateTranslator(final JFXInstanciate tree, JavafxToJava toJava) {
 821  659
             super(tree.pos(), toJava);
 822  659
             this.tree = tree;
 823  659
         }
 824  
         
 825  
         abstract protected void processLocalVar(JFXVar var);
 826  
         
 827  
         protected List<JCExpression> translatedConstructorArgs() {
 828  595
             if (tree.constructor != null && tree.constructor.type != null) {
 829  100
                 List<Type> ptypes = tree.constructor.type.asMethodType().getParameterTypes();
 830  100
                 return toJava.translate(tree.getArgs(), ptypes);
 831  
             } else {
 832  495
                 return toJava.translate(tree.getArgs());
 833  
             }
 834  
         }
 835  
 
 836  
         abstract protected JCStatement translateAttributeSet(JCExpression init, JavafxBindStatus bindStatus, VarSymbol vsym,
 837  
             JCExpression instance);
 838  
         
 839  
         protected JCExpression doit() {
 840  
             Type type;
 841  
             
 842  659
             for (JFXVar var : tree.getLocalvars()) {
 843  
                 // force var to be a Location (so class members can see it)
 844  8
                 toJava.typeMorpher.varMorphInfo(var.sym).markBoundTo();
 845  
                 // add the variable before the class definition or object litersl assignment
 846  8
                 processLocalVar(var);
 847  
             }
 848  659
             if (tree.getClassBody() == null) {
 849  633
                 type = tree.type;
 850  
             } else {
 851  26
                 JFXClassDeclaration cdef = tree.getClassBody();
 852  26
                 stats.append(toJava.translate(cdef));
 853  26
                 type = cdef.type;
 854  
             }
 855  659
             JCExpression classTypeExpr = toJava.makeTypeTree(tree, type, false);
 856  659
             Symbol sym = TreeInfo.symbol(tree.getIdentifier());
 857  
 
 858  659
             List<JCExpression> newClassArgs = translatedConstructorArgs();
 859  659
             if (tree.getClassBody() != null || types.isJFXClass(sym)) {
 860  581
                 assert newClassArgs.size() == 0 : "should not be args for JavaFX class constructors";
 861  581
                 newClassArgs = newClassArgs.append(m().Literal(TypeTags.BOOLEAN, 1));
 862  
             }
 863  659
             if (tree.getClassBody() != null &&
 864  
                     tree.getClassBody().sym != null && toJava.hasOuters.contains(tree.getClassBody().sym)) {
 865  8
                 JCIdent thisIdent = m().Ident(defs.receiverName);
 866  8
                 thisIdent.sym = tree.getClassBody().sym.owner; //TODO: these are assumed cruft - remove
 867  8
                 thisIdent.type = tree.getClassBody().sym.owner.type;
 868  
 
 869  8
                 newClassArgs = newClassArgs.prepend(thisIdent);
 870  
             }
 871  
 
 872  659
             JCNewClass newClass =
 873  
                     m().NewClass(null, null, classTypeExpr,
 874  
                     newClassArgs,
 875  
                     null);
 876  
 
 877  
             JCExpression instExpression;
 878  
             {
 879  659
                 if (sym != null &&
 880  
                         sym.kind == Kinds.TYP && (sym instanceof ClassSymbol) &&
 881  
                         (types.isJFXClass((ClassSymbol) sym) ||
 882  
                         tree.getClassBody() != null)) {
 883  
                     // it is a JavaFX class, initializa it properly
 884  581
                     JCVariableDecl tmpVar = toJava.makeTmpVar(diagPos, "objlit", type, newClass);
 885  581
                     stats.append(tmpVar);
 886  581
                     for (JFXObjectLiteralPart olpart : tree.getParts()) {
 887  765
                         diagPos = olpart.pos(); // overwrite diagPos (must restore)
 888  765
                         JavafxBindStatus bindStatus = olpart.getBindStatus();
 889  765
                         JCExpression init = olpart.getExpression();
 890  765
                         VarSymbol vsym = (VarSymbol) olpart.sym;
 891  765
                         VarMorphInfo vmi = toJava.typeMorpher.varMorphInfo(vsym);
 892  765
                         assert toJava.shouldMorph(vmi);
 893  
 
 894  
                         // Lift JFXObjectLiteralPart if needed
 895  765
                         if (types.isSequence(olpart.type)) {
 896  96
                             JCExpression olexpr = olpart.getExpression();
 897  96
                             if (!types.isSequence(olexpr.type)) {
 898  13
                                 init = ((JavafxTreeMaker) m()).ExplicitSequence(List.<JCExpression>of(olexpr));
 899  13
                                 WildcardType tpType = new WildcardType(olexpr.type, BoundKind.EXTENDS, olexpr.type.tsym);
 900  13
                                 init.type = new ClassType(((JavafxSymtab) syms).javafx_SequenceType, List.<Type>of(tpType), ((JavafxSymtab) syms).javafx_SequenceType.tsym);
 901  
                             }
 902  
                         }
 903  
 
 904  765
                         JCIdent ident1 = m().Ident(tmpVar.name);
 905  765
                         stats.append( translateAttributeSet(init, bindStatus, vsym, ident1) );
 906  765
                     }
 907  581
                     diagPos = tree.pos();
 908  581
                     JCIdent ident3 = m().Ident(tmpVar.name);
 909  581
                     JCStatement applyExec = toJava.callStatement(diagPos, ident3, defs.initializeName);
 910  581
                     stats.append(applyExec);
 911  
 
 912  581
                     JCIdent ident2 = m().Ident(tmpVar.name);
 913  581
                     instExpression = toJava.makeBlockExpression(diagPos, stats, ident2);
 914  581
                 } else {
 915  
                     // this is a Java class, just instanciate it
 916  78
                     instExpression = newClass;
 917  
                 }
 918  
             }
 919  659
             if (toJava.wrap == Wrapped.InLocation) {
 920  1
                  instExpression = toJava.makeConstantLocation(diagPos, tree.type, instExpression);               
 921  
             }
 922  659
             return instExpression;
 923  
         }
 924  
     }
 925  
 
 926  
     @Override
 927  
     public void visitInstanciate(JFXInstanciate tree) {   
 928  
         
 929  590
         ListBuffer<JCStatement> prevPrependToStatements = prependToStatements;
 930  590
         prependToStatements = ListBuffer.lb();
 931  
         
 932  590
         result = new InstanciateTranslator(tree, this) {
 933  
 
 934  
             protected void processLocalVar(JFXVar var) {
 935  7
                 stats.append(translate(var));
 936  7
             }
 937  
 
 938  
             protected JCStatement translateAttributeSet(JCExpression init, JavafxBindStatus bindStatus, VarSymbol vsym, JCExpression instance) {
 939  660
                 return toJava.translateDefinitionalAssignmentToSet(diagPos, init, bindStatus,
 940  
                         vsym, instance, FROM_LITERAL_MILIEU);
 941  
             }
 942  
             }.doit();
 943  
                   
 944  590
             if (result instanceof JFXBlockExpression) {
 945  512
                 JFXBlockExpression blockExpr = (JFXBlockExpression)result;               
 946  512
                 blockExpr.stats = blockExpr.getStatements().prependList(prependToStatements.toList());   
 947  
             }
 948  590
             prependToStatements = prevPrependToStatements;
 949  590
     }
 950  
 
 951  0
     abstract static class StringExpressionTranslator extends Translator {
 952  
 
 953  
         private final JFXStringExpression tree;
 954  
         StringExpressionTranslator(JFXStringExpression tree, JavafxToJava toJava) {
 955  730
             super(tree.pos(), toJava);
 956  730
             this.tree = tree;
 957  730
         }
 958  
 
 959  
         protected JCExpression doit() {
 960  730
             StringBuffer sb = new StringBuffer();
 961  730
             List<JCExpression> parts = tree.getParts();
 962  730
             ListBuffer<JCExpression> values = new ListBuffer<JCExpression>();
 963  
 
 964  730
             JCLiteral lit = (JCLiteral) (parts.head);            // "...{
 965  730
             sb.append((String) lit.value);
 966  730
             parts = parts.tail;
 967  730
             boolean containsExtendedFormat = false;
 968  
 
 969  1883
             while (parts.nonEmpty()) {
 970  1153
                 lit = (JCLiteral) (parts.head);                  // optional format (or null)
 971  1153
                 String format = (String) lit.value;
 972  1153
                 if ((!containsExtendedFormat) && format.length() > 0
 973  
                     && EXTENDED_FORMAT_PATTERN.matcher(format).find()) {
 974  8
                     containsExtendedFormat = true;
 975  
                 }
 976  1153
                 parts = parts.tail;
 977  1153
                 JCExpression exp = parts.head;
 978  1153
                 if (exp != null &&
 979  
                         types.isSameType(exp.type, syms.javafx_DurationType)) {
 980  16
                     exp = m().Apply(null,
 981  
                             m().Select(translateArg(exp),
 982  
                             Name.fromString(toJava.names, "toDate")),
 983  
                             List.<JCExpression>nil());
 984  16
                     sb.append(format.length() == 0 ? "%tQms" : format);
 985  
                 } else {
 986  1137
                     exp = translateArg(exp);
 987  1137
                     sb.append(format.length() == 0 ? "%s" : format);
 988  
                 }
 989  1153
                 values.append(exp);
 990  1153
                 parts = parts.tail;
 991  
 
 992  1153
                 lit = (JCLiteral) (parts.head);                  // }...{  or  }..."
 993  1153
                 String part = (String)lit.value;
 994  1153
                 sb.append(part.replace("%", "%%"));              // escape percent signs
 995  1153
                 parts = parts.tail;
 996  1153
             }
 997  730
             JCLiteral formatLiteral = m().Literal(TypeTags.CLASS, sb.toString());
 998  730
             values.prepend(formatLiteral);
 999  
             String formatMethod;
 1000  730
             if (tree.translationKey != null) {
 1001  28
                 formatMethod = "com.sun.javafx.runtime.util.StringLocalization.getLocalizedString";
 1002  28
                 if (tree.translationKey.length() == 0) {
 1003  24
                     values.prepend(m().Literal(TypeTags.BOT, null));
 1004  
                 } else {
 1005  4
                     values.prepend(m().Literal(TypeTags.CLASS, tree.translationKey));
 1006  
                 }
 1007  28
                 String resourceName =
 1008  
                         toJava.attrEnv.enclClass.sym.flatname.toString().replace('.', '/').replaceAll("\\$.*", "");
 1009  28
                 values.prepend(m().Literal(TypeTags.CLASS, resourceName));
 1010  28
             } else if (containsExtendedFormat) {
 1011  8
                 formatMethod = "com.sun.javafx.runtime.util.FXFormatter.sprintf";
 1012  
             } else {
 1013  694
                 formatMethod = "java.lang.String.format";
 1014  
             }
 1015  730
             JCExpression formatter = toJava.makeQualifiedTree(diagPos, formatMethod);
 1016  730
             return m().Apply(null, formatter, values.toList());
 1017  
         }
 1018  
 
 1019  
         abstract protected JCExpression translateArg(JCExpression arg);
 1020  
         
 1021  
     }
 1022  
 
 1023  
     @Override
 1024  
     public void visitStringExpression(JFXStringExpression tree) {
 1025  716
         result = new StringExpressionTranslator(tree, this) {
 1026  
             protected JCExpression translateArg(JCExpression arg) {
 1027  1125
                 return translate(arg);
 1028  
             }
 1029  
         }.doit();
 1030  716
     }
 1031  
 
 1032  
     private List<JCExpression> translateDefinitionalAssignmentToArgs(DiagnosticPosition diagPos,
 1033  
             JCExpression init, JavafxBindStatus bindStatus, VarMorphInfo vmi) {
 1034  2392
         if (bindStatus.isUnidiBind()) {
 1035  251
             return List.of(toBound.translate(init, vmi.getRealType()));
 1036  2141
         } else if (bindStatus.isBidiBind()) {
 1037  19
             assert (shouldMorph(vmi));
 1038  
             // Bi-directional bind translate so it stays in a Location
 1039  19
             return List.<JCExpression>of( translate(init, Wrapped.InLocation) );
 1040  
         } else {
 1041  
             JCExpression initExpr;
 1042  
             // normal init -- unbound -- but it is setting a Location
 1043  2122
             if (init == null) {
 1044  
                 // no initializing expression determine a default value from the type
 1045  312
                 initExpr = makeDefaultValue(diagPos, vmi);
 1046  
             } else {
 1047  
                 // do a vanilla translation of the expression
 1048  1810
                 initExpr = translate(init, vmi.getSymbol().type);
 1049  
             }
 1050  2122
             return List.<JCExpression>of( initExpr );
 1051  
         }
 1052  
     }
 1053  
 
 1054  
     private JCExpression translateDefinitionalAssignmentToValue(DiagnosticPosition diagPos,
 1055  
             JCExpression init, JavafxBindStatus bindStatus, VarSymbol vsym) {
 1056  1
         VarMorphInfo vmi = typeMorpher.varMorphInfo(vsym);
 1057  1
         List<JCExpression> args = translateDefinitionalAssignmentToArgs(diagPos, init, bindStatus, vmi);
 1058  1
         if (bindStatus.isUnidiBind()) {
 1059  0
             return args.head;
 1060  1
         } else if (shouldMorph(vmi)) {
 1061  0
             Name makeName = defs.makeMethodName;
 1062  0
             if (bindStatus.isBidiBind()) {
 1063  0
                 makeName = defs.makeBijectiveMethodName;
 1064  
             }
 1065  0
             return makeLocationVariable(vmi, diagPos, args, makeName);
 1066  
         } else {
 1067  1
             return args.head;
 1068  
         }
 1069  
     }
 1070  
 
 1071  
     private JCStatement translateDefinitionalAssignmentToSet(DiagnosticPosition diagPos,
 1072  
             JCExpression init, JavafxBindStatus bindStatus, VarSymbol vsym,
 1073  
             JCExpression instance, int milieu) {
 1074  2387
         return make.at(diagPos).Exec( translateDefinitionalAssignmentToSetExpression(diagPos,
 1075  
             init, bindStatus, vsym,
 1076  
              instance, milieu) );
 1077  
     }
 1078  
    
 1079  
     private JCExpression translateDefinitionalAssignmentToSetExpression(DiagnosticPosition diagPos,
 1080  
             JCExpression init, JavafxBindStatus bindStatus, VarSymbol vsym,
 1081  
             JCExpression instance, int milieu) {
 1082  2391
         VarMorphInfo vmi = typeMorpher.varMorphInfo(vsym);
 1083  2391
         List<JCExpression> args = translateDefinitionalAssignmentToArgs(diagPos, init, bindStatus, vmi);
 1084  
         JCExpression localAttr;
 1085  
         
 1086  
         // if it is an attribute
 1087  2391
         if (vsym.owner.kind == Kinds.TYP) {
 1088  1202
             if ((vsym.flags() & STATIC) != 0) {
 1089  
                 // statics are accessed directly
 1090  46
                 localAttr = make.Ident(vsym);
 1091  
             } else {
 1092  1156
                 String attrAccess = attributeGetMethodNamePrefix + vsym;
 1093  1156
                 localAttr = callExpression(diagPos, instance, attrAccess);
 1094  1156
             }
 1095  
         } else {
 1096  
             // if it is a local variable
 1097  1189
             assert( (vsym.flags() & Flags.PARAMETER) == 0): "Parameters are not initialized";
 1098  1189
             localAttr = make.at(diagPos).Ident(vsym);   
 1099  
             
 1100  1189
             if (!shouldMorph(vmi)) {
 1101  709
                 return make.at(diagPos).Assign(localAttr, args.head);
 1102  
             }
 1103  
         }
 1104  
         
 1105  
         Name methName;
 1106  1682
         if (bindStatus.isUnidiBind()) {
 1107  251
             methName = defs.locationBindMilieuMethodName[milieu];
 1108  1431
         } else if (bindStatus.isBidiBind()) {
 1109  19
             methName = defs.locationBijectiveBindMilieuMethodName[milieu];
 1110  
         } else {
 1111  1412
             methName = defs.locationSetMilieuMethodName[vmi.getTypeKind()][milieu];
 1112  
         }   
 1113  1682
         return callExpression(diagPos, localAttr, methName, args);
 1114  
     }
 1115  
 
 1116  
     @Override
 1117  
     public void visitVar(JFXVar tree) {
 1118  2274
         DiagnosticPosition diagPos = tree.pos();
 1119  2274
         Type type = tree.type;
 1120  2274
         JCModifiers mods = tree.getModifiers();
 1121  2274
         long modFlags = mods.flags & ~Flags.FINAL;
 1122  2274
         VarSymbol vsym = tree.sym;
 1123  2274
         VarMorphInfo vmi = typeMorpher.varMorphInfo(vsym);
 1124  2274
         assert vsym.owner.kind != Kinds.TYP : "attributes are processed in the class and should never come here";
 1125  
         
 1126  
         // Variables accessed from an inner class must be FINAL
 1127  2274
         if ((vsym.flags_field & JavafxFlags.INNER_ACCESS) != 0) {   
 1128  9
             modFlags |= Flags.FINAL;
 1129  
         }
 1130  
         
 1131  
         // force morphing on variables with triggers
 1132  2274
         if (tree.getOnReplace() != null)
 1133  7
             vmi.markBoundTo();
 1134  
         
 1135  2274
         if (shouldMorph(vmi)) {
 1136  
             // convert the type to the Location type
 1137  488
             if ((vsym.flags() & Flags.PARAMETER) != 0) {
 1138  8
                 type = vmi.getLocationType();
 1139  
             } else {
 1140  480
                 type = vmi.getVariableType();
 1141  
             }
 1142  
 
 1143  
             // Locations are never overwritten
 1144  488
             modFlags |= Flags.FINAL;
 1145  
         } 
 1146  
 
 1147  2274
         mods = make.at(diagPos).Modifiers(modFlags);
 1148  2274
         JCExpression typeExpression = makeTypeTree(diagPos, type, true);
 1149  
 
 1150  
         // for class vars, initialization happens during class init, so set to
 1151  
         // default Location.  For local vars translate as definitional
 1152  
         JCExpression init;
 1153  2274
         if ((vsym.flags() & Flags.PARAMETER) != 0) {
 1154  
             // parameters aren't initialized
 1155  1084
             init = null; 
 1156  1084
             result = make.at(diagPos).VarDef(mods, tree.name, typeExpression, init);           
 1157  
         } else {
 1158  
            // create a blank variable declaration and move the declaration to the beginning of the block
 1159  1190
            if ( !shouldMorph(vmi)) {
 1160  710
                 if ( (modFlags & Flags.FINAL) != 0 ) {
 1161  1
                     init = translateDefinitionalAssignmentToValue(tree.pos(), tree.init,
 1162  
                     tree.getBindStatus(), tree.sym);
 1163  1
                     result = make.at(diagPos).VarDef(mods, tree.name, typeExpression, init);
 1164  1
                     return;
 1165  
                 }
 1166  
                 // non location types:
 1167  709
                 init = makeDefaultValue(diagPos, vmi);
 1168  
             } else { 
 1169  
                 // location types: XXXVariable.make() 
 1170  480
                 init = makeLocationAttributeVariable(vmi, diagPos);
 1171  
             }
 1172  1189
             prependToStatements.append(make.at(diagPos).VarDef(mods, tree.name, typeExpression, init));
 1173  
             
 1174  
             // create change Listener and append it to the beginning of the block after the blank variable declaration
 1175  1189
             JFXOnReplace onReplace = tree.getOnReplace();
 1176  1189
             if ( onReplace != null ) {
 1177  
                    
 1178  7
                 TranslatedAttributeInfo attrInfo = new TranslatedAttributeInfo(
 1179  
                                                             tree,
 1180  
                                                             typeMorpher.varMorphInfo(vsym),
 1181  
                                                             null,
 1182  
                                                             translate(tree.getOnReplace()));
 1183  7
                 JCStatement changeListener = initBuilder.makeChangeListenerCall(attrInfo); 
 1184  7
                 prependToStatements.append(changeListener);
 1185  
             }
 1186  
             
 1187  1189
             result = translateDefinitionalAssignmentToSet(diagPos, tree.init, tree.getBindStatus(), tree.sym, null, 0);
 1188  
         }   
 1189  2273
     }
 1190  
 
 1191  
     @Override
 1192  
     public void visitOverrideAttribute(JFXOverrideAttribute tree) {
 1193  0
         assert false : "should be processed by parent tree";
 1194  0
     }
 1195  
 
 1196  
     @Override
 1197  
     public void visitOnReplace(JFXOnReplace tree) {
 1198  126
         result = ((JavafxTreeMaker) make).OnReplace(
 1199  
                 tree.getOldValue(), tree.getFirstIndex(), tree.getLastIndex(),
 1200  
                 tree.getEndKind(), tree.getNewElements(),
 1201  
                 translate(tree.getBody()));
 1202  126
     }
 1203  
     
 1204  
     
 1205  
     @Override
 1206  
     public void visitFunctionValue(JFXFunctionValue tree) {
 1207  173
         JFXFunctionDefinition def = tree.definition;
 1208  173
         result = makeFunctionValue(make.Ident(defs.lambdaName), def, tree.pos(), (MethodType) def.type);
 1209  173
     }
 1210  
     
 1211  
    JCExpression makeFunctionValue (JCExpression meth, JFXFunctionDefinition def, DiagnosticPosition diagPos, MethodType mtype) {
 1212  182
         ListBuffer<JCTree> members = new ListBuffer<JCTree>();
 1213  182
         if (def != null)
 1214  173
             members.append(translate(def));
 1215  182
         JCExpression encl = null;
 1216  182
         List<JCExpression> args = List.nil();
 1217  182
         int nargs = mtype.argtypes.size();
 1218  182
         Type ftype = syms.javafx_FunctionTypes[nargs];
 1219  182
         JCExpression t = makeQualifiedTree(null, ftype.tsym.getQualifiedName().toString());
 1220  182
         ListBuffer<JCExpression> typeargs = new ListBuffer<JCExpression>();
 1221  182
         Type rtype = syms.boxIfNeeded(mtype.restype);
 1222  182
         typeargs.append(makeTypeTree(diagPos, rtype));
 1223  182
         ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
 1224  182
         ListBuffer<JCExpression> margs = new ListBuffer<JCExpression>();
 1225  182
         int i = 0;
 1226  217
         for (List<Type> l = mtype.argtypes;  l.nonEmpty();  l = l.tail) {
 1227  35
             Name pname = make.paramName(i++);
 1228  35
             Type ptype = syms.boxIfNeeded(l.head);
 1229  35
             JCVariableDecl param = make.VarDef(make.Modifiers(0), pname,
 1230  
                     makeTypeTree(diagPos, ptype), null);
 1231  35
             params.append(param);
 1232  35
             JCExpression marg = make.Ident(pname);
 1233  35
             margs.append(marg);
 1234  35
             typeargs.append(makeTypeTree(diagPos, ptype));
 1235  
         }
 1236  
 
 1237  
         // The backend's Attr skips SYNTHETIC methods when looking for a matching method.
 1238  182
         long flags = PUBLIC | BRIDGE; // | SYNTHETIC;
 1239  
 
 1240  182
         JCExpression call = make.Apply(null, meth, margs.toList());
 1241  
 
 1242  
         List<JCStatement> stats;
 1243  182
         if (mtype.restype == syms.voidType)
 1244  160
             stats = List.of(make.Exec(call), make.Return(make.Literal(TypeTags.BOT, null)));
 1245  
         else {
 1246  22
             if (mtype.restype.isPrimitive())
 1247  12
                 call = makeBox(diagPos, call, mtype.restype);
 1248  22
             stats = List.<JCStatement>of(make.Return(call));
 1249  
         }
 1250  182
        JCMethodDecl bridgeDef = make.at(diagPos).MethodDef(
 1251  
                 make.Modifiers(flags),
 1252  
                 defs.invokeName, 
 1253  
                 makeTypeTree(diagPos, rtype),
 1254  
                 List.<JCTypeParameter>nil(),
 1255  
                 params.toList(),
 1256  
                 make.at(diagPos).Types(mtype.getThrownTypes()),
 1257  
                 make.Block(0, stats), 
 1258  
                 null);
 1259  
 
 1260  182
         members.append(bridgeDef);
 1261  182
         JCClassDecl cl = make.AnonymousClassDef(make.Modifiers(0), members.toList());
 1262  182
         return make.NewClass(encl, args, make.TypeApply(t, typeargs.toList()), args, cl);
 1263  
     }
 1264  
     
 1265  
    boolean isInnerFunction (MethodSymbol sym) {
 1266  1181
        return sym.owner != null && sym.owner.kind != Kinds.TYP
 1267  
                 && (sym.flags() & Flags.SYNTHETIC) == 0;
 1268  
    }
 1269  
            
 1270  
    /**
 1271  
     * Translate JavaFX a class definition into a Java static implementation method.
 1272  
     */
 1273  
    @Override
 1274  
     public void visitFunctionDefinition(JFXFunctionDefinition tree) {
 1275  1181
         if (isInnerFunction(tree.sym)) {
 1276  
             // If tree's context is not a class, then translate:
 1277  
             //   function foo(args) { body }
 1278  
             // to: final var foo = function(args) { body };
 1279  
             // A probably cleaner and possibly more efficient solution would
 1280  
             // be to create an anonymous class containing the function as
 1281  
             // a method; closed-over local variables become fields.
 1282  
             // That would have the advantage that calling the function directly
 1283  
             // translates into a direct method call, rather than going via
 1284  
             // Function's invoke method, which implies extra casts, possibly
 1285  
             // boxing, etc.  FIXME
 1286  0
             DiagnosticPosition diagPos = tree.pos();
 1287  0
             MethodType mtype = (MethodType) tree.type;
 1288  0
             JCExpression typeExpression = makeTypeTree( diagPos,syms.makeFunctionType(mtype), true);
 1289  0
             JFXFunctionDefinition def = new JFXFunctionDefinition(make.Modifiers(Flags.SYNTHETIC), tree.name, tree.operation);
 1290  0
             def.type = mtype;
 1291  0
             def.sym = new MethodSymbol(0, def.name, mtype, tree.sym.owner.owner);
 1292  0
             JCExpression init =
 1293  
                makeFunctionValue(make.Ident(tree.name), def, tree.pos(), mtype);
 1294  0
             JCModifiers mods = make.at(diagPos).Modifiers(Flags.FINAL);
 1295  0
             result = make.at(diagPos).VarDef(mods, tree.name, typeExpression, init);
 1296  0
             return;
 1297  
         }
 1298  
 
 1299  1181
         boolean isBound = (tree.sym.flags() & JavafxFlags.BOUND) != 0;
 1300  1181
         Wrapped prevWrap = wrap;
 1301  1181
         wrap = Wrapped.InNothing;
 1302  
 
 1303  
         try {
 1304  1181
             boolean classOnly = currentClass.generateClassOnly();
 1305  
             // Made all the operations public. Per Brian's spec.
 1306  
             // If they are left package level it interfere with Multiple Inheritance
 1307  
             // The interface methods cannot be package level and an error is reported.
 1308  1181
             long flags = tree.mods.flags;
 1309  1181
             long originalFlags = flags;
 1310  1181
             flags &= ~(Flags.PROTECTED | Flags.PRIVATE);
 1311  1181
             flags |=  Flags.PUBLIC;
 1312  1181
             if (((flags & (Flags.ABSTRACT | Flags.SYNTHETIC)) == 0) && !classOnly) {
 1313  582
                 flags |= Flags.STATIC;
 1314  
             }
 1315  1181
             flags &= ~Flags.SYNTHETIC;
 1316  1181
             JCModifiers mods = make.Modifiers(flags);     
 1317  1181
             boolean isImplMethod = (originalFlags & (Flags.STATIC | Flags.ABSTRACT | Flags.SYNTHETIC)) == 0 && !classOnly;
 1318  
 
 1319  1181
             DiagnosticPosition diagPos = tree.pos();
 1320  1181
             MethodType mtype = (MethodType)tree.type;
 1321  
             
 1322  1181
             if (isBound) {
 1323  15
                 locallyBound = new HashSet<VarSymbol>();
 1324  15
                 for (JFXVar fxVar : tree.getParameters()) {
 1325  8
                     setLocallyBound(fxVar.sym);
 1326  
                 }
 1327  
             }
 1328  
 
 1329  
             // construct the body of the translated function
 1330  1181
             JFXBlockExpression bexpr = tree.getBodyExpression();
 1331  
             JCBlock body;
 1332  1181
             if (bexpr == null) {
 1333  10
                 body = null; // null if no block expression
 1334  1171
             } else if (isBound) {
 1335  
                 // Build the body of a bound function by treating it as a bound expression
 1336  
                 // TODO: Remove entry in findbugs-exclude.xml if permeateBind is implemented -- it is, so it should be
 1337  14
                 JCExpression expr = toBound.translate(bexpr, typeMorpher.varMorphInfo(tree.sym));
 1338  14
                 body = asBlock(make.at(diagPos).Return(expr));
 1339  14
             } else if (syms.isRunMethod(tree.sym)) {
 1340  
                 // it is a module level run method, do special translation
 1341  340
                 body = runMethodBody(bexpr);
 1342  340
                 isImplMethod = false;
 1343  
             } else {
 1344  
                 // the "normal" case
 1345  817
                 body = asBlock(translateExpressionToStatement(bexpr, mtype.getReturnType()));
 1346  
             }
 1347  
 
 1348  1181
             ListBuffer<JCVariableDecl> params = ListBuffer.lb();
 1349  1181
             if ((originalFlags & (Flags.STATIC | Flags.ABSTRACT | Flags.SYNTHETIC)) == 0) {
 1350  524
                 if (classOnly) {
 1351  
                     // all implementation code is generated assuming a receiver parameter.
 1352  
                     // in the final class case, there is no receiver param, so allow generated code
 1353  
                     // to function by adding:   var receiver = this;
 1354  71
                     body.stats = body.stats.prepend(
 1355  
                             make.at(diagPos).VarDef(
 1356  
                                 make.at(diagPos).Modifiers(Flags.FINAL), 
 1357  
                                 defs.receiverName, 
 1358  
                                 make.Ident(initBuilder.interfaceName(currentClass)), 
 1359  
                                 make.at(diagPos).Ident(names._this))
 1360  
                             );
 1361  
                 } else {
 1362  
                     // if we are converting a standard instance function (to a static method), the first parameter becomes a reference to the receiver
 1363  453
                     params.prepend(makeReceiverParam(currentClass));
 1364  
                 }
 1365  
             }
 1366  1181
             for (JFXVar fxVar : tree.getParameters()) {
 1367  1049
                 JCVariableDecl var = (JCVariableDecl)translate(fxVar);
 1368  1049
                 params.append(var);
 1369  1049
             }
 1370  
             
 1371  1181
             mods = addAccessAnnotationModifiers(diagPos, tree.mods.flags, mods);
 1372  
 
 1373  1181
             result = make.at(diagPos).MethodDef(
 1374  
                     mods,
 1375  
                     functionName(tree.sym, isImplMethod,  isBound), 
 1376  
                     makeReturnTypeTree(diagPos, tree.sym, isBound), 
 1377  
                     make.at(diagPos).TypeParams(mtype.getTypeArguments()), 
 1378  
                     params.toList(),
 1379  
                     make.at(diagPos).Types(mtype.getThrownTypes()),  // makeThrows(diagPos), //
 1380  
                     body, 
 1381  
                     null);
 1382  1181
             ((JCMethodDecl)result).sym = tree.sym;
 1383  1181
             result.type = tree.type;
 1384  
         }
 1385  
         finally {
 1386  1181
             wrap = prevWrap;
 1387  1181
         }
 1388  1181
     }
 1389  
    
 1390  
     public void visitBindExpression(JFXBindExpression tree) {
 1391  0
          throw new AssertionError(tree);
 1392  
     }
 1393  
 
 1394  
     public void visitBlockExpression(JFXBlockExpression tree) {
 1395  1501
         DiagnosticPosition diagPos = tree.pos();
 1396  1501
         ListBuffer<JCStatement> prevPrependToStatements = prependToStatements;
 1397  1501
         prependToStatements = ListBuffer.lb();
 1398  
         
 1399  1501
         JCExpression value = tree.value;
 1400  1501
         boolean valueFromReturn = (value == null) && (yield == Yield.ToReturnStatement);
 1401  1501
         ListBuffer<JCStatement> translated = ListBuffer.lb();
 1402  1501
         for(JCStatement stmt : tree.getStatements()) {
 1403  2070
             if (valueFromReturn && stmt.getTag() == JavafxTag.RETURN) {
 1404  174
                 value = ((JCReturn)stmt).getExpression();
 1405  
             } else {
 1406  1896
                 translated.append( translate(stmt) );
 1407  
             }
 1408  
         }       
 1409  1501
         List<JCStatement> localDefs = translated.toList();
 1410  
         
 1411  1501
         if (yield == Yield.ToExpression) {
 1412  91
             assert (tree.type != syms.voidType) : "void block expressions should be handled below";
 1413  91
             JCExpression tvalue = translate(value); // must be before prepend
 1414  91
             localDefs = prependToStatements.appendList(localDefs).toList();
 1415  91
             result = ((JavafxTreeMaker) make).at(tree.pos).BlockExpression(tree.flags, localDefs, tvalue);
 1416  91
         } else {
 1417  1410
             prependToStatements.appendList(localDefs);
 1418  1410
             if (value != null) {
 1419  1135
                 prependToStatements.append( translateExpressionToStatement(value) );
 1420  
             }
 1421  1410
             localDefs = prependToStatements.toList();
 1422  1410
             result = localDefs.size() == 1? localDefs.head : make.at(diagPos).Block(0L, localDefs);
 1423  
         }
 1424  1501
         prependToStatements = prevPrependToStatements;
 1425  1501
     }
 1426  
  
 1427  
     @Override
 1428  
     public void visitBlock(JCBlock tree) {
 1429  240
         List<JCStatement> localDefs = translateStatements(tree.stats);
 1430  240
         result = make.at(tree.pos).Block(tree.flags, localDefs);
 1431  240
     }
 1432  
 
 1433  
     @Override
 1434  
     public void visitAssign(JCAssign tree) {
 1435  938
         DiagnosticPosition diagPos = tree.pos();
 1436  
         
 1437  938
         Symbol sym = expressionSymbol(tree.lhs);
 1438  938
         VarSymbol vsym = (sym != null && (sym instanceof VarSymbol))? (VarSymbol)sym : null;
 1439  
 
 1440  938
         if (tree.rhs instanceof JFXBindExpression) {
 1441  4
             JFXBindExpression bind = (JFXBindExpression) tree.rhs;
 1442  4
             JCExpression lhs = translate(tree.lhs, Wrapped.InLocation);
 1443  4
             result = translateDefinitionalAssignmentToSetExpression(bind.pos(), 
 1444  
                                     bind.getExpression(), bind.getBindStatus(), vsym,
 1445  
                                     null /*for now*/, FROM_DEFAULT_MILIEU);
 1446  4
             return;
 1447  
         }
 1448  
         
 1449  934
         JCExpression rhs = translate(tree.rhs);
 1450  934
         if (tree.lhs.getTag() == JavafxTag.SEQUENCE_INDEXED) {
 1451  
             // assignment of a sequence element --  s[i]=8, call the sequence set method
 1452  60
             JFXSequenceIndexed si = (JFXSequenceIndexed)tree.lhs;
 1453  60
             JCExpression seq = translate(si.getSequence(), Wrapped.InLocation); 
 1454  60
             JCExpression index = translate(si.getIndex());
 1455  60
             JCFieldAccess select = make.Select(seq, defs.setMethodName);
 1456  60
             List<JCExpression> args = List.of(index, rhs);
 1457  60
             result = make.at(diagPos).Apply(null, select, args);
 1458  60
         } else if (tree.lhs.getTag() == JavafxTag.SEQUENCE_SLICE) {
 1459  
             // assignment of a sequence slice --  s[i..j]=8, call the sequence set method
 1460  12
             JFXSequenceSlice si = (JFXSequenceSlice)tree.lhs;
 1461  12
             JCExpression seq = translate(si.getSequence(), Wrapped.InLocation); 
 1462  12
             JCExpression firstIndex = translate(si.getFirstIndex());
 1463  12
             JCExpression lastIndex = makeSliceLastIndex(si);
 1464  12
             JCFieldAccess select = make.Select(seq, defs.replaceSliceMethodName);
 1465  12
             List<JCExpression> args = List.of(firstIndex, lastIndex, rhs);
 1466  12
             result = make.at(diagPos).Apply(null, select, args);
 1467  12
         } else if (shouldMorph(vsym)) {
 1468  
             // we are setting a var Location, call the set method
 1469  539
             JCExpression lhs = translate(tree.lhs, Wrapped.InLocation);
 1470  539
             JCFieldAccess setSelect = make.Select(lhs, defs.locationSetMethodName[typeMorpher.typeMorphInfo(vsym.type).getTypeKind()]);
 1471  539
             List<JCExpression> setArgs = List.of(rhs);
 1472  539
             result = make.at(diagPos).Apply(null, setSelect, setArgs);
 1473  539
         } else {
 1474  
             // We are setting a "normal" non-Location, use normal assign
 1475  323
             JCExpression lhs = translate(tree.lhs);
 1476  323
             result = make.at(diagPos).Assign(lhs, rhs); // make a new one so we are non-destructive
 1477  
         }
 1478  934
     }
 1479  
 
 1480  
     @Override
 1481  
     public void visitAssignop(JCAssignOp tree) {
 1482  38
         DiagnosticPosition diagPos = tree.pos();
 1483  
         
 1484  38
         Symbol sym = expressionSymbol(tree.lhs);
 1485  38
         VarSymbol vsym = (sym != null && (sym instanceof VarSymbol))? (VarSymbol)sym : null;
 1486  
         
 1487  38
         JCExpression rhs = translate(tree.rhs);
 1488  38
         JCExpression lhs = translate(tree.lhs);
 1489  
         int binaryOp;
 1490  38
         switch (tree.getTag()) {
 1491  
             case JCTree.PLUS_ASG:
 1492  25
                 binaryOp = JCTree.PLUS;
 1493  25
                 break;
 1494  
             case JCTree.MINUS_ASG:
 1495  4
                 binaryOp = JCTree.MINUS;
 1496  4
                 break;
 1497  
             case JCTree.MUL_ASG:
 1498  3
                 binaryOp = JCTree.MUL;
 1499  3
                 break;
 1500  
             case JCTree.DIV_ASG:
 1501  3
                 binaryOp = JCTree.DIV;
 1502  3
                 break;
 1503  
             case JCTree.MOD_ASG:
 1504  3
                 binaryOp = JCTree.MOD;
 1505  3
                 break;
 1506  
             default:
 1507  0
                 assert false : "unexpected assign op kind";
 1508  0
                 binaryOp = JCTree.PLUS;
 1509  
                 break;
 1510  
         }
 1511  38
         JCExpression combined = make.at(diagPos).Binary(binaryOp, lhs, rhs);
 1512  
 
 1513  38
         if (tree.lhs.getTag() == JavafxTag.SEQUENCE_INDEXED) {
 1514  
             // assignment of a sequence element --  s[i]+=8, call the sequence set method
 1515  4
             JFXSequenceIndexed si = (JFXSequenceIndexed)tree.lhs;
 1516  4
             JCExpression seq = translate(si.getSequence(), Wrapped.InLocation); 
 1517  4
             JCExpression index = translate(si.getIndex());
 1518  4
             JCFieldAccess select = make.Select(seq, defs.setMethodName);
 1519  4
             List<JCExpression> args = List.of(index, combined);
 1520  4
             result = make.at(diagPos).Apply(null, select, args);
 1521  4
         } else if (shouldMorph(vsym)) {
 1522  
             // we are setting a var Location, call the set method
 1523  17
             JCExpression targetLHS = translate(tree.lhs, Wrapped.InLocation);
 1524  17
             JCFieldAccess setSelect = make.Select(targetLHS, defs.locationSetMethodName[typeMorpher.typeMorphInfo(vsym.type).getTypeKind()]);
 1525  17
             List<JCExpression> setArgs = List.of(combined);
 1526  17
             result = make.at(diagPos).Apply(null, setSelect, setArgs);
 1527  17
         } else {
 1528  
             // We are setting a "normal" non-Location non-sequence-access, use normal assignop
 1529  17
             result = make.at(diagPos).Assignop(tree.getTag(), lhs, rhs);
 1530  
         }
 1531  38
     }
 1532  
 
 1533  
     @Override
 1534  
     public void visitSelect(JCFieldAccess tree) {
 1535  6473
         DiagnosticPosition diagPos = tree.pos();
 1536  6473
         JCExpression expr = tree.getExpression();
 1537  6473
         Type exprType = expr.type;
 1538  
 
 1539  
         // this may or may not be in a LHS but in either
 1540  
         // event the selector is a value expression
 1541  6473
         JCExpression translatedSelected = translate(expr, Wrapped.InNothing);
 1542  
         
 1543  6473
         if (tree.type instanceof FunctionType && tree.sym.type instanceof MethodType) {
 1544  
             //TODO: this branch is never actually taken (in tests suite)
 1545  0
             MethodType mtype = (MethodType) tree.sym.type;            
 1546  0
             JCVariableDecl selectedTmpDecl = makeTmpVar(diagPos, "tg", exprType, translatedSelected);
 1547  0
             JCExpression translated = make.at(diagPos).Select(make.Ident(selectedTmpDecl.name), tree.getIdentifier());
 1548  0
             translated = makeFunctionValue(translated, null, diagPos, mtype);
 1549  
             //result = make.LetExpr(selectedTmp, translated);
 1550  0
             result = ((JavafxTreeMaker)make).BlockExpression(
 1551  
                 0L,
 1552  
                 List.<JCStatement>of(selectedTmpDecl), 
 1553  
                 translated);
 1554  0
            return;
 1555  
         }
 1556  
 
 1557  6473
         if (exprType != null && exprType.isPrimitive()) { // expr.type is null for package symbols.
 1558  25
             translatedSelected = makeBox(diagPos, translatedSelected, exprType);
 1559  
         }
 1560  
         // determine if this is a static reference, eg.   MyClass.myAttribute
 1561  6473
         boolean staticReference = tree.sym.isStatic();
 1562  6473
         if (staticReference) {
 1563  3558
             translatedSelected = makeTypeTree( diagPos,types.erasure(tree.sym.owner.type), false);
 1564  
         }
 1565  
 
 1566  6473
         boolean testForNull = generateNullChecks && !staticReference
 1567  
                                            && (tree.sym instanceof VarSymbol) 
 1568  
                                            && types.isJFXClass(exprType.tsym);
 1569  6473
         boolean hasSideEffects = testForNull && hasSideEffects(expr);
 1570  6473
         JCVariableDecl tmpVar = null;
 1571  6473
         if (hasSideEffects) {
 1572  8
             tmpVar = makeTmpVar(diagPos, exprType, translatedSelected);
 1573  8
             translatedSelected = make.at(diagPos).Ident(tmpVar.name);
 1574  
         }
 1575  
         
 1576  6473
         JCFieldAccess translated = make.at(diagPos).Select(translatedSelected, tree.getIdentifier());
 1577  
 
 1578  6473
         JCExpression ref = convertVariableReference(
 1579  
                 diagPos,
 1580  
                 translated,
 1581  
                 tree.sym, 
 1582  
                 (wrap == Wrapped.InLocation));
 1583  6473
         if (testForNull) {
 1584  
             // we have a testable guard for null, wrap the attribute access  in it, return default value if null
 1585  471
             TypeMorphInfo tmi = typeMorpher.typeMorphInfo(tree.type);
 1586  471
             JCExpression defaultExpr = makeDefaultValue(diagPos, tmi);
 1587  471
             if (wrap == Wrapped.InLocation) {
 1588  114
                 defaultExpr = makeUnboundLocation(diagPos, tmi, defaultExpr);
 1589  
             }
 1590  
 
 1591  
             JCExpression checkedExpr;
 1592  471
             if (hasSideEffects) {
 1593  
                 // we don't recreate (we've stuck it in a var)
 1594  8
                 checkedExpr = make.at(diagPos).Ident(tmpVar.name);
 1595  
             } else {
 1596  
                 // re-translate, we need two of them
 1597  463
                 checkedExpr = translate(expr, Wrapped.InNothing);
 1598  
             }
 1599  471
             JCExpression cond = make.at(diagPos).Binary(
 1600  
                     JCTree.EQ,
 1601  
                     checkedExpr,
 1602  
                     make.Literal(TypeTags.BOT, null));
 1603  471
             ref = make.at(diagPos).Conditional(cond, defaultExpr, ref);
 1604  471
             if (hasSideEffects) {
 1605  
                 // put the tmp var and the conditional in a block expression
 1606  8
                 List<JCStatement> stmts = List.<JCStatement>of(tmpVar);
 1607  8
                 ref = fxmake.at(diagPos).BlockExpression(0L, stmts, ref);
 1608  
             }
 1609  
         }
 1610  6473
         result = ref;
 1611  6473
     }
 1612  
     //where
 1613  
     private boolean hasSideEffects(JCExpression expr) {
 1614  2596
         final boolean[] hasSideEffectHolder = {false};
 1615  2596
         new JavafxTreeScanner() {
 1616  
 
 1617  
             private void markSideEffects() {
 1618  52
                 hasSideEffectHolder[0] = true;
 1619  52
             }
 1620  
 
 1621  
             @Override
 1622  
             public void visitBlockExpression(JFXBlockExpression tree) {
 1623  0
                 markSideEffects(); // maybe doesn't but covers all statements
 1624  0
             }
 1625  
 
 1626  
             @Override
 1627  
             public void visitUnary(JCUnary tree) {
 1628  3
                 markSideEffects();
 1629  3
             }
 1630  
 
 1631  
             @Override
 1632  
             public void visitAssignop(JCAssignOp tree) {
 1633  0
                 markSideEffects();
 1634  0
             }
 1635  
 
 1636  
             @Override
 1637  
             public void visitInstanciate(JFXInstanciate tree) {
 1638  10
                 markSideEffects();
 1639  10
             }
 1640  
 
 1641  
             @Override
 1642  
             public void visitAssign(JCAssign tree) {
 1643  0
                 markSideEffects();
 1644  0
             }
 1645  
 
 1646  
             @Override
 1647  
             public void visitApply(JCMethodInvocation tree) {
 1648  39
                 markSideEffects();
 1649  39
             }
 1650  
         }.scan(expr);
 1651  2596
         return hasSideEffectHolder[0];
 1652  
     }
 1653  
     
 1654  
     @Override
 1655  
     public void visitIdent(JCIdent tree)   {
 1656  12647
        DiagnosticPosition diagPos = tree.pos();
 1657  12647
         if (tree.name == names._this) {
 1658  
             // in the static implementation method, "this" becomes "receiver$"
 1659  35
             JCExpression rcvr = make.at(diagPos).Ident(defs.receiverName);
 1660  35
             if (wrap == Wrapped.InLocation) {
 1661  0
                 rcvr = makeConstantLocation(diagPos, tree.type, rcvr);
 1662  
             }
 1663  35
             result = rcvr;
 1664  35
             return;
 1665  12612
         } else if (tree.name == names._super) {
 1666  9
             if (types.isCompoundClass(tree.type.tsym)) {
 1667  
                 // "super" become just the class where the static implementation method is defined
 1668  
                 //  the rest of the implementation is in visitApply
 1669  9
                 result = make.at(diagPos).Ident(tree.type.tsym.name);
 1670  
             }
 1671  
             else {
 1672  0
                JCFieldAccess superSelect = make.at(diagPos).Select(make.at(diagPos).Ident(defs.receiverName), tree.name);
 1673  0
                 result = superSelect;
 1674  
             }
 1675  9
             return;
 1676  
         }
 1677  
 
 1678  
        // if this is an instance reference to an attribute or function, it needs to go the the "receiver$" arg,
 1679  
        // and possible outer access methods
 1680  
         JCExpression convert;
 1681  12603
         boolean isStatic = tree.sym.isStatic();
 1682  12603
         int kind = tree.sym.kind;
 1683  12603
         if (isStatic) {
 1684  
             // make class-based direct static reference:   Foo.x
 1685  1044
             convert = make.at(diagPos).Select(makeTypeTree( diagPos,tree.sym.owner.type, false), tree.name);
 1686  
         } else {
 1687  11559
             if ((kind == Kinds.VAR || kind == Kinds.MTH) && tree.sym.owner.kind == Kinds.TYP) {
 1688  
                 // it is a non-static attribute or function class member
 1689  
                 // reference it through the receiver
 1690  1999
                 JCExpression mRec = makeReceiver(diagPos, tree.sym, attrEnv.enclClass.sym);
 1691  1999
                 convert = make.at(diagPos).Select(mRec, tree.name);
 1692  1999
             } else {
 1693  9560
                 convert = make.at(diagPos).Ident(tree.name);
 1694  
             }
 1695  
         }
 1696  
         
 1697  12603
         if (tree.type instanceof FunctionType && tree.sym.type instanceof MethodType) {
 1698  9
             MethodType mtype = (MethodType) tree.sym.type;
 1699  9
             JFXFunctionDefinition def = null; // FIXME
 1700  9
             result = makeFunctionValue(convert, def, tree.pos(), mtype);
 1701  9
             return;
 1702  
         }
 1703  
 
 1704  12594
         result = convertVariableReference(diagPos, 
 1705  
                 convert, 
 1706  
                 tree.sym, 
 1707  
                 (wrap == Wrapped.InLocation));
 1708  12594
     }
 1709  
     
 1710  
     @Override
 1711  
     public void visitSequenceExplicit(JFXSequenceExplicit tree) {
 1712  
         /*** 
 1713  
          * In cases where the components of an explicitly constructed 
 1714  
          * sequence are all singletons, we can revert to this (more 
 1715  
          * optimal) implementation.
 1716  
  
 1717  
         DiagnosticPosition diagPos = tree.pos();
 1718  
         JCExpression meth = ((JavafxTreeMaker)make).at(diagPos).Identifier(sequencesMakeString);
 1719  
         Type elemType = tree.type.getTypeArguments().get(0);
 1720  
         ListBuffer<JCExpression> args = ListBuffer.<JCExpression>lb();
 1721  
         List<JCExpression> typeArgs = List.<JCExpression>of(makeTypeTree(elemType, diagPos));
 1722  
         // type name .class
 1723  
         args.append(makeElementClassObject(diagPos, elemType));
 1724  
         args.appendList( translate( tree.getItems() ) );
 1725  
         result = make.at(diagPos).Apply(typeArgs, meth, args.toList());
 1726  
         */
 1727  378
         ListBuffer<JCStatement> stmts = ListBuffer.lb();
 1728  378
         Type elemType = elementType(tree.type);
 1729  378
         UseSequenceBuilder builder = useSequenceBuilder(tree.pos(), elemType);
 1730  378
         stmts.append(builder.makeBuilderVar());
 1731  378
         for (JCExpression item : tree.getItems()) {
 1732  1420
             stmts.append(builder.makeAdd( item ) );
 1733  
         }
 1734  378
         result = makeBlockExpression(tree.pos(), stmts, builder.makeToSequence());
 1735  378
     }
 1736  
     
 1737  
     @Override
 1738  
     public void visitSequenceRange(JFXSequenceRange tree) {
 1739  180
         DiagnosticPosition diagPos = tree.pos();
 1740  180
         JCExpression meth = makeQualifiedTree(
 1741  
                 diagPos, tree.isExclusive()? 
 1742  
                     sequencesRangeExclusiveString : 
 1743  
                     sequencesRangeString);
 1744  180
         ListBuffer<JCExpression> args = ListBuffer.lb();
 1745  180
         List<JCExpression> typeArgs = List.nil();
 1746  180
         args.append( translate( tree.getLower() ));
 1747  180
         args.append( translate( tree.getUpper() ));
 1748  180
         if (tree.getStepOrNull() != null) {
 1749  39
             args.append( translate( tree.getStepOrNull() ));
 1750  
         }
 1751  180
         result = make.at(diagPos).Apply(typeArgs, meth, args.toList());
 1752  180
     }
 1753  
     
 1754  
     @Override
 1755  
     public void visitSequenceEmpty(JFXSequenceEmpty tree) {
 1756  51
         if (types.isSequence(tree.type)) {
 1757  23
             Type elemType = elementType(tree.type);
 1758  23
             result = makeEmptySequenceCreator(tree.pos(), elemType);
 1759  23
         }
 1760  
         else
 1761  28
             result = make.at(tree.pos).Literal(TypeTags.BOT, null);
 1762  51
     }
 1763  
         
 1764  
     @Override
 1765  
     public void visitSequenceIndexed(JFXSequenceIndexed tree) {
 1766  398
         DiagnosticPosition diagPos = tree.pos();
 1767  398
         JCExpression seq = translate(tree.getSequence(), Wrapped.InLocation);  
 1768  398
         JCExpression index = translate(tree.getIndex());
 1769  398
         JCFieldAccess select = make.at(diagPos).Select(seq, defs.getMethodName);
 1770  398
         List<JCExpression> args = List.of(index);
 1771  398
         result = make.at(diagPos).Apply(null, select, args);
 1772  398
     }
 1773  
 
 1774  
     @Override
 1775  
     public void visitSequenceSlice(JFXSequenceSlice tree) {
 1776  14
         DiagnosticPosition diagPos = tree.pos();
 1777  14
         JCExpression seq = translate(tree.getSequence(), Wrapped.InLocation);  
 1778  14
         JCExpression firstIndex = translate(tree.getFirstIndex());
 1779  14
         JCExpression lastIndex = makeSliceLastIndex(tree);
 1780  14
         JCFieldAccess select = make.at(diagPos).Select(seq, defs.getSliceMethodName);
 1781  14
         List<JCExpression> args = List.of(firstIndex, lastIndex);
 1782  14
         result = make.at(diagPos).Apply(null, select, args);
 1783  14
     }
 1784  
 
 1785  
     @Override
 1786  
     public void visitSequenceInsert(JFXSequenceInsert tree) {
 1787  186
         DiagnosticPosition diagPos = tree.pos();
 1788  186
         JCExpression seqLoc = translate(tree.getSequence(), Wrapped.InLocation);
 1789  186
         JCExpression elem = translate( tree.getElement() );
 1790  186
         if (tree.getPosition() == null) {
 1791  99
             result = callStatement(diagPos, seqLoc, "insert", elem);
 1792  
         } else {
 1793  87
             String meth = tree.shouldInsertAfter()? "insertAfter" : "insertBefore";
 1794  87
             result = callStatement(diagPos, seqLoc, meth, 
 1795  
                     List.of(elem, translate(tree.getPosition())));
 1796  
         }
 1797  186
     }
 1798  
     
 1799  
     @Override
 1800  
     public void visitSequenceDelete(JFXSequenceDelete tree) {
 1801  123
         JCExpression seq = tree.getSequence();
 1802  
 
 1803  123
         if (tree.getElement() != null) {
 1804  25
             JCExpression seqLoc = translate(seq, Wrapped.InLocation);
 1805  25
             result = callStatement(tree.pos(), seqLoc, "deleteValue", translate(tree.getElement()));
 1806  25
         } else {
 1807  98
             if (seq.getTag() == JavafxTag.SEQUENCE_INDEXED) {
 1808  
                 // deletion of a sequence element -- delete s[i]
 1809  38
                 JFXSequenceIndexed si = (JFXSequenceIndexed) seq;
 1810  38
                 JCExpression seqseq = si.getSequence();
 1811  38
                 JCExpression seqLoc = translate(seqseq, Wrapped.InLocation);
 1812  38
                 JCExpression index = translate(si.getIndex());
 1813  38
                 result = callStatement(tree.pos(), seqLoc, "delete", index);
 1814  38
             } else if (seq.getTag() == JavafxTag.SEQUENCE_SLICE) {
 1815  
                 // deletion of a sequence slice --  delete s[i..j]=8
 1816  35
                 JFXSequenceSlice slice = (JFXSequenceSlice) seq;
 1817  35
                 JCExpression seqseq = slice.getSequence();
 1818  35
                 JCExpression seqLoc = translate(seqseq, Wrapped.InLocation);
 1819  35
                 JCExpression first = translate(slice.getFirstIndex());
 1820  35
                 JCExpression last = makeSliceLastIndex(slice);
 1821  35
                 result = callStatement(tree.pos(), seqLoc, "deleteSlice", List.of(first, last));
 1822  35
             } else if (types.isSequence(seq.type)) {
 1823  25
                 JCExpression seqLoc = translate(seq, Wrapped.InLocation);
 1824  25
                 result = callStatement(tree.pos(), seqLoc, "deleteAll");
 1825  25
             } else {
 1826  0
                 result = make.at(tree.pos()).Exec(
 1827  
                             make.Assign(
 1828  
                                 translate(seq), 
 1829  
                                 make.Literal(TypeTags.BOT, null)));
 1830  
             }
 1831  
         }
 1832  123
     }
 1833  
 
 1834  
     /**** utility methods ******/
 1835  
     
 1836  
     JCExpression makeSliceLastIndex(JFXSequenceSlice tree) {
 1837  61
         JCExpression lastIndex = tree.getLastIndex() == null ? 
 1838  
                 callExpression(tree, 
 1839  
                     translate(tree.getSequence()),
 1840  
                     defs.sizeMethodName) : 
 1841  
                 translate(tree.getLastIndex());
 1842  61
         int decr = 
 1843  
                 (tree.getEndKind() == SequenceSliceTree.END_EXCLUSIVE ? 1 : 0) +
 1844  
                 (tree.getLastIndex() == null ? 1 : 0);
 1845  61
         if (decr > 0) {
 1846  26
             lastIndex = make.at(tree).Binary(JavafxTag.MINUS,
 1847  
                     lastIndex, make.Literal(TypeTags.INT, decr));
 1848  
         }
 1849  61
         return lastIndex;
 1850  
     }
 1851  
    
 1852  
     JCMethodDecl makeMainMethod(DiagnosticPosition diagPos, Name className) {
 1853  340
             List<JCExpression> emptyExpressionList = List.nil();
 1854  340
             JCExpression classIdent = make.at(diagPos).Ident(className);
 1855  340
             JCExpression classConstant = make.at(diagPos).Select(classIdent, names._class);
 1856  340
             JCExpression commandLineArgs = makeIdentifier(diagPos, "args");
 1857  340
             JCExpression startIdent = makeQualifiedTree(diagPos, JavafxDefs.startMethodString);
 1858  340
             ListBuffer<JCExpression>args = new ListBuffer<JCExpression>();
 1859  340
             args.append(classConstant);
 1860  340
             args.append(commandLineArgs);
 1861  340
             JCMethodInvocation runCall = make.at(diagPos).Apply(emptyExpressionList, startIdent, args.toList());
 1862  340
             List<JCStatement> mainStats = List.<JCStatement>of(make.at(diagPos).Exec(runCall));
 1863  340
             List<JCVariableDecl> paramList = List.nil();
 1864  340
             paramList = paramList.append(make.at(diagPos).VarDef(make.Modifiers(0), 
 1865  
                     Name.fromString(names, "args"), 
 1866  
                     make.at(diagPos).TypeArray(make.Ident(Name.fromString(names, "String"))), 
 1867  
                     null));
 1868  340
             JCBlock body = make.Block(0, mainStats);
 1869  340
             return make.at(diagPos).MethodDef(make.Modifiers(Flags.PUBLIC | Flags.STATIC),
 1870  
                     Name.fromString(names, "main"), 
 1871  
                     make.at(diagPos).TypeIdent(TypeTags.VOID), 
 1872  
                     List.<JCTypeParameter>nil(), 
 1873  
                     paramList, 
 1874  
                     makeThrows(diagPos), 
 1875  
                     body, 
 1876  
                     null);
 1877  
     }
 1878  
 
 1879  
     /** Equivalent to make.at(pos.getStartPosition()) with side effect of caching
 1880  
      *  pos as make_pos, for use in diagnostics.
 1881  
      **/
 1882  
     TreeMaker make_at(DiagnosticPosition pos) {
 1883  47
         return make.at(pos);
 1884  
     }
 1885  
 
 1886  
     /** Look up a method in a given scope.
 1887  
      */
 1888  
     private MethodSymbol lookupMethod(DiagnosticPosition pos, Name name, Type qual, List<Type> args) {
 1889  47
         return rs.resolveInternalMethod(pos, attrEnv, qual, name, args, null);
 1890  
     }
 1891  
 
 1892  
     /** Look up a constructor.
 1893  
      */
 1894  
     private MethodSymbol lookupConstructor(DiagnosticPosition pos, Type qual, List<Type> args) {
 1895  0
         return rs.resolveInternalConstructor(pos, attrEnv, qual, args, null);
 1896  
     }
 1897  
 
 1898  
     /** Box up a single primitive expression. */
 1899  
     JCExpression makeBox(DiagnosticPosition diagPos, JCExpression translatedExpr, Type primitiveType) {
 1900  47
         make_at(translatedExpr.pos());
 1901  47
         if (target.boxWithConstructors()) {
 1902  0
             Symbol ctor = lookupConstructor(translatedExpr.pos(),
 1903  
                                             types.boxedClass(primitiveType).type,
 1904  
                                             List.<Type>nil()
 1905  
                                             .prepend(primitiveType));
 1906  0
             return make.Create(ctor, List.of(translatedExpr));
 1907  
         } else {
 1908  47
             Symbol valueOfSym = lookupMethod(translatedExpr.pos(),
 1909  
                                              names.valueOf,
 1910  
                                              types.boxedClass(primitiveType).type,
 1911  
                                              List.<Type>nil()
 1912  
                                              .prepend(primitiveType));
 1913  
 //            JCExpression meth =makeIdentifier(valueOfSym.owner.type.toString() + "." + valueOfSym.name.toString());
 1914  47
             JCExpression meth = make.Select(makeTypeTree( diagPos,valueOfSym.owner.type), valueOfSym.name);
 1915  47
             TreeInfo.setSymbol(meth, valueOfSym);
 1916  47
             meth.type = valueOfSym.type;
 1917  47
             return make.App(meth, List.of(translatedExpr));
 1918  
         }
 1919  
     }
 1920  
     
 1921  
     public List<JCExpression> makeThrows(DiagnosticPosition diagPos) {
 1922  340
         return List.of(makeQualifiedTree(diagPos, methodThrowsString));
 1923  
     }
 1924  
     
 1925  
     UseSequenceBuilder useSequenceBuilder(DiagnosticPosition diagPos, Type elemType) {
 1926  
 
 1927  432
         return new UseSequenceBuilder(diagPos, elemType, sequenceBuilderString) {
 1928  
 
 1929  
             JCStatement makeAdd(JCExpression exprToAdd) {
 1930  1474
                 JCExpression expr = translate(exprToAdd);
 1931  1474
                 Type exprType = exprToAdd.type;
 1932  1474
                 return makeAdd(expr, exprType);
 1933  
             }
 1934  
         };
 1935  
     }
 1936  
     
 1937  
     UseSequenceBuilder useBoundSequenceBuilder(DiagnosticPosition diagPos, Type elemType) {
 1938  
 
 1939  29
         return new UseSequenceBuilder(diagPos, elemType, boundSequenceBuilderString) {
 1940  
 
 1941  
             JCStatement makeAdd(JCExpression exprToAdd) {
 1942  80
                 JCExpression expr = toBound.translate(exprToAdd);
 1943  80
                 Type exprType = exprToAdd.type;
 1944  80
                 return makeAdd(expr, exprType);
 1945  
             }
 1946  
         };
 1947  
     }
 1948  
     
 1949  
     abstract class UseSequenceBuilder {
 1950  
         final DiagnosticPosition diagPos;
 1951  
         final Type elemType;
 1952  
         final String seqBuilder;
 1953  
         
 1954  
         Name sbName;
 1955  
         
 1956  461
         UseSequenceBuilder(DiagnosticPosition diagPos, Type elemType, String seqBuilder) {
 1957  461
             this.diagPos = diagPos;
 1958  461
             this.elemType = elemType;
 1959  461
             this.seqBuilder = seqBuilder;
 1960  461
         }
 1961  
         
 1962  
         JCStatement makeBuilderVar() {
 1963  461
             JCExpression builderTypeExpr = makeQualifiedTree(diagPos, seqBuilder);
 1964  461
             List<JCExpression> btargs = List.of(makeTypeTree(diagPos, elemType));
 1965  461
             builderTypeExpr = make.at(diagPos).TypeApply(builderTypeExpr, btargs);
 1966  
 
 1967  
             // Sequence builder temp var name "sb"
 1968  461
             sbName = getSyntheticName("sb");
 1969  
 
 1970  
             // Build "sb" initializing expression -- new SequenceBuilder<T>(clazz)
 1971  461
             List<JCExpression> args = List.<JCExpression>of(
 1972  
                     makeElementClassObject(diagPos, elemType));               
 1973  
 
 1974  461
             JCExpression newExpr = make.at(diagPos).NewClass(
 1975  
                 null,                               // enclosing
 1976  
                 List.<JCExpression>nil(),           // type args
 1977  
                 make.at(diagPos).TypeApply(         // class name -- SequenceBuilder<elemType>
 1978  
                      makeQualifiedTree(diagPos, seqBuilder), 
 1979  
                      List.<JCExpression>of(makeTypeTree(diagPos, elemType))),
 1980  
                 args,                               // args
 1981  
                 null                                // empty body
 1982  
                 );
 1983  
         
 1984  
             // Build the sequence builder variable
 1985  461
             return make.at(diagPos).VarDef( 
 1986  
                 make.at(diagPos).Modifiers(0L), 
 1987  
                 sbName, builderTypeExpr, newExpr);
 1988  
         }
 1989  
         
 1990  
         JCIdent makeBuilderVarAccess() {
 1991  2015
             return make.Ident(sbName);  
 1992  
         }
 1993  
          
 1994  
         abstract JCStatement makeAdd(JCExpression expr);
 1995  
          
 1996  
         JCStatement makeAdd(JCExpression expr, Type exprType) {
 1997  1554
             if (exprType != elemType) {
 1998  863
                 Type unboxedElemType = types.unboxedType(elemType);
 1999  863
                 if (unboxedElemType != Type.noType) {
 2000  734
                     Type unboxedExprType = types.unboxedType(exprType);
 2001  734
                     if (unboxedExprType != Type.noType) {
 2002  0
                             expr = make.at(diagPos).TypeCast(unboxedExprType, expr);
 2003  0
                             exprType = unboxedExprType;
 2004  
                     }
 2005  734
                     if (exprType.tag == TypeTags.INT && unboxedElemType.tag == TypeTags.DOUBLE) {
 2006  26
                         expr = make.at(diagPos).TypeCast(unboxedElemType, expr);
 2007  
                     }
 2008  
                 } 
 2009  
              }
 2010  1554
             JCMethodInvocation addCall = make.Apply(
 2011  
                     List.<JCExpression>nil(), 
 2012  
                     make.at(diagPos).Select(
 2013  
                         makeBuilderVarAccess(), 
 2014  
                         Name.fromString(names, "add")), 
 2015  
                     List.<JCExpression>of(expr));
 2016  1554
             return make.at(diagPos).Exec(addCall);
 2017  
         }
 2018  
 
 2019  
         JCExpression makeToSequence() {
 2020  461
             return make.Apply(
 2021  
                 List.<JCExpression>nil(), // type arguments
 2022  
                 make.at(diagPos).Select(
 2023  
                     makeBuilderVarAccess(), 
 2024  
                     Name.fromString(names, toSequenceString)),
 2025  
                 List.<JCExpression>nil() // arguments
 2026  
                 );
 2027  
         }
 2028  
     }
 2029  
   
 2030  
    JCExpression castFromObject (JCExpression arg, Type castType) {
 2031  26
         if (castType.isPrimitive())
 2032  17
             castType = types.boxedClass(castType).type;
 2033  26
          return make.TypeCast(makeTypeTree( arg.pos(),castType), arg);
 2034  
     }
 2035  
 
 2036  
     /**
 2037  
      * JCTrees which can just be copied and trees which sjould not occur 
 2038  
      * */
 2039  
     
 2040  
     @Override
 2041  
     public void visitAnnotation(JCAnnotation tree) {
 2042  0
         JCTree annotationType = translate(tree.annotationType);
 2043  0
         List<JCExpression> args = translate(tree.args);
 2044  0
         result = make.at(tree.pos).Annotation(annotationType, args);
 2045  0
     }
 2046  
 
 2047  
     @Override
 2048  
     public void visitAssert(JCAssert tree) {
 2049  0
         JCExpression cond = translate(tree.cond);
 2050  0
         JCExpression detail = translate(tree.detail);
 2051  0
         result = make.at(tree.pos).Assert(cond, detail);
 2052  0
     }
 2053  
 
 2054  
     @Override
 2055  
     public void visitBinary(final JCBinary tree) {
 2056  995
         result = (new Translator( tree.pos(), this ) {
 2057  
 
 2058  
             /**
 2059  
              * Compare against null
 2060  
              */
 2061  
             private JCExpression makeNullCheck(JCExpression targ) {
 2062  18
                 return makeEqEq(targ, makeNull());
 2063  
             }
 2064  
             
 2065  
             //TODO: after type system is figured out, this needs to be revisited
 2066  
             /**
 2067  
              * Check if a primitive has the default value for its type.
 2068  
              */
 2069  
             private JCExpression makePrimitiveNullCheck(Type argType, JCExpression arg) {
 2070  0
                 TypeMorphInfo tmi = typeMorpher.typeMorphInfo(argType);
 2071  0
                 JCExpression defaultValue = makeLit(diagPos, tmi.getRealType(), tmi.getDefaultValue());
 2072  0
                 return makeEqEq( arg, defaultValue);
 2073  
             }
 2074  
             
 2075  
             /**
 2076  
              * Check if a non-primitive has the default value for its type.
 2077  
              */
 2078  
             private JCExpression makeObjectNullCheck(Type argType, JCExpression arg) {
 2079  65
                 TypeMorphInfo tmi = typeMorpher.typeMorphInfo(argType);
 2080  65
                 if (tmi.getTypeKind() == TYPE_KIND_SEQUENCE || tmi.getRealType() == syms.javafx_StringType) {
 2081  47
                     return callRuntime(JavafxDefs.isNullMethodString, List.of(arg));
 2082  
                 } else {
 2083  18
                     return makeNullCheck(arg);
 2084  
                 }
 2085  
             }
 2086  
            
 2087  
             /*
 2088  
              * Do a == compare
 2089  
              */
 2090  
             private JCExpression makeEqEq(JCExpression arg1, JCExpression arg2) {
 2091  177
                 return makeBinary(JCTree.EQ, arg1, arg2);
 2092  
             }
 2093  
             
 2094  
             private JCExpression makeBinary(int tag, JCExpression arg1, JCExpression arg2) {
 2095  769
                 return make.at(diagPos).Binary(tag, arg1, arg2);
 2096  
             }
 2097  
             
 2098  
             private JCExpression makeNull() {
 2099  18
                 return make.at(diagPos).Literal(TypeTags.BOT, null);
 2100  
             }
 2101  
             
 2102  
             private JCExpression callRuntime(String methNameString, List<JCExpression> args) {
 2103  218
                 JCExpression meth = makeQualifiedTree(diagPos, methNameString);
 2104  218
                 List<JCExpression> typeArgs = List.nil();
 2105  218
                 return m().Apply(typeArgs, meth, args);
 2106  
             }
 2107  
             
 2108  
             /**
 2109  
              * Make a .equals() comparison with a null check on the receiver
 2110  
              */
 2111  
             private JCExpression makeFullCheck(JCExpression lhs, JCExpression rhs) {
 2112  171
                 return callRuntime(JavafxDefs.equalsMethodString, List.of(lhs, rhs));
 2113  
             }
 2114  
             
 2115  
             /**
 2116  
              * Return the translation for a == comparision
 2117  
              */
 2118  
             private JCExpression translateEqualsEquals() {
 2119  396
                 final JCExpression lhs = translate( tree.lhs );
 2120  396
                 final JCExpression rhs = translate( tree.rhs );
 2121  396
                 final Type lhsType = tree.lhs.type;
 2122  396
                 final Type rhsType = tree.rhs.type;
 2123  
                 
 2124  
                     // this is an x == y
 2125  396
                     if (lhsType.getKind() == TypeKind.NULL) {
 2126  21
                         if (rhsType.getKind() == TypeKind.NULL) {
 2127  
                             // both are known to be null
 2128  1
                             return make.at(diagPos).Literal(TypeTags.BOOLEAN, 1);
 2129  20
                         } else if (rhsType.isPrimitive()) {
 2130  
                             // lhs is null, rhs is primitive, do default check
 2131  0
                             return makePrimitiveNullCheck(rhsType, rhs);
 2132  
                         } else {
 2133  
                             // lhs is null, rhs is non-primitive, figure out what check to do
 2134  20
                             return makeObjectNullCheck(rhsType, rhs);
 2135  
                         }
 2136  375
                     } else if (lhsType.isPrimitive()) {
 2137  163
                         if (rhsType.getKind() == TypeKind.NULL) {
 2138  
                             // lhs is primitive, rhs is null, do default check on lhs
 2139  0
                             return makePrimitiveNullCheck(lhsType, lhs);
 2140  163
                         } else if (rhsType.isPrimitive()) {
 2141  
                             // both are primitive, use ==
 2142  159
                             return makeEqEq(lhs, rhs);
 2143  
                         } else {
 2144  
                             // lhs is primitive, rhs is non-primitive, use equals(), but switch them
 2145  4
                             return makeFullCheck(rhs, lhs);
 2146  
                         }
 2147  
                     } else {
 2148  212
                         if (rhsType.getKind() == TypeKind.NULL) {
 2149  
                             // lhs is non-primitive, rhs is null, figure out what check to do
 2150  45
                             return makeObjectNullCheck(lhsType, lhs);
 2151  
                         } else {
 2152  
                             //  lhs is non-primitive, use equals()
 2153  167
                             return makeFullCheck(lhs, rhs);
 2154  
                         }
 2155  
                     }
 2156  
             }
 2157  
            
 2158  
             /**
 2159  
              * Translate a binary expressions
 2160  
              */
 2161  
             public JCTree doit() {
 2162  
                 //TODO: handle <>
 2163  995
                 if (tree.getTag() == JavafxTag.EQ) {
 2164  303
                     return translateEqualsEquals();
 2165  692
                 } else if (tree.getTag() == JavafxTag.NE) {
 2166  93
                     return make.at(diagPos).Unary(JCTree.NOT, translateEqualsEquals());
 2167  
                 }  else {
 2168  
                     // anything other than == or <>
 2169  
 
 2170  
                     // Duration type operator overloading
 2171  599
                     if ((types.isSameType(tree.lhs.type, syms.javafx_DurationType) ||
 2172  
                          types.isSameType(tree.rhs.type, syms.javafx_DurationType)) &&
 2173  
                         tree.operator == null) { // operator check is to try to get a decent error message by falling through if the Duration method isn't matched
 2174  7
                         JCExpression l = tree.lhs;
 2175  7
                         JCExpression r = tree.rhs;
 2176  7
                         switch (tree.getTag()) {
 2177  
                         case JavafxTag.PLUS:
 2178  4
                             return make.at(diagPos).Apply(null,
 2179  
                                                           make.at(diagPos).Select(translate(l), Name.fromString(names, "add")), List.<JCExpression>of(translate(r)));
 2180  
                             // lhs.add(rhs);
 2181  
                         case JavafxTag.MINUS:
 2182  
                             // lhs.sub(rhs);
 2183  1
                             return make.at(diagPos).Apply(null,
 2184  
                                                           make.at(diagPos).Select(translate(l), Name.fromString(names, "sub")), List.<JCExpression>of(translate(r)));
 2185  
                         case JavafxTag.DIV:
 2186  
                             // lhs.div(rhs);
 2187  1
                             return make.at(diagPos).Apply(null,
 2188  
                                                           make.at(diagPos).Select(translate(l), Name.fromString(names, "div")), List.<JCExpression>of(translate(r)));
 2189  
                         case JavafxTag.MUL:
 2190  
                             // lhs.mul(rhs);
 2191  1
                             if (!types.isSameType(l.type, syms.javafx_DurationType)) {
 2192  0
                                 r = l;
 2193  0
                                 l = tree.rhs;
 2194  
                             }
 2195  1
                             return make.at(diagPos).Apply(null,
 2196  
                                                           make.at(diagPos).Select(translate(l), Name.fromString(names, "mul")), List.<JCExpression>of(translate(r)));
 2197  
                         case JavafxTag.LT:
 2198  0
                             return make.at(diagPos).Apply(null,
 2199  
                                                           make.at(diagPos).Select(translate(l), Name.fromString(names, "lt")), List.<JCExpression>of(translate(r)));
 2200  
                         case JavafxTag.LE:
 2201  0
                             return make.at(diagPos).Apply(null,
 2202  
                                                           make.at(diagPos).Select(translate(l), Name.fromString(names, "le")), List.<JCExpression>of(translate(r)));
 2203  
                         case JavafxTag.GT:
 2204  0
                             return make.at(diagPos).Apply(null,
 2205  
                                                           make.at(diagPos).Select(translate(l), Name.fromString(names, "gt")), List.<JCExpression>of(translate(r)));
 2206  
                         case JavafxTag.GE:
 2207  0
                             return make.at(diagPos).Apply(null,
 2208  
                                                           make.at(diagPos).Select(translate(l), Name.fromString(names, "ge")), List.<JCExpression>of(translate(r)));
 2209  
                         }
 2210  
                     }
 2211  592
                     final JCExpression lhs = translate(tree.lhs);
 2212  592
                     final JCExpression rhs = translate(tree.rhs);
 2213  592
                     return makeBinary(tree.getTag(), lhs, rhs);
 2214  
                 }
 2215  
             }
 2216  
 
 2217  
         }).doit();
 2218  995
     }
 2219  
 
 2220  
     @Override
 2221  
     public void visitBreak(JCBreak tree) {
 2222  5
         result = make.at(tree.pos).Break(tree.label);
 2223  5
     }
 2224  
 
 2225  
     @Override
 2226  
    public void visitCase(JCCase tree) {
 2227  0
         assert false : "should not be in JavaFX AST";
 2228  0
     }
 2229  
 
 2230  
     @Override
 2231  
     public void visitCatch(JCCatch tree) {
 2232  35
         JCVariableDecl param = translate(tree.param);
 2233  35
         JCBlock body = translate(tree.body);
 2234  35
         result = make.at(tree.pos).Catch(param, body);
 2235  35
     }
 2236  
 
 2237  
     @Override
 2238  
     public void visitClassDef(JCClassDecl tree) {
 2239  0
         assert false : "should not be in JavaFX AST";
 2240  0
     }
 2241  
 
 2242  
     
 2243  
     /**
 2244  
      * assume seq is a sequence of element type U
 2245  
      * convert   for (x in seq where cond) { body }
 2246  
      * into the following block expression
 2247  
      * 
 2248  
      *   {
 2249  
      *     SequenceBuilder<T> sb = new SequenceBuilder<T>(clazz);
 2250  
      *     for (U x : seq) {
 2251  
      *       if (!cond)
 2252  
      *         continue;
 2253  
      *       sb.add( { body } );
 2254  
      *     }
 2255  
      *     sb.toSequence()
 2256  
      *   }
 2257  
      *
 2258  
      * **/
 2259  
     @Override
 2260  
     public void visitForExpression(JFXForExpression tree) {
 2261  
         // sub-translation in done inline -- no super.visitForExpression(tree);
 2262  169
         if (yield == Yield.ToExecStatement) {
 2263  115
              result = wrapWithInClause(tree, translateExpressionToStatement(tree.getBodyExpression()));
 2264  
         } else {
 2265  
             // body has value (non-void)
 2266  54
             assert tree.type != syms.voidType : "should be handled above";
 2267  54
             DiagnosticPosition diagPos = tree.pos();
 2268  54
             ListBuffer<JCStatement> stmts = ListBuffer.lb();
 2269  
             JCStatement stmt;
 2270  
             JCExpression value;
 2271  
 
 2272  
             // Compute the element type from the sequence type
 2273  54
             assert tree.type.getTypeArguments().size() == 1;
 2274  54
             Type elemType = elementType(tree.type);
 2275  
 
 2276  54
             UseSequenceBuilder builder = useSequenceBuilder(diagPos, elemType);
 2277  54
             stmts.append(builder.makeBuilderVar());
 2278  
 
 2279  
             // Build innermost loop body
 2280  54
             stmt = builder.makeAdd( tree.getBodyExpression() );
 2281  
 
 2282  
             // Build the result value
 2283  54
             value = builder.makeToSequence();
 2284  54
             stmt = wrapWithInClause(tree, stmt);
 2285  54
             stmts.append(stmt);
 2286  
 
 2287  54
             if (yield == Yield.ToExpression) {
 2288  
                     // Build the block expression -- which is what we translate to
 2289  51
                     result = makeBlockExpression(diagPos, stmts, value);
 2290  
             } else {
 2291  3
                     stmts.append( make.at(tree).Return( value ) );
 2292  3
                     result = make.at(diagPos).Block(0L, stmts.toList());
 2293  
             }
 2294  
         }
 2295  169
     }
 2296  
 
 2297  
     //where
 2298  
     private JCStatement wrapWithInClause(JFXForExpression tree, JCStatement coreStmt) {
 2299  169
         JCStatement stmt = coreStmt;
 2300  344
         for (int inx = tree.getInClauses().size() - 1; inx >= 0; --inx) {
 2301  175
             JFXForExpressionInClause clause = (JFXForExpressionInClause)tree.getInClauses().get(inx);
 2302  175
             if (clause.getWhereExpression() != null) {
 2303  28
                 stmt = make.at(clause).If( translate( clause.getWhereExpression() ), stmt, null);
 2304  
             }
 2305  
 
 2306  
             // Build the loop
 2307  
             //TODO:  below is the simpler version of the loop. Ideally, this should be used in
 2308  
             // cases where the loop variable does not need to be final.
 2309  
             /*
 2310  
             stmt = make.at(clause).ForeachLoop(
 2311  
                     // loop variable is synthetic should not be bound
 2312  
                     // even if we are in a bind context
 2313  
                     boundTranslate(clause.getVar(), JavafxBindStatus.UNBOUND), 
 2314  
                     translate(clause.getSequenceExpression()),
 2315  
                     stmt);
 2316  
              */
 2317  175
             JFXVar var = clause.getVar();
 2318  175
             Name tmpVarName = getSyntheticName(var.getName().toString());
 2319  175
             JCVariableDecl finalVar = make.VarDef(
 2320  
                     make.Modifiers(Flags.FINAL), 
 2321  
                     var.getName(), 
 2322  
                     makeTypeTree( var,var.type), 
 2323  
                     make.Ident(tmpVarName));
 2324  
             Name tmpIndexVarName;
 2325  175
             if (clause.getIndexUsed()) {
 2326  20
                 Name indexVarName = indexVarName(clause);
 2327  20
                 tmpIndexVarName = getSyntheticName(indexVarName.toString());
 2328  20
                 JCVariableDecl finalIndexVar = make.VarDef(
 2329  
                     make.Modifiers(Flags.FINAL),
 2330  
                     indexVarName, 
 2331  
                     makeTypeTree( var,syms.javafx_IntegerType),
 2332  
                     make.Unary(JCTree.POSTINC, make.Ident(tmpIndexVarName)));
 2333  20
                 stmt = make.Block(0L, List.of(finalIndexVar, finalVar, stmt));
 2334  20
             }                
 2335  
             else {
 2336  155
                 tmpIndexVarName = null;
 2337  155
                 stmt = make.Block(0L, List.of(finalVar, stmt));
 2338  
             }
 2339  
     
 2340  175
             DiagnosticPosition diagPos = clause.seqExpr;
 2341  175
             if (types.isSequence(clause.seqExpr.type)) {
 2342  
                 // It would be more efficient to move the Iterable.iterator call
 2343  
                 // to a static method, which can also check for null.
 2344  
                 // But that requires expanding the ForeachLoop by hand.  Later.
 2345  171
                 JCExpression seq = callExpression(diagPos,
 2346  
                     makeQualifiedTree(diagPos, "com.sun.javafx.runtime.sequence.Sequences"),
 2347  
                     "forceNonNull",
 2348  
                     List.of(makeElementClassObject(diagPos, var.type),
 2349  
                         translate(clause.seqExpr)));
 2350  171
                 stmt = make.at(clause).ForeachLoop(
 2351  
                     // loop variable is synthetic should not be bound
 2352  
                     // even if we are in a bind context
 2353  
                     make.VarDef(
 2354  
                         make.Modifiers(0L), 
 2355  
                         tmpVarName, 
 2356  
                         makeTypeTree( var,var.type, true), 
 2357  
                         null),
 2358  
                     seq,
 2359  
                     stmt);
 2360  171
             } else {
 2361  
                 // The "sequence" isn't a Sequence.
 2362  
                 // Compile: { var tmp = seq; if (tmp!=null) stmt; }
 2363  4
                 if (! var.type.isPrimitive())
 2364  3
                     stmt = make.If(make.Binary(JCTree.NE, make.Ident(tmpVarName),
 2365  
                                 make.Literal(TypeTags.BOT, null)),
 2366  
                             stmt, null);
 2367  4
                 stmt = make.at(diagPos).Block(0,
 2368  
                     List.of(make.at(diagPos).VarDef(
 2369  
                         make.Modifiers(0L), 
 2370  
                         tmpVarName, 
 2371  
                         makeTypeTree( var,var.type, true), 
 2372  
                         translate(clause.seqExpr)),
 2373  
                         stmt));
 2374  
             }
 2375  175
             if (clause.getIndexUsed()) {
 2376  20
                 JCVariableDecl tmpIndexVar =
 2377  
                         make.VarDef(
 2378  
                         make.Modifiers(0L), 
 2379  
                         tmpIndexVarName, 
 2380  
                         makeTypeTree( var,syms.javafx_IntegerType), 
 2381  
                         make.Literal(Integer.valueOf(0)));
 2382  20
                 stmt = make.Block(0L, List.of(tmpIndexVar, stmt));
 2383  
             }
 2384  
         }
 2385  169
         return stmt;
 2386  
     }
 2387  
     
 2388  
     public void visitIndexof(JFXIndexof that) {
 2389  21
         result = make.at(that.pos()).Ident(indexVarName(that.clause));
 2390  21
     }
 2391  
 
 2392  
     @Override
 2393  
     public void visitConditional(JCConditional tree) {
 2394  448
         final DiagnosticPosition diagPos = tree.pos();
 2395  448
         JCExpression cond = translate(tree.getCondition());
 2396  448
         JCExpression trueSide = tree.getTrueExpression();
 2397  448
         JCExpression falseSide = tree.getFalseExpression();
 2398  448
         if (yield == Yield.ToExpression) {
 2399  
             JCExpression translatedFalseSide;
 2400  63
             if (falseSide == null) {
 2401  0
                 Type trueSideType = tree.getTrueExpression().type;
 2402  0
                 switch (trueSideType.tag) {
 2403  
                     case TypeTags.BOOLEAN:
 2404  0
                         translatedFalseSide = make.at(diagPos).Literal(TypeTags.BOOLEAN, 0);
 2405  0
                         break;
 2406  
                     case TypeTags.INT:
 2407  0
                         translatedFalseSide = make.at(diagPos).Literal(TypeTags.INT, 0);
 2408  0
                         break;
 2409  
                     case TypeTags.DOUBLE:
 2410  0
                         translatedFalseSide = make.at(diagPos).Literal(TypeTags.DOUBLE, 0.0);
 2411  0
                         break;
 2412  
                     case TypeTags.BOT:
 2413  0
                         translatedFalseSide = make.at(diagPos).Literal(TypeTags.BOT, null);
 2414  0
                         break;
 2415  
                     case TypeTags.VOID:
 2416  0
                         assert false : "should have been translated";
 2417  0
                         translatedFalseSide = make.at(diagPos).Literal(TypeTags.BOT, null);
 2418  0
                         break;
 2419  
                     case TypeTags.CLASS:
 2420  0
                         if (trueSideType == syms.stringType) {
 2421  0
                             translatedFalseSide = make.at(diagPos).Literal(TypeTags.CLASS, "");
 2422  
                         } else {
 2423  0
                             translatedFalseSide = make.at(diagPos).Literal(TypeTags.BOT, null);
 2424  
                         }
 2425  0
                         break;
 2426  
                     default:
 2427  0
                         assert false : "what is this type doing here? " + trueSideType;
 2428  0
                         translatedFalseSide = make.at(diagPos).Literal(TypeTags.BOT, null);
 2429  
                         break;
 2430  
                 }
 2431  0
             } else {
 2432  63
                 translatedFalseSide = translate(falseSide);
 2433  
             }
 2434  63
             JCExpression translatedTrueSide = convertTranslated(translate(trueSide), trueSide, trueSide.type, tree.type);
 2435  63
             translatedFalseSide = convertTranslated(translatedFalseSide, falseSide, falseSide.type, tree.type);
 2436  63
             result = make.at(diagPos).Conditional(cond, translatedTrueSide, translatedFalseSide);
 2437  63
         } else {
 2438  385
             result = make.at(diagPos).If(cond, 
 2439  
                     translateExpressionToStatement(trueSide), 
 2440  
                     falseSide == null ? null : translateExpressionToStatement(falseSide));
 2441  
         }
 2442  448
     }
 2443  
 
 2444  
     @Override
 2445  
     public void visitContinue(JCContinue tree) {
 2446  3
         result = make.at(tree.pos).Continue(tree.label);
 2447  3
     }
 2448  
 
 2449  
     @Override
 2450  
     public void visitDoLoop(JCDoWhileLoop tree) {
 2451  0
         assert false : "should not be in JavaFX AST";
 2452  0
     }
 2453  
 
 2454  
     @Override
 2455  
     public void visitErroneous(JCErroneous tree) {
 2456  0
         List<? extends JCTree> errs = translate(tree.errs);
 2457  0
         result = make.at(tree.pos).Erroneous(errs);
 2458  0
     }
 2459  
    
 2460  
     @Override
 2461  
     public void visitReturn(JCReturn tree) {
 2462  10
         JCExpression exp = tree.getExpression();
 2463  10
         if (exp == null) {
 2464  1
             result = make.at(tree).Return(null);
 2465  
         } else {
 2466  9
             result = translateExpressionToStatement(exp, tree.type);
 2467  
         }
 2468  10
     }
 2469  
 
 2470  
     @Override
 2471  
     public void visitExec(JCExpressionStatement tree) {
 2472  3066
         result = translateExpressionToStatement(tree.getExpression(), syms.voidType);
 2473  3066
     }
 2474  
 
 2475  
     @Override
 2476  
     public void visitParens(JCParens tree) {
 2477  0
         if (yield == Yield.ToExpression) {
 2478  0
             JCExpression expr = translate(tree.expr);
 2479  0
             result = make.at(tree.pos).Parens(expr);
 2480  0
         } else {
 2481  0
             result = translateExpressionToStatement(tree.expr);
 2482  
         }
 2483  0
     }
 2484  
 
 2485  
     @Override
 2486  
     public void visitForeachLoop(JCEnhancedForLoop tree) {
 2487  0
         assert false : "should not be in JavaFX AST";
 2488  0
     }
 2489  
 
 2490  
     @Override
 2491  
     public void visitForLoop(JCForLoop tree) {
 2492  0
         assert false : "should not be in JavaFX AST";
 2493  0
     }
 2494  
 
 2495  
     @Override
 2496  
     public void visitIf(JCIf tree) {
 2497  0
         assert false : "should not be in JavaFX AST";
 2498  0
     }
 2499  
 
 2500  
     @Override
 2501  
     public void visitImport(JCImport tree) {
 2502  0
         JCTree qualid = translate(tree.qualid);
 2503  0
         result = make.at(tree.pos).Import(qualid, tree.staticImport);
 2504  0
     }
 2505  
 
 2506  
     @Override
 2507  
     public void visitIndexed(JCArrayAccess tree) {
 2508  0
         assert false : "should not be in JavaFX AST";
 2509  0
     }
 2510  
 
 2511  
     @Override
 2512  
     public void visitTypeTest(JCInstanceOf tree) {
 2513  30
         JCTree clazz = this.makeTypeTree( tree,tree.clazz.type);
 2514  30
         JCExpression expr = translate(tree.expr);
 2515  30
         if (types.isSequence(tree.expr.type) && ! types.isSequence(tree.clazz.type))
 2516  2
             expr = callExpression(tree.expr,
 2517  
                     makeQualifiedTree(tree.expr, "com.sun.javafx.runtime.sequence.Sequences"),
 2518  
                     "getSingleValue", expr);
 2519  30
         result = make.at(tree.pos).TypeTest(expr, clazz);
 2520  30
     }
 2521  
 
 2522  0
     abstract static class TypeCastTranslator extends Translator {
 2523  
 
 2524  
         protected final JCTypeCast tree;
 2525  
 
 2526  
         TypeCastTranslator(final JCTypeCast tree, JavafxToJava toJava) {
 2527  121
             super(tree.pos(), toJava);
 2528  121
             this.tree = tree;
 2529  121
         }
 2530  
         
 2531  
         abstract protected JCExpression translatedExpr();
 2532  
 
 2533  
         protected JCExpression doit() {
 2534  121
             Type clazztype = tree.clazz.type;
 2535  121
             if (clazztype.isPrimitive() && !tree.expr.type.isPrimitive()) {
 2536  11
                 clazztype = types.boxedClass(clazztype).type;
 2537  
             }
 2538  121
             JCTree clazz = makeExpression(clazztype);
 2539  121
             return m().TypeCast(clazz, translatedExpr());
 2540  
         }
 2541  
     }
 2542  
     
 2543  
     @Override
 2544  
     public void visitTypeCast(final JCTypeCast tree) {
 2545  115
         result = new TypeCastTranslator(tree, this) {
 2546  
             protected JCExpression translatedExpr() {
 2547  115
                 return translate(tree.expr);
 2548  
             }
 2549  
         }.doit();
 2550  115
     }
 2551  
     
 2552  
     @Override
 2553  
     public void visitLabelled(JCLabeledStatement tree) {
 2554  0
         assert false : "should not be in JavaFX AST";
 2555  0
     }
 2556  
 
 2557  
     @Override
 2558  
     public void visitLiteral(JCLiteral tree) {
 2559  4900
         if (tree.typetag == TypeTags.BOT && types.isSequence(tree.type)) {
 2560  6
             Type elemType = elementType(tree.type);
 2561  6
             result = makeEmptySequenceCreator(tree.pos(), elemType);
 2562  6
         }
 2563  
         else
 2564  4894
             result = make.at(tree.pos).Literal(tree.typetag, tree.value);
 2565  4900
     }
 2566  
 
 2567  
     @Override
 2568  
     public void visitMethodDef(JCMethodDecl tree) {
 2569  0
          assert false : "should not be in JavaFX AST";
 2570  0
     }
 2571  
 
 2572  
     abstract static class FunctionCallTranslator extends Translator {
 2573  
 
 2574  
         protected final JCExpression meth;
 2575  
         protected final JCExpression selector;
 2576  
         protected final MethodSymbol msym;
 2577  
         protected final boolean renameToSuper;
 2578  
         protected final boolean superToStatic;
 2579  
         protected final List<Type> formals;
 2580  
         protected final boolean usesVarArgs;
 2581  
         protected final boolean useInvoke;
 2582  
         protected final boolean selectorMutable;
 2583  
         protected final boolean callBound;
 2584  
 
 2585  
         FunctionCallTranslator(final JCMethodInvocation tree, JavafxToJava toJava) {
 2586  3289
             super(tree.pos(), toJava);
 2587  3289
             meth = tree.meth;
 2588  3289
             JCFieldAccess fieldAccess = meth.getTag() == JavafxTag.SELECT ? (JCFieldAccess) meth : null;
 2589  3289
             selector = fieldAccess != null ? fieldAccess.getExpression() : null;
 2590  3289
             Symbol sym = toJava.expressionSymbol(meth);
 2591  3289
             msym = (sym instanceof MethodSymbol) ? (MethodSymbol) sym : null;
 2592  3289
             Name selectorIdName = (selector != null && selector.getTag() == JavafxTag.IDENT) ? ((JCIdent) selector).getName() : null;
 2593  3289
             boolean thisCall = selectorIdName == toJava.names._this;
 2594  3289
             boolean superCall = selectorIdName == toJava.names._super;
 2595  3289
             ClassSymbol csym = toJava.attrEnv.enclClass.sym;
 2596  
             
 2597  3289
             boolean namedSuperCall =
 2598  
                     selector != null && msym != null && !msym.isStatic() &&
 2599  
                     toJava.expressionSymbol(selector) instanceof ClassSymbol &&
 2600  
                     // FIXME should also allow other enclosing classes:
 2601  
                     types.isSuperType(toJava.expressionSymbol(selector).type, csym);
 2602  3289
             renameToSuper = namedSuperCall && !types.isCompoundClass(csym);
 2603  3289
             superToStatic = (superCall || namedSuperCall) && !renameToSuper;
 2604  3289
             formals = meth.type.getParameterTypes();
 2605  
             //TODO: probably move this local to the arg processing
 2606  3289
             usesVarArgs = tree.args != null && msym != null &&
 2607  
                             (msym.flags() & VARARGS) != 0 &&
 2608  
                             (formals.size() != tree.args.size() ||
 2609  
                              types.isConvertible(tree.args.last().type,
 2610  
                                  types.elemtype(formals.last())));
 2611  
 
 2612  3289
             useInvoke = meth.type instanceof FunctionType;
 2613  3289
             selectorMutable = msym != null &&
 2614  
                     !sym.isStatic() && selector != null && !superCall && !namedSuperCall &&
 2615  
                     !thisCall && !renameToSuper;
 2616  3289
             callBound = msym != null && !useInvoke && 
 2617  
                   ((msym.flags() & JavafxFlags.BOUND) != 0);
 2618  3289
         }
 2619  
     }
 2620  
 
 2621  
     // fix me: there must be a better way...
 2622  
     private boolean isJavaLangObjectType(Type type) {
 2623  0
         return type.toString().equals("java.lang.Object");
 2624  
     }
 2625  
 
 2626  
 
 2627  
     @Override
 2628  
     public void visitApply(final JCMethodInvocation tree) {
 2629  3191
         result = (new FunctionCallTranslator( tree, this ) {
 2630  
 
 2631  3191
             private final boolean hasSideEffects = selectorMutable && hasSideEffects(selector);
 2632  
 
 2633  
             public JCTree doit() {
 2634  3191
                 JCVariableDecl selectorVar = null;
 2635  
                 JCExpression transMeth;
 2636  3191
                 if (renameToSuper) {
 2637  2
                     transMeth = make.at(selector).Select(make.Select(makeTypeTree( selector,currentClass.sym.type, false), names._super), msym);
 2638  
                 } else {
 2639  3189
                     transMeth = translate(meth);
 2640  3189
                     if (hasSideEffects && !selector.type.isPrimitive() && transMeth.getTag() == JavafxTag.SELECT) {
 2641  
                         // still a select and presumed to still have side effects -- hold the selector in a temp var
 2642  41
                         JCFieldAccess transMethFA = (JCFieldAccess) transMeth;
 2643  41
                         selectorVar = makeTmpVar(diagPos, "select", selector.type, transMethFA.getExpression());
 2644  41
                         transMeth = m().Select(m().Ident(selectorVar.name), transMethFA.name);
 2645  
                     }  
 2646  
                 }
 2647  
 
 2648  
                 // translate the method name -- e.g., foo  to foo$bound or foo$impl
 2649  
                 //TODO: this is a paranoid cloning of the below -- integrate this
 2650  3191
                 if (superToStatic) {
 2651  11
                     Name name = functionName(msym, superToStatic, callBound);
 2652  11
                     if (transMeth.getTag() == JavafxTag.IDENT) {
 2653  0
                         transMeth = m().Ident(name);
 2654  11
                     } else if (transMeth.getTag() == JavafxTag.SELECT) {
 2655  11
                         transMeth = m().Select(makeTypeTree(diagPos, msym.owner.type, false), name);
 2656  
                     }
 2657  11
                 } else 
 2658  3180
                 if (callBound && ! renameToSuper) {
 2659  19
                     Name name = functionName(msym, superToStatic, callBound);
 2660  19
                     if (transMeth.getTag() == JavafxTag.IDENT) {
 2661  0
                         transMeth = m().Ident(name);
 2662  19
                     } else if (transMeth.getTag() == JavafxTag.SELECT) {
 2663  19
                         JCFieldAccess faccess = (JCFieldAccess) transMeth;
 2664  19
                         transMeth = m().Select(faccess.getExpression(), name);
 2665  
                     }
 2666  
                 }
 2667  3191
                 if (useInvoke) {
 2668  40
                     transMeth = make.Select(transMeth, defs.invokeName);
 2669  
                 }
 2670  
 
 2671  3191
                 JCMethodInvocation app = m().Apply( translate(tree.typeargs), transMeth, determineArgs());
 2672  3191
                 JCExpression fresult = app;
 2673  3191
                 if (callBound) {
 2674  19
                     fresult = makeBoundCall(app);
 2675  
                 }
 2676  3191
                 if (useInvoke) {
 2677  40
                     if (tree.type.tag != TypeTags.VOID) {
 2678  26
                         fresult = castFromObject(fresult, tree.type);
 2679  
                     }
 2680  
                 }
 2681  
                 // If we are to yield a Location, and this isn't going to happen as
 2682  
                 // a return of using a bound call (for example, if this is a Java call)
 2683  
                 // then convert into a Location
 2684  3191
                 if (wrap == Wrapped.InLocation && !callBound && msym != null) {
 2685  0
                     TypeMorphInfo returnTypeInfo = typeMorpher.typeMorphInfo(msym.getReturnType());
 2686  0
                     fresult = makeUnboundLocation(diagPos, returnTypeInfo, fresult);
 2687  
                 }
 2688  3191
                 if (selectorMutable && !selector.type.isPrimitive()) {  // if mutable (and not primitive), we need to test for null
 2689  2113
                     JCExpression toTest = hasSideEffects? 
 2690  
                                              m().Ident(selectorVar.name) :
 2691  
                                              translate(selector);
 2692  
                     // we have a testable guard for null, test before the invoke (boxed conversions don't need a test)
 2693  2113
                     JCExpression cond = m().Binary(JCTree.NE, toTest, make.Literal(TypeTags.BOT, null));
 2694  2113
                     if (msym.getReturnType() == syms.voidType) {
 2695  
                         // if this is a void expression, check it with an If-statement
 2696  1750
                         JCStatement stmt = make.If(cond, make.Exec(fresult), null);
 2697  1750
                         assert yield == Yield.ToExecStatement : "Yield from a void call should always be a statement";
 2698  
                         // a statement is the desired result of the translation, return the If-statement
 2699  1750
                         if (hasSideEffects) {
 2700  
                             // if the selector has side-effects, we created a temp var to hold it
 2701  
                             // so we need to make a block to include the temp var
 2702  7
                             return m().Block(0L, List.<JCStatement>of(selectorVar, stmt));
 2703  
                         } else {
 2704  1743
                             return stmt;
 2705  
                         }
 2706  
                     } else {
 2707  
                         // it has a non-void return type, convert it to a conditional expression
 2708  
                         // if it would dereference null, then instead give the default value
 2709  363
                         TypeMorphInfo returnTypeInfo = typeMorpher.typeMorphInfo(msym.getReturnType());
 2710  363
                         JCExpression defaultExpr = makeDefaultValue(diagPos, returnTypeInfo);
 2711  363
                         if (wrap == Wrapped.InLocation) {
 2712  0
                             defaultExpr = makeUnboundLocation(diagPos, returnTypeInfo, defaultExpr);
 2713  
                         }
 2714  363
                         fresult =  m().Conditional(cond, fresult, defaultExpr);
 2715  363
                         if (hasSideEffects) {
 2716  
                             // if the selector has side-effects, we created a temp var to hold it
 2717  
                             // so we need to make a block-expression to include the temp var
 2718  34
                             fresult = fxmake.at(diagPos).BlockExpression(0L, List.<JCStatement>of(selectorVar), fresult);
 2719  
                         }
 2720  
                     }
 2721  
                 }
 2722  1441
                 return fresult;
 2723  
             }
 2724  
 
 2725  
             // compute the translated arguments.
 2726  
             // if this is a bound call, use left-hand side references for arguments consisting
 2727  
             // solely of a  var or attribute reference, or function call, otherwise, wrap it
 2728  
             // in an expression location
 2729  
             List<JCExpression> determineArgs() {
 2730  
                 List<JCExpression> args;
 2731  3191
                 if (callBound) {
 2732  19
                     ListBuffer<JCExpression> targs = ListBuffer.lb();
 2733  19
                     List<Type> formal = formals;
 2734  19
                     for (JCExpression arg : tree.args) {
 2735  0
                         switch (arg.getTag()) {
 2736  
                             case JavafxTag.IDENT:
 2737  
                             case JavafxTag.SELECT:
 2738  
                             case JavafxTag.APPLY:
 2739  
                                 // This arg expression is one that will translate into a Location;
 2740  
                                 // since that is needed for a this into Location, do so.
 2741  
                                 // However, if the types need to by changed (subclass), this won't
 2742  
                                 // directly work.
 2743  
                                 // Also, if this is a mismatched sequence type, we will need
 2744  
                                 // to do some different
 2745  
                                 //TODO: never actually gets here
 2746  0
                                 if (arg.type.equals(formal.head) || 
 2747  
                                     types.isSequence(formal.head) ||
 2748  
                                     isJavaLangObjectType(formal.head) // don't add conversion for parameter type of java.lang.Object: doing so breaks the Pointer trick to obtain the original location (JFC-826)
 2749  
                                     ) {
 2750  0
                                     targs.append(translate(arg, Wrapped.InLocation));
 2751  0
                                     break;
 2752  
                                 }
 2753  
                                 //TODO: handle sequence subclasses
 2754  
                                 //TODO: use more efficient mechanism (use currently apears rare)
 2755  
                                 //System.err.println("Not match: " + arg.type + " vs " + formal.head);
 2756  
                                 // Otherwise, fall-through, presumably a conversion will work.
 2757  
                             default:
 2758  
                             {
 2759  0
                                 targs.append(makeUnboundLocation(
 2760  
                                         arg.pos(),
 2761  
                                         typeMorpher.typeMorphInfo(formal.head),
 2762  
                                         translate(arg, arg.type)));
 2763  
                             }
 2764  
                         }
 2765  0
                         formal = formal.tail;
 2766  
                     }
 2767  19
                     args = targs.toList();
 2768  19
                 } else {
 2769  3172
                     ListBuffer<JCExpression> translated = ListBuffer.lb();
 2770  3172
                     boolean handlingVarargs = false;
 2771  3172
                     Type formal = null;
 2772  3172
                     List<Type> t = formals;
 2773  6645
                     for (List<JCExpression> l = tree.args; l.nonEmpty();  l = l.tail) {
 2774  3473
                         if (! handlingVarargs) {
 2775  3470
                             formal = t.head;
 2776  3470
                             t = t.tail;
 2777  3470
                             if (usesVarArgs && t.isEmpty()) {
 2778  1
                                 formal = types.elemtype(formal);
 2779  1
                                 handlingVarargs = true;
 2780  
                             }
 2781  
                         }
 2782  3473
                         translated.append( translate(l.head, formal) );
 2783  
                     }
 2784  3172
                     args = translated.toList();
 2785  
                 }
 2786  
 
 2787  
                // if this is a super.foo(x) call, "super" will be translated to referenced class,
 2788  
                 // so we add a receiver arg to make a direct call to the implementing method  MyClass.foo(receiver$, x)
 2789  3191
                 if (superToStatic) {
 2790  11
                     args = args.prepend(make.Ident(defs.receiverName));
 2791  
                 }
 2792  
 
 2793  3191
                 return args;
 2794  
             }
 2795  
 
 2796  
             // This is for calls from non-bound contexts (code for true bound calls is in JavafxToBound)
 2797  
             JCExpression makeBoundCall(JCExpression applyExpression) {
 2798  19
                 JavafxTypeMorpher.TypeMorphInfo tmi = typeMorpher.typeMorphInfo(msym.getReturnType());
 2799  19
                 return wrap == Wrapped.InLocation ? applyExpression : callExpression(diagPos,
 2800  
                         m().Parens(applyExpression),
 2801  
                         defs.locationGetMethodName[tmi.getTypeKind()]);
 2802  
             }
 2803  
 
 2804  
         }).doit();
 2805  3191
     }
 2806  
 
 2807  
     @Override
 2808  
     public void visitModifiers(JCModifiers tree) {
 2809  0
         List<JCAnnotation> annotations = translate(tree.annotations);
 2810  0
         result = make.at(tree.pos).Modifiers(tree.flags, annotations);
 2811  0
     }
 2812  
 
 2813  
     @Override
 2814  
     public void visitNewArray(JCNewArray tree) {
 2815  0
         assert false : "should not be in JavaFX AST";
 2816  0
     }
 2817  
 
 2818  
     @Override
 2819  
     public void visitNewClass(JCNewClass tree) {
 2820  0
         assert false : "should not be in JavaFX AST";
 2821  0
     }
 2822  
 
 2823  
     @Override
 2824  
     public void visitSkip(JCSkip tree) {
 2825  0
         result = make.at(tree.pos).Skip();
 2826  0
     }
 2827  
 
 2828  
     @Override
 2829  
     public void visitSwitch(JCSwitch tree) {
 2830  0
         assert false : "should not be in JavaFX AST";
 2831  0
     }
 2832  
 
 2833  
     @Override
 2834  
     public void visitSynchronized(JCSynchronized tree) {
 2835  0
         assert false : "should not be in JavaFX AST";
 2836  0
     }
 2837  
 
 2838  
     @Override
 2839  
     public void visitThrow(JCThrow tree) {
 2840  24
         JCTree expr = translate(tree.expr);
 2841  24
         result = make.at(tree.pos).Throw(expr);
 2842  24
     }
 2843  
 
 2844  
     @Override
 2845  
     public void visitTry(JCTry tree) {
 2846  24
         JCBlock body = translate(tree.body);
 2847  24
         List<JCCatch> catchers = translate(tree.catchers);
 2848  24
         JCBlock finalizer = translate(tree.finalizer);
 2849  24
         result = make.at(tree.pos).Try(body, catchers, finalizer);
 2850  24
     }
 2851  
 
 2852  
     @Override
 2853  
     public void visitTypeApply(JCTypeApply tree) {
 2854  0
         JCExpression clazz = translate(tree.clazz);
 2855  0
         List<JCExpression> arguments = translate(tree.arguments);
 2856  0
         result = make.at(tree.pos).TypeApply(clazz, arguments);
 2857  0
     }
 2858  
 
 2859  
     @Override
 2860  
     public void visitTypeArray(JCArrayTypeTree tree) {
 2861  0
         assert false : "should not be in JavaFX AST";
 2862  0
     }
 2863  
 
 2864  
     @Override
 2865  
     public void visitTypeBoundKind(TypeBoundKind tree) {
 2866  0
         assert false : "should not be in JavaFX AST";
 2867  0
     }
 2868  
 
 2869  
     @Override
 2870  
     public void visitTypeIdent(JCPrimitiveTypeTree tree) {
 2871  0
         result = make.at(tree.pos).TypeIdent(tree.typetag);
 2872  0
     }
 2873  
 
 2874  
     @Override
 2875  
     public void visitTypeParameter(JCTypeParameter tree) {
 2876  0
         List<JCExpression> bounds = translate(tree.bounds);
 2877  0
         result = make.at(tree.pos).TypeParameter(tree.name, bounds);
 2878  0
     }
 2879  
 
 2880  
     @Override
 2881  
     public void visitUnary(final JCUnary tree) {
 2882  696
         result = (new Translator( tree.pos(), this ) {
 2883  
 
 2884  696
             private final JCExpression expr = tree.getExpression();
 2885  696
             private final JCExpression transExpr = translate(expr);
 2886  
 
 2887  
             private JCExpression doVanilla() {
 2888  209
                 return m().Unary(tree.getTag(), transExpr);
 2889  
             }
 2890  
             
 2891  
             private JCExpression callSetMethod(JCExpression target, List<JCExpression> args) {
 2892  219
                 JCExpression transTarget = translate(target, Wrapped.InLocation); // must be Location
 2893  219
                 JCFieldAccess setSelect = m().Select(transTarget,
 2894  
                                                       args.size() == 1
 2895  
                                                               ? defs.locationSetMethodName[typeMorpher.typeMorphInfo(target.type).getTypeKind()]
 2896  
                                                               : defs.setMethodName);
 2897  219
                 return m().Apply(null, setSelect, args);
 2898  
             }
 2899  
 
 2900  
             private JCExpression doIncDec(int binaryOp, boolean postfix) {
 2901  254
                 final Symbol sym = expressionSymbol(expr);
 2902  254
                 final VarSymbol vsym = (sym != null && (sym instanceof VarSymbol)) ? (VarSymbol) sym : null;
 2903  254
                 final JCExpression one = m().Literal(1);
 2904  254
                 final JCExpression combined = m().Binary(binaryOp, transExpr, one);
 2905  
                 JCExpression ret;
 2906  
 
 2907  254
                 if (expr.getTag() == JavafxTag.SEQUENCE_INDEXED) {
 2908  
                     // assignment of a sequence element --  s[i]+=8, call the sequence set method
 2909  4
                     JFXSequenceIndexed si = (JFXSequenceIndexed) expr;
 2910  4
                     JCExpression index = translate(si.getIndex());
 2911  4
                     ret = callSetMethod( si.getSequence(), List.of(index, combined) );
 2912  4
                 } else if (shouldMorph(vsym)) {
 2913  
                     // we are setting a var Location, call the set method
 2914  215
                     ret = callSetMethod( expr, List.of(combined) );
 2915  
                 } else {
 2916  
                     // We are setting a "normal" non-Location non-sequence-access, use normal operator
 2917  35
                     return doVanilla();
 2918  
                 }
 2919  219
                 if (postfix) {
 2920  
                     // this is a postfix operation, undo the value (not the variable) change
 2921  212
                     return m().Binary(binaryOp, ret, m().Literal(-1));
 2922  
                 } else {
 2923  
                     // prefix operation
 2924  7
                     return ret;
 2925  
                 }
 2926  
             }
 2927  
 
 2928  
             public JCTree doit() {
 2929  696
                 switch (tree.getTag()) {
 2930  
                     case JavafxTag.SIZEOF:
 2931  201
                         return callExpression(diagPos, 
 2932  
                                 makeQualifiedTree(diagPos, "com.sun.javafx.runtime.sequence.Sequences"), 
 2933  
                                 defs.sizeMethodName, transExpr);
 2934  
                     case JavafxTag.REVERSE:
 2935  67
                         return callExpression(diagPos, 
 2936  
                                 makeQualifiedTree(diagPos, "com.sun.javafx.runtime.sequence.Sequences"), 
 2937  
                                 "reverse", transExpr);
 2938  
                     case JCTree.PREINC:
 2939  10
                         return doIncDec(JCTree.PLUS, false);
 2940  
                     case JCTree.PREDEC:
 2941  4
                         return doIncDec(JCTree.MINUS, false);
 2942  
                     case JCTree.POSTINC:
 2943  234
                         return doIncDec(JCTree.PLUS, true);
 2944  
                     case JCTree.POSTDEC:
 2945  6
                         return doIncDec(JCTree.MINUS, true);
 2946  
                     case JCTree.NEG:
 2947  140
                         if (types.isSameType(tree.type, syms.javafx_DurationType)) {
 2948  0
                             return m().Apply(null,
 2949  
                                                           m().Select(translate(tree.arg), Name.fromString(names, "negate")), List.<JCExpression>nil());
 2950  
                         }
 2951  
                     default:
 2952  174
                         return doVanilla();
 2953  
                 }
 2954  
             }
 2955  
         }).doit();
 2956  696
     }
 2957  
   
 2958  
 
 2959  
     @Override
 2960  
     public void visitVarDef(JCVariableDecl tree) {
 2961  0
         assert false : "should not be in JavaFX AST";
 2962  0
     }
 2963  
 
 2964  
     @Override
 2965  
     public void visitWhileLoop(JCWhileLoop tree) {
 2966  11
         JCStatement body = translate(tree.body);
 2967  11
         JCExpression cond = translate(tree.cond);
 2968  11
         result = make.at(tree.pos).WhileLoop(cond, body);
 2969  11
     }
 2970  
 
 2971  
     @Override
 2972  
     public void visitWildcard(JCWildcard tree) {
 2973  0
         TypeBoundKind kind = make.at(tree.kind.pos).TypeBoundKind(tree.kind.kind);
 2974  0
         JCTree inner = translate(tree.inner);
 2975  0
         result = make.at(tree.pos).Wildcard(kind, inner);
 2976  0
     }
 2977  
 
 2978  
     @Override
 2979  
     public void visitLetExpr(LetExpr tree) {
 2980  0
         assert false : "should not be in JavaFX AST";
 2981  0
     }
 2982  
 
 2983  
     @Override
 2984  
     public void visitTree(JCTree tree) {
 2985  0
         assert false : "should not be in JavaFX AST";
 2986  0
     }
 2987  
     
 2988  
     /******** goofy visitors, most of which should go away ******/
 2989  
 
 2990  
     public void visitSetAttributeToObjectBeingInitialized(JFXSetAttributeToObjectBeingInitialized that) {
 2991  0
         assert false : "yeah, right";
 2992  0
     }
 2993  
 
 2994  
     public void visitObjectLiteralPart(JFXObjectLiteralPart that) {
 2995  0
         assert false : "should be processed by parent tree";
 2996  0
     }  
 2997  
     
 2998  
     public void visitTypeAny(JFXTypeAny that) {
 2999  0
         assert false : "should be processed by parent tree";
 3000  0
     }
 3001  
     
 3002  
     public void visitTypeClass(JFXTypeClass that) {
 3003  0
         assert false : "should be processed by parent tree";
 3004  0
     }
 3005  
     
 3006  
     public void visitTypeFunctional(JFXTypeFunctional that) {
 3007  0
         assert false : "should be processed by parent tree";
 3008  0
     }
 3009  
     
 3010  
     public void visitTypeUnknown(JFXTypeUnknown that) {
 3011  0
         assert false : "should be processed by parent tree";
 3012  0
     }
 3013  
 
 3014  
     public void visitForExpressionInClause(JFXForExpressionInClause that) {
 3015  0
         assert false : "should be processed by parent tree";
 3016  0
     }
 3017  
     
 3018  
     /***********************************************************************
 3019  
      *
 3020  
      * Utilities 
 3021  
      *
 3022  
      */
 3023  
     
 3024  
     private JCBlock runMethodBody(JFXBlockExpression bexpr) {
 3025  340
         DiagnosticPosition diagPos = bexpr.pos();
 3026  340
         List<JCStatement> stats = translateStatements(bexpr.stats);
 3027  340
         boolean nullReturnNeeded = true;
 3028  340
         if (bexpr.value != null) {
 3029  224
             Type valueType = bexpr.value.type;
 3030  224
             if (valueType == syms.voidType) {
 3031  
                 // convert the void typed expression to a statement, still return null
 3032  187
                 stats = stats.append( translateExpressionToStatement(bexpr.value, valueType) );
 3033  
             } else {
 3034  
                 // the returned value will be the trailing expression, box if needed
 3035  
                 //TODO: handle cases of single legged if, etc
 3036  37
                 if (valueType.isPrimitive()) {
 3037  10
                     JCExpression boxedExpr = makeBox(diagPos, translate(bexpr.value), valueType);
 3038  10
                     stats = stats.append( make.Return( boxedExpr ) );
 3039  10
                 } else {
 3040  27
                     stats = stats.append( translateExpressionToStatement(bexpr.value, valueType) );
 3041  
                 }
 3042  37
                 nullReturnNeeded = false;
 3043  
             }
 3044  
         }
 3045  340
         if (nullReturnNeeded) {
 3046  303
             stats = stats.append( make.Return(make.Literal(TypeTags.BOT, null)) );
 3047  
         }
 3048  340
         return make.at(diagPos).Block(0L, stats);
 3049  
     }
 3050  
     
 3051  
     protected String getSyntheticPrefix() {
 3052  1288
         return "jfx$";
 3053  
     }
 3054  
     
 3055  
     boolean shouldMorph(VarSymbol vsym) {
 3056  1152
         if (vsym == null) {
 3057  0
             return false;
 3058  
         }
 3059  1152
         VarMorphInfo vmi = typeMorpher.varMorphInfo(vsym);
 3060  1152
         return shouldMorph(vmi);
 3061  
     }
 3062  
     
 3063  
     boolean shouldMorph(VarMorphInfo vmi) {
 3064  18628
         if ( vmi.mustMorph() )
 3065  7541
             return true;
 3066  
         else
 3067  11087
             return locallyBound != null ? locallyBound.contains(vmi.getSymbol()) : false;
 3068  
     }   
 3069  
 
 3070  
     JCExpression convertVariableReference(DiagnosticPosition diagPos,
 3071  
                                                  JCExpression varRef, Symbol sym, 
 3072  
                                                  boolean wantLocation) {
 3073  
 
 3074  19089
         JCExpression expr = varRef;
 3075  
 
 3076  19089
         boolean staticReference = sym.isStatic();
 3077  19089
         if (sym instanceof VarSymbol) {
 3078  12038
              VarSymbol vsym = (VarSymbol) sym;
 3079  12038
             VarMorphInfo vmi = typeMorpher.varMorphInfo(vsym);
 3080  12038
             if (shouldMorph(vmi)) {
 3081  4601
                 if (sym.owner.kind == Kinds.TYP && !staticReference) {
 3082  
                     // this is a non-static reference to an attribute, use the get$ form
 3083  2209
                     assert varRef.getTag() == JCTree.SELECT : "attribute must be accessed through receiver";
 3084  2209
                     JCFieldAccess select = (JCFieldAccess) varRef;
 3085  2209
                     Name attrAccessName = names.fromString(attributeGetMethodNamePrefix + select.name.toString());
 3086  2209
                     select = make.at(diagPos).Select(select.getExpression(), attrAccessName);
 3087  2209
                     List<JCExpression> emptyArgs = List.nil();
 3088  2209
                     expr = make.at(diagPos).Apply(null, select, emptyArgs);
 3089  
                 }
 3090  
 
 3091  4601
                 if (wantLocation) {
 3092  
                     // already in correct form-- leave it
 3093  
                 } else {
 3094  
                     // non-bind context -- want v1.get()
 3095  2621
                     JCFieldAccess getSelect = make.Select(expr, defs.locationGetMethodName[vmi.getTypeKind()]);
 3096  2621
                     List<JCExpression> getArgs = List.nil();
 3097  2621
                     expr = make.at(diagPos).Apply(null, getSelect, getArgs);
 3098  2621
                 }
 3099  
             } else {
 3100  
                 // not morphed
 3101  7437
                 if (wantLocation) {
 3102  88
                     expr = makeUnboundLocation(diagPos, vmi, expr);
 3103  
                 }                
 3104  
             }
 3105  12038
         } else if (sym instanceof MethodSymbol) {
 3106  3210
             if (staticReference) {
 3107  785
                 Name name = functionName((MethodSymbol)sym);
 3108  785
                 if (expr.getTag() == JCTree.SELECT) {
 3109  785
                     JCFieldAccess select = (JCFieldAccess) expr;
 3110  785
                     expr = make.at(diagPos).Select(select.getExpression(), name);
 3111  785
                 } else if (expr.getTag() == JCTree.IDENT) {
 3112  0
                     expr = make.at(diagPos).Ident(name);
 3113  
                 }
 3114  
             }
 3115  
         }
 3116  19089
          return expr;
 3117  
     }
 3118  
 
 3119  
     /**
 3120  
      * Build the AST for accessing the outer member. 
 3121  
      * The accessors might be chained if the member accessed is more than one level up in the outer chain.
 3122  
      * */
 3123  
     private JCExpression makeReceiver(DiagnosticPosition pos, Symbol treeSym, Symbol siteOwner) {
 3124  1999
         JCExpression ret = null;
 3125  1999
         if (treeSym != null && siteOwner != null) {
 3126  
             
 3127  1999
             ret = make.Ident(defs.receiverName);
 3128  1999
             ret.type = siteOwner.type;
 3129  
             
 3130  
             // check if it is in the chain
 3131  1999
             if (siteOwner != treeSym.owner) {
 3132  204
                 Symbol siteCursor = siteOwner;
 3133  204
                 boolean foundOwner = false;
 3134  204
                 int numOfOuters = 0;
 3135  
                 ownerSearch:
 3136  256
                 while (siteCursor.kind != Kinds.PCK) {            
 3137  256
                     ListBuffer<Type> supertypes = ListBuffer.lb();
 3138  256
                     Set<Type> superSet = new HashSet<Type>();
 3139  256
                     if (siteCursor.type != null) {
 3140  230
                         supertypes.append(siteCursor.type);
 3141  230
                         superSet.add(siteCursor.type);
 3142  
                     }
 3143  
 
 3144  256
                     if (siteCursor.kind == Kinds.TYP) {
 3145  230
                         types.getSupertypes(siteCursor, supertypes, superSet);
 3146  
                     }
 3147  
 
 3148  256
                     for (Type supType : supertypes) {
 3149  586
                         if (types.isSameType(supType, treeSym.owner.type)) {
 3150  204
                             foundOwner = true;
 3151  204
                             break ownerSearch;
 3152  
                         }
 3153  
                     }
 3154  
 
 3155  52
                     if (siteCursor.kind == Kinds.TYP) {
 3156  26
                         numOfOuters++;
 3157  
                     }
 3158  
                     
 3159  52
                     siteCursor = siteCursor.owner;
 3160  52
                 }
 3161  
 
 3162  204
                 if (foundOwner) {
 3163  
                     // site was found up the outer class chain, add the chaining accessors
 3164  204
                     siteCursor = siteOwner;
 3165  230
                     while (numOfOuters > 0) {
 3166  26
                         if (siteCursor.kind == Kinds.TYP) {
 3167  26
                             ret = callExpression(pos, ret, initBuilder.outerAccessorName);
 3168  26
                             ret.type = siteCursor.type;
 3169  
                         }
 3170  
                         
 3171  26
                         if (siteCursor.kind == Kinds.TYP) {
 3172  26
                             numOfOuters--;
 3173  
                         }
 3174  26
                         siteCursor = siteCursor.owner;
 3175  
                     }
 3176  
                 }
 3177  
             }
 3178  
         }
 3179  1999
         return ret;
 3180  
     }
 3181  
 
 3182  
     private void fillClassesWithOuters(JCCompilationUnit tree) {
 3183  340
         class FillClassesWithOuters extends JavafxTreeScanner {
 3184  
             JFXClassDeclaration currentClass;
 3185  
             
 3186  
             @Override
 3187  
             public void visitClassDeclaration(JFXClassDeclaration tree) {
 3188  613
                 JFXClassDeclaration prevClass = currentClass;
 3189  
                 try {
 3190  613
                     currentClass = tree;
 3191  613
                     super.visitClassDeclaration(tree);
 3192  
                 }
 3193  
                 finally {
 3194  613
                     currentClass = prevClass;
 3195  613
                 }
 3196  613
             }
 3197  
             
 3198  
             @Override
 3199  
             public void visitIdent(JCIdent tree) {
 3200  10879
                 super.visitIdent(tree);
 3201  10879
                 if (currentClass != null && tree.sym.kind != Kinds.TYP) {
 3202  7926
                     addOutersForOuterAccess(tree.sym, currentClass.sym);
 3203  
                 }
 3204  10879
             }
 3205  
             
 3206  
             @Override // Need this because JavafxTreeScanner is not visiting the args of the JFXInstanciate tree. Starting to visit them generate tons of errors.
 3207  
             public void visitInstanciate(JFXInstanciate tree) {
 3208  632
                 super.visitInstanciate(tree);
 3209  632
                 super.scan(tree.getArgs());
 3210  632
             }
 3211  
 
 3212  
             private void addOutersForOuterAccess(Symbol sym, Symbol currentClass) {
 3213  7926
                 if (sym != null && sym.owner != null && sym.owner.type != null
 3214  
                         && !sym.isStatic() && currentClass != null) {
 3215  5357
                     Symbol outerSym = currentClass;
 3216  5357
                     ListBuffer<ClassSymbol> potentialOuters = new ListBuffer<ClassSymbol>();
 3217  5357
                     boolean foundOuterOwner = false;
 3218  16119
                     while (outerSym != null) {
 3219  12656
                         if (outerSym.kind == Kinds.TYP) {
 3220  5497
                             ClassSymbol outerCSym = (ClassSymbol) outerSym;
 3221  5497
                             if (types.isSuperType(sym.owner.type, outerCSym)) {
 3222  1797
                                 foundOuterOwner = true;
 3223  1797
                                 break;
 3224  
                              }
 3225  3700
                             potentialOuters.append(outerCSym);
 3226  3700
                         }
 3227  7159
                         else if (sym.owner == outerSym)
 3228  97
                             break;
 3229  10762
                         outerSym = outerSym.owner;
 3230  
                     }
 3231  
                     
 3232  5357
                     if (foundOuterOwner) {
 3233  1797
                         for (ClassSymbol cs : potentialOuters) {
 3234  26
                             hasOuters.add(cs);
 3235  
                         }
 3236  
                     }
 3237  
                 }
 3238  7926
             }
 3239  
         }
 3240  
         
 3241  340
         new FillClassesWithOuters().scan(tree);
 3242  340
     }
 3243  
 
 3244  
     public void visitTimeLiteral(JFXTimeLiteral tree) {
 3245  
         // convert time literal to a javafx.lang.Duration object literal
 3246  22
         JCFieldAccess clsname = (JCFieldAccess) fxmake.at(tree.pos()).Type(syms.javafx_DurationType);
 3247  22
         clsname.sym = syms.javafx_DurationType.tsym;
 3248  22
         Name attribute = names.fromString("millis");
 3249  22
         Symbol symMillis = syms.javafx_DurationType.tsym.members().lookup(attribute).sym;
 3250  22
         JFXObjectLiteralPart objLiteral = fxmake.at(tree.pos()).ObjectLiteralPart(attribute, tree.value, JavafxBindStatus.UNBOUND);
 3251  22
         objLiteral.sym = symMillis;
 3252  22
         JFXInstanciate inst = fxmake.at(tree.pos).Instanciate(clsname, null, List.of((JCTree)objLiteral));
 3253  22
         inst.type = clsname.type;
 3254  
         
 3255  
         // now convert that object literal to Java
 3256  22
         visitInstanciate(inst); // sets result
 3257  22
     }
 3258  
 
 3259  
     public void visitInterpolate(JFXInterpolate tree) {
 3260  0
         throw new UnsupportedOperationException("Not supported yet.");
 3261  
     }
 3262  
 
 3263  
     public void visitInterpolateValue(final JFXInterpolateValue tree) {
 3264  5
         DiagnosticPosition diagPos = tree.pos();
 3265  5
         JCExpression clsname = fxmake.at(diagPos).Type(syms.javafx_KeyValueType);
 3266  5
         ((JCFieldAccess) clsname).sym = syms.javafx_KeyValueType.tsym;
 3267  5
         JCExpression interp = tree.interpolation;
 3268  5
         if (interp == null)
 3269  4
             interp = fxmake.at(tree.pos).Literal(TypeTags.BOT, null);
 3270  5
         final Symbol targetSymbol = syms.javafx_KeyValueType.tsym.members().lookup(defs.targetName).sym;
 3271  5
         JFXObjectLiteralPart targetLiteral = fxmake.at(tree.pos()).ObjectLiteralPart(defs.targetName, tree.attribute);
 3272  5
         targetLiteral.sym = targetSymbol;
 3273  5
         JFXObjectLiteralPart valueLiteral =
 3274  
                 fxmake.at(tree.pos()).ObjectLiteralPart(defs.valueName, tree.value, JavafxBindStatus.UNIDIBIND);
 3275  5
         valueLiteral.sym = syms.javafx_KeyValueType.tsym.members().lookup(defs.valueName).sym;
 3276  
         List<JCTree> parts;
 3277  5
         if (tree.interpolation == null)
 3278  4
             parts = List.<JCTree>of(targetLiteral, valueLiteral);
 3279  
         else {
 3280  1
             JFXObjectLiteralPart interpolateLiteral =
 3281  
                     fxmake.at(tree.pos()).ObjectLiteralPart(defs.interpolateName, tree.interpolation, JavafxBindStatus.UNIDIBIND);
 3282  1
             interpolateLiteral.sym = syms.javafx_KeyValueType.tsym.members().lookup(defs.interpolateName).sym;
 3283  1
             parts = List.<JCTree>of(targetLiteral, valueLiteral, interpolateLiteral);
 3284  
         }
 3285  
 
 3286  5
         JFXInstanciate inst = fxmake.at(diagPos).Instanciate(clsname, null, parts);
 3287  5
         inst.type = clsname.type;
 3288  5
         result = new InstanciateTranslator(inst, this) {
 3289  
             protected void processLocalVar(JFXVar var) {
 3290  0
             }
 3291  
 
 3292  
             protected JCStatement translateAttributeSet(JCExpression init, JavafxBindStatus bindStatus, VarSymbol vsym, JCExpression instance) {
 3293  11
                 if (targetSymbol==vsym) {
 3294  5
                     JCExpression target = translate(init, Wrapped.InLocation);
 3295  5
                     target = callExpression(diagPos, make.Type(syms.javafx_PointerType), "make", target);
 3296  5
                     VarMorphInfo vmi = typeMorpher.varMorphInfo(vsym);
 3297  
                     JCExpression localAttr;
 3298  
 
 3299  
                     // if it is an attribute
 3300  5
                     if (vsym.owner.kind == Kinds.TYP) {
 3301  5
                         if ((vsym.flags() & STATIC) != 0) {
 3302  
                             // statics are accessed directly
 3303  0
                             localAttr = make.Ident(vsym);
 3304  
                         } else {
 3305  5
                             String attrAccess = attributeGetMethodNamePrefix + vsym;
 3306  5
                             localAttr = callExpression(diagPos, instance, attrAccess);
 3307  5
                         }
 3308  
                     } else {
 3309  
                         // if it is a local variable
 3310  0
                         assert( (vsym.flags() & Flags.PARAMETER) == 0): "Parameters are not initialized";
 3311  0
                         localAttr = make.at(diagPos).Ident(vsym);   
 3312  
                    }
 3313  5
                    return make.at(diagPos).Exec(callExpression(diagPos, localAttr, defs.locationSetMilieuMethodName[vmi.getTypeKind()][FROM_LITERAL_MILIEU], target));
 3314  
                } else {
 3315  6
                     return toJava.translateDefinitionalAssignmentToSet(diagPos, init, bindStatus,
 3316  
                         vsym, instance, FROM_LITERAL_MILIEU);
 3317  
                 }
 3318  
             }
 3319  
         }.doit();
 3320  5
     }
 3321  
 
 3322  
     public void visitKeyFrameLiteral(JFXKeyFrameLiteral tree) {
 3323  0
         throw new UnsupportedOperationException("Not supported yet.");
 3324  
     }
 3325  
 }