Skip to content
This repository
Browse code

Brought some structure to the classfileparser.

I run out of ways to describe this sort of work: removes
code which does too much, too verbosely and too explicitly,
using too much indirection and too much duplication. Replace
it with code which offers less of these things.
  • Loading branch information...
commit 8c78d4bfc60d8ebc2bd72899a57d2abf2b2eced1 1 parent 71c14e4
Paul Phillips authored April 01, 2013
522  src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -12,9 +12,11 @@ import java.lang.Integer.toHexString
12 12
 import scala.collection.{ mutable, immutable }
13 13
 import scala.collection.mutable.{ ListBuffer, ArrayBuffer }
14 14
 import scala.annotation.switch
  15
+import scala.reflect.internal.{ JavaAccFlags }
15 16
 import scala.reflect.internal.pickling.{PickleBuffer, ByteCodecs}
16 17
 import scala.tools.nsc.io.AbstractFile
17 18
 
  19
+
18 20
 /** This abstract class implements a class file parser.
19 21
  *
20 22
  *  @author Martin Odersky
@@ -41,11 +43,31 @@ abstract class ClassfileParser {
41 43
   protected var classTParams = Map[Name,Symbol]()
42 44
   protected var srcfile0 : Option[AbstractFile] = None
43 45
   protected def moduleClass: Symbol = staticModule.moduleClass
  46
+  private var sawPrivateConstructor = false
  47
+
  48
+  private def ownerForFlags(jflags: JavaAccFlags) = if (jflags.isStatic) moduleClass else clazz
44 49
 
45 50
   def srcfile = srcfile0
46 51
 
  52
+  private def optimized         = global.settings.optimise.value
47 53
   private def currentIsTopLevel = !(currentClass.decodedName containsChar '$')
48 54
 
  55
+  // u1, u2, and u4 are what these data types are called in the JVM spec.
  56
+  // They are an unsigned byte, unsigned char, and unsigned int respectively.
  57
+  // We bitmask u1 into an Int to make sure it's 0-255 (and u1 isn't used
  58
+  // for much beyond tags) but leave u2 alone as it's already unsigned.
  59
+  protected final def u1 = in.nextByte & 0xFF
  60
+  protected final def u2 = in.nextChar
  61
+  protected final def u4 = in.nextInt
  62
+
  63
+  private def readInnerClassFlags() = readClassFlags()
  64
+  private def readClassFlags()      = JavaAccFlags classFlags u2
  65
+  private def readMethodFlags()     = JavaAccFlags methodFlags u2
  66
+  private def readFieldFlags()      = JavaAccFlags fieldFlags u2
  67
+  private def readTypeName()        = readName().toTypeName
  68
+  private def readName()            = pool getName u2
  69
+  private def readType()            = pool getType u2
  70
+
49 71
   private object unpickler extends scala.reflect.internal.pickling.UnPickler {
50 72
     val global: ClassfileParser.this.global.type = ClassfileParser.this.global
51 73
   }
@@ -107,60 +129,60 @@ abstract class ClassfileParser {
107 129
   }
108 130
 
109 131
   private def parseHeader() {
110  
-    val magic = in.nextInt
  132
+    val magic = u4
111 133
     if (magic != JAVA_MAGIC)
112 134
       abort(s"class file ${in.file} has wrong magic number 0x${toHexString(magic)}")
113 135
 
114  
-    val minor, major = in.nextChar.toInt
  136
+    val minor, major = u2
115 137
     if (major < JAVA_MAJOR_VERSION || major == JAVA_MAJOR_VERSION && minor < JAVA_MINOR_VERSION)
116 138
       abort(s"class file ${in.file} has unknown version $major.$minor, should be at least $JAVA_MAJOR_VERSION.$JAVA_MINOR_VERSION")
117 139
   }
118 140
 
119 141
   class ConstantPool {
120  
-    private val len = in.nextChar
121  
-    private val starts = new Array[Int](len)
122  
-    private val values = new Array[AnyRef](len)
  142
+    private val len          = u2
  143
+    private val starts       = new Array[Int](len)
  144
+    private val values       = new Array[AnyRef](len)
123 145
     private val internalized = new Array[Name](len)
124 146
 
125 147
     { var i = 1
126 148
       while (i < starts.length) {
127 149
         starts(i) = in.bp
128 150
         i += 1
129  
-        (in.nextByte.toInt: @switch) match {
130  
-          case CONSTANT_UTF8 | CONSTANT_UNICODE =>
131  
-            in.skip(in.nextChar)
132  
-          case CONSTANT_CLASS | CONSTANT_STRING | CONSTANT_METHODTYPE=>
133  
-            in.skip(2)
134  
-          case CONSTANT_METHODHANDLE =>
135  
-            in.skip(3)
136  
-          case CONSTANT_FIELDREF | CONSTANT_METHODREF | CONSTANT_INTFMETHODREF
137  
-             | CONSTANT_NAMEANDTYPE | CONSTANT_INTEGER | CONSTANT_FLOAT
138  
-             | CONSTANT_INVOKEDYNAMIC =>
139  
-            in.skip(4)
140  
-          case CONSTANT_LONG | CONSTANT_DOUBLE =>
141  
-            in.skip(8)
142  
-            i += 1
143  
-          case _ =>
144  
-            errorBadTag(in.bp - 1)
  151
+        (u1.toInt: @switch) match {
  152
+          case CONSTANT_UTF8 | CONSTANT_UNICODE                                => in skip u2
  153
+          case CONSTANT_CLASS | CONSTANT_STRING | CONSTANT_METHODTYPE          => in skip 2
  154
+          case CONSTANT_METHODHANDLE                                           => in skip 3
  155
+          case CONSTANT_FIELDREF | CONSTANT_METHODREF | CONSTANT_INTFMETHODREF => in skip 4
  156
+          case CONSTANT_NAMEANDTYPE | CONSTANT_INTEGER | CONSTANT_FLOAT        => in skip 4
  157
+          case CONSTANT_INVOKEDYNAMIC                                          => in skip 4
  158
+          case CONSTANT_LONG | CONSTANT_DOUBLE                                 => in skip 8 ; i += 1
  159
+          case _                                                               => errorBadTag(in.bp - 1)
145 160
         }
146 161
       }
147 162
     }
148 163
 
149  
-    /** Return the name found at given index. */
150  
-    def getName(index: Int): Name = {
151  
-      if (index <= 0 || len <= index)
152  
-        errorBadIndex(index)
  164
+    def recordAtIndex[T <: AnyRef](value: T, idx: Int): T = {
  165
+      values(idx) = value
  166
+      value
  167
+    }
153 168
 
154  
-      values(index) match {
  169
+    def firstExpecting(index: Int, expected: Int): Int = {
  170
+      val start = starts(index)
  171
+      val first = in.buf(start).toInt
  172
+      if (first == expected) start + 1
  173
+      else this errorBadTag start
  174
+    }
  175
+
  176
+    /** Return the name found at given index. */
  177
+    def getName(index: Int): Name = (
  178
+      if (index <= 0 || len <= index) errorBadIndex(index)
  179
+      else values(index) match {
155 180
         case name: Name => name
156  
-        case null   =>
157  
-          val start = starts(index)
158  
-          if (in.buf(start).toInt != CONSTANT_UTF8) errorBadTag(start)
159  
-          val name = newTermName(in.buf, start + 3, in.getChar(start + 1))
160  
-          values(index) = name
161  
-          name
  181
+        case _          =>
  182
+          val start = firstExpecting(index, CONSTANT_UTF8)
  183
+          recordAtIndex(newTermName(in.buf, start + 2, in.getChar(start)), index)
162 184
       }
163  
-    }
  185
+    )
164 186
 
165 187
     /** Return the name found at given index in the constant pool, with '/' replaced by '.'. */
166 188
     def getExternalName(index: Int): Name = {
@@ -175,28 +197,23 @@ abstract class ClassfileParser {
175 197
 
176 198
     def getClassSymbol(index: Int): Symbol = {
177 199
       if (index <= 0 || len <= index) errorBadIndex(index)
178  
-      var c = values(index).asInstanceOf[Symbol]
179  
-      if (c eq null) {
180  
-        val start = starts(index)
181  
-        if (in.buf(start).toInt != CONSTANT_CLASS) errorBadTag(start)
182  
-        val name = getExternalName(in.getChar(start + 1))
183  
-        if (nme.isModuleName(name))
184  
-          c = rootMirror.getModuleByName(name.dropModule)
185  
-        else
186  
-          c = classNameToSymbol(name)
187  
-
188  
-        values(index) = c
  200
+      values(index) match {
  201
+        case sym: Symbol => sym
  202
+        case _           =>
  203
+          val result = getClassName(index) match {
  204
+            case name if nme.isModuleName(name) => rootMirror getModuleByName name.dropModule
  205
+            case name                           => classNameToSymbol(name)
  206
+          }
  207
+          recordAtIndex(result, index)
189 208
       }
190  
-      c
191 209
     }
192 210
 
193 211
     /** Return the external name of the class info structure found at 'index'.
194 212
      *  Use 'getClassSymbol' if the class is sure to be a top-level class.
195 213
      */
196 214
     def getClassName(index: Int): Name = {
197  
-      val start = starts(index)
198  
-      if (in.buf(start).toInt != CONSTANT_CLASS) errorBadTag(start)
199  
-      getExternalName(in.getChar(start + 1))
  215
+      val start = firstExpecting(index, CONSTANT_CLASS)
  216
+      getExternalName(in getChar start)
200 217
     }
201 218
 
202 219
     /** Return the symbol of the class member at `index`.
@@ -272,94 +289,66 @@ abstract class ClassfileParser {
272 289
      */
273 290
     private def getNameAndType(index: Int, ownerTpe: Type): (Name, Type) = {
274 291
       if (index <= 0 || len <= index) errorBadIndex(index)
275  
-      var p = values(index).asInstanceOf[(Name, Type)]
276  
-      if (p eq null) {
277  
-        val start = starts(index)
278  
-        if (in.buf(start).toInt != CONSTANT_NAMEANDTYPE) errorBadTag(start)
279  
-        val name = getName(in.getChar(start + 1).toInt)
280  
-        // create a dummy symbol for method types
281  
-        val dummySym = ownerTpe.typeSymbol.newMethod(name.toTermName, ownerTpe.typeSymbol.pos)
282  
-        var tpe  = getType(dummySym, in.getChar(start + 3).toInt)
283  
-
284  
-        // fix the return type, which is blindly set to the class currently parsed
285  
-        if (name == nme.CONSTRUCTOR)
286  
-          tpe match {
287  
-            case MethodType(formals, restpe) =>
288  
-              tpe = MethodType(formals, ownerTpe)
  292
+      (values(index): @unchecked) match {
  293
+        case p: ((Name, Type)) => p
  294
+        case _                 =>
  295
+          val start = firstExpecting(index, CONSTANT_NAMEANDTYPE)
  296
+          val name = getName(in.getChar(start).toInt)
  297
+          // create a dummy symbol for method types
  298
+          val dummy = ownerTpe.typeSymbol.newMethod(name.toTermName, ownerTpe.typeSymbol.pos)
  299
+          val tpe   = getType(dummy, in.getChar(start + 2).toInt)
  300
+          // fix the return type, which is blindly set to the class currently parsed
  301
+          val restpe = tpe match {
  302
+            case MethodType(formals, _) if name == nme.CONSTRUCTOR => MethodType(formals, ownerTpe)
  303
+            case _                                                 => tpe
289 304
           }
290  
-
291  
-        p = (name, tpe)
  305
+          ((name, restpe))
292 306
       }
293  
-      p
294 307
     }
295 308
 
296 309
     /** Return the type of a class constant entry. Since
297 310
      *  arrays are considered to be class types, they might
298 311
      *  appear as entries in 'newarray' or 'cast' opcodes.
299 312
      */
300  
-    def getClassOrArrayType(index: Int): Type = {
  313
+    def getClassOrArrayType(index: Int): Type = (
301 314
       if (index <= 0 || len <= index) errorBadIndex(index)
302  
-      val value = values(index)
303  
-      var c: Type = null
304  
-      if (value eq null) {
305  
-        val start = starts(index)
306  
-        if (in.buf(start).toInt != CONSTANT_CLASS) errorBadTag(start)
307  
-        val name = getExternalName(in.getChar(start + 1))
308  
-        if (name.charAt(0) == ARRAY_TAG) {
309  
-          c = sigToType(null, name)
310  
-          values(index) = c
311  
-        } else {
312  
-          val sym = classNameToSymbol(name)
313  
-                  /*if (name.endsWith("$")) definitions.getModule(name.subName(0, name.length - 1))
314  
-                    else if (name.endsWith("$class")) definitions.getModule(name)
315  
-                    else definitions.getClass(name)*/
316  
-          values(index) = sym
317  
-          c = sym.tpe
318  
-        }
319  
-      } else c = value match {
320  
-          case tp: Type => tp
321  
-          case cls: Symbol => cls.tpe
  315
+      else values(index) match {
  316
+        case tp: Type    => tp
  317
+        case cls: Symbol => cls.tpe_*
  318
+        case _           =>
  319
+          val name = getClassName(index)
  320
+          name charAt 0 match {
  321
+            case ARRAY_TAG => recordAtIndex(sigToType(null, name), index)
  322
+            case _         => recordAtIndex(classNameToSymbol(name), index).tpe_*
  323
+          }
322 324
       }
323  
-      c
324  
-    }
325  
-
326  
-    def getType(index: Int): Type = getType(null, index)
327  
-
328  
-    def getType(sym: Symbol, index: Int): Type =
329  
-      sigToType(sym, getExternalName(index))
  325
+    )
330 326
 
331  
-    def getSuperClass(index: Int): Symbol =
332  
-      if (index == 0) definitions.AnyClass else getClassSymbol(index)
  327
+    def getType(index: Int): Type              = getType(null, index)
  328
+    def getType(sym: Symbol, index: Int): Type = sigToType(sym, getExternalName(index))
  329
+    def getSuperClass(index: Int): Symbol      = if (index == 0) AnyClass else getClassSymbol(index)
333 330
 
334  
-    def getConstant(index: Int): Constant = {
  331
+    private def createConstant(index: Int): Constant = {
  332
+      val start = starts(index)
  333
+      Constant((in.buf(start).toInt: @switch) match {
  334
+        case CONSTANT_STRING  => getName(in.getChar(start + 1).toInt).toString
  335
+        case CONSTANT_INTEGER => in.getInt(start + 1)
  336
+        case CONSTANT_FLOAT   => in.getFloat(start + 1)
  337
+        case CONSTANT_LONG    => in.getLong(start + 1)
  338
+        case CONSTANT_DOUBLE  => in.getDouble(start + 1)
  339
+        case CONSTANT_CLASS   => getClassOrArrayType(index).typeSymbol.tpe_* // !!! Is this necessary or desirable?
  340
+        case _                => errorBadTag(start)
  341
+      })
  342
+    }
  343
+    def getConstant(index: Int): Constant = (
335 344
       if (index <= 0 || len <= index) errorBadIndex(index)
336  
-      var value = values(index)
337  
-      if (value eq null) {
338  
-        val start = starts(index)
339  
-        value = (in.buf(start).toInt: @switch) match {
340  
-          case CONSTANT_STRING =>
341  
-            Constant(getName(in.getChar(start + 1).toInt).toString)
342  
-          case CONSTANT_INTEGER =>
343  
-            Constant(in.getInt(start + 1))
344  
-          case CONSTANT_FLOAT =>
345  
-            Constant(in.getFloat(start + 1))
346  
-          case CONSTANT_LONG =>
347  
-            Constant(in.getLong(start + 1))
348  
-          case CONSTANT_DOUBLE =>
349  
-            Constant(in.getDouble(start + 1))
350  
-          case CONSTANT_CLASS =>
351  
-            getClassOrArrayType(index).typeSymbol
352  
-          case _ =>
353  
-            errorBadTag(start)
354  
-        }
355  
-        values(index) = value
  345
+      else values(index) match {
  346
+        case  const: Constant => const
  347
+        case sym: Symbol      => Constant(sym.tpe_*)
  348
+        case tpe: Type        => Constant(tpe)
  349
+        case _                => recordAtIndex(createConstant(index), index)
356 350
       }
357  
-      value match {
358  
-        case  ct: Constant => ct
359  
-        case cls: Symbol   => Constant(cls.tpe_*)
360  
-        case arr: Type     => Constant(arr)
361  
-      }
362  
-    }
  351
+    )
363 352
 
364 353
     private def getSubArray(bytes: Array[Byte]): Array[Byte] = {
365 354
       val decodedLength = ByteCodecs.decode(bytes)
@@ -368,46 +357,41 @@ abstract class ClassfileParser {
368 357
       arr
369 358
     }
370 359
 
371  
-    def getBytes(index: Int): Array[Byte] = {
  360
+    def getBytes(index: Int): Array[Byte] = (
372 361
       if (index <= 0 || len <= index) errorBadIndex(index)
373  
-      var value = values(index).asInstanceOf[Array[Byte]]
374  
-      if (value eq null) {
375  
-        val start = starts(index)
376  
-        if (in.buf(start).toInt != CONSTANT_UTF8) errorBadTag(start)
377  
-        val len   = in.getChar(start + 1)
378  
-        val bytes = new Array[Byte](len)
379  
-        System.arraycopy(in.buf, start + 3, bytes, 0, len)
380  
-        value = getSubArray(bytes)
381  
-        values(index) = value
  362
+      else values(index) match {
  363
+        case xs: Array[Byte] => xs
  364
+        case _               =>
  365
+          val start = firstExpecting(index, CONSTANT_UTF8)
  366
+          val len   = in getChar start
  367
+          val bytes = new Array[Byte](len)
  368
+          System.arraycopy(in.buf, start + 2, bytes, 0, len)
  369
+          recordAtIndex(getSubArray(bytes), index)
382 370
       }
383  
-      value
384  
-    }
  371
+    )
385 372
 
386 373
     def getBytes(indices: List[Int]): Array[Byte] = {
387  
-      assert(!indices.isEmpty, indices)
388  
-      var value = values(indices.head).asInstanceOf[Array[Byte]]
389  
-      if (value eq null) {
390  
-        val bytesBuffer = ArrayBuffer.empty[Byte]
391  
-        for (index <- indices) {
392  
-          if (index <= 0 || ConstantPool.this.len <= index) errorBadIndex(index)
393  
-          val start = starts(index)
394  
-          if (in.buf(start).toInt != CONSTANT_UTF8) errorBadTag(start)
395  
-          val len = in.getChar(start + 1)
396  
-          bytesBuffer ++= in.buf.view(start + 3, start + 3 + len)
397  
-        }
398  
-        value = getSubArray(bytesBuffer.toArray)
399  
-        values(indices.head) = value
  374
+      val head = indices.head
  375
+      values(head) match {
  376
+        case xs: Array[Byte] => xs
  377
+        case _               =>
  378
+          val arr: Array[Byte] = indices.toArray flatMap { index =>
  379
+            if (index <= 0 || ConstantPool.this.len <= index) errorBadIndex(index)
  380
+            val start = firstExpecting(index, CONSTANT_UTF8)
  381
+            val len   = in getChar start
  382
+            in.buf drop start + 2 take len
  383
+          }
  384
+          recordAtIndex(getSubArray(arr), head)
400 385
       }
401  
-      value
402 386
     }
403 387
 
404 388
     /** Throws an exception signaling a bad constant index. */
405 389
     private def errorBadIndex(index: Int) =
406  
-      throw new RuntimeException("bad constant pool index: " + index + " at pos: " + in.bp)
  390
+      abort(s"bad constant pool index: $index at pos: ${in.bp}")
407 391
 
408 392
     /** Throws an exception signaling a bad tag at given address. */
409 393
     private def errorBadTag(start: Int) =
410  
-      throw new RuntimeException("bad constant pool tag " + in.buf(start) + " at byte " + start)
  394
+      abort("bad constant pool tag ${in.buf(start)} at byte $start")
411 395
   }
412 396
 
413 397
   /** Try to force the chain of enclosing classes for the given name. Otherwise
@@ -486,30 +470,27 @@ abstract class ClassfileParser {
486 470
       catch { case _: FatalError => loadClassSymbol(name) }
487 471
   }
488 472
 
489  
-  var sawPrivateConstructor = false
490  
-
491 473
   def parseClass() {
492  
-    val jflags       = in.nextChar
493  
-    val isAnnotation = hasAnnotation(jflags)
494  
-    val sflags       = toScalaClassFlags(jflags)
495  
-    val nameIdx      = in.nextChar
496  
-    currentClass     = pool.getClassName(nameIdx)
  474
+    val jflags   = readClassFlags()
  475
+    val sflags   = jflags.toScalaFlags
  476
+    val nameIdx  = u2
  477
+    currentClass = pool.getClassName(nameIdx)
497 478
 
498 479
     /* Parse parents for Java classes. For Scala, return AnyRef, since the real type will be unpickled.
499 480
      * Updates the read pointer of 'in'. */
500 481
     def parseParents: List[Type] = {
501 482
       if (isScala) {
502  
-        in.nextChar              // skip superclass
503  
-        val ifaces = in.nextChar
504  
-        in.bp += ifaces * 2     // .. and iface count interfaces
505  
-        List(definitions.AnyRefClass.tpe) // dummy superclass, will be replaced by pickled information
  483
+        u2                    // skip superclass
  484
+        val ifaces = u2
  485
+        in.bp += ifaces * 2   // .. and iface count interfaces
  486
+        List(AnyRefClass.tpe) // dummy superclass, will be replaced by pickled information
506 487
       }
507 488
       else raiseLoaderLevel {
508  
-        val superType = if (isAnnotation) { in.nextChar; definitions.AnnotationClass.tpe }
509  
-                        else pool.getSuperClass(in.nextChar).tpe_*
510  
-        val ifaceCount = in.nextChar
511  
-        var ifaces = for (i <- List.range(0, ifaceCount)) yield pool.getSuperClass(in.nextChar).tpe_*
512  
-        if (isAnnotation) ifaces = definitions.ClassfileAnnotationClass.tpe :: ifaces
  489
+        val superType = if (jflags.isAnnotation) { u2; AnnotationClass.tpe }
  490
+                        else pool.getSuperClass(u2).tpe_*
  491
+        val ifaceCount = u2
  492
+        var ifaces = for (i <- List.range(0, ifaceCount)) yield pool.getSuperClass(u2).tpe_*
  493
+        if (jflags.isAnnotation) ifaces ::= ClassfileAnnotationClass.tpe
513 494
         superType :: ifaces
514 495
       }
515 496
     }
@@ -539,21 +520,20 @@ abstract class ClassfileParser {
539 520
     skipMembers() // methods
540 521
     if (!isScala) {
541 522
       clazz setFlag sflags
542  
-      importPrivateWithinFromJavaFlags(clazz, jflags)
543  
-      importPrivateWithinFromJavaFlags(staticModule, jflags)
544  
-      clazz.setInfo(classInfo)
  523
+      propagatePackageBoundary(jflags, clazz, staticModule)
  524
+      clazz setInfo classInfo
545 525
       moduleClass setInfo staticInfo
546  
-      staticModule.setInfo(moduleClass.tpe)
547  
-      staticModule.setFlag(JAVA)
548  
-      staticModule.moduleClass.setFlag(JAVA)
  526
+      staticModule setInfo moduleClass.tpe
  527
+      staticModule setFlag JAVA
  528
+      staticModule.moduleClass setFlag JAVA
549 529
       // attributes now depend on having infos set already
550 530
       parseAttributes(clazz, classInfo)
551 531
 
552 532
       def queueLoad() {
553 533
         in.bp = curbp
554  
-        0 until in.nextChar foreach (_ => parseField())
  534
+        0 until u2 foreach (_ => parseField())
555 535
         sawPrivateConstructor = false
556  
-        0 until in.nextChar foreach (_ => parseMethod())
  536
+        0 until u2 foreach (_ => parseMethod())
557 537
         val needsConstructor = (
558 538
              !sawPrivateConstructor
559 539
           && !(instanceScope containsName nme.CONSTRUCTOR)
@@ -589,28 +569,28 @@ abstract class ClassfileParser {
589 569
   }
590 570
 
591 571
   def parseField() {
592  
-    val jflags = in.nextChar
593  
-    val sflags = toScalaFieldFlags(jflags)
594  
-    if ((sflags & PRIVATE) != 0L && !global.settings.optimise) {
  572
+    val jflags = readFieldFlags()
  573
+    val sflags = jflags.toScalaFlags
  574
+
  575
+    if ((sflags & PRIVATE) != 0L && !optimized) {
595 576
       in.skip(4); skipAttributes()
596 577
     } else {
597  
-      val name    = pool.getName(in.nextChar)
598  
-      val info    = pool.getType(in.nextChar)
599  
-      val sym     = getOwner(jflags).newValue(name.toTermName, NoPosition, sflags)
600  
-      val isEnum  = (jflags & JAVA_ACC_ENUM) != 0
  578
+      val name    = readName()
  579
+      val info    = readType()
  580
+      val sym     = ownerForFlags(jflags).newValue(name.toTermName, NoPosition, sflags)
601 581
 
602 582
       // Note: the info may be overrwritten later with a generic signature
603 583
       // parsed from SignatureATTR
604 584
       sym setInfo {
605  
-        if (isEnum) ConstantType(Constant(sym))
  585
+        if (jflags.isEnum) ConstantType(Constant(sym))
606 586
         else info
607 587
       }
608  
-      importPrivateWithinFromJavaFlags(sym, jflags)
  588
+      propagatePackageBoundary(jflags, sym)
609 589
       parseAttributes(sym, info)
610  
-      getScope(jflags).enter(sym)
  590
+      getScope(jflags) enter sym
611 591
 
612 592
       // sealed java enums
613  
-      if (isEnum) {
  593
+      if (jflags.isEnum) {
614 594
         val enumClass = sym.owner.linkedClassOfClass
615 595
         if (!enumClass.isSealed)
616 596
           enumClass setFlag (SEALED | ABSTRACT)
@@ -621,26 +601,27 @@ abstract class ClassfileParser {
621 601
   }
622 602
 
623 603
   def parseMethod() {
624  
-    val jflags = in.nextChar.toInt
625  
-    val sflags = toScalaMethodFlags(jflags)
626  
-    if (isPrivate(jflags) && !global.settings.optimise) {
627  
-      val name = pool.getName(in.nextChar)
  604
+    val jflags = readMethodFlags()
  605
+    val sflags = jflags.toScalaFlags
  606
+    if (jflags.isPrivate && !optimized) {
  607
+      val name = readName()
628 608
       if (name == nme.CONSTRUCTOR)
629 609
         sawPrivateConstructor = true
630 610
       in.skip(2); skipAttributes()
631  
-    } else {
632  
-      if ((sflags & PRIVATE) != 0L && global.settings.optimise) {
  611
+    }
  612
+    else {
  613
+      if ((sflags & PRIVATE) != 0L && optimized) {
633 614
         in.skip(4); skipAttributes()
634 615
       } else {
635  
-        val name = pool.getName(in.nextChar)
636  
-        val sym = getOwner(jflags).newMethod(name.toTermName, NoPosition, sflags)
637  
-        var info = pool.getType(sym, (in.nextChar))
  616
+        val name = readName()
  617
+        val sym = ownerForFlags(jflags).newMethod(name.toTermName, NoPosition, sflags)
  618
+        var info = pool.getType(sym, u2)
638 619
         if (name == nme.CONSTRUCTOR)
639 620
           info match {
640 621
             case MethodType(params, restpe) =>
641 622
               // if this is a non-static inner class, remove the explicit outer parameter
642 623
               val newParams = innerClasses getEntry currentClass match {
643  
-                case Some(entry) if !isScalaRaw && !isStatic(entry.jflags) =>
  624
+                case Some(entry) if !isScalaRaw && !entry.jflags.isStatic =>
644 625
                   /* About `clazz.owner.isPackage` below: SI-5957
645 626
                    * For every nested java class A$B, there are two symbols in the scala compiler.
646 627
                    *  1. created by SymbolLoader, because of the existence of the A$B.class file, owner: package
@@ -657,13 +638,13 @@ abstract class ClassfileParser {
657 638
           }
658 639
         // Note: the info may be overrwritten later with a generic signature
659 640
         // parsed from SignatureATTR
660  
-        sym.setInfo(info)
661  
-        importPrivateWithinFromJavaFlags(sym, jflags)
  641
+        sym setInfo info
  642
+        propagatePackageBoundary(jflags, sym)
662 643
         parseAttributes(sym, info)
663  
-        if ((jflags & JAVA_ACC_VARARGS) != 0) {
664  
-          sym.setInfo(arrayToRepeated(sym.info))
665  
-        }
666  
-        getScope(jflags).enter(sym)
  644
+        if (jflags.isVarargs)
  645
+          sym modifyInfo arrayToRepeated
  646
+
  647
+        getScope(jflags) enter sym
667 648
       }
668 649
     }
669 650
   }
@@ -683,15 +664,15 @@ abstract class ClassfileParser {
683 664
     def sig2type(tparams: immutable.Map[Name,Symbol], skiptvs: Boolean): Type = {
684 665
       val tag = sig.charAt(index); index += 1
685 666
       tag match {
686  
-        case BYTE_TAG   => definitions.ByteClass.tpe
687  
-        case CHAR_TAG   => definitions.CharClass.tpe
688  
-        case DOUBLE_TAG => definitions.DoubleClass.tpe
689  
-        case FLOAT_TAG  => definitions.FloatClass.tpe
690  
-        case INT_TAG    => definitions.IntClass.tpe
691  
-        case LONG_TAG   => definitions.LongClass.tpe
692  
-        case SHORT_TAG  => definitions.ShortClass.tpe
693  
-        case VOID_TAG   => definitions.UnitClass.tpe
694  
-        case BOOL_TAG   => definitions.BooleanClass.tpe
  667
+        case BYTE_TAG   => ByteClass.tpe
  668
+        case CHAR_TAG   => CharClass.tpe
  669
+        case DOUBLE_TAG => DoubleClass.tpe
  670
+        case FLOAT_TAG  => FloatClass.tpe
  671
+        case INT_TAG    => IntClass.tpe
  672
+        case LONG_TAG   => LongClass.tpe
  673
+        case SHORT_TAG  => ShortClass.tpe
  674
+        case VOID_TAG   => UnitClass.tpe
  675
+        case BOOL_TAG   => BooleanClass.tpe
695 676
         case 'L' =>
696 677
           def processInner(tp: Type): Type = tp match {
697 678
             case TypeRef(pre, sym, args) if (!sym.isStatic) =>
@@ -716,7 +697,7 @@ abstract class ClassfileParser {
716 697
                           val tp = sig2type(tparams, skiptvs)
717 698
                           // sig2type seems to return AnyClass regardless of the situation:
718 699
                           // we don't want Any as a LOWER bound.
719  
-                          if (tp.typeSymbol == definitions.AnyClass) TypeBounds.empty
  700
+                          if (tp.typeSymbol == AnyClass) TypeBounds.empty
720 701
                           else TypeBounds.lower(tp)
721 702
                         case '*' => TypeBounds.empty
722 703
                       }
@@ -737,7 +718,7 @@ abstract class ClassfileParser {
737 718
               // or we'll create a boatload of needless existentials.
738 719
               else if (classSym.isMonomorphicType || classSym.unsafeTypeParams.isEmpty) tp
739 720
               // raw type - existentially quantify all type parameters
740  
-              else logResult(s"raw type from $classSym")(definitions.unsafeClassExistentialType(classSym))
  721
+              else logResult(s"raw type from $classSym")(unsafeClassExistentialType(classSym))
741 722
             case tp =>
742 723
               assert(sig.charAt(index) != '<', s"sig=$sig, index=$index, tp=$tp")
743 724
               tp
@@ -765,11 +746,11 @@ abstract class ClassfileParser {
765 746
           // NOTE that the comparison to Object only works for abstract types bounded by classes that are strict subclasses of Object
766 747
           // if the bound is exactly Object, it will have been converted to Any, and the comparison will fail
767 748
           // see also RestrictJavaArraysMap (when compiling java sources directly)
768  
-          if (elemtp.typeSymbol.isAbstractType && !(elemtp <:< definitions.ObjectClass.tpe)) {
769  
-            elemtp = intersectionType(List(elemtp, definitions.ObjectClass.tpe))
  749
+          if (elemtp.typeSymbol.isAbstractType && !(elemtp <:< ObjectClass.tpe)) {
  750
+            elemtp = intersectionType(List(elemtp, ObjectClass.tpe))
770 751
           }
771 752
 
772  
-          definitions.arrayType(elemtp)
  753
+          arrayType(elemtp)
773 754
         case '(' =>
774 755
           // we need a method symbol. given in line 486 by calling getType(methodSym, ..)
775 756
           assert(sym ne null, sig)
@@ -787,7 +768,7 @@ abstract class ClassfileParser {
787 768
         case 'T' =>
788 769
           val n = subName(';'.==).toTypeName
789 770
           index += 1
790  
-          if (skiptvs) definitions.AnyClass.tpe
  771
+          if (skiptvs) AnyClass.tpe
791 772
           else tparams(n).typeConstructor
792 773
       }
793 774
     } // sig2type(tparams, skiptvs)
@@ -840,24 +821,20 @@ abstract class ClassfileParser {
840 821
     GenPolyType(ownTypeParams, tpe)
841 822
   } // sigToType
842 823
 
843  
-  class TypeParamsType(override val typeParams: List[Symbol]) extends LazyType with FlagAgnosticCompleter {
844  
-    override def complete(sym: Symbol) { throw new AssertionError("cyclic type dereferencing") }
845  
-  }
846  
-
847 824
   def parseAttributes(sym: Symbol, symtype: Type) {
848 825
     def convertTo(c: Constant, pt: Type): Constant = {
849  
-      if (pt.typeSymbol == definitions.BooleanClass && c.tag == IntTag)
  826
+      if (pt.typeSymbol == BooleanClass && c.tag == IntTag)
850 827
         Constant(c.value != 0)
851 828
       else
852 829
         c convertTo pt
853 830
     }
854 831
     def parseAttribute() {
855  
-      val attrName = pool.getName(in.nextChar).toTypeName
856  
-      val attrLen = in.nextInt
  832
+      val attrName = readTypeName()
  833
+      val attrLen  = u4
857 834
       attrName match {
858 835
         case tpnme.SignatureATTR =>
859 836
           if (!isScala && !isScalaRaw) {
860  
-            val sig = pool.getExternalName(in.nextChar)
  837
+            val sig = pool.getExternalName(u2)
861 838
             val newType = sigToType(sym, sig)
862 839
             sym.setInfo(newType)
863 840
             if (settings.debug && settings.verbose)
@@ -872,10 +849,10 @@ abstract class ClassfileParser {
872 849
           in.skip(attrLen)
873 850
         case tpnme.DeprecatedATTR =>
874 851
           val arg = Literal(Constant("see corresponding Javadoc for more information."))
875  
-          sym.addAnnotation(definitions.DeprecatedAttr, arg, Literal(Constant("")))
  852
+          sym.addAnnotation(DeprecatedAttr, arg, Literal(Constant("")))
876 853
           in.skip(attrLen)
877 854
         case tpnme.ConstantValueATTR =>
878  
-          val c = pool.getConstant(in.nextChar)
  855
+          val c = pool.getConstant(u2)
879 856
           val c1 = convertTo(c, symtype)
880 857
           if (c1 ne null) sym.setInfo(ConstantType(c1))
881 858
           else println("failure to convert " + c + " to " + symtype); //debug
@@ -889,7 +866,7 @@ abstract class ClassfileParser {
889 866
           isScalaRaw = true
890 867
          // Attribute on methods of java annotation classes when that method has a default
891 868
         case tpnme.AnnotationDefaultATTR =>
892  
-          sym.addAnnotation(definitions.AnnotationDefaultAttr)
  869
+          sym.addAnnotation(AnnotationDefaultAttr)
893 870
           in.skip(attrLen)
894 871
         // Java annotations on classes / methods / fields with RetentionPolicy.RUNTIME
895 872
         case tpnme.RuntimeAnnotationATTR =>
@@ -919,7 +896,7 @@ abstract class ClassfileParser {
919 896
           parseExceptions(attrLen)
920 897
 
921 898
         case tpnme.SourceFileATTR =>
922  
-          val srcfileLeaf = pool.getName(in.nextChar).toString.trim
  899
+          val srcfileLeaf = readName().toString.trim
923 900
           val srcpath = sym.enclosingPackage match {
924 901
             case NoSymbol => srcfileLeaf
925 902
             case rootMirror.EmptyPackage => srcfileLeaf
@@ -932,8 +909,8 @@ abstract class ClassfileParser {
932 909
     }
933 910
 
934 911
     def parseAnnotArg: Option[ClassfileAnnotArg] = {
935  
-      val tag = in.nextByte.toChar
936  
-      val index = in.nextChar
  912
+      val tag = u1
  913
+      val index = u2
937 914
       tag match {
938 915
         case STRING_TAG =>
939 916
           Some(LiteralAnnotArg(Constant(pool.getName(index).toString)))
@@ -944,7 +921,7 @@ abstract class ClassfileParser {
944 921
           Some(LiteralAnnotArg(Constant(pool.getType(index))))
945 922
         case ENUM_TAG   =>
946 923
           val t = pool.getType(index)
947  
-          val n = pool.getName(in.nextChar)
  924
+          val n = readName()
948 925
           val s = t.typeSymbol.companionModule.info.decls.lookup(n)
949 926
           assert(s != NoSymbol, t)
950 927
           Some(LiteralAnnotArg(Constant(s)))
@@ -964,20 +941,20 @@ abstract class ClassfileParser {
964 941
     }
965 942
 
966 943
     def parseScalaSigBytes: Option[ScalaSigBytes] = {
967  
-      val tag = in.nextByte.toChar
  944
+      val tag = u1
968 945
       assert(tag == STRING_TAG, tag)
969  
-      Some(ScalaSigBytes(pool getBytes in.nextChar))
  946
+      Some(ScalaSigBytes(pool getBytes u2))
970 947
     }
971 948
 
972 949
     def parseScalaLongSigBytes: Option[ScalaSigBytes] = {
973  
-      val tag = in.nextByte.toChar
  950
+      val tag = u1
974 951
       assert(tag == ARRAY_TAG, tag)
975  
-      val stringCount = in.nextChar
  952
+      val stringCount = u2
976 953
       val entries =
977 954
         for (i <- 0 until stringCount) yield {
978  
-          val stag = in.nextByte.toChar
  955
+          val stag = u1
979 956
           assert(stag == STRING_TAG, stag)
980  
-          in.nextChar.toInt
  957
+          u2.toInt
981 958
         }
982 959
       Some(ScalaSigBytes(pool.getBytes(entries.toList)))
983 960
     }
@@ -987,20 +964,20 @@ abstract class ClassfileParser {
987 964
      */
988 965
     def parseAnnotation(attrNameIndex: Char): Option[AnnotationInfo] = try {
989 966
       val attrType = pool.getType(attrNameIndex)
990  
-      val nargs = in.nextChar
  967
+      val nargs = u2
991 968
       val nvpairs = new ListBuffer[(Name, ClassfileAnnotArg)]
992 969
       var hasError = false
993 970
       for (i <- 0 until nargs) {
994  
-        val name = pool.getName(in.nextChar)
  971
+        val name = readName()
995 972
         // The "bytes: String" argument of the ScalaSignature attribute is parsed specially so that it is
996 973
         // available as an array of bytes (the pickled Scala signature) instead of as a string. The pickled signature
997 974
         // is encoded as a string because of limitations in the Java class file format.
998  
-        if ((attrType == definitions.ScalaSignatureAnnotation.tpe) && (name == nme.bytes))
  975
+        if ((attrType == ScalaSignatureAnnotation.tpe) && (name == nme.bytes))
999 976
           parseScalaSigBytes match {
1000 977
             case Some(c) => nvpairs += ((name, c))
1001 978
             case None => hasError = true
1002 979
           }
1003  
-        else if ((attrType == definitions.ScalaLongSignatureAnnotation.tpe) && (name == nme.bytes))
  980
+        else if ((attrType == ScalaLongSignatureAnnotation.tpe) && (name == nme.bytes))
1004 981
           parseScalaLongSigBytes match {
1005 982
             case Some(c) => nvpairs += ((name, c))
1006 983
             case None => hasError = true
@@ -1033,10 +1010,10 @@ abstract class ClassfileParser {
1033 1010
      * thrown by a method.
1034 1011
      */
1035 1012
     def parseExceptions(len: Int) {
1036  
-      val nClasses = in.nextChar
  1013
+      val nClasses = u2
1037 1014
       for (n <- 0 until nClasses) {
1038 1015
         // FIXME: this performs an equivalent of getExceptionTypes instead of getGenericExceptionTypes (SI-7065)
1039  
-        val cls = pool.getClassSymbol(in.nextChar.toInt)
  1016
+        val cls = pool.getClassSymbol(u2)
1040 1017
         // we call initialize due to the fact that we call Symbol.isMonomorphicType in addThrowsAnnotation
1041 1018
         // and that method requires Symbol to be forced to give the right answers, see SI-7107 for details
1042 1019
         cls.initialize
@@ -1047,13 +1024,13 @@ abstract class ClassfileParser {
1047 1024
     /* Parse a sequence of annotations and attaches them to the
1048 1025
      * current symbol sym, except for the ScalaSignature annotation that it returns, if it is available. */
1049 1026
     def parseAnnotations(len: Int): Option[AnnotationInfo] =  {
1050  
-      val nAttr = in.nextChar
  1027
+      val nAttr = u2
1051 1028
       var scalaSigAnnot: Option[AnnotationInfo] = None
1052 1029
       for (n <- 0 until nAttr)
1053  
-        parseAnnotation(in.nextChar) match {
1054  
-          case Some(scalaSig) if (scalaSig.atp == definitions.ScalaSignatureAnnotation.tpe) =>
  1030
+        parseAnnotation(u2) match {
  1031
+          case Some(scalaSig) if (scalaSig.atp == ScalaSignatureAnnotation.tpe) =>
1055 1032
             scalaSigAnnot = Some(scalaSig)
1056  
-          case Some(scalaSig) if (scalaSig.atp == definitions.ScalaLongSignatureAnnotation.tpe) =>
  1033
+          case Some(scalaSig) if (scalaSig.atp == ScalaLongSignatureAnnotation.tpe) =>
1057 1034
             scalaSigAnnot = Some(scalaSig)
1058 1035
           case Some(annot) =>
1059 1036
             sym.addAnnotation(annot)
@@ -1063,7 +1040,7 @@ abstract class ClassfileParser {
1063 1040
     }
1064 1041
 
1065 1042
     // begin parseAttributes
1066  
-    for (i <- 0 until in.nextChar) parseAttribute()
  1043
+    for (i <- 0 until u2) parseAttribute()
1067 1044
   }
1068 1045
 
1069 1046
   /** Enter own inner classes in the right scope. It needs the scopes to be set up,
@@ -1073,11 +1050,12 @@ abstract class ClassfileParser {
1073 1050
     def className(name: Name): Name =
1074 1051
       name.subName(name.lastPos('.') + 1, name.length)
1075 1052
 
1076  
-    def enterClassAndModule(entry: InnerClassEntry, file: AbstractFile, jflags: Int) {
  1053
+    def enterClassAndModule(entry: InnerClassEntry, file: AbstractFile) {
  1054
+      def jflags      = entry.jflags
1077 1055
       val completer   = new global.loaders.ClassfileLoader(file)
1078 1056
       val name        = entry.originalName
1079  
-      val sflags      = toScalaClassFlags(jflags)
1080  
-      val owner       = getOwner(jflags)
  1057
+      val sflags      = jflags.toScalaFlags
  1058
+      val owner       = ownerForFlags(jflags)
1081 1059
       val scope       = getScope(jflags)
1082 1060
       val innerClass  = owner.newClass(name.toTypeName, NoPosition, sflags) setInfo completer
1083 1061
       val innerModule = owner.newModule(name.toTermName, NoPosition, sflags) setInfo completer
@@ -1106,7 +1084,7 @@ abstract class ClassfileParser {
1106 1084
         val file = global.classPath.findSourceFile(entry.externalName.toString) getOrElse {
1107 1085
           throw new AssertionError(entry.externalName)
1108 1086
         }
1109  
-        enterClassAndModule(entry, file, entry.jflags)
  1087
+        enterClassAndModule(entry, file)
1110 1088
       }
1111 1089
     }
1112 1090
   }
@@ -1119,10 +1097,10 @@ abstract class ClassfileParser {
1119 1097
     skipSuperclasses()
1120 1098
     skipMembers() // fields
1121 1099
     skipMembers() // methods
1122  
-    val attrs = in.nextChar
  1100
+    val attrs = u2
1123 1101
     for (i <- 0 until attrs) {
1124  
-      val attrName = pool.getName(in.nextChar).toTypeName
1125  
-      val attrLen = in.nextInt
  1102
+      val attrName = readTypeName()
  1103
+      val attrLen = u4
1126 1104
       attrName match {
1127 1105
         case tpnme.SignatureATTR =>
1128 1106
           in.skip(attrLen)
@@ -1136,9 +1114,10 @@ abstract class ClassfileParser {
1136 1114
         case tpnme.ScalaATTR =>
1137 1115
           isScalaRaw = true
1138 1116
         case tpnme.InnerClassesATTR if !isScala =>
1139  
-          val entries = in.nextChar.toInt
  1117
+          val entries = u2
1140 1118
           for (i <- 0 until entries) {
1141  
-            val innerIndex, outerIndex, nameIndex, jflags = in.nextChar.toInt
  1119
+            val innerIndex, outerIndex, nameIndex = u2
  1120
+            val jflags = readInnerClassFlags()
1142 1121
             if (innerIndex != 0 && outerIndex != 0 && nameIndex != 0)
1143 1122
               innerClasses add InnerClassEntry(innerIndex, outerIndex, nameIndex, jflags)
1144 1123
           }
@@ -1150,14 +1129,13 @@ abstract class ClassfileParser {
1150 1129
   }
1151 1130
 
1152 1131
   /** An entry in the InnerClasses attribute of this class file. */
1153  
-  case class InnerClassEntry(external: Int, outer: Int, name: Int, jflags: Int) {
  1132
+  case class InnerClassEntry(external: Int, outer: Int, name: Int, jflags: JavaAccFlags) {
1154 1133
     def externalName = pool getClassName external
1155 1134
     def outerName    = pool getClassName outer
1156 1135
     def originalName = pool getName name
1157  
-    def isStatic     = ClassfileParser.this.isStatic(jflags)
1158 1136
     def isModule     = originalName.isTermName
1159  
-    def scope        = if (isStatic) staticScope else instanceScope
1160  
-    def enclosing    = if (isStatic) enclModule else enclClass
  1137
+    def scope        = if (jflags.isStatic) staticScope else instanceScope
  1138
+    def enclosing    = if (jflags.isStatic) enclModule else enclClass
1161 1139
 
1162 1140
     // The name of the outer class, without its trailing $ if it has one.
1163 1141
     private def strippedOuter = nme stripModuleSuffix outerName
@@ -1209,6 +1187,9 @@ abstract class ClassfileParser {
1209 1187
     }
1210 1188
   }
1211 1189
 
  1190
+  class TypeParamsType(override val typeParams: List[Symbol]) extends LazyType with FlagAgnosticCompleter {
  1191
+    override def complete(sym: Symbol) { throw new AssertionError("cyclic type dereferencing") }
  1192
+  }
1212 1193
   class LazyAliasType(alias: Symbol) extends LazyType with FlagAgnosticCompleter {
1213 1194
     override def complete(sym: Symbol) {
1214 1195
       sym setInfo createFromClonedSymbols(alias.initialize.typeParams, alias.tpe)(typeFun)
@@ -1216,16 +1197,16 @@ abstract class ClassfileParser {
1216 1197
   }
1217 1198
 
1218 1199
   def skipAttributes() {
1219  
-    var attrCount: Int = in.nextChar
  1200
+    var attrCount: Int = u2
1220 1201
     while (attrCount > 0) {
1221 1202
       in skip 2
1222  
-      in skip in.nextInt
  1203
+      in skip u4
1223 1204
       attrCount -= 1
1224 1205
     }
1225 1206
   }
1226 1207
 
1227 1208
   def skipMembers() {
1228  
-    var memberCount: Int = in.nextChar
  1209
+    var memberCount: Int = u2
1229 1210
     while (memberCount > 0) {
1230 1211
       in skip 6
1231 1212
       skipAttributes()
@@ -1235,17 +1216,10 @@ abstract class ClassfileParser {
1235 1216
 
1236 1217
   def skipSuperclasses() {
1237 1218
     in.skip(2) // superclass
1238  
-    val ifaces = in.nextChar
  1219
+    val ifaces = u2
1239 1220
     in.skip(2 * ifaces)
1240 1221
   }
1241 1222
 
1242  
-  protected def getOwner(flags: Int): Symbol =
1243  
-    if (isStatic(flags)) moduleClass else clazz
1244  
-
1245  
-  protected def getScope(flags: Int): Scope =
1246  
-    if (isStatic(flags)) staticScope else instanceScope
1247  
-
1248  
-  private def isPrivate(flags: Int)     = (flags & JAVA_ACC_PRIVATE) != 0
1249  
-  private def isStatic(flags: Int)      = (flags & JAVA_ACC_STATIC) != 0
1250  
-  private def hasAnnotation(flags: Int) = (flags & JAVA_ACC_ANNOTATION) != 0
  1223
+  protected def getScope(flags: JavaAccFlags): Scope =
  1224
+    if (flags.isStatic) staticScope else instanceScope
1251 1225
 }
179  src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -10,6 +10,7 @@ package classfile
10 10
 import scala.collection.{ mutable, immutable }
11 11
 import mutable.ListBuffer
12 12
 import ClassfileConstants._
  13
+import scala.reflect.internal.JavaAccFlags
13 14
 
14 15
 /** ICode reader from Java bytecode.
15 16
  *
@@ -45,26 +46,19 @@ abstract class ICodeReader extends ClassfileParser {
45 46
     (staticCode, instanceCode)
46 47
   }
47 48
 
48  
-  /** If we're parsing a scala module, the owner of members is always
49  
-   *  the module symbol.
50  
-   */
51  
-  override def getOwner(jflags: Int): Symbol =
52  
-    if (isScalaModule) this.staticModule
53  
-    else super.getOwner(jflags)
54  
-
55 49
   override def parseClass() {
56 50
     this.instanceCode = new IClass(clazz)
57 51
     this.staticCode   = new IClass(staticModule)
58 52
 
59  
-    in.nextChar
60  
-    pool getClassSymbol in.nextChar
  53
+    u2
  54
+    pool getClassSymbol u2
61 55
     parseInnerClasses()
62 56
 
63 57
     in.skip(2)               // super class
64  
-    in.skip(2 * in.nextChar) // interfaces
65  
-    val fieldCount = in.nextChar
  58
+    in.skip(2 * u2) // interfaces
  59
+    val fieldCount = u2
66 60
     for (i <- 0 until fieldCount) parseField()
67  
-    val methodCount = in.nextChar
  61
+    val methodCount = u2
68 62
     for (i <- 0 until methodCount) parseMethod()
69 63
     instanceCode.methods = instanceCode.methods.reverse
70 64
     staticCode.methods = staticCode.methods.reverse
@@ -76,25 +70,31 @@ abstract class ICodeReader extends ClassfileParser {
76 70
     skipAttributes()
77 71
   }
78 72
 
79  
-  private def parseMember(field: Boolean): (Int, Symbol) = {
80  
-    val jflags   = in.nextChar
81  
-    val name     = pool getName in.nextChar
82  
-    val owner    = getOwner(jflags)
83  
-    val dummySym = owner.newMethod(name.toTermName, owner.pos, toScalaMethodFlags(jflags))
  73
+  private def parseMember(field: Boolean): (JavaAccFlags, Symbol) = {
  74
+    val jflags   = JavaAccFlags(u2)
  75
+    val name     = pool getName u2
  76
+    /** If we're parsing a scala module, the owner of members is always
  77
+     *  the module symbol.
  78
+     */
  79
+    val owner = (
  80
+      if (isScalaModule) staticModule
  81
+      else if (jflags.isStatic) moduleClass
  82
+      else clazz
  83
+    )
  84
+    val dummySym = owner.newMethod(name.toTermName, owner.pos, jflags.toScalaFlags)
84 85
 
85 86
     try {
86  
-      val ch  = in.nextChar
  87
+      val ch  = u2
87 88
       val tpe = pool.getType(dummySym, ch)
88 89
 
89 90
       if ("<clinit>" == name.toString)
90 91
         (jflags, NoSymbol)
91 92
       else {
92  
-        val owner = getOwner(jflags)
93 93
         var sym = owner.info.findMember(name, 0, 0, stableOnly = false).suchThat(old => sameType(old.tpe, tpe))
94 94
         if (sym == NoSymbol)
95 95
           sym = owner.info.findMember(newTermName(name + nme.LOCAL_SUFFIX_STRING), 0, 0, stableOnly = false).suchThat(_.tpe =:= tpe)
96 96
         if (sym == NoSymbol) {
97  
-          sym = if (field) owner.newValue(name.toTermName, owner.pos, toScalaFieldFlags(jflags)) else dummySym
  97
+          sym = if (field) owner.newValue(name.toTermName, owner.pos, jflags.toScalaFlags) else dummySym
98 98
           sym setInfoAndEnter tpe
99 99
           log(s"ICodeReader could not locate ${name.decode} in $owner.  Created ${sym.defString}.")
100 100
         }
@@ -126,9 +126,9 @@ abstract class ICodeReader extends ClassfileParser {
126 126
         this.method = new IMethod(sym)
127 127
         this.method.returnType = toTypeKind(sym.tpe.resultType)
128 128
         getCode(jflags).addMethod(this.method)
129  
-        if ((jflags & JAVA_ACC_NATIVE) != 0)
  129
+        if (jflags.isNative)
130 130
           this.method.native = true