scala.tools.nsc.backend.jvm.GenAndroid.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scala-compiler Show documentation
Show all versions of scala-compiler Show documentation
Compiler for the Scala Programming Language
/* NSC -- new Scala compiler
* Copyright 2005-2013 LAMP/EPFL
* @author Stephane Micheloud
*/
package scala.tools.nsc
package backend.jvm
import ch.epfl.lamp.fjbg._
import symtab.Flags
trait GenAndroid {
self: GenJVM =>
import global._
import icodes._
import opcodes._
/** From the reference documentation of the Android SDK:
* The `Parcelable` interface identifies classes whose instances can be
* written to and restored from a `Parcel`. Classes implementing the
* `Parcelable` interface must also have a static field called `CREATOR`,
* which is an object implementing the `Parcelable.Creator` interface.
*/
private val fieldName = newTermName("CREATOR")
private lazy val AndroidParcelableInterface = rootMirror.getClassIfDefined("android.os.Parcelable")
private lazy val AndroidCreatorClass = rootMirror.getClassIfDefined("android.os.Parcelable$Creator")
def isAndroidParcelableClass(sym: Symbol) =
(AndroidParcelableInterface != NoSymbol) &&
(sym.parentSymbols contains AndroidParcelableInterface)
def addCreatorCode(codegen: BytecodeGenerator, block: BasicBlock) {
import codegen._
val fieldSymbol = (
clasz.symbol.newValue(newTermName(fieldName), NoPosition, Flags.STATIC | Flags.FINAL)
setInfo AndroidCreatorClass.tpe
)
val methodSymbol = definitions.getMember(clasz.symbol.companionModule, fieldName)
clasz addField new IField(fieldSymbol)
block emit CALL_METHOD(methodSymbol, Static(false))
block emit STORE_FIELD(fieldSymbol, true)
}
def legacyAddCreatorCode(codegen: BytecodeGenerator, clinit: JExtendedCode) {
import codegen._
val creatorType = javaType(AndroidCreatorClass)
jclass.addNewField(PublicStaticFinal,
fieldName,
creatorType)
val moduleName = javaName(clasz.symbol)+"$"
clinit.emitGETSTATIC(moduleName,
nme.MODULE_INSTANCE_FIELD.toString,
new JObjectType(moduleName))
clinit.emitINVOKEVIRTUAL(moduleName, fieldName,
new JMethodType(creatorType, Array()))
clinit.emitPUTSTATIC(jclass.getName(), fieldName, creatorType)
}
}