Coverage Report - com.sun.tools.javafx.comp.JavafxClassReader
 
Classes in this File Line Coverage Branch Coverage Complexity
JavafxClassReader
97%
233/241
86%
111/129
0
JavafxClassReader$1
100%
4/4
N/A
0
JavafxClassReader$2
88%
7/8
100%
2/2
0
 
 1  
 /*
 2  
  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
 3  
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 4  
  *
 5  
  * This code is free software; you can redistribute it and/or modify it
 6  
  * under the terms of the GNU General Public License version 2 only, as
 7  
  * published by the Free Software Foundation.  Sun designates this
 8  
  * particular file as subject to the "Classpath" exception as provided
 9  
  * by Sun in the LICENSE file that accompanied this code.
 10  
  *
 11  
  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  
  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  
  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  
  * version 2 for more details (a copy is included in the LICENSE file that
 15  
  * accompanied this code).
 16  
  *
 17  
  * You should have received a copy of the GNU General Public License version
 18  
  * 2 along with this work; if not, write to the Free Software Foundation,
 19  
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  
  *
 21  
  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 22  
  * CA 95054 USA or visit www.sun.com if you need additional information or
 23  
  * have any questions.
 24  
  */
 25  
 
 26  
 package com.sun.tools.javafx.comp;
 27  
 
 28  
 import java.io.*;
 29  
 import java.util.IdentityHashMap;
 30  
 import com.sun.tools.javac.jvm.ClassReader;
 31  
 import com.sun.tools.javac.code.*;
 32  
 import com.sun.tools.javac.code.Type.*;
 33  
 import com.sun.tools.javac.code.Symbol.*;
 34  
 import com.sun.tools.javac.util.*;
 35  
 import com.sun.tools.javac.util.List;
 36  
 
 37  
 import static com.sun.tools.javac.code.Flags.*;
 38  
 import static com.sun.tools.javac.code.Kinds.*;
 39  
 import static com.sun.tools.javac.code.TypeTags.*;
 40  
 import com.sun.tools.javafx.code.JavafxClassSymbol;
 41  
 import com.sun.tools.javafx.code.JavafxSymtab;
 42  
 import com.sun.tools.javafx.code.JavafxFlags;
 43  
 import static com.sun.tools.javafx.comp.JavafxDefs.*;
 44  
 
 45  
 import static javax.tools.StandardLocation.*;
 46  
 
 47  
 import static com.sun.tools.javafx.code.JavafxVarSymbol.*;
 48  
 
 49  
 /** Provides operations to read a classfile into an internal
 50  
  *  representation. The internal representation is anchored in a
 51  
  *  JavafxClassSymbol which contains in its scope symbol representations
 52  
  *  for all other definitions in the classfile. Top-level Classes themselves
 53  
  *  appear as members of the scopes of PackageSymbols.
 54  
  *
 55  
  *  We delegate actual classfile-reading to javac's ClassReader, and then
 56  
  *  translates the resulting ClassSymbol to JavafxClassSymbol, doing some
 57  
  *  renaming etc to make the resulting Symbols and Types match those produced
 58  
  *  by the parser.  This munging is incomplete, and there are still places
 59  
  *  where the compiler needs to know of a class comes from the parser or a
 60  
  *  classfile; those places will hopefully become fewer.
 61  
  *
 62  
  *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
 63  
  *  you write code that depends on this, you do so at your own risk.
 64  
  *  This code and its internal interfaces are subject to change or
 65  
  *  deletion without notice.</b>
 66  
  */
 67  12
 public class JavafxClassReader extends ClassReader {
 68  12
      protected static final Context.Key<ClassReader> backendClassReaderKey =
 69  
          new Context.Key<ClassReader>();
 70  
 
 71  
     private final JavafxDefs defs;
 72  
 
 73  
     /** The raw class-reader, shared by the back-end. */
 74  
     public ClassReader jreader;
 75  
 
 76  
     private final Name functionClassPrefixName;
 77  
     
 78  
     public static void registerBackendReader(final Context context, final ClassReader jreader) {
 79  399
         context.put(backendClassReaderKey, jreader);
 80  399
     }
 81  
     
 82  
     public static void preRegister(final Context context, final ClassReader jreader) {
 83  399
         registerBackendReader(context, jreader);
 84  399
         preRegister(context);
 85  399
     }
 86  
     public static void preRegister(final Context context) {
 87  399
         context.put(classReaderKey, new Context.Factory<ClassReader>() {
 88  
                public JavafxClassReader make() {
 89  399
                    JavafxClassReader reader = new JavafxClassReader(context, true);
 90  399
                    reader.jreader = context.get(backendClassReaderKey);
 91  399
                    return reader;
 92  
                }
 93  
         });
 94  399
     }
 95  
 
 96  
     public static JavafxClassReader instance(Context context) {
 97  1995
         JavafxClassReader instance = (JavafxClassReader) context.get(classReaderKey);
 98  1995
         if (instance == null)
 99  0
             instance = new JavafxClassReader(context, true);
 100  1995
         return instance;
 101  
     }
 102  
 
 103  
     /** Construct a new class reader, optionally treated as the
 104  
      *  definitive classreader for this invocation.
 105  
      */
 106  
     protected JavafxClassReader(Context context, boolean definitive) {
 107  399
         super(context, definitive);
 108  399
         defs = JavafxDefs.instance(context);
 109  399
         functionClassPrefixName = names.fromString(JavafxSymtab.functionClassPrefix);
 110  399
     }
 111  
 
 112  
     public Name.Table getNames() {
 113  0
         return names;
 114  
     }
 115  
 
 116  
     public JavafxClassSymbol enterClass(ClassSymbol jsymbol) {
 117  472540
         Name className = jsymbol.flatname;
 118  472540
         boolean compound = className.endsWith(defs.interfaceSuffixName);
 119  472540
         if (compound)
 120  841
             className = className.subName(0, className.len - defs.interfaceSuffixName.len);
 121  472540
         JavafxClassSymbol cSym = (JavafxClassSymbol) enterClass(className);
 122  472540
         if (compound)
 123  841
             cSym.flags_field |= JavafxFlags.COMPOUND_CLASS;
 124  
         else {
 125  471699
             if (cSym.fullname != jsymbol.fullname &&
 126  
                     cSym.owner.kind == PCK && jsymbol.owner.kind == TYP) {
 127  
                 // reassign fields of classes that might have been loaded with
 128  
                 // their flat names.
 129  793
                 cSym.owner.members().remove(cSym);
 130  793
                 cSym.name = jsymbol.name;
 131  793
                 ClassSymbol owner = enterClass(((ClassSymbol) jsymbol.owner).flatname);
 132  793
                 cSym.owner = owner;
 133  793
                 cSym.fullname = ClassSymbol.formFullName(cSym.name, owner);
 134  
             }
 135  471699
             cSym.jsymbol = jsymbol;
 136  
         }
 137  472540
         return cSym;
 138  
     }
 139  
 
 140  
     /** Define a new class given its name and owner.
 141  
      */
 142  
     public ClassSymbol defineClass(Name name, Symbol owner) {
 143  442299
         ClassSymbol c = new JavafxClassSymbol(0, name, owner);
 144  442299
         if (owner.kind == PCK)
 145  441982
             assert classes.get(c.flatname) == null : c;
 146  442299
         c.completer = this;
 147  442299
         return c;
 148  
     }
 149  
 
 150  
     /* FIXME: The re-written class-reader doesn't translate annotations yet.
 151  
  
 152  
     protected void attachAnnotations(final Symbol sym) {
 153  
         int numAttributes = nextChar();
 154  
         if (numAttributes != 0) {
 155  
             ListBuffer<CompoundAnnotationProxy> proxies =
 156  
                 new ListBuffer<CompoundAnnotationProxy>();
 157  
             for (int i = 0; i<numAttributes; i++) {
 158  
                 CompoundAnnotationProxy proxy = readCompoundAnnotation();
 159  
                 if (proxy.type.tsym == syms.proprietaryType.tsym)
 160  
                     sym.flags_field |= PROPRIETARY;
 161  
                 else {
 162  
                         proxies.append(proxy);
 163  
                 }
 164  
             }
 165  
             annotate.later(new JavafxAnnotationCompleter(sym, proxies.toList(), this));
 166  
         }
 167  
     }
 168  
 
 169  
     static public class JavafxAnnotationCompleter extends AnnotationCompleter {
 170  
         JavafxClassReader classReader;
 171  
         public JavafxAnnotationCompleter(Symbol sym, List<CompoundAnnotationProxy> l, ClassReader classReader) {
 172  
             super(sym, l, classReader);
 173  
             this.classReader = (JavafxClassReader)classReader;
 174  
         }
 175  
         // implement Annotate.Annotator.enterAnnotation()
 176  
         public void enterAnnotation() {
 177  
             JavaFileObject previousClassFile = classReader.currentClassFile;
 178  
             try {
 179  
                 classReader.currentClassFile = classFile;
 180  
                 List<Attribute.Compound> newList = deproxyCompoundList(l);
 181  
                 JavafxSymtab javafxSyms = (JavafxSymtab)classReader.syms;
 182  
                 for (Attribute.Compound comp : newList) {
 183  
                     if (comp.type.tsym.flatName() == javafxSyms.javafx_staticAnnotationType.tsym.flatName()) {
 184  
                         if (sym != null && sym.kind == MTH &&
 185  
                                 sym.name.toString().startsWith(classReader.defs.attributeGetMethodNamePrefix)) {
 186  
                             sym.flags_field |=  Flags.STATIC;
 187  
                         }
 188  
                     }
 189  
                     if (comp.type.tsym.flatName() == javafxSyms.javafx_privateAnnotationType.tsym.flatName()) {
 190  
                         if (sym != null && sym.kind == MTH  && false) {// TODO: Need a way to deal with private methods. The interface 
 191  
                                                               // of a base class defines them, but for a superclasss that implements 
 192  
                                                               // them they are not considered overriding methods since they are private.
 193  
                                 // See above TODO; !sym.name.toString().startsWith(classReader.defs.attributeGetMethodNamePrefix)) {
 194  
                             sym.flags_field &= ~(Flags.PROTECTED | Flags.PUBLIC);
 195  
                             sym.flags_field |=  Flags.PRIVATE;
 196  
                         }
 197  
                     }
 198  
                     else if (comp.type.tsym.flatName() == javafxSyms.javafx_protectedAnnotationType.tsym.flatName()) {
 199  
                         if (sym != null && sym.kind == MTH &&
 200  
                                 !sym.name.toString().startsWith(classReader.defs.attributeGetMethodNamePrefix)) {
 201  
                             sym.flags_field &= ~(Flags.PRIVATE | Flags.PUBLIC);
 202  
                             sym.flags_field |=  Flags.PROTECTED;
 203  
                         }
 204  
                     }
 205  
                     else if (comp.type.tsym.flatName() == javafxSyms.javafx_publicAnnotationType.tsym.flatName()) {
 206  
                         if (sym != null && sym.kind == MTH &&
 207  
                                 !sym.name.toString().startsWith(classReader.defs.attributeGetMethodNamePrefix)) {
 208  
                             sym.flags_field &= ~(Flags.PROTECTED | Flags.PRIVATE);
 209  
                             sym.flags_field |=  Flags.PUBLIC;
 210  
                         }
 211  
                     }
 212  
                 }
 213  
 
 214  
                 sym.attributes_field = ((sym.attributes_field == null)
 215  
                                         ? newList
 216  
                                         : newList.prependList(sym.attributes_field));
 217  
             } finally {
 218  
                 classReader.currentClassFile = previousClassFile;
 219  
             }
 220  
         }
 221  
     }
 222  
     */
 223  
 
 224  
     /** Map javac Type/Symbol to javafx Type/Symbol. */
 225  399
     IdentityHashMap<Object,Object> typeMap = new IdentityHashMap<Object,Object>();
 226  
     
 227  
     /** Translate a List of raw JVM types to Javafx types. */
 228  
     List<Type> translateTypes (List<Type> types) {
 229  341333
         if (types == null)
 230  3355
             return null;
 231  337978
         List<Type> ts = (List<Type>) typeMap.get(types);
 232  337978
         if (ts != null)
 233  198922
             return ts;
 234  139056
         ListBuffer<Type> rs = new ListBuffer<Type>();
 235  139056
         for (List<Type> t = types;
 236  335492
                  t.tail != null;
 237  196436
                  t = t.tail)
 238  196436
             rs.append(translateType(t.head));
 239  139056
         ts = rs.toList();
 240  139056
         typeMap.put(types, ts);
 241  139056
         return ts;
 242  
     }
 243  
 
 244  
     /** Translate raw JVM type to Javafx type. */
 245  
     Type translateType (Type type) {
 246  589334
         if (type == null)
 247  0
             return null;
 248  589334
         Type t = (Type) typeMap.get(type);
 249  589334
         if (t != null)
 250  347585
             return t;
 251  241749
         switch (type.tag) {
 252  
             case VOID:
 253  373
                 t = syms.voidType;
 254  373
                 break;
 255  
             case BOOLEAN:
 256  373
                 t = syms.booleanType;
 257  373
                 break;
 258  
             case CHAR:
 259  357
                 t = syms.charType;
 260  357
                 break;
 261  
             case BYTE:
 262  358
                 t = syms.byteType;
 263  358
                 break;
 264  
             case SHORT:
 265  187
                 t = syms.shortType;
 266  187
                 break;
 267  
             case INT:
 268  373
                 t = syms.intType;
 269  373
                 break;
 270  
             case LONG:
 271  373
                 t = syms.longType;
 272  373
                 break;
 273  
             case DOUBLE:
 274  358
                 t = syms.doubleType;
 275  358
                 break;
 276  
             case FLOAT:
 277  358
                 t = syms.floatType;
 278  358
                 break;
 279  
             case TYPEVAR:
 280  2122
                 TypeVar tv = (TypeVar) type;
 281  2122
                 TypeVar tx = new TypeVar(null, (Type) null, (Type) null);
 282  2122
                 typeMap.put(type, tx); // In case of a cycle.
 283  2122
                 tx.bound = translateType(tv.bound);
 284  2122
                 tx.lower = translateType(tv.lower);
 285  2122
                 tx.tsym = new TypeSymbol(0, tv.tsym.name, tx, translateSymbol(tv.tsym.owner));
 286  2122
                 return tx;
 287  
             case FORALL:
 288  1252
                 ForAll tf = (ForAll) type;
 289  1252
                 t = new ForAll(translateTypes(tf.tvars), translateType(tf.qtype));
 290  1252
                 break;
 291  
             case WILDCARD:
 292  9667
                 WildcardType wt = (WildcardType) type;
 293  9667
                 t = new WildcardType(translateType(wt.type), wt.kind,
 294  
                         translateTypeSymbol(wt.tsym));
 295  9667
                 break;
 296  
             case CLASS:
 297  57776
                 TypeSymbol tsym = type.tsym;
 298  57776
                 if (tsym instanceof ClassSymbol) {
 299  57776
                     if (tsym.name.endsWith(defs.interfaceSuffixName)) {
 300  800
                         t = enterClass((ClassSymbol) tsym).type;
 301  800
                         break;
 302  
                     }
 303  56976
                     final ClassType ctype = (ClassType) type;
 304  56976
                     if (ctype.isCompound()) {
 305  0
                         t = types.makeCompoundType(translateTypes(ctype.interfaces_field), translateType(ctype.supertype_field));
 306  0
                         break;
 307  
                     }
 308  56976
                     Name flatname = ((ClassSymbol) tsym).flatname;
 309  56976
                     Type deloc = defs.delocationize(flatname);
 310  56976
                     if (deloc != null) {
 311  18249
                         if (deloc == syms.intType || deloc == syms.doubleType || deloc == syms.booleanType) {
 312  4943
                             return deloc;
 313  
                         }
 314  13306
                         if (ctype.typarams_field != null && ctype.typarams_field.size() == 1) {
 315  13290
                             if (deloc == syms.objectType) {
 316  12791
                                 return translateType(ctype.typarams_field.head);
 317  
                             }
 318  499
                             if (deloc == ((JavafxSymtab) syms).javafx_SequenceType) {
 319  499
                                 Type tparam = translateType(ctype.typarams_field.head);
 320  499
                                 WildcardType tpType = new WildcardType(tparam, BoundKind.EXTENDS, tparam.tsym);
 321  499
                                 t = new ClassType(Type.noType, List.<Type>of(tpType), ((JavafxSymtab) syms).javafx_SequenceType.tsym);
 322  499
                                 break;
 323  
                             }
 324  
                         }
 325  
                     }
 326  38743
                     if (flatname.startsWith(functionClassPrefixName)
 327  
                         && flatname != functionClassPrefixName) {
 328  2756
                             t = ((JavafxSymtab) syms).makeFunctionType(translateTypes(ctype.typarams_field));
 329  2756
                             break;
 330  
                     }
 331  35987
                     TypeSymbol sym = translateTypeSymbol(tsym);
 332  
                     ClassType ntype;
 333  35987
                     if (tsym.type == type)
 334  2713
                         ntype = (ClassType) sym.type;
 335  
                     else
 336  33274
                         ntype = new ClassType(null, null, sym) {
 337  33274
                         boolean completed = false;
 338  
                         public Type getEnclosingType() {
 339  40276
                             if (!completed) {
 340  2547
                                 completed = true;
 341  2547
                                 tsym.complete();
 342  2547
                                 super.setEnclosingType(translateType(ctype.getEnclosingType()));
 343  
                             }
 344  40276
                             return super.getEnclosingType();
 345  
                         }
 346  
                         public void setEnclosingType(Type outer) {
 347  0
                             throw new UnsupportedOperationException();
 348  
                         }
 349  
                     };
 350  35987
                     typeMap.put(type, ntype); // In case of a cycle.
 351  35987
                     ntype.typarams_field = translateTypes(type.getTypeArguments());
 352  35987
                     return ntype;
 353  
                 }
 354  
                 break;
 355  
             case ARRAY:
 356  19168
                 t = new ArrayType(translateType(((ArrayType) type).elemtype), syms.arrayClass);
 357  19168
                 break;
 358  
             case METHOD:
 359  147911
                 t = new MethodType(translateTypes(type.getParameterTypes()),
 360  
                         translateType(type.getReturnType()),
 361  
                         translateTypes(type.getThrownTypes()),
 362  
                         syms.methodClass);
 363  147911
                 break;
 364  
             default:
 365  743
                 t = type; // FIXME
 366  
         }
 367  185906
         typeMap.put(type, t);
 368  185906
         return t;
 369  
     }
 370  
 
 371  
     TypeSymbol translateTypeSymbol(TypeSymbol tsym) {
 372  46441
         if (tsym == syms.predefClass)
 373  0
             return tsym;
 374  46441
         ClassSymbol csym = (ClassSymbol) tsym; // FIXME
 375  46441
         return enterClass(csym);
 376  
     }
 377  
     Symbol translateSymbol(Symbol sym) {
 378  3538
         if (sym == null)
 379  0
             return null;
 380  3538
         Symbol s = (Symbol) typeMap.get(sym);
 381  3538
         if (s != null)
 382  2122
             return s;
 383  1416
         if (sym instanceof PackageSymbol)
 384  0
             s = enterPackage(((PackageSymbol) sym).fullname);
 385  1416
         else if (sym instanceof MethodSymbol) {
 386  629
             Name name = sym.name;
 387  629
             long flags = sym.flags_field;
 388  629
             Symbol owner = translateSymbol(sym.owner);
 389  629
             Type type = translateType(sym.type);
 390  629
             String nameString = name.toString();
 391  629
             int boundStringIndex = nameString.indexOf(JavafxDefs.boundFunctionDollarSuffix);
 392  629
             if (boundStringIndex != -1) {
 393  
                 // this is a bound function
 394  
                 // remove the bound suffix, and mark as bound
 395  8
                 name = names.fromString(nameString.substring(0, boundStringIndex));
 396  8
                 flags |= JavafxFlags.BOUND;
 397  
             }
 398  629
             MethodSymbol m = new MethodSymbol(flags, name, type, owner);
 399  629
             ((ClassSymbol) owner).members_field.enter(m);
 400  629
             s = m;
 401  629
         }
 402  
         else
 403  787
             s = translateTypeSymbol((TypeSymbol) sym);
 404  1416
         typeMap.put(sym, s);
 405  1416
         return s;
 406  
     }
 407  
 
 408  
     public void complete(Symbol sym) throws CompletionFailure {
 409  10768
         if (sym instanceof PackageSymbol) {
 410  3242
             PackageSymbol psym = (PackageSymbol) sym;
 411  
             PackageSymbol jpackage;
 412  3242
             if (psym == syms.unnamedPackage)
 413  366
                 jpackage = jreader.syms.unnamedPackage;
 414  
             else
 415  2876
                 jpackage = jreader.enterPackage(psym.fullname);
 416  3242
             jpackage.complete();
 417  3242
             if (psym.members_field == null) psym.members_field = new Scope(psym);
 418  3242
             for (Scope.Entry e = jpackage.members_field.elems;
 419  969108
                  e != null;  e = e.sibling) {
 420  482933
                  if (e.sym instanceof ClassSymbol) {
 421  482933
                      ClassSymbol jsym = (ClassSymbol) e.sym;
 422  482933
                      if (jsym.name.endsWith(defs.interfaceSuffixName))
 423  57634
                          continue;
 424  425299
                      JavafxClassSymbol csym = enterClass(jsym);
 425  425299
                      psym.members_field.enter(csym);
 426  425299
                      csym.classfile = jsym.classfile;
 427  425299
                      csym.jsymbol = jsym;
 428  
                  }
 429  
             }
 430  3242
         } else {
 431  7526
             sym.owner.complete();
 432  7526
             JavafxClassSymbol csym = (JavafxClassSymbol) sym;
 433  7526
             ClassSymbol jsymbol = csym.jsymbol;
 434  7526
             csym.jsymbol = jsymbol = jreader.loadClass(csym.flatname);
 435  5516
             typeMap.put(jsymbol, csym);
 436  5516
             jsymbol.classfile = ((ClassSymbol) sym).classfile;
 437  
             
 438  5516
             ClassType ct = (ClassType)csym.type;
 439  5516
             ClassType jt = (ClassType)jsymbol.type;
 440  5516
             csym.members_field = new Scope(csym);
 441  
 
 442  5516
             csym.flags_field = jsymbol.flags_field;
 443  
             
 444  5516
             ct.typarams_field = translateTypes(jt.typarams_field);
 445  5516
             ct.setEnclosingType(translateType(jt.getEnclosingType()));
 446  
             
 447  5516
             ct.supertype_field = translateType(jt.supertype_field);
 448  5516
             ListBuffer<Type> interfaces = new ListBuffer<Type>();
 449  5516
             Type iface = null;
 450  5516
             for (List<Type> it = jt.interfaces_field;
 451  11289
                  it.tail != null;
 452  5773
                  it = it.tail) {
 453  5773
                 Type itype = it.head;
 454  5773
                 if (((ClassSymbol) itype.tsym).flatname == defs.fxObjectName)
 455  327
                     csym.flags_field |= JavafxFlags.FX_CLASS;
 456  5446
                 else if (itype.tsym.name.endsWith(defs.interfaceSuffixName)) {
 457  322
                     assert (csym.fullname.len + defs.interfaceSuffixName.len ==
 458  
                             ((ClassSymbol) itype.tsym).fullname.len) &&
 459  
                            ((ClassSymbol) itype.tsym).fullname.startsWith(csym.fullname);
 460  322
                     iface = itype;
 461  322
                     csym.flags_field |= JavafxFlags.COMPOUND_CLASS;
 462  
                 }
 463  
                 else {
 464  5124
                     itype = translateType(itype);
 465  5124
                     interfaces.append(itype);
 466  
                 }
 467  
             }
 468  
            
 469  5516
             if (iface != null) {
 470  322
                 iface.tsym.complete();
 471  322
                 for (List<Type> it = ((ClassType) iface.tsym.type).interfaces_field;
 472  863
                  it.tail != null;
 473  541
                  it = it.tail) {
 474  541
                     Type itype = it.head;
 475  541
                     if (((ClassSymbol) itype.tsym).flatname == defs.fxObjectName)
 476  322
                         csym.flags_field |= JavafxFlags.FX_CLASS;
 477  
                     else {
 478  219
                         itype = translateType(itype);
 479  219
                         interfaces.append(itype);
 480  219
                         csym.addSuperType(itype);
 481  
                     }
 482  
                 }
 483  
             }
 484  5516
             ct.interfaces_field = interfaces.toList();
 485  
 
 486  
             // Now translate the members.
 487  
             // Do an initial "reverse" pass so we copy the order.
 488  5516
             List<Symbol> syms = List.nil();
 489  5516
             for (Scope.Entry e = jsymbol.members_field.elems;
 490  404910
                  e != null;  e = e.sibling) {
 491  199697
                 if ((e.sym.flags_field & SYNTHETIC) != 0)
 492  2209
                     continue;
 493  197488
                 syms = syms.prepend(e.sym);
 494  
             }
 495  203004
             for (List<Symbol> l = syms; l.nonEmpty(); l=l.tail) {
 496  197488
                 Name name = l.head.name;
 497  197488
                 long flags = l.head.flags_field;
 498  197488
                 if ((flags & PRIVATE) != 0)
 499  18886
                     continue;
 500  178602
                 if (l.head instanceof MethodSymbol) {
 501  
                     // This should be merged with translateSymbol.
 502  
                     // But that doesn't work for some unknown reason.  FIXME
 503  147911
                     Type type = translateType(l.head.type);
 504  147911
                     String nameString = name.toString();
 505  147911
                     int boundStringIndex = nameString.indexOf(JavafxDefs.boundFunctionDollarSuffix);
 506  147911
                     if (boundStringIndex != -1) {
 507  
                         // this is a bound function
 508  
                         // remove the bound suffix, and mark as bound
 509  733
                         name = names.fromString(nameString.substring(0, boundStringIndex));
 510  733
                         flags |= JavafxFlags.BOUND;
 511  
                     }
 512  147911
                     MethodSymbol m = new MethodSymbol(flags, name, type, csym);
 513  147911
                     csym.members_field.enter(m);
 514  147911
                 }
 515  30691
                 else if (l.head instanceof VarSymbol) {
 516  29904
                     Type type = translateType(l.head.type);
 517  29904
                     VarSymbol v = new VarSymbol(flags, name, type, csym);
 518  29904
                     csym.members_field.enter(v);
 519  29904
                 }
 520  
                 else {
 521  787
                     csym.members_field.enter(translateSymbol(l.head));
 522  
                 }
 523  
             }
 524  
         }
 525  8758
     }
 526  
 }