From 7be7786a67323b5c138eab650c9bf0d23924a688 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Mon, 9 Mar 2015 14:20:17 +1000 Subject: SI-8359 Emit invokedynamic for lambdas Suitable lambdas are identified in Delambdafy and marked with such with a tree annotation that includes the data needed by the backend to emit an invokedynamic instruction. GenBCode to rewrite instantiation of such anonymous function classes with an invokedynamic instruction. At this stage, I don't plan to merge the support for this into GenASM. Between these points, the lambda capture is represented as an application of a dummy factory symbol: ``` (captures...) : FunctionN ``` Demo: ``` % wget http://central.maven.org/maven2/org/scala-lang/modules/scala-java8-compat_2.11/0.3.0/scala-java8-compat_2.11-0.3.0.jar % qscala -classpath scala-java8-compat_2.11-0.3.0.jar -Ydelambdafy:method -target:jvm-1.8 -Ybackend:GenBCode Welcome to Scala version 2.11.6-20150309-144147-c91c978c81 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_25). Type in expressions to have them evaluated. Type :help for more information. scala> (() => "").getClass res0: Class[_ <: () => String] = class $$Lambda$1/871790326 ``` I have also corrected an error in a previous commit. The newly added symbol test, `isDelambdafyTarget`, needs to check for the `ARTIFACT` flag, as that is what is added to the method by `Uncurry`. --- .../tools/nsc/backend/jvm/BCodeBodyBuilder.scala | 39 +++++++++++++ .../tools/nsc/backend/jvm/BCodeIdiomatic.scala | 3 + .../scala/tools/nsc/transform/Delambdafy.scala | 65 ++++++++++++++++++---- .../scala/reflect/internal/Definitions.scala | 4 ++ src/reflect/scala/reflect/internal/Symbols.scala | 2 +- 5 files changed, 101 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala index 15b014bdd3..8ebe27e61b 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala @@ -10,6 +10,7 @@ package backend package jvm import scala.annotation.switch +import scala.reflect.internal.Flags import scala.tools.asm import GenBCode._ @@ -632,6 +633,10 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { case _ => abort(s"Cannot instantiate $tpt of kind: $generatedType") } + case Apply(_, args) if app.hasAttachment[delambdafy.LambdaMetaFactoryCapable] => + val attachment = app.attachments.get[delambdafy.LambdaMetaFactoryCapable].get + genLoadArguments(args, paramTKs(app)) + genInvokeDynamicLambda(attachment.target, attachment.arity, attachment.functionalInterface) case Apply(fun @ _, List(expr)) if currentRun.runDefinitions.isBox(fun.symbol) => val nativeKind = tpeTK(expr) @@ -1280,6 +1285,40 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder { def genSynchronized(tree: Apply, expectedType: BType): BType def genLoadTry(tree: Try): BType + def genInvokeDynamicLambda(lambdaTarget: Symbol, arity: Int, functionalInterface: Symbol) { + val isStaticMethod = lambdaTarget.hasFlag(Flags.STATIC) + + val targetHandle = + new asm.Handle(if (lambdaTarget.hasFlag(Flags.STATIC)) asm.Opcodes.H_INVOKESTATIC else asm.Opcodes.H_INVOKEVIRTUAL, + classBTypeFromSymbol(lambdaTarget.owner).internalName, + lambdaTarget.name.toString, + asmMethodType(lambdaTarget).descriptor) + val receiver = if (isStaticMethod) None else Some(lambdaTarget.owner) + val (capturedParams, lambdaParams) = lambdaTarget.paramss.head.splitAt(lambdaTarget.paramss.head.length - arity) + // Requires https://github.com/scala/scala-java8-compat on the runtime classpath + val returnUnit = lambdaTarget.info.resultType.typeSymbol == UnitClass + val functionalInterfaceDesc: String = classBTypeFromSymbol(functionalInterface).descriptor + val desc = (receiver.toList ::: capturedParams).map(sym => toTypeKind(sym.info)).mkString(("("), "", ")") + functionalInterfaceDesc + + // TODO specialization + val constrainedType = new MethodBType(lambdaParams.map(p => toTypeKind(p.tpe)), toTypeKind(lambdaTarget.tpe.resultType)).toASMType + val abstractMethod = functionalInterface.info.decls.find(_.isDeferred).getOrElse(functionalInterface.info.member(nme.apply)) + val methodName = abstractMethod.name.toString + val applyN = { + val mt = asmMethodType(abstractMethod) + mt.toASMType + } + + bc.jmethod.visitInvokeDynamicInsn(methodName, desc, lambdaMetaFactoryBootstrapHandle, + // boostrap args + applyN, targetHandle, constrainedType + ) + } } + val lambdaMetaFactoryBootstrapHandle = + new asm.Handle(asm.Opcodes.H_INVOKESTATIC, + "java/lang/invoke/LambdaMetafactory", "metafactory", + "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;") + } diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala index 9993357eee..8f2a17a2bf 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeIdiomatic.scala @@ -412,6 +412,9 @@ abstract class BCodeIdiomatic extends SubComponent { jmethod.instructions.add(node) if (settings.YoptInlinerEnabled) callsitePositions(node) = pos } + final def invokedynamic(owner: String, name: String, desc: String) { + jmethod.visitMethodInsn(Opcodes.INVOKEDYNAMIC, owner, name, desc) + } // can-multi-thread final def goTo(label: asm.Label) { jmethod.visitJumpInsn(Opcodes.GOTO, label) } diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala index 2d33b35241..315d96d2e9 100644 --- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala +++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala @@ -79,6 +79,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre sealed abstract class TransformedFunction // A class definition for the lambda, an expression insantiating the lambda class case class DelambdafyAnonClass(lambdaClassDef: ClassDef, newExpr: Tree) extends TransformedFunction + case class InvokeDynamicLambda(tree: Apply) extends TransformedFunction // here's the main entry point of the transform override def transform(tree: Tree): Tree = tree match { @@ -93,6 +94,9 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre lambdaClassDefs(pkg) = lambdaClassDef :: lambdaClassDefs(pkg) super.transform(newExpr) + case InvokeDynamicLambda(apply) => + // ... or an invokedynamic call + super.transform(apply) } case _ => super.transform(tree) } @@ -124,6 +128,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre if (!thisReferringMethods.contains(target)) target setFlag STATIC + val isStatic = target.hasFlag(STATIC) /** * Creates the apply method for the anonymous subclass of FunctionN @@ -199,7 +204,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre val abstractFunctionErasedType = AbstractFunctionClass(formals.length).tpe // anonymous subclass of FunctionN with an apply method - def makeAnonymousClass = { + def makeAnonymousClass: ClassDef = { val parents = addSerializable(abstractFunctionErasedType) val funOwner = originalFunction.symbol.owner @@ -232,7 +237,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre // the Optional proxy that will hold a reference to the 'this' // object used by the lambda, if any. NoSymbol if there is no this proxy val thisProxy = { - if (target.hasFlag(STATIC)) + if (isStatic) NoSymbol else { val sym = lambdaClass.newVariable(nme.FAKE_LOCAL_THIS, originalFunction.pos, SYNTHETIC) @@ -271,22 +276,58 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre val body = members ++ List(constr, applyMethodDef) ++ bridgeMethod // TODO if member fields are private this complains that they're not accessible - (localTyper.typedPos(decapturedFunction.pos)(ClassDef(lambdaClass, body)).asInstanceOf[ClassDef], thisProxy) + localTyper.typedPos(decapturedFunction.pos)(ClassDef(lambdaClass, body)).asInstanceOf[ClassDef] } - val (anonymousClassDef, thisProxy) = makeAnonymousClass + val useLambdaMetafactory = { + val hasValueClass = exitingErasure { + val methodType: Type = targetMethod(originalFunction).info + methodType.exists(_.isInstanceOf[ErasedValueType]) + } + val isTarget18 = settings.target.value.contains("jvm-1.8") + settings.isBCodeActive && isTarget18 && !hasValueClass + } + + val thisArg = if (isStatic) Nil else (gen.mkAttributedThis(oldClass) setPos originalFunction.pos) :: Nil - pkg.info.decls enter anonymousClassDef.symbol + def anonClass: TransformedFunction = { + val anonymousClassDef = makeAnonymousClass + pkg.info.decls enter anonymousClassDef.symbol + val captureArgs = captures map (capture => Ident(capture) setPos originalFunction.pos) - val thisArg = optionSymbol(thisProxy) map (_ => gen.mkAttributedThis(oldClass) setPos originalFunction.pos) - val captureArgs = captures map (capture => Ident(capture) setPos originalFunction.pos) + val newStat = + Typed(New(anonymousClassDef.symbol, thisArg ++ captureArgs: _*), TypeTree(abstractFunctionErasedType)) - val newStat = - Typed(New(anonymousClassDef.symbol, (thisArg.toList ++ captureArgs): _*), TypeTree(abstractFunctionErasedType)) + val typedNewStat = localTyper.typedPos(originalFunction.pos)(newStat) - val typedNewStat = localTyper.typedPos(originalFunction.pos)(newStat) + DelambdafyAnonClass(anonymousClassDef, typedNewStat) + } - DelambdafyAnonClass(anonymousClassDef, typedNewStat) + if (useLambdaMetafactory) { + val arity = originalFunction.vparams.length + val functionalInterface: Symbol = { + val sym = originalFunction.tpe.typeSymbol + val pack = currentRun.runDefinitions.Scala_Java8_CompatPackage + val returnUnit = restpe.typeSymbol == UnitClass + val functionInterfaceArray = + if (returnUnit) currentRun.runDefinitions.Scala_Java8_CompatPackage_JProcedure + else currentRun.runDefinitions.Scala_Java8_CompatPackage_JFunction + functionInterfaceArray.apply(arity) + } + if (functionalInterface.exists) { + val captureArgs = captures.iterator.map(capture => gen.mkAttributedRef(capture) setPos originalFunction.pos).toList + val allCaptureArgs = thisArg ++: captureArgs + + val msym = currentOwner.newMethod(nme.ANON_FUN_NAME, originalFunction.pos, ARTIFACT) + val argTypes: List[Type] = allCaptureArgs.map(_.tpe) + val params = msym.newSyntheticValueParams(argTypes) + msym.setInfo(MethodType(params, originalFunction.tpe)) + + val tree = localTyper.typedPos(originalFunction.pos)(Apply(Ident(msym), allCaptureArgs)).asInstanceOf[Apply] + tree.updateAttachment(LambdaMetaFactoryCapable(targetMethod(originalFunction), arity, functionalInterface)) + InvokeDynamicLambda(tree) + } else anonClass + } else anonClass } /** @@ -436,4 +477,6 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre super.traverse(tree) } } + + final case class LambdaMetaFactoryCapable(target: Symbol, arity: Int, functionalInterface: Symbol) } diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 756ed870ca..98fd8e2361 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -1513,6 +1513,10 @@ trait Definitions extends api.StandardDefinitions { def isPolymorphicSignature(sym: Symbol) = PolySigMethods(sym) private lazy val PolySigMethods: Set[Symbol] = Set[Symbol](MethodHandle.info.decl(sn.Invoke), MethodHandle.info.decl(sn.InvokeExact)).filter(_.exists) + + lazy val Scala_Java8_CompatPackage = rootMirror.getPackageIfDefined("scala.compat.java8") + lazy val Scala_Java8_CompatPackage_JFunction = (0 to MaxTupleArity).toArray map (i => getMemberIfDefined(Scala_Java8_CompatPackage.moduleClass, TypeName("JFunction" + i))) + lazy val Scala_Java8_CompatPackage_JProcedure = (0 to MaxTupleArity).toArray map (i => getMemberIfDefined(Scala_Java8_CompatPackage.moduleClass, TypeName("JProcedure" + i))) } } } diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 4a39712ad7..a96948cb69 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -794,7 +794,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME) final def isDelambdafyFunction = isSynthetic && (name containsName tpnme.DELAMBDAFY_LAMBDA_CLASS_NAME) - final def isDelambdafyTarget = isSynthetic && isMethod && (name containsName tpnme.ANON_FUN_NAME) + final def isDelambdafyTarget = isArtifact && isMethod && (name containsName tpnme.ANON_FUN_NAME) final def isDefinedInPackage = effectiveOwner.isPackageClass final def needsFlatClasses = phase.flatClasses && rawowner != NoSymbol && !rawowner.isPackageClass -- cgit v1.2.3 From d12d59a178c4056fb8ea3cdf4eab5ef453c9a113 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sat, 14 Jun 2014 11:22:29 +0200 Subject: Support specialized method-handle based lambdas ``` scala> (x: Int) => {??? : Int} res2: Int => Int = $$Lambda$1371/1961176822@6ed3ccb2 scala> res2(42) scala.NotImplementedError: an implementation is missing at scala.Predef$.$qmark$qmark$qmark(Predef.scala:225) at .$anonfun$1(:8) at $$Lambda$1371/1961176822.apply$mcII$sp(Unknown Source) ... 33 elided scala> (x: Int, y: Long) => {??? : Int} res4: (Int, Long) => Int = $$Lambda$1382/1796047085@6f8e8894 scala> res4(0, 0L) scala.NotImplementedError: an implementation is missing at scala.Predef$.$qmark$qmark$qmark(Predef.scala:225) at .$anonfun$1(:8) at $$Lambda$1382/1796047085.apply$mcIIJ$sp(Unknown Source) ... 33 elided ``` --- src/compiler/scala/tools/nsc/transform/Delambdafy.scala | 15 ++++++++++----- .../scala/tools/nsc/transform/SpecializeTypes.scala | 17 ++++++++++++++++- src/compiler/scala/tools/nsc/transform/UnCurry.scala | 2 +- 3 files changed, 27 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala index 315d96d2e9..548f34d9b9 100644 --- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala +++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala @@ -308,11 +308,16 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre val functionalInterface: Symbol = { val sym = originalFunction.tpe.typeSymbol val pack = currentRun.runDefinitions.Scala_Java8_CompatPackage - val returnUnit = restpe.typeSymbol == UnitClass - val functionInterfaceArray = - if (returnUnit) currentRun.runDefinitions.Scala_Java8_CompatPackage_JProcedure - else currentRun.runDefinitions.Scala_Java8_CompatPackage_JFunction - functionInterfaceArray.apply(arity) + val name1 = specializeTypes.specializedFunctionName(sym, originalFunction.tpe.typeArgs) + if (name1.toTypeName == sym.name) { + val returnUnit = restpe.typeSymbol == UnitClass + val functionInterfaceArray = + if (returnUnit) currentRun.runDefinitions.Scala_Java8_CompatPackage_JProcedure + else currentRun.runDefinitions.Scala_Java8_CompatPackage_JFunction + functionInterfaceArray.apply(arity) + } else { + pack.info.decl(name1.toTypeName.prepend("J")) + } } if (functionalInterface.exists) { val captureArgs = captures.iterator.map(capture => gen.mkAttributedRef(capture) setPos originalFunction.pos).toList diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 086512677e..4f834d31ff 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -303,6 +303,17 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } } + def specializedFunctionName(sym: Symbol, args: List[Type]) = exitingSpecialize { + require(isFunctionSymbol(sym), sym) + val env: TypeEnv = TypeEnv.fromSpecialization(sym, args) + specializedClass.get((sym, env)) match { + case Some(x) => + x.name + case None => + sym.name + } + } + /** Return the specialized name of 'sym' in the given environment. It * guarantees the same result regardless of the map order by sorting * type variables alphabetically. @@ -315,10 +326,14 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { if (sym.isClass) env.keySet else specializedTypeVars(sym).intersect(env.keySet) ) + specializedName(sym.name, tvars, env) + } + + private def specializedName(name: Name, tvars: immutable.Set[Symbol], env: TypeEnv): TermName = { val (methparams, others) = tvars.toList sortBy ("" + _.name) partition (_.owner.isMethod) // debuglog("specName(" + sym + ") env: " + env + " tvars: " + tvars) - specializedName(sym.name, methparams map env, others map env) + specializedName(name, methparams map env, others map env) } /** Specialize name for the two list of types. The first one denotes diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 6484d96a52..836ea808ac 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -237,7 +237,7 @@ abstract class UnCurry extends InfoTransform def canUseDelamdafyMethod = ( (inConstructorFlag == 0) // Avoiding synthesizing code prone to SI-6666, SI-8363 by using old-style lambda translation - && !isSpecialized // DelambdafyTransformer currently only emits generic FunctionN-s, use the old style in the meantime + && (!isSpecialized || (settings.target.value == "jvm-1.8")) // DelambdafyTransformer currently only emits generic FunctionN-s, use the old style in the meantime ) if (inlineFunctionExpansion || !canUseDelamdafyMethod) { val parents = addSerializable(abstractFunctionForFunctionType(fun.tpe)) -- cgit v1.2.3 From 8a9efcc93a47fe647926065ab88962cb392a9f71 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 22 Apr 2015 12:37:25 +1000 Subject: Update internal documentation in Delambdafy phase --- src/compiler/scala/tools/nsc/transform/Delambdafy.scala | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala index 548f34d9b9..79bcf5c655 100644 --- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala +++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala @@ -9,12 +9,17 @@ import scala.reflect.internal.Symbols import scala.collection.mutable.LinkedHashMap /** - * This transformer is responsible for turning lambdas into anonymous classes. + * This transformer is responsible for preparing lambdas for runtime, by either translating to anonymous classes + * or to a tree that will be convereted to invokedynamic by the JVM 1.8+ backend. + * * The main assumption it makes is that a lambda {args => body} has been turned into * {args => liftedBody()} where lifted body is a top level method that implements the body of the lambda. * Currently Uncurry is responsible for that transformation. * - * From a lambda, Delambdafy will create + * From a lambda, Delambdafy will create: + * + * Under -target:jvm-1.7 and below: + * * 1) a new top level class that a) has fields and a constructor taking the captured environment (including possibly the "this" * reference) @@ -22,9 +27,11 @@ import scala.collection.mutable.LinkedHashMap * c) if needed a bridge method for the apply method * 2) an instantiation of the newly created class which replaces the lambda * - * TODO the main work left to be done is to plug into specialization. Primarily that means choosing a - * specialized FunctionN trait instead of the generic FunctionN trait as a parent and creating the - * appropriately named applysp method + * Under -target:jvm-1.8 with GenBCode: + * + * 1) An application of the captured arguments to a fictional symbol representing the lambda factory. + * This will be translated by the backed into an invokedynamic using a bootstrap method in JDK8's `LambdaMetaFactory`. + * The captured arguments include `this` if `liftedBody` is unable to be made STATIC. */ abstract class Delambdafy extends Transform with TypingTransformers with ast.TreeDSL with TypeAdaptingTransformer { import global._ -- cgit v1.2.3 From 3bf208fd26e0ff272e9aaf9e35446daac4a99901 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 22 Apr 2015 13:05:04 +1000 Subject: Small refactorings and additional comments in Delambdafy --- .../scala/tools/nsc/transform/Delambdafy.scala | 100 +++++++++++---------- 1 file changed, 54 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala index 79bcf5c655..729fe76791 100644 --- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala +++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala @@ -286,60 +286,36 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre localTyper.typedPos(decapturedFunction.pos)(ClassDef(lambdaClass, body)).asInstanceOf[ClassDef] } - val useLambdaMetafactory = { - val hasValueClass = exitingErasure { - val methodType: Type = targetMethod(originalFunction).info - methodType.exists(_.isInstanceOf[ErasedValueType]) - } - val isTarget18 = settings.target.value.contains("jvm-1.8") - settings.isBCodeActive && isTarget18 && !hasValueClass + val allCaptureArgs: List[Tree] = { + val thisArg = if (isStatic) Nil else (gen.mkAttributedThis(oldClass) setPos originalFunction.pos) :: Nil + val captureArgs = captures.iterator.map(capture => gen.mkAttributedRef(capture) setPos originalFunction.pos).toList + thisArg ::: captureArgs } - val thisArg = if (isStatic) Nil else (gen.mkAttributedThis(oldClass) setPos originalFunction.pos) :: Nil + val functionalInterface = java8CompatFunctionalInterface(target, originalFunction.tpe) + if (functionalInterface.exists) { + // Create a symbol representing a fictional lambda factory method that accepts the captured + // arguments and returns a Function. + val msym = currentOwner.newMethod(nme.ANON_FUN_NAME, originalFunction.pos, ARTIFACT) + val argTypes: List[Type] = allCaptureArgs.map(_.tpe) + val params = msym.newSyntheticValueParams(argTypes) + msym.setInfo(MethodType(params, originalFunction.tpe)) + val arity = originalFunction.vparams.length + + // We then apply this symbol to the captures. + val apply = localTyper.typedPos(originalFunction.pos)(Apply(Ident(msym), allCaptureArgs)).asInstanceOf[Apply] - def anonClass: TransformedFunction = { + // The backend needs to know the target of the lambda and the functional interface in order + // to emit the invokedynamic instruction. We pass this information as tree attachment. + apply.updateAttachment(LambdaMetaFactoryCapable(target, arity, functionalInterface)) + InvokeDynamicLambda(apply) + } else { val anonymousClassDef = makeAnonymousClass pkg.info.decls enter anonymousClassDef.symbol - val captureArgs = captures map (capture => Ident(capture) setPos originalFunction.pos) - - val newStat = - Typed(New(anonymousClassDef.symbol, thisArg ++ captureArgs: _*), TypeTree(abstractFunctionErasedType)) - + val newStat = Typed(New(anonymousClassDef.symbol, allCaptureArgs: _*), TypeTree(abstractFunctionErasedType)) val typedNewStat = localTyper.typedPos(originalFunction.pos)(newStat) - DelambdafyAnonClass(anonymousClassDef, typedNewStat) } - - if (useLambdaMetafactory) { - val arity = originalFunction.vparams.length - val functionalInterface: Symbol = { - val sym = originalFunction.tpe.typeSymbol - val pack = currentRun.runDefinitions.Scala_Java8_CompatPackage - val name1 = specializeTypes.specializedFunctionName(sym, originalFunction.tpe.typeArgs) - if (name1.toTypeName == sym.name) { - val returnUnit = restpe.typeSymbol == UnitClass - val functionInterfaceArray = - if (returnUnit) currentRun.runDefinitions.Scala_Java8_CompatPackage_JProcedure - else currentRun.runDefinitions.Scala_Java8_CompatPackage_JFunction - functionInterfaceArray.apply(arity) - } else { - pack.info.decl(name1.toTypeName.prepend("J")) - } - } - if (functionalInterface.exists) { - val captureArgs = captures.iterator.map(capture => gen.mkAttributedRef(capture) setPos originalFunction.pos).toList - val allCaptureArgs = thisArg ++: captureArgs - - val msym = currentOwner.newMethod(nme.ANON_FUN_NAME, originalFunction.pos, ARTIFACT) - val argTypes: List[Type] = allCaptureArgs.map(_.tpe) - val params = msym.newSyntheticValueParams(argTypes) - msym.setInfo(MethodType(params, originalFunction.tpe)) - - val tree = localTyper.typedPos(originalFunction.pos)(Apply(Ident(msym), allCaptureArgs)).asInstanceOf[Apply] - tree.updateAttachment(LambdaMetaFactoryCapable(targetMethod(originalFunction), arity, functionalInterface)) - InvokeDynamicLambda(tree) - } else anonClass - } else anonClass } /** @@ -491,4 +467,36 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre } final case class LambdaMetaFactoryCapable(target: Symbol, arity: Int, functionalInterface: Symbol) + + // The functional interface that can be used to adapt the lambda target method `target` to the + // given function type. Returns `NoSymbol` if the compiler settings are unsuitable, or `LambdaMetaFactory` + // would be unable to generate the correct implementation (e.g. functions referring to derived value classes) + private def java8CompatFunctionalInterface(target: Symbol, functionType: Type): Symbol = { + val canUseLambdaMetafactory: Boolean = { + val hasValueClass = exitingErasure { + val methodType: Type = target.info + methodType.exists(_.isInstanceOf[ErasedValueType]) + } + val isTarget18 = settings.target.value.contains("jvm-1.8") + settings.isBCodeActive && isTarget18 && !hasValueClass + } + + def functionalInterface: Symbol = { + val sym = functionType.typeSymbol + val pack = currentRun.runDefinitions.Scala_Java8_CompatPackage + val name1 = specializeTypes.specializedFunctionName(sym, functionType.typeArgs) + val paramTps :+ restpe = functionType.typeArgs + val arity = paramTps.length + if (name1.toTypeName == sym.name) { + val returnUnit = restpe.typeSymbol == UnitClass + val functionInterfaceArray = + if (returnUnit) currentRun.runDefinitions.Scala_Java8_CompatPackage_JProcedure + else currentRun.runDefinitions.Scala_Java8_CompatPackage_JFunction + functionInterfaceArray.apply(arity) + } else { + pack.info.decl(name1.toTypeName.prepend("J")) + } + } + if (canUseLambdaMetafactory) functionalInterface else NoSymbol + } } -- cgit v1.2.3 From 7385a84bb9b3c71d5a7a78de94f23f836ecc3a61 Mon Sep 17 00:00:00 2001 From: nafg Date: Fri, 24 Apr 2015 04:54:01 -0400 Subject: Fix scaladoc of Try#failed The documentation stated that it returns a Success[Throwable] regardless, either containing the failure or an UnsupportedOperationException. However only Failure#failed returns a success; Success#failed returns a Failure. Also the phrasing of "Completes this `Try`" and "that `Try` failed with" sounds like it was copy-pasted from Future? Trys don't complete, nor fail, they are immutable. --- src/library/scala/util/Try.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/library/scala/util/Try.scala b/src/library/scala/util/Try.scala index b0cf122f2a..f65c77f5a0 100644 --- a/src/library/scala/util/Try.scala +++ b/src/library/scala/util/Try.scala @@ -164,8 +164,8 @@ sealed abstract class Try[+T] { def flatten[U](implicit ev: T <:< Try[U]): Try[U] /** - * Completes this `Try` with an exception wrapped in a `Success`. The exception is either the exception that the - * `Try` failed with (if a `Failure`) or an `UnsupportedOperationException`. + * Inverts this `Try`. If this is a `Failure`, returns its exception wrapped in a `Success`. + * If this is a `Success`, returns a `Failure` containing an `UnsupportedOperationException`. */ def failed: Try[Throwable] -- cgit v1.2.3 From 3ecbe596faf9f7b103856d3298eb0325bd5dc294 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sat, 25 Apr 2015 22:02:16 +1000 Subject: SI-9282 Avoid obscuring an exception during classfile parsing Based on analysis of a stack trace in this bug report, I identified a code path in `ClassfileParser` that can lead to an NPE in its exception handling code. If `val in = new AbstractFileReader(file)` throws (e.g during its construction in which it eagerly reads the file `val buf: Array[Byte] = file.toByteArray`), the call to `in.file` in `handleError` will NPE. This commit stores the active file directly a field in ClassfileParser and uses this in the error reporting. --- .../scala/tools/nsc/symtab/classfile/ClassfileParser.scala | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index a59b9d3f48..ed8c404667 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -53,6 +53,7 @@ abstract class ClassfileParser { protected type ThisConstantPool <: ConstantPool protected def newConstantPool: ThisConstantPool + protected var file: AbstractFile = _ // the class file protected var in: AbstractFileReader = _ // the class file reader protected var clazz: Symbol = _ // the class symbol containing dynamic members protected var staticModule: Symbol = _ // the module symbol containing static members @@ -97,14 +98,14 @@ abstract class ClassfileParser { private def handleMissing(e: MissingRequirementError) = { if (settings.debug) e.printStackTrace - throw new IOException(s"Missing dependency '${e.req}', required by ${in.file}") + throw new IOException(s"Missing dependency '${e.req}', required by $file") } private def handleError(e: Exception) = { if (settings.debug) e.printStackTrace() - throw new IOException(s"class file '${in.file}' is broken\n(${e.getClass}/${e.getMessage})") + throw new IOException(s"class file '$file' is broken\n(${e.getClass}/${e.getMessage})") } private def mismatchError(c: Symbol) = { - throw new IOException(s"class file '${in.file}' has location not matching its contents: contains $c") + throw new IOException(s"class file '$file' has location not matching its contents: contains $c") } private def parseErrorHandler[T]: PartialFunction[Throwable, T] = { @@ -131,6 +132,7 @@ abstract class ClassfileParser { def parse(file: AbstractFile, root: Symbol): Unit = { debuglog("[class] >> " + root.fullName) + this.file = file pushBusy(root) { this.in = new AbstractFileReader(file) this.clazz = if (root.isModule) root.companionClass else root -- cgit v1.2.3 From 6f0e4c64017e6504a3c8017a9322b5edbf73b79a Mon Sep 17 00:00:00 2001 From: swaldman Date: Tue, 28 Apr 2015 04:42:11 -0700 Subject: Fixed documentation of assertions in Predef Assertions can be elided at compile time; they generate no runtime conditional code and are in fact run unconditionally if not elided during compilation. Updated documentation to reflect that. --- src/library/scala/Predef.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 42448b38f2..4eed672794 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -36,8 +36,8 @@ import scala.io.StdIn * * A set of `assert` functions are provided for use as a way to document * and dynamically check invariants in code. `assert` statements can be elided - * at runtime by providing the command line argument `-Xdisable-assertions` to - * the `scala` command. + * at compile time by providing the command line argument `-Xdisable-assertions` to + * the `scalac` command. * * Variants of `assert` intended for use with static analysis tools are also * provided: `assume`, `require` and `ensuring`. `require` and `ensuring` are -- cgit v1.2.3 From fd14b6184250430b826c067bd7f3685d27ba9773 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 29 Apr 2015 14:37:55 +1000 Subject: SI-9285 Don't warn about non-sensible equals in synthetic methods Notably, in the synthetic equals method of a case class. Otherwise, we get an unsuppressable warning when defining a case class with a `Unit`-typed parameter, which some folks use a placeholder for real type while evolving a design. --- src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 2 +- test/files/pos/t9285.flags | 1 + test/files/pos/t9285.scala | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 test/files/pos/t9285.flags create mode 100644 test/files/pos/t9285.scala (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index a3a4c70d1e..4b30b4e436 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -1122,7 +1122,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans } /** Sensibility check examines flavors of equals. */ def checkSensible(pos: Position, fn: Tree, args: List[Tree]) = fn match { - case Select(qual, name @ (nme.EQ | nme.NE | nme.eq | nme.ne)) if args.length == 1 && isObjectOrAnyComparisonMethod(fn.symbol) => + case Select(qual, name @ (nme.EQ | nme.NE | nme.eq | nme.ne)) if args.length == 1 && isObjectOrAnyComparisonMethod(fn.symbol) && !currentOwner.isSynthetic => checkSensibleEquals(pos, qual, name, fn.symbol, args.head) case _ => } diff --git a/test/files/pos/t9285.flags b/test/files/pos/t9285.flags new file mode 100644 index 0000000000..85d8eb2ba2 --- /dev/null +++ b/test/files/pos/t9285.flags @@ -0,0 +1 @@ +-Xfatal-warnings diff --git a/test/files/pos/t9285.scala b/test/files/pos/t9285.scala new file mode 100644 index 0000000000..b7146cdf1c --- /dev/null +++ b/test/files/pos/t9285.scala @@ -0,0 +1 @@ +case class C(placeholder: Unit) -- cgit v1.2.3 From 95fe641e4598c1170f6c3d19874330d035656281 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Thu, 30 Apr 2015 20:21:15 +0200 Subject: Remove references to the old PDF version of the specification --- src/library/scala/Array.scala | 2 +- src/reflect/scala/reflect/api/Constants.scala | 2 +- test/disabled/presentation/timeofday/src/timeofday.scala | 4 ++-- test/files/run/reify_timeofday.scala | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/library/scala/Array.scala b/src/library/scala/Array.scala index 6ab82d998e..d89e9d291d 100644 --- a/src/library/scala/Array.scala +++ b/src/library/scala/Array.scala @@ -483,7 +483,7 @@ object Array extends FallbackArrayBuilding { * * @author Martin Odersky * @version 1.0 - * @see [[http://www.scala-lang.org/docu/files/ScalaReference.pdf Scala Language Specification]], for in-depth information on the transformations the Scala compiler makes on Arrays (Sections 6.6 and 6.15 respectively.) + * @see [[http://www.scala-lang.org/files/archive/spec/2.11/ Scala Language Specification]], for in-depth information on the transformations the Scala compiler makes on Arrays (Sections 6.6 and 6.15 respectively.) * @see [[http://docs.scala-lang.org/sips/completed/scala-2-8-arrays.html "Scala 2.8 Arrays"]] the Scala Improvement Document detailing arrays since Scala 2.8. * @see [[http://docs.scala-lang.org/overviews/collections/arrays.html "The Scala 2.8 Collections' API"]] section on `Array` by Martin Odersky for more information. * @define coll array diff --git a/src/reflect/scala/reflect/api/Constants.scala b/src/reflect/scala/reflect/api/Constants.scala index e73c5ffa91..c942d759ce 100644 --- a/src/reflect/scala/reflect/api/Constants.scala +++ b/src/reflect/scala/reflect/api/Constants.scala @@ -95,7 +95,7 @@ trait Constants { * broken down or evaluated, such as "true", "0", "classOf[List]". Such values become parts of the Scala abstract * syntax tree representing the program. The constants * correspond to section 6.24 "Constant Expressions" of the - * [[http://www.scala-lang.org/docu/files/ScalaReference.pdf Scala language specification]]. + * [[http://www.scala-lang.org/files/archive/spec/2.11/ Scala Language Specification]]. * * Such constants are used to represent literals in abstract syntax trees (the [[scala.reflect.api.Trees#Literal]] node) * and literal arguments for Java class file annotations (the [[scala.reflect.api.Annotations#LiteralArgument]] class). diff --git a/test/disabled/presentation/timeofday/src/timeofday.scala b/test/disabled/presentation/timeofday/src/timeofday.scala index d6355097f1..c8dc7cf820 100644 --- a/test/disabled/presentation/timeofday/src/timeofday.scala +++ b/test/disabled/presentation/timeofday/src/timeofday.scala @@ -2,7 +2,7 @@ object timeofday { class DateError extends Exception /** Simulating properties in Scala - * (example 4.2.1 in ScalaReference.pdf) + * (example 4.2.1 in the Scala Language Specification) */ class TimeOfDayVar { private var h, m, s: Int = 0 @@ -32,4 +32,4 @@ object timeofday { d.hours = 8; d./*!*/minutes = 30; d.seconds = 0 d.hours/*#*/ = 25 // throws a DateError exception } -} \ No newline at end of file +} diff --git a/test/files/run/reify_timeofday.scala b/test/files/run/reify_timeofday.scala index efeb81debf..4950ebfae1 100644 --- a/test/files/run/reify_timeofday.scala +++ b/test/files/run/reify_timeofday.scala @@ -6,7 +6,7 @@ object Test extends App { class DateError extends Exception /** Simulating properties in Scala - * (example 4.2.1 in ScalaReference.pdf) + * (example 4.2.1 in the Scala Language Specification) */ class TimeOfDayVar { private var h, m, s: Int = 0 @@ -39,4 +39,4 @@ object Test extends App { case e: Exception => println("Exception") } }.eval -} \ No newline at end of file +} -- cgit v1.2.3 From 70f2169249b07fd7afcb7444233521c787f93e89 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Fri, 1 May 2015 19:52:33 +0200 Subject: Update intellij project files for IDEA 14.1 and latest Scala plugin Removes the src/intellij-14 folder and moves everything back to src/intellij. --- README.md | 6 +- src/intellij-14/README | 12 -- src/intellij-14/actors.iml.SAMPLE | 14 -- src/intellij-14/asm.iml.SAMPLE | 12 -- src/intellij-14/compiler.iml.SAMPLE | 16 -- src/intellij-14/diff.sh | 8 - src/intellij-14/forkjoin.iml.SAMPLE | 11 - src/intellij-14/interactive.iml.SAMPLE | 16 -- src/intellij-14/library.iml.SAMPLE | 13 -- src/intellij-14/manual.iml.SAMPLE | 15 -- src/intellij-14/partest-extras.iml.SAMPLE | 18 -- src/intellij-14/partest-javaagent.iml.SAMPLE | 13 -- src/intellij-14/reflect.iml.SAMPLE | 13 -- src/intellij-14/repl.iml.SAMPLE | 17 -- src/intellij-14/scala.iml.SAMPLE | 11 - src/intellij-14/scala.ipr.SAMPLE | 261 ------------------------ src/intellij-14/scaladoc.iml.SAMPLE | 18 -- src/intellij-14/scalap.iml.SAMPLE | 15 -- src/intellij-14/setup.sh | 17 -- src/intellij-14/test-junit.iml.SAMPLE | 22 -- src/intellij-14/test.iml.SAMPLE | 22 -- src/intellij-14/update.sh | 22 -- src/intellij/README | 4 +- src/intellij/actors.iml.SAMPLE | 15 +- src/intellij/asm.iml.SAMPLE | 3 +- src/intellij/compiler.iml.SAMPLE | 18 +- src/intellij/forkjoin.iml.SAMPLE | 3 +- src/intellij/interactive.iml.SAMPLE | 18 +- src/intellij/library.iml.SAMPLE | 17 +- src/intellij/manual.iml.SAMPLE | 17 +- src/intellij/partest-extras.iml.SAMPLE | 15 +- src/intellij/partest-javaagent.iml.SAMPLE | 3 +- src/intellij/reflect.iml.SAMPLE | 16 +- src/intellij/repl.iml.SAMPLE | 18 +- src/intellij/scala-lang.ipr.SAMPLE | 287 --------------------------- src/intellij/scala.iml.SAMPLE | 3 +- src/intellij/scala.ipr.SAMPLE | 121 +++++++++++ src/intellij/scaladoc.iml.SAMPLE | 20 +- src/intellij/scalap.iml.SAMPLE | 17 +- src/intellij/setup.sh | 3 + src/intellij/test-junit.iml.SAMPLE | 19 +- src/intellij/test-osgi.iml.SAMPLE | 23 --- src/intellij/test.iml.SAMPLE | 23 +-- 43 files changed, 178 insertions(+), 1057 deletions(-) delete mode 100644 src/intellij-14/README delete mode 100644 src/intellij-14/actors.iml.SAMPLE delete mode 100644 src/intellij-14/asm.iml.SAMPLE delete mode 100644 src/intellij-14/compiler.iml.SAMPLE delete mode 100755 src/intellij-14/diff.sh delete mode 100644 src/intellij-14/forkjoin.iml.SAMPLE delete mode 100644 src/intellij-14/interactive.iml.SAMPLE delete mode 100644 src/intellij-14/library.iml.SAMPLE delete mode 100644 src/intellij-14/manual.iml.SAMPLE delete mode 100644 src/intellij-14/partest-extras.iml.SAMPLE delete mode 100644 src/intellij-14/partest-javaagent.iml.SAMPLE delete mode 100644 src/intellij-14/reflect.iml.SAMPLE delete mode 100644 src/intellij-14/repl.iml.SAMPLE delete mode 100644 src/intellij-14/scala.iml.SAMPLE delete mode 100644 src/intellij-14/scala.ipr.SAMPLE delete mode 100644 src/intellij-14/scaladoc.iml.SAMPLE delete mode 100644 src/intellij-14/scalap.iml.SAMPLE delete mode 100755 src/intellij-14/setup.sh delete mode 100644 src/intellij-14/test-junit.iml.SAMPLE delete mode 100644 src/intellij-14/test.iml.SAMPLE delete mode 100755 src/intellij-14/update.sh delete mode 100644 src/intellij/scala-lang.ipr.SAMPLE create mode 100644 src/intellij/scala.ipr.SAMPLE delete mode 100644 src/intellij/test-osgi.iml.SAMPLE (limited to 'src') diff --git a/README.md b/README.md index 1651333188..3c7e4d1ed8 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ scala/ +---/reflect Scala Reflection. +---/compiler Scala Compiler. +---/eclipse Eclipse project files. - +---/intellij-14 IntelliJ project templates. + +---/intellij IntelliJ project templates. +--scripts/ Scripts for the CI jobs (including building releases) +--test/ The Scala test suite. +--build/ [Generated] Build products output directory for ant. @@ -118,8 +118,8 @@ Use the latest IntelliJ IDEA release and install the Scala plugin from within th The following steps are required to use IntelliJ IDEA on Scala trunk - Run `ant init`. This will download some JARs to `./build/deps`, which are included in IntelliJ's classpath. - - Run src/intellij-14/setup.sh - - Open ./src/intellij-14/scala.ipr in IntelliJ + - Run src/intellij/setup.sh + - Open ./src/intellij/scala.ipr in IntelliJ - File, Project Settings, Project, SDK. Create an SDK entry named "1.6" containing the Java 1.6 SDK. (You may use a later SDK for local development, but the CI will verify against Java 6.) diff --git a/src/intellij-14/README b/src/intellij-14/README deleted file mode 100644 index 310a766a20..0000000000 --- a/src/intellij-14/README +++ /dev/null @@ -1,12 +0,0 @@ -Use the latest IntelliJ IDEA release and install the Scala plugin from within the IDE. - -Compilation withing IDEA is performed in "-Dlocker.skip=1" mode: the sources are built -directly using the STARR compiler. - -The following steps are required to use IntelliJ IDEA on Scala trunk - - Run "ant init". This will download some JARs from to ./build/deps, which are - included in IntelliJ's classpath. - - Run src/intellij-14/setup.sh - - Open ./src/intellij-14/scala.ipr in IntelliJ - - File, Project Settings, Project, SDK. Create an SDK entry named "1.6" containing the - Java 1.6 SDK diff --git a/src/intellij-14/actors.iml.SAMPLE b/src/intellij-14/actors.iml.SAMPLE deleted file mode 100644 index 3da7a5f777..0000000000 --- a/src/intellij-14/actors.iml.SAMPLE +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/intellij-14/asm.iml.SAMPLE b/src/intellij-14/asm.iml.SAMPLE deleted file mode 100644 index 9b2fd58ce7..0000000000 --- a/src/intellij-14/asm.iml.SAMPLE +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/src/intellij-14/compiler.iml.SAMPLE b/src/intellij-14/compiler.iml.SAMPLE deleted file mode 100644 index 858ca2f2c2..0000000000 --- a/src/intellij-14/compiler.iml.SAMPLE +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/intellij-14/diff.sh b/src/intellij-14/diff.sh deleted file mode 100755 index 54f9248608..0000000000 --- a/src/intellij-14/diff.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash -# -# Diffs the SAMPLE files against the working project config. -# -export SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" -for f in "$SCRIPT_DIR"/*.{iml,ipr}; do - echo $f; diff -u $f.SAMPLE $f; -done diff --git a/src/intellij-14/forkjoin.iml.SAMPLE b/src/intellij-14/forkjoin.iml.SAMPLE deleted file mode 100644 index 42507b2911..0000000000 --- a/src/intellij-14/forkjoin.iml.SAMPLE +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/src/intellij-14/interactive.iml.SAMPLE b/src/intellij-14/interactive.iml.SAMPLE deleted file mode 100644 index db12a7dc9b..0000000000 --- a/src/intellij-14/interactive.iml.SAMPLE +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/intellij-14/library.iml.SAMPLE b/src/intellij-14/library.iml.SAMPLE deleted file mode 100644 index 08cccba4b9..0000000000 --- a/src/intellij-14/library.iml.SAMPLE +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/intellij-14/manual.iml.SAMPLE b/src/intellij-14/manual.iml.SAMPLE deleted file mode 100644 index 2e67076e28..0000000000 --- a/src/intellij-14/manual.iml.SAMPLE +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/intellij-14/partest-extras.iml.SAMPLE b/src/intellij-14/partest-extras.iml.SAMPLE deleted file mode 100644 index b3537a949a..0000000000 --- a/src/intellij-14/partest-extras.iml.SAMPLE +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/intellij-14/partest-javaagent.iml.SAMPLE b/src/intellij-14/partest-javaagent.iml.SAMPLE deleted file mode 100644 index 3a387aab0f..0000000000 --- a/src/intellij-14/partest-javaagent.iml.SAMPLE +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/intellij-14/reflect.iml.SAMPLE b/src/intellij-14/reflect.iml.SAMPLE deleted file mode 100644 index 87da13777b..0000000000 --- a/src/intellij-14/reflect.iml.SAMPLE +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/intellij-14/repl.iml.SAMPLE b/src/intellij-14/repl.iml.SAMPLE deleted file mode 100644 index 5a7476b1ef..0000000000 --- a/src/intellij-14/repl.iml.SAMPLE +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/intellij-14/scala.iml.SAMPLE b/src/intellij-14/scala.iml.SAMPLE deleted file mode 100644 index 9e8718dd45..0000000000 --- a/src/intellij-14/scala.iml.SAMPLE +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/src/intellij-14/scala.ipr.SAMPLE b/src/intellij-14/scala.ipr.SAMPLE deleted file mode 100644 index 1e3d07466d..0000000000 --- a/src/intellij-14/scala.ipr.SAMPLE +++ /dev/null @@ -1,261 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - localhost - 5050 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/intellij-14/scaladoc.iml.SAMPLE b/src/intellij-14/scaladoc.iml.SAMPLE deleted file mode 100644 index 5c7015aa61..0000000000 --- a/src/intellij-14/scaladoc.iml.SAMPLE +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/intellij-14/scalap.iml.SAMPLE b/src/intellij-14/scalap.iml.SAMPLE deleted file mode 100644 index e09b8d11b6..0000000000 --- a/src/intellij-14/scalap.iml.SAMPLE +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/intellij-14/setup.sh b/src/intellij-14/setup.sh deleted file mode 100755 index cf08898f24..0000000000 --- a/src/intellij-14/setup.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash -# -# Generates IntelliJ IDEA project files based on the checked-in samples. -# - -set -e -export SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" -echo "About to delete .ipr and .iml files and replace with the .SAMPLE files. Press enter to continue or CTRL-C to cancel." -read - -for f in "$SCRIPT_DIR"/*.SAMPLE; do - g=${f%.SAMPLE} - cp $f $g -done - -SCALA_VERSION="`cat $SCRIPT_DIR/../../versions.properties | grep 'starr.version' | awk '{split($0,a,"="); print a[2]}'`" -sed "s/#scala-version#/$SCALA_VERSION/g" $SCRIPT_DIR/scala.ipr.SAMPLE > $SCRIPT_DIR/scala.ipr \ No newline at end of file diff --git a/src/intellij-14/test-junit.iml.SAMPLE b/src/intellij-14/test-junit.iml.SAMPLE deleted file mode 100644 index 786f02e2e2..0000000000 --- a/src/intellij-14/test-junit.iml.SAMPLE +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/intellij-14/test.iml.SAMPLE b/src/intellij-14/test.iml.SAMPLE deleted file mode 100644 index a384d72266..0000000000 --- a/src/intellij-14/test.iml.SAMPLE +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/intellij-14/update.sh b/src/intellij-14/update.sh deleted file mode 100755 index eb6fea782f..0000000000 --- a/src/intellij-14/update.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash -# -# Updates the .SAMPLE files with the current project files. -# - -set -e -export SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )" - -echo "About to create overwrite the .ipr.SAMPLE and .iml.SAMPLE files with the current project files. Press enter to continue or CTRL-C to cancel." -read - -for f in "$SCRIPT_DIR"/*.{iml,ipr}; do - cp $f $f.SAMPLE -done - -for f in "$SCRIPT_DIR"/*.SAMPLE; do - g=${f%.SAMPLE} - if [[ ! -f $g ]]; then - echo "Stale sample file, deleting $f" - rm $f - fi -done diff --git a/src/intellij/README b/src/intellij/README index a39691f4f0..4ecab5561f 100644 --- a/src/intellij/README +++ b/src/intellij/README @@ -7,6 +7,6 @@ The following steps are required to use IntelliJ IDEA on Scala trunk - Run "ant init". This will download some JARs from to ./build/deps, which are included in IntelliJ's classpath. - Run src/intellij/setup.sh - - Open ./src/intellij/scala-lang.ipr in IntelliJ + - Open ./src/intellij/scala.ipr in IntelliJ - File, Project Settings, Project, SDK. Create an SDK entry named "1.6" containing the - java 1.6 SDK + Java 1.6 SDK diff --git a/src/intellij/actors.iml.SAMPLE b/src/intellij/actors.iml.SAMPLE index b15af8b110..dfdf396c46 100644 --- a/src/intellij/actors.iml.SAMPLE +++ b/src/intellij/actors.iml.SAMPLE @@ -1,16 +1,5 @@ - - - - - - @@ -20,6 +9,6 @@ + - - + \ No newline at end of file diff --git a/src/intellij/asm.iml.SAMPLE b/src/intellij/asm.iml.SAMPLE index ba9e7e899f..9886154bdf 100644 --- a/src/intellij/asm.iml.SAMPLE +++ b/src/intellij/asm.iml.SAMPLE @@ -8,5 +8,4 @@ - - + \ No newline at end of file diff --git a/src/intellij/compiler.iml.SAMPLE b/src/intellij/compiler.iml.SAMPLE index 50253000ab..00f732e255 100644 --- a/src/intellij/compiler.iml.SAMPLE +++ b/src/intellij/compiler.iml.SAMPLE @@ -1,27 +1,17 @@ - - - - - - + + - + - - + \ No newline at end of file diff --git a/src/intellij/forkjoin.iml.SAMPLE b/src/intellij/forkjoin.iml.SAMPLE index be807cc019..42507b2911 100644 --- a/src/intellij/forkjoin.iml.SAMPLE +++ b/src/intellij/forkjoin.iml.SAMPLE @@ -8,5 +8,4 @@ - - + \ No newline at end of file diff --git a/src/intellij/interactive.iml.SAMPLE b/src/intellij/interactive.iml.SAMPLE index 83178021d3..047b5c9069 100644 --- a/src/intellij/interactive.iml.SAMPLE +++ b/src/intellij/interactive.iml.SAMPLE @@ -1,16 +1,5 @@ - - - - - - @@ -18,10 +7,9 @@ + - - + - - + \ No newline at end of file diff --git a/src/intellij/library.iml.SAMPLE b/src/intellij/library.iml.SAMPLE index 137ce6eb9c..b03fef9414 100644 --- a/src/intellij/library.iml.SAMPLE +++ b/src/intellij/library.iml.SAMPLE @@ -1,25 +1,14 @@ - - - - - - + + - - + \ No newline at end of file diff --git a/src/intellij/manual.iml.SAMPLE b/src/intellij/manual.iml.SAMPLE index 8babde73ea..97bfb5940a 100644 --- a/src/intellij/manual.iml.SAMPLE +++ b/src/intellij/manual.iml.SAMPLE @@ -1,16 +1,5 @@ - - - - - - @@ -19,8 +8,8 @@ - + + - - + \ No newline at end of file diff --git a/src/intellij/partest-extras.iml.SAMPLE b/src/intellij/partest-extras.iml.SAMPLE index c2ada43493..d352f9ebc3 100644 --- a/src/intellij/partest-extras.iml.SAMPLE +++ b/src/intellij/partest-extras.iml.SAMPLE @@ -1,14 +1,5 @@ - - - - - - @@ -17,11 +8,11 @@ + - + - - + \ No newline at end of file diff --git a/src/intellij/partest-javaagent.iml.SAMPLE b/src/intellij/partest-javaagent.iml.SAMPLE index e47e0f6349..c6081a2a4b 100644 --- a/src/intellij/partest-javaagent.iml.SAMPLE +++ b/src/intellij/partest-javaagent.iml.SAMPLE @@ -9,5 +9,4 @@ - - + \ No newline at end of file diff --git a/src/intellij/reflect.iml.SAMPLE b/src/intellij/reflect.iml.SAMPLE index d206304896..c9b7130aef 100644 --- a/src/intellij/reflect.iml.SAMPLE +++ b/src/intellij/reflect.iml.SAMPLE @@ -1,17 +1,5 @@ - - - - - - @@ -20,6 +8,6 @@ + - - + \ No newline at end of file diff --git a/src/intellij/repl.iml.SAMPLE b/src/intellij/repl.iml.SAMPLE index 83791f4f6e..896ec1dd5c 100644 --- a/src/intellij/repl.iml.SAMPLE +++ b/src/intellij/repl.iml.SAMPLE @@ -1,16 +1,5 @@ - - - - - - @@ -18,10 +7,11 @@ + + - + - - + \ No newline at end of file diff --git a/src/intellij/scala-lang.ipr.SAMPLE b/src/intellij/scala-lang.ipr.SAMPLE deleted file mode 100644 index 0cd3fdae6a..0000000000 --- a/src/intellij/scala-lang.ipr.SAMPLE +++ /dev/null @@ -1,287 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - http://www.w3.org/1999/xhtml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/intellij/scala.iml.SAMPLE b/src/intellij/scala.iml.SAMPLE index a4d863800b..9e8718dd45 100644 --- a/src/intellij/scala.iml.SAMPLE +++ b/src/intellij/scala.iml.SAMPLE @@ -8,5 +8,4 @@ - - + \ No newline at end of file diff --git a/src/intellij/scala.ipr.SAMPLE b/src/intellij/scala.ipr.SAMPLE new file mode 100644 index 0000000000..07f366a302 --- /dev/null +++ b/src/intellij/scala.ipr.SAMPLE @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/intellij/scaladoc.iml.SAMPLE b/src/intellij/scaladoc.iml.SAMPLE index 8f9a0d8344..4ba0a848c6 100644 --- a/src/intellij/scaladoc.iml.SAMPLE +++ b/src/intellij/scaladoc.iml.SAMPLE @@ -1,16 +1,5 @@ - - - - - - @@ -18,11 +7,12 @@ + - - + + + - - + \ No newline at end of file diff --git a/src/intellij/scalap.iml.SAMPLE b/src/intellij/scalap.iml.SAMPLE index 27ae451369..665aac07f8 100644 --- a/src/intellij/scalap.iml.SAMPLE +++ b/src/intellij/scalap.iml.SAMPLE @@ -1,16 +1,5 @@ - - - - - - @@ -19,8 +8,8 @@ - + + - - + \ No newline at end of file diff --git a/src/intellij/setup.sh b/src/intellij/setup.sh index ec303778ed..251f717829 100755 --- a/src/intellij/setup.sh +++ b/src/intellij/setup.sh @@ -12,3 +12,6 @@ for f in "$SCRIPT_DIR"/*.SAMPLE; do g=${f%.SAMPLE} cp $f $g done + +STARR_VERSION="`cat $SCRIPT_DIR/../../versions.properties | grep 'starr.version' | awk '{split($0,a,"="); print a[2]}'`" +sed "s/#starr-version#/$STARR_VERSION/g" $SCRIPT_DIR/scala.ipr.SAMPLE > $SCRIPT_DIR/scala.ipr diff --git a/src/intellij/test-junit.iml.SAMPLE b/src/intellij/test-junit.iml.SAMPLE index bb51c30a4f..fe98fce60c 100644 --- a/src/intellij/test-junit.iml.SAMPLE +++ b/src/intellij/test-junit.iml.SAMPLE @@ -1,13 +1,5 @@ - - - - - - @@ -18,13 +10,14 @@ + + - - - + + + - - + \ No newline at end of file diff --git a/src/intellij/test-osgi.iml.SAMPLE b/src/intellij/test-osgi.iml.SAMPLE deleted file mode 100644 index a589aaa0a9..0000000000 --- a/src/intellij/test-osgi.iml.SAMPLE +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/intellij/test.iml.SAMPLE b/src/intellij/test.iml.SAMPLE index cb4a8568a1..175a920771 100644 --- a/src/intellij/test.iml.SAMPLE +++ b/src/intellij/test.iml.SAMPLE @@ -1,14 +1,5 @@ - - - - - - @@ -16,16 +7,16 @@ - - - - + + + - + + + - - + \ No newline at end of file -- cgit v1.2.3 From 3a9cb71fc314864d946204d668b17567b797ad30 Mon Sep 17 00:00:00 2001 From: Michał Pociecha Date: Sat, 2 May 2015 20:43:07 +0200 Subject: Remove unused, mostly commented out doc/html/page/Source.scala This file seems to be some early, unfinished draft. It's unused and mostly commented out. De facto it hasn't been changed since this version: https://github.com/scala/scala/blob/d9e3dde6d6d18b9a93e7566447cc3ee342f033d5/src/compiler/scala/tools/nsc/doc/html/page/Source.scala Just in meantime someone updated imports, moved it to other package etc. but nothing more. --- .../scala/tools/nsc/doc/html/page/Source.scala | 127 --------------------- 1 file changed, 127 deletions(-) delete mode 100644 src/scaladoc/scala/tools/nsc/doc/html/page/Source.scala (limited to 'src') diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/Source.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Source.scala deleted file mode 100644 index 37145756d9..0000000000 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/Source.scala +++ /dev/null @@ -1,127 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2007-2013 LAMP/EPFL - * @author David Bernard, Manohar Jonnalagedda - */ - -package scala.tools.nsc -package doc -package html -package page - -import scala.xml.NodeSeq -import java.io.File - -class Source(sourceFile: File) extends HtmlPage { - - val path = List("source.html") - - val title = "Scaladoc: page source" - - val headers = - NodeSeq.Empty - - val body = - -

Page source is not implemented yet

- - - /* - - - def readTextFromSrcDir(subPath: String) :Option[String] = { - readTextFromFile(new File(sourceDir, subPath)) - } - - def readTextFromFile(f : File) :Option[String] = { - if (f.exists) { - Some(Source.fromFile(f)(Codec.default).getLines().mkString("")) - } else { - None - } - } - - - def writeTextToFile(f : File, txt : String, header: Option[String], footer: Option[String]) { - val out = new FileOutputStream(f) - try { - val enc = "UTF-8" - header.foreach(s => out.write(s.getBytes(enc))) - out.write(txt.getBytes(enc)) - footer.foreach(s => out.write(s.getBytes(enc))) - } finally { - try { - out.close() - } catch { - case _ => //ignore - } - } - } - - trait SourceHtmlizer { - def scalaToHtml(src :File) : Option[File] - } - - lazy val sourceHtmlizer : SourceHtmlizer = { - if (cfg.htmlizeSource) { - new SourceHtmlizer { - - val inDir: File = cfg.sourcedir - val outDir: File = cfg.outputdir - - private def relativize(uri: URI, from: URI) = linkHelper.relativize(uri, from).getOrElse("__notFound__" + uri.getPath) - - def header(dest: URI) = Some(""" - - - - - - -
-        """)
-
-          def footer(dest: URI) = Some("""
- - - - """) - - //TODO: escape the source code - def scalaToHtml(src :File) = { - val dest = new File(outDir, fileHelper.relativePathUnderDir(src, inDir) + ".html") - if (!dest.exists || dest.lastModified < src.lastModified) { - - //we need to verify whether the directory we are trying to write to has already been created or not - if(!dest.getParentFile.exists) dest.getParentFile.mkdirs - - val uri = linkHelper.uriFor(dest).get - var txt = fileHelper.readTextFromFile(src).getOrElse("") - txt = txt.replace("<", "<") - fileHelper.writeTextToFile(dest, txt, header(uri), footer(uri)) - } - Some(dest) - } - - def copyResources() { - val loader = this.getClass().getClassLoader() - val buf = new Array[Byte](1024) - def copyResource(name: String) = fileHelper.copyResource("/scala/tools/nsc/doc/html/resource/", name, outDir, loader, buf) - copyResource("_highlighter/clipboard.swf") - copyResource("_highlighter/shAll.js") - copyResource("_highlighter/SyntaxHighlighter.css") - } - - copyResources() - } - } else { - new SourceHtmlizer { - def scalaToHtml(src :File) = None - } - } - } - */ - -} -- cgit v1.2.3 From 6097fe5d8434f8e65595b74aa01cd6bf610c8f48 Mon Sep 17 00:00:00 2001 From: Michał Pociecha Date: Sat, 2 May 2015 15:56:42 +0200 Subject: SI-8679 Add support for ScalaLongSignature attribute in scalap scalap didn't support really big class files. It was returning an empty String for such files. The reason was that there were only ScalaSignatures taken into account. This commit adds support for ScalaLongSignature. We try to get such an attribute when we didn't find ScalaSignature. Also there's added an additional case to the logic retrieving bytes for a signature. Since ScalaLongSignature can contain many parts, we have to merge their byte arrays. Changes are tested by a new partest-based test. These two files are really big, but it was required (t8679.scala is a reduced version of BigScalaClass - an example attached to JIRA). There are also added TODOs with a JIRA ticket: We have three places, where we process Scala signatures. In the future it would be better to reuse some common logic, if it's possible. --- .../nsc/symtab/classfile/ClassfileParser.scala | 1 + .../scala/reflect/runtime/JavaMirrors.scala | 1 + src/scalap/scala/tools/scalap/Main.scala | 1 + .../scalap/scalax/rules/scalasig/ScalaSig.scala | 22 +- test/files/scalap/t8679.check | 3503 ++++++++++++++++++++ test/files/scalap/t8679.scala | 3502 +++++++++++++++++++ 6 files changed, 7025 insertions(+), 5 deletions(-) create mode 100644 test/files/scalap/t8679.check create mode 100644 test/files/scalap/t8679.scala (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index a59b9d3f48..0374e1e2e6 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -923,6 +923,7 @@ abstract class ClassfileParser { Some(ScalaSigBytes(pool.getBytes(entries.toList))) } + // TODO SI-9296 duplicated code, refactor /* Parse and return a single annotation. If it is malformed, * return None. */ diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 237efd004f..ce60ade9f5 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -591,6 +591,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive // don't use classOf[scala.reflect.ScalaSignature] here, because it will use getClass.getClassLoader, not mirror's classLoader // don't use asInstanceOf either because of the same reason (lol, I cannot believe I fell for it) // don't use structural types to simplify reflective invocations because of the same reason + // TODO SI-9296 duplicated code, refactor def loadAnnotation(name: String): Option[java.lang.annotation.Annotation] = tryJavaClass(name) flatMap { annotClass => val anns = jclazz.getAnnotations diff --git a/src/scalap/scala/tools/scalap/Main.scala b/src/scalap/scala/tools/scalap/Main.scala index 7c554d196c..3d2bfd7251 100644 --- a/src/scalap/scala/tools/scalap/Main.scala +++ b/src/scalap/scala/tools/scalap/Main.scala @@ -28,6 +28,7 @@ import scalax.rules.scalasig._ class Main { val SCALA_SIG = "ScalaSig" val SCALA_SIG_ANNOTATION = "Lscala/reflect/ScalaSignature;" + val SCALA_LONG_SIG_ANNOTATION = "Lscala/reflect/ScalaLongSignature;" val BYTES_VALUE = "bytes" val versionMsg = "Scala classfile decoder %s -- %s\n".format(Properties.versionString, Properties.copyrightString) diff --git a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala index e3076322dd..c36fdd02cd 100644 --- a/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala +++ b/src/scalap/scala/tools/scalap/scalax/rules/scalasig/ScalaSig.scala @@ -14,20 +14,32 @@ package scalasig import scala.language.postfixOps import scala.language.implicitConversions -import ClassFileParser.{ ConstValueIndex, Annotation } +import ClassFileParser._ import scala.reflect.internal.pickling.ByteCodecs object ScalaSigParser { - import Main.{ SCALA_SIG, SCALA_SIG_ANNOTATION, BYTES_VALUE } + import Main.{ BYTES_VALUE, SCALA_LONG_SIG_ANNOTATION, SCALA_SIG, SCALA_SIG_ANNOTATION } + // TODO SI-9296 duplicated code, refactor def scalaSigFromAnnotation(classFile: ClassFile): Option[ScalaSig] = { import classFile._ - classFile.annotation(SCALA_SIG_ANNOTATION) map { + def getBytes(bytesElem: AnnotationElement): Array[Byte] = bytesElem.elementValue match { + case ConstValueIndex(index) => bytesForIndex(index) + case ArrayValue(signatureParts) => mergedLongSignatureBytes(signatureParts) + } + + def mergedLongSignatureBytes(signatureParts: Seq[ElementValue]): Array[Byte] = signatureParts.flatMap { + case ConstValueIndex(index) => bytesForIndex(index) + }(collection.breakOut) + + def bytesForIndex(index: Int) = constantWrapped(index).asInstanceOf[StringBytesPair].bytes + + classFile.annotation(SCALA_SIG_ANNOTATION) + .orElse(classFile.annotation(SCALA_LONG_SIG_ANNOTATION)).map { case Annotation(_, elements) => val bytesElem = elements.find(elem => constant(elem.elementNameIndex) == BYTES_VALUE).get - val bytes = ((bytesElem.elementValue match {case ConstValueIndex(index) => constantWrapped(index)}) - .asInstanceOf[StringBytesPair].bytes) + val bytes = getBytes(bytesElem) val length = ByteCodecs.decode(bytes) ScalaSigAttributeParsers.parse(ByteCode(bytes.take(length))) diff --git a/test/files/scalap/t8679.check b/test/files/scalap/t8679.check new file mode 100644 index 0000000000..938b76783f --- /dev/null +++ b/test/files/scalap/t8679.check @@ -0,0 +1,3503 @@ +class T8679 extends scala.AnyRef { + def this() = { /* compiled code */ } + def foo1(): scala.Int = { /* compiled code */ } + def foo2(): scala.Int = { /* compiled code */ } + def foo3(): scala.Int = { /* compiled code */ } + def foo4(): scala.Int = { /* compiled code */ } + def foo5(): scala.Int = { /* compiled code */ } + def foo6(): scala.Int = { /* compiled code */ } + def foo7(): scala.Int = { /* compiled code */ } + def foo8(): scala.Int = { /* compiled code */ } + def foo9(): scala.Int = { /* compiled code */ } + def foo10(): scala.Int = { /* compiled code */ } + def foo11(): scala.Int = { /* compiled code */ } + def foo12(): scala.Int = { /* compiled code */ } + def foo13(): scala.Int = { /* compiled code */ } + def foo14(): scala.Int = { /* compiled code */ } + def foo15(): scala.Int = { /* compiled code */ } + def foo16(): scala.Int = { /* compiled code */ } + def foo17(): scala.Int = { /* compiled code */ } + def foo18(): scala.Int = { /* compiled code */ } + def foo19(): scala.Int = { /* compiled code */ } + def foo20(): scala.Int = { /* compiled code */ } + def foo21(): scala.Int = { /* compiled code */ } + def foo22(): scala.Int = { /* compiled code */ } + def foo23(): scala.Int = { /* compiled code */ } + def foo24(): scala.Int = { /* compiled code */ } + def foo25(): scala.Int = { /* compiled code */ } + def foo26(): scala.Int = { /* compiled code */ } + def foo27(): scala.Int = { /* compiled code */ } + def foo28(): scala.Int = { /* compiled code */ } + def foo29(): scala.Int = { /* compiled code */ } + def foo30(): scala.Int = { /* compiled code */ } + def foo31(): scala.Int = { /* compiled code */ } + def foo32(): scala.Int = { /* compiled code */ } + def foo33(): scala.Int = { /* compiled code */ } + def foo34(): scala.Int = { /* compiled code */ } + def foo35(): scala.Int = { /* compiled code */ } + def foo36(): scala.Int = { /* compiled code */ } + def foo37(): scala.Int = { /* compiled code */ } + def foo38(): scala.Int = { /* compiled code */ } + def foo39(): scala.Int = { /* compiled code */ } + def foo40(): scala.Int = { /* compiled code */ } + def foo41(): scala.Int = { /* compiled code */ } + def foo42(): scala.Int = { /* compiled code */ } + def foo43(): scala.Int = { /* compiled code */ } + def foo44(): scala.Int = { /* compiled code */ } + def foo45(): scala.Int = { /* compiled code */ } + def foo46(): scala.Int = { /* compiled code */ } + def foo47(): scala.Int = { /* compiled code */ } + def foo48(): scala.Int = { /* compiled code */ } + def foo49(): scala.Int = { /* compiled code */ } + def foo50(): scala.Int = { /* compiled code */ } + def foo51(): scala.Int = { /* compiled code */ } + def foo52(): scala.Int = { /* compiled code */ } + def foo53(): scala.Int = { /* compiled code */ } + def foo54(): scala.Int = { /* compiled code */ } + def foo55(): scala.Int = { /* compiled code */ } + def foo56(): scala.Int = { /* compiled code */ } + def foo57(): scala.Int = { /* compiled code */ } + def foo58(): scala.Int = { /* compiled code */ } + def foo59(): scala.Int = { /* compiled code */ } + def foo60(): scala.Int = { /* compiled code */ } + def foo61(): scala.Int = { /* compiled code */ } + def foo62(): scala.Int = { /* compiled code */ } + def foo63(): scala.Int = { /* compiled code */ } + def foo64(): scala.Int = { /* compiled code */ } + def foo65(): scala.Int = { /* compiled code */ } + def foo66(): scala.Int = { /* compiled code */ } + def foo67(): scala.Int = { /* compiled code */ } + def foo68(): scala.Int = { /* compiled code */ } + def foo69(): scala.Int = { /* compiled code */ } + def foo70(): scala.Int = { /* compiled code */ } + def foo71(): scala.Int = { /* compiled code */ } + def foo72(): scala.Int = { /* compiled code */ } + def foo73(): scala.Int = { /* compiled code */ } + def foo74(): scala.Int = { /* compiled code */ } + def foo75(): scala.Int = { /* compiled code */ } + def foo76(): scala.Int = { /* compiled code */ } + def foo77(): scala.Int = { /* compiled code */ } + def foo78(): scala.Int = { /* compiled code */ } + def foo79(): scala.Int = { /* compiled code */ } + def foo80(): scala.Int = { /* compiled code */ } + def foo81(): scala.Int = { /* compiled code */ } + def foo82(): scala.Int = { /* compiled code */ } + def foo83(): scala.Int = { /* compiled code */ } + def foo84(): scala.Int = { /* compiled code */ } + def foo85(): scala.Int = { /* compiled code */ } + def foo86(): scala.Int = { /* compiled code */ } + def foo87(): scala.Int = { /* compiled code */ } + def foo88(): scala.Int = { /* compiled code */ } + def foo89(): scala.Int = { /* compiled code */ } + def foo90(): scala.Int = { /* compiled code */ } + def foo91(): scala.Int = { /* compiled code */ } + def foo92(): scala.Int = { /* compiled code */ } + def foo93(): scala.Int = { /* compiled code */ } + def foo94(): scala.Int = { /* compiled code */ } + def foo95(): scala.Int = { /* compiled code */ } + def foo96(): scala.Int = { /* compiled code */ } + def foo97(): scala.Int = { /* compiled code */ } + def foo98(): scala.Int = { /* compiled code */ } + def foo99(): scala.Int = { /* compiled code */ } + def foo100(): scala.Int = { /* compiled code */ } + def foo101(): scala.Int = { /* compiled code */ } + def foo102(): scala.Int = { /* compiled code */ } + def foo103(): scala.Int = { /* compiled code */ } + def foo104(): scala.Int = { /* compiled code */ } + def foo105(): scala.Int = { /* compiled code */ } + def foo106(): scala.Int = { /* compiled code */ } + def foo107(): scala.Int = { /* compiled code */ } + def foo108(): scala.Int = { /* compiled code */ } + def foo109(): scala.Int = { /* compiled code */ } + def foo110(): scala.Int = { /* compiled code */ } + def foo111(): scala.Int = { /* compiled code */ } + def foo112(): scala.Int = { /* compiled code */ } + def foo113(): scala.Int = { /* compiled code */ } + def foo114(): scala.Int = { /* compiled code */ } + def foo115(): scala.Int = { /* compiled code */ } + def foo116(): scala.Int = { /* compiled code */ } + def foo117(): scala.Int = { /* compiled code */ } + def foo118(): scala.Int = { /* compiled code */ } + def foo119(): scala.Int = { /* compiled code */ } + def foo120(): scala.Int = { /* compiled code */ } + def foo121(): scala.Int = { /* compiled code */ } + def foo122(): scala.Int = { /* compiled code */ } + def foo123(): scala.Int = { /* compiled code */ } + def foo124(): scala.Int = { /* compiled code */ } + def foo125(): scala.Int = { /* compiled code */ } + def foo126(): scala.Int = { /* compiled code */ } + def foo127(): scala.Int = { /* compiled code */ } + def foo128(): scala.Int = { /* compiled code */ } + def foo129(): scala.Int = { /* compiled code */ } + def foo130(): scala.Int = { /* compiled code */ } + def foo131(): scala.Int = { /* compiled code */ } + def foo132(): scala.Int = { /* compiled code */ } + def foo133(): scala.Int = { /* compiled code */ } + def foo134(): scala.Int = { /* compiled code */ } + def foo135(): scala.Int = { /* compiled code */ } + def foo136(): scala.Int = { /* compiled code */ } + def foo137(): scala.Int = { /* compiled code */ } + def foo138(): scala.Int = { /* compiled code */ } + def foo139(): scala.Int = { /* compiled code */ } + def foo140(): scala.Int = { /* compiled code */ } + def foo141(): scala.Int = { /* compiled code */ } + def foo142(): scala.Int = { /* compiled code */ } + def foo143(): scala.Int = { /* compiled code */ } + def foo144(): scala.Int = { /* compiled code */ } + def foo145(): scala.Int = { /* compiled code */ } + def foo146(): scala.Int = { /* compiled code */ } + def foo147(): scala.Int = { /* compiled code */ } + def foo148(): scala.Int = { /* compiled code */ } + def foo149(): scala.Int = { /* compiled code */ } + def foo150(): scala.Int = { /* compiled code */ } + def foo151(): scala.Int = { /* compiled code */ } + def foo152(): scala.Int = { /* compiled code */ } + def foo153(): scala.Int = { /* compiled code */ } + def foo154(): scala.Int = { /* compiled code */ } + def foo155(): scala.Int = { /* compiled code */ } + def foo156(): scala.Int = { /* compiled code */ } + def foo157(): scala.Int = { /* compiled code */ } + def foo158(): scala.Int = { /* compiled code */ } + def foo159(): scala.Int = { /* compiled code */ } + def foo160(): scala.Int = { /* compiled code */ } + def foo161(): scala.Int = { /* compiled code */ } + def foo162(): scala.Int = { /* compiled code */ } + def foo163(): scala.Int = { /* compiled code */ } + def foo164(): scala.Int = { /* compiled code */ } + def foo165(): scala.Int = { /* compiled code */ } + def foo166(): scala.Int = { /* compiled code */ } + def foo167(): scala.Int = { /* compiled code */ } + def foo168(): scala.Int = { /* compiled code */ } + def foo169(): scala.Int = { /* compiled code */ } + def foo170(): scala.Int = { /* compiled code */ } + def foo171(): scala.Int = { /* compiled code */ } + def foo172(): scala.Int = { /* compiled code */ } + def foo173(): scala.Int = { /* compiled code */ } + def foo174(): scala.Int = { /* compiled code */ } + def foo175(): scala.Int = { /* compiled code */ } + def foo176(): scala.Int = { /* compiled code */ } + def foo177(): scala.Int = { /* compiled code */ } + def foo178(): scala.Int = { /* compiled code */ } + def foo179(): scala.Int = { /* compiled code */ } + def foo180(): scala.Int = { /* compiled code */ } + def foo181(): scala.Int = { /* compiled code */ } + def foo182(): scala.Int = { /* compiled code */ } + def foo183(): scala.Int = { /* compiled code */ } + def foo184(): scala.Int = { /* compiled code */ } + def foo185(): scala.Int = { /* compiled code */ } + def foo186(): scala.Int = { /* compiled code */ } + def foo187(): scala.Int = { /* compiled code */ } + def foo188(): scala.Int = { /* compiled code */ } + def foo189(): scala.Int = { /* compiled code */ } + def foo190(): scala.Int = { /* compiled code */ } + def foo191(): scala.Int = { /* compiled code */ } + def foo192(): scala.Int = { /* compiled code */ } + def foo193(): scala.Int = { /* compiled code */ } + def foo194(): scala.Int = { /* compiled code */ } + def foo195(): scala.Int = { /* compiled code */ } + def foo196(): scala.Int = { /* compiled code */ } + def foo197(): scala.Int = { /* compiled code */ } + def foo198(): scala.Int = { /* compiled code */ } + def foo199(): scala.Int = { /* compiled code */ } + def foo200(): scala.Int = { /* compiled code */ } + def foo201(): scala.Int = { /* compiled code */ } + def foo202(): scala.Int = { /* compiled code */ } + def foo203(): scala.Int = { /* compiled code */ } + def foo204(): scala.Int = { /* compiled code */ } + def foo205(): scala.Int = { /* compiled code */ } + def foo206(): scala.Int = { /* compiled code */ } + def foo207(): scala.Int = { /* compiled code */ } + def foo208(): scala.Int = { /* compiled code */ } + def foo209(): scala.Int = { /* compiled code */ } + def foo210(): scala.Int = { /* compiled code */ } + def foo211(): scala.Int = { /* compiled code */ } + def foo212(): scala.Int = { /* compiled code */ } + def foo213(): scala.Int = { /* compiled code */ } + def foo214(): scala.Int = { /* compiled code */ } + def foo215(): scala.Int = { /* compiled code */ } + def foo216(): scala.Int = { /* compiled code */ } + def foo217(): scala.Int = { /* compiled code */ } + def foo218(): scala.Int = { /* compiled code */ } + def foo219(): scala.Int = { /* compiled code */ } + def foo220(): scala.Int = { /* compiled code */ } + def foo221(): scala.Int = { /* compiled code */ } + def foo222(): scala.Int = { /* compiled code */ } + def foo223(): scala.Int = { /* compiled code */ } + def foo224(): scala.Int = { /* compiled code */ } + def foo225(): scala.Int = { /* compiled code */ } + def foo226(): scala.Int = { /* compiled code */ } + def foo227(): scala.Int = { /* compiled code */ } + def foo228(): scala.Int = { /* compiled code */ } + def foo229(): scala.Int = { /* compiled code */ } + def foo230(): scala.Int = { /* compiled code */ } + def foo231(): scala.Int = { /* compiled code */ } + def foo232(): scala.Int = { /* compiled code */ } + def foo233(): scala.Int = { /* compiled code */ } + def foo234(): scala.Int = { /* compiled code */ } + def foo235(): scala.Int = { /* compiled code */ } + def foo236(): scala.Int = { /* compiled code */ } + def foo237(): scala.Int = { /* compiled code */ } + def foo238(): scala.Int = { /* compiled code */ } + def foo239(): scala.Int = { /* compiled code */ } + def foo240(): scala.Int = { /* compiled code */ } + def foo241(): scala.Int = { /* compiled code */ } + def foo242(): scala.Int = { /* compiled code */ } + def foo243(): scala.Int = { /* compiled code */ } + def foo244(): scala.Int = { /* compiled code */ } + def foo245(): scala.Int = { /* compiled code */ } + def foo246(): scala.Int = { /* compiled code */ } + def foo247(): scala.Int = { /* compiled code */ } + def foo248(): scala.Int = { /* compiled code */ } + def foo249(): scala.Int = { /* compiled code */ } + def foo250(): scala.Int = { /* compiled code */ } + def foo251(): scala.Int = { /* compiled code */ } + def foo252(): scala.Int = { /* compiled code */ } + def foo253(): scala.Int = { /* compiled code */ } + def foo254(): scala.Int = { /* compiled code */ } + def foo255(): scala.Int = { /* compiled code */ } + def foo256(): scala.Int = { /* compiled code */ } + def foo257(): scala.Int = { /* compiled code */ } + def foo258(): scala.Int = { /* compiled code */ } + def foo259(): scala.Int = { /* compiled code */ } + def foo260(): scala.Int = { /* compiled code */ } + def foo261(): scala.Int = { /* compiled code */ } + def foo262(): scala.Int = { /* compiled code */ } + def foo263(): scala.Int = { /* compiled code */ } + def foo264(): scala.Int = { /* compiled code */ } + def foo265(): scala.Int = { /* compiled code */ } + def foo266(): scala.Int = { /* compiled code */ } + def foo267(): scala.Int = { /* compiled code */ } + def foo268(): scala.Int = { /* compiled code */ } + def foo269(): scala.Int = { /* compiled code */ } + def foo270(): scala.Int = { /* compiled code */ } + def foo271(): scala.Int = { /* compiled code */ } + def foo272(): scala.Int = { /* compiled code */ } + def foo273(): scala.Int = { /* compiled code */ } + def foo274(): scala.Int = { /* compiled code */ } + def foo275(): scala.Int = { /* compiled code */ } + def foo276(): scala.Int = { /* compiled code */ } + def foo277(): scala.Int = { /* compiled code */ } + def foo278(): scala.Int = { /* compiled code */ } + def foo279(): scala.Int = { /* compiled code */ } + def foo280(): scala.Int = { /* compiled code */ } + def foo281(): scala.Int = { /* compiled code */ } + def foo282(): scala.Int = { /* compiled code */ } + def foo283(): scala.Int = { /* compiled code */ } + def foo284(): scala.Int = { /* compiled code */ } + def foo285(): scala.Int = { /* compiled code */ } + def foo286(): scala.Int = { /* compiled code */ } + def foo287(): scala.Int = { /* compiled code */ } + def foo288(): scala.Int = { /* compiled code */ } + def foo289(): scala.Int = { /* compiled code */ } + def foo290(): scala.Int = { /* compiled code */ } + def foo291(): scala.Int = { /* compiled code */ } + def foo292(): scala.Int = { /* compiled code */ } + def foo293(): scala.Int = { /* compiled code */ } + def foo294(): scala.Int = { /* compiled code */ } + def foo295(): scala.Int = { /* compiled code */ } + def foo296(): scala.Int = { /* compiled code */ } + def foo297(): scala.Int = { /* compiled code */ } + def foo298(): scala.Int = { /* compiled code */ } + def foo299(): scala.Int = { /* compiled code */ } + def foo300(): scala.Int = { /* compiled code */ } + def foo301(): scala.Int = { /* compiled code */ } + def foo302(): scala.Int = { /* compiled code */ } + def foo303(): scala.Int = { /* compiled code */ } + def foo304(): scala.Int = { /* compiled code */ } + def foo305(): scala.Int = { /* compiled code */ } + def foo306(): scala.Int = { /* compiled code */ } + def foo307(): scala.Int = { /* compiled code */ } + def foo308(): scala.Int = { /* compiled code */ } + def foo309(): scala.Int = { /* compiled code */ } + def foo310(): scala.Int = { /* compiled code */ } + def foo311(): scala.Int = { /* compiled code */ } + def foo312(): scala.Int = { /* compiled code */ } + def foo313(): scala.Int = { /* compiled code */ } + def foo314(): scala.Int = { /* compiled code */ } + def foo315(): scala.Int = { /* compiled code */ } + def foo316(): scala.Int = { /* compiled code */ } + def foo317(): scala.Int = { /* compiled code */ } + def foo318(): scala.Int = { /* compiled code */ } + def foo319(): scala.Int = { /* compiled code */ } + def foo320(): scala.Int = { /* compiled code */ } + def foo321(): scala.Int = { /* compiled code */ } + def foo322(): scala.Int = { /* compiled code */ } + def foo323(): scala.Int = { /* compiled code */ } + def foo324(): scala.Int = { /* compiled code */ } + def foo325(): scala.Int = { /* compiled code */ } + def foo326(): scala.Int = { /* compiled code */ } + def foo327(): scala.Int = { /* compiled code */ } + def foo328(): scala.Int = { /* compiled code */ } + def foo329(): scala.Int = { /* compiled code */ } + def foo330(): scala.Int = { /* compiled code */ } + def foo331(): scala.Int = { /* compiled code */ } + def foo332(): scala.Int = { /* compiled code */ } + def foo333(): scala.Int = { /* compiled code */ } + def foo334(): scala.Int = { /* compiled code */ } + def foo335(): scala.Int = { /* compiled code */ } + def foo336(): scala.Int = { /* compiled code */ } + def foo337(): scala.Int = { /* compiled code */ } + def foo338(): scala.Int = { /* compiled code */ } + def foo339(): scala.Int = { /* compiled code */ } + def foo340(): scala.Int = { /* compiled code */ } + def foo341(): scala.Int = { /* compiled code */ } + def foo342(): scala.Int = { /* compiled code */ } + def foo343(): scala.Int = { /* compiled code */ } + def foo344(): scala.Int = { /* compiled code */ } + def foo345(): scala.Int = { /* compiled code */ } + def foo346(): scala.Int = { /* compiled code */ } + def foo347(): scala.Int = { /* compiled code */ } + def foo348(): scala.Int = { /* compiled code */ } + def foo349(): scala.Int = { /* compiled code */ } + def foo350(): scala.Int = { /* compiled code */ } + def foo351(): scala.Int = { /* compiled code */ } + def foo352(): scala.Int = { /* compiled code */ } + def foo353(): scala.Int = { /* compiled code */ } + def foo354(): scala.Int = { /* compiled code */ } + def foo355(): scala.Int = { /* compiled code */ } + def foo356(): scala.Int = { /* compiled code */ } + def foo357(): scala.Int = { /* compiled code */ } + def foo358(): scala.Int = { /* compiled code */ } + def foo359(): scala.Int = { /* compiled code */ } + def foo360(): scala.Int = { /* compiled code */ } + def foo361(): scala.Int = { /* compiled code */ } + def foo362(): scala.Int = { /* compiled code */ } + def foo363(): scala.Int = { /* compiled code */ } + def foo364(): scala.Int = { /* compiled code */ } + def foo365(): scala.Int = { /* compiled code */ } + def foo366(): scala.Int = { /* compiled code */ } + def foo367(): scala.Int = { /* compiled code */ } + def foo368(): scala.Int = { /* compiled code */ } + def foo369(): scala.Int = { /* compiled code */ } + def foo370(): scala.Int = { /* compiled code */ } + def foo371(): scala.Int = { /* compiled code */ } + def foo372(): scala.Int = { /* compiled code */ } + def foo373(): scala.Int = { /* compiled code */ } + def foo374(): scala.Int = { /* compiled code */ } + def foo375(): scala.Int = { /* compiled code */ } + def foo376(): scala.Int = { /* compiled code */ } + def foo377(): scala.Int = { /* compiled code */ } + def foo378(): scala.Int = { /* compiled code */ } + def foo379(): scala.Int = { /* compiled code */ } + def foo380(): scala.Int = { /* compiled code */ } + def foo381(): scala.Int = { /* compiled code */ } + def foo382(): scala.Int = { /* compiled code */ } + def foo383(): scala.Int = { /* compiled code */ } + def foo384(): scala.Int = { /* compiled code */ } + def foo385(): scala.Int = { /* compiled code */ } + def foo386(): scala.Int = { /* compiled code */ } + def foo387(): scala.Int = { /* compiled code */ } + def foo388(): scala.Int = { /* compiled code */ } + def foo389(): scala.Int = { /* compiled code */ } + def foo390(): scala.Int = { /* compiled code */ } + def foo391(): scala.Int = { /* compiled code */ } + def foo392(): scala.Int = { /* compiled code */ } + def foo393(): scala.Int = { /* compiled code */ } + def foo394(): scala.Int = { /* compiled code */ } + def foo395(): scala.Int = { /* compiled code */ } + def foo396(): scala.Int = { /* compiled code */ } + def foo397(): scala.Int = { /* compiled code */ } + def foo398(): scala.Int = { /* compiled code */ } + def foo399(): scala.Int = { /* compiled code */ } + def foo400(): scala.Int = { /* compiled code */ } + def foo401(): scala.Int = { /* compiled code */ } + def foo402(): scala.Int = { /* compiled code */ } + def foo403(): scala.Int = { /* compiled code */ } + def foo404(): scala.Int = { /* compiled code */ } + def foo405(): scala.Int = { /* compiled code */ } + def foo406(): scala.Int = { /* compiled code */ } + def foo407(): scala.Int = { /* compiled code */ } + def foo408(): scala.Int = { /* compiled code */ } + def foo409(): scala.Int = { /* compiled code */ } + def foo410(): scala.Int = { /* compiled code */ } + def foo411(): scala.Int = { /* compiled code */ } + def foo412(): scala.Int = { /* compiled code */ } + def foo413(): scala.Int = { /* compiled code */ } + def foo414(): scala.Int = { /* compiled code */ } + def foo415(): scala.Int = { /* compiled code */ } + def foo416(): scala.Int = { /* compiled code */ } + def foo417(): scala.Int = { /* compiled code */ } + def foo418(): scala.Int = { /* compiled code */ } + def foo419(): scala.Int = { /* compiled code */ } + def foo420(): scala.Int = { /* compiled code */ } + def foo421(): scala.Int = { /* compiled code */ } + def foo422(): scala.Int = { /* compiled code */ } + def foo423(): scala.Int = { /* compiled code */ } + def foo424(): scala.Int = { /* compiled code */ } + def foo425(): scala.Int = { /* compiled code */ } + def foo426(): scala.Int = { /* compiled code */ } + def foo427(): scala.Int = { /* compiled code */ } + def foo428(): scala.Int = { /* compiled code */ } + def foo429(): scala.Int = { /* compiled code */ } + def foo430(): scala.Int = { /* compiled code */ } + def foo431(): scala.Int = { /* compiled code */ } + def foo432(): scala.Int = { /* compiled code */ } + def foo433(): scala.Int = { /* compiled code */ } + def foo434(): scala.Int = { /* compiled code */ } + def foo435(): scala.Int = { /* compiled code */ } + def foo436(): scala.Int = { /* compiled code */ } + def foo437(): scala.Int = { /* compiled code */ } + def foo438(): scala.Int = { /* compiled code */ } + def foo439(): scala.Int = { /* compiled code */ } + def foo440(): scala.Int = { /* compiled code */ } + def foo441(): scala.Int = { /* compiled code */ } + def foo442(): scala.Int = { /* compiled code */ } + def foo443(): scala.Int = { /* compiled code */ } + def foo444(): scala.Int = { /* compiled code */ } + def foo445(): scala.Int = { /* compiled code */ } + def foo446(): scala.Int = { /* compiled code */ } + def foo447(): scala.Int = { /* compiled code */ } + def foo448(): scala.Int = { /* compiled code */ } + def foo449(): scala.Int = { /* compiled code */ } + def foo450(): scala.Int = { /* compiled code */ } + def foo451(): scala.Int = { /* compiled code */ } + def foo452(): scala.Int = { /* compiled code */ } + def foo453(): scala.Int = { /* compiled code */ } + def foo454(): scala.Int = { /* compiled code */ } + def foo455(): scala.Int = { /* compiled code */ } + def foo456(): scala.Int = { /* compiled code */ } + def foo457(): scala.Int = { /* compiled code */ } + def foo458(): scala.Int = { /* compiled code */ } + def foo459(): scala.Int = { /* compiled code */ } + def foo460(): scala.Int = { /* compiled code */ } + def foo461(): scala.Int = { /* compiled code */ } + def foo462(): scala.Int = { /* compiled code */ } + def foo463(): scala.Int = { /* compiled code */ } + def foo464(): scala.Int = { /* compiled code */ } + def foo465(): scala.Int = { /* compiled code */ } + def foo466(): scala.Int = { /* compiled code */ } + def foo467(): scala.Int = { /* compiled code */ } + def foo468(): scala.Int = { /* compiled code */ } + def foo469(): scala.Int = { /* compiled code */ } + def foo470(): scala.Int = { /* compiled code */ } + def foo471(): scala.Int = { /* compiled code */ } + def foo472(): scala.Int = { /* compiled code */ } + def foo473(): scala.Int = { /* compiled code */ } + def foo474(): scala.Int = { /* compiled code */ } + def foo475(): scala.Int = { /* compiled code */ } + def foo476(): scala.Int = { /* compiled code */ } + def foo477(): scala.Int = { /* compiled code */ } + def foo478(): scala.Int = { /* compiled code */ } + def foo479(): scala.Int = { /* compiled code */ } + def foo480(): scala.Int = { /* compiled code */ } + def foo481(): scala.Int = { /* compiled code */ } + def foo482(): scala.Int = { /* compiled code */ } + def foo483(): scala.Int = { /* compiled code */ } + def foo484(): scala.Int = { /* compiled code */ } + def foo485(): scala.Int = { /* compiled code */ } + def foo486(): scala.Int = { /* compiled code */ } + def foo487(): scala.Int = { /* compiled code */ } + def foo488(): scala.Int = { /* compiled code */ } + def foo489(): scala.Int = { /* compiled code */ } + def foo490(): scala.Int = { /* compiled code */ } + def foo491(): scala.Int = { /* compiled code */ } + def foo492(): scala.Int = { /* compiled code */ } + def foo493(): scala.Int = { /* compiled code */ } + def foo494(): scala.Int = { /* compiled code */ } + def foo495(): scala.Int = { /* compiled code */ } + def foo496(): scala.Int = { /* compiled code */ } + def foo497(): scala.Int = { /* compiled code */ } + def foo498(): scala.Int = { /* compiled code */ } + def foo499(): scala.Int = { /* compiled code */ } + def foo500(): scala.Int = { /* compiled code */ } + def foo501(): scala.Int = { /* compiled code */ } + def foo502(): scala.Int = { /* compiled code */ } + def foo503(): scala.Int = { /* compiled code */ } + def foo504(): scala.Int = { /* compiled code */ } + def foo505(): scala.Int = { /* compiled code */ } + def foo506(): scala.Int = { /* compiled code */ } + def foo507(): scala.Int = { /* compiled code */ } + def foo508(): scala.Int = { /* compiled code */ } + def foo509(): scala.Int = { /* compiled code */ } + def foo510(): scala.Int = { /* compiled code */ } + def foo511(): scala.Int = { /* compiled code */ } + def foo512(): scala.Int = { /* compiled code */ } + def foo513(): scala.Int = { /* compiled code */ } + def foo514(): scala.Int = { /* compiled code */ } + def foo515(): scala.Int = { /* compiled code */ } + def foo516(): scala.Int = { /* compiled code */ } + def foo517(): scala.Int = { /* compiled code */ } + def foo518(): scala.Int = { /* compiled code */ } + def foo519(): scala.Int = { /* compiled code */ } + def foo520(): scala.Int = { /* compiled code */ } + def foo521(): scala.Int = { /* compiled code */ } + def foo522(): scala.Int = { /* compiled code */ } + def foo523(): scala.Int = { /* compiled code */ } + def foo524(): scala.Int = { /* compiled code */ } + def foo525(): scala.Int = { /* compiled code */ } + def foo526(): scala.Int = { /* compiled code */ } + def foo527(): scala.Int = { /* compiled code */ } + def foo528(): scala.Int = { /* compiled code */ } + def foo529(): scala.Int = { /* compiled code */ } + def foo530(): scala.Int = { /* compiled code */ } + def foo531(): scala.Int = { /* compiled code */ } + def foo532(): scala.Int = { /* compiled code */ } + def foo533(): scala.Int = { /* compiled code */ } + def foo534(): scala.Int = { /* compiled code */ } + def foo535(): scala.Int = { /* compiled code */ } + def foo536(): scala.Int = { /* compiled code */ } + def foo537(): scala.Int = { /* compiled code */ } + def foo538(): scala.Int = { /* compiled code */ } + def foo539(): scala.Int = { /* compiled code */ } + def foo540(): scala.Int = { /* compiled code */ } + def foo541(): scala.Int = { /* compiled code */ } + def foo542(): scala.Int = { /* compiled code */ } + def foo543(): scala.Int = { /* compiled code */ } + def foo544(): scala.Int = { /* compiled code */ } + def foo545(): scala.Int = { /* compiled code */ } + def foo546(): scala.Int = { /* compiled code */ } + def foo547(): scala.Int = { /* compiled code */ } + def foo548(): scala.Int = { /* compiled code */ } + def foo549(): scala.Int = { /* compiled code */ } + def foo550(): scala.Int = { /* compiled code */ } + def foo551(): scala.Int = { /* compiled code */ } + def foo552(): scala.Int = { /* compiled code */ } + def foo553(): scala.Int = { /* compiled code */ } + def foo554(): scala.Int = { /* compiled code */ } + def foo555(): scala.Int = { /* compiled code */ } + def foo556(): scala.Int = { /* compiled code */ } + def foo557(): scala.Int = { /* compiled code */ } + def foo558(): scala.Int = { /* compiled code */ } + def foo559(): scala.Int = { /* compiled code */ } + def foo560(): scala.Int = { /* compiled code */ } + def foo561(): scala.Int = { /* compiled code */ } + def foo562(): scala.Int = { /* compiled code */ } + def foo563(): scala.Int = { /* compiled code */ } + def foo564(): scala.Int = { /* compiled code */ } + def foo565(): scala.Int = { /* compiled code */ } + def foo566(): scala.Int = { /* compiled code */ } + def foo567(): scala.Int = { /* compiled code */ } + def foo568(): scala.Int = { /* compiled code */ } + def foo569(): scala.Int = { /* compiled code */ } + def foo570(): scala.Int = { /* compiled code */ } + def foo571(): scala.Int = { /* compiled code */ } + def foo572(): scala.Int = { /* compiled code */ } + def foo573(): scala.Int = { /* compiled code */ } + def foo574(): scala.Int = { /* compiled code */ } + def foo575(): scala.Int = { /* compiled code */ } + def foo576(): scala.Int = { /* compiled code */ } + def foo577(): scala.Int = { /* compiled code */ } + def foo578(): scala.Int = { /* compiled code */ } + def foo579(): scala.Int = { /* compiled code */ } + def foo580(): scala.Int = { /* compiled code */ } + def foo581(): scala.Int = { /* compiled code */ } + def foo582(): scala.Int = { /* compiled code */ } + def foo583(): scala.Int = { /* compiled code */ } + def foo584(): scala.Int = { /* compiled code */ } + def foo585(): scala.Int = { /* compiled code */ } + def foo586(): scala.Int = { /* compiled code */ } + def foo587(): scala.Int = { /* compiled code */ } + def foo588(): scala.Int = { /* compiled code */ } + def foo589(): scala.Int = { /* compiled code */ } + def foo590(): scala.Int = { /* compiled code */ } + def foo591(): scala.Int = { /* compiled code */ } + def foo592(): scala.Int = { /* compiled code */ } + def foo593(): scala.Int = { /* compiled code */ } + def foo594(): scala.Int = { /* compiled code */ } + def foo595(): scala.Int = { /* compiled code */ } + def foo596(): scala.Int = { /* compiled code */ } + def foo597(): scala.Int = { /* compiled code */ } + def foo598(): scala.Int = { /* compiled code */ } + def foo599(): scala.Int = { /* compiled code */ } + def foo600(): scala.Int = { /* compiled code */ } + def foo601(): scala.Int = { /* compiled code */ } + def foo602(): scala.Int = { /* compiled code */ } + def foo603(): scala.Int = { /* compiled code */ } + def foo604(): scala.Int = { /* compiled code */ } + def foo605(): scala.Int = { /* compiled code */ } + def foo606(): scala.Int = { /* compiled code */ } + def foo607(): scala.Int = { /* compiled code */ } + def foo608(): scala.Int = { /* compiled code */ } + def foo609(): scala.Int = { /* compiled code */ } + def foo610(): scala.Int = { /* compiled code */ } + def foo611(): scala.Int = { /* compiled code */ } + def foo612(): scala.Int = { /* compiled code */ } + def foo613(): scala.Int = { /* compiled code */ } + def foo614(): scala.Int = { /* compiled code */ } + def foo615(): scala.Int = { /* compiled code */ } + def foo616(): scala.Int = { /* compiled code */ } + def foo617(): scala.Int = { /* compiled code */ } + def foo618(): scala.Int = { /* compiled code */ } + def foo619(): scala.Int = { /* compiled code */ } + def foo620(): scala.Int = { /* compiled code */ } + def foo621(): scala.Int = { /* compiled code */ } + def foo622(): scala.Int = { /* compiled code */ } + def foo623(): scala.Int = { /* compiled code */ } + def foo624(): scala.Int = { /* compiled code */ } + def foo625(): scala.Int = { /* compiled code */ } + def foo626(): scala.Int = { /* compiled code */ } + def foo627(): scala.Int = { /* compiled code */ } + def foo628(): scala.Int = { /* compiled code */ } + def foo629(): scala.Int = { /* compiled code */ } + def foo630(): scala.Int = { /* compiled code */ } + def foo631(): scala.Int = { /* compiled code */ } + def foo632(): scala.Int = { /* compiled code */ } + def foo633(): scala.Int = { /* compiled code */ } + def foo634(): scala.Int = { /* compiled code */ } + def foo635(): scala.Int = { /* compiled code */ } + def foo636(): scala.Int = { /* compiled code */ } + def foo637(): scala.Int = { /* compiled code */ } + def foo638(): scala.Int = { /* compiled code */ } + def foo639(): scala.Int = { /* compiled code */ } + def foo640(): scala.Int = { /* compiled code */ } + def foo641(): scala.Int = { /* compiled code */ } + def foo642(): scala.Int = { /* compiled code */ } + def foo643(): scala.Int = { /* compiled code */ } + def foo644(): scala.Int = { /* compiled code */ } + def foo645(): scala.Int = { /* compiled code */ } + def foo646(): scala.Int = { /* compiled code */ } + def foo647(): scala.Int = { /* compiled code */ } + def foo648(): scala.Int = { /* compiled code */ } + def foo649(): scala.Int = { /* compiled code */ } + def foo650(): scala.Int = { /* compiled code */ } + def foo651(): scala.Int = { /* compiled code */ } + def foo652(): scala.Int = { /* compiled code */ } + def foo653(): scala.Int = { /* compiled code */ } + def foo654(): scala.Int = { /* compiled code */ } + def foo655(): scala.Int = { /* compiled code */ } + def foo656(): scala.Int = { /* compiled code */ } + def foo657(): scala.Int = { /* compiled code */ } + def foo658(): scala.Int = { /* compiled code */ } + def foo659(): scala.Int = { /* compiled code */ } + def foo660(): scala.Int = { /* compiled code */ } + def foo661(): scala.Int = { /* compiled code */ } + def foo662(): scala.Int = { /* compiled code */ } + def foo663(): scala.Int = { /* compiled code */ } + def foo664(): scala.Int = { /* compiled code */ } + def foo665(): scala.Int = { /* compiled code */ } + def foo666(): scala.Int = { /* compiled code */ } + def foo667(): scala.Int = { /* compiled code */ } + def foo668(): scala.Int = { /* compiled code */ } + def foo669(): scala.Int = { /* compiled code */ } + def foo670(): scala.Int = { /* compiled code */ } + def foo671(): scala.Int = { /* compiled code */ } + def foo672(): scala.Int = { /* compiled code */ } + def foo673(): scala.Int = { /* compiled code */ } + def foo674(): scala.Int = { /* compiled code */ } + def foo675(): scala.Int = { /* compiled code */ } + def foo676(): scala.Int = { /* compiled code */ } + def foo677(): scala.Int = { /* compiled code */ } + def foo678(): scala.Int = { /* compiled code */ } + def foo679(): scala.Int = { /* compiled code */ } + def foo680(): scala.Int = { /* compiled code */ } + def foo681(): scala.Int = { /* compiled code */ } + def foo682(): scala.Int = { /* compiled code */ } + def foo683(): scala.Int = { /* compiled code */ } + def foo684(): scala.Int = { /* compiled code */ } + def foo685(): scala.Int = { /* compiled code */ } + def foo686(): scala.Int = { /* compiled code */ } + def foo687(): scala.Int = { /* compiled code */ } + def foo688(): scala.Int = { /* compiled code */ } + def foo689(): scala.Int = { /* compiled code */ } + def foo690(): scala.Int = { /* compiled code */ } + def foo691(): scala.Int = { /* compiled code */ } + def foo692(): scala.Int = { /* compiled code */ } + def foo693(): scala.Int = { /* compiled code */ } + def foo694(): scala.Int = { /* compiled code */ } + def foo695(): scala.Int = { /* compiled code */ } + def foo696(): scala.Int = { /* compiled code */ } + def foo697(): scala.Int = { /* compiled code */ } + def foo698(): scala.Int = { /* compiled code */ } + def foo699(): scala.Int = { /* compiled code */ } + def foo700(): scala.Int = { /* compiled code */ } + def foo701(): scala.Int = { /* compiled code */ } + def foo702(): scala.Int = { /* compiled code */ } + def foo703(): scala.Int = { /* compiled code */ } + def foo704(): scala.Int = { /* compiled code */ } + def foo705(): scala.Int = { /* compiled code */ } + def foo706(): scala.Int = { /* compiled code */ } + def foo707(): scala.Int = { /* compiled code */ } + def foo708(): scala.Int = { /* compiled code */ } + def foo709(): scala.Int = { /* compiled code */ } + def foo710(): scala.Int = { /* compiled code */ } + def foo711(): scala.Int = { /* compiled code */ } + def foo712(): scala.Int = { /* compiled code */ } + def foo713(): scala.Int = { /* compiled code */ } + def foo714(): scala.Int = { /* compiled code */ } + def foo715(): scala.Int = { /* compiled code */ } + def foo716(): scala.Int = { /* compiled code */ } + def foo717(): scala.Int = { /* compiled code */ } + def foo718(): scala.Int = { /* compiled code */ } + def foo719(): scala.Int = { /* compiled code */ } + def foo720(): scala.Int = { /* compiled code */ } + def foo721(): scala.Int = { /* compiled code */ } + def foo722(): scala.Int = { /* compiled code */ } + def foo723(): scala.Int = { /* compiled code */ } + def foo724(): scala.Int = { /* compiled code */ } + def foo725(): scala.Int = { /* compiled code */ } + def foo726(): scala.Int = { /* compiled code */ } + def foo727(): scala.Int = { /* compiled code */ } + def foo728(): scala.Int = { /* compiled code */ } + def foo729(): scala.Int = { /* compiled code */ } + def foo730(): scala.Int = { /* compiled code */ } + def foo731(): scala.Int = { /* compiled code */ } + def foo732(): scala.Int = { /* compiled code */ } + def foo733(): scala.Int = { /* compiled code */ } + def foo734(): scala.Int = { /* compiled code */ } + def foo735(): scala.Int = { /* compiled code */ } + def foo736(): scala.Int = { /* compiled code */ } + def foo737(): scala.Int = { /* compiled code */ } + def foo738(): scala.Int = { /* compiled code */ } + def foo739(): scala.Int = { /* compiled code */ } + def foo740(): scala.Int = { /* compiled code */ } + def foo741(): scala.Int = { /* compiled code */ } + def foo742(): scala.Int = { /* compiled code */ } + def foo743(): scala.Int = { /* compiled code */ } + def foo744(): scala.Int = { /* compiled code */ } + def foo745(): scala.Int = { /* compiled code */ } + def foo746(): scala.Int = { /* compiled code */ } + def foo747(): scala.Int = { /* compiled code */ } + def foo748(): scala.Int = { /* compiled code */ } + def foo749(): scala.Int = { /* compiled code */ } + def foo750(): scala.Int = { /* compiled code */ } + def foo751(): scala.Int = { /* compiled code */ } + def foo752(): scala.Int = { /* compiled code */ } + def foo753(): scala.Int = { /* compiled code */ } + def foo754(): scala.Int = { /* compiled code */ } + def foo755(): scala.Int = { /* compiled code */ } + def foo756(): scala.Int = { /* compiled code */ } + def foo757(): scala.Int = { /* compiled code */ } + def foo758(): scala.Int = { /* compiled code */ } + def foo759(): scala.Int = { /* compiled code */ } + def foo760(): scala.Int = { /* compiled code */ } + def foo761(): scala.Int = { /* compiled code */ } + def foo762(): scala.Int = { /* compiled code */ } + def foo763(): scala.Int = { /* compiled code */ } + def foo764(): scala.Int = { /* compiled code */ } + def foo765(): scala.Int = { /* compiled code */ } + def foo766(): scala.Int = { /* compiled code */ } + def foo767(): scala.Int = { /* compiled code */ } + def foo768(): scala.Int = { /* compiled code */ } + def foo769(): scala.Int = { /* compiled code */ } + def foo770(): scala.Int = { /* compiled code */ } + def foo771(): scala.Int = { /* compiled code */ } + def foo772(): scala.Int = { /* compiled code */ } + def foo773(): scala.Int = { /* compiled code */ } + def foo774(): scala.Int = { /* compiled code */ } + def foo775(): scala.Int = { /* compiled code */ } + def foo776(): scala.Int = { /* compiled code */ } + def foo777(): scala.Int = { /* compiled code */ } + def foo778(): scala.Int = { /* compiled code */ } + def foo779(): scala.Int = { /* compiled code */ } + def foo780(): scala.Int = { /* compiled code */ } + def foo781(): scala.Int = { /* compiled code */ } + def foo782(): scala.Int = { /* compiled code */ } + def foo783(): scala.Int = { /* compiled code */ } + def foo784(): scala.Int = { /* compiled code */ } + def foo785(): scala.Int = { /* compiled code */ } + def foo786(): scala.Int = { /* compiled code */ } + def foo787(): scala.Int = { /* compiled code */ } + def foo788(): scala.Int = { /* compiled code */ } + def foo789(): scala.Int = { /* compiled code */ } + def foo790(): scala.Int = { /* compiled code */ } + def foo791(): scala.Int = { /* compiled code */ } + def foo792(): scala.Int = { /* compiled code */ } + def foo793(): scala.Int = { /* compiled code */ } + def foo794(): scala.Int = { /* compiled code */ } + def foo795(): scala.Int = { /* compiled code */ } + def foo796(): scala.Int = { /* compiled code */ } + def foo797(): scala.Int = { /* compiled code */ } + def foo798(): scala.Int = { /* compiled code */ } + def foo799(): scala.Int = { /* compiled code */ } + def foo800(): scala.Int = { /* compiled code */ } + def foo801(): scala.Int = { /* compiled code */ } + def foo802(): scala.Int = { /* compiled code */ } + def foo803(): scala.Int = { /* compiled code */ } + def foo804(): scala.Int = { /* compiled code */ } + def foo805(): scala.Int = { /* compiled code */ } + def foo806(): scala.Int = { /* compiled code */ } + def foo807(): scala.Int = { /* compiled code */ } + def foo808(): scala.Int = { /* compiled code */ } + def foo809(): scala.Int = { /* compiled code */ } + def foo810(): scala.Int = { /* compiled code */ } + def foo811(): scala.Int = { /* compiled code */ } + def foo812(): scala.Int = { /* compiled code */ } + def foo813(): scala.Int = { /* compiled code */ } + def foo814(): scala.Int = { /* compiled code */ } + def foo815(): scala.Int = { /* compiled code */ } + def foo816(): scala.Int = { /* compiled code */ } + def foo817(): scala.Int = { /* compiled code */ } + def foo818(): scala.Int = { /* compiled code */ } + def foo819(): scala.Int = { /* compiled code */ } + def foo820(): scala.Int = { /* compiled code */ } + def foo821(): scala.Int = { /* compiled code */ } + def foo822(): scala.Int = { /* compiled code */ } + def foo823(): scala.Int = { /* compiled code */ } + def foo824(): scala.Int = { /* compiled code */ } + def foo825(): scala.Int = { /* compiled code */ } + def foo826(): scala.Int = { /* compiled code */ } + def foo827(): scala.Int = { /* compiled code */ } + def foo828(): scala.Int = { /* compiled code */ } + def foo829(): scala.Int = { /* compiled code */ } + def foo830(): scala.Int = { /* compiled code */ } + def foo831(): scala.Int = { /* compiled code */ } + def foo832(): scala.Int = { /* compiled code */ } + def foo833(): scala.Int = { /* compiled code */ } + def foo834(): scala.Int = { /* compiled code */ } + def foo835(): scala.Int = { /* compiled code */ } + def foo836(): scala.Int = { /* compiled code */ } + def foo837(): scala.Int = { /* compiled code */ } + def foo838(): scala.Int = { /* compiled code */ } + def foo839(): scala.Int = { /* compiled code */ } + def foo840(): scala.Int = { /* compiled code */ } + def foo841(): scala.Int = { /* compiled code */ } + def foo842(): scala.Int = { /* compiled code */ } + def foo843(): scala.Int = { /* compiled code */ } + def foo844(): scala.Int = { /* compiled code */ } + def foo845(): scala.Int = { /* compiled code */ } + def foo846(): scala.Int = { /* compiled code */ } + def foo847(): scala.Int = { /* compiled code */ } + def foo848(): scala.Int = { /* compiled code */ } + def foo849(): scala.Int = { /* compiled code */ } + def foo850(): scala.Int = { /* compiled code */ } + def foo851(): scala.Int = { /* compiled code */ } + def foo852(): scala.Int = { /* compiled code */ } + def foo853(): scala.Int = { /* compiled code */ } + def foo854(): scala.Int = { /* compiled code */ } + def foo855(): scala.Int = { /* compiled code */ } + def foo856(): scala.Int = { /* compiled code */ } + def foo857(): scala.Int = { /* compiled code */ } + def foo858(): scala.Int = { /* compiled code */ } + def foo859(): scala.Int = { /* compiled code */ } + def foo860(): scala.Int = { /* compiled code */ } + def foo861(): scala.Int = { /* compiled code */ } + def foo862(): scala.Int = { /* compiled code */ } + def foo863(): scala.Int = { /* compiled code */ } + def foo864(): scala.Int = { /* compiled code */ } + def foo865(): scala.Int = { /* compiled code */ } + def foo866(): scala.Int = { /* compiled code */ } + def foo867(): scala.Int = { /* compiled code */ } + def foo868(): scala.Int = { /* compiled code */ } + def foo869(): scala.Int = { /* compiled code */ } + def foo870(): scala.Int = { /* compiled code */ } + def foo871(): scala.Int = { /* compiled code */ } + def foo872(): scala.Int = { /* compiled code */ } + def foo873(): scala.Int = { /* compiled code */ } + def foo874(): scala.Int = { /* compiled code */ } + def foo875(): scala.Int = { /* compiled code */ } + def foo876(): scala.Int = { /* compiled code */ } + def foo877(): scala.Int = { /* compiled code */ } + def foo878(): scala.Int = { /* compiled code */ } + def foo879(): scala.Int = { /* compiled code */ } + def foo880(): scala.Int = { /* compiled code */ } + def foo881(): scala.Int = { /* compiled code */ } + def foo882(): scala.Int = { /* compiled code */ } + def foo883(): scala.Int = { /* compiled code */ } + def foo884(): scala.Int = { /* compiled code */ } + def foo885(): scala.Int = { /* compiled code */ } + def foo886(): scala.Int = { /* compiled code */ } + def foo887(): scala.Int = { /* compiled code */ } + def foo888(): scala.Int = { /* compiled code */ } + def foo889(): scala.Int = { /* compiled code */ } + def foo890(): scala.Int = { /* compiled code */ } + def foo891(): scala.Int = { /* compiled code */ } + def foo892(): scala.Int = { /* compiled code */ } + def foo893(): scala.Int = { /* compiled code */ } + def foo894(): scala.Int = { /* compiled code */ } + def foo895(): scala.Int = { /* compiled code */ } + def foo896(): scala.Int = { /* compiled code */ } + def foo897(): scala.Int = { /* compiled code */ } + def foo898(): scala.Int = { /* compiled code */ } + def foo899(): scala.Int = { /* compiled code */ } + def foo900(): scala.Int = { /* compiled code */ } + def foo901(): scala.Int = { /* compiled code */ } + def foo902(): scala.Int = { /* compiled code */ } + def foo903(): scala.Int = { /* compiled code */ } + def foo904(): scala.Int = { /* compiled code */ } + def foo905(): scala.Int = { /* compiled code */ } + def foo906(): scala.Int = { /* compiled code */ } + def foo907(): scala.Int = { /* compiled code */ } + def foo908(): scala.Int = { /* compiled code */ } + def foo909(): scala.Int = { /* compiled code */ } + def foo910(): scala.Int = { /* compiled code */ } + def foo911(): scala.Int = { /* compiled code */ } + def foo912(): scala.Int = { /* compiled code */ } + def foo913(): scala.Int = { /* compiled code */ } + def foo914(): scala.Int = { /* compiled code */ } + def foo915(): scala.Int = { /* compiled code */ } + def foo916(): scala.Int = { /* compiled code */ } + def foo917(): scala.Int = { /* compiled code */ } + def foo918(): scala.Int = { /* compiled code */ } + def foo919(): scala.Int = { /* compiled code */ } + def foo920(): scala.Int = { /* compiled code */ } + def foo921(): scala.Int = { /* compiled code */ } + def foo922(): scala.Int = { /* compiled code */ } + def foo923(): scala.Int = { /* compiled code */ } + def foo924(): scala.Int = { /* compiled code */ } + def foo925(): scala.Int = { /* compiled code */ } + def foo926(): scala.Int = { /* compiled code */ } + def foo927(): scala.Int = { /* compiled code */ } + def foo928(): scala.Int = { /* compiled code */ } + def foo929(): scala.Int = { /* compiled code */ } + def foo930(): scala.Int = { /* compiled code */ } + def foo931(): scala.Int = { /* compiled code */ } + def foo932(): scala.Int = { /* compiled code */ } + def foo933(): scala.Int = { /* compiled code */ } + def foo934(): scala.Int = { /* compiled code */ } + def foo935(): scala.Int = { /* compiled code */ } + def foo936(): scala.Int = { /* compiled code */ } + def foo937(): scala.Int = { /* compiled code */ } + def foo938(): scala.Int = { /* compiled code */ } + def foo939(): scala.Int = { /* compiled code */ } + def foo940(): scala.Int = { /* compiled code */ } + def foo941(): scala.Int = { /* compiled code */ } + def foo942(): scala.Int = { /* compiled code */ } + def foo943(): scala.Int = { /* compiled code */ } + def foo944(): scala.Int = { /* compiled code */ } + def foo945(): scala.Int = { /* compiled code */ } + def foo946(): scala.Int = { /* compiled code */ } + def foo947(): scala.Int = { /* compiled code */ } + def foo948(): scala.Int = { /* compiled code */ } + def foo949(): scala.Int = { /* compiled code */ } + def foo950(): scala.Int = { /* compiled code */ } + def foo951(): scala.Int = { /* compiled code */ } + def foo952(): scala.Int = { /* compiled code */ } + def foo953(): scala.Int = { /* compiled code */ } + def foo954(): scala.Int = { /* compiled code */ } + def foo955(): scala.Int = { /* compiled code */ } + def foo956(): scala.Int = { /* compiled code */ } + def foo957(): scala.Int = { /* compiled code */ } + def foo958(): scala.Int = { /* compiled code */ } + def foo959(): scala.Int = { /* compiled code */ } + def foo960(): scala.Int = { /* compiled code */ } + def foo961(): scala.Int = { /* compiled code */ } + def foo962(): scala.Int = { /* compiled code */ } + def foo963(): scala.Int = { /* compiled code */ } + def foo964(): scala.Int = { /* compiled code */ } + def foo965(): scala.Int = { /* compiled code */ } + def foo966(): scala.Int = { /* compiled code */ } + def foo967(): scala.Int = { /* compiled code */ } + def foo968(): scala.Int = { /* compiled code */ } + def foo969(): scala.Int = { /* compiled code */ } + def foo970(): scala.Int = { /* compiled code */ } + def foo971(): scala.Int = { /* compiled code */ } + def foo972(): scala.Int = { /* compiled code */ } + def foo973(): scala.Int = { /* compiled code */ } + def foo974(): scala.Int = { /* compiled code */ } + def foo975(): scala.Int = { /* compiled code */ } + def foo976(): scala.Int = { /* compiled code */ } + def foo977(): scala.Int = { /* compiled code */ } + def foo978(): scala.Int = { /* compiled code */ } + def foo979(): scala.Int = { /* compiled code */ } + def foo980(): scala.Int = { /* compiled code */ } + def foo981(): scala.Int = { /* compiled code */ } + def foo982(): scala.Int = { /* compiled code */ } + def foo983(): scala.Int = { /* compiled code */ } + def foo984(): scala.Int = { /* compiled code */ } + def foo985(): scala.Int = { /* compiled code */ } + def foo986(): scala.Int = { /* compiled code */ } + def foo987(): scala.Int = { /* compiled code */ } + def foo988(): scala.Int = { /* compiled code */ } + def foo989(): scala.Int = { /* compiled code */ } + def foo990(): scala.Int = { /* compiled code */ } + def foo991(): scala.Int = { /* compiled code */ } + def foo992(): scala.Int = { /* compiled code */ } + def foo993(): scala.Int = { /* compiled code */ } + def foo994(): scala.Int = { /* compiled code */ } + def foo995(): scala.Int = { /* compiled code */ } + def foo996(): scala.Int = { /* compiled code */ } + def foo997(): scala.Int = { /* compiled code */ } + def foo998(): scala.Int = { /* compiled code */ } + def foo999(): scala.Int = { /* compiled code */ } + def foo1000(): scala.Int = { /* compiled code */ } + def foo1001(): scala.Int = { /* compiled code */ } + def foo1002(): scala.Int = { /* compiled code */ } + def foo1003(): scala.Int = { /* compiled code */ } + def foo1004(): scala.Int = { /* compiled code */ } + def foo1005(): scala.Int = { /* compiled code */ } + def foo1006(): scala.Int = { /* compiled code */ } + def foo1007(): scala.Int = { /* compiled code */ } + def foo1008(): scala.Int = { /* compiled code */ } + def foo1009(): scala.Int = { /* compiled code */ } + def foo1010(): scala.Int = { /* compiled code */ } + def foo1011(): scala.Int = { /* compiled code */ } + def foo1012(): scala.Int = { /* compiled code */ } + def foo1013(): scala.Int = { /* compiled code */ } + def foo1014(): scala.Int = { /* compiled code */ } + def foo1015(): scala.Int = { /* compiled code */ } + def foo1016(): scala.Int = { /* compiled code */ } + def foo1017(): scala.Int = { /* compiled code */ } + def foo1018(): scala.Int = { /* compiled code */ } + def foo1019(): scala.Int = { /* compiled code */ } + def foo1020(): scala.Int = { /* compiled code */ } + def foo1021(): scala.Int = { /* compiled code */ } + def foo1022(): scala.Int = { /* compiled code */ } + def foo1023(): scala.Int = { /* compiled code */ } + def foo1024(): scala.Int = { /* compiled code */ } + def foo1025(): scala.Int = { /* compiled code */ } + def foo1026(): scala.Int = { /* compiled code */ } + def foo1027(): scala.Int = { /* compiled code */ } + def foo1028(): scala.Int = { /* compiled code */ } + def foo1029(): scala.Int = { /* compiled code */ } + def foo1030(): scala.Int = { /* compiled code */ } + def foo1031(): scala.Int = { /* compiled code */ } + def foo1032(): scala.Int = { /* compiled code */ } + def foo1033(): scala.Int = { /* compiled code */ } + def foo1034(): scala.Int = { /* compiled code */ } + def foo1035(): scala.Int = { /* compiled code */ } + def foo1036(): scala.Int = { /* compiled code */ } + def foo1037(): scala.Int = { /* compiled code */ } + def foo1038(): scala.Int = { /* compiled code */ } + def foo1039(): scala.Int = { /* compiled code */ } + def foo1040(): scala.Int = { /* compiled code */ } + def foo1041(): scala.Int = { /* compiled code */ } + def foo1042(): scala.Int = { /* compiled code */ } + def foo1043(): scala.Int = { /* compiled code */ } + def foo1044(): scala.Int = { /* compiled code */ } + def foo1045(): scala.Int = { /* compiled code */ } + def foo1046(): scala.Int = { /* compiled code */ } + def foo1047(): scala.Int = { /* compiled code */ } + def foo1048(): scala.Int = { /* compiled code */ } + def foo1049(): scala.Int = { /* compiled code */ } + def foo1050(): scala.Int = { /* compiled code */ } + def foo1051(): scala.Int = { /* compiled code */ } + def foo1052(): scala.Int = { /* compiled code */ } + def foo1053(): scala.Int = { /* compiled code */ } + def foo1054(): scala.Int = { /* compiled code */ } + def foo1055(): scala.Int = { /* compiled code */ } + def foo1056(): scala.Int = { /* compiled code */ } + def foo1057(): scala.Int = { /* compiled code */ } + def foo1058(): scala.Int = { /* compiled code */ } + def foo1059(): scala.Int = { /* compiled code */ } + def foo1060(): scala.Int = { /* compiled code */ } + def foo1061(): scala.Int = { /* compiled code */ } + def foo1062(): scala.Int = { /* compiled code */ } + def foo1063(): scala.Int = { /* compiled code */ } + def foo1064(): scala.Int = { /* compiled code */ } + def foo1065(): scala.Int = { /* compiled code */ } + def foo1066(): scala.Int = { /* compiled code */ } + def foo1067(): scala.Int = { /* compiled code */ } + def foo1068(): scala.Int = { /* compiled code */ } + def foo1069(): scala.Int = { /* compiled code */ } + def foo1070(): scala.Int = { /* compiled code */ } + def foo1071(): scala.Int = { /* compiled code */ } + def foo1072(): scala.Int = { /* compiled code */ } + def foo1073(): scala.Int = { /* compiled code */ } + def foo1074(): scala.Int = { /* compiled code */ } + def foo1075(): scala.Int = { /* compiled code */ } + def foo1076(): scala.Int = { /* compiled code */ } + def foo1077(): scala.Int = { /* compiled code */ } + def foo1078(): scala.Int = { /* compiled code */ } + def foo1079(): scala.Int = { /* compiled code */ } + def foo1080(): scala.Int = { /* compiled code */ } + def foo1081(): scala.Int = { /* compiled code */ } + def foo1082(): scala.Int = { /* compiled code */ } + def foo1083(): scala.Int = { /* compiled code */ } + def foo1084(): scala.Int = { /* compiled code */ } + def foo1085(): scala.Int = { /* compiled code */ } + def foo1086(): scala.Int = { /* compiled code */ } + def foo1087(): scala.Int = { /* compiled code */ } + def foo1088(): scala.Int = { /* compiled code */ } + def foo1089(): scala.Int = { /* compiled code */ } + def foo1090(): scala.Int = { /* compiled code */ } + def foo1091(): scala.Int = { /* compiled code */ } + def foo1092(): scala.Int = { /* compiled code */ } + def foo1093(): scala.Int = { /* compiled code */ } + def foo1094(): scala.Int = { /* compiled code */ } + def foo1095(): scala.Int = { /* compiled code */ } + def foo1096(): scala.Int = { /* compiled code */ } + def foo1097(): scala.Int = { /* compiled code */ } + def foo1098(): scala.Int = { /* compiled code */ } + def foo1099(): scala.Int = { /* compiled code */ } + def foo1100(): scala.Int = { /* compiled code */ } + def foo1101(): scala.Int = { /* compiled code */ } + def foo1102(): scala.Int = { /* compiled code */ } + def foo1103(): scala.Int = { /* compiled code */ } + def foo1104(): scala.Int = { /* compiled code */ } + def foo1105(): scala.Int = { /* compiled code */ } + def foo1106(): scala.Int = { /* compiled code */ } + def foo1107(): scala.Int = { /* compiled code */ } + def foo1108(): scala.Int = { /* compiled code */ } + def foo1109(): scala.Int = { /* compiled code */ } + def foo1110(): scala.Int = { /* compiled code */ } + def foo1111(): scala.Int = { /* compiled code */ } + def foo1112(): scala.Int = { /* compiled code */ } + def foo1113(): scala.Int = { /* compiled code */ } + def foo1114(): scala.Int = { /* compiled code */ } + def foo1115(): scala.Int = { /* compiled code */ } + def foo1116(): scala.Int = { /* compiled code */ } + def foo1117(): scala.Int = { /* compiled code */ } + def foo1118(): scala.Int = { /* compiled code */ } + def foo1119(): scala.Int = { /* compiled code */ } + def foo1120(): scala.Int = { /* compiled code */ } + def foo1121(): scala.Int = { /* compiled code */ } + def foo1122(): scala.Int = { /* compiled code */ } + def foo1123(): scala.Int = { /* compiled code */ } + def foo1124(): scala.Int = { /* compiled code */ } + def foo1125(): scala.Int = { /* compiled code */ } + def foo1126(): scala.Int = { /* compiled code */ } + def foo1127(): scala.Int = { /* compiled code */ } + def foo1128(): scala.Int = { /* compiled code */ } + def foo1129(): scala.Int = { /* compiled code */ } + def foo1130(): scala.Int = { /* compiled code */ } + def foo1131(): scala.Int = { /* compiled code */ } + def foo1132(): scala.Int = { /* compiled code */ } + def foo1133(): scala.Int = { /* compiled code */ } + def foo1134(): scala.Int = { /* compiled code */ } + def foo1135(): scala.Int = { /* compiled code */ } + def foo1136(): scala.Int = { /* compiled code */ } + def foo1137(): scala.Int = { /* compiled code */ } + def foo1138(): scala.Int = { /* compiled code */ } + def foo1139(): scala.Int = { /* compiled code */ } + def foo1140(): scala.Int = { /* compiled code */ } + def foo1141(): scala.Int = { /* compiled code */ } + def foo1142(): scala.Int = { /* compiled code */ } + def foo1143(): scala.Int = { /* compiled code */ } + def foo1144(): scala.Int = { /* compiled code */ } + def foo1145(): scala.Int = { /* compiled code */ } + def foo1146(): scala.Int = { /* compiled code */ } + def foo1147(): scala.Int = { /* compiled code */ } + def foo1148(): scala.Int = { /* compiled code */ } + def foo1149(): scala.Int = { /* compiled code */ } + def foo1150(): scala.Int = { /* compiled code */ } + def foo1151(): scala.Int = { /* compiled code */ } + def foo1152(): scala.Int = { /* compiled code */ } + def foo1153(): scala.Int = { /* compiled code */ } + def foo1154(): scala.Int = { /* compiled code */ } + def foo1155(): scala.Int = { /* compiled code */ } + def foo1156(): scala.Int = { /* compiled code */ } + def foo1157(): scala.Int = { /* compiled code */ } + def foo1158(): scala.Int = { /* compiled code */ } + def foo1159(): scala.Int = { /* compiled code */ } + def foo1160(): scala.Int = { /* compiled code */ } + def foo1161(): scala.Int = { /* compiled code */ } + def foo1162(): scala.Int = { /* compiled code */ } + def foo1163(): scala.Int = { /* compiled code */ } + def foo1164(): scala.Int = { /* compiled code */ } + def foo1165(): scala.Int = { /* compiled code */ } + def foo1166(): scala.Int = { /* compiled code */ } + def foo1167(): scala.Int = { /* compiled code */ } + def foo1168(): scala.Int = { /* compiled code */ } + def foo1169(): scala.Int = { /* compiled code */ } + def foo1170(): scala.Int = { /* compiled code */ } + def foo1171(): scala.Int = { /* compiled code */ } + def foo1172(): scala.Int = { /* compiled code */ } + def foo1173(): scala.Int = { /* compiled code */ } + def foo1174(): scala.Int = { /* compiled code */ } + def foo1175(): scala.Int = { /* compiled code */ } + def foo1176(): scala.Int = { /* compiled code */ } + def foo1177(): scala.Int = { /* compiled code */ } + def foo1178(): scala.Int = { /* compiled code */ } + def foo1179(): scala.Int = { /* compiled code */ } + def foo1180(): scala.Int = { /* compiled code */ } + def foo1181(): scala.Int = { /* compiled code */ } + def foo1182(): scala.Int = { /* compiled code */ } + def foo1183(): scala.Int = { /* compiled code */ } + def foo1184(): scala.Int = { /* compiled code */ } + def foo1185(): scala.Int = { /* compiled code */ } + def foo1186(): scala.Int = { /* compiled code */ } + def foo1187(): scala.Int = { /* compiled code */ } + def foo1188(): scala.Int = { /* compiled code */ } + def foo1189(): scala.Int = { /* compiled code */ } + def foo1190(): scala.Int = { /* compiled code */ } + def foo1191(): scala.Int = { /* compiled code */ } + def foo1192(): scala.Int = { /* compiled code */ } + def foo1193(): scala.Int = { /* compiled code */ } + def foo1194(): scala.Int = { /* compiled code */ } + def foo1195(): scala.Int = { /* compiled code */ } + def foo1196(): scala.Int = { /* compiled code */ } + def foo1197(): scala.Int = { /* compiled code */ } + def foo1198(): scala.Int = { /* compiled code */ } + def foo1199(): scala.Int = { /* compiled code */ } + def foo1200(): scala.Int = { /* compiled code */ } + def foo1201(): scala.Int = { /* compiled code */ } + def foo1202(): scala.Int = { /* compiled code */ } + def foo1203(): scala.Int = { /* compiled code */ } + def foo1204(): scala.Int = { /* compiled code */ } + def foo1205(): scala.Int = { /* compiled code */ } + def foo1206(): scala.Int = { /* compiled code */ } + def foo1207(): scala.Int = { /* compiled code */ } + def foo1208(): scala.Int = { /* compiled code */ } + def foo1209(): scala.Int = { /* compiled code */ } + def foo1210(): scala.Int = { /* compiled code */ } + def foo1211(): scala.Int = { /* compiled code */ } + def foo1212(): scala.Int = { /* compiled code */ } + def foo1213(): scala.Int = { /* compiled code */ } + def foo1214(): scala.Int = { /* compiled code */ } + def foo1215(): scala.Int = { /* compiled code */ } + def foo1216(): scala.Int = { /* compiled code */ } + def foo1217(): scala.Int = { /* compiled code */ } + def foo1218(): scala.Int = { /* compiled code */ } + def foo1219(): scala.Int = { /* compiled code */ } + def foo1220(): scala.Int = { /* compiled code */ } + def foo1221(): scala.Int = { /* compiled code */ } + def foo1222(): scala.Int = { /* compiled code */ } + def foo1223(): scala.Int = { /* compiled code */ } + def foo1224(): scala.Int = { /* compiled code */ } + def foo1225(): scala.Int = { /* compiled code */ } + def foo1226(): scala.Int = { /* compiled code */ } + def foo1227(): scala.Int = { /* compiled code */ } + def foo1228(): scala.Int = { /* compiled code */ } + def foo1229(): scala.Int = { /* compiled code */ } + def foo1230(): scala.Int = { /* compiled code */ } + def foo1231(): scala.Int = { /* compiled code */ } + def foo1232(): scala.Int = { /* compiled code */ } + def foo1233(): scala.Int = { /* compiled code */ } + def foo1234(): scala.Int = { /* compiled code */ } + def foo1235(): scala.Int = { /* compiled code */ } + def foo1236(): scala.Int = { /* compiled code */ } + def foo1237(): scala.Int = { /* compiled code */ } + def foo1238(): scala.Int = { /* compiled code */ } + def foo1239(): scala.Int = { /* compiled code */ } + def foo1240(): scala.Int = { /* compiled code */ } + def foo1241(): scala.Int = { /* compiled code */ } + def foo1242(): scala.Int = { /* compiled code */ } + def foo1243(): scala.Int = { /* compiled code */ } + def foo1244(): scala.Int = { /* compiled code */ } + def foo1245(): scala.Int = { /* compiled code */ } + def foo1246(): scala.Int = { /* compiled code */ } + def foo1247(): scala.Int = { /* compiled code */ } + def foo1248(): scala.Int = { /* compiled code */ } + def foo1249(): scala.Int = { /* compiled code */ } + def foo1250(): scala.Int = { /* compiled code */ } + def foo1251(): scala.Int = { /* compiled code */ } + def foo1252(): scala.Int = { /* compiled code */ } + def foo1253(): scala.Int = { /* compiled code */ } + def foo1254(): scala.Int = { /* compiled code */ } + def foo1255(): scala.Int = { /* compiled code */ } + def foo1256(): scala.Int = { /* compiled code */ } + def foo1257(): scala.Int = { /* compiled code */ } + def foo1258(): scala.Int = { /* compiled code */ } + def foo1259(): scala.Int = { /* compiled code */ } + def foo1260(): scala.Int = { /* compiled code */ } + def foo1261(): scala.Int = { /* compiled code */ } + def foo1262(): scala.Int = { /* compiled code */ } + def foo1263(): scala.Int = { /* compiled code */ } + def foo1264(): scala.Int = { /* compiled code */ } + def foo1265(): scala.Int = { /* compiled code */ } + def foo1266(): scala.Int = { /* compiled code */ } + def foo1267(): scala.Int = { /* compiled code */ } + def foo1268(): scala.Int = { /* compiled code */ } + def foo1269(): scala.Int = { /* compiled code */ } + def foo1270(): scala.Int = { /* compiled code */ } + def foo1271(): scala.Int = { /* compiled code */ } + def foo1272(): scala.Int = { /* compiled code */ } + def foo1273(): scala.Int = { /* compiled code */ } + def foo1274(): scala.Int = { /* compiled code */ } + def foo1275(): scala.Int = { /* compiled code */ } + def foo1276(): scala.Int = { /* compiled code */ } + def foo1277(): scala.Int = { /* compiled code */ } + def foo1278(): scala.Int = { /* compiled code */ } + def foo1279(): scala.Int = { /* compiled code */ } + def foo1280(): scala.Int = { /* compiled code */ } + def foo1281(): scala.Int = { /* compiled code */ } + def foo1282(): scala.Int = { /* compiled code */ } + def foo1283(): scala.Int = { /* compiled code */ } + def foo1284(): scala.Int = { /* compiled code */ } + def foo1285(): scala.Int = { /* compiled code */ } + def foo1286(): scala.Int = { /* compiled code */ } + def foo1287(): scala.Int = { /* compiled code */ } + def foo1288(): scala.Int = { /* compiled code */ } + def foo1289(): scala.Int = { /* compiled code */ } + def foo1290(): scala.Int = { /* compiled code */ } + def foo1291(): scala.Int = { /* compiled code */ } + def foo1292(): scala.Int = { /* compiled code */ } + def foo1293(): scala.Int = { /* compiled code */ } + def foo1294(): scala.Int = { /* compiled code */ } + def foo1295(): scala.Int = { /* compiled code */ } + def foo1296(): scala.Int = { /* compiled code */ } + def foo1297(): scala.Int = { /* compiled code */ } + def foo1298(): scala.Int = { /* compiled code */ } + def foo1299(): scala.Int = { /* compiled code */ } + def foo1300(): scala.Int = { /* compiled code */ } + def foo1301(): scala.Int = { /* compiled code */ } + def foo1302(): scala.Int = { /* compiled code */ } + def foo1303(): scala.Int = { /* compiled code */ } + def foo1304(): scala.Int = { /* compiled code */ } + def foo1305(): scala.Int = { /* compiled code */ } + def foo1306(): scala.Int = { /* compiled code */ } + def foo1307(): scala.Int = { /* compiled code */ } + def foo1308(): scala.Int = { /* compiled code */ } + def foo1309(): scala.Int = { /* compiled code */ } + def foo1310(): scala.Int = { /* compiled code */ } + def foo1311(): scala.Int = { /* compiled code */ } + def foo1312(): scala.Int = { /* compiled code */ } + def foo1313(): scala.Int = { /* compiled code */ } + def foo1314(): scala.Int = { /* compiled code */ } + def foo1315(): scala.Int = { /* compiled code */ } + def foo1316(): scala.Int = { /* compiled code */ } + def foo1317(): scala.Int = { /* compiled code */ } + def foo1318(): scala.Int = { /* compiled code */ } + def foo1319(): scala.Int = { /* compiled code */ } + def foo1320(): scala.Int = { /* compiled code */ } + def foo1321(): scala.Int = { /* compiled code */ } + def foo1322(): scala.Int = { /* compiled code */ } + def foo1323(): scala.Int = { /* compiled code */ } + def foo1324(): scala.Int = { /* compiled code */ } + def foo1325(): scala.Int = { /* compiled code */ } + def foo1326(): scala.Int = { /* compiled code */ } + def foo1327(): scala.Int = { /* compiled code */ } + def foo1328(): scala.Int = { /* compiled code */ } + def foo1329(): scala.Int = { /* compiled code */ } + def foo1330(): scala.Int = { /* compiled code */ } + def foo1331(): scala.Int = { /* compiled code */ } + def foo1332(): scala.Int = { /* compiled code */ } + def foo1333(): scala.Int = { /* compiled code */ } + def foo1334(): scala.Int = { /* compiled code */ } + def foo1335(): scala.Int = { /* compiled code */ } + def foo1336(): scala.Int = { /* compiled code */ } + def foo1337(): scala.Int = { /* compiled code */ } + def foo1338(): scala.Int = { /* compiled code */ } + def foo1339(): scala.Int = { /* compiled code */ } + def foo1340(): scala.Int = { /* compiled code */ } + def foo1341(): scala.Int = { /* compiled code */ } + def foo1342(): scala.Int = { /* compiled code */ } + def foo1343(): scala.Int = { /* compiled code */ } + def foo1344(): scala.Int = { /* compiled code */ } + def foo1345(): scala.Int = { /* compiled code */ } + def foo1346(): scala.Int = { /* compiled code */ } + def foo1347(): scala.Int = { /* compiled code */ } + def foo1348(): scala.Int = { /* compiled code */ } + def foo1349(): scala.Int = { /* compiled code */ } + def foo1350(): scala.Int = { /* compiled code */ } + def foo1351(): scala.Int = { /* compiled code */ } + def foo1352(): scala.Int = { /* compiled code */ } + def foo1353(): scala.Int = { /* compiled code */ } + def foo1354(): scala.Int = { /* compiled code */ } + def foo1355(): scala.Int = { /* compiled code */ } + def foo1356(): scala.Int = { /* compiled code */ } + def foo1357(): scala.Int = { /* compiled code */ } + def foo1358(): scala.Int = { /* compiled code */ } + def foo1359(): scala.Int = { /* compiled code */ } + def foo1360(): scala.Int = { /* compiled code */ } + def foo1361(): scala.Int = { /* compiled code */ } + def foo1362(): scala.Int = { /* compiled code */ } + def foo1363(): scala.Int = { /* compiled code */ } + def foo1364(): scala.Int = { /* compiled code */ } + def foo1365(): scala.Int = { /* compiled code */ } + def foo1366(): scala.Int = { /* compiled code */ } + def foo1367(): scala.Int = { /* compiled code */ } + def foo1368(): scala.Int = { /* compiled code */ } + def foo1369(): scala.Int = { /* compiled code */ } + def foo1370(): scala.Int = { /* compiled code */ } + def foo1371(): scala.Int = { /* compiled code */ } + def foo1372(): scala.Int = { /* compiled code */ } + def foo1373(): scala.Int = { /* compiled code */ } + def foo1374(): scala.Int = { /* compiled code */ } + def foo1375(): scala.Int = { /* compiled code */ } + def foo1376(): scala.Int = { /* compiled code */ } + def foo1377(): scala.Int = { /* compiled code */ } + def foo1378(): scala.Int = { /* compiled code */ } + def foo1379(): scala.Int = { /* compiled code */ } + def foo1380(): scala.Int = { /* compiled code */ } + def foo1381(): scala.Int = { /* compiled code */ } + def foo1382(): scala.Int = { /* compiled code */ } + def foo1383(): scala.Int = { /* compiled code */ } + def foo1384(): scala.Int = { /* compiled code */ } + def foo1385(): scala.Int = { /* compiled code */ } + def foo1386(): scala.Int = { /* compiled code */ } + def foo1387(): scala.Int = { /* compiled code */ } + def foo1388(): scala.Int = { /* compiled code */ } + def foo1389(): scala.Int = { /* compiled code */ } + def foo1390(): scala.Int = { /* compiled code */ } + def foo1391(): scala.Int = { /* compiled code */ } + def foo1392(): scala.Int = { /* compiled code */ } + def foo1393(): scala.Int = { /* compiled code */ } + def foo1394(): scala.Int = { /* compiled code */ } + def foo1395(): scala.Int = { /* compiled code */ } + def foo1396(): scala.Int = { /* compiled code */ } + def foo1397(): scala.Int = { /* compiled code */ } + def foo1398(): scala.Int = { /* compiled code */ } + def foo1399(): scala.Int = { /* compiled code */ } + def foo1400(): scala.Int = { /* compiled code */ } + def foo1401(): scala.Int = { /* compiled code */ } + def foo1402(): scala.Int = { /* compiled code */ } + def foo1403(): scala.Int = { /* compiled code */ } + def foo1404(): scala.Int = { /* compiled code */ } + def foo1405(): scala.Int = { /* compiled code */ } + def foo1406(): scala.Int = { /* compiled code */ } + def foo1407(): scala.Int = { /* compiled code */ } + def foo1408(): scala.Int = { /* compiled code */ } + def foo1409(): scala.Int = { /* compiled code */ } + def foo1410(): scala.Int = { /* compiled code */ } + def foo1411(): scala.Int = { /* compiled code */ } + def foo1412(): scala.Int = { /* compiled code */ } + def foo1413(): scala.Int = { /* compiled code */ } + def foo1414(): scala.Int = { /* compiled code */ } + def foo1415(): scala.Int = { /* compiled code */ } + def foo1416(): scala.Int = { /* compiled code */ } + def foo1417(): scala.Int = { /* compiled code */ } + def foo1418(): scala.Int = { /* compiled code */ } + def foo1419(): scala.Int = { /* compiled code */ } + def foo1420(): scala.Int = { /* compiled code */ } + def foo1421(): scala.Int = { /* compiled code */ } + def foo1422(): scala.Int = { /* compiled code */ } + def foo1423(): scala.Int = { /* compiled code */ } + def foo1424(): scala.Int = { /* compiled code */ } + def foo1425(): scala.Int = { /* compiled code */ } + def foo1426(): scala.Int = { /* compiled code */ } + def foo1427(): scala.Int = { /* compiled code */ } + def foo1428(): scala.Int = { /* compiled code */ } + def foo1429(): scala.Int = { /* compiled code */ } + def foo1430(): scala.Int = { /* compiled code */ } + def foo1431(): scala.Int = { /* compiled code */ } + def foo1432(): scala.Int = { /* compiled code */ } + def foo1433(): scala.Int = { /* compiled code */ } + def foo1434(): scala.Int = { /* compiled code */ } + def foo1435(): scala.Int = { /* compiled code */ } + def foo1436(): scala.Int = { /* compiled code */ } + def foo1437(): scala.Int = { /* compiled code */ } + def foo1438(): scala.Int = { /* compiled code */ } + def foo1439(): scala.Int = { /* compiled code */ } + def foo1440(): scala.Int = { /* compiled code */ } + def foo1441(): scala.Int = { /* compiled code */ } + def foo1442(): scala.Int = { /* compiled code */ } + def foo1443(): scala.Int = { /* compiled code */ } + def foo1444(): scala.Int = { /* compiled code */ } + def foo1445(): scala.Int = { /* compiled code */ } + def foo1446(): scala.Int = { /* compiled code */ } + def foo1447(): scala.Int = { /* compiled code */ } + def foo1448(): scala.Int = { /* compiled code */ } + def foo1449(): scala.Int = { /* compiled code */ } + def foo1450(): scala.Int = { /* compiled code */ } + def foo1451(): scala.Int = { /* compiled code */ } + def foo1452(): scala.Int = { /* compiled code */ } + def foo1453(): scala.Int = { /* compiled code */ } + def foo1454(): scala.Int = { /* compiled code */ } + def foo1455(): scala.Int = { /* compiled code */ } + def foo1456(): scala.Int = { /* compiled code */ } + def foo1457(): scala.Int = { /* compiled code */ } + def foo1458(): scala.Int = { /* compiled code */ } + def foo1459(): scala.Int = { /* compiled code */ } + def foo1460(): scala.Int = { /* compiled code */ } + def foo1461(): scala.Int = { /* compiled code */ } + def foo1462(): scala.Int = { /* compiled code */ } + def foo1463(): scala.Int = { /* compiled code */ } + def foo1464(): scala.Int = { /* compiled code */ } + def foo1465(): scala.Int = { /* compiled code */ } + def foo1466(): scala.Int = { /* compiled code */ } + def foo1467(): scala.Int = { /* compiled code */ } + def foo1468(): scala.Int = { /* compiled code */ } + def foo1469(): scala.Int = { /* compiled code */ } + def foo1470(): scala.Int = { /* compiled code */ } + def foo1471(): scala.Int = { /* compiled code */ } + def foo1472(): scala.Int = { /* compiled code */ } + def foo1473(): scala.Int = { /* compiled code */ } + def foo1474(): scala.Int = { /* compiled code */ } + def foo1475(): scala.Int = { /* compiled code */ } + def foo1476(): scala.Int = { /* compiled code */ } + def foo1477(): scala.Int = { /* compiled code */ } + def foo1478(): scala.Int = { /* compiled code */ } + def foo1479(): scala.Int = { /* compiled code */ } + def foo1480(): scala.Int = { /* compiled code */ } + def foo1481(): scala.Int = { /* compiled code */ } + def foo1482(): scala.Int = { /* compiled code */ } + def foo1483(): scala.Int = { /* compiled code */ } + def foo1484(): scala.Int = { /* compiled code */ } + def foo1485(): scala.Int = { /* compiled code */ } + def foo1486(): scala.Int = { /* compiled code */ } + def foo1487(): scala.Int = { /* compiled code */ } + def foo1488(): scala.Int = { /* compiled code */ } + def foo1489(): scala.Int = { /* compiled code */ } + def foo1490(): scala.Int = { /* compiled code */ } + def foo1491(): scala.Int = { /* compiled code */ } + def foo1492(): scala.Int = { /* compiled code */ } + def foo1493(): scala.Int = { /* compiled code */ } + def foo1494(): scala.Int = { /* compiled code */ } + def foo1495(): scala.Int = { /* compiled code */ } + def foo1496(): scala.Int = { /* compiled code */ } + def foo1497(): scala.Int = { /* compiled code */ } + def foo1498(): scala.Int = { /* compiled code */ } + def foo1499(): scala.Int = { /* compiled code */ } + def foo1500(): scala.Int = { /* compiled code */ } + def foo1501(): scala.Int = { /* compiled code */ } + def foo1502(): scala.Int = { /* compiled code */ } + def foo1503(): scala.Int = { /* compiled code */ } + def foo1504(): scala.Int = { /* compiled code */ } + def foo1505(): scala.Int = { /* compiled code */ } + def foo1506(): scala.Int = { /* compiled code */ } + def foo1507(): scala.Int = { /* compiled code */ } + def foo1508(): scala.Int = { /* compiled code */ } + def foo1509(): scala.Int = { /* compiled code */ } + def foo1510(): scala.Int = { /* compiled code */ } + def foo1511(): scala.Int = { /* compiled code */ } + def foo1512(): scala.Int = { /* compiled code */ } + def foo1513(): scala.Int = { /* compiled code */ } + def foo1514(): scala.Int = { /* compiled code */ } + def foo1515(): scala.Int = { /* compiled code */ } + def foo1516(): scala.Int = { /* compiled code */ } + def foo1517(): scala.Int = { /* compiled code */ } + def foo1518(): scala.Int = { /* compiled code */ } + def foo1519(): scala.Int = { /* compiled code */ } + def foo1520(): scala.Int = { /* compiled code */ } + def foo1521(): scala.Int = { /* compiled code */ } + def foo1522(): scala.Int = { /* compiled code */ } + def foo1523(): scala.Int = { /* compiled code */ } + def foo1524(): scala.Int = { /* compiled code */ } + def foo1525(): scala.Int = { /* compiled code */ } + def foo1526(): scala.Int = { /* compiled code */ } + def foo1527(): scala.Int = { /* compiled code */ } + def foo1528(): scala.Int = { /* compiled code */ } + def foo1529(): scala.Int = { /* compiled code */ } + def foo1530(): scala.Int = { /* compiled code */ } + def foo1531(): scala.Int = { /* compiled code */ } + def foo1532(): scala.Int = { /* compiled code */ } + def foo1533(): scala.Int = { /* compiled code */ } + def foo1534(): scala.Int = { /* compiled code */ } + def foo1535(): scala.Int = { /* compiled code */ } + def foo1536(): scala.Int = { /* compiled code */ } + def foo1537(): scala.Int = { /* compiled code */ } + def foo1538(): scala.Int = { /* compiled code */ } + def foo1539(): scala.Int = { /* compiled code */ } + def foo1540(): scala.Int = { /* compiled code */ } + def foo1541(): scala.Int = { /* compiled code */ } + def foo1542(): scala.Int = { /* compiled code */ } + def foo1543(): scala.Int = { /* compiled code */ } + def foo1544(): scala.Int = { /* compiled code */ } + def foo1545(): scala.Int = { /* compiled code */ } + def foo1546(): scala.Int = { /* compiled code */ } + def foo1547(): scala.Int = { /* compiled code */ } + def foo1548(): scala.Int = { /* compiled code */ } + def foo1549(): scala.Int = { /* compiled code */ } + def foo1550(): scala.Int = { /* compiled code */ } + def foo1551(): scala.Int = { /* compiled code */ } + def foo1552(): scala.Int = { /* compiled code */ } + def foo1553(): scala.Int = { /* compiled code */ } + def foo1554(): scala.Int = { /* compiled code */ } + def foo1555(): scala.Int = { /* compiled code */ } + def foo1556(): scala.Int = { /* compiled code */ } + def foo1557(): scala.Int = { /* compiled code */ } + def foo1558(): scala.Int = { /* compiled code */ } + def foo1559(): scala.Int = { /* compiled code */ } + def foo1560(): scala.Int = { /* compiled code */ } + def foo1561(): scala.Int = { /* compiled code */ } + def foo1562(): scala.Int = { /* compiled code */ } + def foo1563(): scala.Int = { /* compiled code */ } + def foo1564(): scala.Int = { /* compiled code */ } + def foo1565(): scala.Int = { /* compiled code */ } + def foo1566(): scala.Int = { /* compiled code */ } + def foo1567(): scala.Int = { /* compiled code */ } + def foo1568(): scala.Int = { /* compiled code */ } + def foo1569(): scala.Int = { /* compiled code */ } + def foo1570(): scala.Int = { /* compiled code */ } + def foo1571(): scala.Int = { /* compiled code */ } + def foo1572(): scala.Int = { /* compiled code */ } + def foo1573(): scala.Int = { /* compiled code */ } + def foo1574(): scala.Int = { /* compiled code */ } + def foo1575(): scala.Int = { /* compiled code */ } + def foo1576(): scala.Int = { /* compiled code */ } + def foo1577(): scala.Int = { /* compiled code */ } + def foo1578(): scala.Int = { /* compiled code */ } + def foo1579(): scala.Int = { /* compiled code */ } + def foo1580(): scala.Int = { /* compiled code */ } + def foo1581(): scala.Int = { /* compiled code */ } + def foo1582(): scala.Int = { /* compiled code */ } + def foo1583(): scala.Int = { /* compiled code */ } + def foo1584(): scala.Int = { /* compiled code */ } + def foo1585(): scala.Int = { /* compiled code */ } + def foo1586(): scala.Int = { /* compiled code */ } + def foo1587(): scala.Int = { /* compiled code */ } + def foo1588(): scala.Int = { /* compiled code */ } + def foo1589(): scala.Int = { /* compiled code */ } + def foo1590(): scala.Int = { /* compiled code */ } + def foo1591(): scala.Int = { /* compiled code */ } + def foo1592(): scala.Int = { /* compiled code */ } + def foo1593(): scala.Int = { /* compiled code */ } + def foo1594(): scala.Int = { /* compiled code */ } + def foo1595(): scala.Int = { /* compiled code */ } + def foo1596(): scala.Int = { /* compiled code */ } + def foo1597(): scala.Int = { /* compiled code */ } + def foo1598(): scala.Int = { /* compiled code */ } + def foo1599(): scala.Int = { /* compiled code */ } + def foo1600(): scala.Int = { /* compiled code */ } + def foo1601(): scala.Int = { /* compiled code */ } + def foo1602(): scala.Int = { /* compiled code */ } + def foo1603(): scala.Int = { /* compiled code */ } + def foo1604(): scala.Int = { /* compiled code */ } + def foo1605(): scala.Int = { /* compiled code */ } + def foo1606(): scala.Int = { /* compiled code */ } + def foo1607(): scala.Int = { /* compiled code */ } + def foo1608(): scala.Int = { /* compiled code */ } + def foo1609(): scala.Int = { /* compiled code */ } + def foo1610(): scala.Int = { /* compiled code */ } + def foo1611(): scala.Int = { /* compiled code */ } + def foo1612(): scala.Int = { /* compiled code */ } + def foo1613(): scala.Int = { /* compiled code */ } + def foo1614(): scala.Int = { /* compiled code */ } + def foo1615(): scala.Int = { /* compiled code */ } + def foo1616(): scala.Int = { /* compiled code */ } + def foo1617(): scala.Int = { /* compiled code */ } + def foo1618(): scala.Int = { /* compiled code */ } + def foo1619(): scala.Int = { /* compiled code */ } + def foo1620(): scala.Int = { /* compiled code */ } + def foo1621(): scala.Int = { /* compiled code */ } + def foo1622(): scala.Int = { /* compiled code */ } + def foo1623(): scala.Int = { /* compiled code */ } + def foo1624(): scala.Int = { /* compiled code */ } + def foo1625(): scala.Int = { /* compiled code */ } + def foo1626(): scala.Int = { /* compiled code */ } + def foo1627(): scala.Int = { /* compiled code */ } + def foo1628(): scala.Int = { /* compiled code */ } + def foo1629(): scala.Int = { /* compiled code */ } + def foo1630(): scala.Int = { /* compiled code */ } + def foo1631(): scala.Int = { /* compiled code */ } + def foo1632(): scala.Int = { /* compiled code */ } + def foo1633(): scala.Int = { /* compiled code */ } + def foo1634(): scala.Int = { /* compiled code */ } + def foo1635(): scala.Int = { /* compiled code */ } + def foo1636(): scala.Int = { /* compiled code */ } + def foo1637(): scala.Int = { /* compiled code */ } + def foo1638(): scala.Int = { /* compiled code */ } + def foo1639(): scala.Int = { /* compiled code */ } + def foo1640(): scala.Int = { /* compiled code */ } + def foo1641(): scala.Int = { /* compiled code */ } + def foo1642(): scala.Int = { /* compiled code */ } + def foo1643(): scala.Int = { /* compiled code */ } + def foo1644(): scala.Int = { /* compiled code */ } + def foo1645(): scala.Int = { /* compiled code */ } + def foo1646(): scala.Int = { /* compiled code */ } + def foo1647(): scala.Int = { /* compiled code */ } + def foo1648(): scala.Int = { /* compiled code */ } + def foo1649(): scala.Int = { /* compiled code */ } + def foo1650(): scala.Int = { /* compiled code */ } + def foo1651(): scala.Int = { /* compiled code */ } + def foo1652(): scala.Int = { /* compiled code */ } + def foo1653(): scala.Int = { /* compiled code */ } + def foo1654(): scala.Int = { /* compiled code */ } + def foo1655(): scala.Int = { /* compiled code */ } + def foo1656(): scala.Int = { /* compiled code */ } + def foo1657(): scala.Int = { /* compiled code */ } + def foo1658(): scala.Int = { /* compiled code */ } + def foo1659(): scala.Int = { /* compiled code */ } + def foo1660(): scala.Int = { /* compiled code */ } + def foo1661(): scala.Int = { /* compiled code */ } + def foo1662(): scala.Int = { /* compiled code */ } + def foo1663(): scala.Int = { /* compiled code */ } + def foo1664(): scala.Int = { /* compiled code */ } + def foo1665(): scala.Int = { /* compiled code */ } + def foo1666(): scala.Int = { /* compiled code */ } + def foo1667(): scala.Int = { /* compiled code */ } + def foo1668(): scala.Int = { /* compiled code */ } + def foo1669(): scala.Int = { /* compiled code */ } + def foo1670(): scala.Int = { /* compiled code */ } + def foo1671(): scala.Int = { /* compiled code */ } + def foo1672(): scala.Int = { /* compiled code */ } + def foo1673(): scala.Int = { /* compiled code */ } + def foo1674(): scala.Int = { /* compiled code */ } + def foo1675(): scala.Int = { /* compiled code */ } + def foo1676(): scala.Int = { /* compiled code */ } + def foo1677(): scala.Int = { /* compiled code */ } + def foo1678(): scala.Int = { /* compiled code */ } + def foo1679(): scala.Int = { /* compiled code */ } + def foo1680(): scala.Int = { /* compiled code */ } + def foo1681(): scala.Int = { /* compiled code */ } + def foo1682(): scala.Int = { /* compiled code */ } + def foo1683(): scala.Int = { /* compiled code */ } + def foo1684(): scala.Int = { /* compiled code */ } + def foo1685(): scala.Int = { /* compiled code */ } + def foo1686(): scala.Int = { /* compiled code */ } + def foo1687(): scala.Int = { /* compiled code */ } + def foo1688(): scala.Int = { /* compiled code */ } + def foo1689(): scala.Int = { /* compiled code */ } + def foo1690(): scala.Int = { /* compiled code */ } + def foo1691(): scala.Int = { /* compiled code */ } + def foo1692(): scala.Int = { /* compiled code */ } + def foo1693(): scala.Int = { /* compiled code */ } + def foo1694(): scala.Int = { /* compiled code */ } + def foo1695(): scala.Int = { /* compiled code */ } + def foo1696(): scala.Int = { /* compiled code */ } + def foo1697(): scala.Int = { /* compiled code */ } + def foo1698(): scala.Int = { /* compiled code */ } + def foo1699(): scala.Int = { /* compiled code */ } + def foo1700(): scala.Int = { /* compiled code */ } + def foo1701(): scala.Int = { /* compiled code */ } + def foo1702(): scala.Int = { /* compiled code */ } + def foo1703(): scala.Int = { /* compiled code */ } + def foo1704(): scala.Int = { /* compiled code */ } + def foo1705(): scala.Int = { /* compiled code */ } + def foo1706(): scala.Int = { /* compiled code */ } + def foo1707(): scala.Int = { /* compiled code */ } + def foo1708(): scala.Int = { /* compiled code */ } + def foo1709(): scala.Int = { /* compiled code */ } + def foo1710(): scala.Int = { /* compiled code */ } + def foo1711(): scala.Int = { /* compiled code */ } + def foo1712(): scala.Int = { /* compiled code */ } + def foo1713(): scala.Int = { /* compiled code */ } + def foo1714(): scala.Int = { /* compiled code */ } + def foo1715(): scala.Int = { /* compiled code */ } + def foo1716(): scala.Int = { /* compiled code */ } + def foo1717(): scala.Int = { /* compiled code */ } + def foo1718(): scala.Int = { /* compiled code */ } + def foo1719(): scala.Int = { /* compiled code */ } + def foo1720(): scala.Int = { /* compiled code */ } + def foo1721(): scala.Int = { /* compiled code */ } + def foo1722(): scala.Int = { /* compiled code */ } + def foo1723(): scala.Int = { /* compiled code */ } + def foo1724(): scala.Int = { /* compiled code */ } + def foo1725(): scala.Int = { /* compiled code */ } + def foo1726(): scala.Int = { /* compiled code */ } + def foo1727(): scala.Int = { /* compiled code */ } + def foo1728(): scala.Int = { /* compiled code */ } + def foo1729(): scala.Int = { /* compiled code */ } + def foo1730(): scala.Int = { /* compiled code */ } + def foo1731(): scala.Int = { /* compiled code */ } + def foo1732(): scala.Int = { /* compiled code */ } + def foo1733(): scala.Int = { /* compiled code */ } + def foo1734(): scala.Int = { /* compiled code */ } + def foo1735(): scala.Int = { /* compiled code */ } + def foo1736(): scala.Int = { /* compiled code */ } + def foo1737(): scala.Int = { /* compiled code */ } + def foo1738(): scala.Int = { /* compiled code */ } + def foo1739(): scala.Int = { /* compiled code */ } + def foo1740(): scala.Int = { /* compiled code */ } + def foo1741(): scala.Int = { /* compiled code */ } + def foo1742(): scala.Int = { /* compiled code */ } + def foo1743(): scala.Int = { /* compiled code */ } + def foo1744(): scala.Int = { /* compiled code */ } + def foo1745(): scala.Int = { /* compiled code */ } + def foo1746(): scala.Int = { /* compiled code */ } + def foo1747(): scala.Int = { /* compiled code */ } + def foo1748(): scala.Int = { /* compiled code */ } + def foo1749(): scala.Int = { /* compiled code */ } + def foo1750(): scala.Int = { /* compiled code */ } + def foo1751(): scala.Int = { /* compiled code */ } + def foo1752(): scala.Int = { /* compiled code */ } + def foo1753(): scala.Int = { /* compiled code */ } + def foo1754(): scala.Int = { /* compiled code */ } + def foo1755(): scala.Int = { /* compiled code */ } + def foo1756(): scala.Int = { /* compiled code */ } + def foo1757(): scala.Int = { /* compiled code */ } + def foo1758(): scala.Int = { /* compiled code */ } + def foo1759(): scala.Int = { /* compiled code */ } + def foo1760(): scala.Int = { /* compiled code */ } + def foo1761(): scala.Int = { /* compiled code */ } + def foo1762(): scala.Int = { /* compiled code */ } + def foo1763(): scala.Int = { /* compiled code */ } + def foo1764(): scala.Int = { /* compiled code */ } + def foo1765(): scala.Int = { /* compiled code */ } + def foo1766(): scala.Int = { /* compiled code */ } + def foo1767(): scala.Int = { /* compiled code */ } + def foo1768(): scala.Int = { /* compiled code */ } + def foo1769(): scala.Int = { /* compiled code */ } + def foo1770(): scala.Int = { /* compiled code */ } + def foo1771(): scala.Int = { /* compiled code */ } + def foo1772(): scala.Int = { /* compiled code */ } + def foo1773(): scala.Int = { /* compiled code */ } + def foo1774(): scala.Int = { /* compiled code */ } + def foo1775(): scala.Int = { /* compiled code */ } + def foo1776(): scala.Int = { /* compiled code */ } + def foo1777(): scala.Int = { /* compiled code */ } + def foo1778(): scala.Int = { /* compiled code */ } + def foo1779(): scala.Int = { /* compiled code */ } + def foo1780(): scala.Int = { /* compiled code */ } + def foo1781(): scala.Int = { /* compiled code */ } + def foo1782(): scala.Int = { /* compiled code */ } + def foo1783(): scala.Int = { /* compiled code */ } + def foo1784(): scala.Int = { /* compiled code */ } + def foo1785(): scala.Int = { /* compiled code */ } + def foo1786(): scala.Int = { /* compiled code */ } + def foo1787(): scala.Int = { /* compiled code */ } + def foo1788(): scala.Int = { /* compiled code */ } + def foo1789(): scala.Int = { /* compiled code */ } + def foo1790(): scala.Int = { /* compiled code */ } + def foo1791(): scala.Int = { /* compiled code */ } + def foo1792(): scala.Int = { /* compiled code */ } + def foo1793(): scala.Int = { /* compiled code */ } + def foo1794(): scala.Int = { /* compiled code */ } + def foo1795(): scala.Int = { /* compiled code */ } + def foo1796(): scala.Int = { /* compiled code */ } + def foo1797(): scala.Int = { /* compiled code */ } + def foo1798(): scala.Int = { /* compiled code */ } + def foo1799(): scala.Int = { /* compiled code */ } + def foo1800(): scala.Int = { /* compiled code */ } + def foo1801(): scala.Int = { /* compiled code */ } + def foo1802(): scala.Int = { /* compiled code */ } + def foo1803(): scala.Int = { /* compiled code */ } + def foo1804(): scala.Int = { /* compiled code */ } + def foo1805(): scala.Int = { /* compiled code */ } + def foo1806(): scala.Int = { /* compiled code */ } + def foo1807(): scala.Int = { /* compiled code */ } + def foo1808(): scala.Int = { /* compiled code */ } + def foo1809(): scala.Int = { /* compiled code */ } + def foo1810(): scala.Int = { /* compiled code */ } + def foo1811(): scala.Int = { /* compiled code */ } + def foo1812(): scala.Int = { /* compiled code */ } + def foo1813(): scala.Int = { /* compiled code */ } + def foo1814(): scala.Int = { /* compiled code */ } + def foo1815(): scala.Int = { /* compiled code */ } + def foo1816(): scala.Int = { /* compiled code */ } + def foo1817(): scala.Int = { /* compiled code */ } + def foo1818(): scala.Int = { /* compiled code */ } + def foo1819(): scala.Int = { /* compiled code */ } + def foo1820(): scala.Int = { /* compiled code */ } + def foo1821(): scala.Int = { /* compiled code */ } + def foo1822(): scala.Int = { /* compiled code */ } + def foo1823(): scala.Int = { /* compiled code */ } + def foo1824(): scala.Int = { /* compiled code */ } + def foo1825(): scala.Int = { /* compiled code */ } + def foo1826(): scala.Int = { /* compiled code */ } + def foo1827(): scala.Int = { /* compiled code */ } + def foo1828(): scala.Int = { /* compiled code */ } + def foo1829(): scala.Int = { /* compiled code */ } + def foo1830(): scala.Int = { /* compiled code */ } + def foo1831(): scala.Int = { /* compiled code */ } + def foo1832(): scala.Int = { /* compiled code */ } + def foo1833(): scala.Int = { /* compiled code */ } + def foo1834(): scala.Int = { /* compiled code */ } + def foo1835(): scala.Int = { /* compiled code */ } + def foo1836(): scala.Int = { /* compiled code */ } + def foo1837(): scala.Int = { /* compiled code */ } + def foo1838(): scala.Int = { /* compiled code */ } + def foo1839(): scala.Int = { /* compiled code */ } + def foo1840(): scala.Int = { /* compiled code */ } + def foo1841(): scala.Int = { /* compiled code */ } + def foo1842(): scala.Int = { /* compiled code */ } + def foo1843(): scala.Int = { /* compiled code */ } + def foo1844(): scala.Int = { /* compiled code */ } + def foo1845(): scala.Int = { /* compiled code */ } + def foo1846(): scala.Int = { /* compiled code */ } + def foo1847(): scala.Int = { /* compiled code */ } + def foo1848(): scala.Int = { /* compiled code */ } + def foo1849(): scala.Int = { /* compiled code */ } + def foo1850(): scala.Int = { /* compiled code */ } + def foo1851(): scala.Int = { /* compiled code */ } + def foo1852(): scala.Int = { /* compiled code */ } + def foo1853(): scala.Int = { /* compiled code */ } + def foo1854(): scala.Int = { /* compiled code */ } + def foo1855(): scala.Int = { /* compiled code */ } + def foo1856(): scala.Int = { /* compiled code */ } + def foo1857(): scala.Int = { /* compiled code */ } + def foo1858(): scala.Int = { /* compiled code */ } + def foo1859(): scala.Int = { /* compiled code */ } + def foo1860(): scala.Int = { /* compiled code */ } + def foo1861(): scala.Int = { /* compiled code */ } + def foo1862(): scala.Int = { /* compiled code */ } + def foo1863(): scala.Int = { /* compiled code */ } + def foo1864(): scala.Int = { /* compiled code */ } + def foo1865(): scala.Int = { /* compiled code */ } + def foo1866(): scala.Int = { /* compiled code */ } + def foo1867(): scala.Int = { /* compiled code */ } + def foo1868(): scala.Int = { /* compiled code */ } + def foo1869(): scala.Int = { /* compiled code */ } + def foo1870(): scala.Int = { /* compiled code */ } + def foo1871(): scala.Int = { /* compiled code */ } + def foo1872(): scala.Int = { /* compiled code */ } + def foo1873(): scala.Int = { /* compiled code */ } + def foo1874(): scala.Int = { /* compiled code */ } + def foo1875(): scala.Int = { /* compiled code */ } + def foo1876(): scala.Int = { /* compiled code */ } + def foo1877(): scala.Int = { /* compiled code */ } + def foo1878(): scala.Int = { /* compiled code */ } + def foo1879(): scala.Int = { /* compiled code */ } + def foo1880(): scala.Int = { /* compiled code */ } + def foo1881(): scala.Int = { /* compiled code */ } + def foo1882(): scala.Int = { /* compiled code */ } + def foo1883(): scala.Int = { /* compiled code */ } + def foo1884(): scala.Int = { /* compiled code */ } + def foo1885(): scala.Int = { /* compiled code */ } + def foo1886(): scala.Int = { /* compiled code */ } + def foo1887(): scala.Int = { /* compiled code */ } + def foo1888(): scala.Int = { /* compiled code */ } + def foo1889(): scala.Int = { /* compiled code */ } + def foo1890(): scala.Int = { /* compiled code */ } + def foo1891(): scala.Int = { /* compiled code */ } + def foo1892(): scala.Int = { /* compiled code */ } + def foo1893(): scala.Int = { /* compiled code */ } + def foo1894(): scala.Int = { /* compiled code */ } + def foo1895(): scala.Int = { /* compiled code */ } + def foo1896(): scala.Int = { /* compiled code */ } + def foo1897(): scala.Int = { /* compiled code */ } + def foo1898(): scala.Int = { /* compiled code */ } + def foo1899(): scala.Int = { /* compiled code */ } + def foo1900(): scala.Int = { /* compiled code */ } + def foo1901(): scala.Int = { /* compiled code */ } + def foo1902(): scala.Int = { /* compiled code */ } + def foo1903(): scala.Int = { /* compiled code */ } + def foo1904(): scala.Int = { /* compiled code */ } + def foo1905(): scala.Int = { /* compiled code */ } + def foo1906(): scala.Int = { /* compiled code */ } + def foo1907(): scala.Int = { /* compiled code */ } + def foo1908(): scala.Int = { /* compiled code */ } + def foo1909(): scala.Int = { /* compiled code */ } + def foo1910(): scala.Int = { /* compiled code */ } + def foo1911(): scala.Int = { /* compiled code */ } + def foo1912(): scala.Int = { /* compiled code */ } + def foo1913(): scala.Int = { /* compiled code */ } + def foo1914(): scala.Int = { /* compiled code */ } + def foo1915(): scala.Int = { /* compiled code */ } + def foo1916(): scala.Int = { /* compiled code */ } + def foo1917(): scala.Int = { /* compiled code */ } + def foo1918(): scala.Int = { /* compiled code */ } + def foo1919(): scala.Int = { /* compiled code */ } + def foo1920(): scala.Int = { /* compiled code */ } + def foo1921(): scala.Int = { /* compiled code */ } + def foo1922(): scala.Int = { /* compiled code */ } + def foo1923(): scala.Int = { /* compiled code */ } + def foo1924(): scala.Int = { /* compiled code */ } + def foo1925(): scala.Int = { /* compiled code */ } + def foo1926(): scala.Int = { /* compiled code */ } + def foo1927(): scala.Int = { /* compiled code */ } + def foo1928(): scala.Int = { /* compiled code */ } + def foo1929(): scala.Int = { /* compiled code */ } + def foo1930(): scala.Int = { /* compiled code */ } + def foo1931(): scala.Int = { /* compiled code */ } + def foo1932(): scala.Int = { /* compiled code */ } + def foo1933(): scala.Int = { /* compiled code */ } + def foo1934(): scala.Int = { /* compiled code */ } + def foo1935(): scala.Int = { /* compiled code */ } + def foo1936(): scala.Int = { /* compiled code */ } + def foo1937(): scala.Int = { /* compiled code */ } + def foo1938(): scala.Int = { /* compiled code */ } + def foo1939(): scala.Int = { /* compiled code */ } + def foo1940(): scala.Int = { /* compiled code */ } + def foo1941(): scala.Int = { /* compiled code */ } + def foo1942(): scala.Int = { /* compiled code */ } + def foo1943(): scala.Int = { /* compiled code */ } + def foo1944(): scala.Int = { /* compiled code */ } + def foo1945(): scala.Int = { /* compiled code */ } + def foo1946(): scala.Int = { /* compiled code */ } + def foo1947(): scala.Int = { /* compiled code */ } + def foo1948(): scala.Int = { /* compiled code */ } + def foo1949(): scala.Int = { /* compiled code */ } + def foo1950(): scala.Int = { /* compiled code */ } + def foo1951(): scala.Int = { /* compiled code */ } + def foo1952(): scala.Int = { /* compiled code */ } + def foo1953(): scala.Int = { /* compiled code */ } + def foo1954(): scala.Int = { /* compiled code */ } + def foo1955(): scala.Int = { /* compiled code */ } + def foo1956(): scala.Int = { /* compiled code */ } + def foo1957(): scala.Int = { /* compiled code */ } + def foo1958(): scala.Int = { /* compiled code */ } + def foo1959(): scala.Int = { /* compiled code */ } + def foo1960(): scala.Int = { /* compiled code */ } + def foo1961(): scala.Int = { /* compiled code */ } + def foo1962(): scala.Int = { /* compiled code */ } + def foo1963(): scala.Int = { /* compiled code */ } + def foo1964(): scala.Int = { /* compiled code */ } + def foo1965(): scala.Int = { /* compiled code */ } + def foo1966(): scala.Int = { /* compiled code */ } + def foo1967(): scala.Int = { /* compiled code */ } + def foo1968(): scala.Int = { /* compiled code */ } + def foo1969(): scala.Int = { /* compiled code */ } + def foo1970(): scala.Int = { /* compiled code */ } + def foo1971(): scala.Int = { /* compiled code */ } + def foo1972(): scala.Int = { /* compiled code */ } + def foo1973(): scala.Int = { /* compiled code */ } + def foo1974(): scala.Int = { /* compiled code */ } + def foo1975(): scala.Int = { /* compiled code */ } + def foo1976(): scala.Int = { /* compiled code */ } + def foo1977(): scala.Int = { /* compiled code */ } + def foo1978(): scala.Int = { /* compiled code */ } + def foo1979(): scala.Int = { /* compiled code */ } + def foo1980(): scala.Int = { /* compiled code */ } + def foo1981(): scala.Int = { /* compiled code */ } + def foo1982(): scala.Int = { /* compiled code */ } + def foo1983(): scala.Int = { /* compiled code */ } + def foo1984(): scala.Int = { /* compiled code */ } + def foo1985(): scala.Int = { /* compiled code */ } + def foo1986(): scala.Int = { /* compiled code */ } + def foo1987(): scala.Int = { /* compiled code */ } + def foo1988(): scala.Int = { /* compiled code */ } + def foo1989(): scala.Int = { /* compiled code */ } + def foo1990(): scala.Int = { /* compiled code */ } + def foo1991(): scala.Int = { /* compiled code */ } + def foo1992(): scala.Int = { /* compiled code */ } + def foo1993(): scala.Int = { /* compiled code */ } + def foo1994(): scala.Int = { /* compiled code */ } + def foo1995(): scala.Int = { /* compiled code */ } + def foo1996(): scala.Int = { /* compiled code */ } + def foo1997(): scala.Int = { /* compiled code */ } + def foo1998(): scala.Int = { /* compiled code */ } + def foo1999(): scala.Int = { /* compiled code */ } + def foo2000(): scala.Int = { /* compiled code */ } + def foo2001(): scala.Int = { /* compiled code */ } + def foo2002(): scala.Int = { /* compiled code */ } + def foo2003(): scala.Int = { /* compiled code */ } + def foo2004(): scala.Int = { /* compiled code */ } + def foo2005(): scala.Int = { /* compiled code */ } + def foo2006(): scala.Int = { /* compiled code */ } + def foo2007(): scala.Int = { /* compiled code */ } + def foo2008(): scala.Int = { /* compiled code */ } + def foo2009(): scala.Int = { /* compiled code */ } + def foo2010(): scala.Int = { /* compiled code */ } + def foo2011(): scala.Int = { /* compiled code */ } + def foo2012(): scala.Int = { /* compiled code */ } + def foo2013(): scala.Int = { /* compiled code */ } + def foo2014(): scala.Int = { /* compiled code */ } + def foo2015(): scala.Int = { /* compiled code */ } + def foo2016(): scala.Int = { /* compiled code */ } + def foo2017(): scala.Int = { /* compiled code */ } + def foo2018(): scala.Int = { /* compiled code */ } + def foo2019(): scala.Int = { /* compiled code */ } + def foo2020(): scala.Int = { /* compiled code */ } + def foo2021(): scala.Int = { /* compiled code */ } + def foo2022(): scala.Int = { /* compiled code */ } + def foo2023(): scala.Int = { /* compiled code */ } + def foo2024(): scala.Int = { /* compiled code */ } + def foo2025(): scala.Int = { /* compiled code */ } + def foo2026(): scala.Int = { /* compiled code */ } + def foo2027(): scala.Int = { /* compiled code */ } + def foo2028(): scala.Int = { /* compiled code */ } + def foo2029(): scala.Int = { /* compiled code */ } + def foo2030(): scala.Int = { /* compiled code */ } + def foo2031(): scala.Int = { /* compiled code */ } + def foo2032(): scala.Int = { /* compiled code */ } + def foo2033(): scala.Int = { /* compiled code */ } + def foo2034(): scala.Int = { /* compiled code */ } + def foo2035(): scala.Int = { /* compiled code */ } + def foo2036(): scala.Int = { /* compiled code */ } + def foo2037(): scala.Int = { /* compiled code */ } + def foo2038(): scala.Int = { /* compiled code */ } + def foo2039(): scala.Int = { /* compiled code */ } + def foo2040(): scala.Int = { /* compiled code */ } + def foo2041(): scala.Int = { /* compiled code */ } + def foo2042(): scala.Int = { /* compiled code */ } + def foo2043(): scala.Int = { /* compiled code */ } + def foo2044(): scala.Int = { /* compiled code */ } + def foo2045(): scala.Int = { /* compiled code */ } + def foo2046(): scala.Int = { /* compiled code */ } + def foo2047(): scala.Int = { /* compiled code */ } + def foo2048(): scala.Int = { /* compiled code */ } + def foo2049(): scala.Int = { /* compiled code */ } + def foo2050(): scala.Int = { /* compiled code */ } + def foo2051(): scala.Int = { /* compiled code */ } + def foo2052(): scala.Int = { /* compiled code */ } + def foo2053(): scala.Int = { /* compiled code */ } + def foo2054(): scala.Int = { /* compiled code */ } + def foo2055(): scala.Int = { /* compiled code */ } + def foo2056(): scala.Int = { /* compiled code */ } + def foo2057(): scala.Int = { /* compiled code */ } + def foo2058(): scala.Int = { /* compiled code */ } + def foo2059(): scala.Int = { /* compiled code */ } + def foo2060(): scala.Int = { /* compiled code */ } + def foo2061(): scala.Int = { /* compiled code */ } + def foo2062(): scala.Int = { /* compiled code */ } + def foo2063(): scala.Int = { /* compiled code */ } + def foo2064(): scala.Int = { /* compiled code */ } + def foo2065(): scala.Int = { /* compiled code */ } + def foo2066(): scala.Int = { /* compiled code */ } + def foo2067(): scala.Int = { /* compiled code */ } + def foo2068(): scala.Int = { /* compiled code */ } + def foo2069(): scala.Int = { /* compiled code */ } + def foo2070(): scala.Int = { /* compiled code */ } + def foo2071(): scala.Int = { /* compiled code */ } + def foo2072(): scala.Int = { /* compiled code */ } + def foo2073(): scala.Int = { /* compiled code */ } + def foo2074(): scala.Int = { /* compiled code */ } + def foo2075(): scala.Int = { /* compiled code */ } + def foo2076(): scala.Int = { /* compiled code */ } + def foo2077(): scala.Int = { /* compiled code */ } + def foo2078(): scala.Int = { /* compiled code */ } + def foo2079(): scala.Int = { /* compiled code */ } + def foo2080(): scala.Int = { /* compiled code */ } + def foo2081(): scala.Int = { /* compiled code */ } + def foo2082(): scala.Int = { /* compiled code */ } + def foo2083(): scala.Int = { /* compiled code */ } + def foo2084(): scala.Int = { /* compiled code */ } + def foo2085(): scala.Int = { /* compiled code */ } + def foo2086(): scala.Int = { /* compiled code */ } + def foo2087(): scala.Int = { /* compiled code */ } + def foo2088(): scala.Int = { /* compiled code */ } + def foo2089(): scala.Int = { /* compiled code */ } + def foo2090(): scala.Int = { /* compiled code */ } + def foo2091(): scala.Int = { /* compiled code */ } + def foo2092(): scala.Int = { /* compiled code */ } + def foo2093(): scala.Int = { /* compiled code */ } + def foo2094(): scala.Int = { /* compiled code */ } + def foo2095(): scala.Int = { /* compiled code */ } + def foo2096(): scala.Int = { /* compiled code */ } + def foo2097(): scala.Int = { /* compiled code */ } + def foo2098(): scala.Int = { /* compiled code */ } + def foo2099(): scala.Int = { /* compiled code */ } + def foo2100(): scala.Int = { /* compiled code */ } + def foo2101(): scala.Int = { /* compiled code */ } + def foo2102(): scala.Int = { /* compiled code */ } + def foo2103(): scala.Int = { /* compiled code */ } + def foo2104(): scala.Int = { /* compiled code */ } + def foo2105(): scala.Int = { /* compiled code */ } + def foo2106(): scala.Int = { /* compiled code */ } + def foo2107(): scala.Int = { /* compiled code */ } + def foo2108(): scala.Int = { /* compiled code */ } + def foo2109(): scala.Int = { /* compiled code */ } + def foo2110(): scala.Int = { /* compiled code */ } + def foo2111(): scala.Int = { /* compiled code */ } + def foo2112(): scala.Int = { /* compiled code */ } + def foo2113(): scala.Int = { /* compiled code */ } + def foo2114(): scala.Int = { /* compiled code */ } + def foo2115(): scala.Int = { /* compiled code */ } + def foo2116(): scala.Int = { /* compiled code */ } + def foo2117(): scala.Int = { /* compiled code */ } + def foo2118(): scala.Int = { /* compiled code */ } + def foo2119(): scala.Int = { /* compiled code */ } + def foo2120(): scala.Int = { /* compiled code */ } + def foo2121(): scala.Int = { /* compiled code */ } + def foo2122(): scala.Int = { /* compiled code */ } + def foo2123(): scala.Int = { /* compiled code */ } + def foo2124(): scala.Int = { /* compiled code */ } + def foo2125(): scala.Int = { /* compiled code */ } + def foo2126(): scala.Int = { /* compiled code */ } + def foo2127(): scala.Int = { /* compiled code */ } + def foo2128(): scala.Int = { /* compiled code */ } + def foo2129(): scala.Int = { /* compiled code */ } + def foo2130(): scala.Int = { /* compiled code */ } + def foo2131(): scala.Int = { /* compiled code */ } + def foo2132(): scala.Int = { /* compiled code */ } + def foo2133(): scala.Int = { /* compiled code */ } + def foo2134(): scala.Int = { /* compiled code */ } + def foo2135(): scala.Int = { /* compiled code */ } + def foo2136(): scala.Int = { /* compiled code */ } + def foo2137(): scala.Int = { /* compiled code */ } + def foo2138(): scala.Int = { /* compiled code */ } + def foo2139(): scala.Int = { /* compiled code */ } + def foo2140(): scala.Int = { /* compiled code */ } + def foo2141(): scala.Int = { /* compiled code */ } + def foo2142(): scala.Int = { /* compiled code */ } + def foo2143(): scala.Int = { /* compiled code */ } + def foo2144(): scala.Int = { /* compiled code */ } + def foo2145(): scala.Int = { /* compiled code */ } + def foo2146(): scala.Int = { /* compiled code */ } + def foo2147(): scala.Int = { /* compiled code */ } + def foo2148(): scala.Int = { /* compiled code */ } + def foo2149(): scala.Int = { /* compiled code */ } + def foo2150(): scala.Int = { /* compiled code */ } + def foo2151(): scala.Int = { /* compiled code */ } + def foo2152(): scala.Int = { /* compiled code */ } + def foo2153(): scala.Int = { /* compiled code */ } + def foo2154(): scala.Int = { /* compiled code */ } + def foo2155(): scala.Int = { /* compiled code */ } + def foo2156(): scala.Int = { /* compiled code */ } + def foo2157(): scala.Int = { /* compiled code */ } + def foo2158(): scala.Int = { /* compiled code */ } + def foo2159(): scala.Int = { /* compiled code */ } + def foo2160(): scala.Int = { /* compiled code */ } + def foo2161(): scala.Int = { /* compiled code */ } + def foo2162(): scala.Int = { /* compiled code */ } + def foo2163(): scala.Int = { /* compiled code */ } + def foo2164(): scala.Int = { /* compiled code */ } + def foo2165(): scala.Int = { /* compiled code */ } + def foo2166(): scala.Int = { /* compiled code */ } + def foo2167(): scala.Int = { /* compiled code */ } + def foo2168(): scala.Int = { /* compiled code */ } + def foo2169(): scala.Int = { /* compiled code */ } + def foo2170(): scala.Int = { /* compiled code */ } + def foo2171(): scala.Int = { /* compiled code */ } + def foo2172(): scala.Int = { /* compiled code */ } + def foo2173(): scala.Int = { /* compiled code */ } + def foo2174(): scala.Int = { /* compiled code */ } + def foo2175(): scala.Int = { /* compiled code */ } + def foo2176(): scala.Int = { /* compiled code */ } + def foo2177(): scala.Int = { /* compiled code */ } + def foo2178(): scala.Int = { /* compiled code */ } + def foo2179(): scala.Int = { /* compiled code */ } + def foo2180(): scala.Int = { /* compiled code */ } + def foo2181(): scala.Int = { /* compiled code */ } + def foo2182(): scala.Int = { /* compiled code */ } + def foo2183(): scala.Int = { /* compiled code */ } + def foo2184(): scala.Int = { /* compiled code */ } + def foo2185(): scala.Int = { /* compiled code */ } + def foo2186(): scala.Int = { /* compiled code */ } + def foo2187(): scala.Int = { /* compiled code */ } + def foo2188(): scala.Int = { /* compiled code */ } + def foo2189(): scala.Int = { /* compiled code */ } + def foo2190(): scala.Int = { /* compiled code */ } + def foo2191(): scala.Int = { /* compiled code */ } + def foo2192(): scala.Int = { /* compiled code */ } + def foo2193(): scala.Int = { /* compiled code */ } + def foo2194(): scala.Int = { /* compiled code */ } + def foo2195(): scala.Int = { /* compiled code */ } + def foo2196(): scala.Int = { /* compiled code */ } + def foo2197(): scala.Int = { /* compiled code */ } + def foo2198(): scala.Int = { /* compiled code */ } + def foo2199(): scala.Int = { /* compiled code */ } + def foo2200(): scala.Int = { /* compiled code */ } + def foo2201(): scala.Int = { /* compiled code */ } + def foo2202(): scala.Int = { /* compiled code */ } + def foo2203(): scala.Int = { /* compiled code */ } + def foo2204(): scala.Int = { /* compiled code */ } + def foo2205(): scala.Int = { /* compiled code */ } + def foo2206(): scala.Int = { /* compiled code */ } + def foo2207(): scala.Int = { /* compiled code */ } + def foo2208(): scala.Int = { /* compiled code */ } + def foo2209(): scala.Int = { /* compiled code */ } + def foo2210(): scala.Int = { /* compiled code */ } + def foo2211(): scala.Int = { /* compiled code */ } + def foo2212(): scala.Int = { /* compiled code */ } + def foo2213(): scala.Int = { /* compiled code */ } + def foo2214(): scala.Int = { /* compiled code */ } + def foo2215(): scala.Int = { /* compiled code */ } + def foo2216(): scala.Int = { /* compiled code */ } + def foo2217(): scala.Int = { /* compiled code */ } + def foo2218(): scala.Int = { /* compiled code */ } + def foo2219(): scala.Int = { /* compiled code */ } + def foo2220(): scala.Int = { /* compiled code */ } + def foo2221(): scala.Int = { /* compiled code */ } + def foo2222(): scala.Int = { /* compiled code */ } + def foo2223(): scala.Int = { /* compiled code */ } + def foo2224(): scala.Int = { /* compiled code */ } + def foo2225(): scala.Int = { /* compiled code */ } + def foo2226(): scala.Int = { /* compiled code */ } + def foo2227(): scala.Int = { /* compiled code */ } + def foo2228(): scala.Int = { /* compiled code */ } + def foo2229(): scala.Int = { /* compiled code */ } + def foo2230(): scala.Int = { /* compiled code */ } + def foo2231(): scala.Int = { /* compiled code */ } + def foo2232(): scala.Int = { /* compiled code */ } + def foo2233(): scala.Int = { /* compiled code */ } + def foo2234(): scala.Int = { /* compiled code */ } + def foo2235(): scala.Int = { /* compiled code */ } + def foo2236(): scala.Int = { /* compiled code */ } + def foo2237(): scala.Int = { /* compiled code */ } + def foo2238(): scala.Int = { /* compiled code */ } + def foo2239(): scala.Int = { /* compiled code */ } + def foo2240(): scala.Int = { /* compiled code */ } + def foo2241(): scala.Int = { /* compiled code */ } + def foo2242(): scala.Int = { /* compiled code */ } + def foo2243(): scala.Int = { /* compiled code */ } + def foo2244(): scala.Int = { /* compiled code */ } + def foo2245(): scala.Int = { /* compiled code */ } + def foo2246(): scala.Int = { /* compiled code */ } + def foo2247(): scala.Int = { /* compiled code */ } + def foo2248(): scala.Int = { /* compiled code */ } + def foo2249(): scala.Int = { /* compiled code */ } + def foo2250(): scala.Int = { /* compiled code */ } + def foo2251(): scala.Int = { /* compiled code */ } + def foo2252(): scala.Int = { /* compiled code */ } + def foo2253(): scala.Int = { /* compiled code */ } + def foo2254(): scala.Int = { /* compiled code */ } + def foo2255(): scala.Int = { /* compiled code */ } + def foo2256(): scala.Int = { /* compiled code */ } + def foo2257(): scala.Int = { /* compiled code */ } + def foo2258(): scala.Int = { /* compiled code */ } + def foo2259(): scala.Int = { /* compiled code */ } + def foo2260(): scala.Int = { /* compiled code */ } + def foo2261(): scala.Int = { /* compiled code */ } + def foo2262(): scala.Int = { /* compiled code */ } + def foo2263(): scala.Int = { /* compiled code */ } + def foo2264(): scala.Int = { /* compiled code */ } + def foo2265(): scala.Int = { /* compiled code */ } + def foo2266(): scala.Int = { /* compiled code */ } + def foo2267(): scala.Int = { /* compiled code */ } + def foo2268(): scala.Int = { /* compiled code */ } + def foo2269(): scala.Int = { /* compiled code */ } + def foo2270(): scala.Int = { /* compiled code */ } + def foo2271(): scala.Int = { /* compiled code */ } + def foo2272(): scala.Int = { /* compiled code */ } + def foo2273(): scala.Int = { /* compiled code */ } + def foo2274(): scala.Int = { /* compiled code */ } + def foo2275(): scala.Int = { /* compiled code */ } + def foo2276(): scala.Int = { /* compiled code */ } + def foo2277(): scala.Int = { /* compiled code */ } + def foo2278(): scala.Int = { /* compiled code */ } + def foo2279(): scala.Int = { /* compiled code */ } + def foo2280(): scala.Int = { /* compiled code */ } + def foo2281(): scala.Int = { /* compiled code */ } + def foo2282(): scala.Int = { /* compiled code */ } + def foo2283(): scala.Int = { /* compiled code */ } + def foo2284(): scala.Int = { /* compiled code */ } + def foo2285(): scala.Int = { /* compiled code */ } + def foo2286(): scala.Int = { /* compiled code */ } + def foo2287(): scala.Int = { /* compiled code */ } + def foo2288(): scala.Int = { /* compiled code */ } + def foo2289(): scala.Int = { /* compiled code */ } + def foo2290(): scala.Int = { /* compiled code */ } + def foo2291(): scala.Int = { /* compiled code */ } + def foo2292(): scala.Int = { /* compiled code */ } + def foo2293(): scala.Int = { /* compiled code */ } + def foo2294(): scala.Int = { /* compiled code */ } + def foo2295(): scala.Int = { /* compiled code */ } + def foo2296(): scala.Int = { /* compiled code */ } + def foo2297(): scala.Int = { /* compiled code */ } + def foo2298(): scala.Int = { /* compiled code */ } + def foo2299(): scala.Int = { /* compiled code */ } + def foo2300(): scala.Int = { /* compiled code */ } + def foo2301(): scala.Int = { /* compiled code */ } + def foo2302(): scala.Int = { /* compiled code */ } + def foo2303(): scala.Int = { /* compiled code */ } + def foo2304(): scala.Int = { /* compiled code */ } + def foo2305(): scala.Int = { /* compiled code */ } + def foo2306(): scala.Int = { /* compiled code */ } + def foo2307(): scala.Int = { /* compiled code */ } + def foo2308(): scala.Int = { /* compiled code */ } + def foo2309(): scala.Int = { /* compiled code */ } + def foo2310(): scala.Int = { /* compiled code */ } + def foo2311(): scala.Int = { /* compiled code */ } + def foo2312(): scala.Int = { /* compiled code */ } + def foo2313(): scala.Int = { /* compiled code */ } + def foo2314(): scala.Int = { /* compiled code */ } + def foo2315(): scala.Int = { /* compiled code */ } + def foo2316(): scala.Int = { /* compiled code */ } + def foo2317(): scala.Int = { /* compiled code */ } + def foo2318(): scala.Int = { /* compiled code */ } + def foo2319(): scala.Int = { /* compiled code */ } + def foo2320(): scala.Int = { /* compiled code */ } + def foo2321(): scala.Int = { /* compiled code */ } + def foo2322(): scala.Int = { /* compiled code */ } + def foo2323(): scala.Int = { /* compiled code */ } + def foo2324(): scala.Int = { /* compiled code */ } + def foo2325(): scala.Int = { /* compiled code */ } + def foo2326(): scala.Int = { /* compiled code */ } + def foo2327(): scala.Int = { /* compiled code */ } + def foo2328(): scala.Int = { /* compiled code */ } + def foo2329(): scala.Int = { /* compiled code */ } + def foo2330(): scala.Int = { /* compiled code */ } + def foo2331(): scala.Int = { /* compiled code */ } + def foo2332(): scala.Int = { /* compiled code */ } + def foo2333(): scala.Int = { /* compiled code */ } + def foo2334(): scala.Int = { /* compiled code */ } + def foo2335(): scala.Int = { /* compiled code */ } + def foo2336(): scala.Int = { /* compiled code */ } + def foo2337(): scala.Int = { /* compiled code */ } + def foo2338(): scala.Int = { /* compiled code */ } + def foo2339(): scala.Int = { /* compiled code */ } + def foo2340(): scala.Int = { /* compiled code */ } + def foo2341(): scala.Int = { /* compiled code */ } + def foo2342(): scala.Int = { /* compiled code */ } + def foo2343(): scala.Int = { /* compiled code */ } + def foo2344(): scala.Int = { /* compiled code */ } + def foo2345(): scala.Int = { /* compiled code */ } + def foo2346(): scala.Int = { /* compiled code */ } + def foo2347(): scala.Int = { /* compiled code */ } + def foo2348(): scala.Int = { /* compiled code */ } + def foo2349(): scala.Int = { /* compiled code */ } + def foo2350(): scala.Int = { /* compiled code */ } + def foo2351(): scala.Int = { /* compiled code */ } + def foo2352(): scala.Int = { /* compiled code */ } + def foo2353(): scala.Int = { /* compiled code */ } + def foo2354(): scala.Int = { /* compiled code */ } + def foo2355(): scala.Int = { /* compiled code */ } + def foo2356(): scala.Int = { /* compiled code */ } + def foo2357(): scala.Int = { /* compiled code */ } + def foo2358(): scala.Int = { /* compiled code */ } + def foo2359(): scala.Int = { /* compiled code */ } + def foo2360(): scala.Int = { /* compiled code */ } + def foo2361(): scala.Int = { /* compiled code */ } + def foo2362(): scala.Int = { /* compiled code */ } + def foo2363(): scala.Int = { /* compiled code */ } + def foo2364(): scala.Int = { /* compiled code */ } + def foo2365(): scala.Int = { /* compiled code */ } + def foo2366(): scala.Int = { /* compiled code */ } + def foo2367(): scala.Int = { /* compiled code */ } + def foo2368(): scala.Int = { /* compiled code */ } + def foo2369(): scala.Int = { /* compiled code */ } + def foo2370(): scala.Int = { /* compiled code */ } + def foo2371(): scala.Int = { /* compiled code */ } + def foo2372(): scala.Int = { /* compiled code */ } + def foo2373(): scala.Int = { /* compiled code */ } + def foo2374(): scala.Int = { /* compiled code */ } + def foo2375(): scala.Int = { /* compiled code */ } + def foo2376(): scala.Int = { /* compiled code */ } + def foo2377(): scala.Int = { /* compiled code */ } + def foo2378(): scala.Int = { /* compiled code */ } + def foo2379(): scala.Int = { /* compiled code */ } + def foo2380(): scala.Int = { /* compiled code */ } + def foo2381(): scala.Int = { /* compiled code */ } + def foo2382(): scala.Int = { /* compiled code */ } + def foo2383(): scala.Int = { /* compiled code */ } + def foo2384(): scala.Int = { /* compiled code */ } + def foo2385(): scala.Int = { /* compiled code */ } + def foo2386(): scala.Int = { /* compiled code */ } + def foo2387(): scala.Int = { /* compiled code */ } + def foo2388(): scala.Int = { /* compiled code */ } + def foo2389(): scala.Int = { /* compiled code */ } + def foo2390(): scala.Int = { /* compiled code */ } + def foo2391(): scala.Int = { /* compiled code */ } + def foo2392(): scala.Int = { /* compiled code */ } + def foo2393(): scala.Int = { /* compiled code */ } + def foo2394(): scala.Int = { /* compiled code */ } + def foo2395(): scala.Int = { /* compiled code */ } + def foo2396(): scala.Int = { /* compiled code */ } + def foo2397(): scala.Int = { /* compiled code */ } + def foo2398(): scala.Int = { /* compiled code */ } + def foo2399(): scala.Int = { /* compiled code */ } + def foo2400(): scala.Int = { /* compiled code */ } + def foo2401(): scala.Int = { /* compiled code */ } + def foo2402(): scala.Int = { /* compiled code */ } + def foo2403(): scala.Int = { /* compiled code */ } + def foo2404(): scala.Int = { /* compiled code */ } + def foo2405(): scala.Int = { /* compiled code */ } + def foo2406(): scala.Int = { /* compiled code */ } + def foo2407(): scala.Int = { /* compiled code */ } + def foo2408(): scala.Int = { /* compiled code */ } + def foo2409(): scala.Int = { /* compiled code */ } + def foo2410(): scala.Int = { /* compiled code */ } + def foo2411(): scala.Int = { /* compiled code */ } + def foo2412(): scala.Int = { /* compiled code */ } + def foo2413(): scala.Int = { /* compiled code */ } + def foo2414(): scala.Int = { /* compiled code */ } + def foo2415(): scala.Int = { /* compiled code */ } + def foo2416(): scala.Int = { /* compiled code */ } + def foo2417(): scala.Int = { /* compiled code */ } + def foo2418(): scala.Int = { /* compiled code */ } + def foo2419(): scala.Int = { /* compiled code */ } + def foo2420(): scala.Int = { /* compiled code */ } + def foo2421(): scala.Int = { /* compiled code */ } + def foo2422(): scala.Int = { /* compiled code */ } + def foo2423(): scala.Int = { /* compiled code */ } + def foo2424(): scala.Int = { /* compiled code */ } + def foo2425(): scala.Int = { /* compiled code */ } + def foo2426(): scala.Int = { /* compiled code */ } + def foo2427(): scala.Int = { /* compiled code */ } + def foo2428(): scala.Int = { /* compiled code */ } + def foo2429(): scala.Int = { /* compiled code */ } + def foo2430(): scala.Int = { /* compiled code */ } + def foo2431(): scala.Int = { /* compiled code */ } + def foo2432(): scala.Int = { /* compiled code */ } + def foo2433(): scala.Int = { /* compiled code */ } + def foo2434(): scala.Int = { /* compiled code */ } + def foo2435(): scala.Int = { /* compiled code */ } + def foo2436(): scala.Int = { /* compiled code */ } + def foo2437(): scala.Int = { /* compiled code */ } + def foo2438(): scala.Int = { /* compiled code */ } + def foo2439(): scala.Int = { /* compiled code */ } + def foo2440(): scala.Int = { /* compiled code */ } + def foo2441(): scala.Int = { /* compiled code */ } + def foo2442(): scala.Int = { /* compiled code */ } + def foo2443(): scala.Int = { /* compiled code */ } + def foo2444(): scala.Int = { /* compiled code */ } + def foo2445(): scala.Int = { /* compiled code */ } + def foo2446(): scala.Int = { /* compiled code */ } + def foo2447(): scala.Int = { /* compiled code */ } + def foo2448(): scala.Int = { /* compiled code */ } + def foo2449(): scala.Int = { /* compiled code */ } + def foo2450(): scala.Int = { /* compiled code */ } + def foo2451(): scala.Int = { /* compiled code */ } + def foo2452(): scala.Int = { /* compiled code */ } + def foo2453(): scala.Int = { /* compiled code */ } + def foo2454(): scala.Int = { /* compiled code */ } + def foo2455(): scala.Int = { /* compiled code */ } + def foo2456(): scala.Int = { /* compiled code */ } + def foo2457(): scala.Int = { /* compiled code */ } + def foo2458(): scala.Int = { /* compiled code */ } + def foo2459(): scala.Int = { /* compiled code */ } + def foo2460(): scala.Int = { /* compiled code */ } + def foo2461(): scala.Int = { /* compiled code */ } + def foo2462(): scala.Int = { /* compiled code */ } + def foo2463(): scala.Int = { /* compiled code */ } + def foo2464(): scala.Int = { /* compiled code */ } + def foo2465(): scala.Int = { /* compiled code */ } + def foo2466(): scala.Int = { /* compiled code */ } + def foo2467(): scala.Int = { /* compiled code */ } + def foo2468(): scala.Int = { /* compiled code */ } + def foo2469(): scala.Int = { /* compiled code */ } + def foo2470(): scala.Int = { /* compiled code */ } + def foo2471(): scala.Int = { /* compiled code */ } + def foo2472(): scala.Int = { /* compiled code */ } + def foo2473(): scala.Int = { /* compiled code */ } + def foo2474(): scala.Int = { /* compiled code */ } + def foo2475(): scala.Int = { /* compiled code */ } + def foo2476(): scala.Int = { /* compiled code */ } + def foo2477(): scala.Int = { /* compiled code */ } + def foo2478(): scala.Int = { /* compiled code */ } + def foo2479(): scala.Int = { /* compiled code */ } + def foo2480(): scala.Int = { /* compiled code */ } + def foo2481(): scala.Int = { /* compiled code */ } + def foo2482(): scala.Int = { /* compiled code */ } + def foo2483(): scala.Int = { /* compiled code */ } + def foo2484(): scala.Int = { /* compiled code */ } + def foo2485(): scala.Int = { /* compiled code */ } + def foo2486(): scala.Int = { /* compiled code */ } + def foo2487(): scala.Int = { /* compiled code */ } + def foo2488(): scala.Int = { /* compiled code */ } + def foo2489(): scala.Int = { /* compiled code */ } + def foo2490(): scala.Int = { /* compiled code */ } + def foo2491(): scala.Int = { /* compiled code */ } + def foo2492(): scala.Int = { /* compiled code */ } + def foo2493(): scala.Int = { /* compiled code */ } + def foo2494(): scala.Int = { /* compiled code */ } + def foo2495(): scala.Int = { /* compiled code */ } + def foo2496(): scala.Int = { /* compiled code */ } + def foo2497(): scala.Int = { /* compiled code */ } + def foo2498(): scala.Int = { /* compiled code */ } + def foo2499(): scala.Int = { /* compiled code */ } + def foo2500(): scala.Int = { /* compiled code */ } + def foo2501(): scala.Int = { /* compiled code */ } + def foo2502(): scala.Int = { /* compiled code */ } + def foo2503(): scala.Int = { /* compiled code */ } + def foo2504(): scala.Int = { /* compiled code */ } + def foo2505(): scala.Int = { /* compiled code */ } + def foo2506(): scala.Int = { /* compiled code */ } + def foo2507(): scala.Int = { /* compiled code */ } + def foo2508(): scala.Int = { /* compiled code */ } + def foo2509(): scala.Int = { /* compiled code */ } + def foo2510(): scala.Int = { /* compiled code */ } + def foo2511(): scala.Int = { /* compiled code */ } + def foo2512(): scala.Int = { /* compiled code */ } + def foo2513(): scala.Int = { /* compiled code */ } + def foo2514(): scala.Int = { /* compiled code */ } + def foo2515(): scala.Int = { /* compiled code */ } + def foo2516(): scala.Int = { /* compiled code */ } + def foo2517(): scala.Int = { /* compiled code */ } + def foo2518(): scala.Int = { /* compiled code */ } + def foo2519(): scala.Int = { /* compiled code */ } + def foo2520(): scala.Int = { /* compiled code */ } + def foo2521(): scala.Int = { /* compiled code */ } + def foo2522(): scala.Int = { /* compiled code */ } + def foo2523(): scala.Int = { /* compiled code */ } + def foo2524(): scala.Int = { /* compiled code */ } + def foo2525(): scala.Int = { /* compiled code */ } + def foo2526(): scala.Int = { /* compiled code */ } + def foo2527(): scala.Int = { /* compiled code */ } + def foo2528(): scala.Int = { /* compiled code */ } + def foo2529(): scala.Int = { /* compiled code */ } + def foo2530(): scala.Int = { /* compiled code */ } + def foo2531(): scala.Int = { /* compiled code */ } + def foo2532(): scala.Int = { /* compiled code */ } + def foo2533(): scala.Int = { /* compiled code */ } + def foo2534(): scala.Int = { /* compiled code */ } + def foo2535(): scala.Int = { /* compiled code */ } + def foo2536(): scala.Int = { /* compiled code */ } + def foo2537(): scala.Int = { /* compiled code */ } + def foo2538(): scala.Int = { /* compiled code */ } + def foo2539(): scala.Int = { /* compiled code */ } + def foo2540(): scala.Int = { /* compiled code */ } + def foo2541(): scala.Int = { /* compiled code */ } + def foo2542(): scala.Int = { /* compiled code */ } + def foo2543(): scala.Int = { /* compiled code */ } + def foo2544(): scala.Int = { /* compiled code */ } + def foo2545(): scala.Int = { /* compiled code */ } + def foo2546(): scala.Int = { /* compiled code */ } + def foo2547(): scala.Int = { /* compiled code */ } + def foo2548(): scala.Int = { /* compiled code */ } + def foo2549(): scala.Int = { /* compiled code */ } + def foo2550(): scala.Int = { /* compiled code */ } + def foo2551(): scala.Int = { /* compiled code */ } + def foo2552(): scala.Int = { /* compiled code */ } + def foo2553(): scala.Int = { /* compiled code */ } + def foo2554(): scala.Int = { /* compiled code */ } + def foo2555(): scala.Int = { /* compiled code */ } + def foo2556(): scala.Int = { /* compiled code */ } + def foo2557(): scala.Int = { /* compiled code */ } + def foo2558(): scala.Int = { /* compiled code */ } + def foo2559(): scala.Int = { /* compiled code */ } + def foo2560(): scala.Int = { /* compiled code */ } + def foo2561(): scala.Int = { /* compiled code */ } + def foo2562(): scala.Int = { /* compiled code */ } + def foo2563(): scala.Int = { /* compiled code */ } + def foo2564(): scala.Int = { /* compiled code */ } + def foo2565(): scala.Int = { /* compiled code */ } + def foo2566(): scala.Int = { /* compiled code */ } + def foo2567(): scala.Int = { /* compiled code */ } + def foo2568(): scala.Int = { /* compiled code */ } + def foo2569(): scala.Int = { /* compiled code */ } + def foo2570(): scala.Int = { /* compiled code */ } + def foo2571(): scala.Int = { /* compiled code */ } + def foo2572(): scala.Int = { /* compiled code */ } + def foo2573(): scala.Int = { /* compiled code */ } + def foo2574(): scala.Int = { /* compiled code */ } + def foo2575(): scala.Int = { /* compiled code */ } + def foo2576(): scala.Int = { /* compiled code */ } + def foo2577(): scala.Int = { /* compiled code */ } + def foo2578(): scala.Int = { /* compiled code */ } + def foo2579(): scala.Int = { /* compiled code */ } + def foo2580(): scala.Int = { /* compiled code */ } + def foo2581(): scala.Int = { /* compiled code */ } + def foo2582(): scala.Int = { /* compiled code */ } + def foo2583(): scala.Int = { /* compiled code */ } + def foo2584(): scala.Int = { /* compiled code */ } + def foo2585(): scala.Int = { /* compiled code */ } + def foo2586(): scala.Int = { /* compiled code */ } + def foo2587(): scala.Int = { /* compiled code */ } + def foo2588(): scala.Int = { /* compiled code */ } + def foo2589(): scala.Int = { /* compiled code */ } + def foo2590(): scala.Int = { /* compiled code */ } + def foo2591(): scala.Int = { /* compiled code */ } + def foo2592(): scala.Int = { /* compiled code */ } + def foo2593(): scala.Int = { /* compiled code */ } + def foo2594(): scala.Int = { /* compiled code */ } + def foo2595(): scala.Int = { /* compiled code */ } + def foo2596(): scala.Int = { /* compiled code */ } + def foo2597(): scala.Int = { /* compiled code */ } + def foo2598(): scala.Int = { /* compiled code */ } + def foo2599(): scala.Int = { /* compiled code */ } + def foo2600(): scala.Int = { /* compiled code */ } + def foo2601(): scala.Int = { /* compiled code */ } + def foo2602(): scala.Int = { /* compiled code */ } + def foo2603(): scala.Int = { /* compiled code */ } + def foo2604(): scala.Int = { /* compiled code */ } + def foo2605(): scala.Int = { /* compiled code */ } + def foo2606(): scala.Int = { /* compiled code */ } + def foo2607(): scala.Int = { /* compiled code */ } + def foo2608(): scala.Int = { /* compiled code */ } + def foo2609(): scala.Int = { /* compiled code */ } + def foo2610(): scala.Int = { /* compiled code */ } + def foo2611(): scala.Int = { /* compiled code */ } + def foo2612(): scala.Int = { /* compiled code */ } + def foo2613(): scala.Int = { /* compiled code */ } + def foo2614(): scala.Int = { /* compiled code */ } + def foo2615(): scala.Int = { /* compiled code */ } + def foo2616(): scala.Int = { /* compiled code */ } + def foo2617(): scala.Int = { /* compiled code */ } + def foo2618(): scala.Int = { /* compiled code */ } + def foo2619(): scala.Int = { /* compiled code */ } + def foo2620(): scala.Int = { /* compiled code */ } + def foo2621(): scala.Int = { /* compiled code */ } + def foo2622(): scala.Int = { /* compiled code */ } + def foo2623(): scala.Int = { /* compiled code */ } + def foo2624(): scala.Int = { /* compiled code */ } + def foo2625(): scala.Int = { /* compiled code */ } + def foo2626(): scala.Int = { /* compiled code */ } + def foo2627(): scala.Int = { /* compiled code */ } + def foo2628(): scala.Int = { /* compiled code */ } + def foo2629(): scala.Int = { /* compiled code */ } + def foo2630(): scala.Int = { /* compiled code */ } + def foo2631(): scala.Int = { /* compiled code */ } + def foo2632(): scala.Int = { /* compiled code */ } + def foo2633(): scala.Int = { /* compiled code */ } + def foo2634(): scala.Int = { /* compiled code */ } + def foo2635(): scala.Int = { /* compiled code */ } + def foo2636(): scala.Int = { /* compiled code */ } + def foo2637(): scala.Int = { /* compiled code */ } + def foo2638(): scala.Int = { /* compiled code */ } + def foo2639(): scala.Int = { /* compiled code */ } + def foo2640(): scala.Int = { /* compiled code */ } + def foo2641(): scala.Int = { /* compiled code */ } + def foo2642(): scala.Int = { /* compiled code */ } + def foo2643(): scala.Int = { /* compiled code */ } + def foo2644(): scala.Int = { /* compiled code */ } + def foo2645(): scala.Int = { /* compiled code */ } + def foo2646(): scala.Int = { /* compiled code */ } + def foo2647(): scala.Int = { /* compiled code */ } + def foo2648(): scala.Int = { /* compiled code */ } + def foo2649(): scala.Int = { /* compiled code */ } + def foo2650(): scala.Int = { /* compiled code */ } + def foo2651(): scala.Int = { /* compiled code */ } + def foo2652(): scala.Int = { /* compiled code */ } + def foo2653(): scala.Int = { /* compiled code */ } + def foo2654(): scala.Int = { /* compiled code */ } + def foo2655(): scala.Int = { /* compiled code */ } + def foo2656(): scala.Int = { /* compiled code */ } + def foo2657(): scala.Int = { /* compiled code */ } + def foo2658(): scala.Int = { /* compiled code */ } + def foo2659(): scala.Int = { /* compiled code */ } + def foo2660(): scala.Int = { /* compiled code */ } + def foo2661(): scala.Int = { /* compiled code */ } + def foo2662(): scala.Int = { /* compiled code */ } + def foo2663(): scala.Int = { /* compiled code */ } + def foo2664(): scala.Int = { /* compiled code */ } + def foo2665(): scala.Int = { /* compiled code */ } + def foo2666(): scala.Int = { /* compiled code */ } + def foo2667(): scala.Int = { /* compiled code */ } + def foo2668(): scala.Int = { /* compiled code */ } + def foo2669(): scala.Int = { /* compiled code */ } + def foo2670(): scala.Int = { /* compiled code */ } + def foo2671(): scala.Int = { /* compiled code */ } + def foo2672(): scala.Int = { /* compiled code */ } + def foo2673(): scala.Int = { /* compiled code */ } + def foo2674(): scala.Int = { /* compiled code */ } + def foo2675(): scala.Int = { /* compiled code */ } + def foo2676(): scala.Int = { /* compiled code */ } + def foo2677(): scala.Int = { /* compiled code */ } + def foo2678(): scala.Int = { /* compiled code */ } + def foo2679(): scala.Int = { /* compiled code */ } + def foo2680(): scala.Int = { /* compiled code */ } + def foo2681(): scala.Int = { /* compiled code */ } + def foo2682(): scala.Int = { /* compiled code */ } + def foo2683(): scala.Int = { /* compiled code */ } + def foo2684(): scala.Int = { /* compiled code */ } + def foo2685(): scala.Int = { /* compiled code */ } + def foo2686(): scala.Int = { /* compiled code */ } + def foo2687(): scala.Int = { /* compiled code */ } + def foo2688(): scala.Int = { /* compiled code */ } + def foo2689(): scala.Int = { /* compiled code */ } + def foo2690(): scala.Int = { /* compiled code */ } + def foo2691(): scala.Int = { /* compiled code */ } + def foo2692(): scala.Int = { /* compiled code */ } + def foo2693(): scala.Int = { /* compiled code */ } + def foo2694(): scala.Int = { /* compiled code */ } + def foo2695(): scala.Int = { /* compiled code */ } + def foo2696(): scala.Int = { /* compiled code */ } + def foo2697(): scala.Int = { /* compiled code */ } + def foo2698(): scala.Int = { /* compiled code */ } + def foo2699(): scala.Int = { /* compiled code */ } + def foo2700(): scala.Int = { /* compiled code */ } + def foo2701(): scala.Int = { /* compiled code */ } + def foo2702(): scala.Int = { /* compiled code */ } + def foo2703(): scala.Int = { /* compiled code */ } + def foo2704(): scala.Int = { /* compiled code */ } + def foo2705(): scala.Int = { /* compiled code */ } + def foo2706(): scala.Int = { /* compiled code */ } + def foo2707(): scala.Int = { /* compiled code */ } + def foo2708(): scala.Int = { /* compiled code */ } + def foo2709(): scala.Int = { /* compiled code */ } + def foo2710(): scala.Int = { /* compiled code */ } + def foo2711(): scala.Int = { /* compiled code */ } + def foo2712(): scala.Int = { /* compiled code */ } + def foo2713(): scala.Int = { /* compiled code */ } + def foo2714(): scala.Int = { /* compiled code */ } + def foo2715(): scala.Int = { /* compiled code */ } + def foo2716(): scala.Int = { /* compiled code */ } + def foo2717(): scala.Int = { /* compiled code */ } + def foo2718(): scala.Int = { /* compiled code */ } + def foo2719(): scala.Int = { /* compiled code */ } + def foo2720(): scala.Int = { /* compiled code */ } + def foo2721(): scala.Int = { /* compiled code */ } + def foo2722(): scala.Int = { /* compiled code */ } + def foo2723(): scala.Int = { /* compiled code */ } + def foo2724(): scala.Int = { /* compiled code */ } + def foo2725(): scala.Int = { /* compiled code */ } + def foo2726(): scala.Int = { /* compiled code */ } + def foo2727(): scala.Int = { /* compiled code */ } + def foo2728(): scala.Int = { /* compiled code */ } + def foo2729(): scala.Int = { /* compiled code */ } + def foo2730(): scala.Int = { /* compiled code */ } + def foo2731(): scala.Int = { /* compiled code */ } + def foo2732(): scala.Int = { /* compiled code */ } + def foo2733(): scala.Int = { /* compiled code */ } + def foo2734(): scala.Int = { /* compiled code */ } + def foo2735(): scala.Int = { /* compiled code */ } + def foo2736(): scala.Int = { /* compiled code */ } + def foo2737(): scala.Int = { /* compiled code */ } + def foo2738(): scala.Int = { /* compiled code */ } + def foo2739(): scala.Int = { /* compiled code */ } + def foo2740(): scala.Int = { /* compiled code */ } + def foo2741(): scala.Int = { /* compiled code */ } + def foo2742(): scala.Int = { /* compiled code */ } + def foo2743(): scala.Int = { /* compiled code */ } + def foo2744(): scala.Int = { /* compiled code */ } + def foo2745(): scala.Int = { /* compiled code */ } + def foo2746(): scala.Int = { /* compiled code */ } + def foo2747(): scala.Int = { /* compiled code */ } + def foo2748(): scala.Int = { /* compiled code */ } + def foo2749(): scala.Int = { /* compiled code */ } + def foo2750(): scala.Int = { /* compiled code */ } + def foo2751(): scala.Int = { /* compiled code */ } + def foo2752(): scala.Int = { /* compiled code */ } + def foo2753(): scala.Int = { /* compiled code */ } + def foo2754(): scala.Int = { /* compiled code */ } + def foo2755(): scala.Int = { /* compiled code */ } + def foo2756(): scala.Int = { /* compiled code */ } + def foo2757(): scala.Int = { /* compiled code */ } + def foo2758(): scala.Int = { /* compiled code */ } + def foo2759(): scala.Int = { /* compiled code */ } + def foo2760(): scala.Int = { /* compiled code */ } + def foo2761(): scala.Int = { /* compiled code */ } + def foo2762(): scala.Int = { /* compiled code */ } + def foo2763(): scala.Int = { /* compiled code */ } + def foo2764(): scala.Int = { /* compiled code */ } + def foo2765(): scala.Int = { /* compiled code */ } + def foo2766(): scala.Int = { /* compiled code */ } + def foo2767(): scala.Int = { /* compiled code */ } + def foo2768(): scala.Int = { /* compiled code */ } + def foo2769(): scala.Int = { /* compiled code */ } + def foo2770(): scala.Int = { /* compiled code */ } + def foo2771(): scala.Int = { /* compiled code */ } + def foo2772(): scala.Int = { /* compiled code */ } + def foo2773(): scala.Int = { /* compiled code */ } + def foo2774(): scala.Int = { /* compiled code */ } + def foo2775(): scala.Int = { /* compiled code */ } + def foo2776(): scala.Int = { /* compiled code */ } + def foo2777(): scala.Int = { /* compiled code */ } + def foo2778(): scala.Int = { /* compiled code */ } + def foo2779(): scala.Int = { /* compiled code */ } + def foo2780(): scala.Int = { /* compiled code */ } + def foo2781(): scala.Int = { /* compiled code */ } + def foo2782(): scala.Int = { /* compiled code */ } + def foo2783(): scala.Int = { /* compiled code */ } + def foo2784(): scala.Int = { /* compiled code */ } + def foo2785(): scala.Int = { /* compiled code */ } + def foo2786(): scala.Int = { /* compiled code */ } + def foo2787(): scala.Int = { /* compiled code */ } + def foo2788(): scala.Int = { /* compiled code */ } + def foo2789(): scala.Int = { /* compiled code */ } + def foo2790(): scala.Int = { /* compiled code */ } + def foo2791(): scala.Int = { /* compiled code */ } + def foo2792(): scala.Int = { /* compiled code */ } + def foo2793(): scala.Int = { /* compiled code */ } + def foo2794(): scala.Int = { /* compiled code */ } + def foo2795(): scala.Int = { /* compiled code */ } + def foo2796(): scala.Int = { /* compiled code */ } + def foo2797(): scala.Int = { /* compiled code */ } + def foo2798(): scala.Int = { /* compiled code */ } + def foo2799(): scala.Int = { /* compiled code */ } + def foo2800(): scala.Int = { /* compiled code */ } + def foo2801(): scala.Int = { /* compiled code */ } + def foo2802(): scala.Int = { /* compiled code */ } + def foo2803(): scala.Int = { /* compiled code */ } + def foo2804(): scala.Int = { /* compiled code */ } + def foo2805(): scala.Int = { /* compiled code */ } + def foo2806(): scala.Int = { /* compiled code */ } + def foo2807(): scala.Int = { /* compiled code */ } + def foo2808(): scala.Int = { /* compiled code */ } + def foo2809(): scala.Int = { /* compiled code */ } + def foo2810(): scala.Int = { /* compiled code */ } + def foo2811(): scala.Int = { /* compiled code */ } + def foo2812(): scala.Int = { /* compiled code */ } + def foo2813(): scala.Int = { /* compiled code */ } + def foo2814(): scala.Int = { /* compiled code */ } + def foo2815(): scala.Int = { /* compiled code */ } + def foo2816(): scala.Int = { /* compiled code */ } + def foo2817(): scala.Int = { /* compiled code */ } + def foo2818(): scala.Int = { /* compiled code */ } + def foo2819(): scala.Int = { /* compiled code */ } + def foo2820(): scala.Int = { /* compiled code */ } + def foo2821(): scala.Int = { /* compiled code */ } + def foo2822(): scala.Int = { /* compiled code */ } + def foo2823(): scala.Int = { /* compiled code */ } + def foo2824(): scala.Int = { /* compiled code */ } + def foo2825(): scala.Int = { /* compiled code */ } + def foo2826(): scala.Int = { /* compiled code */ } + def foo2827(): scala.Int = { /* compiled code */ } + def foo2828(): scala.Int = { /* compiled code */ } + def foo2829(): scala.Int = { /* compiled code */ } + def foo2830(): scala.Int = { /* compiled code */ } + def foo2831(): scala.Int = { /* compiled code */ } + def foo2832(): scala.Int = { /* compiled code */ } + def foo2833(): scala.Int = { /* compiled code */ } + def foo2834(): scala.Int = { /* compiled code */ } + def foo2835(): scala.Int = { /* compiled code */ } + def foo2836(): scala.Int = { /* compiled code */ } + def foo2837(): scala.Int = { /* compiled code */ } + def foo2838(): scala.Int = { /* compiled code */ } + def foo2839(): scala.Int = { /* compiled code */ } + def foo2840(): scala.Int = { /* compiled code */ } + def foo2841(): scala.Int = { /* compiled code */ } + def foo2842(): scala.Int = { /* compiled code */ } + def foo2843(): scala.Int = { /* compiled code */ } + def foo2844(): scala.Int = { /* compiled code */ } + def foo2845(): scala.Int = { /* compiled code */ } + def foo2846(): scala.Int = { /* compiled code */ } + def foo2847(): scala.Int = { /* compiled code */ } + def foo2848(): scala.Int = { /* compiled code */ } + def foo2849(): scala.Int = { /* compiled code */ } + def foo2850(): scala.Int = { /* compiled code */ } + def foo2851(): scala.Int = { /* compiled code */ } + def foo2852(): scala.Int = { /* compiled code */ } + def foo2853(): scala.Int = { /* compiled code */ } + def foo2854(): scala.Int = { /* compiled code */ } + def foo2855(): scala.Int = { /* compiled code */ } + def foo2856(): scala.Int = { /* compiled code */ } + def foo2857(): scala.Int = { /* compiled code */ } + def foo2858(): scala.Int = { /* compiled code */ } + def foo2859(): scala.Int = { /* compiled code */ } + def foo2860(): scala.Int = { /* compiled code */ } + def foo2861(): scala.Int = { /* compiled code */ } + def foo2862(): scala.Int = { /* compiled code */ } + def foo2863(): scala.Int = { /* compiled code */ } + def foo2864(): scala.Int = { /* compiled code */ } + def foo2865(): scala.Int = { /* compiled code */ } + def foo2866(): scala.Int = { /* compiled code */ } + def foo2867(): scala.Int = { /* compiled code */ } + def foo2868(): scala.Int = { /* compiled code */ } + def foo2869(): scala.Int = { /* compiled code */ } + def foo2870(): scala.Int = { /* compiled code */ } + def foo2871(): scala.Int = { /* compiled code */ } + def foo2872(): scala.Int = { /* compiled code */ } + def foo2873(): scala.Int = { /* compiled code */ } + def foo2874(): scala.Int = { /* compiled code */ } + def foo2875(): scala.Int = { /* compiled code */ } + def foo2876(): scala.Int = { /* compiled code */ } + def foo2877(): scala.Int = { /* compiled code */ } + def foo2878(): scala.Int = { /* compiled code */ } + def foo2879(): scala.Int = { /* compiled code */ } + def foo2880(): scala.Int = { /* compiled code */ } + def foo2881(): scala.Int = { /* compiled code */ } + def foo2882(): scala.Int = { /* compiled code */ } + def foo2883(): scala.Int = { /* compiled code */ } + def foo2884(): scala.Int = { /* compiled code */ } + def foo2885(): scala.Int = { /* compiled code */ } + def foo2886(): scala.Int = { /* compiled code */ } + def foo2887(): scala.Int = { /* compiled code */ } + def foo2888(): scala.Int = { /* compiled code */ } + def foo2889(): scala.Int = { /* compiled code */ } + def foo2890(): scala.Int = { /* compiled code */ } + def foo2891(): scala.Int = { /* compiled code */ } + def foo2892(): scala.Int = { /* compiled code */ } + def foo2893(): scala.Int = { /* compiled code */ } + def foo2894(): scala.Int = { /* compiled code */ } + def foo2895(): scala.Int = { /* compiled code */ } + def foo2896(): scala.Int = { /* compiled code */ } + def foo2897(): scala.Int = { /* compiled code */ } + def foo2898(): scala.Int = { /* compiled code */ } + def foo2899(): scala.Int = { /* compiled code */ } + def foo2900(): scala.Int = { /* compiled code */ } + def foo2901(): scala.Int = { /* compiled code */ } + def foo2902(): scala.Int = { /* compiled code */ } + def foo2903(): scala.Int = { /* compiled code */ } + def foo2904(): scala.Int = { /* compiled code */ } + def foo2905(): scala.Int = { /* compiled code */ } + def foo2906(): scala.Int = { /* compiled code */ } + def foo2907(): scala.Int = { /* compiled code */ } + def foo2908(): scala.Int = { /* compiled code */ } + def foo2909(): scala.Int = { /* compiled code */ } + def foo2910(): scala.Int = { /* compiled code */ } + def foo2911(): scala.Int = { /* compiled code */ } + def foo2912(): scala.Int = { /* compiled code */ } + def foo2913(): scala.Int = { /* compiled code */ } + def foo2914(): scala.Int = { /* compiled code */ } + def foo2915(): scala.Int = { /* compiled code */ } + def foo2916(): scala.Int = { /* compiled code */ } + def foo2917(): scala.Int = { /* compiled code */ } + def foo2918(): scala.Int = { /* compiled code */ } + def foo2919(): scala.Int = { /* compiled code */ } + def foo2920(): scala.Int = { /* compiled code */ } + def foo2921(): scala.Int = { /* compiled code */ } + def foo2922(): scala.Int = { /* compiled code */ } + def foo2923(): scala.Int = { /* compiled code */ } + def foo2924(): scala.Int = { /* compiled code */ } + def foo2925(): scala.Int = { /* compiled code */ } + def foo2926(): scala.Int = { /* compiled code */ } + def foo2927(): scala.Int = { /* compiled code */ } + def foo2928(): scala.Int = { /* compiled code */ } + def foo2929(): scala.Int = { /* compiled code */ } + def foo2930(): scala.Int = { /* compiled code */ } + def foo2931(): scala.Int = { /* compiled code */ } + def foo2932(): scala.Int = { /* compiled code */ } + def foo2933(): scala.Int = { /* compiled code */ } + def foo2934(): scala.Int = { /* compiled code */ } + def foo2935(): scala.Int = { /* compiled code */ } + def foo2936(): scala.Int = { /* compiled code */ } + def foo2937(): scala.Int = { /* compiled code */ } + def foo2938(): scala.Int = { /* compiled code */ } + def foo2939(): scala.Int = { /* compiled code */ } + def foo2940(): scala.Int = { /* compiled code */ } + def foo2941(): scala.Int = { /* compiled code */ } + def foo2942(): scala.Int = { /* compiled code */ } + def foo2943(): scala.Int = { /* compiled code */ } + def foo2944(): scala.Int = { /* compiled code */ } + def foo2945(): scala.Int = { /* compiled code */ } + def foo2946(): scala.Int = { /* compiled code */ } + def foo2947(): scala.Int = { /* compiled code */ } + def foo2948(): scala.Int = { /* compiled code */ } + def foo2949(): scala.Int = { /* compiled code */ } + def foo2950(): scala.Int = { /* compiled code */ } + def foo2951(): scala.Int = { /* compiled code */ } + def foo2952(): scala.Int = { /* compiled code */ } + def foo2953(): scala.Int = { /* compiled code */ } + def foo2954(): scala.Int = { /* compiled code */ } + def foo2955(): scala.Int = { /* compiled code */ } + def foo2956(): scala.Int = { /* compiled code */ } + def foo2957(): scala.Int = { /* compiled code */ } + def foo2958(): scala.Int = { /* compiled code */ } + def foo2959(): scala.Int = { /* compiled code */ } + def foo2960(): scala.Int = { /* compiled code */ } + def foo2961(): scala.Int = { /* compiled code */ } + def foo2962(): scala.Int = { /* compiled code */ } + def foo2963(): scala.Int = { /* compiled code */ } + def foo2964(): scala.Int = { /* compiled code */ } + def foo2965(): scala.Int = { /* compiled code */ } + def foo2966(): scala.Int = { /* compiled code */ } + def foo2967(): scala.Int = { /* compiled code */ } + def foo2968(): scala.Int = { /* compiled code */ } + def foo2969(): scala.Int = { /* compiled code */ } + def foo2970(): scala.Int = { /* compiled code */ } + def foo2971(): scala.Int = { /* compiled code */ } + def foo2972(): scala.Int = { /* compiled code */ } + def foo2973(): scala.Int = { /* compiled code */ } + def foo2974(): scala.Int = { /* compiled code */ } + def foo2975(): scala.Int = { /* compiled code */ } + def foo2976(): scala.Int = { /* compiled code */ } + def foo2977(): scala.Int = { /* compiled code */ } + def foo2978(): scala.Int = { /* compiled code */ } + def foo2979(): scala.Int = { /* compiled code */ } + def foo2980(): scala.Int = { /* compiled code */ } + def foo2981(): scala.Int = { /* compiled code */ } + def foo2982(): scala.Int = { /* compiled code */ } + def foo2983(): scala.Int = { /* compiled code */ } + def foo2984(): scala.Int = { /* compiled code */ } + def foo2985(): scala.Int = { /* compiled code */ } + def foo2986(): scala.Int = { /* compiled code */ } + def foo2987(): scala.Int = { /* compiled code */ } + def foo2988(): scala.Int = { /* compiled code */ } + def foo2989(): scala.Int = { /* compiled code */ } + def foo2990(): scala.Int = { /* compiled code */ } + def foo2991(): scala.Int = { /* compiled code */ } + def foo2992(): scala.Int = { /* compiled code */ } + def foo2993(): scala.Int = { /* compiled code */ } + def foo2994(): scala.Int = { /* compiled code */ } + def foo2995(): scala.Int = { /* compiled code */ } + def foo2996(): scala.Int = { /* compiled code */ } + def foo2997(): scala.Int = { /* compiled code */ } + def foo2998(): scala.Int = { /* compiled code */ } + def foo2999(): scala.Int = { /* compiled code */ } + def foo3000(): scala.Int = { /* compiled code */ } + def foo3001(): scala.Int = { /* compiled code */ } + def foo3002(): scala.Int = { /* compiled code */ } + def foo3003(): scala.Int = { /* compiled code */ } + def foo3004(): scala.Int = { /* compiled code */ } + def foo3005(): scala.Int = { /* compiled code */ } + def foo3006(): scala.Int = { /* compiled code */ } + def foo3007(): scala.Int = { /* compiled code */ } + def foo3008(): scala.Int = { /* compiled code */ } + def foo3009(): scala.Int = { /* compiled code */ } + def foo3010(): scala.Int = { /* compiled code */ } + def foo3011(): scala.Int = { /* compiled code */ } + def foo3012(): scala.Int = { /* compiled code */ } + def foo3013(): scala.Int = { /* compiled code */ } + def foo3014(): scala.Int = { /* compiled code */ } + def foo3015(): scala.Int = { /* compiled code */ } + def foo3016(): scala.Int = { /* compiled code */ } + def foo3017(): scala.Int = { /* compiled code */ } + def foo3018(): scala.Int = { /* compiled code */ } + def foo3019(): scala.Int = { /* compiled code */ } + def foo3020(): scala.Int = { /* compiled code */ } + def foo3021(): scala.Int = { /* compiled code */ } + def foo3022(): scala.Int = { /* compiled code */ } + def foo3023(): scala.Int = { /* compiled code */ } + def foo3024(): scala.Int = { /* compiled code */ } + def foo3025(): scala.Int = { /* compiled code */ } + def foo3026(): scala.Int = { /* compiled code */ } + def foo3027(): scala.Int = { /* compiled code */ } + def foo3028(): scala.Int = { /* compiled code */ } + def foo3029(): scala.Int = { /* compiled code */ } + def foo3030(): scala.Int = { /* compiled code */ } + def foo3031(): scala.Int = { /* compiled code */ } + def foo3032(): scala.Int = { /* compiled code */ } + def foo3033(): scala.Int = { /* compiled code */ } + def foo3034(): scala.Int = { /* compiled code */ } + def foo3035(): scala.Int = { /* compiled code */ } + def foo3036(): scala.Int = { /* compiled code */ } + def foo3037(): scala.Int = { /* compiled code */ } + def foo3038(): scala.Int = { /* compiled code */ } + def foo3039(): scala.Int = { /* compiled code */ } + def foo3040(): scala.Int = { /* compiled code */ } + def foo3041(): scala.Int = { /* compiled code */ } + def foo3042(): scala.Int = { /* compiled code */ } + def foo3043(): scala.Int = { /* compiled code */ } + def foo3044(): scala.Int = { /* compiled code */ } + def foo3045(): scala.Int = { /* compiled code */ } + def foo3046(): scala.Int = { /* compiled code */ } + def foo3047(): scala.Int = { /* compiled code */ } + def foo3048(): scala.Int = { /* compiled code */ } + def foo3049(): scala.Int = { /* compiled code */ } + def foo3050(): scala.Int = { /* compiled code */ } + def foo3051(): scala.Int = { /* compiled code */ } + def foo3052(): scala.Int = { /* compiled code */ } + def foo3053(): scala.Int = { /* compiled code */ } + def foo3054(): scala.Int = { /* compiled code */ } + def foo3055(): scala.Int = { /* compiled code */ } + def foo3056(): scala.Int = { /* compiled code */ } + def foo3057(): scala.Int = { /* compiled code */ } + def foo3058(): scala.Int = { /* compiled code */ } + def foo3059(): scala.Int = { /* compiled code */ } + def foo3060(): scala.Int = { /* compiled code */ } + def foo3061(): scala.Int = { /* compiled code */ } + def foo3062(): scala.Int = { /* compiled code */ } + def foo3063(): scala.Int = { /* compiled code */ } + def foo3064(): scala.Int = { /* compiled code */ } + def foo3065(): scala.Int = { /* compiled code */ } + def foo3066(): scala.Int = { /* compiled code */ } + def foo3067(): scala.Int = { /* compiled code */ } + def foo3068(): scala.Int = { /* compiled code */ } + def foo3069(): scala.Int = { /* compiled code */ } + def foo3070(): scala.Int = { /* compiled code */ } + def foo3071(): scala.Int = { /* compiled code */ } + def foo3072(): scala.Int = { /* compiled code */ } + def foo3073(): scala.Int = { /* compiled code */ } + def foo3074(): scala.Int = { /* compiled code */ } + def foo3075(): scala.Int = { /* compiled code */ } + def foo3076(): scala.Int = { /* compiled code */ } + def foo3077(): scala.Int = { /* compiled code */ } + def foo3078(): scala.Int = { /* compiled code */ } + def foo3079(): scala.Int = { /* compiled code */ } + def foo3080(): scala.Int = { /* compiled code */ } + def foo3081(): scala.Int = { /* compiled code */ } + def foo3082(): scala.Int = { /* compiled code */ } + def foo3083(): scala.Int = { /* compiled code */ } + def foo3084(): scala.Int = { /* compiled code */ } + def foo3085(): scala.Int = { /* compiled code */ } + def foo3086(): scala.Int = { /* compiled code */ } + def foo3087(): scala.Int = { /* compiled code */ } + def foo3088(): scala.Int = { /* compiled code */ } + def foo3089(): scala.Int = { /* compiled code */ } + def foo3090(): scala.Int = { /* compiled code */ } + def foo3091(): scala.Int = { /* compiled code */ } + def foo3092(): scala.Int = { /* compiled code */ } + def foo3093(): scala.Int = { /* compiled code */ } + def foo3094(): scala.Int = { /* compiled code */ } + def foo3095(): scala.Int = { /* compiled code */ } + def foo3096(): scala.Int = { /* compiled code */ } + def foo3097(): scala.Int = { /* compiled code */ } + def foo3098(): scala.Int = { /* compiled code */ } + def foo3099(): scala.Int = { /* compiled code */ } + def foo3100(): scala.Int = { /* compiled code */ } + def foo3101(): scala.Int = { /* compiled code */ } + def foo3102(): scala.Int = { /* compiled code */ } + def foo3103(): scala.Int = { /* compiled code */ } + def foo3104(): scala.Int = { /* compiled code */ } + def foo3105(): scala.Int = { /* compiled code */ } + def foo3106(): scala.Int = { /* compiled code */ } + def foo3107(): scala.Int = { /* compiled code */ } + def foo3108(): scala.Int = { /* compiled code */ } + def foo3109(): scala.Int = { /* compiled code */ } + def foo3110(): scala.Int = { /* compiled code */ } + def foo3111(): scala.Int = { /* compiled code */ } + def foo3112(): scala.Int = { /* compiled code */ } + def foo3113(): scala.Int = { /* compiled code */ } + def foo3114(): scala.Int = { /* compiled code */ } + def foo3115(): scala.Int = { /* compiled code */ } + def foo3116(): scala.Int = { /* compiled code */ } + def foo3117(): scala.Int = { /* compiled code */ } + def foo3118(): scala.Int = { /* compiled code */ } + def foo3119(): scala.Int = { /* compiled code */ } + def foo3120(): scala.Int = { /* compiled code */ } + def foo3121(): scala.Int = { /* compiled code */ } + def foo3122(): scala.Int = { /* compiled code */ } + def foo3123(): scala.Int = { /* compiled code */ } + def foo3124(): scala.Int = { /* compiled code */ } + def foo3125(): scala.Int = { /* compiled code */ } + def foo3126(): scala.Int = { /* compiled code */ } + def foo3127(): scala.Int = { /* compiled code */ } + def foo3128(): scala.Int = { /* compiled code */ } + def foo3129(): scala.Int = { /* compiled code */ } + def foo3130(): scala.Int = { /* compiled code */ } + def foo3131(): scala.Int = { /* compiled code */ } + def foo3132(): scala.Int = { /* compiled code */ } + def foo3133(): scala.Int = { /* compiled code */ } + def foo3134(): scala.Int = { /* compiled code */ } + def foo3135(): scala.Int = { /* compiled code */ } + def foo3136(): scala.Int = { /* compiled code */ } + def foo3137(): scala.Int = { /* compiled code */ } + def foo3138(): scala.Int = { /* compiled code */ } + def foo3139(): scala.Int = { /* compiled code */ } + def foo3140(): scala.Int = { /* compiled code */ } + def foo3141(): scala.Int = { /* compiled code */ } + def foo3142(): scala.Int = { /* compiled code */ } + def foo3143(): scala.Int = { /* compiled code */ } + def foo3144(): scala.Int = { /* compiled code */ } + def foo3145(): scala.Int = { /* compiled code */ } + def foo3146(): scala.Int = { /* compiled code */ } + def foo3147(): scala.Int = { /* compiled code */ } + def foo3148(): scala.Int = { /* compiled code */ } + def foo3149(): scala.Int = { /* compiled code */ } + def foo3150(): scala.Int = { /* compiled code */ } + def foo3151(): scala.Int = { /* compiled code */ } + def foo3152(): scala.Int = { /* compiled code */ } + def foo3153(): scala.Int = { /* compiled code */ } + def foo3154(): scala.Int = { /* compiled code */ } + def foo3155(): scala.Int = { /* compiled code */ } + def foo3156(): scala.Int = { /* compiled code */ } + def foo3157(): scala.Int = { /* compiled code */ } + def foo3158(): scala.Int = { /* compiled code */ } + def foo3159(): scala.Int = { /* compiled code */ } + def foo3160(): scala.Int = { /* compiled code */ } + def foo3161(): scala.Int = { /* compiled code */ } + def foo3162(): scala.Int = { /* compiled code */ } + def foo3163(): scala.Int = { /* compiled code */ } + def foo3164(): scala.Int = { /* compiled code */ } + def foo3165(): scala.Int = { /* compiled code */ } + def foo3166(): scala.Int = { /* compiled code */ } + def foo3167(): scala.Int = { /* compiled code */ } + def foo3168(): scala.Int = { /* compiled code */ } + def foo3169(): scala.Int = { /* compiled code */ } + def foo3170(): scala.Int = { /* compiled code */ } + def foo3171(): scala.Int = { /* compiled code */ } + def foo3172(): scala.Int = { /* compiled code */ } + def foo3173(): scala.Int = { /* compiled code */ } + def foo3174(): scala.Int = { /* compiled code */ } + def foo3175(): scala.Int = { /* compiled code */ } + def foo3176(): scala.Int = { /* compiled code */ } + def foo3177(): scala.Int = { /* compiled code */ } + def foo3178(): scala.Int = { /* compiled code */ } + def foo3179(): scala.Int = { /* compiled code */ } + def foo3180(): scala.Int = { /* compiled code */ } + def foo3181(): scala.Int = { /* compiled code */ } + def foo3182(): scala.Int = { /* compiled code */ } + def foo3183(): scala.Int = { /* compiled code */ } + def foo3184(): scala.Int = { /* compiled code */ } + def foo3185(): scala.Int = { /* compiled code */ } + def foo3186(): scala.Int = { /* compiled code */ } + def foo3187(): scala.Int = { /* compiled code */ } + def foo3188(): scala.Int = { /* compiled code */ } + def foo3189(): scala.Int = { /* compiled code */ } + def foo3190(): scala.Int = { /* compiled code */ } + def foo3191(): scala.Int = { /* compiled code */ } + def foo3192(): scala.Int = { /* compiled code */ } + def foo3193(): scala.Int = { /* compiled code */ } + def foo3194(): scala.Int = { /* compiled code */ } + def foo3195(): scala.Int = { /* compiled code */ } + def foo3196(): scala.Int = { /* compiled code */ } + def foo3197(): scala.Int = { /* compiled code */ } + def foo3198(): scala.Int = { /* compiled code */ } + def foo3199(): scala.Int = { /* compiled code */ } + def foo3200(): scala.Int = { /* compiled code */ } + def foo3201(): scala.Int = { /* compiled code */ } + def foo3202(): scala.Int = { /* compiled code */ } + def foo3203(): scala.Int = { /* compiled code */ } + def foo3204(): scala.Int = { /* compiled code */ } + def foo3205(): scala.Int = { /* compiled code */ } + def foo3206(): scala.Int = { /* compiled code */ } + def foo3207(): scala.Int = { /* compiled code */ } + def foo3208(): scala.Int = { /* compiled code */ } + def foo3209(): scala.Int = { /* compiled code */ } + def foo3210(): scala.Int = { /* compiled code */ } + def foo3211(): scala.Int = { /* compiled code */ } + def foo3212(): scala.Int = { /* compiled code */ } + def foo3213(): scala.Int = { /* compiled code */ } + def foo3214(): scala.Int = { /* compiled code */ } + def foo3215(): scala.Int = { /* compiled code */ } + def foo3216(): scala.Int = { /* compiled code */ } + def foo3217(): scala.Int = { /* compiled code */ } + def foo3218(): scala.Int = { /* compiled code */ } + def foo3219(): scala.Int = { /* compiled code */ } + def foo3220(): scala.Int = { /* compiled code */ } + def foo3221(): scala.Int = { /* compiled code */ } + def foo3222(): scala.Int = { /* compiled code */ } + def foo3223(): scala.Int = { /* compiled code */ } + def foo3224(): scala.Int = { /* compiled code */ } + def foo3225(): scala.Int = { /* compiled code */ } + def foo3226(): scala.Int = { /* compiled code */ } + def foo3227(): scala.Int = { /* compiled code */ } + def foo3228(): scala.Int = { /* compiled code */ } + def foo3229(): scala.Int = { /* compiled code */ } + def foo3230(): scala.Int = { /* compiled code */ } + def foo3231(): scala.Int = { /* compiled code */ } + def foo3232(): scala.Int = { /* compiled code */ } + def foo3233(): scala.Int = { /* compiled code */ } + def foo3234(): scala.Int = { /* compiled code */ } + def foo3235(): scala.Int = { /* compiled code */ } + def foo3236(): scala.Int = { /* compiled code */ } + def foo3237(): scala.Int = { /* compiled code */ } + def foo3238(): scala.Int = { /* compiled code */ } + def foo3239(): scala.Int = { /* compiled code */ } + def foo3240(): scala.Int = { /* compiled code */ } + def foo3241(): scala.Int = { /* compiled code */ } + def foo3242(): scala.Int = { /* compiled code */ } + def foo3243(): scala.Int = { /* compiled code */ } + def foo3244(): scala.Int = { /* compiled code */ } + def foo3245(): scala.Int = { /* compiled code */ } + def foo3246(): scala.Int = { /* compiled code */ } + def foo3247(): scala.Int = { /* compiled code */ } + def foo3248(): scala.Int = { /* compiled code */ } + def foo3249(): scala.Int = { /* compiled code */ } + def foo3250(): scala.Int = { /* compiled code */ } + def foo3251(): scala.Int = { /* compiled code */ } + def foo3252(): scala.Int = { /* compiled code */ } + def foo3253(): scala.Int = { /* compiled code */ } + def foo3254(): scala.Int = { /* compiled code */ } + def foo3255(): scala.Int = { /* compiled code */ } + def foo3256(): scala.Int = { /* compiled code */ } + def foo3257(): scala.Int = { /* compiled code */ } + def foo3258(): scala.Int = { /* compiled code */ } + def foo3259(): scala.Int = { /* compiled code */ } + def foo3260(): scala.Int = { /* compiled code */ } + def foo3261(): scala.Int = { /* compiled code */ } + def foo3262(): scala.Int = { /* compiled code */ } + def foo3263(): scala.Int = { /* compiled code */ } + def foo3264(): scala.Int = { /* compiled code */ } + def foo3265(): scala.Int = { /* compiled code */ } + def foo3266(): scala.Int = { /* compiled code */ } + def foo3267(): scala.Int = { /* compiled code */ } + def foo3268(): scala.Int = { /* compiled code */ } + def foo3269(): scala.Int = { /* compiled code */ } + def foo3270(): scala.Int = { /* compiled code */ } + def foo3271(): scala.Int = { /* compiled code */ } + def foo3272(): scala.Int = { /* compiled code */ } + def foo3273(): scala.Int = { /* compiled code */ } + def foo3274(): scala.Int = { /* compiled code */ } + def foo3275(): scala.Int = { /* compiled code */ } + def foo3276(): scala.Int = { /* compiled code */ } + def foo3277(): scala.Int = { /* compiled code */ } + def foo3278(): scala.Int = { /* compiled code */ } + def foo3279(): scala.Int = { /* compiled code */ } + def foo3280(): scala.Int = { /* compiled code */ } + def foo3281(): scala.Int = { /* compiled code */ } + def foo3282(): scala.Int = { /* compiled code */ } + def foo3283(): scala.Int = { /* compiled code */ } + def foo3284(): scala.Int = { /* compiled code */ } + def foo3285(): scala.Int = { /* compiled code */ } + def foo3286(): scala.Int = { /* compiled code */ } + def foo3287(): scala.Int = { /* compiled code */ } + def foo3288(): scala.Int = { /* compiled code */ } + def foo3289(): scala.Int = { /* compiled code */ } + def foo3290(): scala.Int = { /* compiled code */ } + def foo3291(): scala.Int = { /* compiled code */ } + def foo3292(): scala.Int = { /* compiled code */ } + def foo3293(): scala.Int = { /* compiled code */ } + def foo3294(): scala.Int = { /* compiled code */ } + def foo3295(): scala.Int = { /* compiled code */ } + def foo3296(): scala.Int = { /* compiled code */ } + def foo3297(): scala.Int = { /* compiled code */ } + def foo3298(): scala.Int = { /* compiled code */ } + def foo3299(): scala.Int = { /* compiled code */ } + def foo3300(): scala.Int = { /* compiled code */ } + def foo3301(): scala.Int = { /* compiled code */ } + def foo3302(): scala.Int = { /* compiled code */ } + def foo3303(): scala.Int = { /* compiled code */ } + def foo3304(): scala.Int = { /* compiled code */ } + def foo3305(): scala.Int = { /* compiled code */ } + def foo3306(): scala.Int = { /* compiled code */ } + def foo3307(): scala.Int = { /* compiled code */ } + def foo3308(): scala.Int = { /* compiled code */ } + def foo3309(): scala.Int = { /* compiled code */ } + def foo3310(): scala.Int = { /* compiled code */ } + def foo3311(): scala.Int = { /* compiled code */ } + def foo3312(): scala.Int = { /* compiled code */ } + def foo3313(): scala.Int = { /* compiled code */ } + def foo3314(): scala.Int = { /* compiled code */ } + def foo3315(): scala.Int = { /* compiled code */ } + def foo3316(): scala.Int = { /* compiled code */ } + def foo3317(): scala.Int = { /* compiled code */ } + def foo3318(): scala.Int = { /* compiled code */ } + def foo3319(): scala.Int = { /* compiled code */ } + def foo3320(): scala.Int = { /* compiled code */ } + def foo3321(): scala.Int = { /* compiled code */ } + def foo3322(): scala.Int = { /* compiled code */ } + def foo3323(): scala.Int = { /* compiled code */ } + def foo3324(): scala.Int = { /* compiled code */ } + def foo3325(): scala.Int = { /* compiled code */ } + def foo3326(): scala.Int = { /* compiled code */ } + def foo3327(): scala.Int = { /* compiled code */ } + def foo3328(): scala.Int = { /* compiled code */ } + def foo3329(): scala.Int = { /* compiled code */ } + def foo3330(): scala.Int = { /* compiled code */ } + def foo3331(): scala.Int = { /* compiled code */ } + def foo3332(): scala.Int = { /* compiled code */ } + def foo3333(): scala.Int = { /* compiled code */ } + def foo3334(): scala.Int = { /* compiled code */ } + def foo3335(): scala.Int = { /* compiled code */ } + def foo3336(): scala.Int = { /* compiled code */ } + def foo3337(): scala.Int = { /* compiled code */ } + def foo3338(): scala.Int = { /* compiled code */ } + def foo3339(): scala.Int = { /* compiled code */ } + def foo3340(): scala.Int = { /* compiled code */ } + def foo3341(): scala.Int = { /* compiled code */ } + def foo3342(): scala.Int = { /* compiled code */ } + def foo3343(): scala.Int = { /* compiled code */ } + def foo3344(): scala.Int = { /* compiled code */ } + def foo3345(): scala.Int = { /* compiled code */ } + def foo3346(): scala.Int = { /* compiled code */ } + def foo3347(): scala.Int = { /* compiled code */ } + def foo3348(): scala.Int = { /* compiled code */ } + def foo3349(): scala.Int = { /* compiled code */ } + def foo3350(): scala.Int = { /* compiled code */ } + def foo3351(): scala.Int = { /* compiled code */ } + def foo3352(): scala.Int = { /* compiled code */ } + def foo3353(): scala.Int = { /* compiled code */ } + def foo3354(): scala.Int = { /* compiled code */ } + def foo3355(): scala.Int = { /* compiled code */ } + def foo3356(): scala.Int = { /* compiled code */ } + def foo3357(): scala.Int = { /* compiled code */ } + def foo3358(): scala.Int = { /* compiled code */ } + def foo3359(): scala.Int = { /* compiled code */ } + def foo3360(): scala.Int = { /* compiled code */ } + def foo3361(): scala.Int = { /* compiled code */ } + def foo3362(): scala.Int = { /* compiled code */ } + def foo3363(): scala.Int = { /* compiled code */ } + def foo3364(): scala.Int = { /* compiled code */ } + def foo3365(): scala.Int = { /* compiled code */ } + def foo3366(): scala.Int = { /* compiled code */ } + def foo3367(): scala.Int = { /* compiled code */ } + def foo3368(): scala.Int = { /* compiled code */ } + def foo3369(): scala.Int = { /* compiled code */ } + def foo3370(): scala.Int = { /* compiled code */ } + def foo3371(): scala.Int = { /* compiled code */ } + def foo3372(): scala.Int = { /* compiled code */ } + def foo3373(): scala.Int = { /* compiled code */ } + def foo3374(): scala.Int = { /* compiled code */ } + def foo3375(): scala.Int = { /* compiled code */ } + def foo3376(): scala.Int = { /* compiled code */ } + def foo3377(): scala.Int = { /* compiled code */ } + def foo3378(): scala.Int = { /* compiled code */ } + def foo3379(): scala.Int = { /* compiled code */ } + def foo3380(): scala.Int = { /* compiled code */ } + def foo3381(): scala.Int = { /* compiled code */ } + def foo3382(): scala.Int = { /* compiled code */ } + def foo3383(): scala.Int = { /* compiled code */ } + def foo3384(): scala.Int = { /* compiled code */ } + def foo3385(): scala.Int = { /* compiled code */ } + def foo3386(): scala.Int = { /* compiled code */ } + def foo3387(): scala.Int = { /* compiled code */ } + def foo3388(): scala.Int = { /* compiled code */ } + def foo3389(): scala.Int = { /* compiled code */ } + def foo3390(): scala.Int = { /* compiled code */ } + def foo3391(): scala.Int = { /* compiled code */ } + def foo3392(): scala.Int = { /* compiled code */ } + def foo3393(): scala.Int = { /* compiled code */ } + def foo3394(): scala.Int = { /* compiled code */ } + def foo3395(): scala.Int = { /* compiled code */ } + def foo3396(): scala.Int = { /* compiled code */ } + def foo3397(): scala.Int = { /* compiled code */ } + def foo3398(): scala.Int = { /* compiled code */ } + def foo3399(): scala.Int = { /* compiled code */ } + def foo3400(): scala.Int = { /* compiled code */ } + def foo3401(): scala.Int = { /* compiled code */ } + def foo3402(): scala.Int = { /* compiled code */ } + def foo3403(): scala.Int = { /* compiled code */ } + def foo3404(): scala.Int = { /* compiled code */ } + def foo3405(): scala.Int = { /* compiled code */ } + def foo3406(): scala.Int = { /* compiled code */ } + def foo3407(): scala.Int = { /* compiled code */ } + def foo3408(): scala.Int = { /* compiled code */ } + def foo3409(): scala.Int = { /* compiled code */ } + def foo3410(): scala.Int = { /* compiled code */ } + def foo3411(): scala.Int = { /* compiled code */ } + def foo3412(): scala.Int = { /* compiled code */ } + def foo3413(): scala.Int = { /* compiled code */ } + def foo3414(): scala.Int = { /* compiled code */ } + def foo3415(): scala.Int = { /* compiled code */ } + def foo3416(): scala.Int = { /* compiled code */ } + def foo3417(): scala.Int = { /* compiled code */ } + def foo3418(): scala.Int = { /* compiled code */ } + def foo3419(): scala.Int = { /* compiled code */ } + def foo3420(): scala.Int = { /* compiled code */ } + def foo3421(): scala.Int = { /* compiled code */ } + def foo3422(): scala.Int = { /* compiled code */ } + def foo3423(): scala.Int = { /* compiled code */ } + def foo3424(): scala.Int = { /* compiled code */ } + def foo3425(): scala.Int = { /* compiled code */ } + def foo3426(): scala.Int = { /* compiled code */ } + def foo3427(): scala.Int = { /* compiled code */ } + def foo3428(): scala.Int = { /* compiled code */ } + def foo3429(): scala.Int = { /* compiled code */ } + def foo3430(): scala.Int = { /* compiled code */ } + def foo3431(): scala.Int = { /* compiled code */ } + def foo3432(): scala.Int = { /* compiled code */ } + def foo3433(): scala.Int = { /* compiled code */ } + def foo3434(): scala.Int = { /* compiled code */ } + def foo3435(): scala.Int = { /* compiled code */ } + def foo3436(): scala.Int = { /* compiled code */ } + def foo3437(): scala.Int = { /* compiled code */ } + def foo3438(): scala.Int = { /* compiled code */ } + def foo3439(): scala.Int = { /* compiled code */ } + def foo3440(): scala.Int = { /* compiled code */ } + def foo3441(): scala.Int = { /* compiled code */ } + def foo3442(): scala.Int = { /* compiled code */ } + def foo3443(): scala.Int = { /* compiled code */ } + def foo3444(): scala.Int = { /* compiled code */ } + def foo3445(): scala.Int = { /* compiled code */ } + def foo3446(): scala.Int = { /* compiled code */ } + def foo3447(): scala.Int = { /* compiled code */ } + def foo3448(): scala.Int = { /* compiled code */ } + def foo3449(): scala.Int = { /* compiled code */ } + def foo3450(): scala.Int = { /* compiled code */ } + def foo3451(): scala.Int = { /* compiled code */ } + def foo3452(): scala.Int = { /* compiled code */ } + def foo3453(): scala.Int = { /* compiled code */ } + def foo3454(): scala.Int = { /* compiled code */ } + def foo3455(): scala.Int = { /* compiled code */ } + def foo3456(): scala.Int = { /* compiled code */ } + def foo3457(): scala.Int = { /* compiled code */ } + def foo3458(): scala.Int = { /* compiled code */ } + def foo3459(): scala.Int = { /* compiled code */ } + def foo3460(): scala.Int = { /* compiled code */ } + def foo3461(): scala.Int = { /* compiled code */ } + def foo3462(): scala.Int = { /* compiled code */ } + def foo3463(): scala.Int = { /* compiled code */ } + def foo3464(): scala.Int = { /* compiled code */ } + def foo3465(): scala.Int = { /* compiled code */ } + def foo3466(): scala.Int = { /* compiled code */ } + def foo3467(): scala.Int = { /* compiled code */ } + def foo3468(): scala.Int = { /* compiled code */ } + def foo3469(): scala.Int = { /* compiled code */ } + def foo3470(): scala.Int = { /* compiled code */ } + def foo3471(): scala.Int = { /* compiled code */ } + def foo3472(): scala.Int = { /* compiled code */ } + def foo3473(): scala.Int = { /* compiled code */ } + def foo3474(): scala.Int = { /* compiled code */ } + def foo3475(): scala.Int = { /* compiled code */ } + def foo3476(): scala.Int = { /* compiled code */ } + def foo3477(): scala.Int = { /* compiled code */ } + def foo3478(): scala.Int = { /* compiled code */ } + def foo3479(): scala.Int = { /* compiled code */ } + def foo3480(): scala.Int = { /* compiled code */ } + def foo3481(): scala.Int = { /* compiled code */ } + def foo3482(): scala.Int = { /* compiled code */ } + def foo3483(): scala.Int = { /* compiled code */ } + def foo3484(): scala.Int = { /* compiled code */ } + def foo3485(): scala.Int = { /* compiled code */ } + def foo3486(): scala.Int = { /* compiled code */ } + def foo3487(): scala.Int = { /* compiled code */ } + def foo3488(): scala.Int = { /* compiled code */ } + def foo3489(): scala.Int = { /* compiled code */ } + def foo3490(): scala.Int = { /* compiled code */ } + def foo3491(): scala.Int = { /* compiled code */ } + def foo3492(): scala.Int = { /* compiled code */ } + def foo3493(): scala.Int = { /* compiled code */ } + def foo3494(): scala.Int = { /* compiled code */ } + def foo3495(): scala.Int = { /* compiled code */ } + def foo3496(): scala.Int = { /* compiled code */ } + def foo3497(): scala.Int = { /* compiled code */ } + def foo3498(): scala.Int = { /* compiled code */ } + def foo3499(): scala.Int = { /* compiled code */ } + def foo3500(): scala.Int = { /* compiled code */ } +} diff --git a/test/files/scalap/t8679.scala b/test/files/scalap/t8679.scala new file mode 100644 index 0000000000..f008a7af35 --- /dev/null +++ b/test/files/scalap/t8679.scala @@ -0,0 +1,3502 @@ +class T8679 { + def foo1(): Int = 3 + def foo2(): Int = 4 + def foo3(): Int = 5 + def foo4(): Int = 6 + def foo5(): Int = 7 + def foo6(): Int = 8 + def foo7(): Int = 9 + def foo8(): Int = 10 + def foo9(): Int = 11 + def foo10(): Int = 12 + def foo11(): Int = 13 + def foo12(): Int = 14 + def foo13(): Int = 15 + def foo14(): Int = 16 + def foo15(): Int = 17 + def foo16(): Int = 18 + def foo17(): Int = 19 + def foo18(): Int = 20 + def foo19(): Int = 21 + def foo20(): Int = 22 + def foo21(): Int = 23 + def foo22(): Int = 24 + def foo23(): Int = 25 + def foo24(): Int = 26 + def foo25(): Int = 27 + def foo26(): Int = 28 + def foo27(): Int = 29 + def foo28(): Int = 30 + def foo29(): Int = 31 + def foo30(): Int = 32 + def foo31(): Int = 33 + def foo32(): Int = 34 + def foo33(): Int = 35 + def foo34(): Int = 36 + def foo35(): Int = 37 + def foo36(): Int = 38 + def foo37(): Int = 39 + def foo38(): Int = 40 + def foo39(): Int = 41 + def foo40(): Int = 42 + def foo41(): Int = 43 + def foo42(): Int = 44 + def foo43(): Int = 45 + def foo44(): Int = 46 + def foo45(): Int = 47 + def foo46(): Int = 48 + def foo47(): Int = 49 + def foo48(): Int = 50 + def foo49(): Int = 51 + def foo50(): Int = 52 + def foo51(): Int = 53 + def foo52(): Int = 54 + def foo53(): Int = 55 + def foo54(): Int = 56 + def foo55(): Int = 57 + def foo56(): Int = 58 + def foo57(): Int = 59 + def foo58(): Int = 60 + def foo59(): Int = 61 + def foo60(): Int = 62 + def foo61(): Int = 63 + def foo62(): Int = 64 + def foo63(): Int = 65 + def foo64(): Int = 66 + def foo65(): Int = 67 + def foo66(): Int = 68 + def foo67(): Int = 69 + def foo68(): Int = 70 + def foo69(): Int = 71 + def foo70(): Int = 72 + def foo71(): Int = 73 + def foo72(): Int = 74 + def foo73(): Int = 75 + def foo74(): Int = 76 + def foo75(): Int = 77 + def foo76(): Int = 78 + def foo77(): Int = 79 + def foo78(): Int = 80 + def foo79(): Int = 81 + def foo80(): Int = 82 + def foo81(): Int = 83 + def foo82(): Int = 84 + def foo83(): Int = 85 + def foo84(): Int = 86 + def foo85(): Int = 87 + def foo86(): Int = 88 + def foo87(): Int = 89 + def foo88(): Int = 90 + def foo89(): Int = 91 + def foo90(): Int = 92 + def foo91(): Int = 93 + def foo92(): Int = 94 + def foo93(): Int = 95 + def foo94(): Int = 96 + def foo95(): Int = 97 + def foo96(): Int = 98 + def foo97(): Int = 99 + def foo98(): Int = 100 + def foo99(): Int = 101 + def foo100(): Int = 102 + def foo101(): Int = 103 + def foo102(): Int = 104 + def foo103(): Int = 105 + def foo104(): Int = 106 + def foo105(): Int = 107 + def foo106(): Int = 108 + def foo107(): Int = 109 + def foo108(): Int = 110 + def foo109(): Int = 111 + def foo110(): Int = 112 + def foo111(): Int = 113 + def foo112(): Int = 114 + def foo113(): Int = 115 + def foo114(): Int = 116 + def foo115(): Int = 117 + def foo116(): Int = 118 + def foo117(): Int = 119 + def foo118(): Int = 120 + def foo119(): Int = 121 + def foo120(): Int = 122 + def foo121(): Int = 123 + def foo122(): Int = 124 + def foo123(): Int = 125 + def foo124(): Int = 126 + def foo125(): Int = 127 + def foo126(): Int = 128 + def foo127(): Int = 129 + def foo128(): Int = 130 + def foo129(): Int = 131 + def foo130(): Int = 132 + def foo131(): Int = 133 + def foo132(): Int = 134 + def foo133(): Int = 135 + def foo134(): Int = 136 + def foo135(): Int = 137 + def foo136(): Int = 138 + def foo137(): Int = 139 + def foo138(): Int = 140 + def foo139(): Int = 141 + def foo140(): Int = 142 + def foo141(): Int = 143 + def foo142(): Int = 144 + def foo143(): Int = 145 + def foo144(): Int = 146 + def foo145(): Int = 147 + def foo146(): Int = 148 + def foo147(): Int = 149 + def foo148(): Int = 150 + def foo149(): Int = 151 + def foo150(): Int = 152 + def foo151(): Int = 153 + def foo152(): Int = 154 + def foo153(): Int = 155 + def foo154(): Int = 156 + def foo155(): Int = 157 + def foo156(): Int = 158 + def foo157(): Int = 159 + def foo158(): Int = 160 + def foo159(): Int = 161 + def foo160(): Int = 162 + def foo161(): Int = 163 + def foo162(): Int = 164 + def foo163(): Int = 165 + def foo164(): Int = 166 + def foo165(): Int = 167 + def foo166(): Int = 168 + def foo167(): Int = 169 + def foo168(): Int = 170 + def foo169(): Int = 171 + def foo170(): Int = 172 + def foo171(): Int = 173 + def foo172(): Int = 174 + def foo173(): Int = 175 + def foo174(): Int = 176 + def foo175(): Int = 177 + def foo176(): Int = 178 + def foo177(): Int = 179 + def foo178(): Int = 180 + def foo179(): Int = 181 + def foo180(): Int = 182 + def foo181(): Int = 183 + def foo182(): Int = 184 + def foo183(): Int = 185 + def foo184(): Int = 186 + def foo185(): Int = 187 + def foo186(): Int = 188 + def foo187(): Int = 189 + def foo188(): Int = 190 + def foo189(): Int = 191 + def foo190(): Int = 192 + def foo191(): Int = 193 + def foo192(): Int = 194 + def foo193(): Int = 195 + def foo194(): Int = 196 + def foo195(): Int = 197 + def foo196(): Int = 198 + def foo197(): Int = 199 + def foo198(): Int = 200 + def foo199(): Int = 201 + def foo200(): Int = 202 + def foo201(): Int = 203 + def foo202(): Int = 204 + def foo203(): Int = 205 + def foo204(): Int = 206 + def foo205(): Int = 207 + def foo206(): Int = 208 + def foo207(): Int = 209 + def foo208(): Int = 210 + def foo209(): Int = 211 + def foo210(): Int = 212 + def foo211(): Int = 213 + def foo212(): Int = 214 + def foo213(): Int = 215 + def foo214(): Int = 216 + def foo215(): Int = 217 + def foo216(): Int = 218 + def foo217(): Int = 219 + def foo218(): Int = 220 + def foo219(): Int = 221 + def foo220(): Int = 222 + def foo221(): Int = 223 + def foo222(): Int = 224 + def foo223(): Int = 225 + def foo224(): Int = 226 + def foo225(): Int = 227 + def foo226(): Int = 228 + def foo227(): Int = 229 + def foo228(): Int = 230 + def foo229(): Int = 231 + def foo230(): Int = 232 + def foo231(): Int = 233 + def foo232(): Int = 234 + def foo233(): Int = 235 + def foo234(): Int = 236 + def foo235(): Int = 237 + def foo236(): Int = 238 + def foo237(): Int = 239 + def foo238(): Int = 240 + def foo239(): Int = 241 + def foo240(): Int = 242 + def foo241(): Int = 243 + def foo242(): Int = 244 + def foo243(): Int = 245 + def foo244(): Int = 246 + def foo245(): Int = 247 + def foo246(): Int = 248 + def foo247(): Int = 249 + def foo248(): Int = 250 + def foo249(): Int = 251 + def foo250(): Int = 252 + def foo251(): Int = 253 + def foo252(): Int = 254 + def foo253(): Int = 255 + def foo254(): Int = 256 + def foo255(): Int = 257 + def foo256(): Int = 258 + def foo257(): Int = 259 + def foo258(): Int = 260 + def foo259(): Int = 261 + def foo260(): Int = 262 + def foo261(): Int = 263 + def foo262(): Int = 264 + def foo263(): Int = 265 + def foo264(): Int = 266 + def foo265(): Int = 267 + def foo266(): Int = 268 + def foo267(): Int = 269 + def foo268(): Int = 270 + def foo269(): Int = 271 + def foo270(): Int = 272 + def foo271(): Int = 273 + def foo272(): Int = 274 + def foo273(): Int = 275 + def foo274(): Int = 276 + def foo275(): Int = 277 + def foo276(): Int = 278 + def foo277(): Int = 279 + def foo278(): Int = 280 + def foo279(): Int = 281 + def foo280(): Int = 282 + def foo281(): Int = 283 + def foo282(): Int = 284 + def foo283(): Int = 285 + def foo284(): Int = 286 + def foo285(): Int = 287 + def foo286(): Int = 288 + def foo287(): Int = 289 + def foo288(): Int = 290 + def foo289(): Int = 291 + def foo290(): Int = 292 + def foo291(): Int = 293 + def foo292(): Int = 294 + def foo293(): Int = 295 + def foo294(): Int = 296 + def foo295(): Int = 297 + def foo296(): Int = 298 + def foo297(): Int = 299 + def foo298(): Int = 300 + def foo299(): Int = 301 + def foo300(): Int = 302 + def foo301(): Int = 303 + def foo302(): Int = 304 + def foo303(): Int = 305 + def foo304(): Int = 306 + def foo305(): Int = 307 + def foo306(): Int = 308 + def foo307(): Int = 309 + def foo308(): Int = 310 + def foo309(): Int = 311 + def foo310(): Int = 312 + def foo311(): Int = 313 + def foo312(): Int = 314 + def foo313(): Int = 315 + def foo314(): Int = 316 + def foo315(): Int = 317 + def foo316(): Int = 318 + def foo317(): Int = 319 + def foo318(): Int = 320 + def foo319(): Int = 321 + def foo320(): Int = 322 + def foo321(): Int = 323 + def foo322(): Int = 324 + def foo323(): Int = 325 + def foo324(): Int = 326 + def foo325(): Int = 327 + def foo326(): Int = 328 + def foo327(): Int = 329 + def foo328(): Int = 330 + def foo329(): Int = 331 + def foo330(): Int = 332 + def foo331(): Int = 333 + def foo332(): Int = 334 + def foo333(): Int = 335 + def foo334(): Int = 336 + def foo335(): Int = 337 + def foo336(): Int = 338 + def foo337(): Int = 339 + def foo338(): Int = 340 + def foo339(): Int = 341 + def foo340(): Int = 342 + def foo341(): Int = 343 + def foo342(): Int = 344 + def foo343(): Int = 345 + def foo344(): Int = 346 + def foo345(): Int = 347 + def foo346(): Int = 348 + def foo347(): Int = 349 + def foo348(): Int = 350 + def foo349(): Int = 351 + def foo350(): Int = 352 + def foo351(): Int = 353 + def foo352(): Int = 354 + def foo353(): Int = 355 + def foo354(): Int = 356 + def foo355(): Int = 357 + def foo356(): Int = 358 + def foo357(): Int = 359 + def foo358(): Int = 360 + def foo359(): Int = 361 + def foo360(): Int = 362 + def foo361(): Int = 363 + def foo362(): Int = 364 + def foo363(): Int = 365 + def foo364(): Int = 366 + def foo365(): Int = 367 + def foo366(): Int = 368 + def foo367(): Int = 369 + def foo368(): Int = 370 + def foo369(): Int = 371 + def foo370(): Int = 372 + def foo371(): Int = 373 + def foo372(): Int = 374 + def foo373(): Int = 375 + def foo374(): Int = 376 + def foo375(): Int = 377 + def foo376(): Int = 378 + def foo377(): Int = 379 + def foo378(): Int = 380 + def foo379(): Int = 381 + def foo380(): Int = 382 + def foo381(): Int = 383 + def foo382(): Int = 384 + def foo383(): Int = 385 + def foo384(): Int = 386 + def foo385(): Int = 387 + def foo386(): Int = 388 + def foo387(): Int = 389 + def foo388(): Int = 390 + def foo389(): Int = 391 + def foo390(): Int = 392 + def foo391(): Int = 393 + def foo392(): Int = 394 + def foo393(): Int = 395 + def foo394(): Int = 396 + def foo395(): Int = 397 + def foo396(): Int = 398 + def foo397(): Int = 399 + def foo398(): Int = 400 + def foo399(): Int = 401 + def foo400(): Int = 402 + def foo401(): Int = 403 + def foo402(): Int = 404 + def foo403(): Int = 405 + def foo404(): Int = 406 + def foo405(): Int = 407 + def foo406(): Int = 408 + def foo407(): Int = 409 + def foo408(): Int = 410 + def foo409(): Int = 411 + def foo410(): Int = 412 + def foo411(): Int = 413 + def foo412(): Int = 414 + def foo413(): Int = 415 + def foo414(): Int = 416 + def foo415(): Int = 417 + def foo416(): Int = 418 + def foo417(): Int = 419 + def foo418(): Int = 420 + def foo419(): Int = 421 + def foo420(): Int = 422 + def foo421(): Int = 423 + def foo422(): Int = 424 + def foo423(): Int = 425 + def foo424(): Int = 426 + def foo425(): Int = 427 + def foo426(): Int = 428 + def foo427(): Int = 429 + def foo428(): Int = 430 + def foo429(): Int = 431 + def foo430(): Int = 432 + def foo431(): Int = 433 + def foo432(): Int = 434 + def foo433(): Int = 435 + def foo434(): Int = 436 + def foo435(): Int = 437 + def foo436(): Int = 438 + def foo437(): Int = 439 + def foo438(): Int = 440 + def foo439(): Int = 441 + def foo440(): Int = 442 + def foo441(): Int = 443 + def foo442(): Int = 444 + def foo443(): Int = 445 + def foo444(): Int = 446 + def foo445(): Int = 447 + def foo446(): Int = 448 + def foo447(): Int = 449 + def foo448(): Int = 450 + def foo449(): Int = 451 + def foo450(): Int = 452 + def foo451(): Int = 453 + def foo452(): Int = 454 + def foo453(): Int = 455 + def foo454(): Int = 456 + def foo455(): Int = 457 + def foo456(): Int = 458 + def foo457(): Int = 459 + def foo458(): Int = 460 + def foo459(): Int = 461 + def foo460(): Int = 462 + def foo461(): Int = 463 + def foo462(): Int = 464 + def foo463(): Int = 465 + def foo464(): Int = 466 + def foo465(): Int = 467 + def foo466(): Int = 468 + def foo467(): Int = 469 + def foo468(): Int = 470 + def foo469(): Int = 471 + def foo470(): Int = 472 + def foo471(): Int = 473 + def foo472(): Int = 474 + def foo473(): Int = 475 + def foo474(): Int = 476 + def foo475(): Int = 477 + def foo476(): Int = 478 + def foo477(): Int = 479 + def foo478(): Int = 480 + def foo479(): Int = 481 + def foo480(): Int = 482 + def foo481(): Int = 483 + def foo482(): Int = 484 + def foo483(): Int = 485 + def foo484(): Int = 486 + def foo485(): Int = 487 + def foo486(): Int = 488 + def foo487(): Int = 489 + def foo488(): Int = 490 + def foo489(): Int = 491 + def foo490(): Int = 492 + def foo491(): Int = 493 + def foo492(): Int = 494 + def foo493(): Int = 495 + def foo494(): Int = 496 + def foo495(): Int = 497 + def foo496(): Int = 498 + def foo497(): Int = 499 + def foo498(): Int = 500 + def foo499(): Int = 501 + def foo500(): Int = 502 + def foo501(): Int = 503 + def foo502(): Int = 504 + def foo503(): Int = 505 + def foo504(): Int = 506 + def foo505(): Int = 507 + def foo506(): Int = 508 + def foo507(): Int = 509 + def foo508(): Int = 510 + def foo509(): Int = 511 + def foo510(): Int = 512 + def foo511(): Int = 513 + def foo512(): Int = 514 + def foo513(): Int = 515 + def foo514(): Int = 516 + def foo515(): Int = 517 + def foo516(): Int = 518 + def foo517(): Int = 519 + def foo518(): Int = 520 + def foo519(): Int = 521 + def foo520(): Int = 522 + def foo521(): Int = 523 + def foo522(): Int = 524 + def foo523(): Int = 525 + def foo524(): Int = 526 + def foo525(): Int = 527 + def foo526(): Int = 528 + def foo527(): Int = 529 + def foo528(): Int = 530 + def foo529(): Int = 531 + def foo530(): Int = 532 + def foo531(): Int = 533 + def foo532(): Int = 534 + def foo533(): Int = 535 + def foo534(): Int = 536 + def foo535(): Int = 537 + def foo536(): Int = 538 + def foo537(): Int = 539 + def foo538(): Int = 540 + def foo539(): Int = 541 + def foo540(): Int = 542 + def foo541(): Int = 543 + def foo542(): Int = 544 + def foo543(): Int = 545 + def foo544(): Int = 546 + def foo545(): Int = 547 + def foo546(): Int = 548 + def foo547(): Int = 549 + def foo548(): Int = 550 + def foo549(): Int = 551 + def foo550(): Int = 552 + def foo551(): Int = 553 + def foo552(): Int = 554 + def foo553(): Int = 555 + def foo554(): Int = 556 + def foo555(): Int = 557 + def foo556(): Int = 558 + def foo557(): Int = 559 + def foo558(): Int = 560 + def foo559(): Int = 561 + def foo560(): Int = 562 + def foo561(): Int = 563 + def foo562(): Int = 564 + def foo563(): Int = 565 + def foo564(): Int = 566 + def foo565(): Int = 567 + def foo566(): Int = 568 + def foo567(): Int = 569 + def foo568(): Int = 570 + def foo569(): Int = 571 + def foo570(): Int = 572 + def foo571(): Int = 573 + def foo572(): Int = 574 + def foo573(): Int = 575 + def foo574(): Int = 576 + def foo575(): Int = 577 + def foo576(): Int = 578 + def foo577(): Int = 579 + def foo578(): Int = 580 + def foo579(): Int = 581 + def foo580(): Int = 582 + def foo581(): Int = 583 + def foo582(): Int = 584 + def foo583(): Int = 585 + def foo584(): Int = 586 + def foo585(): Int = 587 + def foo586(): Int = 588 + def foo587(): Int = 589 + def foo588(): Int = 590 + def foo589(): Int = 591 + def foo590(): Int = 592 + def foo591(): Int = 593 + def foo592(): Int = 594 + def foo593(): Int = 595 + def foo594(): Int = 596 + def foo595(): Int = 597 + def foo596(): Int = 598 + def foo597(): Int = 599 + def foo598(): Int = 600 + def foo599(): Int = 601 + def foo600(): Int = 602 + def foo601(): Int = 603 + def foo602(): Int = 604 + def foo603(): Int = 605 + def foo604(): Int = 606 + def foo605(): Int = 607 + def foo606(): Int = 608 + def foo607(): Int = 609 + def foo608(): Int = 610 + def foo609(): Int = 611 + def foo610(): Int = 612 + def foo611(): Int = 613 + def foo612(): Int = 614 + def foo613(): Int = 615 + def foo614(): Int = 616 + def foo615(): Int = 617 + def foo616(): Int = 618 + def foo617(): Int = 619 + def foo618(): Int = 620 + def foo619(): Int = 621 + def foo620(): Int = 622 + def foo621(): Int = 623 + def foo622(): Int = 624 + def foo623(): Int = 625 + def foo624(): Int = 626 + def foo625(): Int = 627 + def foo626(): Int = 628 + def foo627(): Int = 629 + def foo628(): Int = 630 + def foo629(): Int = 631 + def foo630(): Int = 632 + def foo631(): Int = 633 + def foo632(): Int = 634 + def foo633(): Int = 635 + def foo634(): Int = 636 + def foo635(): Int = 637 + def foo636(): Int = 638 + def foo637(): Int = 639 + def foo638(): Int = 640 + def foo639(): Int = 641 + def foo640(): Int = 642 + def foo641(): Int = 643 + def foo642(): Int = 644 + def foo643(): Int = 645 + def foo644(): Int = 646 + def foo645(): Int = 647 + def foo646(): Int = 648 + def foo647(): Int = 649 + def foo648(): Int = 650 + def foo649(): Int = 651 + def foo650(): Int = 652 + def foo651(): Int = 653 + def foo652(): Int = 654 + def foo653(): Int = 655 + def foo654(): Int = 656 + def foo655(): Int = 657 + def foo656(): Int = 658 + def foo657(): Int = 659 + def foo658(): Int = 660 + def foo659(): Int = 661 + def foo660(): Int = 662 + def foo661(): Int = 663 + def foo662(): Int = 664 + def foo663(): Int = 665 + def foo664(): Int = 666 + def foo665(): Int = 667 + def foo666(): Int = 668 + def foo667(): Int = 669 + def foo668(): Int = 670 + def foo669(): Int = 671 + def foo670(): Int = 672 + def foo671(): Int = 673 + def foo672(): Int = 674 + def foo673(): Int = 675 + def foo674(): Int = 676 + def foo675(): Int = 677 + def foo676(): Int = 678 + def foo677(): Int = 679 + def foo678(): Int = 680 + def foo679(): Int = 681 + def foo680(): Int = 682 + def foo681(): Int = 683 + def foo682(): Int = 684 + def foo683(): Int = 685 + def foo684(): Int = 686 + def foo685(): Int = 687 + def foo686(): Int = 688 + def foo687(): Int = 689 + def foo688(): Int = 690 + def foo689(): Int = 691 + def foo690(): Int = 692 + def foo691(): Int = 693 + def foo692(): Int = 694 + def foo693(): Int = 695 + def foo694(): Int = 696 + def foo695(): Int = 697 + def foo696(): Int = 698 + def foo697(): Int = 699 + def foo698(): Int = 700 + def foo699(): Int = 701 + def foo700(): Int = 702 + def foo701(): Int = 703 + def foo702(): Int = 704 + def foo703(): Int = 705 + def foo704(): Int = 706 + def foo705(): Int = 707 + def foo706(): Int = 708 + def foo707(): Int = 709 + def foo708(): Int = 710 + def foo709(): Int = 711 + def foo710(): Int = 712 + def foo711(): Int = 713 + def foo712(): Int = 714 + def foo713(): Int = 715 + def foo714(): Int = 716 + def foo715(): Int = 717 + def foo716(): Int = 718 + def foo717(): Int = 719 + def foo718(): Int = 720 + def foo719(): Int = 721 + def foo720(): Int = 722 + def foo721(): Int = 723 + def foo722(): Int = 724 + def foo723(): Int = 725 + def foo724(): Int = 726 + def foo725(): Int = 727 + def foo726(): Int = 728 + def foo727(): Int = 729 + def foo728(): Int = 730 + def foo729(): Int = 731 + def foo730(): Int = 732 + def foo731(): Int = 733 + def foo732(): Int = 734 + def foo733(): Int = 735 + def foo734(): Int = 736 + def foo735(): Int = 737 + def foo736(): Int = 738 + def foo737(): Int = 739 + def foo738(): Int = 740 + def foo739(): Int = 741 + def foo740(): Int = 742 + def foo741(): Int = 743 + def foo742(): Int = 744 + def foo743(): Int = 745 + def foo744(): Int = 746 + def foo745(): Int = 747 + def foo746(): Int = 748 + def foo747(): Int = 749 + def foo748(): Int = 750 + def foo749(): Int = 751 + def foo750(): Int = 752 + def foo751(): Int = 753 + def foo752(): Int = 754 + def foo753(): Int = 755 + def foo754(): Int = 756 + def foo755(): Int = 757 + def foo756(): Int = 758 + def foo757(): Int = 759 + def foo758(): Int = 760 + def foo759(): Int = 761 + def foo760(): Int = 762 + def foo761(): Int = 763 + def foo762(): Int = 764 + def foo763(): Int = 765 + def foo764(): Int = 766 + def foo765(): Int = 767 + def foo766(): Int = 768 + def foo767(): Int = 769 + def foo768(): Int = 770 + def foo769(): Int = 771 + def foo770(): Int = 772 + def foo771(): Int = 773 + def foo772(): Int = 774 + def foo773(): Int = 775 + def foo774(): Int = 776 + def foo775(): Int = 777 + def foo776(): Int = 778 + def foo777(): Int = 779 + def foo778(): Int = 780 + def foo779(): Int = 781 + def foo780(): Int = 782 + def foo781(): Int = 783 + def foo782(): Int = 784 + def foo783(): Int = 785 + def foo784(): Int = 786 + def foo785(): Int = 787 + def foo786(): Int = 788 + def foo787(): Int = 789 + def foo788(): Int = 790 + def foo789(): Int = 791 + def foo790(): Int = 792 + def foo791(): Int = 793 + def foo792(): Int = 794 + def foo793(): Int = 795 + def foo794(): Int = 796 + def foo795(): Int = 797 + def foo796(): Int = 798 + def foo797(): Int = 799 + def foo798(): Int = 800 + def foo799(): Int = 801 + def foo800(): Int = 802 + def foo801(): Int = 803 + def foo802(): Int = 804 + def foo803(): Int = 805 + def foo804(): Int = 806 + def foo805(): Int = 807 + def foo806(): Int = 808 + def foo807(): Int = 809 + def foo808(): Int = 810 + def foo809(): Int = 811 + def foo810(): Int = 812 + def foo811(): Int = 813 + def foo812(): Int = 814 + def foo813(): Int = 815 + def foo814(): Int = 816 + def foo815(): Int = 817 + def foo816(): Int = 818 + def foo817(): Int = 819 + def foo818(): Int = 820 + def foo819(): Int = 821 + def foo820(): Int = 822 + def foo821(): Int = 823 + def foo822(): Int = 824 + def foo823(): Int = 825 + def foo824(): Int = 826 + def foo825(): Int = 827 + def foo826(): Int = 828 + def foo827(): Int = 829 + def foo828(): Int = 830 + def foo829(): Int = 831 + def foo830(): Int = 832 + def foo831(): Int = 833 + def foo832(): Int = 834 + def foo833(): Int = 835 + def foo834(): Int = 836 + def foo835(): Int = 837 + def foo836(): Int = 838 + def foo837(): Int = 839 + def foo838(): Int = 840 + def foo839(): Int = 841 + def foo840(): Int = 842 + def foo841(): Int = 843 + def foo842(): Int = 844 + def foo843(): Int = 845 + def foo844(): Int = 846 + def foo845(): Int = 847 + def foo846(): Int = 848 + def foo847(): Int = 849 + def foo848(): Int = 850 + def foo849(): Int = 851 + def foo850(): Int = 852 + def foo851(): Int = 853 + def foo852(): Int = 854 + def foo853(): Int = 855 + def foo854(): Int = 856 + def foo855(): Int = 857 + def foo856(): Int = 858 + def foo857(): Int = 859 + def foo858(): Int = 860 + def foo859(): Int = 861 + def foo860(): Int = 862 + def foo861(): Int = 863 + def foo862(): Int = 864 + def foo863(): Int = 865 + def foo864(): Int = 866 + def foo865(): Int = 867 + def foo866(): Int = 868 + def foo867(): Int = 869 + def foo868(): Int = 870 + def foo869(): Int = 871 + def foo870(): Int = 872 + def foo871(): Int = 873 + def foo872(): Int = 874 + def foo873(): Int = 875 + def foo874(): Int = 876 + def foo875(): Int = 877 + def foo876(): Int = 878 + def foo877(): Int = 879 + def foo878(): Int = 880 + def foo879(): Int = 881 + def foo880(): Int = 882 + def foo881(): Int = 883 + def foo882(): Int = 884 + def foo883(): Int = 885 + def foo884(): Int = 886 + def foo885(): Int = 887 + def foo886(): Int = 888 + def foo887(): Int = 889 + def foo888(): Int = 890 + def foo889(): Int = 891 + def foo890(): Int = 892 + def foo891(): Int = 893 + def foo892(): Int = 894 + def foo893(): Int = 895 + def foo894(): Int = 896 + def foo895(): Int = 897 + def foo896(): Int = 898 + def foo897(): Int = 899 + def foo898(): Int = 900 + def foo899(): Int = 901 + def foo900(): Int = 902 + def foo901(): Int = 903 + def foo902(): Int = 904 + def foo903(): Int = 905 + def foo904(): Int = 906 + def foo905(): Int = 907 + def foo906(): Int = 908 + def foo907(): Int = 909 + def foo908(): Int = 910 + def foo909(): Int = 911 + def foo910(): Int = 912 + def foo911(): Int = 913 + def foo912(): Int = 914 + def foo913(): Int = 915 + def foo914(): Int = 916 + def foo915(): Int = 917 + def foo916(): Int = 918 + def foo917(): Int = 919 + def foo918(): Int = 920 + def foo919(): Int = 921 + def foo920(): Int = 922 + def foo921(): Int = 923 + def foo922(): Int = 924 + def foo923(): Int = 925 + def foo924(): Int = 926 + def foo925(): Int = 927 + def foo926(): Int = 928 + def foo927(): Int = 929 + def foo928(): Int = 930 + def foo929(): Int = 931 + def foo930(): Int = 932 + def foo931(): Int = 933 + def foo932(): Int = 934 + def foo933(): Int = 935 + def foo934(): Int = 936 + def foo935(): Int = 937 + def foo936(): Int = 938 + def foo937(): Int = 939 + def foo938(): Int = 940 + def foo939(): Int = 941 + def foo940(): Int = 942 + def foo941(): Int = 943 + def foo942(): Int = 944 + def foo943(): Int = 945 + def foo944(): Int = 946 + def foo945(): Int = 947 + def foo946(): Int = 948 + def foo947(): Int = 949 + def foo948(): Int = 950 + def foo949(): Int = 951 + def foo950(): Int = 952 + def foo951(): Int = 953 + def foo952(): Int = 954 + def foo953(): Int = 955 + def foo954(): Int = 956 + def foo955(): Int = 957 + def foo956(): Int = 958 + def foo957(): Int = 959 + def foo958(): Int = 960 + def foo959(): Int = 961 + def foo960(): Int = 962 + def foo961(): Int = 963 + def foo962(): Int = 964 + def foo963(): Int = 965 + def foo964(): Int = 966 + def foo965(): Int = 967 + def foo966(): Int = 968 + def foo967(): Int = 969 + def foo968(): Int = 970 + def foo969(): Int = 971 + def foo970(): Int = 972 + def foo971(): Int = 973 + def foo972(): Int = 974 + def foo973(): Int = 975 + def foo974(): Int = 976 + def foo975(): Int = 977 + def foo976(): Int = 978 + def foo977(): Int = 979 + def foo978(): Int = 980 + def foo979(): Int = 981 + def foo980(): Int = 982 + def foo981(): Int = 983 + def foo982(): Int = 984 + def foo983(): Int = 985 + def foo984(): Int = 986 + def foo985(): Int = 987 + def foo986(): Int = 988 + def foo987(): Int = 989 + def foo988(): Int = 990 + def foo989(): Int = 991 + def foo990(): Int = 992 + def foo991(): Int = 993 + def foo992(): Int = 994 + def foo993(): Int = 995 + def foo994(): Int = 996 + def foo995(): Int = 997 + def foo996(): Int = 998 + def foo997(): Int = 999 + def foo998(): Int = 1000 + def foo999(): Int = 1001 + def foo1000(): Int = 1002 + def foo1001(): Int = 1003 + def foo1002(): Int = 1004 + def foo1003(): Int = 1005 + def foo1004(): Int = 1006 + def foo1005(): Int = 1007 + def foo1006(): Int = 1008 + def foo1007(): Int = 1009 + def foo1008(): Int = 1010 + def foo1009(): Int = 1011 + def foo1010(): Int = 1012 + def foo1011(): Int = 1013 + def foo1012(): Int = 1014 + def foo1013(): Int = 1015 + def foo1014(): Int = 1016 + def foo1015(): Int = 1017 + def foo1016(): Int = 1018 + def foo1017(): Int = 1019 + def foo1018(): Int = 1020 + def foo1019(): Int = 1021 + def foo1020(): Int = 1022 + def foo1021(): Int = 1023 + def foo1022(): Int = 1024 + def foo1023(): Int = 1025 + def foo1024(): Int = 1026 + def foo1025(): Int = 1027 + def foo1026(): Int = 1028 + def foo1027(): Int = 1029 + def foo1028(): Int = 1030 + def foo1029(): Int = 1031 + def foo1030(): Int = 1032 + def foo1031(): Int = 1033 + def foo1032(): Int = 1034 + def foo1033(): Int = 1035 + def foo1034(): Int = 1036 + def foo1035(): Int = 1037 + def foo1036(): Int = 1038 + def foo1037(): Int = 1039 + def foo1038(): Int = 1040 + def foo1039(): Int = 1041 + def foo1040(): Int = 1042 + def foo1041(): Int = 1043 + def foo1042(): Int = 1044 + def foo1043(): Int = 1045 + def foo1044(): Int = 1046 + def foo1045(): Int = 1047 + def foo1046(): Int = 1048 + def foo1047(): Int = 1049 + def foo1048(): Int = 1050 + def foo1049(): Int = 1051 + def foo1050(): Int = 1052 + def foo1051(): Int = 1053 + def foo1052(): Int = 1054 + def foo1053(): Int = 1055 + def foo1054(): Int = 1056 + def foo1055(): Int = 1057 + def foo1056(): Int = 1058 + def foo1057(): Int = 1059 + def foo1058(): Int = 1060 + def foo1059(): Int = 1061 + def foo1060(): Int = 1062 + def foo1061(): Int = 1063 + def foo1062(): Int = 1064 + def foo1063(): Int = 1065 + def foo1064(): Int = 1066 + def foo1065(): Int = 1067 + def foo1066(): Int = 1068 + def foo1067(): Int = 1069 + def foo1068(): Int = 1070 + def foo1069(): Int = 1071 + def foo1070(): Int = 1072 + def foo1071(): Int = 1073 + def foo1072(): Int = 1074 + def foo1073(): Int = 1075 + def foo1074(): Int = 1076 + def foo1075(): Int = 1077 + def foo1076(): Int = 1078 + def foo1077(): Int = 1079 + def foo1078(): Int = 1080 + def foo1079(): Int = 1081 + def foo1080(): Int = 1082 + def foo1081(): Int = 1083 + def foo1082(): Int = 1084 + def foo1083(): Int = 1085 + def foo1084(): Int = 1086 + def foo1085(): Int = 1087 + def foo1086(): Int = 1088 + def foo1087(): Int = 1089 + def foo1088(): Int = 1090 + def foo1089(): Int = 1091 + def foo1090(): Int = 1092 + def foo1091(): Int = 1093 + def foo1092(): Int = 1094 + def foo1093(): Int = 1095 + def foo1094(): Int = 1096 + def foo1095(): Int = 1097 + def foo1096(): Int = 1098 + def foo1097(): Int = 1099 + def foo1098(): Int = 1100 + def foo1099(): Int = 1101 + def foo1100(): Int = 1102 + def foo1101(): Int = 1103 + def foo1102(): Int = 1104 + def foo1103(): Int = 1105 + def foo1104(): Int = 1106 + def foo1105(): Int = 1107 + def foo1106(): Int = 1108 + def foo1107(): Int = 1109 + def foo1108(): Int = 1110 + def foo1109(): Int = 1111 + def foo1110(): Int = 1112 + def foo1111(): Int = 1113 + def foo1112(): Int = 1114 + def foo1113(): Int = 1115 + def foo1114(): Int = 1116 + def foo1115(): Int = 1117 + def foo1116(): Int = 1118 + def foo1117(): Int = 1119 + def foo1118(): Int = 1120 + def foo1119(): Int = 1121 + def foo1120(): Int = 1122 + def foo1121(): Int = 1123 + def foo1122(): Int = 1124 + def foo1123(): Int = 1125 + def foo1124(): Int = 1126 + def foo1125(): Int = 1127 + def foo1126(): Int = 1128 + def foo1127(): Int = 1129 + def foo1128(): Int = 1130 + def foo1129(): Int = 1131 + def foo1130(): Int = 1132 + def foo1131(): Int = 1133 + def foo1132(): Int = 1134 + def foo1133(): Int = 1135 + def foo1134(): Int = 1136 + def foo1135(): Int = 1137 + def foo1136(): Int = 1138 + def foo1137(): Int = 1139 + def foo1138(): Int = 1140 + def foo1139(): Int = 1141 + def foo1140(): Int = 1142 + def foo1141(): Int = 1143 + def foo1142(): Int = 1144 + def foo1143(): Int = 1145 + def foo1144(): Int = 1146 + def foo1145(): Int = 1147 + def foo1146(): Int = 1148 + def foo1147(): Int = 1149 + def foo1148(): Int = 1150 + def foo1149(): Int = 1151 + def foo1150(): Int = 1152 + def foo1151(): Int = 1153 + def foo1152(): Int = 1154 + def foo1153(): Int = 1155 + def foo1154(): Int = 1156 + def foo1155(): Int = 1157 + def foo1156(): Int = 1158 + def foo1157(): Int = 1159 + def foo1158(): Int = 1160 + def foo1159(): Int = 1161 + def foo1160(): Int = 1162 + def foo1161(): Int = 1163 + def foo1162(): Int = 1164 + def foo1163(): Int = 1165 + def foo1164(): Int = 1166 + def foo1165(): Int = 1167 + def foo1166(): Int = 1168 + def foo1167(): Int = 1169 + def foo1168(): Int = 1170 + def foo1169(): Int = 1171 + def foo1170(): Int = 1172 + def foo1171(): Int = 1173 + def foo1172(): Int = 1174 + def foo1173(): Int = 1175 + def foo1174(): Int = 1176 + def foo1175(): Int = 1177 + def foo1176(): Int = 1178 + def foo1177(): Int = 1179 + def foo1178(): Int = 1180 + def foo1179(): Int = 1181 + def foo1180(): Int = 1182 + def foo1181(): Int = 1183 + def foo1182(): Int = 1184 + def foo1183(): Int = 1185 + def foo1184(): Int = 1186 + def foo1185(): Int = 1187 + def foo1186(): Int = 1188 + def foo1187(): Int = 1189 + def foo1188(): Int = 1190 + def foo1189(): Int = 1191 + def foo1190(): Int = 1192 + def foo1191(): Int = 1193 + def foo1192(): Int = 1194 + def foo1193(): Int = 1195 + def foo1194(): Int = 1196 + def foo1195(): Int = 1197 + def foo1196(): Int = 1198 + def foo1197(): Int = 1199 + def foo1198(): Int = 1200 + def foo1199(): Int = 1201 + def foo1200(): Int = 1202 + def foo1201(): Int = 1203 + def foo1202(): Int = 1204 + def foo1203(): Int = 1205 + def foo1204(): Int = 1206 + def foo1205(): Int = 1207 + def foo1206(): Int = 1208 + def foo1207(): Int = 1209 + def foo1208(): Int = 1210 + def foo1209(): Int = 1211 + def foo1210(): Int = 1212 + def foo1211(): Int = 1213 + def foo1212(): Int = 1214 + def foo1213(): Int = 1215 + def foo1214(): Int = 1216 + def foo1215(): Int = 1217 + def foo1216(): Int = 1218 + def foo1217(): Int = 1219 + def foo1218(): Int = 1220 + def foo1219(): Int = 1221 + def foo1220(): Int = 1222 + def foo1221(): Int = 1223 + def foo1222(): Int = 1224 + def foo1223(): Int = 1225 + def foo1224(): Int = 1226 + def foo1225(): Int = 1227 + def foo1226(): Int = 1228 + def foo1227(): Int = 1229 + def foo1228(): Int = 1230 + def foo1229(): Int = 1231 + def foo1230(): Int = 1232 + def foo1231(): Int = 1233 + def foo1232(): Int = 1234 + def foo1233(): Int = 1235 + def foo1234(): Int = 1236 + def foo1235(): Int = 1237 + def foo1236(): Int = 1238 + def foo1237(): Int = 1239 + def foo1238(): Int = 1240 + def foo1239(): Int = 1241 + def foo1240(): Int = 1242 + def foo1241(): Int = 1243 + def foo1242(): Int = 1244 + def foo1243(): Int = 1245 + def foo1244(): Int = 1246 + def foo1245(): Int = 1247 + def foo1246(): Int = 1248 + def foo1247(): Int = 1249 + def foo1248(): Int = 1250 + def foo1249(): Int = 1251 + def foo1250(): Int = 1252 + def foo1251(): Int = 1253 + def foo1252(): Int = 1254 + def foo1253(): Int = 1255 + def foo1254(): Int = 1256 + def foo1255(): Int = 1257 + def foo1256(): Int = 1258 + def foo1257(): Int = 1259 + def foo1258(): Int = 1260 + def foo1259(): Int = 1261 + def foo1260(): Int = 1262 + def foo1261(): Int = 1263 + def foo1262(): Int = 1264 + def foo1263(): Int = 1265 + def foo1264(): Int = 1266 + def foo1265(): Int = 1267 + def foo1266(): Int = 1268 + def foo1267(): Int = 1269 + def foo1268(): Int = 1270 + def foo1269(): Int = 1271 + def foo1270(): Int = 1272 + def foo1271(): Int = 1273 + def foo1272(): Int = 1274 + def foo1273(): Int = 1275 + def foo1274(): Int = 1276 + def foo1275(): Int = 1277 + def foo1276(): Int = 1278 + def foo1277(): Int = 1279 + def foo1278(): Int = 1280 + def foo1279(): Int = 1281 + def foo1280(): Int = 1282 + def foo1281(): Int = 1283 + def foo1282(): Int = 1284 + def foo1283(): Int = 1285 + def foo1284(): Int = 1286 + def foo1285(): Int = 1287 + def foo1286(): Int = 1288 + def foo1287(): Int = 1289 + def foo1288(): Int = 1290 + def foo1289(): Int = 1291 + def foo1290(): Int = 1292 + def foo1291(): Int = 1293 + def foo1292(): Int = 1294 + def foo1293(): Int = 1295 + def foo1294(): Int = 1296 + def foo1295(): Int = 1297 + def foo1296(): Int = 1298 + def foo1297(): Int = 1299 + def foo1298(): Int = 1300 + def foo1299(): Int = 1301 + def foo1300(): Int = 1302 + def foo1301(): Int = 1303 + def foo1302(): Int = 1304 + def foo1303(): Int = 1305 + def foo1304(): Int = 1306 + def foo1305(): Int = 1307 + def foo1306(): Int = 1308 + def foo1307(): Int = 1309 + def foo1308(): Int = 1310 + def foo1309(): Int = 1311 + def foo1310(): Int = 1312 + def foo1311(): Int = 1313 + def foo1312(): Int = 1314 + def foo1313(): Int = 1315 + def foo1314(): Int = 1316 + def foo1315(): Int = 1317 + def foo1316(): Int = 1318 + def foo1317(): Int = 1319 + def foo1318(): Int = 1320 + def foo1319(): Int = 1321 + def foo1320(): Int = 1322 + def foo1321(): Int = 1323 + def foo1322(): Int = 1324 + def foo1323(): Int = 1325 + def foo1324(): Int = 1326 + def foo1325(): Int = 1327 + def foo1326(): Int = 1328 + def foo1327(): Int = 1329 + def foo1328(): Int = 1330 + def foo1329(): Int = 1331 + def foo1330(): Int = 1332 + def foo1331(): Int = 1333 + def foo1332(): Int = 1334 + def foo1333(): Int = 1335 + def foo1334(): Int = 1336 + def foo1335(): Int = 1337 + def foo1336(): Int = 1338 + def foo1337(): Int = 1339 + def foo1338(): Int = 1340 + def foo1339(): Int = 1341 + def foo1340(): Int = 1342 + def foo1341(): Int = 1343 + def foo1342(): Int = 1344 + def foo1343(): Int = 1345 + def foo1344(): Int = 1346 + def foo1345(): Int = 1347 + def foo1346(): Int = 1348 + def foo1347(): Int = 1349 + def foo1348(): Int = 1350 + def foo1349(): Int = 1351 + def foo1350(): Int = 1352 + def foo1351(): Int = 1353 + def foo1352(): Int = 1354 + def foo1353(): Int = 1355 + def foo1354(): Int = 1356 + def foo1355(): Int = 1357 + def foo1356(): Int = 1358 + def foo1357(): Int = 1359 + def foo1358(): Int = 1360 + def foo1359(): Int = 1361 + def foo1360(): Int = 1362 + def foo1361(): Int = 1363 + def foo1362(): Int = 1364 + def foo1363(): Int = 1365 + def foo1364(): Int = 1366 + def foo1365(): Int = 1367 + def foo1366(): Int = 1368 + def foo1367(): Int = 1369 + def foo1368(): Int = 1370 + def foo1369(): Int = 1371 + def foo1370(): Int = 1372 + def foo1371(): Int = 1373 + def foo1372(): Int = 1374 + def foo1373(): Int = 1375 + def foo1374(): Int = 1376 + def foo1375(): Int = 1377 + def foo1376(): Int = 1378 + def foo1377(): Int = 1379 + def foo1378(): Int = 1380 + def foo1379(): Int = 1381 + def foo1380(): Int = 1382 + def foo1381(): Int = 1383 + def foo1382(): Int = 1384 + def foo1383(): Int = 1385 + def foo1384(): Int = 1386 + def foo1385(): Int = 1387 + def foo1386(): Int = 1388 + def foo1387(): Int = 1389 + def foo1388(): Int = 1390 + def foo1389(): Int = 1391 + def foo1390(): Int = 1392 + def foo1391(): Int = 1393 + def foo1392(): Int = 1394 + def foo1393(): Int = 1395 + def foo1394(): Int = 1396 + def foo1395(): Int = 1397 + def foo1396(): Int = 1398 + def foo1397(): Int = 1399 + def foo1398(): Int = 1400 + def foo1399(): Int = 1401 + def foo1400(): Int = 1402 + def foo1401(): Int = 1403 + def foo1402(): Int = 1404 + def foo1403(): Int = 1405 + def foo1404(): Int = 1406 + def foo1405(): Int = 1407 + def foo1406(): Int = 1408 + def foo1407(): Int = 1409 + def foo1408(): Int = 1410 + def foo1409(): Int = 1411 + def foo1410(): Int = 1412 + def foo1411(): Int = 1413 + def foo1412(): Int = 1414 + def foo1413(): Int = 1415 + def foo1414(): Int = 1416 + def foo1415(): Int = 1417 + def foo1416(): Int = 1418 + def foo1417(): Int = 1419 + def foo1418(): Int = 1420 + def foo1419(): Int = 1421 + def foo1420(): Int = 1422 + def foo1421(): Int = 1423 + def foo1422(): Int = 1424 + def foo1423(): Int = 1425 + def foo1424(): Int = 1426 + def foo1425(): Int = 1427 + def foo1426(): Int = 1428 + def foo1427(): Int = 1429 + def foo1428(): Int = 1430 + def foo1429(): Int = 1431 + def foo1430(): Int = 1432 + def foo1431(): Int = 1433 + def foo1432(): Int = 1434 + def foo1433(): Int = 1435 + def foo1434(): Int = 1436 + def foo1435(): Int = 1437 + def foo1436(): Int = 1438 + def foo1437(): Int = 1439 + def foo1438(): Int = 1440 + def foo1439(): Int = 1441 + def foo1440(): Int = 1442 + def foo1441(): Int = 1443 + def foo1442(): Int = 1444 + def foo1443(): Int = 1445 + def foo1444(): Int = 1446 + def foo1445(): Int = 1447 + def foo1446(): Int = 1448 + def foo1447(): Int = 1449 + def foo1448(): Int = 1450 + def foo1449(): Int = 1451 + def foo1450(): Int = 1452 + def foo1451(): Int = 1453 + def foo1452(): Int = 1454 + def foo1453(): Int = 1455 + def foo1454(): Int = 1456 + def foo1455(): Int = 1457 + def foo1456(): Int = 1458 + def foo1457(): Int = 1459 + def foo1458(): Int = 1460 + def foo1459(): Int = 1461 + def foo1460(): Int = 1462 + def foo1461(): Int = 1463 + def foo1462(): Int = 1464 + def foo1463(): Int = 1465 + def foo1464(): Int = 1466 + def foo1465(): Int = 1467 + def foo1466(): Int = 1468 + def foo1467(): Int = 1469 + def foo1468(): Int = 1470 + def foo1469(): Int = 1471 + def foo1470(): Int = 1472 + def foo1471(): Int = 1473 + def foo1472(): Int = 1474 + def foo1473(): Int = 1475 + def foo1474(): Int = 1476 + def foo1475(): Int = 1477 + def foo1476(): Int = 1478 + def foo1477(): Int = 1479 + def foo1478(): Int = 1480 + def foo1479(): Int = 1481 + def foo1480(): Int = 1482 + def foo1481(): Int = 1483 + def foo1482(): Int = 1484 + def foo1483(): Int = 1485 + def foo1484(): Int = 1486 + def foo1485(): Int = 1487 + def foo1486(): Int = 1488 + def foo1487(): Int = 1489 + def foo1488(): Int = 1490 + def foo1489(): Int = 1491 + def foo1490(): Int = 1492 + def foo1491(): Int = 1493 + def foo1492(): Int = 1494 + def foo1493(): Int = 1495 + def foo1494(): Int = 1496 + def foo1495(): Int = 1497 + def foo1496(): Int = 1498 + def foo1497(): Int = 1499 + def foo1498(): Int = 1500 + def foo1499(): Int = 1501 + def foo1500(): Int = 1502 + def foo1501(): Int = 1503 + def foo1502(): Int = 1504 + def foo1503(): Int = 1505 + def foo1504(): Int = 1506 + def foo1505(): Int = 1507 + def foo1506(): Int = 1508 + def foo1507(): Int = 1509 + def foo1508(): Int = 1510 + def foo1509(): Int = 1511 + def foo1510(): Int = 1512 + def foo1511(): Int = 1513 + def foo1512(): Int = 1514 + def foo1513(): Int = 1515 + def foo1514(): Int = 1516 + def foo1515(): Int = 1517 + def foo1516(): Int = 1518 + def foo1517(): Int = 1519 + def foo1518(): Int = 1520 + def foo1519(): Int = 1521 + def foo1520(): Int = 1522 + def foo1521(): Int = 1523 + def foo1522(): Int = 1524 + def foo1523(): Int = 1525 + def foo1524(): Int = 1526 + def foo1525(): Int = 1527 + def foo1526(): Int = 1528 + def foo1527(): Int = 1529 + def foo1528(): Int = 1530 + def foo1529(): Int = 1531 + def foo1530(): Int = 1532 + def foo1531(): Int = 1533 + def foo1532(): Int = 1534 + def foo1533(): Int = 1535 + def foo1534(): Int = 1536 + def foo1535(): Int = 1537 + def foo1536(): Int = 1538 + def foo1537(): Int = 1539 + def foo1538(): Int = 1540 + def foo1539(): Int = 1541 + def foo1540(): Int = 1542 + def foo1541(): Int = 1543 + def foo1542(): Int = 1544 + def foo1543(): Int = 1545 + def foo1544(): Int = 1546 + def foo1545(): Int = 1547 + def foo1546(): Int = 1548 + def foo1547(): Int = 1549 + def foo1548(): Int = 1550 + def foo1549(): Int = 1551 + def foo1550(): Int = 1552 + def foo1551(): Int = 1553 + def foo1552(): Int = 1554 + def foo1553(): Int = 1555 + def foo1554(): Int = 1556 + def foo1555(): Int = 1557 + def foo1556(): Int = 1558 + def foo1557(): Int = 1559 + def foo1558(): Int = 1560 + def foo1559(): Int = 1561 + def foo1560(): Int = 1562 + def foo1561(): Int = 1563 + def foo1562(): Int = 1564 + def foo1563(): Int = 1565 + def foo1564(): Int = 1566 + def foo1565(): Int = 1567 + def foo1566(): Int = 1568 + def foo1567(): Int = 1569 + def foo1568(): Int = 1570 + def foo1569(): Int = 1571 + def foo1570(): Int = 1572 + def foo1571(): Int = 1573 + def foo1572(): Int = 1574 + def foo1573(): Int = 1575 + def foo1574(): Int = 1576 + def foo1575(): Int = 1577 + def foo1576(): Int = 1578 + def foo1577(): Int = 1579 + def foo1578(): Int = 1580 + def foo1579(): Int = 1581 + def foo1580(): Int = 1582 + def foo1581(): Int = 1583 + def foo1582(): Int = 1584 + def foo1583(): Int = 1585 + def foo1584(): Int = 1586 + def foo1585(): Int = 1587 + def foo1586(): Int = 1588 + def foo1587(): Int = 1589 + def foo1588(): Int = 1590 + def foo1589(): Int = 1591 + def foo1590(): Int = 1592 + def foo1591(): Int = 1593 + def foo1592(): Int = 1594 + def foo1593(): Int = 1595 + def foo1594(): Int = 1596 + def foo1595(): Int = 1597 + def foo1596(): Int = 1598 + def foo1597(): Int = 1599 + def foo1598(): Int = 1600 + def foo1599(): Int = 1601 + def foo1600(): Int = 1602 + def foo1601(): Int = 1603 + def foo1602(): Int = 1604 + def foo1603(): Int = 1605 + def foo1604(): Int = 1606 + def foo1605(): Int = 1607 + def foo1606(): Int = 1608 + def foo1607(): Int = 1609 + def foo1608(): Int = 1610 + def foo1609(): Int = 1611 + def foo1610(): Int = 1612 + def foo1611(): Int = 1613 + def foo1612(): Int = 1614 + def foo1613(): Int = 1615 + def foo1614(): Int = 1616 + def foo1615(): Int = 1617 + def foo1616(): Int = 1618 + def foo1617(): Int = 1619 + def foo1618(): Int = 1620 + def foo1619(): Int = 1621 + def foo1620(): Int = 1622 + def foo1621(): Int = 1623 + def foo1622(): Int = 1624 + def foo1623(): Int = 1625 + def foo1624(): Int = 1626 + def foo1625(): Int = 1627 + def foo1626(): Int = 1628 + def foo1627(): Int = 1629 + def foo1628(): Int = 1630 + def foo1629(): Int = 1631 + def foo1630(): Int = 1632 + def foo1631(): Int = 1633 + def foo1632(): Int = 1634 + def foo1633(): Int = 1635 + def foo1634(): Int = 1636 + def foo1635(): Int = 1637 + def foo1636(): Int = 1638 + def foo1637(): Int = 1639 + def foo1638(): Int = 1640 + def foo1639(): Int = 1641 + def foo1640(): Int = 1642 + def foo1641(): Int = 1643 + def foo1642(): Int = 1644 + def foo1643(): Int = 1645 + def foo1644(): Int = 1646 + def foo1645(): Int = 1647 + def foo1646(): Int = 1648 + def foo1647(): Int = 1649 + def foo1648(): Int = 1650 + def foo1649(): Int = 1651 + def foo1650(): Int = 1652 + def foo1651(): Int = 1653 + def foo1652(): Int = 1654 + def foo1653(): Int = 1655 + def foo1654(): Int = 1656 + def foo1655(): Int = 1657 + def foo1656(): Int = 1658 + def foo1657(): Int = 1659 + def foo1658(): Int = 1660 + def foo1659(): Int = 1661 + def foo1660(): Int = 1662 + def foo1661(): Int = 1663 + def foo1662(): Int = 1664 + def foo1663(): Int = 1665 + def foo1664(): Int = 1666 + def foo1665(): Int = 1667 + def foo1666(): Int = 1668 + def foo1667(): Int = 1669 + def foo1668(): Int = 1670 + def foo1669(): Int = 1671 + def foo1670(): Int = 1672 + def foo1671(): Int = 1673 + def foo1672(): Int = 1674 + def foo1673(): Int = 1675 + def foo1674(): Int = 1676 + def foo1675(): Int = 1677 + def foo1676(): Int = 1678 + def foo1677(): Int = 1679 + def foo1678(): Int = 1680 + def foo1679(): Int = 1681 + def foo1680(): Int = 1682 + def foo1681(): Int = 1683 + def foo1682(): Int = 1684 + def foo1683(): Int = 1685 + def foo1684(): Int = 1686 + def foo1685(): Int = 1687 + def foo1686(): Int = 1688 + def foo1687(): Int = 1689 + def foo1688(): Int = 1690 + def foo1689(): Int = 1691 + def foo1690(): Int = 1692 + def foo1691(): Int = 1693 + def foo1692(): Int = 1694 + def foo1693(): Int = 1695 + def foo1694(): Int = 1696 + def foo1695(): Int = 1697 + def foo1696(): Int = 1698 + def foo1697(): Int = 1699 + def foo1698(): Int = 1700 + def foo1699(): Int = 1701 + def foo1700(): Int = 1702 + def foo1701(): Int = 1703 + def foo1702(): Int = 1704 + def foo1703(): Int = 1705 + def foo1704(): Int = 1706 + def foo1705(): Int = 1707 + def foo1706(): Int = 1708 + def foo1707(): Int = 1709 + def foo1708(): Int = 1710 + def foo1709(): Int = 1711 + def foo1710(): Int = 1712 + def foo1711(): Int = 1713 + def foo1712(): Int = 1714 + def foo1713(): Int = 1715 + def foo1714(): Int = 1716 + def foo1715(): Int = 1717 + def foo1716(): Int = 1718 + def foo1717(): Int = 1719 + def foo1718(): Int = 1720 + def foo1719(): Int = 1721 + def foo1720(): Int = 1722 + def foo1721(): Int = 1723 + def foo1722(): Int = 1724 + def foo1723(): Int = 1725 + def foo1724(): Int = 1726 + def foo1725(): Int = 1727 + def foo1726(): Int = 1728 + def foo1727(): Int = 1729 + def foo1728(): Int = 1730 + def foo1729(): Int = 1731 + def foo1730(): Int = 1732 + def foo1731(): Int = 1733 + def foo1732(): Int = 1734 + def foo1733(): Int = 1735 + def foo1734(): Int = 1736 + def foo1735(): Int = 1737 + def foo1736(): Int = 1738 + def foo1737(): Int = 1739 + def foo1738(): Int = 1740 + def foo1739(): Int = 1741 + def foo1740(): Int = 1742 + def foo1741(): Int = 1743 + def foo1742(): Int = 1744 + def foo1743(): Int = 1745 + def foo1744(): Int = 1746 + def foo1745(): Int = 1747 + def foo1746(): Int = 1748 + def foo1747(): Int = 1749 + def foo1748(): Int = 1750 + def foo1749(): Int = 1751 + def foo1750(): Int = 1752 + def foo1751(): Int = 1753 + def foo1752(): Int = 1754 + def foo1753(): Int = 1755 + def foo1754(): Int = 1756 + def foo1755(): Int = 1757 + def foo1756(): Int = 1758 + def foo1757(): Int = 1759 + def foo1758(): Int = 1760 + def foo1759(): Int = 1761 + def foo1760(): Int = 1762 + def foo1761(): Int = 1763 + def foo1762(): Int = 1764 + def foo1763(): Int = 1765 + def foo1764(): Int = 1766 + def foo1765(): Int = 1767 + def foo1766(): Int = 1768 + def foo1767(): Int = 1769 + def foo1768(): Int = 1770 + def foo1769(): Int = 1771 + def foo1770(): Int = 1772 + def foo1771(): Int = 1773 + def foo1772(): Int = 1774 + def foo1773(): Int = 1775 + def foo1774(): Int = 1776 + def foo1775(): Int = 1777 + def foo1776(): Int = 1778 + def foo1777(): Int = 1779 + def foo1778(): Int = 1780 + def foo1779(): Int = 1781 + def foo1780(): Int = 1782 + def foo1781(): Int = 1783 + def foo1782(): Int = 1784 + def foo1783(): Int = 1785 + def foo1784(): Int = 1786 + def foo1785(): Int = 1787 + def foo1786(): Int = 1788 + def foo1787(): Int = 1789 + def foo1788(): Int = 1790 + def foo1789(): Int = 1791 + def foo1790(): Int = 1792 + def foo1791(): Int = 1793 + def foo1792(): Int = 1794 + def foo1793(): Int = 1795 + def foo1794(): Int = 1796 + def foo1795(): Int = 1797 + def foo1796(): Int = 1798 + def foo1797(): Int = 1799 + def foo1798(): Int = 1800 + def foo1799(): Int = 1801 + def foo1800(): Int = 1802 + def foo1801(): Int = 1803 + def foo1802(): Int = 1804 + def foo1803(): Int = 1805 + def foo1804(): Int = 1806 + def foo1805(): Int = 1807 + def foo1806(): Int = 1808 + def foo1807(): Int = 1809 + def foo1808(): Int = 1810 + def foo1809(): Int = 1811 + def foo1810(): Int = 1812 + def foo1811(): Int = 1813 + def foo1812(): Int = 1814 + def foo1813(): Int = 1815 + def foo1814(): Int = 1816 + def foo1815(): Int = 1817 + def foo1816(): Int = 1818 + def foo1817(): Int = 1819 + def foo1818(): Int = 1820 + def foo1819(): Int = 1821 + def foo1820(): Int = 1822 + def foo1821(): Int = 1823 + def foo1822(): Int = 1824 + def foo1823(): Int = 1825 + def foo1824(): Int = 1826 + def foo1825(): Int = 1827 + def foo1826(): Int = 1828 + def foo1827(): Int = 1829 + def foo1828(): Int = 1830 + def foo1829(): Int = 1831 + def foo1830(): Int = 1832 + def foo1831(): Int = 1833 + def foo1832(): Int = 1834 + def foo1833(): Int = 1835 + def foo1834(): Int = 1836 + def foo1835(): Int = 1837 + def foo1836(): Int = 1838 + def foo1837(): Int = 1839 + def foo1838(): Int = 1840 + def foo1839(): Int = 1841 + def foo1840(): Int = 1842 + def foo1841(): Int = 1843 + def foo1842(): Int = 1844 + def foo1843(): Int = 1845 + def foo1844(): Int = 1846 + def foo1845(): Int = 1847 + def foo1846(): Int = 1848 + def foo1847(): Int = 1849 + def foo1848(): Int = 1850 + def foo1849(): Int = 1851 + def foo1850(): Int = 1852 + def foo1851(): Int = 1853 + def foo1852(): Int = 1854 + def foo1853(): Int = 1855 + def foo1854(): Int = 1856 + def foo1855(): Int = 1857 + def foo1856(): Int = 1858 + def foo1857(): Int = 1859 + def foo1858(): Int = 1860 + def foo1859(): Int = 1861 + def foo1860(): Int = 1862 + def foo1861(): Int = 1863 + def foo1862(): Int = 1864 + def foo1863(): Int = 1865 + def foo1864(): Int = 1866 + def foo1865(): Int = 1867 + def foo1866(): Int = 1868 + def foo1867(): Int = 1869 + def foo1868(): Int = 1870 + def foo1869(): Int = 1871 + def foo1870(): Int = 1872 + def foo1871(): Int = 1873 + def foo1872(): Int = 1874 + def foo1873(): Int = 1875 + def foo1874(): Int = 1876 + def foo1875(): Int = 1877 + def foo1876(): Int = 1878 + def foo1877(): Int = 1879 + def foo1878(): Int = 1880 + def foo1879(): Int = 1881 + def foo1880(): Int = 1882 + def foo1881(): Int = 1883 + def foo1882(): Int = 1884 + def foo1883(): Int = 1885 + def foo1884(): Int = 1886 + def foo1885(): Int = 1887 + def foo1886(): Int = 1888 + def foo1887(): Int = 1889 + def foo1888(): Int = 1890 + def foo1889(): Int = 1891 + def foo1890(): Int = 1892 + def foo1891(): Int = 1893 + def foo1892(): Int = 1894 + def foo1893(): Int = 1895 + def foo1894(): Int = 1896 + def foo1895(): Int = 1897 + def foo1896(): Int = 1898 + def foo1897(): Int = 1899 + def foo1898(): Int = 1900 + def foo1899(): Int = 1901 + def foo1900(): Int = 1902 + def foo1901(): Int = 1903 + def foo1902(): Int = 1904 + def foo1903(): Int = 1905 + def foo1904(): Int = 1906 + def foo1905(): Int = 1907 + def foo1906(): Int = 1908 + def foo1907(): Int = 1909 + def foo1908(): Int = 1910 + def foo1909(): Int = 1911 + def foo1910(): Int = 1912 + def foo1911(): Int = 1913 + def foo1912(): Int = 1914 + def foo1913(): Int = 1915 + def foo1914(): Int = 1916 + def foo1915(): Int = 1917 + def foo1916(): Int = 1918 + def foo1917(): Int = 1919 + def foo1918(): Int = 1920 + def foo1919(): Int = 1921 + def foo1920(): Int = 1922 + def foo1921(): Int = 1923 + def foo1922(): Int = 1924 + def foo1923(): Int = 1925 + def foo1924(): Int = 1926 + def foo1925(): Int = 1927 + def foo1926(): Int = 1928 + def foo1927(): Int = 1929 + def foo1928(): Int = 1930 + def foo1929(): Int = 1931 + def foo1930(): Int = 1932 + def foo1931(): Int = 1933 + def foo1932(): Int = 1934 + def foo1933(): Int = 1935 + def foo1934(): Int = 1936 + def foo1935(): Int = 1937 + def foo1936(): Int = 1938 + def foo1937(): Int = 1939 + def foo1938(): Int = 1940 + def foo1939(): Int = 1941 + def foo1940(): Int = 1942 + def foo1941(): Int = 1943 + def foo1942(): Int = 1944 + def foo1943(): Int = 1945 + def foo1944(): Int = 1946 + def foo1945(): Int = 1947 + def foo1946(): Int = 1948 + def foo1947(): Int = 1949 + def foo1948(): Int = 1950 + def foo1949(): Int = 1951 + def foo1950(): Int = 1952 + def foo1951(): Int = 1953 + def foo1952(): Int = 1954 + def foo1953(): Int = 1955 + def foo1954(): Int = 1956 + def foo1955(): Int = 1957 + def foo1956(): Int = 1958 + def foo1957(): Int = 1959 + def foo1958(): Int = 1960 + def foo1959(): Int = 1961 + def foo1960(): Int = 1962 + def foo1961(): Int = 1963 + def foo1962(): Int = 1964 + def foo1963(): Int = 1965 + def foo1964(): Int = 1966 + def foo1965(): Int = 1967 + def foo1966(): Int = 1968 + def foo1967(): Int = 1969 + def foo1968(): Int = 1970 + def foo1969(): Int = 1971 + def foo1970(): Int = 1972 + def foo1971(): Int = 1973 + def foo1972(): Int = 1974 + def foo1973(): Int = 1975 + def foo1974(): Int = 1976 + def foo1975(): Int = 1977 + def foo1976(): Int = 1978 + def foo1977(): Int = 1979 + def foo1978(): Int = 1980 + def foo1979(): Int = 1981 + def foo1980(): Int = 1982 + def foo1981(): Int = 1983 + def foo1982(): Int = 1984 + def foo1983(): Int = 1985 + def foo1984(): Int = 1986 + def foo1985(): Int = 1987 + def foo1986(): Int = 1988 + def foo1987(): Int = 1989 + def foo1988(): Int = 1990 + def foo1989(): Int = 1991 + def foo1990(): Int = 1992 + def foo1991(): Int = 1993 + def foo1992(): Int = 1994 + def foo1993(): Int = 1995 + def foo1994(): Int = 1996 + def foo1995(): Int = 1997 + def foo1996(): Int = 1998 + def foo1997(): Int = 1999 + def foo1998(): Int = 2000 + def foo1999(): Int = 2001 + def foo2000(): Int = 2002 + def foo2001(): Int = 2003 + def foo2002(): Int = 2004 + def foo2003(): Int = 2005 + def foo2004(): Int = 2006 + def foo2005(): Int = 2007 + def foo2006(): Int = 2008 + def foo2007(): Int = 2009 + def foo2008(): Int = 2010 + def foo2009(): Int = 2011 + def foo2010(): Int = 2012 + def foo2011(): Int = 2013 + def foo2012(): Int = 2014 + def foo2013(): Int = 2015 + def foo2014(): Int = 2016 + def foo2015(): Int = 2017 + def foo2016(): Int = 2018 + def foo2017(): Int = 2019 + def foo2018(): Int = 2020 + def foo2019(): Int = 2021 + def foo2020(): Int = 2022 + def foo2021(): Int = 2023 + def foo2022(): Int = 2024 + def foo2023(): Int = 2025 + def foo2024(): Int = 2026 + def foo2025(): Int = 2027 + def foo2026(): Int = 2028 + def foo2027(): Int = 2029 + def foo2028(): Int = 2030 + def foo2029(): Int = 2031 + def foo2030(): Int = 2032 + def foo2031(): Int = 2033 + def foo2032(): Int = 2034 + def foo2033(): Int = 2035 + def foo2034(): Int = 2036 + def foo2035(): Int = 2037 + def foo2036(): Int = 2038 + def foo2037(): Int = 2039 + def foo2038(): Int = 2040 + def foo2039(): Int = 2041 + def foo2040(): Int = 2042 + def foo2041(): Int = 2043 + def foo2042(): Int = 2044 + def foo2043(): Int = 2045 + def foo2044(): Int = 2046 + def foo2045(): Int = 2047 + def foo2046(): Int = 2048 + def foo2047(): Int = 2049 + def foo2048(): Int = 2050 + def foo2049(): Int = 2051 + def foo2050(): Int = 2052 + def foo2051(): Int = 2053 + def foo2052(): Int = 2054 + def foo2053(): Int = 2055 + def foo2054(): Int = 2056 + def foo2055(): Int = 2057 + def foo2056(): Int = 2058 + def foo2057(): Int = 2059 + def foo2058(): Int = 2060 + def foo2059(): Int = 2061 + def foo2060(): Int = 2062 + def foo2061(): Int = 2063 + def foo2062(): Int = 2064 + def foo2063(): Int = 2065 + def foo2064(): Int = 2066 + def foo2065(): Int = 2067 + def foo2066(): Int = 2068 + def foo2067(): Int = 2069 + def foo2068(): Int = 2070 + def foo2069(): Int = 2071 + def foo2070(): Int = 2072 + def foo2071(): Int = 2073 + def foo2072(): Int = 2074 + def foo2073(): Int = 2075 + def foo2074(): Int = 2076 + def foo2075(): Int = 2077 + def foo2076(): Int = 2078 + def foo2077(): Int = 2079 + def foo2078(): Int = 2080 + def foo2079(): Int = 2081 + def foo2080(): Int = 2082 + def foo2081(): Int = 2083 + def foo2082(): Int = 2084 + def foo2083(): Int = 2085 + def foo2084(): Int = 2086 + def foo2085(): Int = 2087 + def foo2086(): Int = 2088 + def foo2087(): Int = 2089 + def foo2088(): Int = 2090 + def foo2089(): Int = 2091 + def foo2090(): Int = 2092 + def foo2091(): Int = 2093 + def foo2092(): Int = 2094 + def foo2093(): Int = 2095 + def foo2094(): Int = 2096 + def foo2095(): Int = 2097 + def foo2096(): Int = 2098 + def foo2097(): Int = 2099 + def foo2098(): Int = 2100 + def foo2099(): Int = 2101 + def foo2100(): Int = 2102 + def foo2101(): Int = 2103 + def foo2102(): Int = 2104 + def foo2103(): Int = 2105 + def foo2104(): Int = 2106 + def foo2105(): Int = 2107 + def foo2106(): Int = 2108 + def foo2107(): Int = 2109 + def foo2108(): Int = 2110 + def foo2109(): Int = 2111 + def foo2110(): Int = 2112 + def foo2111(): Int = 2113 + def foo2112(): Int = 2114 + def foo2113(): Int = 2115 + def foo2114(): Int = 2116 + def foo2115(): Int = 2117 + def foo2116(): Int = 2118 + def foo2117(): Int = 2119 + def foo2118(): Int = 2120 + def foo2119(): Int = 2121 + def foo2120(): Int = 2122 + def foo2121(): Int = 2123 + def foo2122(): Int = 2124 + def foo2123(): Int = 2125 + def foo2124(): Int = 2126 + def foo2125(): Int = 2127 + def foo2126(): Int = 2128 + def foo2127(): Int = 2129 + def foo2128(): Int = 2130 + def foo2129(): Int = 2131 + def foo2130(): Int = 2132 + def foo2131(): Int = 2133 + def foo2132(): Int = 2134 + def foo2133(): Int = 2135 + def foo2134(): Int = 2136 + def foo2135(): Int = 2137 + def foo2136(): Int = 2138 + def foo2137(): Int = 2139 + def foo2138(): Int = 2140 + def foo2139(): Int = 2141 + def foo2140(): Int = 2142 + def foo2141(): Int = 2143 + def foo2142(): Int = 2144 + def foo2143(): Int = 2145 + def foo2144(): Int = 2146 + def foo2145(): Int = 2147 + def foo2146(): Int = 2148 + def foo2147(): Int = 2149 + def foo2148(): Int = 2150 + def foo2149(): Int = 2151 + def foo2150(): Int = 2152 + def foo2151(): Int = 2153 + def foo2152(): Int = 2154 + def foo2153(): Int = 2155 + def foo2154(): Int = 2156 + def foo2155(): Int = 2157 + def foo2156(): Int = 2158 + def foo2157(): Int = 2159 + def foo2158(): Int = 2160 + def foo2159(): Int = 2161 + def foo2160(): Int = 2162 + def foo2161(): Int = 2163 + def foo2162(): Int = 2164 + def foo2163(): Int = 2165 + def foo2164(): Int = 2166 + def foo2165(): Int = 2167 + def foo2166(): Int = 2168 + def foo2167(): Int = 2169 + def foo2168(): Int = 2170 + def foo2169(): Int = 2171 + def foo2170(): Int = 2172 + def foo2171(): Int = 2173 + def foo2172(): Int = 2174 + def foo2173(): Int = 2175 + def foo2174(): Int = 2176 + def foo2175(): Int = 2177 + def foo2176(): Int = 2178 + def foo2177(): Int = 2179 + def foo2178(): Int = 2180 + def foo2179(): Int = 2181 + def foo2180(): Int = 2182 + def foo2181(): Int = 2183 + def foo2182(): Int = 2184 + def foo2183(): Int = 2185 + def foo2184(): Int = 2186 + def foo2185(): Int = 2187 + def foo2186(): Int = 2188 + def foo2187(): Int = 2189 + def foo2188(): Int = 2190 + def foo2189(): Int = 2191 + def foo2190(): Int = 2192 + def foo2191(): Int = 2193 + def foo2192(): Int = 2194 + def foo2193(): Int = 2195 + def foo2194(): Int = 2196 + def foo2195(): Int = 2197 + def foo2196(): Int = 2198 + def foo2197(): Int = 2199 + def foo2198(): Int = 2200 + def foo2199(): Int = 2201 + def foo2200(): Int = 2202 + def foo2201(): Int = 2203 + def foo2202(): Int = 2204 + def foo2203(): Int = 2205 + def foo2204(): Int = 2206 + def foo2205(): Int = 2207 + def foo2206(): Int = 2208 + def foo2207(): Int = 2209 + def foo2208(): Int = 2210 + def foo2209(): Int = 2211 + def foo2210(): Int = 2212 + def foo2211(): Int = 2213 + def foo2212(): Int = 2214 + def foo2213(): Int = 2215 + def foo2214(): Int = 2216 + def foo2215(): Int = 2217 + def foo2216(): Int = 2218 + def foo2217(): Int = 2219 + def foo2218(): Int = 2220 + def foo2219(): Int = 2221 + def foo2220(): Int = 2222 + def foo2221(): Int = 2223 + def foo2222(): Int = 2224 + def foo2223(): Int = 2225 + def foo2224(): Int = 2226 + def foo2225(): Int = 2227 + def foo2226(): Int = 2228 + def foo2227(): Int = 2229 + def foo2228(): Int = 2230 + def foo2229(): Int = 2231 + def foo2230(): Int = 2232 + def foo2231(): Int = 2233 + def foo2232(): Int = 2234 + def foo2233(): Int = 2235 + def foo2234(): Int = 2236 + def foo2235(): Int = 2237 + def foo2236(): Int = 2238 + def foo2237(): Int = 2239 + def foo2238(): Int = 2240 + def foo2239(): Int = 2241 + def foo2240(): Int = 2242 + def foo2241(): Int = 2243 + def foo2242(): Int = 2244 + def foo2243(): Int = 2245 + def foo2244(): Int = 2246 + def foo2245(): Int = 2247 + def foo2246(): Int = 2248 + def foo2247(): Int = 2249 + def foo2248(): Int = 2250 + def foo2249(): Int = 2251 + def foo2250(): Int = 2252 + def foo2251(): Int = 2253 + def foo2252(): Int = 2254 + def foo2253(): Int = 2255 + def foo2254(): Int = 2256 + def foo2255(): Int = 2257 + def foo2256(): Int = 2258 + def foo2257(): Int = 2259 + def foo2258(): Int = 2260 + def foo2259(): Int = 2261 + def foo2260(): Int = 2262 + def foo2261(): Int = 2263 + def foo2262(): Int = 2264 + def foo2263(): Int = 2265 + def foo2264(): Int = 2266 + def foo2265(): Int = 2267 + def foo2266(): Int = 2268 + def foo2267(): Int = 2269 + def foo2268(): Int = 2270 + def foo2269(): Int = 2271 + def foo2270(): Int = 2272 + def foo2271(): Int = 2273 + def foo2272(): Int = 2274 + def foo2273(): Int = 2275 + def foo2274(): Int = 2276 + def foo2275(): Int = 2277 + def foo2276(): Int = 2278 + def foo2277(): Int = 2279 + def foo2278(): Int = 2280 + def foo2279(): Int = 2281 + def foo2280(): Int = 2282 + def foo2281(): Int = 2283 + def foo2282(): Int = 2284 + def foo2283(): Int = 2285 + def foo2284(): Int = 2286 + def foo2285(): Int = 2287 + def foo2286(): Int = 2288 + def foo2287(): Int = 2289 + def foo2288(): Int = 2290 + def foo2289(): Int = 2291 + def foo2290(): Int = 2292 + def foo2291(): Int = 2293 + def foo2292(): Int = 2294 + def foo2293(): Int = 2295 + def foo2294(): Int = 2296 + def foo2295(): Int = 2297 + def foo2296(): Int = 2298 + def foo2297(): Int = 2299 + def foo2298(): Int = 2300 + def foo2299(): Int = 2301 + def foo2300(): Int = 2302 + def foo2301(): Int = 2303 + def foo2302(): Int = 2304 + def foo2303(): Int = 2305 + def foo2304(): Int = 2306 + def foo2305(): Int = 2307 + def foo2306(): Int = 2308 + def foo2307(): Int = 2309 + def foo2308(): Int = 2310 + def foo2309(): Int = 2311 + def foo2310(): Int = 2312 + def foo2311(): Int = 2313 + def foo2312(): Int = 2314 + def foo2313(): Int = 2315 + def foo2314(): Int = 2316 + def foo2315(): Int = 2317 + def foo2316(): Int = 2318 + def foo2317(): Int = 2319 + def foo2318(): Int = 2320 + def foo2319(): Int = 2321 + def foo2320(): Int = 2322 + def foo2321(): Int = 2323 + def foo2322(): Int = 2324 + def foo2323(): Int = 2325 + def foo2324(): Int = 2326 + def foo2325(): Int = 2327 + def foo2326(): Int = 2328 + def foo2327(): Int = 2329 + def foo2328(): Int = 2330 + def foo2329(): Int = 2331 + def foo2330(): Int = 2332 + def foo2331(): Int = 2333 + def foo2332(): Int = 2334 + def foo2333(): Int = 2335 + def foo2334(): Int = 2336 + def foo2335(): Int = 2337 + def foo2336(): Int = 2338 + def foo2337(): Int = 2339 + def foo2338(): Int = 2340 + def foo2339(): Int = 2341 + def foo2340(): Int = 2342 + def foo2341(): Int = 2343 + def foo2342(): Int = 2344 + def foo2343(): Int = 2345 + def foo2344(): Int = 2346 + def foo2345(): Int = 2347 + def foo2346(): Int = 2348 + def foo2347(): Int = 2349 + def foo2348(): Int = 2350 + def foo2349(): Int = 2351 + def foo2350(): Int = 2352 + def foo2351(): Int = 2353 + def foo2352(): Int = 2354 + def foo2353(): Int = 2355 + def foo2354(): Int = 2356 + def foo2355(): Int = 2357 + def foo2356(): Int = 2358 + def foo2357(): Int = 2359 + def foo2358(): Int = 2360 + def foo2359(): Int = 2361 + def foo2360(): Int = 2362 + def foo2361(): Int = 2363 + def foo2362(): Int = 2364 + def foo2363(): Int = 2365 + def foo2364(): Int = 2366 + def foo2365(): Int = 2367 + def foo2366(): Int = 2368 + def foo2367(): Int = 2369 + def foo2368(): Int = 2370 + def foo2369(): Int = 2371 + def foo2370(): Int = 2372 + def foo2371(): Int = 2373 + def foo2372(): Int = 2374 + def foo2373(): Int = 2375 + def foo2374(): Int = 2376 + def foo2375(): Int = 2377 + def foo2376(): Int = 2378 + def foo2377(): Int = 2379 + def foo2378(): Int = 2380 + def foo2379(): Int = 2381 + def foo2380(): Int = 2382 + def foo2381(): Int = 2383 + def foo2382(): Int = 2384 + def foo2383(): Int = 2385 + def foo2384(): Int = 2386 + def foo2385(): Int = 2387 + def foo2386(): Int = 2388 + def foo2387(): Int = 2389 + def foo2388(): Int = 2390 + def foo2389(): Int = 2391 + def foo2390(): Int = 2392 + def foo2391(): Int = 2393 + def foo2392(): Int = 2394 + def foo2393(): Int = 2395 + def foo2394(): Int = 2396 + def foo2395(): Int = 2397 + def foo2396(): Int = 2398 + def foo2397(): Int = 2399 + def foo2398(): Int = 2400 + def foo2399(): Int = 2401 + def foo2400(): Int = 2402 + def foo2401(): Int = 2403 + def foo2402(): Int = 2404 + def foo2403(): Int = 2405 + def foo2404(): Int = 2406 + def foo2405(): Int = 2407 + def foo2406(): Int = 2408 + def foo2407(): Int = 2409 + def foo2408(): Int = 2410 + def foo2409(): Int = 2411 + def foo2410(): Int = 2412 + def foo2411(): Int = 2413 + def foo2412(): Int = 2414 + def foo2413(): Int = 2415 + def foo2414(): Int = 2416 + def foo2415(): Int = 2417 + def foo2416(): Int = 2418 + def foo2417(): Int = 2419 + def foo2418(): Int = 2420 + def foo2419(): Int = 2421 + def foo2420(): Int = 2422 + def foo2421(): Int = 2423 + def foo2422(): Int = 2424 + def foo2423(): Int = 2425 + def foo2424(): Int = 2426 + def foo2425(): Int = 2427 + def foo2426(): Int = 2428 + def foo2427(): Int = 2429 + def foo2428(): Int = 2430 + def foo2429(): Int = 2431 + def foo2430(): Int = 2432 + def foo2431(): Int = 2433 + def foo2432(): Int = 2434 + def foo2433(): Int = 2435 + def foo2434(): Int = 2436 + def foo2435(): Int = 2437 + def foo2436(): Int = 2438 + def foo2437(): Int = 2439 + def foo2438(): Int = 2440 + def foo2439(): Int = 2441 + def foo2440(): Int = 2442 + def foo2441(): Int = 2443 + def foo2442(): Int = 2444 + def foo2443(): Int = 2445 + def foo2444(): Int = 2446 + def foo2445(): Int = 2447 + def foo2446(): Int = 2448 + def foo2447(): Int = 2449 + def foo2448(): Int = 2450 + def foo2449(): Int = 2451 + def foo2450(): Int = 2452 + def foo2451(): Int = 2453 + def foo2452(): Int = 2454 + def foo2453(): Int = 2455 + def foo2454(): Int = 2456 + def foo2455(): Int = 2457 + def foo2456(): Int = 2458 + def foo2457(): Int = 2459 + def foo2458(): Int = 2460 + def foo2459(): Int = 2461 + def foo2460(): Int = 2462 + def foo2461(): Int = 2463 + def foo2462(): Int = 2464 + def foo2463(): Int = 2465 + def foo2464(): Int = 2466 + def foo2465(): Int = 2467 + def foo2466(): Int = 2468 + def foo2467(): Int = 2469 + def foo2468(): Int = 2470 + def foo2469(): Int = 2471 + def foo2470(): Int = 2472 + def foo2471(): Int = 2473 + def foo2472(): Int = 2474 + def foo2473(): Int = 2475 + def foo2474(): Int = 2476 + def foo2475(): Int = 2477 + def foo2476(): Int = 2478 + def foo2477(): Int = 2479 + def foo2478(): Int = 2480 + def foo2479(): Int = 2481 + def foo2480(): Int = 2482 + def foo2481(): Int = 2483 + def foo2482(): Int = 2484 + def foo2483(): Int = 2485 + def foo2484(): Int = 2486 + def foo2485(): Int = 2487 + def foo2486(): Int = 2488 + def foo2487(): Int = 2489 + def foo2488(): Int = 2490 + def foo2489(): Int = 2491 + def foo2490(): Int = 2492 + def foo2491(): Int = 2493 + def foo2492(): Int = 2494 + def foo2493(): Int = 2495 + def foo2494(): Int = 2496 + def foo2495(): Int = 2497 + def foo2496(): Int = 2498 + def foo2497(): Int = 2499 + def foo2498(): Int = 2500 + def foo2499(): Int = 2501 + def foo2500(): Int = 2502 + def foo2501(): Int = 2503 + def foo2502(): Int = 2504 + def foo2503(): Int = 2505 + def foo2504(): Int = 2506 + def foo2505(): Int = 2507 + def foo2506(): Int = 2508 + def foo2507(): Int = 2509 + def foo2508(): Int = 2510 + def foo2509(): Int = 2511 + def foo2510(): Int = 2512 + def foo2511(): Int = 2513 + def foo2512(): Int = 2514 + def foo2513(): Int = 2515 + def foo2514(): Int = 2516 + def foo2515(): Int = 2517 + def foo2516(): Int = 2518 + def foo2517(): Int = 2519 + def foo2518(): Int = 2520 + def foo2519(): Int = 2521 + def foo2520(): Int = 2522 + def foo2521(): Int = 2523 + def foo2522(): Int = 2524 + def foo2523(): Int = 2525 + def foo2524(): Int = 2526 + def foo2525(): Int = 2527 + def foo2526(): Int = 2528 + def foo2527(): Int = 2529 + def foo2528(): Int = 2530 + def foo2529(): Int = 2531 + def foo2530(): Int = 2532 + def foo2531(): Int = 2533 + def foo2532(): Int = 2534 + def foo2533(): Int = 2535 + def foo2534(): Int = 2536 + def foo2535(): Int = 2537 + def foo2536(): Int = 2538 + def foo2537(): Int = 2539 + def foo2538(): Int = 2540 + def foo2539(): Int = 2541 + def foo2540(): Int = 2542 + def foo2541(): Int = 2543 + def foo2542(): Int = 2544 + def foo2543(): Int = 2545 + def foo2544(): Int = 2546 + def foo2545(): Int = 2547 + def foo2546(): Int = 2548 + def foo2547(): Int = 2549 + def foo2548(): Int = 2550 + def foo2549(): Int = 2551 + def foo2550(): Int = 2552 + def foo2551(): Int = 2553 + def foo2552(): Int = 2554 + def foo2553(): Int = 2555 + def foo2554(): Int = 2556 + def foo2555(): Int = 2557 + def foo2556(): Int = 2558 + def foo2557(): Int = 2559 + def foo2558(): Int = 2560 + def foo2559(): Int = 2561 + def foo2560(): Int = 2562 + def foo2561(): Int = 2563 + def foo2562(): Int = 2564 + def foo2563(): Int = 2565 + def foo2564(): Int = 2566 + def foo2565(): Int = 2567 + def foo2566(): Int = 2568 + def foo2567(): Int = 2569 + def foo2568(): Int = 2570 + def foo2569(): Int = 2571 + def foo2570(): Int = 2572 + def foo2571(): Int = 2573 + def foo2572(): Int = 2574 + def foo2573(): Int = 2575 + def foo2574(): Int = 2576 + def foo2575(): Int = 2577 + def foo2576(): Int = 2578 + def foo2577(): Int = 2579 + def foo2578(): Int = 2580 + def foo2579(): Int = 2581 + def foo2580(): Int = 2582 + def foo2581(): Int = 2583 + def foo2582(): Int = 2584 + def foo2583(): Int = 2585 + def foo2584(): Int = 2586 + def foo2585(): Int = 2587 + def foo2586(): Int = 2588 + def foo2587(): Int = 2589 + def foo2588(): Int = 2590 + def foo2589(): Int = 2591 + def foo2590(): Int = 2592 + def foo2591(): Int = 2593 + def foo2592(): Int = 2594 + def foo2593(): Int = 2595 + def foo2594(): Int = 2596 + def foo2595(): Int = 2597 + def foo2596(): Int = 2598 + def foo2597(): Int = 2599 + def foo2598(): Int = 2600 + def foo2599(): Int = 2601 + def foo2600(): Int = 2602 + def foo2601(): Int = 2603 + def foo2602(): Int = 2604 + def foo2603(): Int = 2605 + def foo2604(): Int = 2606 + def foo2605(): Int = 2607 + def foo2606(): Int = 2608 + def foo2607(): Int = 2609 + def foo2608(): Int = 2610 + def foo2609(): Int = 2611 + def foo2610(): Int = 2612 + def foo2611(): Int = 2613 + def foo2612(): Int = 2614 + def foo2613(): Int = 2615 + def foo2614(): Int = 2616 + def foo2615(): Int = 2617 + def foo2616(): Int = 2618 + def foo2617(): Int = 2619 + def foo2618(): Int = 2620 + def foo2619(): Int = 2621 + def foo2620(): Int = 2622 + def foo2621(): Int = 2623 + def foo2622(): Int = 2624 + def foo2623(): Int = 2625 + def foo2624(): Int = 2626 + def foo2625(): Int = 2627 + def foo2626(): Int = 2628 + def foo2627(): Int = 2629 + def foo2628(): Int = 2630 + def foo2629(): Int = 2631 + def foo2630(): Int = 2632 + def foo2631(): Int = 2633 + def foo2632(): Int = 2634 + def foo2633(): Int = 2635 + def foo2634(): Int = 2636 + def foo2635(): Int = 2637 + def foo2636(): Int = 2638 + def foo2637(): Int = 2639 + def foo2638(): Int = 2640 + def foo2639(): Int = 2641 + def foo2640(): Int = 2642 + def foo2641(): Int = 2643 + def foo2642(): Int = 2644 + def foo2643(): Int = 2645 + def foo2644(): Int = 2646 + def foo2645(): Int = 2647 + def foo2646(): Int = 2648 + def foo2647(): Int = 2649 + def foo2648(): Int = 2650 + def foo2649(): Int = 2651 + def foo2650(): Int = 2652 + def foo2651(): Int = 2653 + def foo2652(): Int = 2654 + def foo2653(): Int = 2655 + def foo2654(): Int = 2656 + def foo2655(): Int = 2657 + def foo2656(): Int = 2658 + def foo2657(): Int = 2659 + def foo2658(): Int = 2660 + def foo2659(): Int = 2661 + def foo2660(): Int = 2662 + def foo2661(): Int = 2663 + def foo2662(): Int = 2664 + def foo2663(): Int = 2665 + def foo2664(): Int = 2666 + def foo2665(): Int = 2667 + def foo2666(): Int = 2668 + def foo2667(): Int = 2669 + def foo2668(): Int = 2670 + def foo2669(): Int = 2671 + def foo2670(): Int = 2672 + def foo2671(): Int = 2673 + def foo2672(): Int = 2674 + def foo2673(): Int = 2675 + def foo2674(): Int = 2676 + def foo2675(): Int = 2677 + def foo2676(): Int = 2678 + def foo2677(): Int = 2679 + def foo2678(): Int = 2680 + def foo2679(): Int = 2681 + def foo2680(): Int = 2682 + def foo2681(): Int = 2683 + def foo2682(): Int = 2684 + def foo2683(): Int = 2685 + def foo2684(): Int = 2686 + def foo2685(): Int = 2687 + def foo2686(): Int = 2688 + def foo2687(): Int = 2689 + def foo2688(): Int = 2690 + def foo2689(): Int = 2691 + def foo2690(): Int = 2692 + def foo2691(): Int = 2693 + def foo2692(): Int = 2694 + def foo2693(): Int = 2695 + def foo2694(): Int = 2696 + def foo2695(): Int = 2697 + def foo2696(): Int = 2698 + def foo2697(): Int = 2699 + def foo2698(): Int = 2700 + def foo2699(): Int = 2701 + def foo2700(): Int = 2702 + def foo2701(): Int = 2703 + def foo2702(): Int = 2704 + def foo2703(): Int = 2705 + def foo2704(): Int = 2706 + def foo2705(): Int = 2707 + def foo2706(): Int = 2708 + def foo2707(): Int = 2709 + def foo2708(): Int = 2710 + def foo2709(): Int = 2711 + def foo2710(): Int = 2712 + def foo2711(): Int = 2713 + def foo2712(): Int = 2714 + def foo2713(): Int = 2715 + def foo2714(): Int = 2716 + def foo2715(): Int = 2717 + def foo2716(): Int = 2718 + def foo2717(): Int = 2719 + def foo2718(): Int = 2720 + def foo2719(): Int = 2721 + def foo2720(): Int = 2722 + def foo2721(): Int = 2723 + def foo2722(): Int = 2724 + def foo2723(): Int = 2725 + def foo2724(): Int = 2726 + def foo2725(): Int = 2727 + def foo2726(): Int = 2728 + def foo2727(): Int = 2729 + def foo2728(): Int = 2730 + def foo2729(): Int = 2731 + def foo2730(): Int = 2732 + def foo2731(): Int = 2733 + def foo2732(): Int = 2734 + def foo2733(): Int = 2735 + def foo2734(): Int = 2736 + def foo2735(): Int = 2737 + def foo2736(): Int = 2738 + def foo2737(): Int = 2739 + def foo2738(): Int = 2740 + def foo2739(): Int = 2741 + def foo2740(): Int = 2742 + def foo2741(): Int = 2743 + def foo2742(): Int = 2744 + def foo2743(): Int = 2745 + def foo2744(): Int = 2746 + def foo2745(): Int = 2747 + def foo2746(): Int = 2748 + def foo2747(): Int = 2749 + def foo2748(): Int = 2750 + def foo2749(): Int = 2751 + def foo2750(): Int = 2752 + def foo2751(): Int = 2753 + def foo2752(): Int = 2754 + def foo2753(): Int = 2755 + def foo2754(): Int = 2756 + def foo2755(): Int = 2757 + def foo2756(): Int = 2758 + def foo2757(): Int = 2759 + def foo2758(): Int = 2760 + def foo2759(): Int = 2761 + def foo2760(): Int = 2762 + def foo2761(): Int = 2763 + def foo2762(): Int = 2764 + def foo2763(): Int = 2765 + def foo2764(): Int = 2766 + def foo2765(): Int = 2767 + def foo2766(): Int = 2768 + def foo2767(): Int = 2769 + def foo2768(): Int = 2770 + def foo2769(): Int = 2771 + def foo2770(): Int = 2772 + def foo2771(): Int = 2773 + def foo2772(): Int = 2774 + def foo2773(): Int = 2775 + def foo2774(): Int = 2776 + def foo2775(): Int = 2777 + def foo2776(): Int = 2778 + def foo2777(): Int = 2779 + def foo2778(): Int = 2780 + def foo2779(): Int = 2781 + def foo2780(): Int = 2782 + def foo2781(): Int = 2783 + def foo2782(): Int = 2784 + def foo2783(): Int = 2785 + def foo2784(): Int = 2786 + def foo2785(): Int = 2787 + def foo2786(): Int = 2788 + def foo2787(): Int = 2789 + def foo2788(): Int = 2790 + def foo2789(): Int = 2791 + def foo2790(): Int = 2792 + def foo2791(): Int = 2793 + def foo2792(): Int = 2794 + def foo2793(): Int = 2795 + def foo2794(): Int = 2796 + def foo2795(): Int = 2797 + def foo2796(): Int = 2798 + def foo2797(): Int = 2799 + def foo2798(): Int = 2800 + def foo2799(): Int = 2801 + def foo2800(): Int = 2802 + def foo2801(): Int = 2803 + def foo2802(): Int = 2804 + def foo2803(): Int = 2805 + def foo2804(): Int = 2806 + def foo2805(): Int = 2807 + def foo2806(): Int = 2808 + def foo2807(): Int = 2809 + def foo2808(): Int = 2810 + def foo2809(): Int = 2811 + def foo2810(): Int = 2812 + def foo2811(): Int = 2813 + def foo2812(): Int = 2814 + def foo2813(): Int = 2815 + def foo2814(): Int = 2816 + def foo2815(): Int = 2817 + def foo2816(): Int = 2818 + def foo2817(): Int = 2819 + def foo2818(): Int = 2820 + def foo2819(): Int = 2821 + def foo2820(): Int = 2822 + def foo2821(): Int = 2823 + def foo2822(): Int = 2824 + def foo2823(): Int = 2825 + def foo2824(): Int = 2826 + def foo2825(): Int = 2827 + def foo2826(): Int = 2828 + def foo2827(): Int = 2829 + def foo2828(): Int = 2830 + def foo2829(): Int = 2831 + def foo2830(): Int = 2832 + def foo2831(): Int = 2833 + def foo2832(): Int = 2834 + def foo2833(): Int = 2835 + def foo2834(): Int = 2836 + def foo2835(): Int = 2837 + def foo2836(): Int = 2838 + def foo2837(): Int = 2839 + def foo2838(): Int = 2840 + def foo2839(): Int = 2841 + def foo2840(): Int = 2842 + def foo2841(): Int = 2843 + def foo2842(): Int = 2844 + def foo2843(): Int = 2845 + def foo2844(): Int = 2846 + def foo2845(): Int = 2847 + def foo2846(): Int = 2848 + def foo2847(): Int = 2849 + def foo2848(): Int = 2850 + def foo2849(): Int = 2851 + def foo2850(): Int = 2852 + def foo2851(): Int = 2853 + def foo2852(): Int = 2854 + def foo2853(): Int = 2855 + def foo2854(): Int = 2856 + def foo2855(): Int = 2857 + def foo2856(): Int = 2858 + def foo2857(): Int = 2859 + def foo2858(): Int = 2860 + def foo2859(): Int = 2861 + def foo2860(): Int = 2862 + def foo2861(): Int = 2863 + def foo2862(): Int = 2864 + def foo2863(): Int = 2865 + def foo2864(): Int = 2866 + def foo2865(): Int = 2867 + def foo2866(): Int = 2868 + def foo2867(): Int = 2869 + def foo2868(): Int = 2870 + def foo2869(): Int = 2871 + def foo2870(): Int = 2872 + def foo2871(): Int = 2873 + def foo2872(): Int = 2874 + def foo2873(): Int = 2875 + def foo2874(): Int = 2876 + def foo2875(): Int = 2877 + def foo2876(): Int = 2878 + def foo2877(): Int = 2879 + def foo2878(): Int = 2880 + def foo2879(): Int = 2881 + def foo2880(): Int = 2882 + def foo2881(): Int = 2883 + def foo2882(): Int = 2884 + def foo2883(): Int = 2885 + def foo2884(): Int = 2886 + def foo2885(): Int = 2887 + def foo2886(): Int = 2888 + def foo2887(): Int = 2889 + def foo2888(): Int = 2890 + def foo2889(): Int = 2891 + def foo2890(): Int = 2892 + def foo2891(): Int = 2893 + def foo2892(): Int = 2894 + def foo2893(): Int = 2895 + def foo2894(): Int = 2896 + def foo2895(): Int = 2897 + def foo2896(): Int = 2898 + def foo2897(): Int = 2899 + def foo2898(): Int = 2900 + def foo2899(): Int = 2901 + def foo2900(): Int = 2902 + def foo2901(): Int = 2903 + def foo2902(): Int = 2904 + def foo2903(): Int = 2905 + def foo2904(): Int = 2906 + def foo2905(): Int = 2907 + def foo2906(): Int = 2908 + def foo2907(): Int = 2909 + def foo2908(): Int = 2910 + def foo2909(): Int = 2911 + def foo2910(): Int = 2912 + def foo2911(): Int = 2913 + def foo2912(): Int = 2914 + def foo2913(): Int = 2915 + def foo2914(): Int = 2916 + def foo2915(): Int = 2917 + def foo2916(): Int = 2918 + def foo2917(): Int = 2919 + def foo2918(): Int = 2920 + def foo2919(): Int = 2921 + def foo2920(): Int = 2922 + def foo2921(): Int = 2923 + def foo2922(): Int = 2924 + def foo2923(): Int = 2925 + def foo2924(): Int = 2926 + def foo2925(): Int = 2927 + def foo2926(): Int = 2928 + def foo2927(): Int = 2929 + def foo2928(): Int = 2930 + def foo2929(): Int = 2931 + def foo2930(): Int = 2932 + def foo2931(): Int = 2933 + def foo2932(): Int = 2934 + def foo2933(): Int = 2935 + def foo2934(): Int = 2936 + def foo2935(): Int = 2937 + def foo2936(): Int = 2938 + def foo2937(): Int = 2939 + def foo2938(): Int = 2940 + def foo2939(): Int = 2941 + def foo2940(): Int = 2942 + def foo2941(): Int = 2943 + def foo2942(): Int = 2944 + def foo2943(): Int = 2945 + def foo2944(): Int = 2946 + def foo2945(): Int = 2947 + def foo2946(): Int = 2948 + def foo2947(): Int = 2949 + def foo2948(): Int = 2950 + def foo2949(): Int = 2951 + def foo2950(): Int = 2952 + def foo2951(): Int = 2953 + def foo2952(): Int = 2954 + def foo2953(): Int = 2955 + def foo2954(): Int = 2956 + def foo2955(): Int = 2957 + def foo2956(): Int = 2958 + def foo2957(): Int = 2959 + def foo2958(): Int = 2960 + def foo2959(): Int = 2961 + def foo2960(): Int = 2962 + def foo2961(): Int = 2963 + def foo2962(): Int = 2964 + def foo2963(): Int = 2965 + def foo2964(): Int = 2966 + def foo2965(): Int = 2967 + def foo2966(): Int = 2968 + def foo2967(): Int = 2969 + def foo2968(): Int = 2970 + def foo2969(): Int = 2971 + def foo2970(): Int = 2972 + def foo2971(): Int = 2973 + def foo2972(): Int = 2974 + def foo2973(): Int = 2975 + def foo2974(): Int = 2976 + def foo2975(): Int = 2977 + def foo2976(): Int = 2978 + def foo2977(): Int = 2979 + def foo2978(): Int = 2980 + def foo2979(): Int = 2981 + def foo2980(): Int = 2982 + def foo2981(): Int = 2983 + def foo2982(): Int = 2984 + def foo2983(): Int = 2985 + def foo2984(): Int = 2986 + def foo2985(): Int = 2987 + def foo2986(): Int = 2988 + def foo2987(): Int = 2989 + def foo2988(): Int = 2990 + def foo2989(): Int = 2991 + def foo2990(): Int = 2992 + def foo2991(): Int = 2993 + def foo2992(): Int = 2994 + def foo2993(): Int = 2995 + def foo2994(): Int = 2996 + def foo2995(): Int = 2997 + def foo2996(): Int = 2998 + def foo2997(): Int = 2999 + def foo2998(): Int = 3000 + def foo2999(): Int = 3001 + def foo3000(): Int = 3002 + def foo3001(): Int = 3003 + def foo3002(): Int = 3004 + def foo3003(): Int = 3005 + def foo3004(): Int = 3006 + def foo3005(): Int = 3007 + def foo3006(): Int = 3008 + def foo3007(): Int = 3009 + def foo3008(): Int = 3010 + def foo3009(): Int = 3011 + def foo3010(): Int = 3012 + def foo3011(): Int = 3013 + def foo3012(): Int = 3014 + def foo3013(): Int = 3015 + def foo3014(): Int = 3016 + def foo3015(): Int = 3017 + def foo3016(): Int = 3018 + def foo3017(): Int = 3019 + def foo3018(): Int = 3020 + def foo3019(): Int = 3021 + def foo3020(): Int = 3022 + def foo3021(): Int = 3023 + def foo3022(): Int = 3024 + def foo3023(): Int = 3025 + def foo3024(): Int = 3026 + def foo3025(): Int = 3027 + def foo3026(): Int = 3028 + def foo3027(): Int = 3029 + def foo3028(): Int = 3030 + def foo3029(): Int = 3031 + def foo3030(): Int = 3032 + def foo3031(): Int = 3033 + def foo3032(): Int = 3034 + def foo3033(): Int = 3035 + def foo3034(): Int = 3036 + def foo3035(): Int = 3037 + def foo3036(): Int = 3038 + def foo3037(): Int = 3039 + def foo3038(): Int = 3040 + def foo3039(): Int = 3041 + def foo3040(): Int = 3042 + def foo3041(): Int = 3043 + def foo3042(): Int = 3044 + def foo3043(): Int = 3045 + def foo3044(): Int = 3046 + def foo3045(): Int = 3047 + def foo3046(): Int = 3048 + def foo3047(): Int = 3049 + def foo3048(): Int = 3050 + def foo3049(): Int = 3051 + def foo3050(): Int = 3052 + def foo3051(): Int = 3053 + def foo3052(): Int = 3054 + def foo3053(): Int = 3055 + def foo3054(): Int = 3056 + def foo3055(): Int = 3057 + def foo3056(): Int = 3058 + def foo3057(): Int = 3059 + def foo3058(): Int = 3060 + def foo3059(): Int = 3061 + def foo3060(): Int = 3062 + def foo3061(): Int = 3063 + def foo3062(): Int = 3064 + def foo3063(): Int = 3065 + def foo3064(): Int = 3066 + def foo3065(): Int = 3067 + def foo3066(): Int = 3068 + def foo3067(): Int = 3069 + def foo3068(): Int = 3070 + def foo3069(): Int = 3071 + def foo3070(): Int = 3072 + def foo3071(): Int = 3073 + def foo3072(): Int = 3074 + def foo3073(): Int = 3075 + def foo3074(): Int = 3076 + def foo3075(): Int = 3077 + def foo3076(): Int = 3078 + def foo3077(): Int = 3079 + def foo3078(): Int = 3080 + def foo3079(): Int = 3081 + def foo3080(): Int = 3082 + def foo3081(): Int = 3083 + def foo3082(): Int = 3084 + def foo3083(): Int = 3085 + def foo3084(): Int = 3086 + def foo3085(): Int = 3087 + def foo3086(): Int = 3088 + def foo3087(): Int = 3089 + def foo3088(): Int = 3090 + def foo3089(): Int = 3091 + def foo3090(): Int = 3092 + def foo3091(): Int = 3093 + def foo3092(): Int = 3094 + def foo3093(): Int = 3095 + def foo3094(): Int = 3096 + def foo3095(): Int = 3097 + def foo3096(): Int = 3098 + def foo3097(): Int = 3099 + def foo3098(): Int = 3100 + def foo3099(): Int = 3101 + def foo3100(): Int = 3102 + def foo3101(): Int = 3103 + def foo3102(): Int = 3104 + def foo3103(): Int = 3105 + def foo3104(): Int = 3106 + def foo3105(): Int = 3107 + def foo3106(): Int = 3108 + def foo3107(): Int = 3109 + def foo3108(): Int = 3110 + def foo3109(): Int = 3111 + def foo3110(): Int = 3112 + def foo3111(): Int = 3113 + def foo3112(): Int = 3114 + def foo3113(): Int = 3115 + def foo3114(): Int = 3116 + def foo3115(): Int = 3117 + def foo3116(): Int = 3118 + def foo3117(): Int = 3119 + def foo3118(): Int = 3120 + def foo3119(): Int = 3121 + def foo3120(): Int = 3122 + def foo3121(): Int = 3123 + def foo3122(): Int = 3124 + def foo3123(): Int = 3125 + def foo3124(): Int = 3126 + def foo3125(): Int = 3127 + def foo3126(): Int = 3128 + def foo3127(): Int = 3129 + def foo3128(): Int = 3130 + def foo3129(): Int = 3131 + def foo3130(): Int = 3132 + def foo3131(): Int = 3133 + def foo3132(): Int = 3134 + def foo3133(): Int = 3135 + def foo3134(): Int = 3136 + def foo3135(): Int = 3137 + def foo3136(): Int = 3138 + def foo3137(): Int = 3139 + def foo3138(): Int = 3140 + def foo3139(): Int = 3141 + def foo3140(): Int = 3142 + def foo3141(): Int = 3143 + def foo3142(): Int = 3144 + def foo3143(): Int = 3145 + def foo3144(): Int = 3146 + def foo3145(): Int = 3147 + def foo3146(): Int = 3148 + def foo3147(): Int = 3149 + def foo3148(): Int = 3150 + def foo3149(): Int = 3151 + def foo3150(): Int = 3152 + def foo3151(): Int = 3153 + def foo3152(): Int = 3154 + def foo3153(): Int = 3155 + def foo3154(): Int = 3156 + def foo3155(): Int = 3157 + def foo3156(): Int = 3158 + def foo3157(): Int = 3159 + def foo3158(): Int = 3160 + def foo3159(): Int = 3161 + def foo3160(): Int = 3162 + def foo3161(): Int = 3163 + def foo3162(): Int = 3164 + def foo3163(): Int = 3165 + def foo3164(): Int = 3166 + def foo3165(): Int = 3167 + def foo3166(): Int = 3168 + def foo3167(): Int = 3169 + def foo3168(): Int = 3170 + def foo3169(): Int = 3171 + def foo3170(): Int = 3172 + def foo3171(): Int = 3173 + def foo3172(): Int = 3174 + def foo3173(): Int = 3175 + def foo3174(): Int = 3176 + def foo3175(): Int = 3177 + def foo3176(): Int = 3178 + def foo3177(): Int = 3179 + def foo3178(): Int = 3180 + def foo3179(): Int = 3181 + def foo3180(): Int = 3182 + def foo3181(): Int = 3183 + def foo3182(): Int = 3184 + def foo3183(): Int = 3185 + def foo3184(): Int = 3186 + def foo3185(): Int = 3187 + def foo3186(): Int = 3188 + def foo3187(): Int = 3189 + def foo3188(): Int = 3190 + def foo3189(): Int = 3191 + def foo3190(): Int = 3192 + def foo3191(): Int = 3193 + def foo3192(): Int = 3194 + def foo3193(): Int = 3195 + def foo3194(): Int = 3196 + def foo3195(): Int = 3197 + def foo3196(): Int = 3198 + def foo3197(): Int = 3199 + def foo3198(): Int = 3200 + def foo3199(): Int = 3201 + def foo3200(): Int = 3202 + def foo3201(): Int = 3203 + def foo3202(): Int = 3204 + def foo3203(): Int = 3205 + def foo3204(): Int = 3206 + def foo3205(): Int = 3207 + def foo3206(): Int = 3208 + def foo3207(): Int = 3209 + def foo3208(): Int = 3210 + def foo3209(): Int = 3211 + def foo3210(): Int = 3212 + def foo3211(): Int = 3213 + def foo3212(): Int = 3214 + def foo3213(): Int = 3215 + def foo3214(): Int = 3216 + def foo3215(): Int = 3217 + def foo3216(): Int = 3218 + def foo3217(): Int = 3219 + def foo3218(): Int = 3220 + def foo3219(): Int = 3221 + def foo3220(): Int = 3222 + def foo3221(): Int = 3223 + def foo3222(): Int = 3224 + def foo3223(): Int = 3225 + def foo3224(): Int = 3226 + def foo3225(): Int = 3227 + def foo3226(): Int = 3228 + def foo3227(): Int = 3229 + def foo3228(): Int = 3230 + def foo3229(): Int = 3231 + def foo3230(): Int = 3232 + def foo3231(): Int = 3233 + def foo3232(): Int = 3234 + def foo3233(): Int = 3235 + def foo3234(): Int = 3236 + def foo3235(): Int = 3237 + def foo3236(): Int = 3238 + def foo3237(): Int = 3239 + def foo3238(): Int = 3240 + def foo3239(): Int = 3241 + def foo3240(): Int = 3242 + def foo3241(): Int = 3243 + def foo3242(): Int = 3244 + def foo3243(): Int = 3245 + def foo3244(): Int = 3246 + def foo3245(): Int = 3247 + def foo3246(): Int = 3248 + def foo3247(): Int = 3249 + def foo3248(): Int = 3250 + def foo3249(): Int = 3251 + def foo3250(): Int = 3252 + def foo3251(): Int = 3253 + def foo3252(): Int = 3254 + def foo3253(): Int = 3255 + def foo3254(): Int = 3256 + def foo3255(): Int = 3257 + def foo3256(): Int = 3258 + def foo3257(): Int = 3259 + def foo3258(): Int = 3260 + def foo3259(): Int = 3261 + def foo3260(): Int = 3262 + def foo3261(): Int = 3263 + def foo3262(): Int = 3264 + def foo3263(): Int = 3265 + def foo3264(): Int = 3266 + def foo3265(): Int = 3267 + def foo3266(): Int = 3268 + def foo3267(): Int = 3269 + def foo3268(): Int = 3270 + def foo3269(): Int = 3271 + def foo3270(): Int = 3272 + def foo3271(): Int = 3273 + def foo3272(): Int = 3274 + def foo3273(): Int = 3275 + def foo3274(): Int = 3276 + def foo3275(): Int = 3277 + def foo3276(): Int = 3278 + def foo3277(): Int = 3279 + def foo3278(): Int = 3280 + def foo3279(): Int = 3281 + def foo3280(): Int = 3282 + def foo3281(): Int = 3283 + def foo3282(): Int = 3284 + def foo3283(): Int = 3285 + def foo3284(): Int = 3286 + def foo3285(): Int = 3287 + def foo3286(): Int = 3288 + def foo3287(): Int = 3289 + def foo3288(): Int = 3290 + def foo3289(): Int = 3291 + def foo3290(): Int = 3292 + def foo3291(): Int = 3293 + def foo3292(): Int = 3294 + def foo3293(): Int = 3295 + def foo3294(): Int = 3296 + def foo3295(): Int = 3297 + def foo3296(): Int = 3298 + def foo3297(): Int = 3299 + def foo3298(): Int = 3300 + def foo3299(): Int = 3301 + def foo3300(): Int = 3302 + def foo3301(): Int = 3303 + def foo3302(): Int = 3304 + def foo3303(): Int = 3305 + def foo3304(): Int = 3306 + def foo3305(): Int = 3307 + def foo3306(): Int = 3308 + def foo3307(): Int = 3309 + def foo3308(): Int = 3310 + def foo3309(): Int = 3311 + def foo3310(): Int = 3312 + def foo3311(): Int = 3313 + def foo3312(): Int = 3314 + def foo3313(): Int = 3315 + def foo3314(): Int = 3316 + def foo3315(): Int = 3317 + def foo3316(): Int = 3318 + def foo3317(): Int = 3319 + def foo3318(): Int = 3320 + def foo3319(): Int = 3321 + def foo3320(): Int = 3322 + def foo3321(): Int = 3323 + def foo3322(): Int = 3324 + def foo3323(): Int = 3325 + def foo3324(): Int = 3326 + def foo3325(): Int = 3327 + def foo3326(): Int = 3328 + def foo3327(): Int = 3329 + def foo3328(): Int = 3330 + def foo3329(): Int = 3331 + def foo3330(): Int = 3332 + def foo3331(): Int = 3333 + def foo3332(): Int = 3334 + def foo3333(): Int = 3335 + def foo3334(): Int = 3336 + def foo3335(): Int = 3337 + def foo3336(): Int = 3338 + def foo3337(): Int = 3339 + def foo3338(): Int = 3340 + def foo3339(): Int = 3341 + def foo3340(): Int = 3342 + def foo3341(): Int = 3343 + def foo3342(): Int = 3344 + def foo3343(): Int = 3345 + def foo3344(): Int = 3346 + def foo3345(): Int = 3347 + def foo3346(): Int = 3348 + def foo3347(): Int = 3349 + def foo3348(): Int = 3350 + def foo3349(): Int = 3351 + def foo3350(): Int = 3352 + def foo3351(): Int = 3353 + def foo3352(): Int = 3354 + def foo3353(): Int = 3355 + def foo3354(): Int = 3356 + def foo3355(): Int = 3357 + def foo3356(): Int = 3358 + def foo3357(): Int = 3359 + def foo3358(): Int = 3360 + def foo3359(): Int = 3361 + def foo3360(): Int = 3362 + def foo3361(): Int = 3363 + def foo3362(): Int = 3364 + def foo3363(): Int = 3365 + def foo3364(): Int = 3366 + def foo3365(): Int = 3367 + def foo3366(): Int = 3368 + def foo3367(): Int = 3369 + def foo3368(): Int = 3370 + def foo3369(): Int = 3371 + def foo3370(): Int = 3372 + def foo3371(): Int = 3373 + def foo3372(): Int = 3374 + def foo3373(): Int = 3375 + def foo3374(): Int = 3376 + def foo3375(): Int = 3377 + def foo3376(): Int = 3378 + def foo3377(): Int = 3379 + def foo3378(): Int = 3380 + def foo3379(): Int = 3381 + def foo3380(): Int = 3382 + def foo3381(): Int = 3383 + def foo3382(): Int = 3384 + def foo3383(): Int = 3385 + def foo3384(): Int = 3386 + def foo3385(): Int = 3387 + def foo3386(): Int = 3388 + def foo3387(): Int = 3389 + def foo3388(): Int = 3390 + def foo3389(): Int = 3391 + def foo3390(): Int = 3392 + def foo3391(): Int = 3393 + def foo3392(): Int = 3394 + def foo3393(): Int = 3395 + def foo3394(): Int = 3396 + def foo3395(): Int = 3397 + def foo3396(): Int = 3398 + def foo3397(): Int = 3399 + def foo3398(): Int = 3400 + def foo3399(): Int = 3401 + def foo3400(): Int = 3402 + def foo3401(): Int = 3403 + def foo3402(): Int = 3404 + def foo3403(): Int = 3405 + def foo3404(): Int = 3406 + def foo3405(): Int = 3407 + def foo3406(): Int = 3408 + def foo3407(): Int = 3409 + def foo3408(): Int = 3410 + def foo3409(): Int = 3411 + def foo3410(): Int = 3412 + def foo3411(): Int = 3413 + def foo3412(): Int = 3414 + def foo3413(): Int = 3415 + def foo3414(): Int = 3416 + def foo3415(): Int = 3417 + def foo3416(): Int = 3418 + def foo3417(): Int = 3419 + def foo3418(): Int = 3420 + def foo3419(): Int = 3421 + def foo3420(): Int = 3422 + def foo3421(): Int = 3423 + def foo3422(): Int = 3424 + def foo3423(): Int = 3425 + def foo3424(): Int = 3426 + def foo3425(): Int = 3427 + def foo3426(): Int = 3428 + def foo3427(): Int = 3429 + def foo3428(): Int = 3430 + def foo3429(): Int = 3431 + def foo3430(): Int = 3432 + def foo3431(): Int = 3433 + def foo3432(): Int = 3434 + def foo3433(): Int = 3435 + def foo3434(): Int = 3436 + def foo3435(): Int = 3437 + def foo3436(): Int = 3438 + def foo3437(): Int = 3439 + def foo3438(): Int = 3440 + def foo3439(): Int = 3441 + def foo3440(): Int = 3442 + def foo3441(): Int = 3443 + def foo3442(): Int = 3444 + def foo3443(): Int = 3445 + def foo3444(): Int = 3446 + def foo3445(): Int = 3447 + def foo3446(): Int = 3448 + def foo3447(): Int = 3449 + def foo3448(): Int = 3450 + def foo3449(): Int = 3451 + def foo3450(): Int = 3452 + def foo3451(): Int = 3453 + def foo3452(): Int = 3454 + def foo3453(): Int = 3455 + def foo3454(): Int = 3456 + def foo3455(): Int = 3457 + def foo3456(): Int = 3458 + def foo3457(): Int = 3459 + def foo3458(): Int = 3460 + def foo3459(): Int = 3461 + def foo3460(): Int = 3462 + def foo3461(): Int = 3463 + def foo3462(): Int = 3464 + def foo3463(): Int = 3465 + def foo3464(): Int = 3466 + def foo3465(): Int = 3467 + def foo3466(): Int = 3468 + def foo3467(): Int = 3469 + def foo3468(): Int = 3470 + def foo3469(): Int = 3471 + def foo3470(): Int = 3472 + def foo3471(): Int = 3473 + def foo3472(): Int = 3474 + def foo3473(): Int = 3475 + def foo3474(): Int = 3476 + def foo3475(): Int = 3477 + def foo3476(): Int = 3478 + def foo3477(): Int = 3479 + def foo3478(): Int = 3480 + def foo3479(): Int = 3481 + def foo3480(): Int = 3482 + def foo3481(): Int = 3483 + def foo3482(): Int = 3484 + def foo3483(): Int = 3485 + def foo3484(): Int = 3486 + def foo3485(): Int = 3487 + def foo3486(): Int = 3488 + def foo3487(): Int = 3489 + def foo3488(): Int = 3490 + def foo3489(): Int = 3491 + def foo3490(): Int = 3492 + def foo3491(): Int = 3493 + def foo3492(): Int = 3494 + def foo3493(): Int = 3495 + def foo3494(): Int = 3496 + def foo3495(): Int = 3497 + def foo3496(): Int = 3498 + def foo3497(): Int = 3499 + def foo3498(): Int = 3500 + def foo3499(): Int = 3501 + def foo3500(): Int = 3502 +} -- cgit v1.2.3 From 36f2028fba8c8ed4e9cc82f5665edd1b233c88fc Mon Sep 17 00:00:00 2001 From: Gerard Basler Date: Sun, 3 May 2015 15:45:58 +0200 Subject: Move test files to the right place. --- .../test/files/neg/virtpatmat_exhaust_big.check | 7 ----- .../test/files/neg/virtpatmat_exhaust_big.flags | 1 - .../test/files/neg/virtpatmat_exhaust_big.scala | 32 -------------------- .../test/files/pos/virtpatmat_exhaust_big.scala | 34 ---------------------- test/files/neg/virtpatmat_exhaust_big.check | 7 +++++ test/files/neg/virtpatmat_exhaust_big.flags | 1 + test/files/neg/virtpatmat_exhaust_big.scala | 32 ++++++++++++++++++++ test/files/pos/virtpatmat_exhaust_big.scala | 33 +++++++++++++++++++++ 8 files changed, 73 insertions(+), 74 deletions(-) delete mode 100644 src/intellij/test/files/neg/virtpatmat_exhaust_big.check delete mode 100644 src/intellij/test/files/neg/virtpatmat_exhaust_big.flags delete mode 100644 src/intellij/test/files/neg/virtpatmat_exhaust_big.scala delete mode 100644 src/intellij/test/files/pos/virtpatmat_exhaust_big.scala create mode 100644 test/files/neg/virtpatmat_exhaust_big.check create mode 100644 test/files/neg/virtpatmat_exhaust_big.flags create mode 100644 test/files/neg/virtpatmat_exhaust_big.scala create mode 100644 test/files/pos/virtpatmat_exhaust_big.scala (limited to 'src') diff --git a/src/intellij/test/files/neg/virtpatmat_exhaust_big.check b/src/intellij/test/files/neg/virtpatmat_exhaust_big.check deleted file mode 100644 index fddc85a362..0000000000 --- a/src/intellij/test/files/neg/virtpatmat_exhaust_big.check +++ /dev/null @@ -1,7 +0,0 @@ -virtpatmat_exhaust_big.scala:27: warning: match may not be exhaustive. -It would fail on the following input: Z11() - def foo(z: Z) = z match { - ^ -error: No warnings can be incurred under -Xfatal-warnings. -one warning found -one error found diff --git a/src/intellij/test/files/neg/virtpatmat_exhaust_big.flags b/src/intellij/test/files/neg/virtpatmat_exhaust_big.flags deleted file mode 100644 index b5a8748652..0000000000 --- a/src/intellij/test/files/neg/virtpatmat_exhaust_big.flags +++ /dev/null @@ -1 +0,0 @@ --Xfatal-warnings -unchecked diff --git a/src/intellij/test/files/neg/virtpatmat_exhaust_big.scala b/src/intellij/test/files/neg/virtpatmat_exhaust_big.scala deleted file mode 100644 index dd639eb56e..0000000000 --- a/src/intellij/test/files/neg/virtpatmat_exhaust_big.scala +++ /dev/null @@ -1,32 +0,0 @@ -sealed abstract class Z -object Z { - object Z0 extends Z - case class Z1() extends Z - object Z2 extends Z - case class Z3() extends Z - object Z4 extends Z - case class Z5() extends Z - object Z6 extends Z - case class Z7() extends Z - object Z8 extends Z - case class Z9() extends Z - object Z10 extends Z - case class Z11() extends Z - object Z12 extends Z - case class Z13() extends Z - object Z14 extends Z - case class Z15() extends Z - object Z16 extends Z - case class Z17() extends Z - object Z18 extends Z - case class Z19() extends Z -} - -object Test { - import Z._ - def foo(z: Z) = z match { - case Z0 | Z1() | Z2 | Z3() | Z4 | Z5() | Z6 | Z7() | Z8 | Z9() | - Z10 | Z12 | Z13() | Z14 | Z15() | Z16 | Z17() | Z18 | Z19() - => - } -} diff --git a/src/intellij/test/files/pos/virtpatmat_exhaust_big.scala b/src/intellij/test/files/pos/virtpatmat_exhaust_big.scala deleted file mode 100644 index 41aef3226e..0000000000 --- a/src/intellij/test/files/pos/virtpatmat_exhaust_big.scala +++ /dev/null @@ -1,34 +0,0 @@ -sealed abstract class Z -object Z { - object Z0 extends Z - case class Z1() extends Z - object Z2 extends Z - case class Z3() extends Z - object Z4 extends Z - case class Z5() extends Z - object Z6 extends Z - case class Z7() extends Z - object Z8 extends Z - case class Z9() extends Z - object Z10 extends Z - case class Z11() extends Z - object Z12 extends Z - case class Z13() extends Z - object Z14 extends Z - case class Z15() extends Z - object Z16 extends Z - case class Z17() extends Z - object Z18 extends Z - case class Z19() extends Z -} - -// drop any case and it will report an error -object Test { - import Z._ - def foo(z: Z) = z match { - case Z0 | Z1() | Z2 | Z3() | Z4 | Z5() | Z6 | Z7() | Z8 | Z9() | - Z10 | Z11() | Z12 | Z13() | Z14 | Z15() | Z16 | Z17() | Z18 | Z19() - => - } -} -- diff --git a/test/files/neg/virtpatmat_exhaust_big.check b/test/files/neg/virtpatmat_exhaust_big.check new file mode 100644 index 0000000000..fddc85a362 --- /dev/null +++ b/test/files/neg/virtpatmat_exhaust_big.check @@ -0,0 +1,7 @@ +virtpatmat_exhaust_big.scala:27: warning: match may not be exhaustive. +It would fail on the following input: Z11() + def foo(z: Z) = z match { + ^ +error: No warnings can be incurred under -Xfatal-warnings. +one warning found +one error found diff --git a/test/files/neg/virtpatmat_exhaust_big.flags b/test/files/neg/virtpatmat_exhaust_big.flags new file mode 100644 index 0000000000..b5a8748652 --- /dev/null +++ b/test/files/neg/virtpatmat_exhaust_big.flags @@ -0,0 +1 @@ +-Xfatal-warnings -unchecked diff --git a/test/files/neg/virtpatmat_exhaust_big.scala b/test/files/neg/virtpatmat_exhaust_big.scala new file mode 100644 index 0000000000..dd639eb56e --- /dev/null +++ b/test/files/neg/virtpatmat_exhaust_big.scala @@ -0,0 +1,32 @@ +sealed abstract class Z +object Z { + object Z0 extends Z + case class Z1() extends Z + object Z2 extends Z + case class Z3() extends Z + object Z4 extends Z + case class Z5() extends Z + object Z6 extends Z + case class Z7() extends Z + object Z8 extends Z + case class Z9() extends Z + object Z10 extends Z + case class Z11() extends Z + object Z12 extends Z + case class Z13() extends Z + object Z14 extends Z + case class Z15() extends Z + object Z16 extends Z + case class Z17() extends Z + object Z18 extends Z + case class Z19() extends Z +} + +object Test { + import Z._ + def foo(z: Z) = z match { + case Z0 | Z1() | Z2 | Z3() | Z4 | Z5() | Z6 | Z7() | Z8 | Z9() | + Z10 | Z12 | Z13() | Z14 | Z15() | Z16 | Z17() | Z18 | Z19() + => + } +} diff --git a/test/files/pos/virtpatmat_exhaust_big.scala b/test/files/pos/virtpatmat_exhaust_big.scala new file mode 100644 index 0000000000..9850933540 --- /dev/null +++ b/test/files/pos/virtpatmat_exhaust_big.scala @@ -0,0 +1,33 @@ +sealed abstract class Z +object Z { + object Z0 extends Z + case class Z1() extends Z + object Z2 extends Z + case class Z3() extends Z + object Z4 extends Z + case class Z5() extends Z + object Z6 extends Z + case class Z7() extends Z + object Z8 extends Z + case class Z9() extends Z + object Z10 extends Z + case class Z11() extends Z + object Z12 extends Z + case class Z13() extends Z + object Z14 extends Z + case class Z15() extends Z + object Z16 extends Z + case class Z17() extends Z + object Z18 extends Z + case class Z19() extends Z +} + +// drop any case and it will report an error +object Test { + import Z._ + def foo(z: Z) = z match { + case Z0 | Z1() | Z2 | Z3() | Z4 | Z5() | Z6 | Z7() | Z8 | Z9() | + Z10 | Z11() | Z12 | Z13() | Z14 | Z15() | Z16 | Z17() | Z18 | Z19() + => + } +} \ No newline at end of file -- cgit v1.2.3 From a094654b4dc4a9d911f36ab8bfc7451872bcee53 Mon Sep 17 00:00:00 2001 From: Gerard Basler Date: Sun, 3 May 2015 15:46:50 +0200 Subject: Avoid `Set` instantiation. --- src/compiler/scala/tools/nsc/transform/patmat/Logic.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala index cef22d7d6b..227c45b3a7 100644 --- a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala +++ b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala @@ -384,9 +384,8 @@ trait Logic extends Debugging { // ... and what must not? excluded foreach { excludedSym => - val related = Set(sym, excludedSym) val exclusive = v.groupedDomains.exists { - domain => related subsetOf domain.toSet + domain => domain.contains(sym) && domain.contains(excludedSym) } // TODO: populate `v.exclusiveDomains` with `Set`s from the start, and optimize to: -- cgit v1.2.3 From a18e42bc0773084a3e311646e1e2ffd623db4cfa Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Tue, 5 May 2015 09:59:43 +1000 Subject: SI-9298 Fix erasure of value classes in Java Value classes that appear in signatures of Java defined methods should not be erased to the underlying type. Before this change, we'd get a `ClassCastException`, as the Scala call site would unbox the value class despite the fact the Java recipient would expect the boxed representation. I've tested this for primitive and object wrapped types in parameter and return position. --- src/reflect/scala/reflect/internal/transform/Erasure.scala | 2 ++ test/files/run/t9298/Test.java | 7 +++++++ test/files/run/t9298/VC.scala | 5 +++++ test/files/run/t9298b/Test.java | 7 +++++++ test/files/run/t9298b/VC.scala | 8 ++++++++ 5 files changed, 29 insertions(+) create mode 100644 test/files/run/t9298/Test.java create mode 100644 test/files/run/t9298/VC.scala create mode 100644 test/files/run/t9298b/Test.java create mode 100644 test/files/run/t9298b/VC.scala (limited to 'src') diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala index d5b5967145..707972242a 100644 --- a/src/reflect/scala/reflect/internal/transform/Erasure.scala +++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala @@ -254,6 +254,8 @@ trait Erasure { def mergeParents(parents: List[Type]): Type = if (parents.isEmpty) ObjectTpe else parents.head + + override protected def eraseDerivedValueClassRef(tref: TypeRef): Type = eraseNormalClassRef(tref) } object scalaErasure extends ScalaErasureMap diff --git a/test/files/run/t9298/Test.java b/test/files/run/t9298/Test.java new file mode 100644 index 0000000000..81f5265985 --- /dev/null +++ b/test/files/run/t9298/Test.java @@ -0,0 +1,7 @@ +public class Test { + public void consume(VC vc) {} + + public static void main(String[] args) { + new Client().test(); + } +} diff --git a/test/files/run/t9298/VC.scala b/test/files/run/t9298/VC.scala new file mode 100644 index 0000000000..916e62dc59 --- /dev/null +++ b/test/files/run/t9298/VC.scala @@ -0,0 +1,5 @@ +class VC(val s: String) extends AnyVal + +class Client { + def test = new Test().consume(new VC("")) +} diff --git a/test/files/run/t9298b/Test.java b/test/files/run/t9298b/Test.java new file mode 100644 index 0000000000..f369b26f36 --- /dev/null +++ b/test/files/run/t9298b/Test.java @@ -0,0 +1,7 @@ +public class Test { + public VC identity(VC vc) { return vc; } + + public static void main(String[] args) { + new Client().test(); + } +} diff --git a/test/files/run/t9298b/VC.scala b/test/files/run/t9298b/VC.scala new file mode 100644 index 0000000000..bb5978b6e4 --- /dev/null +++ b/test/files/run/t9298b/VC.scala @@ -0,0 +1,8 @@ +class VC(val s: Int) extends AnyVal + +class Client { + def test = { + val vc: VC = new Test().identity(new VC(42)) + assert(vc.s == 42) + } +} -- cgit v1.2.3 From 92f69d253ee6e941263aaf0a09936b4e4ce21dc7 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Tue, 5 May 2015 13:52:22 -0700 Subject: SI-9302 -Xdisable-assertions raises elide level Previously, the flag caused any elidable to be elided. This commit simply sets -Xelide-below to ASSERTION + 1. The flag is useful because there's no mnemonic for specifying the magic constant as an option argument. `-Xelide-below ASSERTION` means asserts are enabled. --- src/compiler/scala/tools/nsc/settings/ScalaSettings.scala | 3 ++- src/compiler/scala/tools/nsc/transform/UnCurry.scala | 4 +--- src/library/scala/Predef.scala | 6 +++--- test/files/run/disable-assertions.flags | 1 + test/files/run/disable-assertions.scala | 14 ++++++++++++++ 5 files changed, 21 insertions(+), 7 deletions(-) create mode 100644 test/files/run/disable-assertions.flags create mode 100644 test/files/run/disable-assertions.scala (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 630276e412..35ee889c58 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -101,7 +101,8 @@ trait ScalaSettings extends AbsScalaSettings val Xhelp = BooleanSetting ("-X", "Print a synopsis of advanced options.") val checkInit = BooleanSetting ("-Xcheckinit", "Wrap field accessors to throw an exception on uninitialized access.") val developer = BooleanSetting ("-Xdev", "Indicates user is a developer - issue warnings about anything which seems amiss") - val noassertions = BooleanSetting ("-Xdisable-assertions", "Generate no assertions or assumptions.") + val noassertions = BooleanSetting ("-Xdisable-assertions", "Generate no assertions or assumptions.") andThen (flag => + if (flag) elidebelow.value = elidable.ASSERTION + 1) val elidebelow = IntSetting ("-Xelide-below", "Calls to @elidable methods are omitted if method priority is lower than argument", elidable.MINIMUM, None, elidable.byName get _) val noForwarders = BooleanSetting ("-Xno-forwarders", "Do not generate static forwarders in mirror classes.") diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index 836ea808ac..1020b98bb9 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -437,9 +437,7 @@ abstract class UnCurry extends InfoTransform def isLiftedLambdaBody(target: Tree) = target.symbol.isLocalToBlock && target.symbol.isArtifact && target.symbol.name.containsName(nme.ANON_FUN_NAME) val result = ( - // TODO - settings.noassertions.value temporarily retained to avoid - // breakage until a reasonable interface is settled upon. - if ((sym ne null) && (sym.elisionLevel.exists (_ < settings.elidebelow.value || settings.noassertions))) + if ((sym ne null) && sym.elisionLevel.exists(_ < settings.elidebelow.value)) replaceElidableTree(tree) else translateSynchronized(tree) match { case dd @ DefDef(mods, name, tparams, _, tpt, rhs) => diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 4eed672794..0f300412b7 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -35,9 +35,9 @@ import scala.io.StdIn * === Assertions === * * A set of `assert` functions are provided for use as a way to document - * and dynamically check invariants in code. `assert` statements can be elided - * at compile time by providing the command line argument `-Xdisable-assertions` to - * the `scalac` command. + * and dynamically check invariants in code. Invocations of `assert` can be elided + * at compile time by providing the command line option `-Xdisable-assertions`, + * which raises `-Xelide-below` above `elidable.ASSERTION`, to the `scalac` command. * * Variants of `assert` intended for use with static analysis tools are also * provided: `assume`, `require` and `ensuring`. `require` and `ensuring` are diff --git a/test/files/run/disable-assertions.flags b/test/files/run/disable-assertions.flags new file mode 100644 index 0000000000..afaa521a12 --- /dev/null +++ b/test/files/run/disable-assertions.flags @@ -0,0 +1 @@ +-Xdisable-assertions diff --git a/test/files/run/disable-assertions.scala b/test/files/run/disable-assertions.scala new file mode 100644 index 0000000000..7ec4cfb495 --- /dev/null +++ b/test/files/run/disable-assertions.scala @@ -0,0 +1,14 @@ + +object Elided { + import annotation._, elidable._ + @elidable(INFO) def info(): Boolean = true + @elidable(10000) def f(): Boolean = true + def g(): Boolean = { assert(false); true } +} + +object Test extends App { + import Elided._ + if (info()) println("Bad info.") + if (!f()) println("Elided f.") + if (!g()) println("Elided g?") // assert should be off +} -- cgit v1.2.3 From ee8442d295b095c302acce7bcf22287b26a16ed9 Mon Sep 17 00:00:00 2001 From: Cody Allen Date: Thu, 7 May 2015 19:09:32 -0400 Subject: Add @throws annotation to GenSeqLike.updated Similarly to GenSeqLike.apply, GenSeqLike.updated can throw IndexOutOfBoundsException. For example, the following throws IndexOutOfBoundsException: Vector.empty[String].updated(0, "foo") --- src/library/scala/collection/GenSeqLike.scala | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/library/scala/collection/GenSeqLike.scala b/src/library/scala/collection/GenSeqLike.scala index cf1de0c8e6..f786293822 100644 --- a/src/library/scala/collection/GenSeqLike.scala +++ b/src/library/scala/collection/GenSeqLike.scala @@ -275,6 +275,7 @@ trait GenSeqLike[+A, +Repr] extends Any with GenIterableLike[A, Repr] with Equal * @tparam That $thatinfo * @param bf $bfinfo * @return a new $coll` which is a copy of this $coll with the element at position `index` replaced by `elem`. + * @throws IndexOutOfBoundsException if `index` does not satisfy `0 <= index < length`. * * @usecase def updated(index: Int, elem: A): $Coll[A] * @inheritdoc -- cgit v1.2.3 From 9c1d5cedecd8d367c50533b09c543844f1c0d314 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Mon, 11 May 2015 14:03:00 +0200 Subject: intellij project files for ASM removal ij fix --- src/intellij/compiler.iml.SAMPLE | 2 +- src/intellij/partest-extras.iml.SAMPLE | 2 +- src/intellij/partest-javaagent.iml.SAMPLE | 2 +- src/intellij/repl.iml.SAMPLE | 2 +- src/intellij/scala.ipr.SAMPLE | 11 +++++++++-- src/intellij/test-junit.iml.SAMPLE | 2 +- src/intellij/test.iml.SAMPLE | 2 +- 7 files changed, 15 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/intellij/compiler.iml.SAMPLE b/src/intellij/compiler.iml.SAMPLE index 00f732e255..0e121925e6 100644 --- a/src/intellij/compiler.iml.SAMPLE +++ b/src/intellij/compiler.iml.SAMPLE @@ -8,10 +8,10 @@ - + \ No newline at end of file diff --git a/src/intellij/partest-extras.iml.SAMPLE b/src/intellij/partest-extras.iml.SAMPLE index d352f9ebc3..1cd712184b 100644 --- a/src/intellij/partest-extras.iml.SAMPLE +++ b/src/intellij/partest-extras.iml.SAMPLE @@ -7,12 +7,12 @@ - + \ No newline at end of file diff --git a/src/intellij/partest-javaagent.iml.SAMPLE b/src/intellij/partest-javaagent.iml.SAMPLE index c6081a2a4b..ffc540cdb9 100644 --- a/src/intellij/partest-javaagent.iml.SAMPLE +++ b/src/intellij/partest-javaagent.iml.SAMPLE @@ -7,6 +7,6 @@ - + \ No newline at end of file diff --git a/src/intellij/repl.iml.SAMPLE b/src/intellij/repl.iml.SAMPLE index 896ec1dd5c..7476f30131 100644 --- a/src/intellij/repl.iml.SAMPLE +++ b/src/intellij/repl.iml.SAMPLE @@ -7,11 +7,11 @@ - + \ No newline at end of file diff --git a/src/intellij/scala.ipr.SAMPLE b/src/intellij/scala.ipr.SAMPLE index 07f366a302..47ac2be188 100644 --- a/src/intellij/scala.ipr.SAMPLE +++ b/src/intellij/scala.ipr.SAMPLE @@ -36,7 +36,6 @@ - @@ -73,6 +72,14 @@ + + + + + + + + @@ -118,4 +125,4 @@ - + \ No newline at end of file diff --git a/src/intellij/test-junit.iml.SAMPLE b/src/intellij/test-junit.iml.SAMPLE index fe98fce60c..86dc39c175 100644 --- a/src/intellij/test-junit.iml.SAMPLE +++ b/src/intellij/test-junit.iml.SAMPLE @@ -8,7 +8,6 @@ - @@ -19,5 +18,6 @@ + \ No newline at end of file diff --git a/src/intellij/test.iml.SAMPLE b/src/intellij/test.iml.SAMPLE index 175a920771..5047967721 100644 --- a/src/intellij/test.iml.SAMPLE +++ b/src/intellij/test.iml.SAMPLE @@ -8,7 +8,6 @@ - @@ -18,5 +17,6 @@ + \ No newline at end of file -- cgit v1.2.3 From 6fc2a6897b52b684ffe40dac87df6fbfc2d3d508 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Fri, 8 May 2015 15:39:50 +0200 Subject: Remove ASM sources --- src/asm/README | 37 - src/asm/scala/tools/asm/AnnotationVisitor.java | 169 -- src/asm/scala/tools/asm/AnnotationWriter.java | 371 --- src/asm/scala/tools/asm/Attribute.java | 255 -- src/asm/scala/tools/asm/ByteVector.java | 339 --- src/asm/scala/tools/asm/ClassReader.java | 2496 ----------------- src/asm/scala/tools/asm/ClassVisitor.java | 320 --- src/asm/scala/tools/asm/ClassWriter.java | 1785 ------------ src/asm/scala/tools/asm/Context.java | 145 - src/asm/scala/tools/asm/CustomAttr.java | 20 - src/asm/scala/tools/asm/Edge.java | 75 - src/asm/scala/tools/asm/FieldVisitor.java | 150 - src/asm/scala/tools/asm/FieldWriter.java | 329 --- src/asm/scala/tools/asm/Frame.java | 1462 ---------- src/asm/scala/tools/asm/Handle.java | 170 -- src/asm/scala/tools/asm/Handler.java | 121 - src/asm/scala/tools/asm/Item.java | 312 --- src/asm/scala/tools/asm/Label.java | 560 ---- src/asm/scala/tools/asm/MethodVisitor.java | 880 ------ src/asm/scala/tools/asm/MethodWriter.java | 2924 -------------------- src/asm/scala/tools/asm/Opcodes.java | 361 --- src/asm/scala/tools/asm/Type.java | 896 ------ src/asm/scala/tools/asm/TypePath.java | 193 -- src/asm/scala/tools/asm/TypeReference.java | 452 --- .../scala/tools/asm/commons/CodeSizeEvaluator.java | 238 -- .../scala/tools/asm/signature/SignatureReader.java | 228 -- .../tools/asm/signature/SignatureVisitor.java | 238 -- .../scala/tools/asm/signature/SignatureWriter.java | 227 -- src/asm/scala/tools/asm/tree/AbstractInsnNode.java | 326 --- src/asm/scala/tools/asm/tree/AnnotationNode.java | 231 -- src/asm/scala/tools/asm/tree/ClassNode.java | 417 --- src/asm/scala/tools/asm/tree/FieldInsnNode.java | 110 - src/asm/scala/tools/asm/tree/FieldNode.java | 307 -- src/asm/scala/tools/asm/tree/FrameNode.java | 210 -- src/asm/scala/tools/asm/tree/IincInsnNode.java | 83 - src/asm/scala/tools/asm/tree/InnerClassNode.java | 101 - src/asm/scala/tools/asm/tree/InsnList.java | 622 ----- src/asm/scala/tools/asm/tree/InsnNode.java | 88 - src/asm/scala/tools/asm/tree/IntInsnNode.java | 88 - .../tools/asm/tree/InvokeDynamicInsnNode.java | 102 - src/asm/scala/tools/asm/tree/JumpInsnNode.java | 97 - src/asm/scala/tools/asm/tree/LabelNode.java | 78 - src/asm/scala/tools/asm/tree/LdcInsnNode.java | 79 - src/asm/scala/tools/asm/tree/LineNumberNode.java | 84 - .../asm/tree/LocalVariableAnnotationNode.java | 157 -- .../scala/tools/asm/tree/LocalVariableNode.java | 112 - .../scala/tools/asm/tree/LookupSwitchInsnNode.java | 118 - src/asm/scala/tools/asm/tree/MethodInsnNode.java | 141 - src/asm/scala/tools/asm/tree/MethodNode.java | 839 ------ .../tools/asm/tree/MultiANewArrayInsnNode.java | 84 - src/asm/scala/tools/asm/tree/ParameterNode.java | 76 - .../scala/tools/asm/tree/TableSwitchInsnNode.java | 114 - .../scala/tools/asm/tree/TryCatchBlockNode.java | 153 - .../scala/tools/asm/tree/TypeAnnotationNode.java | 100 - src/asm/scala/tools/asm/tree/TypeInsnNode.java | 91 - src/asm/scala/tools/asm/tree/VarInsnNode.java | 94 - .../scala/tools/asm/tree/analysis/Analyzer.java | 549 ---- .../tools/asm/tree/analysis/AnalyzerException.java | 62 - .../tools/asm/tree/analysis/BasicInterpreter.java | 358 --- .../scala/tools/asm/tree/analysis/BasicValue.java | 111 - .../tools/asm/tree/analysis/BasicVerifier.java | 433 --- src/asm/scala/tools/asm/tree/analysis/Frame.java | 738 ----- .../scala/tools/asm/tree/analysis/Interpreter.java | 226 -- .../tools/asm/tree/analysis/SimpleVerifier.java | 320 --- .../scala/tools/asm/tree/analysis/SmallSet.java | 134 - .../tools/asm/tree/analysis/SourceInterpreter.java | 198 -- .../scala/tools/asm/tree/analysis/SourceValue.java | 97 - .../scala/tools/asm/tree/analysis/Subroutine.java | 90 - src/asm/scala/tools/asm/tree/analysis/Value.java | 45 - src/asm/scala/tools/asm/util/ASMifiable.java | 56 - src/asm/scala/tools/asm/util/ASMifier.java | 1284 --------- .../tools/asm/util/CheckAnnotationAdapter.java | 136 - .../scala/tools/asm/util/CheckClassAdapter.java | 1009 ------- .../scala/tools/asm/util/CheckFieldAdapter.java | 122 - .../scala/tools/asm/util/CheckMethodAdapter.java | 1542 ----------- .../tools/asm/util/CheckSignatureAdapter.java | 330 --- src/asm/scala/tools/asm/util/Printer.java | 589 ---- src/asm/scala/tools/asm/util/Textifiable.java | 56 - src/asm/scala/tools/asm/util/Textifier.java | 1459 ---------- .../tools/asm/util/TraceAnnotationVisitor.java | 89 - .../scala/tools/asm/util/TraceClassVisitor.java | 220 -- .../scala/tools/asm/util/TraceFieldVisitor.java | 87 - .../scala/tools/asm/util/TraceMethodVisitor.java | 292 -- .../tools/asm/util/TraceSignatureVisitor.java | 317 --- 84 files changed, 31804 deletions(-) delete mode 100644 src/asm/README delete mode 100644 src/asm/scala/tools/asm/AnnotationVisitor.java delete mode 100644 src/asm/scala/tools/asm/AnnotationWriter.java delete mode 100644 src/asm/scala/tools/asm/Attribute.java delete mode 100644 src/asm/scala/tools/asm/ByteVector.java delete mode 100644 src/asm/scala/tools/asm/ClassReader.java delete mode 100644 src/asm/scala/tools/asm/ClassVisitor.java delete mode 100644 src/asm/scala/tools/asm/ClassWriter.java delete mode 100644 src/asm/scala/tools/asm/Context.java delete mode 100644 src/asm/scala/tools/asm/CustomAttr.java delete mode 100644 src/asm/scala/tools/asm/Edge.java delete mode 100644 src/asm/scala/tools/asm/FieldVisitor.java delete mode 100644 src/asm/scala/tools/asm/FieldWriter.java delete mode 100644 src/asm/scala/tools/asm/Frame.java delete mode 100644 src/asm/scala/tools/asm/Handle.java delete mode 100644 src/asm/scala/tools/asm/Handler.java delete mode 100644 src/asm/scala/tools/asm/Item.java delete mode 100644 src/asm/scala/tools/asm/Label.java delete mode 100644 src/asm/scala/tools/asm/MethodVisitor.java delete mode 100644 src/asm/scala/tools/asm/MethodWriter.java delete mode 100644 src/asm/scala/tools/asm/Opcodes.java delete mode 100644 src/asm/scala/tools/asm/Type.java delete mode 100644 src/asm/scala/tools/asm/TypePath.java delete mode 100644 src/asm/scala/tools/asm/TypeReference.java delete mode 100644 src/asm/scala/tools/asm/commons/CodeSizeEvaluator.java delete mode 100644 src/asm/scala/tools/asm/signature/SignatureReader.java delete mode 100644 src/asm/scala/tools/asm/signature/SignatureVisitor.java delete mode 100644 src/asm/scala/tools/asm/signature/SignatureWriter.java delete mode 100644 src/asm/scala/tools/asm/tree/AbstractInsnNode.java delete mode 100644 src/asm/scala/tools/asm/tree/AnnotationNode.java delete mode 100644 src/asm/scala/tools/asm/tree/ClassNode.java delete mode 100644 src/asm/scala/tools/asm/tree/FieldInsnNode.java delete mode 100644 src/asm/scala/tools/asm/tree/FieldNode.java delete mode 100644 src/asm/scala/tools/asm/tree/FrameNode.java delete mode 100644 src/asm/scala/tools/asm/tree/IincInsnNode.java delete mode 100644 src/asm/scala/tools/asm/tree/InnerClassNode.java delete mode 100644 src/asm/scala/tools/asm/tree/InsnList.java delete mode 100644 src/asm/scala/tools/asm/tree/InsnNode.java delete mode 100644 src/asm/scala/tools/asm/tree/IntInsnNode.java delete mode 100644 src/asm/scala/tools/asm/tree/InvokeDynamicInsnNode.java delete mode 100644 src/asm/scala/tools/asm/tree/JumpInsnNode.java delete mode 100644 src/asm/scala/tools/asm/tree/LabelNode.java delete mode 100644 src/asm/scala/tools/asm/tree/LdcInsnNode.java delete mode 100644 src/asm/scala/tools/asm/tree/LineNumberNode.java delete mode 100644 src/asm/scala/tools/asm/tree/LocalVariableAnnotationNode.java delete mode 100644 src/asm/scala/tools/asm/tree/LocalVariableNode.java delete mode 100644 src/asm/scala/tools/asm/tree/LookupSwitchInsnNode.java delete mode 100644 src/asm/scala/tools/asm/tree/MethodInsnNode.java delete mode 100644 src/asm/scala/tools/asm/tree/MethodNode.java delete mode 100644 src/asm/scala/tools/asm/tree/MultiANewArrayInsnNode.java delete mode 100644 src/asm/scala/tools/asm/tree/ParameterNode.java delete mode 100644 src/asm/scala/tools/asm/tree/TableSwitchInsnNode.java delete mode 100644 src/asm/scala/tools/asm/tree/TryCatchBlockNode.java delete mode 100644 src/asm/scala/tools/asm/tree/TypeAnnotationNode.java delete mode 100644 src/asm/scala/tools/asm/tree/TypeInsnNode.java delete mode 100644 src/asm/scala/tools/asm/tree/VarInsnNode.java delete mode 100644 src/asm/scala/tools/asm/tree/analysis/Analyzer.java delete mode 100644 src/asm/scala/tools/asm/tree/analysis/AnalyzerException.java delete mode 100644 src/asm/scala/tools/asm/tree/analysis/BasicInterpreter.java delete mode 100644 src/asm/scala/tools/asm/tree/analysis/BasicValue.java delete mode 100644 src/asm/scala/tools/asm/tree/analysis/BasicVerifier.java delete mode 100644 src/asm/scala/tools/asm/tree/analysis/Frame.java delete mode 100644 src/asm/scala/tools/asm/tree/analysis/Interpreter.java delete mode 100644 src/asm/scala/tools/asm/tree/analysis/SimpleVerifier.java delete mode 100644 src/asm/scala/tools/asm/tree/analysis/SmallSet.java delete mode 100644 src/asm/scala/tools/asm/tree/analysis/SourceInterpreter.java delete mode 100644 src/asm/scala/tools/asm/tree/analysis/SourceValue.java delete mode 100644 src/asm/scala/tools/asm/tree/analysis/Subroutine.java delete mode 100644 src/asm/scala/tools/asm/tree/analysis/Value.java delete mode 100644 src/asm/scala/tools/asm/util/ASMifiable.java delete mode 100644 src/asm/scala/tools/asm/util/ASMifier.java delete mode 100644 src/asm/scala/tools/asm/util/CheckAnnotationAdapter.java delete mode 100644 src/asm/scala/tools/asm/util/CheckClassAdapter.java delete mode 100644 src/asm/scala/tools/asm/util/CheckFieldAdapter.java delete mode 100644 src/asm/scala/tools/asm/util/CheckMethodAdapter.java delete mode 100644 src/asm/scala/tools/asm/util/CheckSignatureAdapter.java delete mode 100644 src/asm/scala/tools/asm/util/Printer.java delete mode 100644 src/asm/scala/tools/asm/util/Textifiable.java delete mode 100644 src/asm/scala/tools/asm/util/Textifier.java delete mode 100644 src/asm/scala/tools/asm/util/TraceAnnotationVisitor.java delete mode 100644 src/asm/scala/tools/asm/util/TraceClassVisitor.java delete mode 100644 src/asm/scala/tools/asm/util/TraceFieldVisitor.java delete mode 100644 src/asm/scala/tools/asm/util/TraceMethodVisitor.java delete mode 100644 src/asm/scala/tools/asm/util/TraceSignatureVisitor.java (limited to 'src') diff --git a/src/asm/README b/src/asm/README deleted file mode 100644 index 58d555acde..0000000000 --- a/src/asm/README +++ /dev/null @@ -1,37 +0,0 @@ -Version 5.0.3, SVN r1748, tags/ASM_5_0_3 - -Git SVN repo: https://github.com/lrytz/asm - - git svn howto: https://github.com/lrytz/asm/issues/1 - -Upgrading ASM -------------- - -Check the commit history of src/asm: https://github.com/scala/scala/commits/2.11.x/src/asm. -Find the previous commit that upgraded ASM and take a look at its commit message. It should -be a squashed version of a pull request that shows the precise procedure how the last upgrade -was made. - -Start by deleting all source files in src/asm/ and copy the ones from the latest ASM release. - -Excluded Files (don't copy): - - package.html files - - org/objectweb/asm/commons, but keep CodeSizeEvaluator.java - - org/objectweb/asm/optimizer - - org/objectweb/asm/xml - -Re-packaging and cosmetic changes: - - convert line endings (there are some CRLF) - find src/asm/scala/tools/asm -name '*.java' | xargs dos2unix - - change package clauses - find src/asm/scala/tools/asm -name '*.java' | xargs sed -i '' -e 's/package org\.objectweb\.asm/package scala.tools.asm/' - - update imports - find src/asm/scala/tools/asm -name '*.java' | xargs sed -i '' -e 's/import org\.objectweb\.asm/import scala.tools.asm/' - - update @links, @associates - find src/asm/scala/tools/asm -name '*.java' | xargs sed -i '' -e 's/@link org\.objectweb\.asm/@link scala.tools.asm/' - find src/asm/scala/tools/asm -name '*.java' | xargs sed -i '' -e 's/@associates org\.objectweb\.asm/@associates scala.tools.asm/' - - remove trailing whitespace - find src/asm/scala/tools/asm -name '*.java' | xargs sed -i '' -e 's/[ ]*$//' - -Include the actual changes that we have in our repostiory - - Include the commits labelled [asm-cherry-pick] in the non-squashed PR of the previous upgrade - - Include the changes that were added to src/asm since the last upgrade and label them [asm-cherry-pick] diff --git a/src/asm/scala/tools/asm/AnnotationVisitor.java b/src/asm/scala/tools/asm/AnnotationVisitor.java deleted file mode 100644 index abcaf1d6d1..0000000000 --- a/src/asm/scala/tools/asm/AnnotationVisitor.java +++ /dev/null @@ -1,169 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm; - -/** - * A visitor to visit a Java annotation. The methods of this class must be - * called in the following order: ( visit | visitEnum | - * visitAnnotation | visitArray )* visitEnd. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -public abstract class AnnotationVisitor { - - /** - * The ASM API version implemented by this visitor. The value of this field - * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - protected final int api; - - /** - * The annotation visitor to which this visitor must delegate method calls. - * May be null. - */ - protected AnnotationVisitor av; - - /** - * Constructs a new {@link AnnotationVisitor}. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - public AnnotationVisitor(final int api) { - this(api, null); - } - - /** - * Constructs a new {@link AnnotationVisitor}. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - * @param av - * the annotation visitor to which this visitor must delegate - * method calls. May be null. - */ - public AnnotationVisitor(final int api, final AnnotationVisitor av) { - if (api != Opcodes.ASM4 && api != Opcodes.ASM5) { - throw new IllegalArgumentException(); - } - this.api = api; - this.av = av; - } - - /** - * Visits a primitive value of the annotation. - * - * @param name - * the value name. - * @param value - * the actual value, whose type must be {@link Byte}, - * {@link Boolean}, {@link Character}, {@link Short}, - * {@link Integer} , {@link Long}, {@link Float}, {@link Double}, - * {@link String} or {@link Type} or OBJECT or ARRAY sort. This - * value can also be an array of byte, boolean, short, char, int, - * long, float or double values (this is equivalent to using - * {@link #visitArray visitArray} and visiting each array element - * in turn, but is more convenient). - */ - public void visit(String name, Object value) { - if (av != null) { - av.visit(name, value); - } - } - - /** - * Visits an enumeration value of the annotation. - * - * @param name - * the value name. - * @param desc - * the class descriptor of the enumeration class. - * @param value - * the actual enumeration value. - */ - public void visitEnum(String name, String desc, String value) { - if (av != null) { - av.visitEnum(name, desc, value); - } - } - - /** - * Visits a nested annotation value of the annotation. - * - * @param name - * the value name. - * @param desc - * the class descriptor of the nested annotation class. - * @return a visitor to visit the actual nested annotation value, or - * null if this visitor is not interested in visiting this - * nested annotation. The nested annotation value must be fully - * visited before calling other methods on this annotation - * visitor. - */ - public AnnotationVisitor visitAnnotation(String name, String desc) { - if (av != null) { - return av.visitAnnotation(name, desc); - } - return null; - } - - /** - * Visits an array value of the annotation. Note that arrays of primitive - * types (such as byte, boolean, short, char, int, long, float or double) - * can be passed as value to {@link #visit visit}. This is what - * {@link ClassReader} does. - * - * @param name - * the value name. - * @return a visitor to visit the actual array value elements, or - * null if this visitor is not interested in visiting these - * values. The 'name' parameters passed to the methods of this - * visitor are ignored. All the array values must be visited - * before calling other methods on this annotation visitor. - */ - public AnnotationVisitor visitArray(String name) { - if (av != null) { - return av.visitArray(name); - } - return null; - } - - /** - * Visits the end of the annotation. - */ - public void visitEnd() { - if (av != null) { - av.visitEnd(); - } - } -} diff --git a/src/asm/scala/tools/asm/AnnotationWriter.java b/src/asm/scala/tools/asm/AnnotationWriter.java deleted file mode 100644 index 6de74ce041..0000000000 --- a/src/asm/scala/tools/asm/AnnotationWriter.java +++ /dev/null @@ -1,371 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm; - -/** - * An {@link AnnotationVisitor} that generates annotations in bytecode form. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -final class AnnotationWriter extends AnnotationVisitor { - - /** - * The class writer to which this annotation must be added. - */ - private final ClassWriter cw; - - /** - * The number of values in this annotation. - */ - private int size; - - /** - * true if values are named, false otherwise. Annotation - * writers used for annotation default and annotation arrays use unnamed - * values. - */ - private final boolean named; - - /** - * The annotation values in bytecode form. This byte vector only contains - * the values themselves, i.e. the number of values must be stored as a - * unsigned short just before these bytes. - */ - private final ByteVector bv; - - /** - * The byte vector to be used to store the number of values of this - * annotation. See {@link #bv}. - */ - private final ByteVector parent; - - /** - * Where the number of values of this annotation must be stored in - * {@link #parent}. - */ - private final int offset; - - /** - * Next annotation writer. This field is used to store annotation lists. - */ - AnnotationWriter next; - - /** - * Previous annotation writer. This field is used to store annotation lists. - */ - AnnotationWriter prev; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructs a new {@link AnnotationWriter}. - * - * @param cw - * the class writer to which this annotation must be added. - * @param named - * true if values are named, false otherwise. - * @param bv - * where the annotation values must be stored. - * @param parent - * where the number of annotation values must be stored. - * @param offset - * where in parent the number of annotation values must - * be stored. - */ - AnnotationWriter(final ClassWriter cw, final boolean named, - final ByteVector bv, final ByteVector parent, final int offset) { - super(Opcodes.ASM5); - this.cw = cw; - this.named = named; - this.bv = bv; - this.parent = parent; - this.offset = offset; - } - - // ------------------------------------------------------------------------ - // Implementation of the AnnotationVisitor abstract class - // ------------------------------------------------------------------------ - - @Override - public void visit(final String name, final Object value) { - ++size; - if (named) { - bv.putShort(cw.newUTF8(name)); - } - if (value instanceof String) { - bv.put12('s', cw.newUTF8((String) value)); - } else if (value instanceof Byte) { - bv.put12('B', cw.newInteger(((Byte) value).byteValue()).index); - } else if (value instanceof Boolean) { - int v = ((Boolean) value).booleanValue() ? 1 : 0; - bv.put12('Z', cw.newInteger(v).index); - } else if (value instanceof Character) { - bv.put12('C', cw.newInteger(((Character) value).charValue()).index); - } else if (value instanceof Short) { - bv.put12('S', cw.newInteger(((Short) value).shortValue()).index); - } else if (value instanceof Type) { - bv.put12('c', cw.newUTF8(((Type) value).getDescriptor())); - } else if (value instanceof byte[]) { - byte[] v = (byte[]) value; - bv.put12('[', v.length); - for (int i = 0; i < v.length; i++) { - bv.put12('B', cw.newInteger(v[i]).index); - } - } else if (value instanceof boolean[]) { - boolean[] v = (boolean[]) value; - bv.put12('[', v.length); - for (int i = 0; i < v.length; i++) { - bv.put12('Z', cw.newInteger(v[i] ? 1 : 0).index); - } - } else if (value instanceof short[]) { - short[] v = (short[]) value; - bv.put12('[', v.length); - for (int i = 0; i < v.length; i++) { - bv.put12('S', cw.newInteger(v[i]).index); - } - } else if (value instanceof char[]) { - char[] v = (char[]) value; - bv.put12('[', v.length); - for (int i = 0; i < v.length; i++) { - bv.put12('C', cw.newInteger(v[i]).index); - } - } else if (value instanceof int[]) { - int[] v = (int[]) value; - bv.put12('[', v.length); - for (int i = 0; i < v.length; i++) { - bv.put12('I', cw.newInteger(v[i]).index); - } - } else if (value instanceof long[]) { - long[] v = (long[]) value; - bv.put12('[', v.length); - for (int i = 0; i < v.length; i++) { - bv.put12('J', cw.newLong(v[i]).index); - } - } else if (value instanceof float[]) { - float[] v = (float[]) value; - bv.put12('[', v.length); - for (int i = 0; i < v.length; i++) { - bv.put12('F', cw.newFloat(v[i]).index); - } - } else if (value instanceof double[]) { - double[] v = (double[]) value; - bv.put12('[', v.length); - for (int i = 0; i < v.length; i++) { - bv.put12('D', cw.newDouble(v[i]).index); - } - } else { - Item i = cw.newConstItem(value); - bv.put12(".s.IFJDCS".charAt(i.type), i.index); - } - } - - @Override - public void visitEnum(final String name, final String desc, - final String value) { - ++size; - if (named) { - bv.putShort(cw.newUTF8(name)); - } - bv.put12('e', cw.newUTF8(desc)).putShort(cw.newUTF8(value)); - } - - @Override - public AnnotationVisitor visitAnnotation(final String name, - final String desc) { - ++size; - if (named) { - bv.putShort(cw.newUTF8(name)); - } - // write tag and type, and reserve space for values count - bv.put12('@', cw.newUTF8(desc)).putShort(0); - return new AnnotationWriter(cw, true, bv, bv, bv.length - 2); - } - - @Override - public AnnotationVisitor visitArray(final String name) { - ++size; - if (named) { - bv.putShort(cw.newUTF8(name)); - } - // write tag, and reserve space for array size - bv.put12('[', 0); - return new AnnotationWriter(cw, false, bv, bv, bv.length - 2); - } - - @Override - public void visitEnd() { - if (parent != null) { - byte[] data = parent.data; - data[offset] = (byte) (size >>> 8); - data[offset + 1] = (byte) size; - } - } - - // ------------------------------------------------------------------------ - // Utility methods - // ------------------------------------------------------------------------ - - /** - * Returns the size of this annotation writer list. - * - * @return the size of this annotation writer list. - */ - int getSize() { - int size = 0; - AnnotationWriter aw = this; - while (aw != null) { - size += aw.bv.length; - aw = aw.next; - } - return size; - } - - /** - * Puts the annotations of this annotation writer list into the given byte - * vector. - * - * @param out - * where the annotations must be put. - */ - void put(final ByteVector out) { - int n = 0; - int size = 2; - AnnotationWriter aw = this; - AnnotationWriter last = null; - while (aw != null) { - ++n; - size += aw.bv.length; - aw.visitEnd(); // in case user forgot to call visitEnd - aw.prev = last; - last = aw; - aw = aw.next; - } - out.putInt(size); - out.putShort(n); - aw = last; - while (aw != null) { - out.putByteArray(aw.bv.data, 0, aw.bv.length); - aw = aw.prev; - } - } - - /** - * Puts the given annotation lists into the given byte vector. - * - * @param panns - * an array of annotation writer lists. - * @param off - * index of the first annotation to be written. - * @param out - * where the annotations must be put. - */ - static void put(final AnnotationWriter[] panns, final int off, - final ByteVector out) { - int size = 1 + 2 * (panns.length - off); - for (int i = off; i < panns.length; ++i) { - size += panns[i] == null ? 0 : panns[i].getSize(); - } - out.putInt(size).putByte(panns.length - off); - for (int i = off; i < panns.length; ++i) { - AnnotationWriter aw = panns[i]; - AnnotationWriter last = null; - int n = 0; - while (aw != null) { - ++n; - aw.visitEnd(); // in case user forgot to call visitEnd - aw.prev = last; - last = aw; - aw = aw.next; - } - out.putShort(n); - aw = last; - while (aw != null) { - out.putByteArray(aw.bv.data, 0, aw.bv.length); - aw = aw.prev; - } - } - } - - /** - * Puts the given type reference and type path into the given bytevector. - * LOCAL_VARIABLE and RESOURCE_VARIABLE target types are not supported. - * - * @param typeRef - * a reference to the annotated type. See {@link TypeReference}. - * @param typePath - * the path to the annotated type argument, wildcard bound, array - * element type, or static inner type within 'typeRef'. May be - * null if the annotation targets 'typeRef' as a whole. - * @param out - * where the type reference and type path must be put. - */ - static void putTarget(int typeRef, TypePath typePath, ByteVector out) { - switch (typeRef >>> 24) { - case 0x00: // CLASS_TYPE_PARAMETER - case 0x01: // METHOD_TYPE_PARAMETER - case 0x16: // METHOD_FORMAL_PARAMETER - out.putShort(typeRef >>> 16); - break; - case 0x13: // FIELD - case 0x14: // METHOD_RETURN - case 0x15: // METHOD_RECEIVER - out.putByte(typeRef >>> 24); - break; - case 0x47: // CAST - case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT - case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT - case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT - case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT - out.putInt(typeRef); - break; - // case 0x10: // CLASS_EXTENDS - // case 0x11: // CLASS_TYPE_PARAMETER_BOUND - // case 0x12: // METHOD_TYPE_PARAMETER_BOUND - // case 0x17: // THROWS - // case 0x42: // EXCEPTION_PARAMETER - // case 0x43: // INSTANCEOF - // case 0x44: // NEW - // case 0x45: // CONSTRUCTOR_REFERENCE - // case 0x46: // METHOD_REFERENCE - default: - out.put12(typeRef >>> 24, (typeRef & 0xFFFF00) >> 8); - break; - } - if (typePath == null) { - out.putByte(0); - } else { - int length = typePath.b[typePath.offset] * 2 + 1; - out.putByteArray(typePath.b, typePath.offset, length); - } - } -} diff --git a/src/asm/scala/tools/asm/Attribute.java b/src/asm/scala/tools/asm/Attribute.java deleted file mode 100644 index ac40a758a2..0000000000 --- a/src/asm/scala/tools/asm/Attribute.java +++ /dev/null @@ -1,255 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm; - -/** - * A non standard class, field, method or code attribute. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -public class Attribute { - - /** - * The type of this attribute. - */ - public final String type; - - /** - * The raw value of this attribute, used only for unknown attributes. - */ - byte[] value; - - /** - * The next attribute in this attribute list. May be null. - */ - Attribute next; - - /** - * Constructs a new empty attribute. - * - * @param type - * the type of the attribute. - */ - protected Attribute(final String type) { - this.type = type; - } - - /** - * Returns true if this type of attribute is unknown. The default - * implementation of this method always returns true. - * - * @return true if this type of attribute is unknown. - */ - public boolean isUnknown() { - return true; - } - - /** - * Returns true if this type of attribute is a code attribute. - * - * @return true if this type of attribute is a code attribute. - */ - public boolean isCodeAttribute() { - return false; - } - - /** - * Returns the labels corresponding to this attribute. - * - * @return the labels corresponding to this attribute, or null if - * this attribute is not a code attribute that contains labels. - */ - protected Label[] getLabels() { - return null; - } - - /** - * Reads a {@link #type type} attribute. This method must return a - * new {@link Attribute} object, of type {@link #type type}, - * corresponding to the len bytes starting at the given offset, in - * the given class reader. - * - * @param cr - * the class that contains the attribute to be read. - * @param off - * index of the first byte of the attribute's content in - * {@link ClassReader#b cr.b}. The 6 attribute header bytes, - * containing the type and the length of the attribute, are not - * taken into account here. - * @param len - * the length of the attribute's content. - * @param buf - * buffer to be used to call {@link ClassReader#readUTF8 - * readUTF8}, {@link ClassReader#readClass(int,char[]) readClass} - * or {@link ClassReader#readConst readConst}. - * @param codeOff - * index of the first byte of code's attribute content in - * {@link ClassReader#b cr.b}, or -1 if the attribute to be read - * is not a code attribute. The 6 attribute header bytes, - * containing the type and the length of the attribute, are not - * taken into account here. - * @param labels - * the labels of the method's code, or null if the - * attribute to be read is not a code attribute. - * @return a new {@link Attribute} object corresponding to the given - * bytes. - */ - protected Attribute read(final ClassReader cr, final int off, - final int len, final char[] buf, final int codeOff, - final Label[] labels) { - Attribute attr = new Attribute(type); - attr.value = new byte[len]; - System.arraycopy(cr.b, off, attr.value, 0, len); - return attr; - } - - /** - * Returns the byte array form of this attribute. - * - * @param cw - * the class to which this attribute must be added. This - * parameter can be used to add to the constant pool of this - * class the items that corresponds to this attribute. - * @param code - * the bytecode of the method corresponding to this code - * attribute, or null if this attribute is not a code - * attributes. - * @param len - * the length of the bytecode of the method corresponding to this - * code attribute, or null if this attribute is not a - * code attribute. - * @param maxStack - * the maximum stack size of the method corresponding to this - * code attribute, or -1 if this attribute is not a code - * attribute. - * @param maxLocals - * the maximum number of local variables of the method - * corresponding to this code attribute, or -1 if this attribute - * is not a code attribute. - * @return the byte array form of this attribute. - */ - protected ByteVector write(final ClassWriter cw, final byte[] code, - final int len, final int maxStack, final int maxLocals) { - ByteVector v = new ByteVector(); - v.data = value; - v.length = value.length; - return v; - } - - /** - * Returns the length of the attribute list that begins with this attribute. - * - * @return the length of the attribute list that begins with this attribute. - */ - final int getCount() { - int count = 0; - Attribute attr = this; - while (attr != null) { - count += 1; - attr = attr.next; - } - return count; - } - - /** - * Returns the size of all the attributes in this attribute list. - * - * @param cw - * the class writer to be used to convert the attributes into - * byte arrays, with the {@link #write write} method. - * @param code - * the bytecode of the method corresponding to these code - * attributes, or null if these attributes are not code - * attributes. - * @param len - * the length of the bytecode of the method corresponding to - * these code attributes, or null if these attributes - * are not code attributes. - * @param maxStack - * the maximum stack size of the method corresponding to these - * code attributes, or -1 if these attributes are not code - * attributes. - * @param maxLocals - * the maximum number of local variables of the method - * corresponding to these code attributes, or -1 if these - * attributes are not code attributes. - * @return the size of all the attributes in this attribute list. This size - * includes the size of the attribute headers. - */ - final int getSize(final ClassWriter cw, final byte[] code, final int len, - final int maxStack, final int maxLocals) { - Attribute attr = this; - int size = 0; - while (attr != null) { - cw.newUTF8(attr.type); - size += attr.write(cw, code, len, maxStack, maxLocals).length + 6; - attr = attr.next; - } - return size; - } - - /** - * Writes all the attributes of this attribute list in the given byte - * vector. - * - * @param cw - * the class writer to be used to convert the attributes into - * byte arrays, with the {@link #write write} method. - * @param code - * the bytecode of the method corresponding to these code - * attributes, or null if these attributes are not code - * attributes. - * @param len - * the length of the bytecode of the method corresponding to - * these code attributes, or null if these attributes - * are not code attributes. - * @param maxStack - * the maximum stack size of the method corresponding to these - * code attributes, or -1 if these attributes are not code - * attributes. - * @param maxLocals - * the maximum number of local variables of the method - * corresponding to these code attributes, or -1 if these - * attributes are not code attributes. - * @param out - * where the attributes must be written. - */ - final void put(final ClassWriter cw, final byte[] code, final int len, - final int maxStack, final int maxLocals, final ByteVector out) { - Attribute attr = this; - while (attr != null) { - ByteVector b = attr.write(cw, code, len, maxStack, maxLocals); - out.putShort(cw.newUTF8(attr.type)).putInt(b.length); - out.putByteArray(b.data, 0, b.length); - attr = attr.next; - } - } -} diff --git a/src/asm/scala/tools/asm/ByteVector.java b/src/asm/scala/tools/asm/ByteVector.java deleted file mode 100644 index 3bca7af12a..0000000000 --- a/src/asm/scala/tools/asm/ByteVector.java +++ /dev/null @@ -1,339 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm; - -/** - * A dynamically extensible vector of bytes. This class is roughly equivalent to - * a DataOutputStream on top of a ByteArrayOutputStream, but is more efficient. - * - * @author Eric Bruneton - */ -public class ByteVector { - - /** - * The content of this vector. - */ - byte[] data; - - /** - * Actual number of bytes in this vector. - */ - int length; - - /** - * Constructs a new {@link ByteVector ByteVector} with a default initial - * size. - */ - public ByteVector() { - data = new byte[64]; - } - - /** - * Constructs a new {@link ByteVector ByteVector} with the given initial - * size. - * - * @param initialSize - * the initial size of the byte vector to be constructed. - */ - public ByteVector(final int initialSize) { - data = new byte[initialSize]; - } - - /** - * Puts a byte into this byte vector. The byte vector is automatically - * enlarged if necessary. - * - * @param b - * a byte. - * @return this byte vector. - */ - public ByteVector putByte(final int b) { - int length = this.length; - if (length + 1 > data.length) { - enlarge(1); - } - data[length++] = (byte) b; - this.length = length; - return this; - } - - /** - * Puts two bytes into this byte vector. The byte vector is automatically - * enlarged if necessary. - * - * @param b1 - * a byte. - * @param b2 - * another byte. - * @return this byte vector. - */ - ByteVector put11(final int b1, final int b2) { - int length = this.length; - if (length + 2 > data.length) { - enlarge(2); - } - byte[] data = this.data; - data[length++] = (byte) b1; - data[length++] = (byte) b2; - this.length = length; - return this; - } - - /** - * Puts a short into this byte vector. The byte vector is automatically - * enlarged if necessary. - * - * @param s - * a short. - * @return this byte vector. - */ - public ByteVector putShort(final int s) { - int length = this.length; - if (length + 2 > data.length) { - enlarge(2); - } - byte[] data = this.data; - data[length++] = (byte) (s >>> 8); - data[length++] = (byte) s; - this.length = length; - return this; - } - - /** - * Puts a byte and a short into this byte vector. The byte vector is - * automatically enlarged if necessary. - * - * @param b - * a byte. - * @param s - * a short. - * @return this byte vector. - */ - ByteVector put12(final int b, final int s) { - int length = this.length; - if (length + 3 > data.length) { - enlarge(3); - } - byte[] data = this.data; - data[length++] = (byte) b; - data[length++] = (byte) (s >>> 8); - data[length++] = (byte) s; - this.length = length; - return this; - } - - /** - * Puts an int into this byte vector. The byte vector is automatically - * enlarged if necessary. - * - * @param i - * an int. - * @return this byte vector. - */ - public ByteVector putInt(final int i) { - int length = this.length; - if (length + 4 > data.length) { - enlarge(4); - } - byte[] data = this.data; - data[length++] = (byte) (i >>> 24); - data[length++] = (byte) (i >>> 16); - data[length++] = (byte) (i >>> 8); - data[length++] = (byte) i; - this.length = length; - return this; - } - - /** - * Puts a long into this byte vector. The byte vector is automatically - * enlarged if necessary. - * - * @param l - * a long. - * @return this byte vector. - */ - public ByteVector putLong(final long l) { - int length = this.length; - if (length + 8 > data.length) { - enlarge(8); - } - byte[] data = this.data; - int i = (int) (l >>> 32); - data[length++] = (byte) (i >>> 24); - data[length++] = (byte) (i >>> 16); - data[length++] = (byte) (i >>> 8); - data[length++] = (byte) i; - i = (int) l; - data[length++] = (byte) (i >>> 24); - data[length++] = (byte) (i >>> 16); - data[length++] = (byte) (i >>> 8); - data[length++] = (byte) i; - this.length = length; - return this; - } - - /** - * Puts an UTF8 string into this byte vector. The byte vector is - * automatically enlarged if necessary. - * - * @param s - * a String whose UTF8 encoded length must be less than 65536. - * @return this byte vector. - */ - public ByteVector putUTF8(final String s) { - int charLength = s.length(); - if (charLength > 65535) { - throw new IllegalArgumentException(); - } - int len = length; - if (len + 2 + charLength > data.length) { - enlarge(2 + charLength); - } - byte[] data = this.data; - // optimistic algorithm: instead of computing the byte length and then - // serializing the string (which requires two loops), we assume the byte - // length is equal to char length (which is the most frequent case), and - // we start serializing the string right away. During the serialization, - // if we find that this assumption is wrong, we continue with the - // general method. - data[len++] = (byte) (charLength >>> 8); - data[len++] = (byte) charLength; - for (int i = 0; i < charLength; ++i) { - char c = s.charAt(i); - if (c >= '\001' && c <= '\177') { - data[len++] = (byte) c; - } else { - length = len; - return encodeUTF8(s, i, 65535); - } - } - length = len; - return this; - } - - /** - * Puts an UTF8 string into this byte vector. The byte vector is - * automatically enlarged if necessary. The string length is encoded in two - * bytes before the encoded characters, if there is space for that (i.e. if - * this.length - i - 2 >= 0). - * - * @param s - * the String to encode. - * @param i - * the index of the first character to encode. The previous - * characters are supposed to have already been encoded, using - * only one byte per character. - * @param maxByteLength - * the maximum byte length of the encoded string, including the - * already encoded characters. - * @return this byte vector. - */ - ByteVector encodeUTF8(final String s, int i, int maxByteLength) { - int charLength = s.length(); - int byteLength = i; - char c; - for (int j = i; j < charLength; ++j) { - c = s.charAt(j); - if (c >= '\001' && c <= '\177') { - byteLength++; - } else if (c > '\u07FF') { - byteLength += 3; - } else { - byteLength += 2; - } - } - if (byteLength > maxByteLength) { - throw new IllegalArgumentException(); - } - int start = length - i - 2; - if (start >= 0) { - data[start] = (byte) (byteLength >>> 8); - data[start + 1] = (byte) byteLength; - } - if (length + byteLength - i > data.length) { - enlarge(byteLength - i); - } - int len = length; - for (int j = i; j < charLength; ++j) { - c = s.charAt(j); - if (c >= '\001' && c <= '\177') { - data[len++] = (byte) c; - } else if (c > '\u07FF') { - data[len++] = (byte) (0xE0 | c >> 12 & 0xF); - data[len++] = (byte) (0x80 | c >> 6 & 0x3F); - data[len++] = (byte) (0x80 | c & 0x3F); - } else { - data[len++] = (byte) (0xC0 | c >> 6 & 0x1F); - data[len++] = (byte) (0x80 | c & 0x3F); - } - } - length = len; - return this; - } - - /** - * Puts an array of bytes into this byte vector. The byte vector is - * automatically enlarged if necessary. - * - * @param b - * an array of bytes. May be null to put len - * null bytes into this byte vector. - * @param off - * index of the fist byte of b that must be copied. - * @param len - * number of bytes of b that must be copied. - * @return this byte vector. - */ - public ByteVector putByteArray(final byte[] b, final int off, final int len) { - if (length + len > data.length) { - enlarge(len); - } - if (b != null) { - System.arraycopy(b, off, data, length, len); - } - length += len; - return this; - } - - /** - * Enlarge this byte vector so that it can receive n more bytes. - * - * @param size - * number of additional bytes that this byte vector should be - * able to receive. - */ - private void enlarge(final int size) { - int length1 = 2 * data.length; - int length2 = length + size; - byte[] newData = new byte[length1 > length2 ? length1 : length2]; - System.arraycopy(data, 0, newData, 0, length); - data = newData; - } -} diff --git a/src/asm/scala/tools/asm/ClassReader.java b/src/asm/scala/tools/asm/ClassReader.java deleted file mode 100644 index 8b0e12cb04..0000000000 --- a/src/asm/scala/tools/asm/ClassReader.java +++ /dev/null @@ -1,2496 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm; - -import java.io.IOException; -import java.io.InputStream; - -/** - * A Java class parser to make a {@link ClassVisitor} visit an existing class. - * This class parses a byte array conforming to the Java class file format and - * calls the appropriate visit methods of a given class visitor for each field, - * method and bytecode instruction encountered. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -public class ClassReader { - - /** - * True to enable signatures support. - */ - static final boolean SIGNATURES = true; - - /** - * True to enable annotations support. - */ - static final boolean ANNOTATIONS = true; - - /** - * True to enable stack map frames support. - */ - static final boolean FRAMES = true; - - /** - * True to enable bytecode writing support. - */ - static final boolean WRITER = true; - - /** - * True to enable JSR_W and GOTO_W support. - */ - static final boolean RESIZE = true; - - /** - * Flag to skip method code. If this class is set CODE - * attribute won't be visited. This can be used, for example, to retrieve - * annotations for methods and method parameters. - */ - public static final int SKIP_CODE = 1; - - /** - * Flag to skip the debug information in the class. If this flag is set the - * debug information of the class is not visited, i.e. the - * {@link MethodVisitor#visitLocalVariable visitLocalVariable} and - * {@link MethodVisitor#visitLineNumber visitLineNumber} methods will not be - * called. - */ - public static final int SKIP_DEBUG = 2; - - /** - * Flag to skip the stack map frames in the class. If this flag is set the - * stack map frames of the class is not visited, i.e. the - * {@link MethodVisitor#visitFrame visitFrame} method will not be called. - * This flag is useful when the {@link ClassWriter#COMPUTE_FRAMES} option is - * used: it avoids visiting frames that will be ignored and recomputed from - * scratch in the class writer. - */ - public static final int SKIP_FRAMES = 4; - - /** - * Flag to expand the stack map frames. By default stack map frames are - * visited in their original format (i.e. "expanded" for classes whose - * version is less than V1_6, and "compressed" for the other classes). If - * this flag is set, stack map frames are always visited in expanded format - * (this option adds a decompression/recompression step in ClassReader and - * ClassWriter which degrades performances quite a lot). - */ - public static final int EXPAND_FRAMES = 8; - - /** - * The class to be parsed. The content of this array must not be - * modified. This field is intended for {@link Attribute} sub classes, and - * is normally not needed by class generators or adapters. - */ - public final byte[] b; - - /** - * The start index of each constant pool item in {@link #b b}, plus one. The - * one byte offset skips the constant pool item tag that indicates its type. - */ - private final int[] items; - - /** - * The String objects corresponding to the CONSTANT_Utf8 items. This cache - * avoids multiple parsing of a given CONSTANT_Utf8 constant pool item, - * which GREATLY improves performances (by a factor 2 to 3). This caching - * strategy could be extended to all constant pool items, but its benefit - * would not be so great for these items (because they are much less - * expensive to parse than CONSTANT_Utf8 items). - */ - private final String[] strings; - - /** - * Maximum length of the strings contained in the constant pool of the - * class. - */ - private final int maxStringLength; - - /** - * Start index of the class header information (access, name...) in - * {@link #b b}. - */ - public final int header; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructs a new {@link ClassReader} object. - * - * @param b - * the bytecode of the class to be read. - */ - public ClassReader(final byte[] b) { - this(b, 0, b.length); - } - - /** - * Constructs a new {@link ClassReader} object. - * - * @param b - * the bytecode of the class to be read. - * @param off - * the start offset of the class data. - * @param len - * the length of the class data. - */ - public ClassReader(final byte[] b, final int off, final int len) { - this.b = b; - // checks the class version - if (readShort(off + 6) > Opcodes.V1_8) { - throw new IllegalArgumentException(); - } - // parses the constant pool - items = new int[readUnsignedShort(off + 8)]; - int n = items.length; - strings = new String[n]; - int max = 0; - int index = off + 10; - for (int i = 1; i < n; ++i) { - items[i] = index + 1; - int size; - switch (b[index]) { - case ClassWriter.FIELD: - case ClassWriter.METH: - case ClassWriter.IMETH: - case ClassWriter.INT: - case ClassWriter.FLOAT: - case ClassWriter.NAME_TYPE: - case ClassWriter.INDY: - size = 5; - break; - case ClassWriter.LONG: - case ClassWriter.DOUBLE: - size = 9; - ++i; - break; - case ClassWriter.UTF8: - size = 3 + readUnsignedShort(index + 1); - if (size > max) { - max = size; - } - break; - case ClassWriter.HANDLE: - size = 4; - break; - // case ClassWriter.CLASS: - // case ClassWriter.STR: - // case ClassWriter.MTYPE - default: - size = 3; - break; - } - index += size; - } - maxStringLength = max; - // the class header information starts just after the constant pool - header = index; - } - - /** - * Returns the class's access flags (see {@link Opcodes}). This value may - * not reflect Deprecated and Synthetic flags when bytecode is before 1.5 - * and those flags are represented by attributes. - * - * @return the class access flags - * - * @see ClassVisitor#visit(int, int, String, String, String, String[]) - */ - public int getAccess() { - return readUnsignedShort(header); - } - - /** - * Returns the internal name of the class (see - * {@link Type#getInternalName() getInternalName}). - * - * @return the internal class name - * - * @see ClassVisitor#visit(int, int, String, String, String, String[]) - */ - public String getClassName() { - return readClass(header + 2, new char[maxStringLength]); - } - - /** - * Returns the internal of name of the super class (see - * {@link Type#getInternalName() getInternalName}). For interfaces, the - * super class is {@link Object}. - * - * @return the internal name of super class, or null for - * {@link Object} class. - * - * @see ClassVisitor#visit(int, int, String, String, String, String[]) - */ - public String getSuperName() { - return readClass(header + 4, new char[maxStringLength]); - } - - /** - * Returns the internal names of the class's interfaces (see - * {@link Type#getInternalName() getInternalName}). - * - * @return the array of internal names for all implemented interfaces or - * null. - * - * @see ClassVisitor#visit(int, int, String, String, String, String[]) - */ - public String[] getInterfaces() { - int index = header + 6; - int n = readUnsignedShort(index); - String[] interfaces = new String[n]; - if (n > 0) { - char[] buf = new char[maxStringLength]; - for (int i = 0; i < n; ++i) { - index += 2; - interfaces[i] = readClass(index, buf); - } - } - return interfaces; - } - - /** - * Copies the constant pool data into the given {@link ClassWriter}. Should - * be called before the {@link #accept(ClassVisitor,int)} method. - * - * @param classWriter - * the {@link ClassWriter} to copy constant pool into. - */ - void copyPool(final ClassWriter classWriter) { - char[] buf = new char[maxStringLength]; - int ll = items.length; - Item[] items2 = new Item[ll]; - for (int i = 1; i < ll; i++) { - int index = items[i]; - int tag = b[index - 1]; - Item item = new Item(i); - int nameType; - switch (tag) { - case ClassWriter.FIELD: - case ClassWriter.METH: - case ClassWriter.IMETH: - nameType = items[readUnsignedShort(index + 2)]; - item.set(tag, readClass(index, buf), readUTF8(nameType, buf), - readUTF8(nameType + 2, buf)); - break; - case ClassWriter.INT: - item.set(readInt(index)); - break; - case ClassWriter.FLOAT: - item.set(Float.intBitsToFloat(readInt(index))); - break; - case ClassWriter.NAME_TYPE: - item.set(tag, readUTF8(index, buf), readUTF8(index + 2, buf), - null); - break; - case ClassWriter.LONG: - item.set(readLong(index)); - ++i; - break; - case ClassWriter.DOUBLE: - item.set(Double.longBitsToDouble(readLong(index))); - ++i; - break; - case ClassWriter.UTF8: { - String s = strings[i]; - if (s == null) { - index = items[i]; - s = strings[i] = readUTF(index + 2, - readUnsignedShort(index), buf); - } - item.set(tag, s, null, null); - break; - } - case ClassWriter.HANDLE: { - int fieldOrMethodRef = items[readUnsignedShort(index + 1)]; - nameType = items[readUnsignedShort(fieldOrMethodRef + 2)]; - item.set(ClassWriter.HANDLE_BASE + readByte(index), - readClass(fieldOrMethodRef, buf), - readUTF8(nameType, buf), readUTF8(nameType + 2, buf)); - break; - } - case ClassWriter.INDY: - if (classWriter.bootstrapMethods == null) { - copyBootstrapMethods(classWriter, items2, buf); - } - nameType = items[readUnsignedShort(index + 2)]; - item.set(readUTF8(nameType, buf), readUTF8(nameType + 2, buf), - readUnsignedShort(index)); - break; - // case ClassWriter.STR: - // case ClassWriter.CLASS: - // case ClassWriter.MTYPE - default: - item.set(tag, readUTF8(index, buf), null, null); - break; - } - - int index2 = item.hashCode % items2.length; - item.next = items2[index2]; - items2[index2] = item; - } - - int off = items[1] - 1; - classWriter.pool.putByteArray(b, off, header - off); - classWriter.items = items2; - classWriter.threshold = (int) (0.75d * ll); - classWriter.index = ll; - } - - /** - * Copies the bootstrap method data into the given {@link ClassWriter}. - * Should be called before the {@link #accept(ClassVisitor,int)} method. - * - * @param classWriter - * the {@link ClassWriter} to copy bootstrap methods into. - */ - private void copyBootstrapMethods(final ClassWriter classWriter, - final Item[] items, final char[] c) { - // finds the "BootstrapMethods" attribute - int u = getAttributes(); - boolean found = false; - for (int i = readUnsignedShort(u); i > 0; --i) { - String attrName = readUTF8(u + 2, c); - if ("BootstrapMethods".equals(attrName)) { - found = true; - break; - } - u += 6 + readInt(u + 4); - } - if (!found) { - return; - } - // copies the bootstrap methods in the class writer - int boostrapMethodCount = readUnsignedShort(u + 8); - for (int j = 0, v = u + 10; j < boostrapMethodCount; j++) { - int position = v - u - 10; - int hashCode = readConst(readUnsignedShort(v), c).hashCode(); - for (int k = readUnsignedShort(v + 2); k > 0; --k) { - hashCode ^= readConst(readUnsignedShort(v + 4), c).hashCode(); - v += 2; - } - v += 4; - Item item = new Item(j); - item.set(position, hashCode & 0x7FFFFFFF); - int index = item.hashCode % items.length; - item.next = items[index]; - items[index] = item; - } - int attrSize = readInt(u + 4); - ByteVector bootstrapMethods = new ByteVector(attrSize + 62); - bootstrapMethods.putByteArray(b, u + 10, attrSize - 2); - classWriter.bootstrapMethodsCount = boostrapMethodCount; - classWriter.bootstrapMethods = bootstrapMethods; - } - - /** - * Constructs a new {@link ClassReader} object. - * - * @param is - * an input stream from which to read the class. - * @throws IOException - * if a problem occurs during reading. - */ - public ClassReader(final InputStream is) throws IOException { - this(readClass(is, false)); - } - - /** - * Constructs a new {@link ClassReader} object. - * - * @param name - * the binary qualified name of the class to be read. - * @throws IOException - * if an exception occurs during reading. - */ - public ClassReader(final String name) throws IOException { - this(readClass( - ClassLoader.getSystemResourceAsStream(name.replace('.', '/') - + ".class"), true)); - } - - /** - * Reads the bytecode of a class. - * - * @param is - * an input stream from which to read the class. - * @param close - * true to close the input stream after reading. - * @return the bytecode read from the given input stream. - * @throws IOException - * if a problem occurs during reading. - */ - private static byte[] readClass(final InputStream is, boolean close) - throws IOException { - if (is == null) { - throw new IOException("Class not found"); - } - try { - byte[] b = new byte[is.available()]; - int len = 0; - while (true) { - int n = is.read(b, len, b.length - len); - if (n == -1) { - if (len < b.length) { - byte[] c = new byte[len]; - System.arraycopy(b, 0, c, 0, len); - b = c; - } - return b; - } - len += n; - if (len == b.length) { - int last = is.read(); - if (last < 0) { - return b; - } - byte[] c = new byte[b.length + 1000]; - System.arraycopy(b, 0, c, 0, len); - c[len++] = (byte) last; - b = c; - } - } - } finally { - if (close) { - is.close(); - } - } - } - - // ------------------------------------------------------------------------ - // Public methods - // ------------------------------------------------------------------------ - - /** - * Makes the given visitor visit the Java class of this {@link ClassReader} - * . This class is the one specified in the constructor (see - * {@link #ClassReader(byte[]) ClassReader}). - * - * @param classVisitor - * the visitor that must visit this class. - * @param flags - * option flags that can be used to modify the default behavior - * of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES} - * , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}. - */ - public void accept(final ClassVisitor classVisitor, final int flags) { - accept(classVisitor, new Attribute[0], flags); - } - - /** - * Makes the given visitor visit the Java class of this {@link ClassReader}. - * This class is the one specified in the constructor (see - * {@link #ClassReader(byte[]) ClassReader}). - * - * @param classVisitor - * the visitor that must visit this class. - * @param attrs - * prototypes of the attributes that must be parsed during the - * visit of the class. Any attribute whose type is not equal to - * the type of one the prototypes will not be parsed: its byte - * array value will be passed unchanged to the ClassWriter. - * This may corrupt it if this value contains references to - * the constant pool, or has syntactic or semantic links with a - * class element that has been transformed by a class adapter - * between the reader and the writer. - * @param flags - * option flags that can be used to modify the default behavior - * of this class. See {@link #SKIP_DEBUG}, {@link #EXPAND_FRAMES} - * , {@link #SKIP_FRAMES}, {@link #SKIP_CODE}. - */ - public void accept(final ClassVisitor classVisitor, - final Attribute[] attrs, final int flags) { - int u = header; // current offset in the class file - char[] c = new char[maxStringLength]; // buffer used to read strings - - Context context = new Context(); - context.attrs = attrs; - context.flags = flags; - context.buffer = c; - - // reads the class declaration - int access = readUnsignedShort(u); - String name = readClass(u + 2, c); - String superClass = readClass(u + 4, c); - String[] interfaces = new String[readUnsignedShort(u + 6)]; - u += 8; - for (int i = 0; i < interfaces.length; ++i) { - interfaces[i] = readClass(u, c); - u += 2; - } - - // reads the class attributes - String signature = null; - String sourceFile = null; - String sourceDebug = null; - String enclosingOwner = null; - String enclosingName = null; - String enclosingDesc = null; - int anns = 0; - int ianns = 0; - int tanns = 0; - int itanns = 0; - int innerClasses = 0; - Attribute attributes = null; - - u = getAttributes(); - for (int i = readUnsignedShort(u); i > 0; --i) { - String attrName = readUTF8(u + 2, c); - // tests are sorted in decreasing frequency order - // (based on frequencies observed on typical classes) - if ("SourceFile".equals(attrName)) { - sourceFile = readUTF8(u + 8, c); - } else if ("InnerClasses".equals(attrName)) { - innerClasses = u + 8; - } else if ("EnclosingMethod".equals(attrName)) { - enclosingOwner = readClass(u + 8, c); - int item = readUnsignedShort(u + 10); - if (item != 0) { - enclosingName = readUTF8(items[item], c); - enclosingDesc = readUTF8(items[item] + 2, c); - } - } else if (SIGNATURES && "Signature".equals(attrName)) { - signature = readUTF8(u + 8, c); - } else if (ANNOTATIONS - && "RuntimeVisibleAnnotations".equals(attrName)) { - anns = u + 8; - } else if (ANNOTATIONS - && "RuntimeVisibleTypeAnnotations".equals(attrName)) { - tanns = u + 8; - } else if ("Deprecated".equals(attrName)) { - access |= Opcodes.ACC_DEPRECATED; - } else if ("Synthetic".equals(attrName)) { - access |= Opcodes.ACC_SYNTHETIC - | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE; - } else if ("SourceDebugExtension".equals(attrName)) { - int len = readInt(u + 4); - sourceDebug = readUTF(u + 8, len, new char[len]); - } else if (ANNOTATIONS - && "RuntimeInvisibleAnnotations".equals(attrName)) { - ianns = u + 8; - } else if (ANNOTATIONS - && "RuntimeInvisibleTypeAnnotations".equals(attrName)) { - itanns = u + 8; - } else if ("BootstrapMethods".equals(attrName)) { - int[] bootstrapMethods = new int[readUnsignedShort(u + 8)]; - for (int j = 0, v = u + 10; j < bootstrapMethods.length; j++) { - bootstrapMethods[j] = v; - v += 2 + readUnsignedShort(v + 2) << 1; - } - context.bootstrapMethods = bootstrapMethods; - } else { - Attribute attr = readAttribute(attrs, attrName, u + 8, - readInt(u + 4), c, -1, null); - if (attr != null) { - attr.next = attributes; - attributes = attr; - } - } - u += 6 + readInt(u + 4); - } - - // visits the class declaration - classVisitor.visit(readInt(items[1] - 7), access, name, signature, - superClass, interfaces); - - // visits the source and debug info - if ((flags & SKIP_DEBUG) == 0 - && (sourceFile != null || sourceDebug != null)) { - classVisitor.visitSource(sourceFile, sourceDebug); - } - - // visits the outer class - if (enclosingOwner != null) { - classVisitor.visitOuterClass(enclosingOwner, enclosingName, - enclosingDesc); - } - - // visits the class annotations and type annotations - if (ANNOTATIONS && anns != 0) { - for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) { - v = readAnnotationValues(v + 2, c, true, - classVisitor.visitAnnotation(readUTF8(v, c), true)); - } - } - if (ANNOTATIONS && ianns != 0) { - for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) { - v = readAnnotationValues(v + 2, c, true, - classVisitor.visitAnnotation(readUTF8(v, c), false)); - } - } - if (ANNOTATIONS && tanns != 0) { - for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) { - v = readAnnotationTarget(context, v); - v = readAnnotationValues(v + 2, c, true, - classVisitor.visitTypeAnnotation(context.typeRef, - context.typePath, readUTF8(v, c), true)); - } - } - if (ANNOTATIONS && itanns != 0) { - for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) { - v = readAnnotationTarget(context, v); - v = readAnnotationValues(v + 2, c, true, - classVisitor.visitTypeAnnotation(context.typeRef, - context.typePath, readUTF8(v, c), false)); - } - } - - // visits the attributes - while (attributes != null) { - Attribute attr = attributes.next; - attributes.next = null; - classVisitor.visitAttribute(attributes); - attributes = attr; - } - - // visits the inner classes - if (innerClasses != 0) { - int v = innerClasses + 2; - for (int i = readUnsignedShort(innerClasses); i > 0; --i) { - classVisitor.visitInnerClass(readClass(v, c), - readClass(v + 2, c), readUTF8(v + 4, c), - readUnsignedShort(v + 6)); - v += 8; - } - } - - // visits the fields and methods - u = header + 10 + 2 * interfaces.length; - for (int i = readUnsignedShort(u - 2); i > 0; --i) { - u = readField(classVisitor, context, u); - } - u += 2; - for (int i = readUnsignedShort(u - 2); i > 0; --i) { - u = readMethod(classVisitor, context, u); - } - - // visits the end of the class - classVisitor.visitEnd(); - } - - /** - * Reads a field and makes the given visitor visit it. - * - * @param classVisitor - * the visitor that must visit the field. - * @param context - * information about the class being parsed. - * @param u - * the start offset of the field in the class file. - * @return the offset of the first byte following the field in the class. - */ - private int readField(final ClassVisitor classVisitor, - final Context context, int u) { - // reads the field declaration - char[] c = context.buffer; - int access = readUnsignedShort(u); - String name = readUTF8(u + 2, c); - String desc = readUTF8(u + 4, c); - u += 6; - - // reads the field attributes - String signature = null; - int anns = 0; - int ianns = 0; - int tanns = 0; - int itanns = 0; - Object value = null; - Attribute attributes = null; - - for (int i = readUnsignedShort(u); i > 0; --i) { - String attrName = readUTF8(u + 2, c); - // tests are sorted in decreasing frequency order - // (based on frequencies observed on typical classes) - if ("ConstantValue".equals(attrName)) { - int item = readUnsignedShort(u + 8); - value = item == 0 ? null : readConst(item, c); - } else if (SIGNATURES && "Signature".equals(attrName)) { - signature = readUTF8(u + 8, c); - } else if ("Deprecated".equals(attrName)) { - access |= Opcodes.ACC_DEPRECATED; - } else if ("Synthetic".equals(attrName)) { - access |= Opcodes.ACC_SYNTHETIC - | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE; - } else if (ANNOTATIONS - && "RuntimeVisibleAnnotations".equals(attrName)) { - anns = u + 8; - } else if (ANNOTATIONS - && "RuntimeVisibleTypeAnnotations".equals(attrName)) { - tanns = u + 8; - } else if (ANNOTATIONS - && "RuntimeInvisibleAnnotations".equals(attrName)) { - ianns = u + 8; - } else if (ANNOTATIONS - && "RuntimeInvisibleTypeAnnotations".equals(attrName)) { - itanns = u + 8; - } else { - Attribute attr = readAttribute(context.attrs, attrName, u + 8, - readInt(u + 4), c, -1, null); - if (attr != null) { - attr.next = attributes; - attributes = attr; - } - } - u += 6 + readInt(u + 4); - } - u += 2; - - // visits the field declaration - FieldVisitor fv = classVisitor.visitField(access, name, desc, - signature, value); - if (fv == null) { - return u; - } - - // visits the field annotations and type annotations - if (ANNOTATIONS && anns != 0) { - for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) { - v = readAnnotationValues(v + 2, c, true, - fv.visitAnnotation(readUTF8(v, c), true)); - } - } - if (ANNOTATIONS && ianns != 0) { - for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) { - v = readAnnotationValues(v + 2, c, true, - fv.visitAnnotation(readUTF8(v, c), false)); - } - } - if (ANNOTATIONS && tanns != 0) { - for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) { - v = readAnnotationTarget(context, v); - v = readAnnotationValues(v + 2, c, true, - fv.visitTypeAnnotation(context.typeRef, - context.typePath, readUTF8(v, c), true)); - } - } - if (ANNOTATIONS && itanns != 0) { - for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) { - v = readAnnotationTarget(context, v); - v = readAnnotationValues(v + 2, c, true, - fv.visitTypeAnnotation(context.typeRef, - context.typePath, readUTF8(v, c), false)); - } - } - - // visits the field attributes - while (attributes != null) { - Attribute attr = attributes.next; - attributes.next = null; - fv.visitAttribute(attributes); - attributes = attr; - } - - // visits the end of the field - fv.visitEnd(); - - return u; - } - - /** - * Reads a method and makes the given visitor visit it. - * - * @param classVisitor - * the visitor that must visit the method. - * @param context - * information about the class being parsed. - * @param u - * the start offset of the method in the class file. - * @return the offset of the first byte following the method in the class. - */ - private int readMethod(final ClassVisitor classVisitor, - final Context context, int u) { - // reads the method declaration - char[] c = context.buffer; - context.access = readUnsignedShort(u); - context.name = readUTF8(u + 2, c); - context.desc = readUTF8(u + 4, c); - u += 6; - - // reads the method attributes - int code = 0; - int exception = 0; - String[] exceptions = null; - String signature = null; - int methodParameters = 0; - int anns = 0; - int ianns = 0; - int tanns = 0; - int itanns = 0; - int dann = 0; - int mpanns = 0; - int impanns = 0; - int firstAttribute = u; - Attribute attributes = null; - - for (int i = readUnsignedShort(u); i > 0; --i) { - String attrName = readUTF8(u + 2, c); - // tests are sorted in decreasing frequency order - // (based on frequencies observed on typical classes) - if ("Code".equals(attrName)) { - if ((context.flags & SKIP_CODE) == 0) { - code = u + 8; - } - } else if ("Exceptions".equals(attrName)) { - exceptions = new String[readUnsignedShort(u + 8)]; - exception = u + 10; - for (int j = 0; j < exceptions.length; ++j) { - exceptions[j] = readClass(exception, c); - exception += 2; - } - } else if (SIGNATURES && "Signature".equals(attrName)) { - signature = readUTF8(u + 8, c); - } else if ("Deprecated".equals(attrName)) { - context.access |= Opcodes.ACC_DEPRECATED; - } else if (ANNOTATIONS - && "RuntimeVisibleAnnotations".equals(attrName)) { - anns = u + 8; - } else if (ANNOTATIONS - && "RuntimeVisibleTypeAnnotations".equals(attrName)) { - tanns = u + 8; - } else if (ANNOTATIONS && "AnnotationDefault".equals(attrName)) { - dann = u + 8; - } else if ("Synthetic".equals(attrName)) { - context.access |= Opcodes.ACC_SYNTHETIC - | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE; - } else if (ANNOTATIONS - && "RuntimeInvisibleAnnotations".equals(attrName)) { - ianns = u + 8; - } else if (ANNOTATIONS - && "RuntimeInvisibleTypeAnnotations".equals(attrName)) { - itanns = u + 8; - } else if (ANNOTATIONS - && "RuntimeVisibleParameterAnnotations".equals(attrName)) { - mpanns = u + 8; - } else if (ANNOTATIONS - && "RuntimeInvisibleParameterAnnotations".equals(attrName)) { - impanns = u + 8; - } else if ("MethodParameters".equals(attrName)) { - methodParameters = u + 8; - } else { - Attribute attr = readAttribute(context.attrs, attrName, u + 8, - readInt(u + 4), c, -1, null); - if (attr != null) { - attr.next = attributes; - attributes = attr; - } - } - u += 6 + readInt(u + 4); - } - u += 2; - - // visits the method declaration - MethodVisitor mv = classVisitor.visitMethod(context.access, - context.name, context.desc, signature, exceptions); - if (mv == null) { - return u; - } - - /* - * if the returned MethodVisitor is in fact a MethodWriter, it means - * there is no method adapter between the reader and the writer. If, in - * addition, the writer's constant pool was copied from this reader - * (mw.cw.cr == this), and the signature and exceptions of the method - * have not been changed, then it is possible to skip all visit events - * and just copy the original code of the method to the writer (the - * access, name and descriptor can have been changed, this is not - * important since they are not copied as is from the reader). - */ - if (WRITER && mv instanceof MethodWriter) { - MethodWriter mw = (MethodWriter) mv; - if (mw.cw.cr == this && signature == mw.signature) { - boolean sameExceptions = false; - if (exceptions == null) { - sameExceptions = mw.exceptionCount == 0; - } else if (exceptions.length == mw.exceptionCount) { - sameExceptions = true; - for (int j = exceptions.length - 1; j >= 0; --j) { - exception -= 2; - if (mw.exceptions[j] != readUnsignedShort(exception)) { - sameExceptions = false; - break; - } - } - } - if (sameExceptions) { - /* - * we do not copy directly the code into MethodWriter to - * save a byte array copy operation. The real copy will be - * done in ClassWriter.toByteArray(). - */ - mw.classReaderOffset = firstAttribute; - mw.classReaderLength = u - firstAttribute; - return u; - } - } - } - - // visit the method parameters - if (methodParameters != 0) { - for (int i = b[methodParameters] & 0xFF, v = methodParameters + 1; i > 0; --i, v = v + 4) { - mv.visitParameter(readUTF8(v, c), readUnsignedShort(v + 2)); - } - } - - // visits the method annotations - if (ANNOTATIONS && dann != 0) { - AnnotationVisitor dv = mv.visitAnnotationDefault(); - readAnnotationValue(dann, c, null, dv); - if (dv != null) { - dv.visitEnd(); - } - } - if (ANNOTATIONS && anns != 0) { - for (int i = readUnsignedShort(anns), v = anns + 2; i > 0; --i) { - v = readAnnotationValues(v + 2, c, true, - mv.visitAnnotation(readUTF8(v, c), true)); - } - } - if (ANNOTATIONS && ianns != 0) { - for (int i = readUnsignedShort(ianns), v = ianns + 2; i > 0; --i) { - v = readAnnotationValues(v + 2, c, true, - mv.visitAnnotation(readUTF8(v, c), false)); - } - } - if (ANNOTATIONS && tanns != 0) { - for (int i = readUnsignedShort(tanns), v = tanns + 2; i > 0; --i) { - v = readAnnotationTarget(context, v); - v = readAnnotationValues(v + 2, c, true, - mv.visitTypeAnnotation(context.typeRef, - context.typePath, readUTF8(v, c), true)); - } - } - if (ANNOTATIONS && itanns != 0) { - for (int i = readUnsignedShort(itanns), v = itanns + 2; i > 0; --i) { - v = readAnnotationTarget(context, v); - v = readAnnotationValues(v + 2, c, true, - mv.visitTypeAnnotation(context.typeRef, - context.typePath, readUTF8(v, c), false)); - } - } - if (ANNOTATIONS && mpanns != 0) { - readParameterAnnotations(mv, context, mpanns, true); - } - if (ANNOTATIONS && impanns != 0) { - readParameterAnnotations(mv, context, impanns, false); - } - - // visits the method attributes - while (attributes != null) { - Attribute attr = attributes.next; - attributes.next = null; - mv.visitAttribute(attributes); - attributes = attr; - } - - // visits the method code - if (code != 0) { - mv.visitCode(); - readCode(mv, context, code); - } - - // visits the end of the method - mv.visitEnd(); - - return u; - } - - /** - * Reads the bytecode of a method and makes the given visitor visit it. - * - * @param mv - * the visitor that must visit the method's code. - * @param context - * information about the class being parsed. - * @param u - * the start offset of the code attribute in the class file. - */ - private void readCode(final MethodVisitor mv, final Context context, int u) { - // reads the header - byte[] b = this.b; - char[] c = context.buffer; - int maxStack = readUnsignedShort(u); - int maxLocals = readUnsignedShort(u + 2); - int codeLength = readInt(u + 4); - u += 8; - - // reads the bytecode to find the labels - int codeStart = u; - int codeEnd = u + codeLength; - Label[] labels = context.labels = new Label[codeLength + 2]; - readLabel(codeLength + 1, labels); - while (u < codeEnd) { - int offset = u - codeStart; - int opcode = b[u] & 0xFF; - switch (ClassWriter.TYPE[opcode]) { - case ClassWriter.NOARG_INSN: - case ClassWriter.IMPLVAR_INSN: - u += 1; - break; - case ClassWriter.LABEL_INSN: - readLabel(offset + readShort(u + 1), labels); - u += 3; - break; - case ClassWriter.LABELW_INSN: - readLabel(offset + readInt(u + 1), labels); - u += 5; - break; - case ClassWriter.WIDE_INSN: - opcode = b[u + 1] & 0xFF; - if (opcode == Opcodes.IINC) { - u += 6; - } else { - u += 4; - } - break; - case ClassWriter.TABL_INSN: - // skips 0 to 3 padding bytes - u = u + 4 - (offset & 3); - // reads instruction - readLabel(offset + readInt(u), labels); - for (int i = readInt(u + 8) - readInt(u + 4) + 1; i > 0; --i) { - readLabel(offset + readInt(u + 12), labels); - u += 4; - } - u += 12; - break; - case ClassWriter.LOOK_INSN: - // skips 0 to 3 padding bytes - u = u + 4 - (offset & 3); - // reads instruction - readLabel(offset + readInt(u), labels); - for (int i = readInt(u + 4); i > 0; --i) { - readLabel(offset + readInt(u + 12), labels); - u += 8; - } - u += 8; - break; - case ClassWriter.VAR_INSN: - case ClassWriter.SBYTE_INSN: - case ClassWriter.LDC_INSN: - u += 2; - break; - case ClassWriter.SHORT_INSN: - case ClassWriter.LDCW_INSN: - case ClassWriter.FIELDORMETH_INSN: - case ClassWriter.TYPE_INSN: - case ClassWriter.IINC_INSN: - u += 3; - break; - case ClassWriter.ITFMETH_INSN: - case ClassWriter.INDYMETH_INSN: - u += 5; - break; - // case MANA_INSN: - default: - u += 4; - break; - } - } - - // reads the try catch entries to find the labels, and also visits them - for (int i = readUnsignedShort(u); i > 0; --i) { - Label start = readLabel(readUnsignedShort(u + 2), labels); - Label end = readLabel(readUnsignedShort(u + 4), labels); - Label handler = readLabel(readUnsignedShort(u + 6), labels); - String type = readUTF8(items[readUnsignedShort(u + 8)], c); - mv.visitTryCatchBlock(start, end, handler, type); - u += 8; - } - u += 2; - - // reads the code attributes - int[] tanns = null; // start index of each visible type annotation - int[] itanns = null; // start index of each invisible type annotation - int tann = 0; // current index in tanns array - int itann = 0; // current index in itanns array - int ntoff = -1; // next visible type annotation code offset - int nitoff = -1; // next invisible type annotation code offset - int varTable = 0; - int varTypeTable = 0; - boolean zip = true; - boolean unzip = (context.flags & EXPAND_FRAMES) != 0; - int stackMap = 0; - int stackMapSize = 0; - int frameCount = 0; - Context frame = null; - Attribute attributes = null; - - for (int i = readUnsignedShort(u); i > 0; --i) { - String attrName = readUTF8(u + 2, c); - if ("LocalVariableTable".equals(attrName)) { - if ((context.flags & SKIP_DEBUG) == 0) { - varTable = u + 8; - for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) { - int label = readUnsignedShort(v + 10); - if (labels[label] == null) { - readLabel(label, labels).status |= Label.DEBUG; - } - label += readUnsignedShort(v + 12); - if (labels[label] == null) { - readLabel(label, labels).status |= Label.DEBUG; - } - v += 10; - } - } - } else if ("LocalVariableTypeTable".equals(attrName)) { - varTypeTable = u + 8; - } else if ("LineNumberTable".equals(attrName)) { - if ((context.flags & SKIP_DEBUG) == 0) { - for (int j = readUnsignedShort(u + 8), v = u; j > 0; --j) { - int label = readUnsignedShort(v + 10); - if (labels[label] == null) { - readLabel(label, labels).status |= Label.DEBUG; - } - labels[label].line = readUnsignedShort(v + 12); - v += 4; - } - } - } else if (ANNOTATIONS - && "RuntimeVisibleTypeAnnotations".equals(attrName)) { - tanns = readTypeAnnotations(mv, context, u + 8, true); - ntoff = tanns.length == 0 || readByte(tanns[0]) < 0x43 ? -1 - : readUnsignedShort(tanns[0] + 1); - } else if (ANNOTATIONS - && "RuntimeInvisibleTypeAnnotations".equals(attrName)) { - itanns = readTypeAnnotations(mv, context, u + 8, false); - nitoff = itanns.length == 0 || readByte(itanns[0]) < 0x43 ? -1 - : readUnsignedShort(itanns[0] + 1); - } else if (FRAMES && "StackMapTable".equals(attrName)) { - if ((context.flags & SKIP_FRAMES) == 0) { - stackMap = u + 10; - stackMapSize = readInt(u + 4); - frameCount = readUnsignedShort(u + 8); - } - /* - * here we do not extract the labels corresponding to the - * attribute content. This would require a full parsing of the - * attribute, which would need to be repeated in the second - * phase (see below). Instead the content of the attribute is - * read one frame at a time (i.e. after a frame has been - * visited, the next frame is read), and the labels it contains - * are also extracted one frame at a time. Thanks to the - * ordering of frames, having only a "one frame lookahead" is - * not a problem, i.e. it is not possible to see an offset - * smaller than the offset of the current insn and for which no - * Label exist. - */ - /* - * This is not true for UNINITIALIZED type offsets. We solve - * this by parsing the stack map table without a full decoding - * (see below). - */ - } else if (FRAMES && "StackMap".equals(attrName)) { - if ((context.flags & SKIP_FRAMES) == 0) { - zip = false; - stackMap = u + 10; - stackMapSize = readInt(u + 4); - frameCount = readUnsignedShort(u + 8); - } - /* - * IMPORTANT! here we assume that the frames are ordered, as in - * the StackMapTable attribute, although this is not guaranteed - * by the attribute format. - */ - } else { - for (int j = 0; j < context.attrs.length; ++j) { - if (context.attrs[j].type.equals(attrName)) { - Attribute attr = context.attrs[j].read(this, u + 8, - readInt(u + 4), c, codeStart - 8, labels); - if (attr != null) { - attr.next = attributes; - attributes = attr; - } - } - } - } - u += 6 + readInt(u + 4); - } - u += 2; - - // generates the first (implicit) stack map frame - if (FRAMES && stackMap != 0) { - /* - * for the first explicit frame the offset is not offset_delta + 1 - * but only offset_delta; setting the implicit frame offset to -1 - * allow the use of the "offset_delta + 1" rule in all cases - */ - frame = context; - frame.offset = -1; - frame.mode = 0; - frame.localCount = 0; - frame.localDiff = 0; - frame.stackCount = 0; - frame.local = new Object[maxLocals]; - frame.stack = new Object[maxStack]; - if (unzip) { - getImplicitFrame(context); - } - /* - * Finds labels for UNINITIALIZED frame types. Instead of decoding - * each element of the stack map table, we look for 3 consecutive - * bytes that "look like" an UNINITIALIZED type (tag 8, offset - * within code bounds, NEW instruction at this offset). We may find - * false positives (i.e. not real UNINITIALIZED types), but this - * should be rare, and the only consequence will be the creation of - * an unneeded label. This is better than creating a label for each - * NEW instruction, and faster than fully decoding the whole stack - * map table. - */ - for (int i = stackMap; i < stackMap + stackMapSize - 2; ++i) { - if (b[i] == 8) { // UNINITIALIZED FRAME TYPE - int v = readUnsignedShort(i + 1); - if (v >= 0 && v < codeLength) { - if ((b[codeStart + v] & 0xFF) == Opcodes.NEW) { - readLabel(v, labels); - } - } - } - } - } - - // visits the instructions - u = codeStart; - while (u < codeEnd) { - int offset = u - codeStart; - - // visits the label and line number for this offset, if any - Label l = labels[offset]; - if (l != null) { - mv.visitLabel(l); - if ((context.flags & SKIP_DEBUG) == 0 && l.line > 0) { - mv.visitLineNumber(l.line, l); - } - } - - // visits the frame for this offset, if any - while (FRAMES && frame != null - && (frame.offset == offset || frame.offset == -1)) { - // if there is a frame for this offset, makes the visitor visit - // it, and reads the next frame if there is one. - if (frame.offset != -1) { - if (!zip || unzip) { - mv.visitFrame(Opcodes.F_NEW, frame.localCount, - frame.local, frame.stackCount, frame.stack); - } else { - mv.visitFrame(frame.mode, frame.localDiff, frame.local, - frame.stackCount, frame.stack); - } - } - if (frameCount > 0) { - stackMap = readFrame(stackMap, zip, unzip, frame); - --frameCount; - } else { - frame = null; - } - } - - // visits the instruction at this offset - int opcode = b[u] & 0xFF; - switch (ClassWriter.TYPE[opcode]) { - case ClassWriter.NOARG_INSN: - mv.visitInsn(opcode); - u += 1; - break; - case ClassWriter.IMPLVAR_INSN: - if (opcode > Opcodes.ISTORE) { - opcode -= 59; // ISTORE_0 - mv.visitVarInsn(Opcodes.ISTORE + (opcode >> 2), - opcode & 0x3); - } else { - opcode -= 26; // ILOAD_0 - mv.visitVarInsn(Opcodes.ILOAD + (opcode >> 2), opcode & 0x3); - } - u += 1; - break; - case ClassWriter.LABEL_INSN: - mv.visitJumpInsn(opcode, labels[offset + readShort(u + 1)]); - u += 3; - break; - case ClassWriter.LABELW_INSN: - mv.visitJumpInsn(opcode - 33, labels[offset + readInt(u + 1)]); - u += 5; - break; - case ClassWriter.WIDE_INSN: - opcode = b[u + 1] & 0xFF; - if (opcode == Opcodes.IINC) { - mv.visitIincInsn(readUnsignedShort(u + 2), readShort(u + 4)); - u += 6; - } else { - mv.visitVarInsn(opcode, readUnsignedShort(u + 2)); - u += 4; - } - break; - case ClassWriter.TABL_INSN: { - // skips 0 to 3 padding bytes - u = u + 4 - (offset & 3); - // reads instruction - int label = offset + readInt(u); - int min = readInt(u + 4); - int max = readInt(u + 8); - Label[] table = new Label[max - min + 1]; - u += 12; - for (int i = 0; i < table.length; ++i) { - table[i] = labels[offset + readInt(u)]; - u += 4; - } - mv.visitTableSwitchInsn(min, max, labels[label], table); - break; - } - case ClassWriter.LOOK_INSN: { - // skips 0 to 3 padding bytes - u = u + 4 - (offset & 3); - // reads instruction - int label = offset + readInt(u); - int len = readInt(u + 4); - int[] keys = new int[len]; - Label[] values = new Label[len]; - u += 8; - for (int i = 0; i < len; ++i) { - keys[i] = readInt(u); - values[i] = labels[offset + readInt(u + 4)]; - u += 8; - } - mv.visitLookupSwitchInsn(labels[label], keys, values); - break; - } - case ClassWriter.VAR_INSN: - mv.visitVarInsn(opcode, b[u + 1] & 0xFF); - u += 2; - break; - case ClassWriter.SBYTE_INSN: - mv.visitIntInsn(opcode, b[u + 1]); - u += 2; - break; - case ClassWriter.SHORT_INSN: - mv.visitIntInsn(opcode, readShort(u + 1)); - u += 3; - break; - case ClassWriter.LDC_INSN: - mv.visitLdcInsn(readConst(b[u + 1] & 0xFF, c)); - u += 2; - break; - case ClassWriter.LDCW_INSN: - mv.visitLdcInsn(readConst(readUnsignedShort(u + 1), c)); - u += 3; - break; - case ClassWriter.FIELDORMETH_INSN: - case ClassWriter.ITFMETH_INSN: { - int cpIndex = items[readUnsignedShort(u + 1)]; - boolean itf = b[cpIndex - 1] == ClassWriter.IMETH; - String iowner = readClass(cpIndex, c); - cpIndex = items[readUnsignedShort(cpIndex + 2)]; - String iname = readUTF8(cpIndex, c); - String idesc = readUTF8(cpIndex + 2, c); - if (opcode < Opcodes.INVOKEVIRTUAL) { - mv.visitFieldInsn(opcode, iowner, iname, idesc); - } else { - mv.visitMethodInsn(opcode, iowner, iname, idesc, itf); - } - if (opcode == Opcodes.INVOKEINTERFACE) { - u += 5; - } else { - u += 3; - } - break; - } - case ClassWriter.INDYMETH_INSN: { - int cpIndex = items[readUnsignedShort(u + 1)]; - int bsmIndex = context.bootstrapMethods[readUnsignedShort(cpIndex)]; - Handle bsm = (Handle) readConst(readUnsignedShort(bsmIndex), c); - int bsmArgCount = readUnsignedShort(bsmIndex + 2); - Object[] bsmArgs = new Object[bsmArgCount]; - bsmIndex += 4; - for (int i = 0; i < bsmArgCount; i++) { - bsmArgs[i] = readConst(readUnsignedShort(bsmIndex), c); - bsmIndex += 2; - } - cpIndex = items[readUnsignedShort(cpIndex + 2)]; - String iname = readUTF8(cpIndex, c); - String idesc = readUTF8(cpIndex + 2, c); - mv.visitInvokeDynamicInsn(iname, idesc, bsm, bsmArgs); - u += 5; - break; - } - case ClassWriter.TYPE_INSN: - mv.visitTypeInsn(opcode, readClass(u + 1, c)); - u += 3; - break; - case ClassWriter.IINC_INSN: - mv.visitIincInsn(b[u + 1] & 0xFF, b[u + 2]); - u += 3; - break; - // case MANA_INSN: - default: - mv.visitMultiANewArrayInsn(readClass(u + 1, c), b[u + 3] & 0xFF); - u += 4; - break; - } - - // visit the instruction annotations, if any - while (tanns != null && tann < tanns.length && ntoff <= offset) { - if (ntoff == offset) { - int v = readAnnotationTarget(context, tanns[tann]); - readAnnotationValues(v + 2, c, true, - mv.visitInsnAnnotation(context.typeRef, - context.typePath, readUTF8(v, c), true)); - } - ntoff = ++tann >= tanns.length || readByte(tanns[tann]) < 0x43 ? -1 - : readUnsignedShort(tanns[tann] + 1); - } - while (itanns != null && itann < itanns.length && nitoff <= offset) { - if (nitoff == offset) { - int v = readAnnotationTarget(context, itanns[itann]); - readAnnotationValues(v + 2, c, true, - mv.visitInsnAnnotation(context.typeRef, - context.typePath, readUTF8(v, c), false)); - } - nitoff = ++itann >= itanns.length - || readByte(itanns[itann]) < 0x43 ? -1 - : readUnsignedShort(itanns[itann] + 1); - } - } - if (labels[codeLength] != null) { - mv.visitLabel(labels[codeLength]); - } - - // visits the local variable tables - if ((context.flags & SKIP_DEBUG) == 0 && varTable != 0) { - int[] typeTable = null; - if (varTypeTable != 0) { - u = varTypeTable + 2; - typeTable = new int[readUnsignedShort(varTypeTable) * 3]; - for (int i = typeTable.length; i > 0;) { - typeTable[--i] = u + 6; // signature - typeTable[--i] = readUnsignedShort(u + 8); // index - typeTable[--i] = readUnsignedShort(u); // start - u += 10; - } - } - u = varTable + 2; - for (int i = readUnsignedShort(varTable); i > 0; --i) { - int start = readUnsignedShort(u); - int length = readUnsignedShort(u + 2); - int index = readUnsignedShort(u + 8); - String vsignature = null; - if (typeTable != null) { - for (int j = 0; j < typeTable.length; j += 3) { - if (typeTable[j] == start && typeTable[j + 1] == index) { - vsignature = readUTF8(typeTable[j + 2], c); - break; - } - } - } - mv.visitLocalVariable(readUTF8(u + 4, c), readUTF8(u + 6, c), - vsignature, labels[start], labels[start + length], - index); - u += 10; - } - } - - // visits the local variables type annotations - if (tanns != null) { - for (int i = 0; i < tanns.length; ++i) { - if ((readByte(tanns[i]) >> 1) == (0x40 >> 1)) { - int v = readAnnotationTarget(context, tanns[i]); - v = readAnnotationValues(v + 2, c, true, - mv.visitLocalVariableAnnotation(context.typeRef, - context.typePath, context.start, - context.end, context.index, readUTF8(v, c), - true)); - } - } - } - if (itanns != null) { - for (int i = 0; i < itanns.length; ++i) { - if ((readByte(itanns[i]) >> 1) == (0x40 >> 1)) { - int v = readAnnotationTarget(context, itanns[i]); - v = readAnnotationValues(v + 2, c, true, - mv.visitLocalVariableAnnotation(context.typeRef, - context.typePath, context.start, - context.end, context.index, readUTF8(v, c), - false)); - } - } - } - - // visits the code attributes - while (attributes != null) { - Attribute attr = attributes.next; - attributes.next = null; - mv.visitAttribute(attributes); - attributes = attr; - } - - // visits the max stack and max locals values - mv.visitMaxs(maxStack, maxLocals); - } - - /** - * Parses a type annotation table to find the labels, and to visit the try - * catch block annotations. - * - * @param u - * the start offset of a type annotation table. - * @param mv - * the method visitor to be used to visit the try catch block - * annotations. - * @param context - * information about the class being parsed. - * @param visible - * if the type annotation table to parse contains runtime visible - * annotations. - * @return the start offset of each type annotation in the parsed table. - */ - private int[] readTypeAnnotations(final MethodVisitor mv, - final Context context, int u, boolean visible) { - char[] c = context.buffer; - int[] offsets = new int[readUnsignedShort(u)]; - u += 2; - for (int i = 0; i < offsets.length; ++i) { - offsets[i] = u; - int target = readInt(u); - switch (target >>> 24) { - case 0x00: // CLASS_TYPE_PARAMETER - case 0x01: // METHOD_TYPE_PARAMETER - case 0x16: // METHOD_FORMAL_PARAMETER - u += 2; - break; - case 0x13: // FIELD - case 0x14: // METHOD_RETURN - case 0x15: // METHOD_RECEIVER - u += 1; - break; - case 0x40: // LOCAL_VARIABLE - case 0x41: // RESOURCE_VARIABLE - for (int j = readUnsignedShort(u + 1); j > 0; --j) { - int start = readUnsignedShort(u + 3); - int length = readUnsignedShort(u + 5); - readLabel(start, context.labels); - readLabel(start + length, context.labels); - u += 6; - } - u += 3; - break; - case 0x47: // CAST - case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT - case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT - case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT - case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT - u += 4; - break; - // case 0x10: // CLASS_EXTENDS - // case 0x11: // CLASS_TYPE_PARAMETER_BOUND - // case 0x12: // METHOD_TYPE_PARAMETER_BOUND - // case 0x17: // THROWS - // case 0x42: // EXCEPTION_PARAMETER - // case 0x43: // INSTANCEOF - // case 0x44: // NEW - // case 0x45: // CONSTRUCTOR_REFERENCE - // case 0x46: // METHOD_REFERENCE - default: - u += 3; - break; - } - int pathLength = readByte(u); - if ((target >>> 24) == 0x42) { - TypePath path = pathLength == 0 ? null : new TypePath(b, u); - u += 1 + 2 * pathLength; - u = readAnnotationValues(u + 2, c, true, - mv.visitTryCatchAnnotation(target, path, - readUTF8(u, c), visible)); - } else { - u = readAnnotationValues(u + 3 + 2 * pathLength, c, true, null); - } - } - return offsets; - } - - /** - * Parses the header of a type annotation to extract its target_type and - * target_path (the result is stored in the given context), and returns the - * start offset of the rest of the type_annotation structure (i.e. the - * offset to the type_index field, which is followed by - * num_element_value_pairs and then the name,value pairs). - * - * @param context - * information about the class being parsed. This is where the - * extracted target_type and target_path must be stored. - * @param u - * the start offset of a type_annotation structure. - * @return the start offset of the rest of the type_annotation structure. - */ - private int readAnnotationTarget(final Context context, int u) { - int target = readInt(u); - switch (target >>> 24) { - case 0x00: // CLASS_TYPE_PARAMETER - case 0x01: // METHOD_TYPE_PARAMETER - case 0x16: // METHOD_FORMAL_PARAMETER - target &= 0xFFFF0000; - u += 2; - break; - case 0x13: // FIELD - case 0x14: // METHOD_RETURN - case 0x15: // METHOD_RECEIVER - target &= 0xFF000000; - u += 1; - break; - case 0x40: // LOCAL_VARIABLE - case 0x41: { // RESOURCE_VARIABLE - target &= 0xFF000000; - int n = readUnsignedShort(u + 1); - context.start = new Label[n]; - context.end = new Label[n]; - context.index = new int[n]; - u += 3; - for (int i = 0; i < n; ++i) { - int start = readUnsignedShort(u); - int length = readUnsignedShort(u + 2); - context.start[i] = readLabel(start, context.labels); - context.end[i] = readLabel(start + length, context.labels); - context.index[i] = readUnsignedShort(u + 4); - u += 6; - } - break; - } - case 0x47: // CAST - case 0x48: // CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT - case 0x49: // METHOD_INVOCATION_TYPE_ARGUMENT - case 0x4A: // CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT - case 0x4B: // METHOD_REFERENCE_TYPE_ARGUMENT - target &= 0xFF0000FF; - u += 4; - break; - // case 0x10: // CLASS_EXTENDS - // case 0x11: // CLASS_TYPE_PARAMETER_BOUND - // case 0x12: // METHOD_TYPE_PARAMETER_BOUND - // case 0x17: // THROWS - // case 0x42: // EXCEPTION_PARAMETER - // case 0x43: // INSTANCEOF - // case 0x44: // NEW - // case 0x45: // CONSTRUCTOR_REFERENCE - // case 0x46: // METHOD_REFERENCE - default: - target &= (target >>> 24) < 0x43 ? 0xFFFFFF00 : 0xFF000000; - u += 3; - break; - } - int pathLength = readByte(u); - context.typeRef = target; - context.typePath = pathLength == 0 ? null : new TypePath(b, u); - return u + 1 + 2 * pathLength; - } - - /** - * Reads parameter annotations and makes the given visitor visit them. - * - * @param mv - * the visitor that must visit the annotations. - * @param context - * information about the class being parsed. - * @param v - * start offset in {@link #b b} of the annotations to be read. - * @param visible - * true if the annotations to be read are visible at - * runtime. - */ - private void readParameterAnnotations(final MethodVisitor mv, - final Context context, int v, final boolean visible) { - int i; - int n = b[v++] & 0xFF; - // workaround for a bug in javac (javac compiler generates a parameter - // annotation array whose size is equal to the number of parameters in - // the Java source file, while it should generate an array whose size is - // equal to the number of parameters in the method descriptor - which - // includes the synthetic parameters added by the compiler). This work- - // around supposes that the synthetic parameters are the first ones. - int synthetics = Type.getArgumentTypes(context.desc).length - n; - AnnotationVisitor av; - for (i = 0; i < synthetics; ++i) { - // virtual annotation to detect synthetic parameters in MethodWriter - av = mv.visitParameterAnnotation(i, "Ljava/lang/Synthetic;", false); - if (av != null) { - av.visitEnd(); - } - } - char[] c = context.buffer; - for (; i < n + synthetics; ++i) { - int j = readUnsignedShort(v); - v += 2; - for (; j > 0; --j) { - av = mv.visitParameterAnnotation(i, readUTF8(v, c), visible); - v = readAnnotationValues(v + 2, c, true, av); - } - } - } - - /** - * Reads the values of an annotation and makes the given visitor visit them. - * - * @param v - * the start offset in {@link #b b} of the values to be read - * (including the unsigned short that gives the number of - * values). - * @param buf - * buffer to be used to call {@link #readUTF8 readUTF8}, - * {@link #readClass(int,char[]) readClass} or {@link #readConst - * readConst}. - * @param named - * if the annotation values are named or not. - * @param av - * the visitor that must visit the values. - * @return the end offset of the annotation values. - */ - private int readAnnotationValues(int v, final char[] buf, - final boolean named, final AnnotationVisitor av) { - int i = readUnsignedShort(v); - v += 2; - if (named) { - for (; i > 0; --i) { - v = readAnnotationValue(v + 2, buf, readUTF8(v, buf), av); - } - } else { - for (; i > 0; --i) { - v = readAnnotationValue(v, buf, null, av); - } - } - if (av != null) { - av.visitEnd(); - } - return v; - } - - /** - * Reads a value of an annotation and makes the given visitor visit it. - * - * @param v - * the start offset in {@link #b b} of the value to be read - * (not including the value name constant pool index). - * @param buf - * buffer to be used to call {@link #readUTF8 readUTF8}, - * {@link #readClass(int,char[]) readClass} or {@link #readConst - * readConst}. - * @param name - * the name of the value to be read. - * @param av - * the visitor that must visit the value. - * @return the end offset of the annotation value. - */ - private int readAnnotationValue(int v, final char[] buf, final String name, - final AnnotationVisitor av) { - int i; - if (av == null) { - switch (b[v] & 0xFF) { - case 'e': // enum_const_value - return v + 5; - case '@': // annotation_value - return readAnnotationValues(v + 3, buf, true, null); - case '[': // array_value - return readAnnotationValues(v + 1, buf, false, null); - default: - return v + 3; - } - } - switch (b[v++] & 0xFF) { - case 'I': // pointer to CONSTANT_Integer - case 'J': // pointer to CONSTANT_Long - case 'F': // pointer to CONSTANT_Float - case 'D': // pointer to CONSTANT_Double - av.visit(name, readConst(readUnsignedShort(v), buf)); - v += 2; - break; - case 'B': // pointer to CONSTANT_Byte - av.visit(name, - new Byte((byte) readInt(items[readUnsignedShort(v)]))); - v += 2; - break; - case 'Z': // pointer to CONSTANT_Boolean - av.visit(name, - readInt(items[readUnsignedShort(v)]) == 0 ? Boolean.FALSE - : Boolean.TRUE); - v += 2; - break; - case 'S': // pointer to CONSTANT_Short - av.visit(name, new Short( - (short) readInt(items[readUnsignedShort(v)]))); - v += 2; - break; - case 'C': // pointer to CONSTANT_Char - av.visit(name, new Character( - (char) readInt(items[readUnsignedShort(v)]))); - v += 2; - break; - case 's': // pointer to CONSTANT_Utf8 - av.visit(name, readUTF8(v, buf)); - v += 2; - break; - case 'e': // enum_const_value - av.visitEnum(name, readUTF8(v, buf), readUTF8(v + 2, buf)); - v += 4; - break; - case 'c': // class_info - av.visit(name, Type.getType(readUTF8(v, buf))); - v += 2; - break; - case '@': // annotation_value - v = readAnnotationValues(v + 2, buf, true, - av.visitAnnotation(name, readUTF8(v, buf))); - break; - case '[': // array_value - int size = readUnsignedShort(v); - v += 2; - if (size == 0) { - return readAnnotationValues(v - 2, buf, false, - av.visitArray(name)); - } - switch (this.b[v++] & 0xFF) { - case 'B': - byte[] bv = new byte[size]; - for (i = 0; i < size; i++) { - bv[i] = (byte) readInt(items[readUnsignedShort(v)]); - v += 3; - } - av.visit(name, bv); - --v; - break; - case 'Z': - boolean[] zv = new boolean[size]; - for (i = 0; i < size; i++) { - zv[i] = readInt(items[readUnsignedShort(v)]) != 0; - v += 3; - } - av.visit(name, zv); - --v; - break; - case 'S': - short[] sv = new short[size]; - for (i = 0; i < size; i++) { - sv[i] = (short) readInt(items[readUnsignedShort(v)]); - v += 3; - } - av.visit(name, sv); - --v; - break; - case 'C': - char[] cv = new char[size]; - for (i = 0; i < size; i++) { - cv[i] = (char) readInt(items[readUnsignedShort(v)]); - v += 3; - } - av.visit(name, cv); - --v; - break; - case 'I': - int[] iv = new int[size]; - for (i = 0; i < size; i++) { - iv[i] = readInt(items[readUnsignedShort(v)]); - v += 3; - } - av.visit(name, iv); - --v; - break; - case 'J': - long[] lv = new long[size]; - for (i = 0; i < size; i++) { - lv[i] = readLong(items[readUnsignedShort(v)]); - v += 3; - } - av.visit(name, lv); - --v; - break; - case 'F': - float[] fv = new float[size]; - for (i = 0; i < size; i++) { - fv[i] = Float - .intBitsToFloat(readInt(items[readUnsignedShort(v)])); - v += 3; - } - av.visit(name, fv); - --v; - break; - case 'D': - double[] dv = new double[size]; - for (i = 0; i < size; i++) { - dv[i] = Double - .longBitsToDouble(readLong(items[readUnsignedShort(v)])); - v += 3; - } - av.visit(name, dv); - --v; - break; - default: - v = readAnnotationValues(v - 3, buf, false, av.visitArray(name)); - } - } - return v; - } - - /** - * Computes the implicit frame of the method currently being parsed (as - * defined in the given {@link Context}) and stores it in the given context. - * - * @param frame - * information about the class being parsed. - */ - private void getImplicitFrame(final Context frame) { - String desc = frame.desc; - Object[] locals = frame.local; - int local = 0; - if ((frame.access & Opcodes.ACC_STATIC) == 0) { - if ("".equals(frame.name)) { - locals[local++] = Opcodes.UNINITIALIZED_THIS; - } else { - locals[local++] = readClass(header + 2, frame.buffer); - } - } - int i = 1; - loop: while (true) { - int j = i; - switch (desc.charAt(i++)) { - case 'Z': - case 'C': - case 'B': - case 'S': - case 'I': - locals[local++] = Opcodes.INTEGER; - break; - case 'F': - locals[local++] = Opcodes.FLOAT; - break; - case 'J': - locals[local++] = Opcodes.LONG; - break; - case 'D': - locals[local++] = Opcodes.DOUBLE; - break; - case '[': - while (desc.charAt(i) == '[') { - ++i; - } - if (desc.charAt(i) == 'L') { - ++i; - while (desc.charAt(i) != ';') { - ++i; - } - } - locals[local++] = desc.substring(j, ++i); - break; - case 'L': - while (desc.charAt(i) != ';') { - ++i; - } - locals[local++] = desc.substring(j + 1, i++); - break; - default: - break loop; - } - } - frame.localCount = local; - } - - /** - * Reads a stack map frame and stores the result in the given - * {@link Context} object. - * - * @param stackMap - * the start offset of a stack map frame in the class file. - * @param zip - * if the stack map frame at stackMap is compressed or not. - * @param unzip - * if the stack map frame must be uncompressed. - * @param frame - * where the parsed stack map frame must be stored. - * @return the offset of the first byte following the parsed frame. - */ - private int readFrame(int stackMap, boolean zip, boolean unzip, - Context frame) { - char[] c = frame.buffer; - Label[] labels = frame.labels; - int tag; - int delta; - if (zip) { - tag = b[stackMap++] & 0xFF; - } else { - tag = MethodWriter.FULL_FRAME; - frame.offset = -1; - } - frame.localDiff = 0; - if (tag < MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME) { - delta = tag; - frame.mode = Opcodes.F_SAME; - frame.stackCount = 0; - } else if (tag < MethodWriter.RESERVED) { - delta = tag - MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME; - stackMap = readFrameType(frame.stack, 0, stackMap, c, labels); - frame.mode = Opcodes.F_SAME1; - frame.stackCount = 1; - } else { - delta = readUnsignedShort(stackMap); - stackMap += 2; - if (tag == MethodWriter.SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) { - stackMap = readFrameType(frame.stack, 0, stackMap, c, labels); - frame.mode = Opcodes.F_SAME1; - frame.stackCount = 1; - } else if (tag >= MethodWriter.CHOP_FRAME - && tag < MethodWriter.SAME_FRAME_EXTENDED) { - frame.mode = Opcodes.F_CHOP; - frame.localDiff = MethodWriter.SAME_FRAME_EXTENDED - tag; - frame.localCount -= frame.localDiff; - frame.stackCount = 0; - } else if (tag == MethodWriter.SAME_FRAME_EXTENDED) { - frame.mode = Opcodes.F_SAME; - frame.stackCount = 0; - } else if (tag < MethodWriter.FULL_FRAME) { - int local = unzip ? frame.localCount : 0; - for (int i = tag - MethodWriter.SAME_FRAME_EXTENDED; i > 0; i--) { - stackMap = readFrameType(frame.local, local++, stackMap, c, - labels); - } - frame.mode = Opcodes.F_APPEND; - frame.localDiff = tag - MethodWriter.SAME_FRAME_EXTENDED; - frame.localCount += frame.localDiff; - frame.stackCount = 0; - } else { // if (tag == FULL_FRAME) { - frame.mode = Opcodes.F_FULL; - int n = readUnsignedShort(stackMap); - stackMap += 2; - frame.localDiff = n; - frame.localCount = n; - for (int local = 0; n > 0; n--) { - stackMap = readFrameType(frame.local, local++, stackMap, c, - labels); - } - n = readUnsignedShort(stackMap); - stackMap += 2; - frame.stackCount = n; - for (int stack = 0; n > 0; n--) { - stackMap = readFrameType(frame.stack, stack++, stackMap, c, - labels); - } - } - } - frame.offset += delta + 1; - readLabel(frame.offset, labels); - return stackMap; - } - - /** - * Reads a stack map frame type and stores it at the given index in the - * given array. - * - * @param frame - * the array where the parsed type must be stored. - * @param index - * the index in 'frame' where the parsed type must be stored. - * @param v - * the start offset of the stack map frame type to read. - * @param buf - * a buffer to read strings. - * @param labels - * the labels of the method currently being parsed, indexed by - * their offset. If the parsed type is an Uninitialized type, a - * new label for the corresponding NEW instruction is stored in - * this array if it does not already exist. - * @return the offset of the first byte after the parsed type. - */ - private int readFrameType(final Object[] frame, final int index, int v, - final char[] buf, final Label[] labels) { - int type = b[v++] & 0xFF; - switch (type) { - case 0: - frame[index] = Opcodes.TOP; - break; - case 1: - frame[index] = Opcodes.INTEGER; - break; - case 2: - frame[index] = Opcodes.FLOAT; - break; - case 3: - frame[index] = Opcodes.DOUBLE; - break; - case 4: - frame[index] = Opcodes.LONG; - break; - case 5: - frame[index] = Opcodes.NULL; - break; - case 6: - frame[index] = Opcodes.UNINITIALIZED_THIS; - break; - case 7: // Object - frame[index] = readClass(v, buf); - v += 2; - break; - default: // Uninitialized - frame[index] = readLabel(readUnsignedShort(v), labels); - v += 2; - } - return v; - } - - /** - * Returns the label corresponding to the given offset. The default - * implementation of this method creates a label for the given offset if it - * has not been already created. - * - * @param offset - * a bytecode offset in a method. - * @param labels - * the already created labels, indexed by their offset. If a - * label already exists for offset this method must not create a - * new one. Otherwise it must store the new label in this array. - * @return a non null Label, which must be equal to labels[offset]. - */ - protected Label readLabel(int offset, Label[] labels) { - if (labels[offset] == null) { - labels[offset] = new Label(); - } - return labels[offset]; - } - - /** - * Returns the start index of the attribute_info structure of this class. - * - * @return the start index of the attribute_info structure of this class. - */ - private int getAttributes() { - // skips the header - int u = header + 8 + readUnsignedShort(header + 6) * 2; - // skips fields and methods - for (int i = readUnsignedShort(u); i > 0; --i) { - for (int j = readUnsignedShort(u + 8); j > 0; --j) { - u += 6 + readInt(u + 12); - } - u += 8; - } - u += 2; - for (int i = readUnsignedShort(u); i > 0; --i) { - for (int j = readUnsignedShort(u + 8); j > 0; --j) { - u += 6 + readInt(u + 12); - } - u += 8; - } - // the attribute_info structure starts just after the methods - return u + 2; - } - - /** - * Reads an attribute in {@link #b b}. - * - * @param attrs - * prototypes of the attributes that must be parsed during the - * visit of the class. Any attribute whose type is not equal to - * the type of one the prototypes is ignored (i.e. an empty - * {@link Attribute} instance is returned). - * @param type - * the type of the attribute. - * @param off - * index of the first byte of the attribute's content in - * {@link #b b}. The 6 attribute header bytes, containing the - * type and the length of the attribute, are not taken into - * account here (they have already been read). - * @param len - * the length of the attribute's content. - * @param buf - * buffer to be used to call {@link #readUTF8 readUTF8}, - * {@link #readClass(int,char[]) readClass} or {@link #readConst - * readConst}. - * @param codeOff - * index of the first byte of code's attribute content in - * {@link #b b}, or -1 if the attribute to be read is not a code - * attribute. The 6 attribute header bytes, containing the type - * and the length of the attribute, are not taken into account - * here. - * @param labels - * the labels of the method's code, or null if the - * attribute to be read is not a code attribute. - * @return the attribute that has been read, or null to skip this - * attribute. - */ - private Attribute readAttribute(final Attribute[] attrs, final String type, - final int off, final int len, final char[] buf, final int codeOff, - final Label[] labels) { - for (int i = 0; i < attrs.length; ++i) { - if (attrs[i].type.equals(type)) { - return attrs[i].read(this, off, len, buf, codeOff, labels); - } - } - return new Attribute(type).read(this, off, len, null, -1, null); - } - - // ------------------------------------------------------------------------ - // Utility methods: low level parsing - // ------------------------------------------------------------------------ - - /** - * Returns the number of constant pool items in {@link #b b}. - * - * @return the number of constant pool items in {@link #b b}. - */ - public int getItemCount() { - return items.length; - } - - /** - * Returns the start index of the constant pool item in {@link #b b}, plus - * one. This method is intended for {@link Attribute} sub classes, and is - * normally not needed by class generators or adapters. - * - * @param item - * the index a constant pool item. - * @return the start index of the constant pool item in {@link #b b}, plus - * one. - */ - public int getItem(final int item) { - return items[item]; - } - - /** - * Returns the maximum length of the strings contained in the constant pool - * of the class. - * - * @return the maximum length of the strings contained in the constant pool - * of the class. - */ - public int getMaxStringLength() { - return maxStringLength; - } - - /** - * Reads a byte value in {@link #b b}. This method is intended for - * {@link Attribute} sub classes, and is normally not needed by class - * generators or adapters. - * - * @param index - * the start index of the value to be read in {@link #b b}. - * @return the read value. - */ - public int readByte(final int index) { - return b[index] & 0xFF; - } - - /** - * Reads an unsigned short value in {@link #b b}. This method is intended - * for {@link Attribute} sub classes, and is normally not needed by class - * generators or adapters. - * - * @param index - * the start index of the value to be read in {@link #b b}. - * @return the read value. - */ - public int readUnsignedShort(final int index) { - byte[] b = this.b; - return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF); - } - - /** - * Reads a signed short value in {@link #b b}. This method is intended - * for {@link Attribute} sub classes, and is normally not needed by class - * generators or adapters. - * - * @param index - * the start index of the value to be read in {@link #b b}. - * @return the read value. - */ - public short readShort(final int index) { - byte[] b = this.b; - return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF)); - } - - /** - * Reads a signed int value in {@link #b b}. This method is intended for - * {@link Attribute} sub classes, and is normally not needed by class - * generators or adapters. - * - * @param index - * the start index of the value to be read in {@link #b b}. - * @return the read value. - */ - public int readInt(final int index) { - byte[] b = this.b; - return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16) - | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF); - } - - /** - * Reads a signed long value in {@link #b b}. This method is intended for - * {@link Attribute} sub classes, and is normally not needed by class - * generators or adapters. - * - * @param index - * the start index of the value to be read in {@link #b b}. - * @return the read value. - */ - public long readLong(final int index) { - long l1 = readInt(index); - long l0 = readInt(index + 4) & 0xFFFFFFFFL; - return (l1 << 32) | l0; - } - - /** - * Reads an UTF8 string constant pool item in {@link #b b}. This method - * is intended for {@link Attribute} sub classes, and is normally not needed - * by class generators or adapters. - * - * @param index - * the start index of an unsigned short value in {@link #b b}, - * whose value is the index of an UTF8 constant pool item. - * @param buf - * buffer to be used to read the item. This buffer must be - * sufficiently large. It is not automatically resized. - * @return the String corresponding to the specified UTF8 item. - */ - public String readUTF8(int index, final char[] buf) { - int item = readUnsignedShort(index); - if (index == 0 || item == 0) { - return null; - } - String s = strings[item]; - if (s != null) { - return s; - } - index = items[item]; - return strings[item] = readUTF(index + 2, readUnsignedShort(index), buf); - } - - /** - * Reads UTF8 string in {@link #b b}. - * - * @param index - * start offset of the UTF8 string to be read. - * @param utfLen - * length of the UTF8 string to be read. - * @param buf - * buffer to be used to read the string. This buffer must be - * sufficiently large. It is not automatically resized. - * @return the String corresponding to the specified UTF8 string. - */ - private String readUTF(int index, final int utfLen, final char[] buf) { - int endIndex = index + utfLen; - byte[] b = this.b; - int strLen = 0; - int c; - int st = 0; - char cc = 0; - while (index < endIndex) { - c = b[index++]; - switch (st) { - case 0: - c = c & 0xFF; - if (c < 0x80) { // 0xxxxxxx - buf[strLen++] = (char) c; - } else if (c < 0xE0 && c > 0xBF) { // 110x xxxx 10xx xxxx - cc = (char) (c & 0x1F); - st = 1; - } else { // 1110 xxxx 10xx xxxx 10xx xxxx - cc = (char) (c & 0x0F); - st = 2; - } - break; - - case 1: // byte 2 of 2-byte char or byte 3 of 3-byte char - buf[strLen++] = (char) ((cc << 6) | (c & 0x3F)); - st = 0; - break; - - case 2: // byte 2 of 3-byte char - cc = (char) ((cc << 6) | (c & 0x3F)); - st = 1; - break; - } - } - return new String(buf, 0, strLen); - } - - /** - * Reads a class constant pool item in {@link #b b}. This method is - * intended for {@link Attribute} sub classes, and is normally not needed by - * class generators or adapters. - * - * @param index - * the start index of an unsigned short value in {@link #b b}, - * whose value is the index of a class constant pool item. - * @param buf - * buffer to be used to read the item. This buffer must be - * sufficiently large. It is not automatically resized. - * @return the String corresponding to the specified class item. - */ - public String readClass(final int index, final char[] buf) { - // computes the start index of the CONSTANT_Class item in b - // and reads the CONSTANT_Utf8 item designated by - // the first two bytes of this CONSTANT_Class item - return readUTF8(items[readUnsignedShort(index)], buf); - } - - /** - * Reads a numeric or string constant pool item in {@link #b b}. This - * method is intended for {@link Attribute} sub classes, and is normally not - * needed by class generators or adapters. - * - * @param item - * the index of a constant pool item. - * @param buf - * buffer to be used to read the item. This buffer must be - * sufficiently large. It is not automatically resized. - * @return the {@link Integer}, {@link Float}, {@link Long}, {@link Double}, - * {@link String}, {@link Type} or {@link Handle} corresponding to - * the given constant pool item. - */ - public Object readConst(final int item, final char[] buf) { - int index = items[item]; - switch (b[index - 1]) { - case ClassWriter.INT: - return new Integer(readInt(index)); - case ClassWriter.FLOAT: - return new Float(Float.intBitsToFloat(readInt(index))); - case ClassWriter.LONG: - return new Long(readLong(index)); - case ClassWriter.DOUBLE: - return new Double(Double.longBitsToDouble(readLong(index))); - case ClassWriter.CLASS: - return Type.getObjectType(readUTF8(index, buf)); - case ClassWriter.STR: - return readUTF8(index, buf); - case ClassWriter.MTYPE: - return Type.getMethodType(readUTF8(index, buf)); - default: // case ClassWriter.HANDLE_BASE + [1..9]: - int tag = readByte(index); - int[] items = this.items; - int cpIndex = items[readUnsignedShort(index + 1)]; - String owner = readClass(cpIndex, buf); - cpIndex = items[readUnsignedShort(cpIndex + 2)]; - String name = readUTF8(cpIndex, buf); - String desc = readUTF8(cpIndex + 2, buf); - return new Handle(tag, owner, name, desc); - } - } -} diff --git a/src/asm/scala/tools/asm/ClassVisitor.java b/src/asm/scala/tools/asm/ClassVisitor.java deleted file mode 100644 index 48dc2ca6ae..0000000000 --- a/src/asm/scala/tools/asm/ClassVisitor.java +++ /dev/null @@ -1,320 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm; - -/** - * A visitor to visit a Java class. The methods of this class must be called in - * the following order: visit [ visitSource ] [ - * visitOuterClass ] ( visitAnnotation | - * visitTypeAnnotation | visitAttribute )* ( - * visitInnerClass | visitField | visitMethod )* - * visitEnd. - * - * @author Eric Bruneton - */ -public abstract class ClassVisitor { - - /** - * The ASM API version implemented by this visitor. The value of this field - * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - protected final int api; - - /** - * The class visitor to which this visitor must delegate method calls. May - * be null. - */ - protected ClassVisitor cv; - - /** - * Constructs a new {@link ClassVisitor}. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - public ClassVisitor(final int api) { - this(api, null); - } - - /** - * Constructs a new {@link ClassVisitor}. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - * @param cv - * the class visitor to which this visitor must delegate method - * calls. May be null. - */ - public ClassVisitor(final int api, final ClassVisitor cv) { - if (api != Opcodes.ASM4 && api != Opcodes.ASM5) { - throw new IllegalArgumentException(); - } - this.api = api; - this.cv = cv; - } - - /** - * Visits the header of the class. - * - * @param version - * the class version. - * @param access - * the class's access flags (see {@link Opcodes}). This parameter - * also indicates if the class is deprecated. - * @param name - * the internal name of the class (see - * {@link Type#getInternalName() getInternalName}). - * @param signature - * the signature of this class. May be null if the class - * is not a generic one, and does not extend or implement generic - * classes or interfaces. - * @param superName - * the internal of name of the super class (see - * {@link Type#getInternalName() getInternalName}). For - * interfaces, the super class is {@link Object}. May be - * null, but only for the {@link Object} class. - * @param interfaces - * the internal names of the class's interfaces (see - * {@link Type#getInternalName() getInternalName}). May be - * null. - */ - public void visit(int version, int access, String name, String signature, - String superName, String[] interfaces) { - if (cv != null) { - cv.visit(version, access, name, signature, superName, interfaces); - } - } - - /** - * Visits the source of the class. - * - * @param source - * the name of the source file from which the class was compiled. - * May be null. - * @param debug - * additional debug information to compute the correspondance - * between source and compiled elements of the class. May be - * null. - */ - public void visitSource(String source, String debug) { - if (cv != null) { - cv.visitSource(source, debug); - } - } - - /** - * Visits the enclosing class of the class. This method must be called only - * if the class has an enclosing class. - * - * @param owner - * internal name of the enclosing class of the class. - * @param name - * the name of the method that contains the class, or - * null if the class is not enclosed in a method of its - * enclosing class. - * @param desc - * the descriptor of the method that contains the class, or - * null if the class is not enclosed in a method of its - * enclosing class. - */ - public void visitOuterClass(String owner, String name, String desc) { - if (cv != null) { - cv.visitOuterClass(owner, name, desc); - } - } - - /** - * Visits an annotation of the class. - * - * @param desc - * the class descriptor of the annotation class. - * @param visible - * true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if - * this visitor is not interested in visiting this annotation. - */ - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - if (cv != null) { - return cv.visitAnnotation(desc, visible); - } - return null; - } - - /** - * Visits an annotation on a type in the class signature. - * - * @param typeRef - * a reference to the annotated type. The sort of this type - * reference must be {@link TypeReference#CLASS_TYPE_PARAMETER - * CLASS_TYPE_PARAMETER}, - * {@link TypeReference#CLASS_TYPE_PARAMETER_BOUND - * CLASS_TYPE_PARAMETER_BOUND} or - * {@link TypeReference#CLASS_EXTENDS CLASS_EXTENDS}. See - * {@link TypeReference}. - * @param typePath - * the path to the annotated type argument, wildcard bound, array - * element type, or static inner type within 'typeRef'. May be - * null if the annotation targets 'typeRef' as a whole. - * @param desc - * the class descriptor of the annotation class. - * @param visible - * true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if - * this visitor is not interested in visiting this annotation. - */ - public AnnotationVisitor visitTypeAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - if (api < Opcodes.ASM5) { - throw new RuntimeException(); - } - if (cv != null) { - return cv.visitTypeAnnotation(typeRef, typePath, desc, visible); - } - return null; - } - - /** - * Visits a non standard attribute of the class. - * - * @param attr - * an attribute. - */ - public void visitAttribute(Attribute attr) { - if (cv != null) { - cv.visitAttribute(attr); - } - } - - /** - * Visits information about an inner class. This inner class is not - * necessarily a member of the class being visited. - * - * @param name - * the internal name of an inner class (see - * {@link Type#getInternalName() getInternalName}). - * @param outerName - * the internal name of the class to which the inner class - * belongs (see {@link Type#getInternalName() getInternalName}). - * May be null for not member classes. - * @param innerName - * the (simple) name of the inner class inside its enclosing - * class. May be null for anonymous inner classes. - * @param access - * the access flags of the inner class as originally declared in - * the enclosing class. - */ - public void visitInnerClass(String name, String outerName, - String innerName, int access) { - if (cv != null) { - cv.visitInnerClass(name, outerName, innerName, access); - } - } - - /** - * Visits a field of the class. - * - * @param access - * the field's access flags (see {@link Opcodes}). This parameter - * also indicates if the field is synthetic and/or deprecated. - * @param name - * the field's name. - * @param desc - * the field's descriptor (see {@link Type Type}). - * @param signature - * the field's signature. May be null if the field's - * type does not use generic types. - * @param value - * the field's initial value. This parameter, which may be - * null if the field does not have an initial value, - * must be an {@link Integer}, a {@link Float}, a {@link Long}, a - * {@link Double} or a {@link String} (for int, - * float, long or String fields - * respectively). This parameter is only used for static - * fields. Its value is ignored for non static fields, which - * must be initialized through bytecode instructions in - * constructors or methods. - * @return a visitor to visit field annotations and attributes, or - * null if this class visitor is not interested in visiting - * these annotations and attributes. - */ - public FieldVisitor visitField(int access, String name, String desc, - String signature, Object value) { - if (cv != null) { - return cv.visitField(access, name, desc, signature, value); - } - return null; - } - - /** - * Visits a method of the class. This method must return a new - * {@link MethodVisitor} instance (or null) each time it is called, - * i.e., it should not return a previously returned visitor. - * - * @param access - * the method's access flags (see {@link Opcodes}). This - * parameter also indicates if the method is synthetic and/or - * deprecated. - * @param name - * the method's name. - * @param desc - * the method's descriptor (see {@link Type Type}). - * @param signature - * the method's signature. May be null if the method - * parameters, return type and exceptions do not use generic - * types. - * @param exceptions - * the internal names of the method's exception classes (see - * {@link Type#getInternalName() getInternalName}). May be - * null. - * @return an object to visit the byte code of the method, or null - * if this class visitor is not interested in visiting the code of - * this method. - */ - public MethodVisitor visitMethod(int access, String name, String desc, - String signature, String[] exceptions) { - if (cv != null) { - return cv.visitMethod(access, name, desc, signature, exceptions); - } - return null; - } - - /** - * Visits the end of the class. This method, which is the last one to be - * called, is used to inform the visitor that all the fields and methods of - * the class have been visited. - */ - public void visitEnd() { - if (cv != null) { - cv.visitEnd(); - } - } -} diff --git a/src/asm/scala/tools/asm/ClassWriter.java b/src/asm/scala/tools/asm/ClassWriter.java deleted file mode 100644 index 5c2de3f982..0000000000 --- a/src/asm/scala/tools/asm/ClassWriter.java +++ /dev/null @@ -1,1785 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm; - -/** - * A {@link ClassVisitor} that generates classes in bytecode form. More - * precisely this visitor generates a byte array conforming to the Java class - * file format. It can be used alone, to generate a Java class "from scratch", - * or with one or more {@link ClassReader ClassReader} and adapter class visitor - * to generate a modified class from one or more existing Java classes. - * - * @author Eric Bruneton - */ -public class ClassWriter extends ClassVisitor { - - /** - * Flag to automatically compute the maximum stack size and the maximum - * number of local variables of methods. If this flag is set, then the - * arguments of the {@link MethodVisitor#visitMaxs visitMaxs} method of the - * {@link MethodVisitor} returned by the {@link #visitMethod visitMethod} - * method will be ignored, and computed automatically from the signature and - * the bytecode of each method. - * - * @see #ClassWriter(int) - */ - public static final int COMPUTE_MAXS = 1; - - /** - * Flag to automatically compute the stack map frames of methods from - * scratch. If this flag is set, then the calls to the - * {@link MethodVisitor#visitFrame} method are ignored, and the stack map - * frames are recomputed from the methods bytecode. The arguments of the - * {@link MethodVisitor#visitMaxs visitMaxs} method are also ignored and - * recomputed from the bytecode. In other words, computeFrames implies - * computeMaxs. - * - * @see #ClassWriter(int) - */ - public static final int COMPUTE_FRAMES = 2; - - /** - * Pseudo access flag to distinguish between the synthetic attribute and the - * synthetic access flag. - */ - static final int ACC_SYNTHETIC_ATTRIBUTE = 0x40000; - - /** - * Factor to convert from ACC_SYNTHETIC_ATTRIBUTE to Opcode.ACC_SYNTHETIC. - */ - static final int TO_ACC_SYNTHETIC = ACC_SYNTHETIC_ATTRIBUTE - / Opcodes.ACC_SYNTHETIC; - - /** - * The type of instructions without any argument. - */ - static final int NOARG_INSN = 0; - - /** - * The type of instructions with an signed byte argument. - */ - static final int SBYTE_INSN = 1; - - /** - * The type of instructions with an signed short argument. - */ - static final int SHORT_INSN = 2; - - /** - * The type of instructions with a local variable index argument. - */ - static final int VAR_INSN = 3; - - /** - * The type of instructions with an implicit local variable index argument. - */ - static final int IMPLVAR_INSN = 4; - - /** - * The type of instructions with a type descriptor argument. - */ - static final int TYPE_INSN = 5; - - /** - * The type of field and method invocations instructions. - */ - static final int FIELDORMETH_INSN = 6; - - /** - * The type of the INVOKEINTERFACE/INVOKEDYNAMIC instruction. - */ - static final int ITFMETH_INSN = 7; - - /** - * The type of the INVOKEDYNAMIC instruction. - */ - static final int INDYMETH_INSN = 8; - - /** - * The type of instructions with a 2 bytes bytecode offset label. - */ - static final int LABEL_INSN = 9; - - /** - * The type of instructions with a 4 bytes bytecode offset label. - */ - static final int LABELW_INSN = 10; - - /** - * The type of the LDC instruction. - */ - static final int LDC_INSN = 11; - - /** - * The type of the LDC_W and LDC2_W instructions. - */ - static final int LDCW_INSN = 12; - - /** - * The type of the IINC instruction. - */ - static final int IINC_INSN = 13; - - /** - * The type of the TABLESWITCH instruction. - */ - static final int TABL_INSN = 14; - - /** - * The type of the LOOKUPSWITCH instruction. - */ - static final int LOOK_INSN = 15; - - /** - * The type of the MULTIANEWARRAY instruction. - */ - static final int MANA_INSN = 16; - - /** - * The type of the WIDE instruction. - */ - static final int WIDE_INSN = 17; - - /** - * The instruction types of all JVM opcodes. - */ - static final byte[] TYPE; - - /** - * The type of CONSTANT_Class constant pool items. - */ - static final int CLASS = 7; - - /** - * The type of CONSTANT_Fieldref constant pool items. - */ - static final int FIELD = 9; - - /** - * The type of CONSTANT_Methodref constant pool items. - */ - static final int METH = 10; - - /** - * The type of CONSTANT_InterfaceMethodref constant pool items. - */ - static final int IMETH = 11; - - /** - * The type of CONSTANT_String constant pool items. - */ - static final int STR = 8; - - /** - * The type of CONSTANT_Integer constant pool items. - */ - static final int INT = 3; - - /** - * The type of CONSTANT_Float constant pool items. - */ - static final int FLOAT = 4; - - /** - * The type of CONSTANT_Long constant pool items. - */ - static final int LONG = 5; - - /** - * The type of CONSTANT_Double constant pool items. - */ - static final int DOUBLE = 6; - - /** - * The type of CONSTANT_NameAndType constant pool items. - */ - static final int NAME_TYPE = 12; - - /** - * The type of CONSTANT_Utf8 constant pool items. - */ - static final int UTF8 = 1; - - /** - * The type of CONSTANT_MethodType constant pool items. - */ - static final int MTYPE = 16; - - /** - * The type of CONSTANT_MethodHandle constant pool items. - */ - static final int HANDLE = 15; - - /** - * The type of CONSTANT_InvokeDynamic constant pool items. - */ - static final int INDY = 18; - - /** - * The base value for all CONSTANT_MethodHandle constant pool items. - * Internally, ASM store the 9 variations of CONSTANT_MethodHandle into 9 - * different items. - */ - static final int HANDLE_BASE = 20; - - /** - * Normal type Item stored in the ClassWriter {@link ClassWriter#typeTable}, - * instead of the constant pool, in order to avoid clashes with normal - * constant pool items in the ClassWriter constant pool's hash table. - */ - static final int TYPE_NORMAL = 30; - - /** - * Uninitialized type Item stored in the ClassWriter - * {@link ClassWriter#typeTable}, instead of the constant pool, in order to - * avoid clashes with normal constant pool items in the ClassWriter constant - * pool's hash table. - */ - static final int TYPE_UNINIT = 31; - - /** - * Merged type Item stored in the ClassWriter {@link ClassWriter#typeTable}, - * instead of the constant pool, in order to avoid clashes with normal - * constant pool items in the ClassWriter constant pool's hash table. - */ - static final int TYPE_MERGED = 32; - - /** - * The type of BootstrapMethods items. These items are stored in a special - * class attribute named BootstrapMethods and not in the constant pool. - */ - static final int BSM = 33; - - /** - * The class reader from which this class writer was constructed, if any. - */ - ClassReader cr; - - /** - * Minor and major version numbers of the class to be generated. - */ - int version; - - /** - * Index of the next item to be added in the constant pool. - */ - int index; - - /** - * The constant pool of this class. - */ - final ByteVector pool; - - /** - * The constant pool's hash table data. - */ - Item[] items; - - /** - * The threshold of the constant pool's hash table. - */ - int threshold; - - /** - * A reusable key used to look for items in the {@link #items} hash table. - */ - final Item key; - - /** - * A reusable key used to look for items in the {@link #items} hash table. - */ - final Item key2; - - /** - * A reusable key used to look for items in the {@link #items} hash table. - */ - final Item key3; - - /** - * A reusable key used to look for items in the {@link #items} hash table. - */ - final Item key4; - - /** - * A type table used to temporarily store internal names that will not - * necessarily be stored in the constant pool. This type table is used by - * the control flow and data flow analysis algorithm used to compute stack - * map frames from scratch. This array associates to each index i - * the Item whose index is i. All Item objects stored in this array - * are also stored in the {@link #items} hash table. These two arrays allow - * to retrieve an Item from its index or, conversely, to get the index of an - * Item from its value. Each Item stores an internal name in its - * {@link Item#strVal1} field. - */ - Item[] typeTable; - - /** - * Number of elements in the {@link #typeTable} array. - */ - private short typeCount; - - /** - * The access flags of this class. - */ - private int access; - - /** - * The constant pool item that contains the internal name of this class. - */ - private int name; - - /** - * The internal name of this class. - */ - String thisName; - - /** - * The constant pool item that contains the signature of this class. - */ - private int signature; - - /** - * The constant pool item that contains the internal name of the super class - * of this class. - */ - private int superName; - - /** - * Number of interfaces implemented or extended by this class or interface. - */ - private int interfaceCount; - - /** - * The interfaces implemented or extended by this class or interface. More - * precisely, this array contains the indexes of the constant pool items - * that contain the internal names of these interfaces. - */ - private int[] interfaces; - - /** - * The index of the constant pool item that contains the name of the source - * file from which this class was compiled. - */ - private int sourceFile; - - /** - * The SourceDebug attribute of this class. - */ - private ByteVector sourceDebug; - - /** - * The constant pool item that contains the name of the enclosing class of - * this class. - */ - private int enclosingMethodOwner; - - /** - * The constant pool item that contains the name and descriptor of the - * enclosing method of this class. - */ - private int enclosingMethod; - - /** - * The runtime visible annotations of this class. - */ - private AnnotationWriter anns; - - /** - * The runtime invisible annotations of this class. - */ - private AnnotationWriter ianns; - - /** - * The runtime visible type annotations of this class. - */ - private AnnotationWriter tanns; - - /** - * The runtime invisible type annotations of this class. - */ - private AnnotationWriter itanns; - - /** - * The non standard attributes of this class. - */ - private Attribute attrs; - - /** - * The number of entries in the InnerClasses attribute. - */ - private int innerClassesCount; - - /** - * The InnerClasses attribute. - */ - private ByteVector innerClasses; - - /** - * The number of entries in the BootstrapMethods attribute. - */ - int bootstrapMethodsCount; - - /** - * The BootstrapMethods attribute. - */ - ByteVector bootstrapMethods; - - /** - * The fields of this class. These fields are stored in a linked list of - * {@link FieldWriter} objects, linked to each other by their - * {@link FieldWriter#fv} field. This field stores the first element of this - * list. - */ - FieldWriter firstField; - - /** - * The fields of this class. These fields are stored in a linked list of - * {@link FieldWriter} objects, linked to each other by their - * {@link FieldWriter#fv} field. This field stores the last element of this - * list. - */ - FieldWriter lastField; - - /** - * The methods of this class. These methods are stored in a linked list of - * {@link MethodWriter} objects, linked to each other by their - * {@link MethodWriter#mv} field. This field stores the first element of - * this list. - */ - MethodWriter firstMethod; - - /** - * The methods of this class. These methods are stored in a linked list of - * {@link MethodWriter} objects, linked to each other by their - * {@link MethodWriter#mv} field. This field stores the last element of this - * list. - */ - MethodWriter lastMethod; - - /** - * true if the maximum stack size and number of local variables - * must be automatically computed. - */ - private boolean computeMaxs; - - /** - * true if the stack map frames must be recomputed from scratch. - */ - private boolean computeFrames; - - /** - * true if the stack map tables of this class are invalid. The - * {@link MethodWriter#resizeInstructions} method cannot transform existing - * stack map tables, and so produces potentially invalid classes when it is - * executed. In this case the class is reread and rewritten with the - * {@link #COMPUTE_FRAMES} option (the resizeInstructions method can resize - * stack map tables when this option is used). - */ - boolean invalidFrames; - - // ------------------------------------------------------------------------ - // Static initializer - // ------------------------------------------------------------------------ - - /** - * Computes the instruction types of JVM opcodes. - */ - static { - int i; - byte[] b = new byte[220]; - String s = "AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD" - + "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" - + "AAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAA" - + "AAAAGGGGGGGHIFBFAAFFAARQJJKKJJJJJJJJJJJJJJJJJJ"; - for (i = 0; i < b.length; ++i) { - b[i] = (byte) (s.charAt(i) - 'A'); - } - TYPE = b; - - // code to generate the above string - // - // // SBYTE_INSN instructions - // b[Constants.NEWARRAY] = SBYTE_INSN; - // b[Constants.BIPUSH] = SBYTE_INSN; - // - // // SHORT_INSN instructions - // b[Constants.SIPUSH] = SHORT_INSN; - // - // // (IMPL)VAR_INSN instructions - // b[Constants.RET] = VAR_INSN; - // for (i = Constants.ILOAD; i <= Constants.ALOAD; ++i) { - // b[i] = VAR_INSN; - // } - // for (i = Constants.ISTORE; i <= Constants.ASTORE; ++i) { - // b[i] = VAR_INSN; - // } - // for (i = 26; i <= 45; ++i) { // ILOAD_0 to ALOAD_3 - // b[i] = IMPLVAR_INSN; - // } - // for (i = 59; i <= 78; ++i) { // ISTORE_0 to ASTORE_3 - // b[i] = IMPLVAR_INSN; - // } - // - // // TYPE_INSN instructions - // b[Constants.NEW] = TYPE_INSN; - // b[Constants.ANEWARRAY] = TYPE_INSN; - // b[Constants.CHECKCAST] = TYPE_INSN; - // b[Constants.INSTANCEOF] = TYPE_INSN; - // - // // (Set)FIELDORMETH_INSN instructions - // for (i = Constants.GETSTATIC; i <= Constants.INVOKESTATIC; ++i) { - // b[i] = FIELDORMETH_INSN; - // } - // b[Constants.INVOKEINTERFACE] = ITFMETH_INSN; - // b[Constants.INVOKEDYNAMIC] = INDYMETH_INSN; - // - // // LABEL(W)_INSN instructions - // for (i = Constants.IFEQ; i <= Constants.JSR; ++i) { - // b[i] = LABEL_INSN; - // } - // b[Constants.IFNULL] = LABEL_INSN; - // b[Constants.IFNONNULL] = LABEL_INSN; - // b[200] = LABELW_INSN; // GOTO_W - // b[201] = LABELW_INSN; // JSR_W - // // temporary opcodes used internally by ASM - see Label and - // MethodWriter - // for (i = 202; i < 220; ++i) { - // b[i] = LABEL_INSN; - // } - // - // // LDC(_W) instructions - // b[Constants.LDC] = LDC_INSN; - // b[19] = LDCW_INSN; // LDC_W - // b[20] = LDCW_INSN; // LDC2_W - // - // // special instructions - // b[Constants.IINC] = IINC_INSN; - // b[Constants.TABLESWITCH] = TABL_INSN; - // b[Constants.LOOKUPSWITCH] = LOOK_INSN; - // b[Constants.MULTIANEWARRAY] = MANA_INSN; - // b[196] = WIDE_INSN; // WIDE - // - // for (i = 0; i < b.length; ++i) { - // System.err.print((char)('A' + b[i])); - // } - // System.err.println(); - } - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructs a new {@link ClassWriter} object. - * - * @param flags - * option flags that can be used to modify the default behavior - * of this class. See {@link #COMPUTE_MAXS}, - * {@link #COMPUTE_FRAMES}. - */ - public ClassWriter(final int flags) { - super(Opcodes.ASM5); - index = 1; - pool = new ByteVector(); - items = new Item[256]; - threshold = (int) (0.75d * items.length); - key = new Item(); - key2 = new Item(); - key3 = new Item(); - key4 = new Item(); - this.computeMaxs = (flags & COMPUTE_MAXS) != 0; - this.computeFrames = (flags & COMPUTE_FRAMES) != 0; - } - - /** - * Constructs a new {@link ClassWriter} object and enables optimizations for - * "mostly add" bytecode transformations. These optimizations are the - * following: - * - *
    - *
  • The constant pool from the original class is copied as is in the new - * class, which saves time. New constant pool entries will be added at the - * end if necessary, but unused constant pool entries won't be - * removed.
  • - *
  • Methods that are not transformed are copied as is in the new class, - * directly from the original class bytecode (i.e. without emitting visit - * events for all the method instructions), which saves a lot of - * time. Untransformed methods are detected by the fact that the - * {@link ClassReader} receives {@link MethodVisitor} objects that come from - * a {@link ClassWriter} (and not from any other {@link ClassVisitor} - * instance).
  • - *
- * - * @param classReader - * the {@link ClassReader} used to read the original class. It - * will be used to copy the entire constant pool from the - * original class and also to copy other fragments of original - * bytecode where applicable. - * @param flags - * option flags that can be used to modify the default behavior - * of this class. These option flags do not affect methods - * that are copied as is in the new class. This means that the - * maximum stack size nor the stack frames will be computed for - * these methods. See {@link #COMPUTE_MAXS}, - * {@link #COMPUTE_FRAMES}. - */ - public ClassWriter(final ClassReader classReader, final int flags) { - this(flags); - classReader.copyPool(this); - this.cr = classReader; - } - - // ------------------------------------------------------------------------ - // Implementation of the ClassVisitor abstract class - // ------------------------------------------------------------------------ - - @Override - public final void visit(final int version, final int access, - final String name, final String signature, final String superName, - final String[] interfaces) { - this.version = version; - this.access = access; - this.name = newClass(name); - thisName = name; - if (ClassReader.SIGNATURES && signature != null) { - this.signature = newUTF8(signature); - } - this.superName = superName == null ? 0 : newClass(superName); - if (interfaces != null && interfaces.length > 0) { - interfaceCount = interfaces.length; - this.interfaces = new int[interfaceCount]; - for (int i = 0; i < interfaceCount; ++i) { - this.interfaces[i] = newClass(interfaces[i]); - } - } - } - - @Override - public final void visitSource(final String file, final String debug) { - if (file != null) { - sourceFile = newUTF8(file); - } - if (debug != null) { - sourceDebug = new ByteVector().encodeUTF8(debug, 0, - Integer.MAX_VALUE); - } - } - - @Override - public final void visitOuterClass(final String owner, final String name, - final String desc) { - enclosingMethodOwner = newClass(owner); - if (name != null && desc != null) { - enclosingMethod = newNameType(name, desc); - } - } - - @Override - public final AnnotationVisitor visitAnnotation(final String desc, - final boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - // write type, and reserve space for values count - bv.putShort(newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, 2); - if (visible) { - aw.next = anns; - anns = aw; - } else { - aw.next = ianns; - ianns = aw; - } - return aw; - } - - @Override - public final AnnotationVisitor visitTypeAnnotation(int typeRef, - TypePath typePath, final String desc, final boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - // write target_type and target_info - AnnotationWriter.putTarget(typeRef, typePath, bv); - // write type, and reserve space for values count - bv.putShort(newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(this, true, bv, bv, - bv.length - 2); - if (visible) { - aw.next = tanns; - tanns = aw; - } else { - aw.next = itanns; - itanns = aw; - } - return aw; - } - - @Override - public final void visitAttribute(final Attribute attr) { - attr.next = attrs; - attrs = attr; - } - - @Override - public final void visitInnerClass(final String name, - final String outerName, final String innerName, final int access) { - if (innerClasses == null) { - innerClasses = new ByteVector(); - } - // Sec. 4.7.6 of the JVMS states "Every CONSTANT_Class_info entry in the - // constant_pool table which represents a class or interface C that is - // not a package member must have exactly one corresponding entry in the - // classes array". To avoid duplicates we keep track in the intVal field - // of the Item of each CONSTANT_Class_info entry C whether an inner - // class entry has already been added for C (this field is unused for - // class entries, and changing its value does not change the hashcode - // and equality tests). If so we store the index of this inner class - // entry (plus one) in intVal. This hack allows duplicate detection in - // O(1) time. - Item nameItem = newClassItem(name); - if (nameItem.intVal == 0) { - ++innerClassesCount; - innerClasses.putShort(nameItem.index); - innerClasses.putShort(outerName == null ? 0 : newClass(outerName)); - innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName)); - innerClasses.putShort(access); - nameItem.intVal = innerClassesCount; - } else { - // Compare the inner classes entry nameItem.intVal - 1 with the - // arguments of this method and throw an exception if there is a - // difference? - } - } - - @Override - public final FieldVisitor visitField(final int access, final String name, - final String desc, final String signature, final Object value) { - return new FieldWriter(this, access, name, desc, signature, value); - } - - @Override - public final MethodVisitor visitMethod(final int access, final String name, - final String desc, final String signature, final String[] exceptions) { - return new MethodWriter(this, access, name, desc, signature, - exceptions, computeMaxs, computeFrames); - } - - @Override - public final void visitEnd() { - } - - // ------------------------------------------------------------------------ - // Other public methods - // ------------------------------------------------------------------------ - - /** - * Returns the bytecode of the class that was build with this class writer. - * - * @return the bytecode of the class that was build with this class writer. - */ - public byte[] toByteArray() { - if (index > 0xFFFF) { - throw new RuntimeException("Class file too large!"); - } - // computes the real size of the bytecode of this class - int size = 24 + 2 * interfaceCount; - int nbFields = 0; - FieldWriter fb = firstField; - while (fb != null) { - ++nbFields; - size += fb.getSize(); - fb = (FieldWriter) fb.fv; - } - int nbMethods = 0; - MethodWriter mb = firstMethod; - while (mb != null) { - ++nbMethods; - size += mb.getSize(); - mb = (MethodWriter) mb.mv; - } - int attributeCount = 0; - if (bootstrapMethods != null) { - // we put it as first attribute in order to improve a bit - // ClassReader.copyBootstrapMethods - ++attributeCount; - size += 8 + bootstrapMethods.length; - newUTF8("BootstrapMethods"); - } - if (ClassReader.SIGNATURES && signature != 0) { - ++attributeCount; - size += 8; - newUTF8("Signature"); - } - if (sourceFile != 0) { - ++attributeCount; - size += 8; - newUTF8("SourceFile"); - } - if (sourceDebug != null) { - ++attributeCount; - size += sourceDebug.length + 6; - newUTF8("SourceDebugExtension"); - } - if (enclosingMethodOwner != 0) { - ++attributeCount; - size += 10; - newUTF8("EnclosingMethod"); - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - ++attributeCount; - size += 6; - newUTF8("Deprecated"); - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0) { - if ((version & 0xFFFF) < Opcodes.V1_5 - || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) { - ++attributeCount; - size += 6; - newUTF8("Synthetic"); - } - } - if (innerClasses != null) { - ++attributeCount; - size += 8 + innerClasses.length; - newUTF8("InnerClasses"); - } - if (ClassReader.ANNOTATIONS && anns != null) { - ++attributeCount; - size += 8 + anns.getSize(); - newUTF8("RuntimeVisibleAnnotations"); - } - if (ClassReader.ANNOTATIONS && ianns != null) { - ++attributeCount; - size += 8 + ianns.getSize(); - newUTF8("RuntimeInvisibleAnnotations"); - } - if (ClassReader.ANNOTATIONS && tanns != null) { - ++attributeCount; - size += 8 + tanns.getSize(); - newUTF8("RuntimeVisibleTypeAnnotations"); - } - if (ClassReader.ANNOTATIONS && itanns != null) { - ++attributeCount; - size += 8 + itanns.getSize(); - newUTF8("RuntimeInvisibleTypeAnnotations"); - } - if (attrs != null) { - attributeCount += attrs.getCount(); - size += attrs.getSize(this, null, 0, -1, -1); - } - size += pool.length; - // allocates a byte vector of this size, in order to avoid unnecessary - // arraycopy operations in the ByteVector.enlarge() method - ByteVector out = new ByteVector(size); - out.putInt(0xCAFEBABE).putInt(version); - out.putShort(index).putByteArray(pool.data, 0, pool.length); - int mask = Opcodes.ACC_DEPRECATED | ACC_SYNTHETIC_ATTRIBUTE - | ((access & ACC_SYNTHETIC_ATTRIBUTE) / TO_ACC_SYNTHETIC); - out.putShort(access & ~mask).putShort(name).putShort(superName); - out.putShort(interfaceCount); - for (int i = 0; i < interfaceCount; ++i) { - out.putShort(interfaces[i]); - } - out.putShort(nbFields); - fb = firstField; - while (fb != null) { - fb.put(out); - fb = (FieldWriter) fb.fv; - } - out.putShort(nbMethods); - mb = firstMethod; - while (mb != null) { - mb.put(out); - mb = (MethodWriter) mb.mv; - } - out.putShort(attributeCount); - if (bootstrapMethods != null) { - out.putShort(newUTF8("BootstrapMethods")); - out.putInt(bootstrapMethods.length + 2).putShort( - bootstrapMethodsCount); - out.putByteArray(bootstrapMethods.data, 0, bootstrapMethods.length); - } - if (ClassReader.SIGNATURES && signature != 0) { - out.putShort(newUTF8("Signature")).putInt(2).putShort(signature); - } - if (sourceFile != 0) { - out.putShort(newUTF8("SourceFile")).putInt(2).putShort(sourceFile); - } - if (sourceDebug != null) { - int len = sourceDebug.length; - out.putShort(newUTF8("SourceDebugExtension")).putInt(len); - out.putByteArray(sourceDebug.data, 0, len); - } - if (enclosingMethodOwner != 0) { - out.putShort(newUTF8("EnclosingMethod")).putInt(4); - out.putShort(enclosingMethodOwner).putShort(enclosingMethod); - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - out.putShort(newUTF8("Deprecated")).putInt(0); - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0) { - if ((version & 0xFFFF) < Opcodes.V1_5 - || (access & ACC_SYNTHETIC_ATTRIBUTE) != 0) { - out.putShort(newUTF8("Synthetic")).putInt(0); - } - } - if (innerClasses != null) { - out.putShort(newUTF8("InnerClasses")); - out.putInt(innerClasses.length + 2).putShort(innerClassesCount); - out.putByteArray(innerClasses.data, 0, innerClasses.length); - } - if (ClassReader.ANNOTATIONS && anns != null) { - out.putShort(newUTF8("RuntimeVisibleAnnotations")); - anns.put(out); - } - if (ClassReader.ANNOTATIONS && ianns != null) { - out.putShort(newUTF8("RuntimeInvisibleAnnotations")); - ianns.put(out); - } - if (ClassReader.ANNOTATIONS && tanns != null) { - out.putShort(newUTF8("RuntimeVisibleTypeAnnotations")); - tanns.put(out); - } - if (ClassReader.ANNOTATIONS && itanns != null) { - out.putShort(newUTF8("RuntimeInvisibleTypeAnnotations")); - itanns.put(out); - } - if (attrs != null) { - attrs.put(this, null, 0, -1, -1, out); - } - if (invalidFrames) { - anns = null; - ianns = null; - attrs = null; - innerClassesCount = 0; - innerClasses = null; - bootstrapMethodsCount = 0; - bootstrapMethods = null; - firstField = null; - lastField = null; - firstMethod = null; - lastMethod = null; - computeMaxs = false; - computeFrames = true; - invalidFrames = false; - new ClassReader(out.data).accept(this, ClassReader.SKIP_FRAMES); - return toByteArray(); - } - return out.data; - } - - // ------------------------------------------------------------------------ - // Utility methods: constant pool management - // ------------------------------------------------------------------------ - - /** - * Adds a number or string constant to the constant pool of the class being - * build. Does nothing if the constant pool already contains a similar item. - * - * @param cst - * the value of the constant to be added to the constant pool. - * This parameter must be an {@link Integer}, a {@link Float}, a - * {@link Long}, a {@link Double}, a {@link String} or a - * {@link Type}. - * @return a new or already existing constant item with the given value. - */ - Item newConstItem(final Object cst) { - if (cst instanceof Integer) { - int val = ((Integer) cst).intValue(); - return newInteger(val); - } else if (cst instanceof Byte) { - int val = ((Byte) cst).intValue(); - return newInteger(val); - } else if (cst instanceof Character) { - int val = ((Character) cst).charValue(); - return newInteger(val); - } else if (cst instanceof Short) { - int val = ((Short) cst).intValue(); - return newInteger(val); - } else if (cst instanceof Boolean) { - int val = ((Boolean) cst).booleanValue() ? 1 : 0; - return newInteger(val); - } else if (cst instanceof Float) { - float val = ((Float) cst).floatValue(); - return newFloat(val); - } else if (cst instanceof Long) { - long val = ((Long) cst).longValue(); - return newLong(val); - } else if (cst instanceof Double) { - double val = ((Double) cst).doubleValue(); - return newDouble(val); - } else if (cst instanceof String) { - return newString((String) cst); - } else if (cst instanceof Type) { - Type t = (Type) cst; - int s = t.getSort(); - if (s == Type.OBJECT) { - return newClassItem(t.getInternalName()); - } else if (s == Type.METHOD) { - return newMethodTypeItem(t.getDescriptor()); - } else { // s == primitive type or array - return newClassItem(t.getDescriptor()); - } - } else if (cst instanceof Handle) { - Handle h = (Handle) cst; - return newHandleItem(h.tag, h.owner, h.name, h.desc); - } else { - throw new IllegalArgumentException("value " + cst); - } - } - - /** - * Adds a number or string constant to the constant pool of the class being - * build. Does nothing if the constant pool already contains a similar item. - * This method is intended for {@link Attribute} sub classes, and is - * normally not needed by class generators or adapters. - * - * @param cst - * the value of the constant to be added to the constant pool. - * This parameter must be an {@link Integer}, a {@link Float}, a - * {@link Long}, a {@link Double} or a {@link String}. - * @return the index of a new or already existing constant item with the - * given value. - */ - public int newConst(final Object cst) { - return newConstItem(cst).index; - } - - /** - * Adds an UTF8 string to the constant pool of the class being build. Does - * nothing if the constant pool already contains a similar item. This - * method is intended for {@link Attribute} sub classes, and is normally not - * needed by class generators or adapters. - * - * @param value - * the String value. - * @return the index of a new or already existing UTF8 item. - */ - public int newUTF8(final String value) { - key.set(UTF8, value, null, null); - Item result = get(key); - if (result == null) { - pool.putByte(UTF8).putUTF8(value); - result = new Item(index++, key); - put(result); - } - return result.index; - } - - /** - * Adds a class reference to the constant pool of the class being build. - * Does nothing if the constant pool already contains a similar item. - * This method is intended for {@link Attribute} sub classes, and is - * normally not needed by class generators or adapters. - * - * @param value - * the internal name of the class. - * @return a new or already existing class reference item. - */ - Item newClassItem(final String value) { - key2.set(CLASS, value, null, null); - Item result = get(key2); - if (result == null) { - pool.put12(CLASS, newUTF8(value)); - result = new Item(index++, key2); - put(result); - } - return result; - } - - /** - * Adds a class reference to the constant pool of the class being build. - * Does nothing if the constant pool already contains a similar item. - * This method is intended for {@link Attribute} sub classes, and is - * normally not needed by class generators or adapters. - * - * @param value - * the internal name of the class. - * @return the index of a new or already existing class reference item. - */ - public int newClass(final String value) { - return newClassItem(value).index; - } - - /** - * Adds a method type reference to the constant pool of the class being - * build. Does nothing if the constant pool already contains a similar item. - * This method is intended for {@link Attribute} sub classes, and is - * normally not needed by class generators or adapters. - * - * @param methodDesc - * method descriptor of the method type. - * @return a new or already existing method type reference item. - */ - Item newMethodTypeItem(final String methodDesc) { - key2.set(MTYPE, methodDesc, null, null); - Item result = get(key2); - if (result == null) { - pool.put12(MTYPE, newUTF8(methodDesc)); - result = new Item(index++, key2); - put(result); - } - return result; - } - - /** - * Adds a method type reference to the constant pool of the class being - * build. Does nothing if the constant pool already contains a similar item. - * This method is intended for {@link Attribute} sub classes, and is - * normally not needed by class generators or adapters. - * - * @param methodDesc - * method descriptor of the method type. - * @return the index of a new or already existing method type reference - * item. - */ - public int newMethodType(final String methodDesc) { - return newMethodTypeItem(methodDesc).index; - } - - /** - * Adds a handle to the constant pool of the class being build. Does nothing - * if the constant pool already contains a similar item. This method is - * intended for {@link Attribute} sub classes, and is normally not needed by - * class generators or adapters. - * - * @param tag - * the kind of this handle. Must be {@link Opcodes#H_GETFIELD}, - * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, - * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, - * {@link Opcodes#H_INVOKESTATIC}, - * {@link Opcodes#H_INVOKESPECIAL}, - * {@link Opcodes#H_NEWINVOKESPECIAL} or - * {@link Opcodes#H_INVOKEINTERFACE}. - * @param owner - * the internal name of the field or method owner class. - * @param name - * the name of the field or method. - * @param desc - * the descriptor of the field or method. - * @return a new or an already existing method type reference item. - */ - Item newHandleItem(final int tag, final String owner, final String name, - final String desc) { - key4.set(HANDLE_BASE + tag, owner, name, desc); - Item result = get(key4); - if (result == null) { - if (tag <= Opcodes.H_PUTSTATIC) { - put112(HANDLE, tag, newField(owner, name, desc)); - } else { - put112(HANDLE, - tag, - newMethod(owner, name, desc, - tag == Opcodes.H_INVOKEINTERFACE)); - } - result = new Item(index++, key4); - put(result); - } - return result; - } - - /** - * Adds a handle to the constant pool of the class being build. Does nothing - * if the constant pool already contains a similar item. This method is - * intended for {@link Attribute} sub classes, and is normally not needed by - * class generators or adapters. - * - * @param tag - * the kind of this handle. Must be {@link Opcodes#H_GETFIELD}, - * {@link Opcodes#H_GETSTATIC}, {@link Opcodes#H_PUTFIELD}, - * {@link Opcodes#H_PUTSTATIC}, {@link Opcodes#H_INVOKEVIRTUAL}, - * {@link Opcodes#H_INVOKESTATIC}, - * {@link Opcodes#H_INVOKESPECIAL}, - * {@link Opcodes#H_NEWINVOKESPECIAL} or - * {@link Opcodes#H_INVOKEINTERFACE}. - * @param owner - * the internal name of the field or method owner class. - * @param name - * the name of the field or method. - * @param desc - * the descriptor of the field or method. - * @return the index of a new or already existing method type reference - * item. - */ - public int newHandle(final int tag, final String owner, final String name, - final String desc) { - return newHandleItem(tag, owner, name, desc).index; - } - - /** - * Adds an invokedynamic reference to the constant pool of the class being - * build. Does nothing if the constant pool already contains a similar item. - * This method is intended for {@link Attribute} sub classes, and is - * normally not needed by class generators or adapters. - * - * @param name - * name of the invoked method. - * @param desc - * descriptor of the invoke method. - * @param bsm - * the bootstrap method. - * @param bsmArgs - * the bootstrap method constant arguments. - * - * @return a new or an already existing invokedynamic type reference item. - */ - Item newInvokeDynamicItem(final String name, final String desc, - final Handle bsm, final Object... bsmArgs) { - // cache for performance - ByteVector bootstrapMethods = this.bootstrapMethods; - if (bootstrapMethods == null) { - bootstrapMethods = this.bootstrapMethods = new ByteVector(); - } - - int position = bootstrapMethods.length; // record current position - - int hashCode = bsm.hashCode(); - bootstrapMethods.putShort(newHandle(bsm.tag, bsm.owner, bsm.name, - bsm.desc)); - - int argsLength = bsmArgs.length; - bootstrapMethods.putShort(argsLength); - - for (int i = 0; i < argsLength; i++) { - Object bsmArg = bsmArgs[i]; - hashCode ^= bsmArg.hashCode(); - bootstrapMethods.putShort(newConst(bsmArg)); - } - - byte[] data = bootstrapMethods.data; - int length = (1 + 1 + argsLength) << 1; // (bsm + argCount + arguments) - hashCode &= 0x7FFFFFFF; - Item result = items[hashCode % items.length]; - loop: while (result != null) { - if (result.type != BSM || result.hashCode != hashCode) { - result = result.next; - continue; - } - - // because the data encode the size of the argument - // we don't need to test if these size are equals - int resultPosition = result.intVal; - for (int p = 0; p < length; p++) { - if (data[position + p] != data[resultPosition + p]) { - result = result.next; - continue loop; - } - } - break; - } - - int bootstrapMethodIndex; - if (result != null) { - bootstrapMethodIndex = result.index; - bootstrapMethods.length = position; // revert to old position - } else { - bootstrapMethodIndex = bootstrapMethodsCount++; - result = new Item(bootstrapMethodIndex); - result.set(position, hashCode); - put(result); - } - - // now, create the InvokeDynamic constant - key3.set(name, desc, bootstrapMethodIndex); - result = get(key3); - if (result == null) { - put122(INDY, bootstrapMethodIndex, newNameType(name, desc)); - result = new Item(index++, key3); - put(result); - } - return result; - } - - /** - * Adds an invokedynamic reference to the constant pool of the class being - * build. Does nothing if the constant pool already contains a similar item. - * This method is intended for {@link Attribute} sub classes, and is - * normally not needed by class generators or adapters. - * - * @param name - * name of the invoked method. - * @param desc - * descriptor of the invoke method. - * @param bsm - * the bootstrap method. - * @param bsmArgs - * the bootstrap method constant arguments. - * - * @return the index of a new or already existing invokedynamic reference - * item. - */ - public int newInvokeDynamic(final String name, final String desc, - final Handle bsm, final Object... bsmArgs) { - return newInvokeDynamicItem(name, desc, bsm, bsmArgs).index; - } - - /** - * Adds a field reference to the constant pool of the class being build. - * Does nothing if the constant pool already contains a similar item. - * - * @param owner - * the internal name of the field's owner class. - * @param name - * the field's name. - * @param desc - * the field's descriptor. - * @return a new or already existing field reference item. - */ - Item newFieldItem(final String owner, final String name, final String desc) { - key3.set(FIELD, owner, name, desc); - Item result = get(key3); - if (result == null) { - put122(FIELD, newClass(owner), newNameType(name, desc)); - result = new Item(index++, key3); - put(result); - } - return result; - } - - /** - * Adds a field reference to the constant pool of the class being build. - * Does nothing if the constant pool already contains a similar item. - * This method is intended for {@link Attribute} sub classes, and is - * normally not needed by class generators or adapters. - * - * @param owner - * the internal name of the field's owner class. - * @param name - * the field's name. - * @param desc - * the field's descriptor. - * @return the index of a new or already existing field reference item. - */ - public int newField(final String owner, final String name, final String desc) { - return newFieldItem(owner, name, desc).index; - } - - /** - * Adds a method reference to the constant pool of the class being build. - * Does nothing if the constant pool already contains a similar item. - * - * @param owner - * the internal name of the method's owner class. - * @param name - * the method's name. - * @param desc - * the method's descriptor. - * @param itf - * true if owner is an interface. - * @return a new or already existing method reference item. - */ - Item newMethodItem(final String owner, final String name, - final String desc, final boolean itf) { - int type = itf ? IMETH : METH; - key3.set(type, owner, name, desc); - Item result = get(key3); - if (result == null) { - put122(type, newClass(owner), newNameType(name, desc)); - result = new Item(index++, key3); - put(result); - } - return result; - } - - /** - * Adds a method reference to the constant pool of the class being build. - * Does nothing if the constant pool already contains a similar item. - * This method is intended for {@link Attribute} sub classes, and is - * normally not needed by class generators or adapters. - * - * @param owner - * the internal name of the method's owner class. - * @param name - * the method's name. - * @param desc - * the method's descriptor. - * @param itf - * true if owner is an interface. - * @return the index of a new or already existing method reference item. - */ - public int newMethod(final String owner, final String name, - final String desc, final boolean itf) { - return newMethodItem(owner, name, desc, itf).index; - } - - /** - * Adds an integer to the constant pool of the class being build. Does - * nothing if the constant pool already contains a similar item. - * - * @param value - * the int value. - * @return a new or already existing int item. - */ - Item newInteger(final int value) { - key.set(value); - Item result = get(key); - if (result == null) { - pool.putByte(INT).putInt(value); - result = new Item(index++, key); - put(result); - } - return result; - } - - /** - * Adds a float to the constant pool of the class being build. Does nothing - * if the constant pool already contains a similar item. - * - * @param value - * the float value. - * @return a new or already existing float item. - */ - Item newFloat(final float value) { - key.set(value); - Item result = get(key); - if (result == null) { - pool.putByte(FLOAT).putInt(key.intVal); - result = new Item(index++, key); - put(result); - } - return result; - } - - /** - * Adds a long to the constant pool of the class being build. Does nothing - * if the constant pool already contains a similar item. - * - * @param value - * the long value. - * @return a new or already existing long item. - */ - Item newLong(final long value) { - key.set(value); - Item result = get(key); - if (result == null) { - pool.putByte(LONG).putLong(value); - result = new Item(index, key); - index += 2; - put(result); - } - return result; - } - - /** - * Adds a double to the constant pool of the class being build. Does nothing - * if the constant pool already contains a similar item. - * - * @param value - * the double value. - * @return a new or already existing double item. - */ - Item newDouble(final double value) { - key.set(value); - Item result = get(key); - if (result == null) { - pool.putByte(DOUBLE).putLong(key.longVal); - result = new Item(index, key); - index += 2; - put(result); - } - return result; - } - - /** - * Adds a string to the constant pool of the class being build. Does nothing - * if the constant pool already contains a similar item. - * - * @param value - * the String value. - * @return a new or already existing string item. - */ - private Item newString(final String value) { - key2.set(STR, value, null, null); - Item result = get(key2); - if (result == null) { - pool.put12(STR, newUTF8(value)); - result = new Item(index++, key2); - put(result); - } - return result; - } - - /** - * Adds a name and type to the constant pool of the class being build. Does - * nothing if the constant pool already contains a similar item. This - * method is intended for {@link Attribute} sub classes, and is normally not - * needed by class generators or adapters. - * - * @param name - * a name. - * @param desc - * a type descriptor. - * @return the index of a new or already existing name and type item. - */ - public int newNameType(final String name, final String desc) { - return newNameTypeItem(name, desc).index; - } - - /** - * Adds a name and type to the constant pool of the class being build. Does - * nothing if the constant pool already contains a similar item. - * - * @param name - * a name. - * @param desc - * a type descriptor. - * @return a new or already existing name and type item. - */ - Item newNameTypeItem(final String name, final String desc) { - key2.set(NAME_TYPE, name, desc, null); - Item result = get(key2); - if (result == null) { - put122(NAME_TYPE, newUTF8(name), newUTF8(desc)); - result = new Item(index++, key2); - put(result); - } - return result; - } - - /** - * Adds the given internal name to {@link #typeTable} and returns its index. - * Does nothing if the type table already contains this internal name. - * - * @param type - * the internal name to be added to the type table. - * @return the index of this internal name in the type table. - */ - int addType(final String type) { - key.set(TYPE_NORMAL, type, null, null); - Item result = get(key); - if (result == null) { - result = addType(key); - } - return result.index; - } - - /** - * Adds the given "uninitialized" type to {@link #typeTable} and returns its - * index. This method is used for UNINITIALIZED types, made of an internal - * name and a bytecode offset. - * - * @param type - * the internal name to be added to the type table. - * @param offset - * the bytecode offset of the NEW instruction that created this - * UNINITIALIZED type value. - * @return the index of this internal name in the type table. - */ - int addUninitializedType(final String type, final int offset) { - key.type = TYPE_UNINIT; - key.intVal = offset; - key.strVal1 = type; - key.hashCode = 0x7FFFFFFF & (TYPE_UNINIT + type.hashCode() + offset); - Item result = get(key); - if (result == null) { - result = addType(key); - } - return result.index; - } - - /** - * Adds the given Item to {@link #typeTable}. - * - * @param item - * the value to be added to the type table. - * @return the added Item, which a new Item instance with the same value as - * the given Item. - */ - private Item addType(final Item item) { - ++typeCount; - Item result = new Item(typeCount, key); - put(result); - if (typeTable == null) { - typeTable = new Item[16]; - } - if (typeCount == typeTable.length) { - Item[] newTable = new Item[2 * typeTable.length]; - System.arraycopy(typeTable, 0, newTable, 0, typeTable.length); - typeTable = newTable; - } - typeTable[typeCount] = result; - return result; - } - - /** - * Returns the index of the common super type of the two given types. This - * method calls {@link #getCommonSuperClass} and caches the result in the - * {@link #items} hash table to speedup future calls with the same - * parameters. - * - * @param type1 - * index of an internal name in {@link #typeTable}. - * @param type2 - * index of an internal name in {@link #typeTable}. - * @return the index of the common super type of the two given types. - */ - int getMergedType(final int type1, final int type2) { - key2.type = TYPE_MERGED; - key2.longVal = type1 | (((long) type2) << 32); - key2.hashCode = 0x7FFFFFFF & (TYPE_MERGED + type1 + type2); - Item result = get(key2); - if (result == null) { - String t = typeTable[type1].strVal1; - String u = typeTable[type2].strVal1; - key2.intVal = addType(getCommonSuperClass(t, u)); - result = new Item((short) 0, key2); - put(result); - } - return result.intVal; - } - - /** - * Returns the common super type of the two given types. The default - * implementation of this method loads the two given classes and uses - * the java.lang.Class methods to find the common super class. It can be - * overridden to compute this common super type in other ways, in particular - * without actually loading any class, or to take into account the class - * that is currently being generated by this ClassWriter, which can of - * course not be loaded since it is under construction. - * - * @param type1 - * the internal name of a class. - * @param type2 - * the internal name of another class. - * @return the internal name of the common super class of the two given - * classes. - */ - protected String getCommonSuperClass(final String type1, final String type2) { - Class c, d; - ClassLoader classLoader = getClass().getClassLoader(); - try { - c = Class.forName(type1.replace('/', '.'), false, classLoader); - d = Class.forName(type2.replace('/', '.'), false, classLoader); - } catch (Exception e) { - throw new RuntimeException(e.toString()); - } - if (c.isAssignableFrom(d)) { - return type1; - } - if (d.isAssignableFrom(c)) { - return type2; - } - if (c.isInterface() || d.isInterface()) { - return "java/lang/Object"; - } else { - do { - c = c.getSuperclass(); - } while (!c.isAssignableFrom(d)); - return c.getName().replace('.', '/'); - } - } - - /** - * Returns the constant pool's hash table item which is equal to the given - * item. - * - * @param key - * a constant pool item. - * @return the constant pool's hash table item which is equal to the given - * item, or null if there is no such item. - */ - private Item get(final Item key) { - Item i = items[key.hashCode % items.length]; - while (i != null && (i.type != key.type || !key.isEqualTo(i))) { - i = i.next; - } - return i; - } - - /** - * Puts the given item in the constant pool's hash table. The hash table - * must not already contains this item. - * - * @param i - * the item to be added to the constant pool's hash table. - */ - private void put(final Item i) { - if (index + typeCount > threshold) { - int ll = items.length; - int nl = ll * 2 + 1; - Item[] newItems = new Item[nl]; - for (int l = ll - 1; l >= 0; --l) { - Item j = items[l]; - while (j != null) { - int index = j.hashCode % newItems.length; - Item k = j.next; - j.next = newItems[index]; - newItems[index] = j; - j = k; - } - } - items = newItems; - threshold = (int) (nl * 0.75); - } - int index = i.hashCode % items.length; - i.next = items[index]; - items[index] = i; - } - - /** - * Find item that whose index is `index`. - */ - public Item findItemByIndex(int index) { - int i = 0; - while (i < items.length && (items[i] == null || items[i].index != index)) i++; - return items[i]; - } - - /** - * Puts one byte and two shorts into the constant pool. - * - * @param b - * a byte. - * @param s1 - * a short. - * @param s2 - * another short. - */ - private void put122(final int b, final int s1, final int s2) { - pool.put12(b, s1).putShort(s2); - } - - /** - * Puts two bytes and one short into the constant pool. - * - * @param b1 - * a byte. - * @param b2 - * another byte. - * @param s - * a short. - */ - private void put112(final int b1, final int b2, final int s) { - pool.put11(b1, b2).putShort(s); - } -} diff --git a/src/asm/scala/tools/asm/Context.java b/src/asm/scala/tools/asm/Context.java deleted file mode 100644 index 24546969e3..0000000000 --- a/src/asm/scala/tools/asm/Context.java +++ /dev/null @@ -1,145 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -package scala.tools.asm; - -/** - * Information about a class being parsed in a {@link ClassReader}. - * - * @author Eric Bruneton - */ -class Context { - - /** - * Prototypes of the attributes that must be parsed for this class. - */ - Attribute[] attrs; - - /** - * The {@link ClassReader} option flags for the parsing of this class. - */ - int flags; - - /** - * The buffer used to read strings. - */ - char[] buffer; - - /** - * The start index of each bootstrap method. - */ - int[] bootstrapMethods; - - /** - * The access flags of the method currently being parsed. - */ - int access; - - /** - * The name of the method currently being parsed. - */ - String name; - - /** - * The descriptor of the method currently being parsed. - */ - String desc; - - /** - * The label objects, indexed by bytecode offset, of the method currently - * being parsed (only bytecode offsets for which a label is needed have a - * non null associated Label object). - */ - Label[] labels; - - /** - * The target of the type annotation currently being parsed. - */ - int typeRef; - - /** - * The path of the type annotation currently being parsed. - */ - TypePath typePath; - - /** - * The offset of the latest stack map frame that has been parsed. - */ - int offset; - - /** - * The labels corresponding to the start of the local variable ranges in the - * local variable type annotation currently being parsed. - */ - Label[] start; - - /** - * The labels corresponding to the end of the local variable ranges in the - * local variable type annotation currently being parsed. - */ - Label[] end; - - /** - * The local variable indices for each local variable range in the local - * variable type annotation currently being parsed. - */ - int[] index; - - /** - * The encoding of the latest stack map frame that has been parsed. - */ - int mode; - - /** - * The number of locals in the latest stack map frame that has been parsed. - */ - int localCount; - - /** - * The number locals in the latest stack map frame that has been parsed, - * minus the number of locals in the previous frame. - */ - int localDiff; - - /** - * The local values of the latest stack map frame that has been parsed. - */ - Object[] local; - - /** - * The stack size of the latest stack map frame that has been parsed. - */ - int stackCount; - - /** - * The stack values of the latest stack map frame that has been parsed. - */ - Object[] stack; -} diff --git a/src/asm/scala/tools/asm/CustomAttr.java b/src/asm/scala/tools/asm/CustomAttr.java deleted file mode 100644 index 5ecfd283d0..0000000000 --- a/src/asm/scala/tools/asm/CustomAttr.java +++ /dev/null @@ -1,20 +0,0 @@ -/* NSC -- new Scala compiler - * Copyright 2005-2012 LAMP/EPFL - */ - -package scala.tools.asm; - -import scala.tools.asm.Attribute; - -/** - * A subclass of ASM's Attribute for the sole purpose of accessing a protected field there. - * - */ -public class CustomAttr extends Attribute { - - public CustomAttr(final String type, final byte[] value) { - super(type); - super.value = value; - } - -} diff --git a/src/asm/scala/tools/asm/Edge.java b/src/asm/scala/tools/asm/Edge.java deleted file mode 100644 index daac1f7bb0..0000000000 --- a/src/asm/scala/tools/asm/Edge.java +++ /dev/null @@ -1,75 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm; - -/** - * An edge in the control flow graph of a method body. See {@link Label Label}. - * - * @author Eric Bruneton - */ -class Edge { - - /** - * Denotes a normal control flow graph edge. - */ - static final int NORMAL = 0; - - /** - * Denotes a control flow graph edge corresponding to an exception handler. - * More precisely any {@link Edge} whose {@link #info} is strictly positive - * corresponds to an exception handler. The actual value of {@link #info} is - * the index, in the {@link ClassWriter} type table, of the exception that - * is catched. - */ - static final int EXCEPTION = 0x7FFFFFFF; - - /** - * Information about this control flow graph edge. If - * {@link ClassWriter#COMPUTE_MAXS} is used this field is the (relative) - * stack size in the basic block from which this edge originates. This size - * is equal to the stack size at the "jump" instruction to which this edge - * corresponds, relatively to the stack size at the beginning of the - * originating basic block. If {@link ClassWriter#COMPUTE_FRAMES} is used, - * this field is the kind of this control flow graph edge (i.e. NORMAL or - * EXCEPTION). - */ - int info; - - /** - * The successor block of the basic block from which this edge originates. - */ - Label successor; - - /** - * The next edge in the list of successors of the originating basic block. - * See {@link Label#successors successors}. - */ - Edge next; -} diff --git a/src/asm/scala/tools/asm/FieldVisitor.java b/src/asm/scala/tools/asm/FieldVisitor.java deleted file mode 100644 index 708c1d322e..0000000000 --- a/src/asm/scala/tools/asm/FieldVisitor.java +++ /dev/null @@ -1,150 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm; - -/** - * A visitor to visit a Java field. The methods of this class must be called in - * the following order: ( visitAnnotation | - * visitTypeAnnotation | visitAttribute )* visitEnd. - * - * @author Eric Bruneton - */ -public abstract class FieldVisitor { - - /** - * The ASM API version implemented by this visitor. The value of this field - * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - protected final int api; - - /** - * The field visitor to which this visitor must delegate method calls. May - * be null. - */ - protected FieldVisitor fv; - - /** - * Constructs a new {@link FieldVisitor}. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - public FieldVisitor(final int api) { - this(api, null); - } - - /** - * Constructs a new {@link FieldVisitor}. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - * @param fv - * the field visitor to which this visitor must delegate method - * calls. May be null. - */ - public FieldVisitor(final int api, final FieldVisitor fv) { - if (api != Opcodes.ASM4 && api != Opcodes.ASM5) { - throw new IllegalArgumentException(); - } - this.api = api; - this.fv = fv; - } - - /** - * Visits an annotation of the field. - * - * @param desc - * the class descriptor of the annotation class. - * @param visible - * true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if - * this visitor is not interested in visiting this annotation. - */ - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - if (fv != null) { - return fv.visitAnnotation(desc, visible); - } - return null; - } - - /** - * Visits an annotation on the type of the field. - * - * @param typeRef - * a reference to the annotated type. The sort of this type - * reference must be {@link TypeReference#FIELD FIELD}. See - * {@link TypeReference}. - * @param typePath - * the path to the annotated type argument, wildcard bound, array - * element type, or static inner type within 'typeRef'. May be - * null if the annotation targets 'typeRef' as a whole. - * @param desc - * the class descriptor of the annotation class. - * @param visible - * true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if - * this visitor is not interested in visiting this annotation. - */ - public AnnotationVisitor visitTypeAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - if (api < Opcodes.ASM5) { - throw new RuntimeException(); - } - if (fv != null) { - return fv.visitTypeAnnotation(typeRef, typePath, desc, visible); - } - return null; - } - - /** - * Visits a non standard attribute of the field. - * - * @param attr - * an attribute. - */ - public void visitAttribute(Attribute attr) { - if (fv != null) { - fv.visitAttribute(attr); - } - } - - /** - * Visits the end of the field. This method, which is the last one to be - * called, is used to inform the visitor that all the annotations and - * attributes of the field have been visited. - */ - public void visitEnd() { - if (fv != null) { - fv.visitEnd(); - } - } -} diff --git a/src/asm/scala/tools/asm/FieldWriter.java b/src/asm/scala/tools/asm/FieldWriter.java deleted file mode 100644 index e640a8d406..0000000000 --- a/src/asm/scala/tools/asm/FieldWriter.java +++ /dev/null @@ -1,329 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm; - -/** - * An {@link FieldVisitor} that generates Java fields in bytecode form. - * - * @author Eric Bruneton - */ -final class FieldWriter extends FieldVisitor { - - /** - * The class writer to which this field must be added. - */ - private final ClassWriter cw; - - /** - * Access flags of this field. - */ - private final int access; - - /** - * The index of the constant pool item that contains the name of this - * method. - */ - private final int name; - - /** - * The index of the constant pool item that contains the descriptor of this - * field. - */ - private final int desc; - - /** - * The index of the constant pool item that contains the signature of this - * field. - */ - private int signature; - - /** - * The index of the constant pool item that contains the constant value of - * this field. - */ - private int value; - - /** - * The runtime visible annotations of this field. May be null. - */ - private AnnotationWriter anns; - - /** - * The runtime invisible annotations of this field. May be null. - */ - private AnnotationWriter ianns; - - /** - * The runtime visible type annotations of this field. May be null. - */ - private AnnotationWriter tanns; - - /** - * The runtime invisible type annotations of this field. May be - * null. - */ - private AnnotationWriter itanns; - - /** - * The non standard attributes of this field. May be null. - */ - private Attribute attrs; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructs a new {@link FieldWriter}. - * - * @param cw - * the class writer to which this field must be added. - * @param access - * the field's access flags (see {@link Opcodes}). - * @param name - * the field's name. - * @param desc - * the field's descriptor (see {@link Type}). - * @param signature - * the field's signature. May be null. - * @param value - * the field's constant value. May be null. - */ - FieldWriter(final ClassWriter cw, final int access, final String name, - final String desc, final String signature, final Object value) { - super(Opcodes.ASM5); - if (cw.firstField == null) { - cw.firstField = this; - } else { - cw.lastField.fv = this; - } - cw.lastField = this; - this.cw = cw; - this.access = access; - this.name = cw.newUTF8(name); - this.desc = cw.newUTF8(desc); - if (ClassReader.SIGNATURES && signature != null) { - this.signature = cw.newUTF8(signature); - } - if (value != null) { - this.value = cw.newConstItem(value).index; - } - } - - // ------------------------------------------------------------------------ - // Implementation of the FieldVisitor abstract class - // ------------------------------------------------------------------------ - - @Override - public AnnotationVisitor visitAnnotation(final String desc, - final boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - // write type, and reserve space for values count - bv.putShort(cw.newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2); - if (visible) { - aw.next = anns; - anns = aw; - } else { - aw.next = ianns; - ianns = aw; - } - return aw; - } - - @Override - public AnnotationVisitor visitTypeAnnotation(final int typeRef, - final TypePath typePath, final String desc, final boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - // write target_type and target_info - AnnotationWriter.putTarget(typeRef, typePath, bv); - // write type, and reserve space for values count - bv.putShort(cw.newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, - bv.length - 2); - if (visible) { - aw.next = tanns; - tanns = aw; - } else { - aw.next = itanns; - itanns = aw; - } - return aw; - } - - @Override - public void visitAttribute(final Attribute attr) { - attr.next = attrs; - attrs = attr; - } - - @Override - public void visitEnd() { - } - - // ------------------------------------------------------------------------ - // Utility methods - // ------------------------------------------------------------------------ - - /** - * Returns the size of this field. - * - * @return the size of this field. - */ - int getSize() { - int size = 8; - if (value != 0) { - cw.newUTF8("ConstantValue"); - size += 8; - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0) { - if ((cw.version & 0xFFFF) < Opcodes.V1_5 - || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { - cw.newUTF8("Synthetic"); - size += 6; - } - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - cw.newUTF8("Deprecated"); - size += 6; - } - if (ClassReader.SIGNATURES && signature != 0) { - cw.newUTF8("Signature"); - size += 8; - } - if (ClassReader.ANNOTATIONS && anns != null) { - cw.newUTF8("RuntimeVisibleAnnotations"); - size += 8 + anns.getSize(); - } - if (ClassReader.ANNOTATIONS && ianns != null) { - cw.newUTF8("RuntimeInvisibleAnnotations"); - size += 8 + ianns.getSize(); - } - if (ClassReader.ANNOTATIONS && tanns != null) { - cw.newUTF8("RuntimeVisibleTypeAnnotations"); - size += 8 + tanns.getSize(); - } - if (ClassReader.ANNOTATIONS && itanns != null) { - cw.newUTF8("RuntimeInvisibleTypeAnnotations"); - size += 8 + itanns.getSize(); - } - if (attrs != null) { - size += attrs.getSize(cw, null, 0, -1, -1); - } - return size; - } - - /** - * Puts the content of this field into the given byte vector. - * - * @param out - * where the content of this field must be put. - */ - void put(final ByteVector out) { - final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC; - int mask = Opcodes.ACC_DEPRECATED | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE - | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR); - out.putShort(access & ~mask).putShort(name).putShort(desc); - int attributeCount = 0; - if (value != 0) { - ++attributeCount; - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0) { - if ((cw.version & 0xFFFF) < Opcodes.V1_5 - || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { - ++attributeCount; - } - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - ++attributeCount; - } - if (ClassReader.SIGNATURES && signature != 0) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && anns != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && ianns != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && tanns != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && itanns != null) { - ++attributeCount; - } - if (attrs != null) { - attributeCount += attrs.getCount(); - } - out.putShort(attributeCount); - if (value != 0) { - out.putShort(cw.newUTF8("ConstantValue")); - out.putInt(2).putShort(value); - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0) { - if ((cw.version & 0xFFFF) < Opcodes.V1_5 - || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { - out.putShort(cw.newUTF8("Synthetic")).putInt(0); - } - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - out.putShort(cw.newUTF8("Deprecated")).putInt(0); - } - if (ClassReader.SIGNATURES && signature != 0) { - out.putShort(cw.newUTF8("Signature")); - out.putInt(2).putShort(signature); - } - if (ClassReader.ANNOTATIONS && anns != null) { - out.putShort(cw.newUTF8("RuntimeVisibleAnnotations")); - anns.put(out); - } - if (ClassReader.ANNOTATIONS && ianns != null) { - out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations")); - ianns.put(out); - } - if (ClassReader.ANNOTATIONS && tanns != null) { - out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations")); - tanns.put(out); - } - if (ClassReader.ANNOTATIONS && itanns != null) { - out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations")); - itanns.put(out); - } - if (attrs != null) { - attrs.put(cw, null, 0, -1, -1, out); - } - } -} diff --git a/src/asm/scala/tools/asm/Frame.java b/src/asm/scala/tools/asm/Frame.java deleted file mode 100644 index 85ad3269ab..0000000000 --- a/src/asm/scala/tools/asm/Frame.java +++ /dev/null @@ -1,1462 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm; - -/** - * Information about the input and output stack map frames of a basic block. - * - * @author Eric Bruneton - */ -final class Frame { - - /* - * Frames are computed in a two steps process: during the visit of each - * instruction, the state of the frame at the end of current basic block is - * updated by simulating the action of the instruction on the previous state - * of this so called "output frame". In visitMaxs, a fix point algorithm is - * used to compute the "input frame" of each basic block, i.e. the stack map - * frame at the beginning of the basic block, starting from the input frame - * of the first basic block (which is computed from the method descriptor), - * and by using the previously computed output frames to compute the input - * state of the other blocks. - * - * All output and input frames are stored as arrays of integers. Reference - * and array types are represented by an index into a type table (which is - * not the same as the constant pool of the class, in order to avoid adding - * unnecessary constants in the pool - not all computed frames will end up - * being stored in the stack map table). This allows very fast type - * comparisons. - * - * Output stack map frames are computed relatively to the input frame of the - * basic block, which is not yet known when output frames are computed. It - * is therefore necessary to be able to represent abstract types such as - * "the type at position x in the input frame locals" or "the type at - * position x from the top of the input frame stack" or even "the type at - * position x in the input frame, with y more (or less) array dimensions". - * This explains the rather complicated type format used in output frames. - * - * This format is the following: DIM KIND VALUE (4, 4 and 24 bits). DIM is a - * signed number of array dimensions (from -8 to 7). KIND is either BASE, - * LOCAL or STACK. BASE is used for types that are not relative to the input - * frame. LOCAL is used for types that are relative to the input local - * variable types. STACK is used for types that are relative to the input - * stack types. VALUE depends on KIND. For LOCAL types, it is an index in - * the input local variable types. For STACK types, it is a position - * relatively to the top of input frame stack. For BASE types, it is either - * one of the constants defined below, or for OBJECT and UNINITIALIZED - * types, a tag and an index in the type table. - * - * Output frames can contain types of any kind and with a positive or - * negative dimension (and even unassigned types, represented by 0 - which - * does not correspond to any valid type value). Input frames can only - * contain BASE types of positive or null dimension. In all cases the type - * table contains only internal type names (array type descriptors are - * forbidden - dimensions must be represented through the DIM field). - * - * The LONG and DOUBLE types are always represented by using two slots (LONG - * + TOP or DOUBLE + TOP), for local variable types as well as in the - * operand stack. This is necessary to be able to simulate DUPx_y - * instructions, whose effect would be dependent on the actual type values - * if types were always represented by a single slot in the stack (and this - * is not possible, since actual type values are not always known - cf LOCAL - * and STACK type kinds). - */ - - /** - * Mask to get the dimension of a frame type. This dimension is a signed - * integer between -8 and 7. - */ - static final int DIM = 0xF0000000; - - /** - * Constant to be added to a type to get a type with one more dimension. - */ - static final int ARRAY_OF = 0x10000000; - - /** - * Constant to be added to a type to get a type with one less dimension. - */ - static final int ELEMENT_OF = 0xF0000000; - - /** - * Mask to get the kind of a frame type. - * - * @see #BASE - * @see #LOCAL - * @see #STACK - */ - static final int KIND = 0xF000000; - - /** - * Flag used for LOCAL and STACK types. Indicates that if this type happens - * to be a long or double type (during the computations of input frames), - * then it must be set to TOP because the second word of this value has been - * reused to store other data in the basic block. Hence the first word no - * longer stores a valid long or double value. - */ - static final int TOP_IF_LONG_OR_DOUBLE = 0x800000; - - /** - * Mask to get the value of a frame type. - */ - static final int VALUE = 0x7FFFFF; - - /** - * Mask to get the kind of base types. - */ - static final int BASE_KIND = 0xFF00000; - - /** - * Mask to get the value of base types. - */ - static final int BASE_VALUE = 0xFFFFF; - - /** - * Kind of the types that are not relative to an input stack map frame. - */ - static final int BASE = 0x1000000; - - /** - * Base kind of the base reference types. The BASE_VALUE of such types is an - * index into the type table. - */ - static final int OBJECT = BASE | 0x700000; - - /** - * Base kind of the uninitialized base types. The BASE_VALUE of such types - * in an index into the type table (the Item at that index contains both an - * instruction offset and an internal class name). - */ - static final int UNINITIALIZED = BASE | 0x800000; - - /** - * Kind of the types that are relative to the local variable types of an - * input stack map frame. The value of such types is a local variable index. - */ - private static final int LOCAL = 0x2000000; - - /** - * Kind of the the types that are relative to the stack of an input stack - * map frame. The value of such types is a position relatively to the top of - * this stack. - */ - private static final int STACK = 0x3000000; - - /** - * The TOP type. This is a BASE type. - */ - static final int TOP = BASE | 0; - - /** - * The BOOLEAN type. This is a BASE type mainly used for array types. - */ - static final int BOOLEAN = BASE | 9; - - /** - * The BYTE type. This is a BASE type mainly used for array types. - */ - static final int BYTE = BASE | 10; - - /** - * The CHAR type. This is a BASE type mainly used for array types. - */ - static final int CHAR = BASE | 11; - - /** - * The SHORT type. This is a BASE type mainly used for array types. - */ - static final int SHORT = BASE | 12; - - /** - * The INTEGER type. This is a BASE type. - */ - static final int INTEGER = BASE | 1; - - /** - * The FLOAT type. This is a BASE type. - */ - static final int FLOAT = BASE | 2; - - /** - * The DOUBLE type. This is a BASE type. - */ - static final int DOUBLE = BASE | 3; - - /** - * The LONG type. This is a BASE type. - */ - static final int LONG = BASE | 4; - - /** - * The NULL type. This is a BASE type. - */ - static final int NULL = BASE | 5; - - /** - * The UNINITIALIZED_THIS type. This is a BASE type. - */ - static final int UNINITIALIZED_THIS = BASE | 6; - - /** - * The stack size variation corresponding to each JVM instruction. This - * stack variation is equal to the size of the values produced by an - * instruction, minus the size of the values consumed by this instruction. - */ - static final int[] SIZE; - - /** - * Computes the stack size variation corresponding to each JVM instruction. - */ - static { - int i; - int[] b = new int[202]; - String s = "EFFFFFFFFGGFFFGGFFFEEFGFGFEEEEEEEEEEEEEEEEEEEEDEDEDDDDD" - + "CDCDEEEEEEEEEEEEEEEEEEEEBABABBBBDCFFFGGGEDCDCDCDCDCDCDCDCD" - + "CDCEEEEDDDDDDDCDCDCEFEFDDEEFFDEDEEEBDDBBDDDDDDCCCCCCCCEFED" - + "DDCDCDEEEEEEEEEEFEEEEEEDDEEDDEE"; - for (i = 0; i < b.length; ++i) { - b[i] = s.charAt(i) - 'E'; - } - SIZE = b; - - // code to generate the above string - // - // int NA = 0; // not applicable (unused opcode or variable size opcode) - // - // b = new int[] { - // 0, //NOP, // visitInsn - // 1, //ACONST_NULL, // - - // 1, //ICONST_M1, // - - // 1, //ICONST_0, // - - // 1, //ICONST_1, // - - // 1, //ICONST_2, // - - // 1, //ICONST_3, // - - // 1, //ICONST_4, // - - // 1, //ICONST_5, // - - // 2, //LCONST_0, // - - // 2, //LCONST_1, // - - // 1, //FCONST_0, // - - // 1, //FCONST_1, // - - // 1, //FCONST_2, // - - // 2, //DCONST_0, // - - // 2, //DCONST_1, // - - // 1, //BIPUSH, // visitIntInsn - // 1, //SIPUSH, // - - // 1, //LDC, // visitLdcInsn - // NA, //LDC_W, // - - // NA, //LDC2_W, // - - // 1, //ILOAD, // visitVarInsn - // 2, //LLOAD, // - - // 1, //FLOAD, // - - // 2, //DLOAD, // - - // 1, //ALOAD, // - - // NA, //ILOAD_0, // - - // NA, //ILOAD_1, // - - // NA, //ILOAD_2, // - - // NA, //ILOAD_3, // - - // NA, //LLOAD_0, // - - // NA, //LLOAD_1, // - - // NA, //LLOAD_2, // - - // NA, //LLOAD_3, // - - // NA, //FLOAD_0, // - - // NA, //FLOAD_1, // - - // NA, //FLOAD_2, // - - // NA, //FLOAD_3, // - - // NA, //DLOAD_0, // - - // NA, //DLOAD_1, // - - // NA, //DLOAD_2, // - - // NA, //DLOAD_3, // - - // NA, //ALOAD_0, // - - // NA, //ALOAD_1, // - - // NA, //ALOAD_2, // - - // NA, //ALOAD_3, // - - // -1, //IALOAD, // visitInsn - // 0, //LALOAD, // - - // -1, //FALOAD, // - - // 0, //DALOAD, // - - // -1, //AALOAD, // - - // -1, //BALOAD, // - - // -1, //CALOAD, // - - // -1, //SALOAD, // - - // -1, //ISTORE, // visitVarInsn - // -2, //LSTORE, // - - // -1, //FSTORE, // - - // -2, //DSTORE, // - - // -1, //ASTORE, // - - // NA, //ISTORE_0, // - - // NA, //ISTORE_1, // - - // NA, //ISTORE_2, // - - // NA, //ISTORE_3, // - - // NA, //LSTORE_0, // - - // NA, //LSTORE_1, // - - // NA, //LSTORE_2, // - - // NA, //LSTORE_3, // - - // NA, //FSTORE_0, // - - // NA, //FSTORE_1, // - - // NA, //FSTORE_2, // - - // NA, //FSTORE_3, // - - // NA, //DSTORE_0, // - - // NA, //DSTORE_1, // - - // NA, //DSTORE_2, // - - // NA, //DSTORE_3, // - - // NA, //ASTORE_0, // - - // NA, //ASTORE_1, // - - // NA, //ASTORE_2, // - - // NA, //ASTORE_3, // - - // -3, //IASTORE, // visitInsn - // -4, //LASTORE, // - - // -3, //FASTORE, // - - // -4, //DASTORE, // - - // -3, //AASTORE, // - - // -3, //BASTORE, // - - // -3, //CASTORE, // - - // -3, //SASTORE, // - - // -1, //POP, // - - // -2, //POP2, // - - // 1, //DUP, // - - // 1, //DUP_X1, // - - // 1, //DUP_X2, // - - // 2, //DUP2, // - - // 2, //DUP2_X1, // - - // 2, //DUP2_X2, // - - // 0, //SWAP, // - - // -1, //IADD, // - - // -2, //LADD, // - - // -1, //FADD, // - - // -2, //DADD, // - - // -1, //ISUB, // - - // -2, //LSUB, // - - // -1, //FSUB, // - - // -2, //DSUB, // - - // -1, //IMUL, // - - // -2, //LMUL, // - - // -1, //FMUL, // - - // -2, //DMUL, // - - // -1, //IDIV, // - - // -2, //LDIV, // - - // -1, //FDIV, // - - // -2, //DDIV, // - - // -1, //IREM, // - - // -2, //LREM, // - - // -1, //FREM, // - - // -2, //DREM, // - - // 0, //INEG, // - - // 0, //LNEG, // - - // 0, //FNEG, // - - // 0, //DNEG, // - - // -1, //ISHL, // - - // -1, //LSHL, // - - // -1, //ISHR, // - - // -1, //LSHR, // - - // -1, //IUSHR, // - - // -1, //LUSHR, // - - // -1, //IAND, // - - // -2, //LAND, // - - // -1, //IOR, // - - // -2, //LOR, // - - // -1, //IXOR, // - - // -2, //LXOR, // - - // 0, //IINC, // visitIincInsn - // 1, //I2L, // visitInsn - // 0, //I2F, // - - // 1, //I2D, // - - // -1, //L2I, // - - // -1, //L2F, // - - // 0, //L2D, // - - // 0, //F2I, // - - // 1, //F2L, // - - // 1, //F2D, // - - // -1, //D2I, // - - // 0, //D2L, // - - // -1, //D2F, // - - // 0, //I2B, // - - // 0, //I2C, // - - // 0, //I2S, // - - // -3, //LCMP, // - - // -1, //FCMPL, // - - // -1, //FCMPG, // - - // -3, //DCMPL, // - - // -3, //DCMPG, // - - // -1, //IFEQ, // visitJumpInsn - // -1, //IFNE, // - - // -1, //IFLT, // - - // -1, //IFGE, // - - // -1, //IFGT, // - - // -1, //IFLE, // - - // -2, //IF_ICMPEQ, // - - // -2, //IF_ICMPNE, // - - // -2, //IF_ICMPLT, // - - // -2, //IF_ICMPGE, // - - // -2, //IF_ICMPGT, // - - // -2, //IF_ICMPLE, // - - // -2, //IF_ACMPEQ, // - - // -2, //IF_ACMPNE, // - - // 0, //GOTO, // - - // 1, //JSR, // - - // 0, //RET, // visitVarInsn - // -1, //TABLESWITCH, // visiTableSwitchInsn - // -1, //LOOKUPSWITCH, // visitLookupSwitch - // -1, //IRETURN, // visitInsn - // -2, //LRETURN, // - - // -1, //FRETURN, // - - // -2, //DRETURN, // - - // -1, //ARETURN, // - - // 0, //RETURN, // - - // NA, //GETSTATIC, // visitFieldInsn - // NA, //PUTSTATIC, // - - // NA, //GETFIELD, // - - // NA, //PUTFIELD, // - - // NA, //INVOKEVIRTUAL, // visitMethodInsn - // NA, //INVOKESPECIAL, // - - // NA, //INVOKESTATIC, // - - // NA, //INVOKEINTERFACE, // - - // NA, //INVOKEDYNAMIC, // visitInvokeDynamicInsn - // 1, //NEW, // visitTypeInsn - // 0, //NEWARRAY, // visitIntInsn - // 0, //ANEWARRAY, // visitTypeInsn - // 0, //ARRAYLENGTH, // visitInsn - // NA, //ATHROW, // - - // 0, //CHECKCAST, // visitTypeInsn - // 0, //INSTANCEOF, // - - // -1, //MONITORENTER, // visitInsn - // -1, //MONITOREXIT, // - - // NA, //WIDE, // NOT VISITED - // NA, //MULTIANEWARRAY, // visitMultiANewArrayInsn - // -1, //IFNULL, // visitJumpInsn - // -1, //IFNONNULL, // - - // NA, //GOTO_W, // - - // NA, //JSR_W, // - - // }; - // for (i = 0; i < b.length; ++i) { - // System.err.print((char)('E' + b[i])); - // } - // System.err.println(); - } - - /** - * The label (i.e. basic block) to which these input and output stack map - * frames correspond. - */ - Label owner; - - /** - * The input stack map frame locals. - */ - int[] inputLocals; - - /** - * The input stack map frame stack. - */ - int[] inputStack; - - /** - * The output stack map frame locals. - */ - private int[] outputLocals; - - /** - * The output stack map frame stack. - */ - private int[] outputStack; - - /** - * Relative size of the output stack. The exact semantics of this field - * depends on the algorithm that is used. - * - * When only the maximum stack size is computed, this field is the size of - * the output stack relatively to the top of the input stack. - * - * When the stack map frames are completely computed, this field is the - * actual number of types in {@link #outputStack}. - */ - private int outputStackTop; - - /** - * Number of types that are initialized in the basic block. - * - * @see #initializations - */ - private int initializationCount; - - /** - * The types that are initialized in the basic block. A constructor - * invocation on an UNINITIALIZED or UNINITIALIZED_THIS type must replace - * every occurence of this type in the local variables and in the - * operand stack. This cannot be done during the first phase of the - * algorithm since, during this phase, the local variables and the operand - * stack are not completely computed. It is therefore necessary to store the - * types on which constructors are invoked in the basic block, in order to - * do this replacement during the second phase of the algorithm, where the - * frames are fully computed. Note that this array can contain types that - * are relative to input locals or to the input stack (see below for the - * description of the algorithm). - */ - private int[] initializations; - - /** - * Returns the output frame local variable type at the given index. - * - * @param local - * the index of the local that must be returned. - * @return the output frame local variable type at the given index. - */ - private int get(final int local) { - if (outputLocals == null || local >= outputLocals.length) { - // this local has never been assigned in this basic block, - // so it is still equal to its value in the input frame - return LOCAL | local; - } else { - int type = outputLocals[local]; - if (type == 0) { - // this local has never been assigned in this basic block, - // so it is still equal to its value in the input frame - type = outputLocals[local] = LOCAL | local; - } - return type; - } - } - - /** - * Sets the output frame local variable type at the given index. - * - * @param local - * the index of the local that must be set. - * @param type - * the value of the local that must be set. - */ - private void set(final int local, final int type) { - // creates and/or resizes the output local variables array if necessary - if (outputLocals == null) { - outputLocals = new int[10]; - } - int n = outputLocals.length; - if (local >= n) { - int[] t = new int[Math.max(local + 1, 2 * n)]; - System.arraycopy(outputLocals, 0, t, 0, n); - outputLocals = t; - } - // sets the local variable - outputLocals[local] = type; - } - - /** - * Pushes a new type onto the output frame stack. - * - * @param type - * the type that must be pushed. - */ - private void push(final int type) { - // creates and/or resizes the output stack array if necessary - if (outputStack == null) { - outputStack = new int[10]; - } - int n = outputStack.length; - if (outputStackTop >= n) { - int[] t = new int[Math.max(outputStackTop + 1, 2 * n)]; - System.arraycopy(outputStack, 0, t, 0, n); - outputStack = t; - } - // pushes the type on the output stack - outputStack[outputStackTop++] = type; - // updates the maximun height reached by the output stack, if needed - int top = owner.inputStackTop + outputStackTop; - if (top > owner.outputStackMax) { - owner.outputStackMax = top; - } - } - - /** - * Pushes a new type onto the output frame stack. - * - * @param cw - * the ClassWriter to which this label belongs. - * @param desc - * the descriptor of the type to be pushed. Can also be a method - * descriptor (in this case this method pushes its return type - * onto the output frame stack). - */ - private void push(final ClassWriter cw, final String desc) { - int type = type(cw, desc); - if (type != 0) { - push(type); - if (type == LONG || type == DOUBLE) { - push(TOP); - } - } - } - - /** - * Returns the int encoding of the given type. - * - * @param cw - * the ClassWriter to which this label belongs. - * @param desc - * a type descriptor. - * @return the int encoding of the given type. - */ - private static int type(final ClassWriter cw, final String desc) { - String t; - int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0; - switch (desc.charAt(index)) { - case 'V': - return 0; - case 'Z': - case 'C': - case 'B': - case 'S': - case 'I': - return INTEGER; - case 'F': - return FLOAT; - case 'J': - return LONG; - case 'D': - return DOUBLE; - case 'L': - // stores the internal name, not the descriptor! - t = desc.substring(index + 1, desc.length() - 1); - return OBJECT | cw.addType(t); - // case '[': - default: - // extracts the dimensions and the element type - int data; - int dims = index + 1; - while (desc.charAt(dims) == '[') { - ++dims; - } - switch (desc.charAt(dims)) { - case 'Z': - data = BOOLEAN; - break; - case 'C': - data = CHAR; - break; - case 'B': - data = BYTE; - break; - case 'S': - data = SHORT; - break; - case 'I': - data = INTEGER; - break; - case 'F': - data = FLOAT; - break; - case 'J': - data = LONG; - break; - case 'D': - data = DOUBLE; - break; - // case 'L': - default: - // stores the internal name, not the descriptor - t = desc.substring(dims + 1, desc.length() - 1); - data = OBJECT | cw.addType(t); - } - return (dims - index) << 28 | data; - } - } - - /** - * Pops a type from the output frame stack and returns its value. - * - * @return the type that has been popped from the output frame stack. - */ - private int pop() { - if (outputStackTop > 0) { - return outputStack[--outputStackTop]; - } else { - // if the output frame stack is empty, pops from the input stack - return STACK | -(--owner.inputStackTop); - } - } - - /** - * Pops the given number of types from the output frame stack. - * - * @param elements - * the number of types that must be popped. - */ - private void pop(final int elements) { - if (outputStackTop >= elements) { - outputStackTop -= elements; - } else { - // if the number of elements to be popped is greater than the number - // of elements in the output stack, clear it, and pops the remaining - // elements from the input stack. - owner.inputStackTop -= elements - outputStackTop; - outputStackTop = 0; - } - } - - /** - * Pops a type from the output frame stack. - * - * @param desc - * the descriptor of the type to be popped. Can also be a method - * descriptor (in this case this method pops the types - * corresponding to the method arguments). - */ - private void pop(final String desc) { - char c = desc.charAt(0); - if (c == '(') { - pop((Type.getArgumentsAndReturnSizes(desc) >> 2) - 1); - } else if (c == 'J' || c == 'D') { - pop(2); - } else { - pop(1); - } - } - - /** - * Adds a new type to the list of types on which a constructor is invoked in - * the basic block. - * - * @param var - * a type on a which a constructor is invoked. - */ - private void init(final int var) { - // creates and/or resizes the initializations array if necessary - if (initializations == null) { - initializations = new int[2]; - } - int n = initializations.length; - if (initializationCount >= n) { - int[] t = new int[Math.max(initializationCount + 1, 2 * n)]; - System.arraycopy(initializations, 0, t, 0, n); - initializations = t; - } - // stores the type to be initialized - initializations[initializationCount++] = var; - } - - /** - * Replaces the given type with the appropriate type if it is one of the - * types on which a constructor is invoked in the basic block. - * - * @param cw - * the ClassWriter to which this label belongs. - * @param t - * a type - * @return t or, if t is one of the types on which a constructor is invoked - * in the basic block, the type corresponding to this constructor. - */ - private int init(final ClassWriter cw, final int t) { - int s; - if (t == UNINITIALIZED_THIS) { - s = OBJECT | cw.addType(cw.thisName); - } else if ((t & (DIM | BASE_KIND)) == UNINITIALIZED) { - String type = cw.typeTable[t & BASE_VALUE].strVal1; - s = OBJECT | cw.addType(type); - } else { - return t; - } - for (int j = 0; j < initializationCount; ++j) { - int u = initializations[j]; - int dim = u & DIM; - int kind = u & KIND; - if (kind == LOCAL) { - u = dim + inputLocals[u & VALUE]; - } else if (kind == STACK) { - u = dim + inputStack[inputStack.length - (u & VALUE)]; - } - if (t == u) { - return s; - } - } - return t; - } - - /** - * Initializes the input frame of the first basic block from the method - * descriptor. - * - * @param cw - * the ClassWriter to which this label belongs. - * @param access - * the access flags of the method to which this label belongs. - * @param args - * the formal parameter types of this method. - * @param maxLocals - * the maximum number of local variables of this method. - */ - void initInputFrame(final ClassWriter cw, final int access, - final Type[] args, final int maxLocals) { - inputLocals = new int[maxLocals]; - inputStack = new int[0]; - int i = 0; - if ((access & Opcodes.ACC_STATIC) == 0) { - if ((access & MethodWriter.ACC_CONSTRUCTOR) == 0) { - inputLocals[i++] = OBJECT | cw.addType(cw.thisName); - } else { - inputLocals[i++] = UNINITIALIZED_THIS; - } - } - for (int j = 0; j < args.length; ++j) { - int t = type(cw, args[j].getDescriptor()); - inputLocals[i++] = t; - if (t == LONG || t == DOUBLE) { - inputLocals[i++] = TOP; - } - } - while (i < maxLocals) { - inputLocals[i++] = TOP; - } - } - - /** - * Simulates the action of the given instruction on the output stack frame. - * - * @param opcode - * the opcode of the instruction. - * @param arg - * the operand of the instruction, if any. - * @param cw - * the class writer to which this label belongs. - * @param item - * the operand of the instructions, if any. - */ - void execute(final int opcode, final int arg, final ClassWriter cw, - final Item item) { - int t1, t2, t3, t4; - switch (opcode) { - case Opcodes.NOP: - case Opcodes.INEG: - case Opcodes.LNEG: - case Opcodes.FNEG: - case Opcodes.DNEG: - case Opcodes.I2B: - case Opcodes.I2C: - case Opcodes.I2S: - case Opcodes.GOTO: - case Opcodes.RETURN: - break; - case Opcodes.ACONST_NULL: - push(NULL); - break; - case Opcodes.ICONST_M1: - case Opcodes.ICONST_0: - case Opcodes.ICONST_1: - case Opcodes.ICONST_2: - case Opcodes.ICONST_3: - case Opcodes.ICONST_4: - case Opcodes.ICONST_5: - case Opcodes.BIPUSH: - case Opcodes.SIPUSH: - case Opcodes.ILOAD: - push(INTEGER); - break; - case Opcodes.LCONST_0: - case Opcodes.LCONST_1: - case Opcodes.LLOAD: - push(LONG); - push(TOP); - break; - case Opcodes.FCONST_0: - case Opcodes.FCONST_1: - case Opcodes.FCONST_2: - case Opcodes.FLOAD: - push(FLOAT); - break; - case Opcodes.DCONST_0: - case Opcodes.DCONST_1: - case Opcodes.DLOAD: - push(DOUBLE); - push(TOP); - break; - case Opcodes.LDC: - switch (item.type) { - case ClassWriter.INT: - push(INTEGER); - break; - case ClassWriter.LONG: - push(LONG); - push(TOP); - break; - case ClassWriter.FLOAT: - push(FLOAT); - break; - case ClassWriter.DOUBLE: - push(DOUBLE); - push(TOP); - break; - case ClassWriter.CLASS: - push(OBJECT | cw.addType("java/lang/Class")); - break; - case ClassWriter.STR: - push(OBJECT | cw.addType("java/lang/String")); - break; - case ClassWriter.MTYPE: - push(OBJECT | cw.addType("java/lang/invoke/MethodType")); - break; - // case ClassWriter.HANDLE_BASE + [1..9]: - default: - push(OBJECT | cw.addType("java/lang/invoke/MethodHandle")); - } - break; - case Opcodes.ALOAD: - push(get(arg)); - break; - case Opcodes.IALOAD: - case Opcodes.BALOAD: - case Opcodes.CALOAD: - case Opcodes.SALOAD: - pop(2); - push(INTEGER); - break; - case Opcodes.LALOAD: - case Opcodes.D2L: - pop(2); - push(LONG); - push(TOP); - break; - case Opcodes.FALOAD: - pop(2); - push(FLOAT); - break; - case Opcodes.DALOAD: - case Opcodes.L2D: - pop(2); - push(DOUBLE); - push(TOP); - break; - case Opcodes.AALOAD: - pop(1); - t1 = pop(); - push(ELEMENT_OF + t1); - break; - case Opcodes.ISTORE: - case Opcodes.FSTORE: - case Opcodes.ASTORE: - t1 = pop(); - set(arg, t1); - if (arg > 0) { - t2 = get(arg - 1); - // if t2 is of kind STACK or LOCAL we cannot know its size! - if (t2 == LONG || t2 == DOUBLE) { - set(arg - 1, TOP); - } else if ((t2 & KIND) != BASE) { - set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE); - } - } - break; - case Opcodes.LSTORE: - case Opcodes.DSTORE: - pop(1); - t1 = pop(); - set(arg, t1); - set(arg + 1, TOP); - if (arg > 0) { - t2 = get(arg - 1); - // if t2 is of kind STACK or LOCAL we cannot know its size! - if (t2 == LONG || t2 == DOUBLE) { - set(arg - 1, TOP); - } else if ((t2 & KIND) != BASE) { - set(arg - 1, t2 | TOP_IF_LONG_OR_DOUBLE); - } - } - break; - case Opcodes.IASTORE: - case Opcodes.BASTORE: - case Opcodes.CASTORE: - case Opcodes.SASTORE: - case Opcodes.FASTORE: - case Opcodes.AASTORE: - pop(3); - break; - case Opcodes.LASTORE: - case Opcodes.DASTORE: - pop(4); - break; - case Opcodes.POP: - case Opcodes.IFEQ: - case Opcodes.IFNE: - case Opcodes.IFLT: - case Opcodes.IFGE: - case Opcodes.IFGT: - case Opcodes.IFLE: - case Opcodes.IRETURN: - case Opcodes.FRETURN: - case Opcodes.ARETURN: - case Opcodes.TABLESWITCH: - case Opcodes.LOOKUPSWITCH: - case Opcodes.ATHROW: - case Opcodes.MONITORENTER: - case Opcodes.MONITOREXIT: - case Opcodes.IFNULL: - case Opcodes.IFNONNULL: - pop(1); - break; - case Opcodes.POP2: - case Opcodes.IF_ICMPEQ: - case Opcodes.IF_ICMPNE: - case Opcodes.IF_ICMPLT: - case Opcodes.IF_ICMPGE: - case Opcodes.IF_ICMPGT: - case Opcodes.IF_ICMPLE: - case Opcodes.IF_ACMPEQ: - case Opcodes.IF_ACMPNE: - case Opcodes.LRETURN: - case Opcodes.DRETURN: - pop(2); - break; - case Opcodes.DUP: - t1 = pop(); - push(t1); - push(t1); - break; - case Opcodes.DUP_X1: - t1 = pop(); - t2 = pop(); - push(t1); - push(t2); - push(t1); - break; - case Opcodes.DUP_X2: - t1 = pop(); - t2 = pop(); - t3 = pop(); - push(t1); - push(t3); - push(t2); - push(t1); - break; - case Opcodes.DUP2: - t1 = pop(); - t2 = pop(); - push(t2); - push(t1); - push(t2); - push(t1); - break; - case Opcodes.DUP2_X1: - t1 = pop(); - t2 = pop(); - t3 = pop(); - push(t2); - push(t1); - push(t3); - push(t2); - push(t1); - break; - case Opcodes.DUP2_X2: - t1 = pop(); - t2 = pop(); - t3 = pop(); - t4 = pop(); - push(t2); - push(t1); - push(t4); - push(t3); - push(t2); - push(t1); - break; - case Opcodes.SWAP: - t1 = pop(); - t2 = pop(); - push(t1); - push(t2); - break; - case Opcodes.IADD: - case Opcodes.ISUB: - case Opcodes.IMUL: - case Opcodes.IDIV: - case Opcodes.IREM: - case Opcodes.IAND: - case Opcodes.IOR: - case Opcodes.IXOR: - case Opcodes.ISHL: - case Opcodes.ISHR: - case Opcodes.IUSHR: - case Opcodes.L2I: - case Opcodes.D2I: - case Opcodes.FCMPL: - case Opcodes.FCMPG: - pop(2); - push(INTEGER); - break; - case Opcodes.LADD: - case Opcodes.LSUB: - case Opcodes.LMUL: - case Opcodes.LDIV: - case Opcodes.LREM: - case Opcodes.LAND: - case Opcodes.LOR: - case Opcodes.LXOR: - pop(4); - push(LONG); - push(TOP); - break; - case Opcodes.FADD: - case Opcodes.FSUB: - case Opcodes.FMUL: - case Opcodes.FDIV: - case Opcodes.FREM: - case Opcodes.L2F: - case Opcodes.D2F: - pop(2); - push(FLOAT); - break; - case Opcodes.DADD: - case Opcodes.DSUB: - case Opcodes.DMUL: - case Opcodes.DDIV: - case Opcodes.DREM: - pop(4); - push(DOUBLE); - push(TOP); - break; - case Opcodes.LSHL: - case Opcodes.LSHR: - case Opcodes.LUSHR: - pop(3); - push(LONG); - push(TOP); - break; - case Opcodes.IINC: - set(arg, INTEGER); - break; - case Opcodes.I2L: - case Opcodes.F2L: - pop(1); - push(LONG); - push(TOP); - break; - case Opcodes.I2F: - pop(1); - push(FLOAT); - break; - case Opcodes.I2D: - case Opcodes.F2D: - pop(1); - push(DOUBLE); - push(TOP); - break; - case Opcodes.F2I: - case Opcodes.ARRAYLENGTH: - case Opcodes.INSTANCEOF: - pop(1); - push(INTEGER); - break; - case Opcodes.LCMP: - case Opcodes.DCMPL: - case Opcodes.DCMPG: - pop(4); - push(INTEGER); - break; - case Opcodes.JSR: - case Opcodes.RET: - throw new RuntimeException( - "JSR/RET are not supported with computeFrames option"); - case Opcodes.GETSTATIC: - push(cw, item.strVal3); - break; - case Opcodes.PUTSTATIC: - pop(item.strVal3); - break; - case Opcodes.GETFIELD: - pop(1); - push(cw, item.strVal3); - break; - case Opcodes.PUTFIELD: - pop(item.strVal3); - pop(); - break; - case Opcodes.INVOKEVIRTUAL: - case Opcodes.INVOKESPECIAL: - case Opcodes.INVOKESTATIC: - case Opcodes.INVOKEINTERFACE: - pop(item.strVal3); - if (opcode != Opcodes.INVOKESTATIC) { - t1 = pop(); - if (opcode == Opcodes.INVOKESPECIAL - && item.strVal2.charAt(0) == '<') { - init(t1); - } - } - push(cw, item.strVal3); - break; - case Opcodes.INVOKEDYNAMIC: - pop(item.strVal2); - push(cw, item.strVal2); - break; - case Opcodes.NEW: - push(UNINITIALIZED | cw.addUninitializedType(item.strVal1, arg)); - break; - case Opcodes.NEWARRAY: - pop(); - switch (arg) { - case Opcodes.T_BOOLEAN: - push(ARRAY_OF | BOOLEAN); - break; - case Opcodes.T_CHAR: - push(ARRAY_OF | CHAR); - break; - case Opcodes.T_BYTE: - push(ARRAY_OF | BYTE); - break; - case Opcodes.T_SHORT: - push(ARRAY_OF | SHORT); - break; - case Opcodes.T_INT: - push(ARRAY_OF | INTEGER); - break; - case Opcodes.T_FLOAT: - push(ARRAY_OF | FLOAT); - break; - case Opcodes.T_DOUBLE: - push(ARRAY_OF | DOUBLE); - break; - // case Opcodes.T_LONG: - default: - push(ARRAY_OF | LONG); - break; - } - break; - case Opcodes.ANEWARRAY: - String s = item.strVal1; - pop(); - if (s.charAt(0) == '[') { - push(cw, '[' + s); - } else { - push(ARRAY_OF | OBJECT | cw.addType(s)); - } - break; - case Opcodes.CHECKCAST: - s = item.strVal1; - pop(); - if (s.charAt(0) == '[') { - push(cw, s); - } else { - push(OBJECT | cw.addType(s)); - } - break; - // case Opcodes.MULTIANEWARRAY: - default: - pop(arg); - push(cw, item.strVal1); - break; - } - } - - /** - * Merges the input frame of the given basic block with the input and output - * frames of this basic block. Returns true if the input frame of - * the given label has been changed by this operation. - * - * @param cw - * the ClassWriter to which this label belongs. - * @param frame - * the basic block whose input frame must be updated. - * @param edge - * the kind of the {@link Edge} between this label and 'label'. - * See {@link Edge#info}. - * @return true if the input frame of the given label has been - * changed by this operation. - */ - boolean merge(final ClassWriter cw, final Frame frame, final int edge) { - boolean changed = false; - int i, s, dim, kind, t; - - int nLocal = inputLocals.length; - int nStack = inputStack.length; - if (frame.inputLocals == null) { - frame.inputLocals = new int[nLocal]; - changed = true; - } - - for (i = 0; i < nLocal; ++i) { - if (outputLocals != null && i < outputLocals.length) { - s = outputLocals[i]; - if (s == 0) { - t = inputLocals[i]; - } else { - dim = s & DIM; - kind = s & KIND; - if (kind == BASE) { - t = s; - } else { - if (kind == LOCAL) { - t = dim + inputLocals[s & VALUE]; - } else { - t = dim + inputStack[nStack - (s & VALUE)]; - } - if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 - && (t == LONG || t == DOUBLE)) { - t = TOP; - } - } - } - } else { - t = inputLocals[i]; - } - if (initializations != null) { - t = init(cw, t); - } - changed |= merge(cw, t, frame.inputLocals, i); - } - - if (edge > 0) { - for (i = 0; i < nLocal; ++i) { - t = inputLocals[i]; - changed |= merge(cw, t, frame.inputLocals, i); - } - if (frame.inputStack == null) { - frame.inputStack = new int[1]; - changed = true; - } - changed |= merge(cw, edge, frame.inputStack, 0); - return changed; - } - - int nInputStack = inputStack.length + owner.inputStackTop; - if (frame.inputStack == null) { - frame.inputStack = new int[nInputStack + outputStackTop]; - changed = true; - } - - for (i = 0; i < nInputStack; ++i) { - t = inputStack[i]; - if (initializations != null) { - t = init(cw, t); - } - changed |= merge(cw, t, frame.inputStack, i); - } - for (i = 0; i < outputStackTop; ++i) { - s = outputStack[i]; - dim = s & DIM; - kind = s & KIND; - if (kind == BASE) { - t = s; - } else { - if (kind == LOCAL) { - t = dim + inputLocals[s & VALUE]; - } else { - t = dim + inputStack[nStack - (s & VALUE)]; - } - if ((s & TOP_IF_LONG_OR_DOUBLE) != 0 - && (t == LONG || t == DOUBLE)) { - t = TOP; - } - } - if (initializations != null) { - t = init(cw, t); - } - changed |= merge(cw, t, frame.inputStack, nInputStack + i); - } - return changed; - } - - /** - * Merges the type at the given index in the given type array with the given - * type. Returns true if the type array has been modified by this - * operation. - * - * @param cw - * the ClassWriter to which this label belongs. - * @param t - * the type with which the type array element must be merged. - * @param types - * an array of types. - * @param index - * the index of the type that must be merged in 'types'. - * @return true if the type array has been modified by this - * operation. - */ - private static boolean merge(final ClassWriter cw, int t, - final int[] types, final int index) { - int u = types[index]; - if (u == t) { - // if the types are equal, merge(u,t)=u, so there is no change - return false; - } - if ((t & ~DIM) == NULL) { - if (u == NULL) { - return false; - } - t = NULL; - } - if (u == 0) { - // if types[index] has never been assigned, merge(u,t)=t - types[index] = t; - return true; - } - int v; - if ((u & BASE_KIND) == OBJECT || (u & DIM) != 0) { - // if u is a reference type of any dimension - if (t == NULL) { - // if t is the NULL type, merge(u,t)=u, so there is no change - return false; - } else if ((t & (DIM | BASE_KIND)) == (u & (DIM | BASE_KIND))) { - // if t and u have the same dimension and same base kind - if ((u & BASE_KIND) == OBJECT) { - // if t is also a reference type, and if u and t have the - // same dimension merge(u,t) = dim(t) | common parent of the - // element types of u and t - v = (t & DIM) | OBJECT - | cw.getMergedType(t & BASE_VALUE, u & BASE_VALUE); - } else { - // if u and t are array types, but not with the same element - // type, merge(u,t) = dim(u) - 1 | java/lang/Object - int vdim = ELEMENT_OF + (u & DIM); - v = vdim | OBJECT | cw.addType("java/lang/Object"); - } - } else if ((t & BASE_KIND) == OBJECT || (t & DIM) != 0) { - // if t is any other reference or array type, the merged type - // is min(udim, tdim) | java/lang/Object, where udim is the - // array dimension of u, minus 1 if u is an array type with a - // primitive element type (and similarly for tdim). - int tdim = (((t & DIM) == 0 || (t & BASE_KIND) == OBJECT) ? 0 - : ELEMENT_OF) + (t & DIM); - int udim = (((u & DIM) == 0 || (u & BASE_KIND) == OBJECT) ? 0 - : ELEMENT_OF) + (u & DIM); - v = Math.min(tdim, udim) | OBJECT - | cw.addType("java/lang/Object"); - } else { - // if t is any other type, merge(u,t)=TOP - v = TOP; - } - } else if (u == NULL) { - // if u is the NULL type, merge(u,t)=t, - // or TOP if t is not a reference type - v = (t & BASE_KIND) == OBJECT || (t & DIM) != 0 ? t : TOP; - } else { - // if u is any other type, merge(u,t)=TOP whatever t - v = TOP; - } - if (u != v) { - types[index] = v; - return true; - } - return false; - } -} diff --git a/src/asm/scala/tools/asm/Handle.java b/src/asm/scala/tools/asm/Handle.java deleted file mode 100644 index cf12bb7613..0000000000 --- a/src/asm/scala/tools/asm/Handle.java +++ /dev/null @@ -1,170 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -package scala.tools.asm; - -/** - * A reference to a field or a method. - * - * @author Remi Forax - * @author Eric Bruneton - */ -public final class Handle { - - /** - * The kind of field or method designated by this Handle. Should be - * {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, - * {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, - * {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, - * {@link Opcodes#H_INVOKESPECIAL}, {@link Opcodes#H_NEWINVOKESPECIAL} or - * {@link Opcodes#H_INVOKEINTERFACE}. - */ - final int tag; - - /** - * The internal name of the class that owns the field or method designated - * by this handle. - */ - final String owner; - - /** - * The name of the field or method designated by this handle. - */ - final String name; - - /** - * The descriptor of the field or method designated by this handle. - */ - final String desc; - - /** - * Constructs a new field or method handle. - * - * @param tag - * the kind of field or method designated by this Handle. Must be - * {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, - * {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, - * {@link Opcodes#H_INVOKEVIRTUAL}, - * {@link Opcodes#H_INVOKESTATIC}, - * {@link Opcodes#H_INVOKESPECIAL}, - * {@link Opcodes#H_NEWINVOKESPECIAL} or - * {@link Opcodes#H_INVOKEINTERFACE}. - * @param owner - * the internal name of the class that owns the field or method - * designated by this handle. - * @param name - * the name of the field or method designated by this handle. - * @param desc - * the descriptor of the field or method designated by this - * handle. - */ - public Handle(int tag, String owner, String name, String desc) { - this.tag = tag; - this.owner = owner; - this.name = name; - this.desc = desc; - } - - /** - * Returns the kind of field or method designated by this handle. - * - * @return {@link Opcodes#H_GETFIELD}, {@link Opcodes#H_GETSTATIC}, - * {@link Opcodes#H_PUTFIELD}, {@link Opcodes#H_PUTSTATIC}, - * {@link Opcodes#H_INVOKEVIRTUAL}, {@link Opcodes#H_INVOKESTATIC}, - * {@link Opcodes#H_INVOKESPECIAL}, - * {@link Opcodes#H_NEWINVOKESPECIAL} or - * {@link Opcodes#H_INVOKEINTERFACE}. - */ - public int getTag() { - return tag; - } - - /** - * Returns the internal name of the class that owns the field or method - * designated by this handle. - * - * @return the internal name of the class that owns the field or method - * designated by this handle. - */ - public String getOwner() { - return owner; - } - - /** - * Returns the name of the field or method designated by this handle. - * - * @return the name of the field or method designated by this handle. - */ - public String getName() { - return name; - } - - /** - * Returns the descriptor of the field or method designated by this handle. - * - * @return the descriptor of the field or method designated by this handle. - */ - public String getDesc() { - return desc; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof Handle)) { - return false; - } - Handle h = (Handle) obj; - return tag == h.tag && owner.equals(h.owner) && name.equals(h.name) - && desc.equals(h.desc); - } - - @Override - public int hashCode() { - return tag + owner.hashCode() * name.hashCode() * desc.hashCode(); - } - - /** - * Returns the textual representation of this handle. The textual - * representation is: - * - *
-     * owner '.' name desc ' ' '(' tag ')'
-     * 
- * - * . As this format is unambiguous, it can be parsed if necessary. - */ - @Override - public String toString() { - return owner + '.' + name + desc + " (" + tag + ')'; - } -} diff --git a/src/asm/scala/tools/asm/Handler.java b/src/asm/scala/tools/asm/Handler.java deleted file mode 100644 index a06cb8152a..0000000000 --- a/src/asm/scala/tools/asm/Handler.java +++ /dev/null @@ -1,121 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm; - -/** - * Information about an exception handler block. - * - * @author Eric Bruneton - */ -class Handler { - - /** - * Beginning of the exception handler's scope (inclusive). - */ - Label start; - - /** - * End of the exception handler's scope (exclusive). - */ - Label end; - - /** - * Beginning of the exception handler's code. - */ - Label handler; - - /** - * Internal name of the type of exceptions handled by this handler, or - * null to catch any exceptions. - */ - String desc; - - /** - * Constant pool index of the internal name of the type of exceptions - * handled by this handler, or 0 to catch any exceptions. - */ - int type; - - /** - * Next exception handler block info. - */ - Handler next; - - /** - * Removes the range between start and end from the given exception - * handlers. - * - * @param h - * an exception handler list. - * @param start - * the start of the range to be removed. - * @param end - * the end of the range to be removed. Maybe null. - * @return the exception handler list with the start-end range removed. - */ - static Handler remove(Handler h, Label start, Label end) { - if (h == null) { - return null; - } else { - h.next = remove(h.next, start, end); - } - int hstart = h.start.position; - int hend = h.end.position; - int s = start.position; - int e = end == null ? Integer.MAX_VALUE : end.position; - // if [hstart,hend[ and [s,e[ intervals intersect... - if (s < hend && e > hstart) { - if (s <= hstart) { - if (e >= hend) { - // [hstart,hend[ fully included in [s,e[, h removed - h = h.next; - } else { - // [hstart,hend[ minus [s,e[ = [e,hend[ - h.start = end; - } - } else if (e >= hend) { - // [hstart,hend[ minus [s,e[ = [hstart,s[ - h.end = start; - } else { - // [hstart,hend[ minus [s,e[ = [hstart,s[ + [e,hend[ - Handler g = new Handler(); - g.start = end; - g.end = h.end; - g.handler = h.handler; - g.desc = h.desc; - g.type = h.type; - g.next = h.next; - h.end = start; - h.next = g; - } - } - return h; - } -} diff --git a/src/asm/scala/tools/asm/Item.java b/src/asm/scala/tools/asm/Item.java deleted file mode 100644 index 4693f5ae99..0000000000 --- a/src/asm/scala/tools/asm/Item.java +++ /dev/null @@ -1,312 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm; - -/** - * A constant pool item. Constant pool items can be created with the 'newXXX' - * methods in the {@link ClassWriter} class. - * - * @author Eric Bruneton - */ -final class Item { - - /** - * Index of this item in the constant pool. - */ - int index; - - /** - * Type of this constant pool item. A single class is used to represent all - * constant pool item types, in order to minimize the bytecode size of this - * package. The value of this field is one of {@link ClassWriter#INT}, - * {@link ClassWriter#LONG}, {@link ClassWriter#FLOAT}, - * {@link ClassWriter#DOUBLE}, {@link ClassWriter#UTF8}, - * {@link ClassWriter#STR}, {@link ClassWriter#CLASS}, - * {@link ClassWriter#NAME_TYPE}, {@link ClassWriter#FIELD}, - * {@link ClassWriter#METH}, {@link ClassWriter#IMETH}, - * {@link ClassWriter#MTYPE}, {@link ClassWriter#INDY}. - * - * MethodHandle constant 9 variations are stored using a range of 9 values - * from {@link ClassWriter#HANDLE_BASE} + 1 to - * {@link ClassWriter#HANDLE_BASE} + 9. - * - * Special Item types are used for Items that are stored in the ClassWriter - * {@link ClassWriter#typeTable}, instead of the constant pool, in order to - * avoid clashes with normal constant pool items in the ClassWriter constant - * pool's hash table. These special item types are - * {@link ClassWriter#TYPE_NORMAL}, {@link ClassWriter#TYPE_UNINIT} and - * {@link ClassWriter#TYPE_MERGED}. - */ - int type; - - /** - * Value of this item, for an integer item. - */ - int intVal; - - /** - * Value of this item, for a long item. - */ - long longVal; - - /** - * First part of the value of this item, for items that do not hold a - * primitive value. - */ - String strVal1; - - /** - * Second part of the value of this item, for items that do not hold a - * primitive value. - */ - String strVal2; - - /** - * Third part of the value of this item, for items that do not hold a - * primitive value. - */ - String strVal3; - - /** - * The hash code value of this constant pool item. - */ - int hashCode; - - /** - * Link to another constant pool item, used for collision lists in the - * constant pool's hash table. - */ - Item next; - - /** - * Constructs an uninitialized {@link Item}. - */ - Item() { - } - - /** - * Constructs an uninitialized {@link Item} for constant pool element at - * given position. - * - * @param index - * index of the item to be constructed. - */ - Item(final int index) { - this.index = index; - } - - /** - * Constructs a copy of the given item. - * - * @param index - * index of the item to be constructed. - * @param i - * the item that must be copied into the item to be constructed. - */ - Item(final int index, final Item i) { - this.index = index; - type = i.type; - intVal = i.intVal; - longVal = i.longVal; - strVal1 = i.strVal1; - strVal2 = i.strVal2; - strVal3 = i.strVal3; - hashCode = i.hashCode; - } - - /** - * Sets this item to an integer item. - * - * @param intVal - * the value of this item. - */ - void set(final int intVal) { - this.type = ClassWriter.INT; - this.intVal = intVal; - this.hashCode = 0x7FFFFFFF & (type + intVal); - } - - /** - * Sets this item to a long item. - * - * @param longVal - * the value of this item. - */ - void set(final long longVal) { - this.type = ClassWriter.LONG; - this.longVal = longVal; - this.hashCode = 0x7FFFFFFF & (type + (int) longVal); - } - - /** - * Sets this item to a float item. - * - * @param floatVal - * the value of this item. - */ - void set(final float floatVal) { - this.type = ClassWriter.FLOAT; - this.intVal = Float.floatToRawIntBits(floatVal); - this.hashCode = 0x7FFFFFFF & (type + (int) floatVal); - } - - /** - * Sets this item to a double item. - * - * @param doubleVal - * the value of this item. - */ - void set(final double doubleVal) { - this.type = ClassWriter.DOUBLE; - this.longVal = Double.doubleToRawLongBits(doubleVal); - this.hashCode = 0x7FFFFFFF & (type + (int) doubleVal); - } - - /** - * Sets this item to an item that do not hold a primitive value. - * - * @param type - * the type of this item. - * @param strVal1 - * first part of the value of this item. - * @param strVal2 - * second part of the value of this item. - * @param strVal3 - * third part of the value of this item. - */ - void set(final int type, final String strVal1, final String strVal2, - final String strVal3) { - this.type = type; - this.strVal1 = strVal1; - this.strVal2 = strVal2; - this.strVal3 = strVal3; - switch (type) { - case ClassWriter.CLASS: - this.intVal = 0; // intVal of a class must be zero, see visitInnerClass - case ClassWriter.UTF8: - case ClassWriter.STR: - case ClassWriter.MTYPE: - case ClassWriter.TYPE_NORMAL: - hashCode = 0x7FFFFFFF & (type + strVal1.hashCode()); - return; - case ClassWriter.NAME_TYPE: { - hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() - * strVal2.hashCode()); - return; - } - // ClassWriter.FIELD: - // ClassWriter.METH: - // ClassWriter.IMETH: - // ClassWriter.HANDLE_BASE + 1..9 - default: - hashCode = 0x7FFFFFFF & (type + strVal1.hashCode() - * strVal2.hashCode() * strVal3.hashCode()); - } - } - - /** - * Sets the item to an InvokeDynamic item. - * - * @param name - * invokedynamic's name. - * @param desc - * invokedynamic's desc. - * @param bsmIndex - * zero based index into the class attribute BootrapMethods. - */ - void set(String name, String desc, int bsmIndex) { - this.type = ClassWriter.INDY; - this.longVal = bsmIndex; - this.strVal1 = name; - this.strVal2 = desc; - this.hashCode = 0x7FFFFFFF & (ClassWriter.INDY + bsmIndex - * strVal1.hashCode() * strVal2.hashCode()); - } - - /** - * Sets the item to a BootstrapMethod item. - * - * @param position - * position in byte in the class attribute BootrapMethods. - * @param hashCode - * hashcode of the item. This hashcode is processed from the - * hashcode of the bootstrap method and the hashcode of all - * bootstrap arguments. - */ - void set(int position, int hashCode) { - this.type = ClassWriter.BSM; - this.intVal = position; - this.hashCode = hashCode; - } - - /** - * Indicates if the given item is equal to this one. This method assumes - * that the two items have the same {@link #type}. - * - * @param i - * the item to be compared to this one. Both items must have the - * same {@link #type}. - * @return true if the given item if equal to this one, - * false otherwise. - */ - boolean isEqualTo(final Item i) { - switch (type) { - case ClassWriter.UTF8: - case ClassWriter.STR: - case ClassWriter.CLASS: - case ClassWriter.MTYPE: - case ClassWriter.TYPE_NORMAL: - return i.strVal1.equals(strVal1); - case ClassWriter.TYPE_MERGED: - case ClassWriter.LONG: - case ClassWriter.DOUBLE: - return i.longVal == longVal; - case ClassWriter.INT: - case ClassWriter.FLOAT: - return i.intVal == intVal; - case ClassWriter.TYPE_UNINIT: - return i.intVal == intVal && i.strVal1.equals(strVal1); - case ClassWriter.NAME_TYPE: - return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2); - case ClassWriter.INDY: { - return i.longVal == longVal && i.strVal1.equals(strVal1) - && i.strVal2.equals(strVal2); - } - // case ClassWriter.FIELD: - // case ClassWriter.METH: - // case ClassWriter.IMETH: - // case ClassWriter.HANDLE_BASE + 1..9 - default: - return i.strVal1.equals(strVal1) && i.strVal2.equals(strVal2) - && i.strVal3.equals(strVal3); - } - } - -} diff --git a/src/asm/scala/tools/asm/Label.java b/src/asm/scala/tools/asm/Label.java deleted file mode 100644 index 22b6798fb5..0000000000 --- a/src/asm/scala/tools/asm/Label.java +++ /dev/null @@ -1,560 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm; - -/** - * A label represents a position in the bytecode of a method. Labels are used - * for jump, goto, and switch instructions, and for try catch blocks. A label - * designates the instruction that is just after. Note however that there - * can be other elements between a label and the instruction it designates (such - * as other labels, stack map frames, line numbers, etc.). - * - * @author Eric Bruneton - */ -public class Label { - - /** - * Indicates if this label is only used for debug attributes. Such a label - * is not the start of a basic block, the target of a jump instruction, or - * an exception handler. It can be safely ignored in control flow graph - * analysis algorithms (for optimization purposes). - */ - static final int DEBUG = 1; - - /** - * Indicates if the position of this label is known. - */ - static final int RESOLVED = 2; - - /** - * Indicates if this label has been updated, after instruction resizing. - */ - static final int RESIZED = 4; - - /** - * Indicates if this basic block has been pushed in the basic block stack. - * See {@link MethodWriter#visitMaxs visitMaxs}. - */ - static final int PUSHED = 8; - - /** - * Indicates if this label is the target of a jump instruction, or the start - * of an exception handler. - */ - static final int TARGET = 16; - - /** - * Indicates if a stack map frame must be stored for this label. - */ - static final int STORE = 32; - - /** - * Indicates if this label corresponds to a reachable basic block. - */ - static final int REACHABLE = 64; - - /** - * Indicates if this basic block ends with a JSR instruction. - */ - static final int JSR = 128; - - /** - * Indicates if this basic block ends with a RET instruction. - */ - static final int RET = 256; - - /** - * Indicates if this basic block is the start of a subroutine. - */ - static final int SUBROUTINE = 512; - - /** - * Indicates if this subroutine basic block has been visited by a - * visitSubroutine(null, ...) call. - */ - static final int VISITED = 1024; - - /** - * Indicates if this subroutine basic block has been visited by a - * visitSubroutine(!null, ...) call. - */ - static final int VISITED2 = 2048; - - /** - * Field used to associate user information to a label. Warning: this field - * is used by the ASM tree package. In order to use it with the ASM tree - * package you must override the - * {@link scala.tools.asm.tree.MethodNode#getLabelNode} method. - */ - public Object info; - - /** - * Flags that indicate the status of this label. - * - * @see #DEBUG - * @see #RESOLVED - * @see #RESIZED - * @see #PUSHED - * @see #TARGET - * @see #STORE - * @see #REACHABLE - * @see #JSR - * @see #RET - */ - int status; - - /** - * The line number corresponding to this label, if known. - */ - int line; - - /** - * The position of this label in the code, if known. - */ - int position; - - /** - * Number of forward references to this label, times two. - */ - private int referenceCount; - - /** - * Informations about forward references. Each forward reference is - * described by two consecutive integers in this array: the first one is the - * position of the first byte of the bytecode instruction that contains the - * forward reference, while the second is the position of the first byte of - * the forward reference itself. In fact the sign of the first integer - * indicates if this reference uses 2 or 4 bytes, and its absolute value - * gives the position of the bytecode instruction. This array is also used - * as a bitset to store the subroutines to which a basic block belongs. This - * information is needed in {@linked MethodWriter#visitMaxs}, after all - * forward references have been resolved. Hence the same array can be used - * for both purposes without problems. - */ - private int[] srcAndRefPositions; - - // ------------------------------------------------------------------------ - - /* - * Fields for the control flow and data flow graph analysis algorithms (used - * to compute the maximum stack size or the stack map frames). A control - * flow graph contains one node per "basic block", and one edge per "jump" - * from one basic block to another. Each node (i.e., each basic block) is - * represented by the Label object that corresponds to the first instruction - * of this basic block. Each node also stores the list of its successors in - * the graph, as a linked list of Edge objects. - * - * The control flow analysis algorithms used to compute the maximum stack - * size or the stack map frames are similar and use two steps. The first - * step, during the visit of each instruction, builds information about the - * state of the local variables and the operand stack at the end of each - * basic block, called the "output frame", relatively to the frame - * state at the beginning of the basic block, which is called the "input - * frame", and which is unknown during this step. The second step, in - * {@link MethodWriter#visitMaxs}, is a fix point algorithm that computes - * information about the input frame of each basic block, from the input - * state of the first basic block (known from the method signature), and by - * the using the previously computed relative output frames. - * - * The algorithm used to compute the maximum stack size only computes the - * relative output and absolute input stack heights, while the algorithm - * used to compute stack map frames computes relative output frames and - * absolute input frames. - */ - - /** - * Start of the output stack relatively to the input stack. The exact - * semantics of this field depends on the algorithm that is used. - * - * When only the maximum stack size is computed, this field is the number of - * elements in the input stack. - * - * When the stack map frames are completely computed, this field is the - * offset of the first output stack element relatively to the top of the - * input stack. This offset is always negative or null. A null offset means - * that the output stack must be appended to the input stack. A -n offset - * means that the first n output stack elements must replace the top n input - * stack elements, and that the other elements must be appended to the input - * stack. - */ - int inputStackTop; - - /** - * Maximum height reached by the output stack, relatively to the top of the - * input stack. This maximum is always positive or null. - */ - int outputStackMax; - - /** - * Information about the input and output stack map frames of this basic - * block. This field is only used when {@link ClassWriter#COMPUTE_FRAMES} - * option is used. - */ - Frame frame; - - /** - * The successor of this label, in the order they are visited. This linked - * list does not include labels used for debug info only. If - * {@link ClassWriter#COMPUTE_FRAMES} option is used then, in addition, it - * does not contain successive labels that denote the same bytecode position - * (in this case only the first label appears in this list). - */ - Label successor; - - /** - * The successors of this node in the control flow graph. These successors - * are stored in a linked list of {@link Edge Edge} objects, linked to each - * other by their {@link Edge#next} field. - */ - Edge successors; - - /** - * The next basic block in the basic block stack. This stack is used in the - * main loop of the fix point algorithm used in the second step of the - * control flow analysis algorithms. It is also used in - * {@link #visitSubroutine} to avoid using a recursive method. - * - * @see MethodWriter#visitMaxs - */ - Label next; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructs a new label. - */ - public Label() { - } - - // ------------------------------------------------------------------------ - // Methods to compute offsets and to manage forward references - // ------------------------------------------------------------------------ - - /** - * Returns the offset corresponding to this label. This offset is computed - * from the start of the method's bytecode. This method is intended for - * {@link Attribute} sub classes, and is normally not needed by class - * generators or adapters. - * - * @return the offset corresponding to this label. - * @throws IllegalStateException - * if this label is not resolved yet. - */ - public int getOffset() { - if ((status & RESOLVED) == 0) { - throw new IllegalStateException( - "Label offset position has not been resolved yet"); - } - return position; - } - - /** - * Puts a reference to this label in the bytecode of a method. If the - * position of the label is known, the offset is computed and written - * directly. Otherwise, a null offset is written and a new forward reference - * is declared for this label. - * - * @param owner - * the code writer that calls this method. - * @param out - * the bytecode of the method. - * @param source - * the position of first byte of the bytecode instruction that - * contains this label. - * @param wideOffset - * true if the reference must be stored in 4 bytes, or - * false if it must be stored with 2 bytes. - * @throws IllegalArgumentException - * if this label has not been created by the given code writer. - */ - void put(final MethodWriter owner, final ByteVector out, final int source, - final boolean wideOffset) { - if ((status & RESOLVED) == 0) { - if (wideOffset) { - addReference(-1 - source, out.length); - out.putInt(-1); - } else { - addReference(source, out.length); - out.putShort(-1); - } - } else { - if (wideOffset) { - out.putInt(position - source); - } else { - out.putShort(position - source); - } - } - } - - /** - * Adds a forward reference to this label. This method must be called only - * for a true forward reference, i.e. only if this label is not resolved - * yet. For backward references, the offset of the reference can be, and - * must be, computed and stored directly. - * - * @param sourcePosition - * the position of the referencing instruction. This position - * will be used to compute the offset of this forward reference. - * @param referencePosition - * the position where the offset for this forward reference must - * be stored. - */ - private void addReference(final int sourcePosition, - final int referencePosition) { - if (srcAndRefPositions == null) { - srcAndRefPositions = new int[6]; - } - if (referenceCount >= srcAndRefPositions.length) { - int[] a = new int[srcAndRefPositions.length + 6]; - System.arraycopy(srcAndRefPositions, 0, a, 0, - srcAndRefPositions.length); - srcAndRefPositions = a; - } - srcAndRefPositions[referenceCount++] = sourcePosition; - srcAndRefPositions[referenceCount++] = referencePosition; - } - - /** - * Resolves all forward references to this label. This method must be called - * when this label is added to the bytecode of the method, i.e. when its - * position becomes known. This method fills in the blanks that where left - * in the bytecode by each forward reference previously added to this label. - * - * @param owner - * the code writer that calls this method. - * @param position - * the position of this label in the bytecode. - * @param data - * the bytecode of the method. - * @return true if a blank that was left for this label was to - * small to store the offset. In such a case the corresponding jump - * instruction is replaced with a pseudo instruction (using unused - * opcodes) using an unsigned two bytes offset. These pseudo - * instructions will need to be replaced with true instructions with - * wider offsets (4 bytes instead of 2). This is done in - * {@link MethodWriter#resizeInstructions}. - * @throws IllegalArgumentException - * if this label has already been resolved, or if it has not - * been created by the given code writer. - */ - boolean resolve(final MethodWriter owner, final int position, - final byte[] data) { - boolean needUpdate = false; - this.status |= RESOLVED; - this.position = position; - int i = 0; - while (i < referenceCount) { - int source = srcAndRefPositions[i++]; - int reference = srcAndRefPositions[i++]; - int offset; - if (source >= 0) { - offset = position - source; - if (offset < Short.MIN_VALUE || offset > Short.MAX_VALUE) { - /* - * changes the opcode of the jump instruction, in order to - * be able to find it later (see resizeInstructions in - * MethodWriter). These temporary opcodes are similar to - * jump instruction opcodes, except that the 2 bytes offset - * is unsigned (and can therefore represent values from 0 to - * 65535, which is sufficient since the size of a method is - * limited to 65535 bytes). - */ - int opcode = data[reference - 1] & 0xFF; - if (opcode <= Opcodes.JSR) { - // changes IFEQ ... JSR to opcodes 202 to 217 - data[reference - 1] = (byte) (opcode + 49); - } else { - // changes IFNULL and IFNONNULL to opcodes 218 and 219 - data[reference - 1] = (byte) (opcode + 20); - } - needUpdate = true; - } - data[reference++] = (byte) (offset >>> 8); - data[reference] = (byte) offset; - } else { - offset = position + source + 1; - data[reference++] = (byte) (offset >>> 24); - data[reference++] = (byte) (offset >>> 16); - data[reference++] = (byte) (offset >>> 8); - data[reference] = (byte) offset; - } - } - return needUpdate; - } - - /** - * Returns the first label of the series to which this label belongs. For an - * isolated label or for the first label in a series of successive labels, - * this method returns the label itself. For other labels it returns the - * first label of the series. - * - * @return the first label of the series to which this label belongs. - */ - Label getFirst() { - return !ClassReader.FRAMES || frame == null ? this : frame.owner; - } - - // ------------------------------------------------------------------------ - // Methods related to subroutines - // ------------------------------------------------------------------------ - - /** - * Returns true is this basic block belongs to the given subroutine. - * - * @param id - * a subroutine id. - * @return true is this basic block belongs to the given subroutine. - */ - boolean inSubroutine(final long id) { - if ((status & Label.VISITED) != 0) { - return (srcAndRefPositions[(int) (id >>> 32)] & (int) id) != 0; - } - return false; - } - - /** - * Returns true if this basic block and the given one belong to a common - * subroutine. - * - * @param block - * another basic block. - * @return true if this basic block and the given one belong to a common - * subroutine. - */ - boolean inSameSubroutine(final Label block) { - if ((status & VISITED) == 0 || (block.status & VISITED) == 0) { - return false; - } - for (int i = 0; i < srcAndRefPositions.length; ++i) { - if ((srcAndRefPositions[i] & block.srcAndRefPositions[i]) != 0) { - return true; - } - } - return false; - } - - /** - * Marks this basic block as belonging to the given subroutine. - * - * @param id - * a subroutine id. - * @param nbSubroutines - * the total number of subroutines in the method. - */ - void addToSubroutine(final long id, final int nbSubroutines) { - if ((status & VISITED) == 0) { - status |= VISITED; - srcAndRefPositions = new int[nbSubroutines / 32 + 1]; - } - srcAndRefPositions[(int) (id >>> 32)] |= (int) id; - } - - /** - * Finds the basic blocks that belong to a given subroutine, and marks these - * blocks as belonging to this subroutine. This method follows the control - * flow graph to find all the blocks that are reachable from the current - * block WITHOUT following any JSR target. - * - * @param JSR - * a JSR block that jumps to this subroutine. If this JSR is not - * null it is added to the successor of the RET blocks found in - * the subroutine. - * @param id - * the id of this subroutine. - * @param nbSubroutines - * the total number of subroutines in the method. - */ - void visitSubroutine(final Label JSR, final long id, final int nbSubroutines) { - // user managed stack of labels, to avoid using a recursive method - // (recursivity can lead to stack overflow with very large methods) - Label stack = this; - while (stack != null) { - // removes a label l from the stack - Label l = stack; - stack = l.next; - l.next = null; - - if (JSR != null) { - if ((l.status & VISITED2) != 0) { - continue; - } - l.status |= VISITED2; - // adds JSR to the successors of l, if it is a RET block - if ((l.status & RET) != 0) { - if (!l.inSameSubroutine(JSR)) { - Edge e = new Edge(); - e.info = l.inputStackTop; - e.successor = JSR.successors.successor; - e.next = l.successors; - l.successors = e; - } - } - } else { - // if the l block already belongs to subroutine 'id', continue - if (l.inSubroutine(id)) { - continue; - } - // marks the l block as belonging to subroutine 'id' - l.addToSubroutine(id, nbSubroutines); - } - // pushes each successor of l on the stack, except JSR targets - Edge e = l.successors; - while (e != null) { - // if the l block is a JSR block, then 'l.successors.next' leads - // to the JSR target (see {@link #visitJumpInsn}) and must - // therefore not be followed - if ((l.status & Label.JSR) == 0 || e != l.successors.next) { - // pushes e.successor on the stack if it not already added - if (e.successor.next == null) { - e.successor.next = stack; - stack = e.successor; - } - } - e = e.next; - } - } - } - - // ------------------------------------------------------------------------ - // Overridden Object methods - // ------------------------------------------------------------------------ - - /** - * Returns a string representation of this label. - * - * @return a string representation of this label. - */ - @Override - public String toString() { - return "L" + System.identityHashCode(this); - } -} diff --git a/src/asm/scala/tools/asm/MethodVisitor.java b/src/asm/scala/tools/asm/MethodVisitor.java deleted file mode 100644 index bddc325020..0000000000 --- a/src/asm/scala/tools/asm/MethodVisitor.java +++ /dev/null @@ -1,880 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm; - -/** - * A visitor to visit a Java method. The methods of this class must be called in - * the following order: ( visitParameter )* [ - * visitAnnotationDefault ] ( visitAnnotation | - * visitTypeAnnotation | visitAttribute )* [ - * visitCode ( visitFrame | visitXInsn | - * visitLabel | visitInsnAnnotation | - * visitTryCatchBlock | visitTryCatchBlockAnnotation | - * visitLocalVariable | visitLocalVariableAnnotation | - * visitLineNumber )* visitMaxs ] visitEnd. In - * addition, the visitXInsn and visitLabel methods must - * be called in the sequential order of the bytecode instructions of the visited - * code, visitInsnAnnotation must be called after the annotated - * instruction, visitTryCatchBlock must be called before the - * labels passed as arguments have been visited, - * visitTryCatchBlockAnnotation must be called after the - * corresponding try catch block has been visited, and the - * visitLocalVariable, visitLocalVariableAnnotation and - * visitLineNumber methods must be called after the labels - * passed as arguments have been visited. - * - * @author Eric Bruneton - */ -public abstract class MethodVisitor { - - /** - * The ASM API version implemented by this visitor. The value of this field - * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - protected final int api; - - /** - * The method visitor to which this visitor must delegate method calls. May - * be null. - */ - protected MethodVisitor mv; - - /** - * Constructs a new {@link MethodVisitor}. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - public MethodVisitor(final int api) { - this(api, null); - } - - /** - * Constructs a new {@link MethodVisitor}. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - * @param mv - * the method visitor to which this visitor must delegate method - * calls. May be null. - */ - public MethodVisitor(final int api, final MethodVisitor mv) { - if (api != Opcodes.ASM4 && api != Opcodes.ASM5) { - throw new IllegalArgumentException(); - } - this.api = api; - this.mv = mv; - } - - // ------------------------------------------------------------------------- - // Parameters, annotations and non standard attributes - // ------------------------------------------------------------------------- - - /** - * Visits a parameter of this method. - * - * @param name - * parameter name or null if none is provided. - * @param access - * the parameter's access flags, only ACC_FINAL, - * ACC_SYNTHETIC or/and ACC_MANDATED are - * allowed (see {@link Opcodes}). - */ - public void visitParameter(String name, int access) { - if (api < Opcodes.ASM5) { - throw new RuntimeException(); - } - if (mv != null) { - mv.visitParameter(name, access); - } - } - - /** - * Visits the default value of this annotation interface method. - * - * @return a visitor to the visit the actual default value of this - * annotation interface method, or null if this visitor is - * not interested in visiting this default value. The 'name' - * parameters passed to the methods of this annotation visitor are - * ignored. Moreover, exacly one visit method must be called on this - * annotation visitor, followed by visitEnd. - */ - public AnnotationVisitor visitAnnotationDefault() { - if (mv != null) { - return mv.visitAnnotationDefault(); - } - return null; - } - - /** - * Visits an annotation of this method. - * - * @param desc - * the class descriptor of the annotation class. - * @param visible - * true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if - * this visitor is not interested in visiting this annotation. - */ - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - if (mv != null) { - return mv.visitAnnotation(desc, visible); - } - return null; - } - - /** - * Visits an annotation on a type in the method signature. - * - * @param typeRef - * a reference to the annotated type. The sort of this type - * reference must be {@link TypeReference#METHOD_TYPE_PARAMETER - * METHOD_TYPE_PARAMETER}, - * {@link TypeReference#METHOD_TYPE_PARAMETER_BOUND - * METHOD_TYPE_PARAMETER_BOUND}, - * {@link TypeReference#METHOD_RETURN METHOD_RETURN}, - * {@link TypeReference#METHOD_RECEIVER METHOD_RECEIVER}, - * {@link TypeReference#METHOD_FORMAL_PARAMETER - * METHOD_FORMAL_PARAMETER} or {@link TypeReference#THROWS - * THROWS}. See {@link TypeReference}. - * @param typePath - * the path to the annotated type argument, wildcard bound, array - * element type, or static inner type within 'typeRef'. May be - * null if the annotation targets 'typeRef' as a whole. - * @param desc - * the class descriptor of the annotation class. - * @param visible - * true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if - * this visitor is not interested in visiting this annotation. - */ - public AnnotationVisitor visitTypeAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - if (api < Opcodes.ASM5) { - throw new RuntimeException(); - } - if (mv != null) { - return mv.visitTypeAnnotation(typeRef, typePath, desc, visible); - } - return null; - } - - /** - * Visits an annotation of a parameter this method. - * - * @param parameter - * the parameter index. - * @param desc - * the class descriptor of the annotation class. - * @param visible - * true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if - * this visitor is not interested in visiting this annotation. - */ - public AnnotationVisitor visitParameterAnnotation(int parameter, - String desc, boolean visible) { - if (mv != null) { - return mv.visitParameterAnnotation(parameter, desc, visible); - } - return null; - } - - /** - * Visits a non standard attribute of this method. - * - * @param attr - * an attribute. - */ - public void visitAttribute(Attribute attr) { - if (mv != null) { - mv.visitAttribute(attr); - } - } - - /** - * Starts the visit of the method's code, if any (i.e. non abstract method). - */ - public void visitCode() { - if (mv != null) { - mv.visitCode(); - } - } - - /** - * Visits the current state of the local variables and operand stack - * elements. This method must(*) be called just before any - * instruction i that follows an unconditional branch instruction - * such as GOTO or THROW, that is the target of a jump instruction, or that - * starts an exception handler block. The visited types must describe the - * values of the local variables and of the operand stack elements just - * before i is executed.
- *
- * (*) this is mandatory only for classes whose version is greater than or - * equal to {@link Opcodes#V1_6 V1_6}.
- *
- * The frames of a method must be given either in expanded form, or in - * compressed form (all frames must use the same format, i.e. you must not - * mix expanded and compressed frames within a single method): - *
    - *
  • In expanded form, all frames must have the F_NEW type.
  • - *
  • In compressed form, frames are basically "deltas" from the state of - * the previous frame: - *
      - *
    • {@link Opcodes#F_SAME} representing frame with exactly the same - * locals as the previous frame and with the empty stack.
    • - *
    • {@link Opcodes#F_SAME1} representing frame with exactly the same - * locals as the previous frame and with single value on the stack ( - * nStack is 1 and stack[0] contains value for the - * type of the stack item).
    • - *
    • {@link Opcodes#F_APPEND} representing frame with current locals are - * the same as the locals in the previous frame, except that additional - * locals are defined (nLocal is 1, 2 or 3 and - * local elements contains values representing added types).
    • - *
    • {@link Opcodes#F_CHOP} representing frame with current locals are the - * same as the locals in the previous frame, except that the last 1-3 locals - * are absent and with the empty stack (nLocals is 1, 2 or 3).
    • - *
    • {@link Opcodes#F_FULL} representing complete frame data.
    • - *
    - *
  • - *
- *
- * In both cases the first frame, corresponding to the method's parameters - * and access flags, is implicit and must not be visited. Also, it is - * illegal to visit two or more frames for the same code location (i.e., at - * least one instruction must be visited between two calls to visitFrame). - * - * @param type - * the type of this stack map frame. Must be - * {@link Opcodes#F_NEW} for expanded frames, or - * {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, - * {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or - * {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for - * compressed frames. - * @param nLocal - * the number of local variables in the visited frame. - * @param local - * the local variable types in this frame. This array must not be - * modified. Primitive types are represented by - * {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, - * {@link Opcodes#FLOAT}, {@link Opcodes#LONG}, - * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or - * {@link Opcodes#UNINITIALIZED_THIS} (long and double are - * represented by a single element). Reference types are - * represented by String objects (representing internal names), - * and uninitialized types by Label objects (this label - * designates the NEW instruction that created this uninitialized - * value). - * @param nStack - * the number of operand stack elements in the visited frame. - * @param stack - * the operand stack types in this frame. This array must not be - * modified. Its content has the same format as the "local" - * array. - * @throws IllegalStateException - * if a frame is visited just after another one, without any - * instruction between the two (unless this frame is a - * Opcodes#F_SAME frame, in which case it is silently ignored). - */ - public void visitFrame(int type, int nLocal, Object[] local, int nStack, - Object[] stack) { - if (mv != null) { - mv.visitFrame(type, nLocal, local, nStack, stack); - } - } - - // ------------------------------------------------------------------------- - // Normal instructions - // ------------------------------------------------------------------------- - - /** - * Visits a zero operand instruction. - * - * @param opcode - * the opcode of the instruction to be visited. This opcode is - * either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, - * ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, - * FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, - * LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, - * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, - * SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, - * DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, - * IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM, - * FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, - * IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, - * L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S, - * LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN, - * DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, - * or MONITOREXIT. - */ - public void visitInsn(int opcode) { - if (mv != null) { - mv.visitInsn(opcode); - } - } - - /** - * Visits an instruction with a single int operand. - * - * @param opcode - * the opcode of the instruction to be visited. This opcode is - * either BIPUSH, SIPUSH or NEWARRAY. - * @param operand - * the operand of the instruction to be visited.
- * When opcode is BIPUSH, operand value should be between - * Byte.MIN_VALUE and Byte.MAX_VALUE.
- * When opcode is SIPUSH, operand value should be between - * Short.MIN_VALUE and Short.MAX_VALUE.
- * When opcode is NEWARRAY, operand value should be one of - * {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR}, - * {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, - * {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT}, - * {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}. - */ - public void visitIntInsn(int opcode, int operand) { - if (mv != null) { - mv.visitIntInsn(opcode, operand); - } - } - - /** - * Visits a local variable instruction. A local variable instruction is an - * instruction that loads or stores the value of a local variable. - * - * @param opcode - * the opcode of the local variable instruction to be visited. - * This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, - * ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET. - * @param var - * the operand of the instruction to be visited. This operand is - * the index of a local variable. - */ - public void visitVarInsn(int opcode, int var) { - if (mv != null) { - mv.visitVarInsn(opcode, var); - } - } - - /** - * Visits a type instruction. A type instruction is an instruction that - * takes the internal name of a class as parameter. - * - * @param opcode - * the opcode of the type instruction to be visited. This opcode - * is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF. - * @param type - * the operand of the instruction to be visited. This operand - * must be the internal name of an object or array class (see - * {@link Type#getInternalName() getInternalName}). - */ - public void visitTypeInsn(int opcode, String type) { - if (mv != null) { - mv.visitTypeInsn(opcode, type); - } - } - - /** - * Visits a field instruction. A field instruction is an instruction that - * loads or stores the value of a field of an object. - * - * @param opcode - * the opcode of the type instruction to be visited. This opcode - * is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. - * @param owner - * the internal name of the field's owner class (see - * {@link Type#getInternalName() getInternalName}). - * @param name - * the field's name. - * @param desc - * the field's descriptor (see {@link Type Type}). - */ - public void visitFieldInsn(int opcode, String owner, String name, - String desc) { - if (mv != null) { - mv.visitFieldInsn(opcode, owner, name, desc); - } - } - - /** - * Visits a method instruction. A method instruction is an instruction that - * invokes a method. - * - * @param opcode - * the opcode of the type instruction to be visited. This opcode - * is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or - * INVOKEINTERFACE. - * @param owner - * the internal name of the method's owner class (see - * {@link Type#getInternalName() getInternalName}). - * @param name - * the method's name. - * @param desc - * the method's descriptor (see {@link Type Type}). - */ - @Deprecated - public void visitMethodInsn(int opcode, String owner, String name, - String desc) { - if (api >= Opcodes.ASM5) { - boolean itf = opcode == Opcodes.INVOKEINTERFACE; - visitMethodInsn(opcode, owner, name, desc, itf); - return; - } - if (mv != null) { - mv.visitMethodInsn(opcode, owner, name, desc); - } - } - - /** - * Visits a method instruction. A method instruction is an instruction that - * invokes a method. - * - * @param opcode - * the opcode of the type instruction to be visited. This opcode - * is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or - * INVOKEINTERFACE. - * @param owner - * the internal name of the method's owner class (see - * {@link Type#getInternalName() getInternalName}). - * @param name - * the method's name. - * @param desc - * the method's descriptor (see {@link Type Type}). - * @param itf - * if the method's owner class is an interface. - */ - public void visitMethodInsn(int opcode, String owner, String name, - String desc, boolean itf) { - if (api < Opcodes.ASM5) { - if (itf != (opcode == Opcodes.INVOKEINTERFACE)) { - throw new IllegalArgumentException( - "INVOKESPECIAL/STATIC on interfaces require ASM 5"); - } - visitMethodInsn(opcode, owner, name, desc); - return; - } - if (mv != null) { - mv.visitMethodInsn(opcode, owner, name, desc, itf); - } - } - - /** - * Visits an invokedynamic instruction. - * - * @param name - * the method's name. - * @param desc - * the method's descriptor (see {@link Type Type}). - * @param bsm - * the bootstrap method. - * @param bsmArgs - * the bootstrap method constant arguments. Each argument must be - * an {@link Integer}, {@link Float}, {@link Long}, - * {@link Double}, {@link String}, {@link Type} or {@link Handle} - * value. This method is allowed to modify the content of the - * array so a caller should expect that this array may change. - */ - public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, - Object... bsmArgs) { - if (mv != null) { - mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); - } - } - - /** - * Visits a jump instruction. A jump instruction is an instruction that may - * jump to another instruction. - * - * @param opcode - * the opcode of the type instruction to be visited. This opcode - * is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, - * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, - * IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL. - * @param label - * the operand of the instruction to be visited. This operand is - * a label that designates the instruction to which the jump - * instruction may jump. - */ - public void visitJumpInsn(int opcode, Label label) { - if (mv != null) { - mv.visitJumpInsn(opcode, label); - } - } - - /** - * Visits a label. A label designates the instruction that will be visited - * just after it. - * - * @param label - * a {@link Label Label} object. - */ - public void visitLabel(Label label) { - if (mv != null) { - mv.visitLabel(label); - } - } - - // ------------------------------------------------------------------------- - // Special instructions - // ------------------------------------------------------------------------- - - /** - * Visits a LDC instruction. Note that new constant types may be added in - * future versions of the Java Virtual Machine. To easily detect new - * constant types, implementations of this method should check for - * unexpected constant types, like this: - * - *
-     * if (cst instanceof Integer) {
-     *     // ...
-     * } else if (cst instanceof Float) {
-     *     // ...
-     * } else if (cst instanceof Long) {
-     *     // ...
-     * } else if (cst instanceof Double) {
-     *     // ...
-     * } else if (cst instanceof String) {
-     *     // ...
-     * } else if (cst instanceof Type) {
-     *     int sort = ((Type) cst).getSort();
-     *     if (sort == Type.OBJECT) {
-     *         // ...
-     *     } else if (sort == Type.ARRAY) {
-     *         // ...
-     *     } else if (sort == Type.METHOD) {
-     *         // ...
-     *     } else {
-     *         // throw an exception
-     *     }
-     * } else if (cst instanceof Handle) {
-     *     // ...
-     * } else {
-     *     // throw an exception
-     * }
-     * 
- * - * @param cst - * the constant to be loaded on the stack. This parameter must be - * a non null {@link Integer}, a {@link Float}, a {@link Long}, a - * {@link Double}, a {@link String}, a {@link Type} of OBJECT or - * ARRAY sort for .class constants, for classes whose - * version is 49.0, a {@link Type} of METHOD sort or a - * {@link Handle} for MethodType and MethodHandle constants, for - * classes whose version is 51.0. - */ - public void visitLdcInsn(Object cst) { - if (mv != null) { - mv.visitLdcInsn(cst); - } - } - - /** - * Visits an IINC instruction. - * - * @param var - * index of the local variable to be incremented. - * @param increment - * amount to increment the local variable by. - */ - public void visitIincInsn(int var, int increment) { - if (mv != null) { - mv.visitIincInsn(var, increment); - } - } - - /** - * Visits a TABLESWITCH instruction. - * - * @param min - * the minimum key value. - * @param max - * the maximum key value. - * @param dflt - * beginning of the default handler block. - * @param labels - * beginnings of the handler blocks. labels[i] is the - * beginning of the handler block for the min + i key. - */ - public void visitTableSwitchInsn(int min, int max, Label dflt, - Label... labels) { - if (mv != null) { - mv.visitTableSwitchInsn(min, max, dflt, labels); - } - } - - /** - * Visits a LOOKUPSWITCH instruction. - * - * @param dflt - * beginning of the default handler block. - * @param keys - * the values of the keys. - * @param labels - * beginnings of the handler blocks. labels[i] is the - * beginning of the handler block for the keys[i] key. - */ - public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { - if (mv != null) { - mv.visitLookupSwitchInsn(dflt, keys, labels); - } - } - - /** - * Visits a MULTIANEWARRAY instruction. - * - * @param desc - * an array type descriptor (see {@link Type Type}). - * @param dims - * number of dimensions of the array to allocate. - */ - public void visitMultiANewArrayInsn(String desc, int dims) { - if (mv != null) { - mv.visitMultiANewArrayInsn(desc, dims); - } - } - - /** - * Visits an annotation on an instruction. This method must be called just - * after the annotated instruction. It can be called several times - * for the same instruction. - * - * @param typeRef - * a reference to the annotated type. The sort of this type - * reference must be {@link TypeReference#INSTANCEOF INSTANCEOF}, - * {@link TypeReference#NEW NEW}, - * {@link TypeReference#CONSTRUCTOR_REFERENCE - * CONSTRUCTOR_REFERENCE}, {@link TypeReference#METHOD_REFERENCE - * METHOD_REFERENCE}, {@link TypeReference#CAST CAST}, - * {@link TypeReference#CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT - * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, - * {@link TypeReference#METHOD_INVOCATION_TYPE_ARGUMENT - * METHOD_INVOCATION_TYPE_ARGUMENT}, - * {@link TypeReference#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT - * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or - * {@link TypeReference#METHOD_REFERENCE_TYPE_ARGUMENT - * METHOD_REFERENCE_TYPE_ARGUMENT}. See {@link TypeReference}. - * @param typePath - * the path to the annotated type argument, wildcard bound, array - * element type, or static inner type within 'typeRef'. May be - * null if the annotation targets 'typeRef' as a whole. - * @param desc - * the class descriptor of the annotation class. - * @param visible - * true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if - * this visitor is not interested in visiting this annotation. - */ - public AnnotationVisitor visitInsnAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - if (api < Opcodes.ASM5) { - throw new RuntimeException(); - } - if (mv != null) { - return mv.visitInsnAnnotation(typeRef, typePath, desc, visible); - } - return null; - } - - // ------------------------------------------------------------------------- - // Exceptions table entries, debug information, max stack and max locals - // ------------------------------------------------------------------------- - - /** - * Visits a try catch block. - * - * @param start - * beginning of the exception handler's scope (inclusive). - * @param end - * end of the exception handler's scope (exclusive). - * @param handler - * beginning of the exception handler's code. - * @param type - * internal name of the type of exceptions handled by the - * handler, or null to catch any exceptions (for - * "finally" blocks). - * @throws IllegalArgumentException - * if one of the labels has already been visited by this visitor - * (by the {@link #visitLabel visitLabel} method). - */ - public void visitTryCatchBlock(Label start, Label end, Label handler, - String type) { - if (mv != null) { - mv.visitTryCatchBlock(start, end, handler, type); - } - } - - /** - * Visits an annotation on an exception handler type. This method must be - * called after the {@link #visitTryCatchBlock} for the annotated - * exception handler. It can be called several times for the same exception - * handler. - * - * @param typeRef - * a reference to the annotated type. The sort of this type - * reference must be {@link TypeReference#EXCEPTION_PARAMETER - * EXCEPTION_PARAMETER}. See {@link TypeReference}. - * @param typePath - * the path to the annotated type argument, wildcard bound, array - * element type, or static inner type within 'typeRef'. May be - * null if the annotation targets 'typeRef' as a whole. - * @param desc - * the class descriptor of the annotation class. - * @param visible - * true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if - * this visitor is not interested in visiting this annotation. - */ - public AnnotationVisitor visitTryCatchAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - if (api < Opcodes.ASM5) { - throw new RuntimeException(); - } - if (mv != null) { - return mv.visitTryCatchAnnotation(typeRef, typePath, desc, visible); - } - return null; - } - - /** - * Visits a local variable declaration. - * - * @param name - * the name of a local variable. - * @param desc - * the type descriptor of this local variable. - * @param signature - * the type signature of this local variable. May be - * null if the local variable type does not use generic - * types. - * @param start - * the first instruction corresponding to the scope of this local - * variable (inclusive). - * @param end - * the last instruction corresponding to the scope of this local - * variable (exclusive). - * @param index - * the local variable's index. - * @throws IllegalArgumentException - * if one of the labels has not already been visited by this - * visitor (by the {@link #visitLabel visitLabel} method). - */ - public void visitLocalVariable(String name, String desc, String signature, - Label start, Label end, int index) { - if (mv != null) { - mv.visitLocalVariable(name, desc, signature, start, end, index); - } - } - - /** - * Visits an annotation on a local variable type. - * - * @param typeRef - * a reference to the annotated type. The sort of this type - * reference must be {@link TypeReference#LOCAL_VARIABLE - * LOCAL_VARIABLE} or {@link TypeReference#RESOURCE_VARIABLE - * RESOURCE_VARIABLE}. See {@link TypeReference}. - * @param typePath - * the path to the annotated type argument, wildcard bound, array - * element type, or static inner type within 'typeRef'. May be - * null if the annotation targets 'typeRef' as a whole. - * @param start - * the fist instructions corresponding to the continuous ranges - * that make the scope of this local variable (inclusive). - * @param end - * the last instructions corresponding to the continuous ranges - * that make the scope of this local variable (exclusive). This - * array must have the same size as the 'start' array. - * @param index - * the local variable's index in each range. This array must have - * the same size as the 'start' array. - * @param desc - * the class descriptor of the annotation class. - * @param visible - * true if the annotation is visible at runtime. - * @return a visitor to visit the annotation values, or null if - * this visitor is not interested in visiting this annotation. - */ - public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, - TypePath typePath, Label[] start, Label[] end, int[] index, - String desc, boolean visible) { - if (api < Opcodes.ASM5) { - throw new RuntimeException(); - } - if (mv != null) { - return mv.visitLocalVariableAnnotation(typeRef, typePath, start, - end, index, desc, visible); - } - return null; - } - - /** - * Visits a line number declaration. - * - * @param line - * a line number. This number refers to the source file from - * which the class was compiled. - * @param start - * the first instruction corresponding to this line number. - * @throws IllegalArgumentException - * if start has not already been visited by this - * visitor (by the {@link #visitLabel visitLabel} method). - */ - public void visitLineNumber(int line, Label start) { - if (mv != null) { - mv.visitLineNumber(line, start); - } - } - - /** - * Visits the maximum stack size and the maximum number of local variables - * of the method. - * - * @param maxStack - * maximum stack size of the method. - * @param maxLocals - * maximum number of local variables for the method. - */ - public void visitMaxs(int maxStack, int maxLocals) { - if (mv != null) { - mv.visitMaxs(maxStack, maxLocals); - } - } - - /** - * Visits the end of the method. This method, which is the last one to be - * called, is used to inform the visitor that all the annotations and - * attributes of the method have been visited. - */ - public void visitEnd() { - if (mv != null) { - mv.visitEnd(); - } - } -} diff --git a/src/asm/scala/tools/asm/MethodWriter.java b/src/asm/scala/tools/asm/MethodWriter.java deleted file mode 100644 index 9c72ead61d..0000000000 --- a/src/asm/scala/tools/asm/MethodWriter.java +++ /dev/null @@ -1,2924 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm; - -/** - * A {@link MethodVisitor} that generates methods in bytecode form. Each visit - * method of this class appends the bytecode corresponding to the visited - * instruction to a byte vector, in the order these methods are called. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -public class MethodWriter extends MethodVisitor { - - /** - * Pseudo access flag used to denote constructors. - */ - static final int ACC_CONSTRUCTOR = 0x80000; - - /** - * Frame has exactly the same locals as the previous stack map frame and - * number of stack items is zero. - */ - static final int SAME_FRAME = 0; // to 63 (0-3f) - - /** - * Frame has exactly the same locals as the previous stack map frame and - * number of stack items is 1 - */ - static final int SAME_LOCALS_1_STACK_ITEM_FRAME = 64; // to 127 (40-7f) - - /** - * Reserved for future use - */ - static final int RESERVED = 128; - - /** - * Frame has exactly the same locals as the previous stack map frame and - * number of stack items is 1. Offset is bigger then 63; - */ - static final int SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED = 247; // f7 - - /** - * Frame where current locals are the same as the locals in the previous - * frame, except that the k last locals are absent. The value of k is given - * by the formula 251-frame_type. - */ - static final int CHOP_FRAME = 248; // to 250 (f8-fA) - - /** - * Frame has exactly the same locals as the previous stack map frame and - * number of stack items is zero. Offset is bigger then 63; - */ - static final int SAME_FRAME_EXTENDED = 251; // fb - - /** - * Frame where current locals are the same as the locals in the previous - * frame, except that k additional locals are defined. The value of k is - * given by the formula frame_type-251. - */ - static final int APPEND_FRAME = 252; // to 254 // fc-fe - - /** - * Full frame - */ - static final int FULL_FRAME = 255; // ff - - /** - * Indicates that the stack map frames must be recomputed from scratch. In - * this case the maximum stack size and number of local variables is also - * recomputed from scratch. - * - * @see #compute - */ - private static final int FRAMES = 0; - - /** - * Indicates that the maximum stack size and number of local variables must - * be automatically computed. - * - * @see #compute - */ - private static final int MAXS = 1; - - /** - * Indicates that nothing must be automatically computed. - * - * @see #compute - */ - private static final int NOTHING = 2; - - /** - * The class writer to which this method must be added. - */ - final ClassWriter cw; - - /** - * Access flags of this method. - */ - private int access; - - /** - * The index of the constant pool item that contains the name of this - * method. - */ - private final int name; - - /** - * The index of the constant pool item that contains the descriptor of this - * method. - */ - private final int desc; - - /** - * The descriptor of this method. - */ - private final String descriptor; - - /** - * The signature of this method. - */ - String signature; - - /** - * If not zero, indicates that the code of this method must be copied from - * the ClassReader associated to this writer in cw.cr. More - * precisely, this field gives the index of the first byte to copied from - * cw.cr.b. - */ - int classReaderOffset; - - /** - * If not zero, indicates that the code of this method must be copied from - * the ClassReader associated to this writer in cw.cr. More - * precisely, this field gives the number of bytes to copied from - * cw.cr.b. - */ - int classReaderLength; - - /** - * Number of exceptions that can be thrown by this method. - */ - int exceptionCount; - - /** - * The exceptions that can be thrown by this method. More precisely, this - * array contains the indexes of the constant pool items that contain the - * internal names of these exception classes. - */ - int[] exceptions; - - /** - * The annotation default attribute of this method. May be null. - */ - private ByteVector annd; - - /** - * The runtime visible annotations of this method. May be null. - */ - private AnnotationWriter anns; - - /** - * The runtime invisible annotations of this method. May be null. - */ - private AnnotationWriter ianns; - - /** - * The runtime visible type annotations of this method. May be null - * . - */ - private AnnotationWriter tanns; - - /** - * The runtime invisible type annotations of this method. May be - * null. - */ - private AnnotationWriter itanns; - - /** - * The runtime visible parameter annotations of this method. May be - * null. - */ - private AnnotationWriter[] panns; - - /** - * The runtime invisible parameter annotations of this method. May be - * null. - */ - private AnnotationWriter[] ipanns; - - /** - * The number of synthetic parameters of this method. - */ - private int synthetics; - - /** - * The non standard attributes of the method. - */ - private Attribute attrs; - - /** - * The bytecode of this method. - */ - private ByteVector code = new ByteVector(); - - /** - * Maximum stack size of this method. - */ - private int maxStack; - - public int getMaxStack() { - return maxStack; - } - - /** - * Maximum number of local variables for this method. - */ - private int maxLocals; - - public int getMaxLocals() { - return maxLocals; - } - - /** - * Number of local variables in the current stack map frame. - */ - private int currentLocals; - - /** - * Number of stack map frames in the StackMapTable attribute. - */ - private int frameCount; - - /** - * The StackMapTable attribute. - */ - private ByteVector stackMap; - - /** - * The offset of the last frame that was written in the StackMapTable - * attribute. - */ - private int previousFrameOffset; - - /** - * The last frame that was written in the StackMapTable attribute. - * - * @see #frame - */ - private int[] previousFrame; - - /** - * The current stack map frame. The first element contains the offset of the - * instruction to which the frame corresponds, the second element is the - * number of locals and the third one is the number of stack elements. The - * local variables start at index 3 and are followed by the operand stack - * values. In summary frame[0] = offset, frame[1] = nLocal, frame[2] = - * nStack, frame[3] = nLocal. All types are encoded as integers, with the - * same format as the one used in {@link Label}, but limited to BASE types. - */ - private int[] frame; - - /** - * Number of elements in the exception handler list. - */ - private int handlerCount; - - /** - * The first element in the exception handler list. - */ - private Handler firstHandler; - - /** - * The last element in the exception handler list. - */ - private Handler lastHandler; - - /** - * Number of entries in the MethodParameters attribute. - */ - private int methodParametersCount; - - /** - * The MethodParameters attribute. - */ - private ByteVector methodParameters; - - /** - * Number of entries in the LocalVariableTable attribute. - */ - private int localVarCount; - - /** - * The LocalVariableTable attribute. - */ - private ByteVector localVar; - - /** - * Number of entries in the LocalVariableTypeTable attribute. - */ - private int localVarTypeCount; - - /** - * The LocalVariableTypeTable attribute. - */ - private ByteVector localVarType; - - /** - * Number of entries in the LineNumberTable attribute. - */ - private int lineNumberCount; - - /** - * The LineNumberTable attribute. - */ - private ByteVector lineNumber; - - /** - * The start offset of the last visited instruction. - */ - private int lastCodeOffset; - - /** - * The runtime visible type annotations of the code. May be null. - */ - private AnnotationWriter ctanns; - - /** - * The runtime invisible type annotations of the code. May be null. - */ - private AnnotationWriter ictanns; - - /** - * The non standard attributes of the method's code. - */ - private Attribute cattrs; - - /** - * Indicates if some jump instructions are too small and need to be resized. - */ - private boolean resize; - - /** - * The number of subroutines in this method. - */ - private int subroutines; - - // ------------------------------------------------------------------------ - - /* - * Fields for the control flow graph analysis algorithm (used to compute the - * maximum stack size). A control flow graph contains one node per "basic - * block", and one edge per "jump" from one basic block to another. Each - * node (i.e., each basic block) is represented by the Label object that - * corresponds to the first instruction of this basic block. Each node also - * stores the list of its successors in the graph, as a linked list of Edge - * objects. - */ - - /** - * Indicates what must be automatically computed. - * - * @see #FRAMES - * @see #MAXS - * @see #NOTHING - */ - private final int compute; - - /** - * A list of labels. This list is the list of basic blocks in the method, - * i.e. a list of Label objects linked to each other by their - * {@link Label#successor} field, in the order they are visited by - * {@link MethodVisitor#visitLabel}, and starting with the first basic - * block. - */ - private Label labels; - - /** - * The previous basic block. - */ - private Label previousBlock; - - /** - * The current basic block. - */ - private Label currentBlock; - - /** - * The (relative) stack size after the last visited instruction. This size - * is relative to the beginning of the current basic block, i.e., the true - * stack size after the last visited instruction is equal to the - * {@link Label#inputStackTop beginStackSize} of the current basic block - * plus stackSize. - */ - private int stackSize; - - /** - * The (relative) maximum stack size after the last visited instruction. - * This size is relative to the beginning of the current basic block, i.e., - * the true maximum stack size after the last visited instruction is equal - * to the {@link Label#inputStackTop beginStackSize} of the current basic - * block plus stackSize. - */ - private int maxStackSize; - - // ------------------------------------------------------------------------ - // Constructor - // ------------------------------------------------------------------------ - - /** - * Constructs a new {@link MethodWriter}. - * - * @param cw - * the class writer in which the method must be added. - * @param access - * the method's access flags (see {@link Opcodes}). - * @param name - * the method's name. - * @param desc - * the method's descriptor (see {@link Type}). - * @param signature - * the method's signature. May be null. - * @param exceptions - * the internal names of the method's exceptions. May be - * null. - * @param computeMaxs - * true if the maximum stack size and number of local - * variables must be automatically computed. - * @param computeFrames - * true if the stack map tables must be recomputed from - * scratch. - */ - MethodWriter(final ClassWriter cw, final int access, final String name, - final String desc, final String signature, - final String[] exceptions, final boolean computeMaxs, - final boolean computeFrames) { - super(Opcodes.ASM5); - if (cw.firstMethod == null) { - cw.firstMethod = this; - } else { - cw.lastMethod.mv = this; - } - cw.lastMethod = this; - this.cw = cw; - this.access = access; - if ("".equals(name)) { - this.access |= ACC_CONSTRUCTOR; - } - this.name = cw.newUTF8(name); - this.desc = cw.newUTF8(desc); - this.descriptor = desc; - if (ClassReader.SIGNATURES) { - this.signature = signature; - } - if (exceptions != null && exceptions.length > 0) { - exceptionCount = exceptions.length; - this.exceptions = new int[exceptionCount]; - for (int i = 0; i < exceptionCount; ++i) { - this.exceptions[i] = cw.newClass(exceptions[i]); - } - } - this.compute = computeFrames ? FRAMES : (computeMaxs ? MAXS : NOTHING); - if (computeMaxs || computeFrames) { - // updates maxLocals - int size = Type.getArgumentsAndReturnSizes(descriptor) >> 2; - if ((access & Opcodes.ACC_STATIC) != 0) { - --size; - } - maxLocals = size; - currentLocals = size; - // creates and visits the label for the first basic block - labels = new Label(); - labels.status |= Label.PUSHED; - visitLabel(labels); - } - } - - // ------------------------------------------------------------------------ - // Implementation of the MethodVisitor abstract class - // ------------------------------------------------------------------------ - - @Override - public void visitParameter(String name, int access) { - if (methodParameters == null) { - methodParameters = new ByteVector(); - } - ++methodParametersCount; - methodParameters.putShort((name == null) ? 0 : cw.newUTF8(name)) - .putShort(access); - } - - @Override - public AnnotationVisitor visitAnnotationDefault() { - if (!ClassReader.ANNOTATIONS) { - return null; - } - annd = new ByteVector(); - return new AnnotationWriter(cw, false, annd, null, 0); - } - - @Override - public AnnotationVisitor visitAnnotation(final String desc, - final boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - // write type, and reserve space for values count - bv.putShort(cw.newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2); - if (visible) { - aw.next = anns; - anns = aw; - } else { - aw.next = ianns; - ianns = aw; - } - return aw; - } - - @Override - public AnnotationVisitor visitTypeAnnotation(final int typeRef, - final TypePath typePath, final String desc, final boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - // write target_type and target_info - AnnotationWriter.putTarget(typeRef, typePath, bv); - // write type, and reserve space for values count - bv.putShort(cw.newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, - bv.length - 2); - if (visible) { - aw.next = tanns; - tanns = aw; - } else { - aw.next = itanns; - itanns = aw; - } - return aw; - } - - @Override - public AnnotationVisitor visitParameterAnnotation(final int parameter, - final String desc, final boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - if ("Ljava/lang/Synthetic;".equals(desc)) { - // workaround for a bug in javac with synthetic parameters - // see ClassReader.readParameterAnnotations - synthetics = Math.max(synthetics, parameter + 1); - return new AnnotationWriter(cw, false, bv, null, 0); - } - // write type, and reserve space for values count - bv.putShort(cw.newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, 2); - if (visible) { - if (panns == null) { - panns = new AnnotationWriter[Type.getArgumentTypes(descriptor).length]; - } - aw.next = panns[parameter]; - panns[parameter] = aw; - } else { - if (ipanns == null) { - ipanns = new AnnotationWriter[Type.getArgumentTypes(descriptor).length]; - } - aw.next = ipanns[parameter]; - ipanns[parameter] = aw; - } - return aw; - } - - @Override - public void visitAttribute(final Attribute attr) { - if (attr.isCodeAttribute()) { - attr.next = cattrs; - cattrs = attr; - } else { - attr.next = attrs; - attrs = attr; - } - } - - @Override - public void visitCode() { - } - - @Override - public void visitFrame(final int type, final int nLocal, - final Object[] local, final int nStack, final Object[] stack) { - if (!ClassReader.FRAMES || compute == FRAMES) { - return; - } - - if (type == Opcodes.F_NEW) { - if (previousFrame == null) { - visitImplicitFirstFrame(); - } - currentLocals = nLocal; - int frameIndex = startFrame(code.length, nLocal, nStack); - for (int i = 0; i < nLocal; ++i) { - if (local[i] instanceof String) { - frame[frameIndex++] = Frame.OBJECT - | cw.addType((String) local[i]); - } else if (local[i] instanceof Integer) { - frame[frameIndex++] = ((Integer) local[i]).intValue(); - } else { - frame[frameIndex++] = Frame.UNINITIALIZED - | cw.addUninitializedType("", - ((Label) local[i]).position); - } - } - for (int i = 0; i < nStack; ++i) { - if (stack[i] instanceof String) { - frame[frameIndex++] = Frame.OBJECT - | cw.addType((String) stack[i]); - } else if (stack[i] instanceof Integer) { - frame[frameIndex++] = ((Integer) stack[i]).intValue(); - } else { - frame[frameIndex++] = Frame.UNINITIALIZED - | cw.addUninitializedType("", - ((Label) stack[i]).position); - } - } - endFrame(); - } else { - int delta; - if (stackMap == null) { - stackMap = new ByteVector(); - delta = code.length; - } else { - delta = code.length - previousFrameOffset - 1; - if (delta < 0) { - if (type == Opcodes.F_SAME) { - return; - } else { - throw new IllegalStateException(); - } - } - } - - switch (type) { - case Opcodes.F_FULL: - currentLocals = nLocal; - stackMap.putByte(FULL_FRAME).putShort(delta).putShort(nLocal); - for (int i = 0; i < nLocal; ++i) { - writeFrameType(local[i]); - } - stackMap.putShort(nStack); - for (int i = 0; i < nStack; ++i) { - writeFrameType(stack[i]); - } - break; - case Opcodes.F_APPEND: - currentLocals += nLocal; - stackMap.putByte(SAME_FRAME_EXTENDED + nLocal).putShort(delta); - for (int i = 0; i < nLocal; ++i) { - writeFrameType(local[i]); - } - break; - case Opcodes.F_CHOP: - currentLocals -= nLocal; - stackMap.putByte(SAME_FRAME_EXTENDED - nLocal).putShort(delta); - break; - case Opcodes.F_SAME: - if (delta < 64) { - stackMap.putByte(delta); - } else { - stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta); - } - break; - case Opcodes.F_SAME1: - if (delta < 64) { - stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta); - } else { - stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED) - .putShort(delta); - } - writeFrameType(stack[0]); - break; - } - - previousFrameOffset = code.length; - ++frameCount; - } - - maxStack = Math.max(maxStack, nStack); - maxLocals = Math.max(maxLocals, currentLocals); - } - - @Override - public void visitInsn(final int opcode) { - lastCodeOffset = code.length; - // adds the instruction to the bytecode of the method - code.putByte(opcode); - // update currentBlock - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(opcode, 0, null, null); - } else { - // updates current and max stack sizes - int size = stackSize + Frame.SIZE[opcode]; - if (size > maxStackSize) { - maxStackSize = size; - } - stackSize = size; - } - // if opcode == ATHROW or xRETURN, ends current block (no successor) - if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) - || opcode == Opcodes.ATHROW) { - noSuccessor(); - } - } - } - - @Override - public void visitIntInsn(final int opcode, final int operand) { - lastCodeOffset = code.length; - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(opcode, operand, null, null); - } else if (opcode != Opcodes.NEWARRAY) { - // updates current and max stack sizes only for NEWARRAY - // (stack size variation = 0 for BIPUSH or SIPUSH) - int size = stackSize + 1; - if (size > maxStackSize) { - maxStackSize = size; - } - stackSize = size; - } - } - // adds the instruction to the bytecode of the method - if (opcode == Opcodes.SIPUSH) { - code.put12(opcode, operand); - } else { // BIPUSH or NEWARRAY - code.put11(opcode, operand); - } - } - - @Override - public void visitVarInsn(final int opcode, final int var) { - lastCodeOffset = code.length; - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(opcode, var, null, null); - } else { - // updates current and max stack sizes - if (opcode == Opcodes.RET) { - // no stack change, but end of current block (no successor) - currentBlock.status |= Label.RET; - // save 'stackSize' here for future use - // (see {@link #findSubroutineSuccessors}) - currentBlock.inputStackTop = stackSize; - noSuccessor(); - } else { // xLOAD or xSTORE - int size = stackSize + Frame.SIZE[opcode]; - if (size > maxStackSize) { - maxStackSize = size; - } - stackSize = size; - } - } - } - if (compute != NOTHING) { - // updates max locals - int n; - if (opcode == Opcodes.LLOAD || opcode == Opcodes.DLOAD - || opcode == Opcodes.LSTORE || opcode == Opcodes.DSTORE) { - n = var + 2; - } else { - n = var + 1; - } - if (n > maxLocals) { - maxLocals = n; - } - } - // adds the instruction to the bytecode of the method - if (var < 4 && opcode != Opcodes.RET) { - int opt; - if (opcode < Opcodes.ISTORE) { - /* ILOAD_0 */ - opt = 26 + ((opcode - Opcodes.ILOAD) << 2) + var; - } else { - /* ISTORE_0 */ - opt = 59 + ((opcode - Opcodes.ISTORE) << 2) + var; - } - code.putByte(opt); - } else if (var >= 256) { - code.putByte(196 /* WIDE */).put12(opcode, var); - } else { - code.put11(opcode, var); - } - if (opcode >= Opcodes.ISTORE && compute == FRAMES && handlerCount > 0) { - visitLabel(new Label()); - } - } - - @Override - public void visitTypeInsn(final int opcode, final String type) { - lastCodeOffset = code.length; - Item i = cw.newClassItem(type); - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(opcode, code.length, cw, i); - } else if (opcode == Opcodes.NEW) { - // updates current and max stack sizes only if opcode == NEW - // (no stack change for ANEWARRAY, CHECKCAST, INSTANCEOF) - int size = stackSize + 1; - if (size > maxStackSize) { - maxStackSize = size; - } - stackSize = size; - } - } - // adds the instruction to the bytecode of the method - code.put12(opcode, i.index); - } - - @Override - public void visitFieldInsn(final int opcode, final String owner, - final String name, final String desc) { - lastCodeOffset = code.length; - Item i = cw.newFieldItem(owner, name, desc); - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(opcode, 0, cw, i); - } else { - int size; - // computes the stack size variation - char c = desc.charAt(0); - switch (opcode) { - case Opcodes.GETSTATIC: - size = stackSize + (c == 'D' || c == 'J' ? 2 : 1); - break; - case Opcodes.PUTSTATIC: - size = stackSize + (c == 'D' || c == 'J' ? -2 : -1); - break; - case Opcodes.GETFIELD: - size = stackSize + (c == 'D' || c == 'J' ? 1 : 0); - break; - // case Constants.PUTFIELD: - default: - size = stackSize + (c == 'D' || c == 'J' ? -3 : -2); - break; - } - // updates current and max stack sizes - if (size > maxStackSize) { - maxStackSize = size; - } - stackSize = size; - } - } - // adds the instruction to the bytecode of the method - code.put12(opcode, i.index); - } - - @Override - public void visitMethodInsn(final int opcode, final String owner, - final String name, final String desc, final boolean itf) { - lastCodeOffset = code.length; - Item i = cw.newMethodItem(owner, name, desc, itf); - int argSize = i.intVal; - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(opcode, 0, cw, i); - } else { - /* - * computes the stack size variation. In order not to recompute - * several times this variation for the same Item, we use the - * intVal field of this item to store this variation, once it - * has been computed. More precisely this intVal field stores - * the sizes of the arguments and of the return value - * corresponding to desc. - */ - if (argSize == 0) { - // the above sizes have not been computed yet, - // so we compute them... - argSize = Type.getArgumentsAndReturnSizes(desc); - // ... and we save them in order - // not to recompute them in the future - i.intVal = argSize; - } - int size; - if (opcode == Opcodes.INVOKESTATIC) { - size = stackSize - (argSize >> 2) + (argSize & 0x03) + 1; - } else { - size = stackSize - (argSize >> 2) + (argSize & 0x03); - } - // updates current and max stack sizes - if (size > maxStackSize) { - maxStackSize = size; - } - stackSize = size; - } - } - // adds the instruction to the bytecode of the method - if (opcode == Opcodes.INVOKEINTERFACE) { - if (argSize == 0) { - argSize = Type.getArgumentsAndReturnSizes(desc); - i.intVal = argSize; - } - code.put12(Opcodes.INVOKEINTERFACE, i.index).put11(argSize >> 2, 0); - } else { - code.put12(opcode, i.index); - } - } - - @Override - public void visitInvokeDynamicInsn(final String name, final String desc, - final Handle bsm, final Object... bsmArgs) { - lastCodeOffset = code.length; - Item i = cw.newInvokeDynamicItem(name, desc, bsm, bsmArgs); - int argSize = i.intVal; - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(Opcodes.INVOKEDYNAMIC, 0, cw, i); - } else { - /* - * computes the stack size variation. In order not to recompute - * several times this variation for the same Item, we use the - * intVal field of this item to store this variation, once it - * has been computed. More precisely this intVal field stores - * the sizes of the arguments and of the return value - * corresponding to desc. - */ - if (argSize == 0) { - // the above sizes have not been computed yet, - // so we compute them... - argSize = Type.getArgumentsAndReturnSizes(desc); - // ... and we save them in order - // not to recompute them in the future - i.intVal = argSize; - } - int size = stackSize - (argSize >> 2) + (argSize & 0x03) + 1; - - // updates current and max stack sizes - if (size > maxStackSize) { - maxStackSize = size; - } - stackSize = size; - } - } - // adds the instruction to the bytecode of the method - code.put12(Opcodes.INVOKEDYNAMIC, i.index); - code.putShort(0); - } - - @Override - public void visitJumpInsn(final int opcode, final Label label) { - lastCodeOffset = code.length; - Label nextInsn = null; - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(opcode, 0, null, null); - // 'label' is the target of a jump instruction - label.getFirst().status |= Label.TARGET; - // adds 'label' as a successor of this basic block - addSuccessor(Edge.NORMAL, label); - if (opcode != Opcodes.GOTO) { - // creates a Label for the next basic block - nextInsn = new Label(); - } - } else { - if (opcode == Opcodes.JSR) { - if ((label.status & Label.SUBROUTINE) == 0) { - label.status |= Label.SUBROUTINE; - ++subroutines; - } - currentBlock.status |= Label.JSR; - addSuccessor(stackSize + 1, label); - // creates a Label for the next basic block - nextInsn = new Label(); - /* - * note that, by construction in this method, a JSR block - * has at least two successors in the control flow graph: - * the first one leads the next instruction after the JSR, - * while the second one leads to the JSR target. - */ - } else { - // updates current stack size (max stack size unchanged - // because stack size variation always negative in this - // case) - stackSize += Frame.SIZE[opcode]; - addSuccessor(stackSize, label); - } - } - } - // adds the instruction to the bytecode of the method - if ((label.status & Label.RESOLVED) != 0 - && label.position - code.length < Short.MIN_VALUE) { - /* - * case of a backward jump with an offset < -32768. In this case we - * automatically replace GOTO with GOTO_W, JSR with JSR_W and IFxxx - * with IFNOTxxx GOTO_W , where IFNOTxxx is the - * "opposite" opcode of IFxxx (i.e., IFNE for IFEQ) and where - * designates the instruction just after the GOTO_W. - */ - if (opcode == Opcodes.GOTO) { - code.putByte(200); // GOTO_W - } else if (opcode == Opcodes.JSR) { - code.putByte(201); // JSR_W - } else { - // if the IF instruction is transformed into IFNOT GOTO_W the - // next instruction becomes the target of the IFNOT instruction - if (nextInsn != null) { - nextInsn.status |= Label.TARGET; - } - code.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1 - : opcode ^ 1); - code.putShort(8); // jump offset - code.putByte(200); // GOTO_W - } - label.put(this, code, code.length - 1, true); - } else { - /* - * case of a backward jump with an offset >= -32768, or of a forward - * jump with, of course, an unknown offset. In these cases we store - * the offset in 2 bytes (which will be increased in - * resizeInstructions, if needed). - */ - code.putByte(opcode); - label.put(this, code, code.length - 1, false); - } - if (currentBlock != null) { - if (nextInsn != null) { - // if the jump instruction is not a GOTO, the next instruction - // is also a successor of this instruction. Calling visitLabel - // adds the label of this next instruction as a successor of the - // current block, and starts a new basic block - visitLabel(nextInsn); - } - if (opcode == Opcodes.GOTO) { - noSuccessor(); - } - } - } - - @Override - public void visitLabel(final Label label) { - // resolves previous forward references to label, if any - resize |= label.resolve(this, code.length, code.data); - // updates currentBlock - if ((label.status & Label.DEBUG) != 0) { - return; - } - if (compute == FRAMES) { - if (currentBlock != null) { - if (label.position == currentBlock.position) { - // successive labels, do not start a new basic block - currentBlock.status |= (label.status & Label.TARGET); - label.frame = currentBlock.frame; - return; - } - // ends current block (with one new successor) - addSuccessor(Edge.NORMAL, label); - } - // begins a new current block - currentBlock = label; - if (label.frame == null) { - label.frame = new Frame(); - label.frame.owner = label; - } - // updates the basic block list - if (previousBlock != null) { - if (label.position == previousBlock.position) { - previousBlock.status |= (label.status & Label.TARGET); - label.frame = previousBlock.frame; - currentBlock = previousBlock; - return; - } - previousBlock.successor = label; - } - previousBlock = label; - } else if (compute == MAXS) { - if (currentBlock != null) { - // ends current block (with one new successor) - currentBlock.outputStackMax = maxStackSize; - addSuccessor(stackSize, label); - } - // begins a new current block - currentBlock = label; - // resets the relative current and max stack sizes - stackSize = 0; - maxStackSize = 0; - // updates the basic block list - if (previousBlock != null) { - previousBlock.successor = label; - } - previousBlock = label; - } - } - - @Override - public void visitLdcInsn(final Object cst) { - lastCodeOffset = code.length; - Item i = cw.newConstItem(cst); - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(Opcodes.LDC, 0, cw, i); - } else { - int size; - // computes the stack size variation - if (i.type == ClassWriter.LONG || i.type == ClassWriter.DOUBLE) { - size = stackSize + 2; - } else { - size = stackSize + 1; - } - // updates current and max stack sizes - if (size > maxStackSize) { - maxStackSize = size; - } - stackSize = size; - } - } - // adds the instruction to the bytecode of the method - int index = i.index; - if (i.type == ClassWriter.LONG || i.type == ClassWriter.DOUBLE) { - code.put12(20 /* LDC2_W */, index); - } else if (index >= 256) { - code.put12(19 /* LDC_W */, index); - } else { - code.put11(Opcodes.LDC, index); - } - } - - @Override - public void visitIincInsn(final int var, final int increment) { - lastCodeOffset = code.length; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(Opcodes.IINC, var, null, null); - } - } - if (compute != NOTHING) { - // updates max locals - int n = var + 1; - if (n > maxLocals) { - maxLocals = n; - } - } - // adds the instruction to the bytecode of the method - if ((var > 255) || (increment > 127) || (increment < -128)) { - code.putByte(196 /* WIDE */).put12(Opcodes.IINC, var) - .putShort(increment); - } else { - code.putByte(Opcodes.IINC).put11(var, increment); - } - } - - @Override - public void visitTableSwitchInsn(final int min, final int max, - final Label dflt, final Label... labels) { - lastCodeOffset = code.length; - // adds the instruction to the bytecode of the method - int source = code.length; - code.putByte(Opcodes.TABLESWITCH); - code.putByteArray(null, 0, (4 - code.length % 4) % 4); - dflt.put(this, code, source, true); - code.putInt(min).putInt(max); - for (int i = 0; i < labels.length; ++i) { - labels[i].put(this, code, source, true); - } - // updates currentBlock - visitSwitchInsn(dflt, labels); - } - - @Override - public void visitLookupSwitchInsn(final Label dflt, final int[] keys, - final Label[] labels) { - lastCodeOffset = code.length; - // adds the instruction to the bytecode of the method - int source = code.length; - code.putByte(Opcodes.LOOKUPSWITCH); - code.putByteArray(null, 0, (4 - code.length % 4) % 4); - dflt.put(this, code, source, true); - code.putInt(labels.length); - for (int i = 0; i < labels.length; ++i) { - code.putInt(keys[i]); - labels[i].put(this, code, source, true); - } - // updates currentBlock - visitSwitchInsn(dflt, labels); - } - - private void visitSwitchInsn(final Label dflt, final Label[] labels) { - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(Opcodes.LOOKUPSWITCH, 0, null, null); - // adds current block successors - addSuccessor(Edge.NORMAL, dflt); - dflt.getFirst().status |= Label.TARGET; - for (int i = 0; i < labels.length; ++i) { - addSuccessor(Edge.NORMAL, labels[i]); - labels[i].getFirst().status |= Label.TARGET; - } - } else { - // updates current stack size (max stack size unchanged) - --stackSize; - // adds current block successors - addSuccessor(stackSize, dflt); - for (int i = 0; i < labels.length; ++i) { - addSuccessor(stackSize, labels[i]); - } - } - // ends current block - noSuccessor(); - } - } - - @Override - public void visitMultiANewArrayInsn(final String desc, final int dims) { - lastCodeOffset = code.length; - Item i = cw.newClassItem(desc); - // Label currentBlock = this.currentBlock; - if (currentBlock != null) { - if (compute == FRAMES) { - currentBlock.frame.execute(Opcodes.MULTIANEWARRAY, dims, cw, i); - } else { - // updates current stack size (max stack size unchanged because - // stack size variation always negative or null) - stackSize += 1 - dims; - } - } - // adds the instruction to the bytecode of the method - code.put12(Opcodes.MULTIANEWARRAY, i.index).putByte(dims); - } - - @Override - public AnnotationVisitor visitInsnAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - // write target_type and target_info - typeRef = (typeRef & 0xFF0000FF) | (lastCodeOffset << 8); - AnnotationWriter.putTarget(typeRef, typePath, bv); - // write type, and reserve space for values count - bv.putShort(cw.newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, - bv.length - 2); - if (visible) { - aw.next = ctanns; - ctanns = aw; - } else { - aw.next = ictanns; - ictanns = aw; - } - return aw; - } - - @Override - public void visitTryCatchBlock(final Label start, final Label end, - final Label handler, final String type) { - ++handlerCount; - Handler h = new Handler(); - h.start = start; - h.end = end; - h.handler = handler; - h.desc = type; - h.type = type != null ? cw.newClass(type) : 0; - if (lastHandler == null) { - firstHandler = h; - } else { - lastHandler.next = h; - } - lastHandler = h; - } - - @Override - public AnnotationVisitor visitTryCatchAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - // write target_type and target_info - AnnotationWriter.putTarget(typeRef, typePath, bv); - // write type, and reserve space for values count - bv.putShort(cw.newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, - bv.length - 2); - if (visible) { - aw.next = ctanns; - ctanns = aw; - } else { - aw.next = ictanns; - ictanns = aw; - } - return aw; - } - - @Override - public void visitLocalVariable(final String name, final String desc, - final String signature, final Label start, final Label end, - final int index) { - if (signature != null) { - if (localVarType == null) { - localVarType = new ByteVector(); - } - ++localVarTypeCount; - localVarType.putShort(start.position) - .putShort(end.position - start.position) - .putShort(cw.newUTF8(name)).putShort(cw.newUTF8(signature)) - .putShort(index); - } - if (localVar == null) { - localVar = new ByteVector(); - } - ++localVarCount; - localVar.putShort(start.position) - .putShort(end.position - start.position) - .putShort(cw.newUTF8(name)).putShort(cw.newUTF8(desc)) - .putShort(index); - if (compute != NOTHING) { - // updates max locals - char c = desc.charAt(0); - int n = index + (c == 'J' || c == 'D' ? 2 : 1); - if (n > maxLocals) { - maxLocals = n; - } - } - } - - @Override - public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, - TypePath typePath, Label[] start, Label[] end, int[] index, - String desc, boolean visible) { - if (!ClassReader.ANNOTATIONS) { - return null; - } - ByteVector bv = new ByteVector(); - // write target_type and target_info - bv.putByte(typeRef >>> 24).putShort(start.length); - for (int i = 0; i < start.length; ++i) { - bv.putShort(start[i].position) - .putShort(end[i].position - start[i].position) - .putShort(index[i]); - } - if (typePath == null) { - bv.putByte(0); - } else { - int length = typePath.b[typePath.offset] * 2 + 1; - bv.putByteArray(typePath.b, typePath.offset, length); - } - // write type, and reserve space for values count - bv.putShort(cw.newUTF8(desc)).putShort(0); - AnnotationWriter aw = new AnnotationWriter(cw, true, bv, bv, - bv.length - 2); - if (visible) { - aw.next = ctanns; - ctanns = aw; - } else { - aw.next = ictanns; - ictanns = aw; - } - return aw; - } - - @Override - public void visitLineNumber(final int line, final Label start) { - if (lineNumber == null) { - lineNumber = new ByteVector(); - } - ++lineNumberCount; - lineNumber.putShort(start.position); - lineNumber.putShort(line); - } - - @Override - public void visitMaxs(final int maxStack, final int maxLocals) { - if (resize) { - // replaces the temporary jump opcodes introduced by Label.resolve. - if (ClassReader.RESIZE) { - resizeInstructions(); - } else { - throw new RuntimeException("Method code too large!"); - } - } - if (ClassReader.FRAMES && compute == FRAMES) { - // completes the control flow graph with exception handler blocks - Handler handler = firstHandler; - while (handler != null) { - Label l = handler.start.getFirst(); - Label h = handler.handler.getFirst(); - Label e = handler.end.getFirst(); - // computes the kind of the edges to 'h' - String t = handler.desc == null ? "java/lang/Throwable" - : handler.desc; - int kind = Frame.OBJECT | cw.addType(t); - // h is an exception handler - h.status |= Label.TARGET; - // adds 'h' as a successor of labels between 'start' and 'end' - while (l != e) { - // creates an edge to 'h' - Edge b = new Edge(); - b.info = kind; - b.successor = h; - // adds it to the successors of 'l' - b.next = l.successors; - l.successors = b; - // goes to the next label - l = l.successor; - } - handler = handler.next; - } - - // creates and visits the first (implicit) frame - Frame f = labels.frame; - Type[] args = Type.getArgumentTypes(descriptor); - f.initInputFrame(cw, access, args, this.maxLocals); - visitFrame(f); - - /* - * fix point algorithm: mark the first basic block as 'changed' - * (i.e. put it in the 'changed' list) and, while there are changed - * basic blocks, choose one, mark it as unchanged, and update its - * successors (which can be changed in the process). - */ - int max = 0; - Label changed = labels; - while (changed != null) { - // removes a basic block from the list of changed basic blocks - Label l = changed; - changed = changed.next; - l.next = null; - f = l.frame; - // a reachable jump target must be stored in the stack map - if ((l.status & Label.TARGET) != 0) { - l.status |= Label.STORE; - } - // all visited labels are reachable, by definition - l.status |= Label.REACHABLE; - // updates the (absolute) maximum stack size - int blockMax = f.inputStack.length + l.outputStackMax; - if (blockMax > max) { - max = blockMax; - } - // updates the successors of the current basic block - Edge e = l.successors; - while (e != null) { - Label n = e.successor.getFirst(); - boolean change = f.merge(cw, n.frame, e.info); - if (change && n.next == null) { - // if n has changed and is not already in the 'changed' - // list, adds it to this list - n.next = changed; - changed = n; - } - e = e.next; - } - } - - // visits all the frames that must be stored in the stack map - Label l = labels; - while (l != null) { - f = l.frame; - if ((l.status & Label.STORE) != 0) { - visitFrame(f); - } - if ((l.status & Label.REACHABLE) == 0) { - // finds start and end of dead basic block - Label k = l.successor; - int start = l.position; - int end = (k == null ? code.length : k.position) - 1; - // if non empty basic block - if (end >= start) { - max = Math.max(max, 1); - // replaces instructions with NOP ... NOP ATHROW - for (int i = start; i < end; ++i) { - code.data[i] = Opcodes.NOP; - } - code.data[end] = (byte) Opcodes.ATHROW; - // emits a frame for this unreachable block - int frameIndex = startFrame(start, 0, 1); - frame[frameIndex] = Frame.OBJECT - | cw.addType("java/lang/Throwable"); - endFrame(); - // removes the start-end range from the exception - // handlers - firstHandler = Handler.remove(firstHandler, l, k); - } - } - l = l.successor; - } - - handler = firstHandler; - handlerCount = 0; - while (handler != null) { - handlerCount += 1; - handler = handler.next; - } - - this.maxStack = max; - } else if (compute == MAXS) { - // completes the control flow graph with exception handler blocks - Handler handler = firstHandler; - while (handler != null) { - Label l = handler.start; - Label h = handler.handler; - Label e = handler.end; - // adds 'h' as a successor of labels between 'start' and 'end' - while (l != e) { - // creates an edge to 'h' - Edge b = new Edge(); - b.info = Edge.EXCEPTION; - b.successor = h; - // adds it to the successors of 'l' - if ((l.status & Label.JSR) == 0) { - b.next = l.successors; - l.successors = b; - } else { - // if l is a JSR block, adds b after the first two edges - // to preserve the hypothesis about JSR block successors - // order (see {@link #visitJumpInsn}) - b.next = l.successors.next.next; - l.successors.next.next = b; - } - // goes to the next label - l = l.successor; - } - handler = handler.next; - } - - if (subroutines > 0) { - // completes the control flow graph with the RET successors - /* - * first step: finds the subroutines. This step determines, for - * each basic block, to which subroutine(s) it belongs. - */ - // finds the basic blocks that belong to the "main" subroutine - int id = 0; - labels.visitSubroutine(null, 1, subroutines); - // finds the basic blocks that belong to the real subroutines - Label l = labels; - while (l != null) { - if ((l.status & Label.JSR) != 0) { - // the subroutine is defined by l's TARGET, not by l - Label subroutine = l.successors.next.successor; - // if this subroutine has not been visited yet... - if ((subroutine.status & Label.VISITED) == 0) { - // ...assigns it a new id and finds its basic blocks - id += 1; - subroutine.visitSubroutine(null, (id / 32L) << 32 - | (1L << (id % 32)), subroutines); - } - } - l = l.successor; - } - // second step: finds the successors of RET blocks - l = labels; - while (l != null) { - if ((l.status & Label.JSR) != 0) { - Label L = labels; - while (L != null) { - L.status &= ~Label.VISITED2; - L = L.successor; - } - // the subroutine is defined by l's TARGET, not by l - Label subroutine = l.successors.next.successor; - subroutine.visitSubroutine(l, 0, subroutines); - } - l = l.successor; - } - } - - /* - * control flow analysis algorithm: while the block stack is not - * empty, pop a block from this stack, update the max stack size, - * compute the true (non relative) begin stack size of the - * successors of this block, and push these successors onto the - * stack (unless they have already been pushed onto the stack). - * Note: by hypothesis, the {@link Label#inputStackTop} of the - * blocks in the block stack are the true (non relative) beginning - * stack sizes of these blocks. - */ - int max = 0; - Label stack = labels; - while (stack != null) { - // pops a block from the stack - Label l = stack; - stack = stack.next; - // computes the true (non relative) max stack size of this block - int start = l.inputStackTop; - int blockMax = start + l.outputStackMax; - // updates the global max stack size - if (blockMax > max) { - max = blockMax; - } - // analyzes the successors of the block - Edge b = l.successors; - if ((l.status & Label.JSR) != 0) { - // ignores the first edge of JSR blocks (virtual successor) - b = b.next; - } - while (b != null) { - l = b.successor; - // if this successor has not already been pushed... - if ((l.status & Label.PUSHED) == 0) { - // computes its true beginning stack size... - l.inputStackTop = b.info == Edge.EXCEPTION ? 1 : start - + b.info; - // ...and pushes it onto the stack - l.status |= Label.PUSHED; - l.next = stack; - stack = l; - } - b = b.next; - } - } - this.maxStack = Math.max(maxStack, max); - } else { - this.maxStack = maxStack; - this.maxLocals = maxLocals; - } - } - - @Override - public void visitEnd() { - } - - // ------------------------------------------------------------------------ - // Utility methods: control flow analysis algorithm - // ------------------------------------------------------------------------ - - /** - * Adds a successor to the {@link #currentBlock currentBlock} block. - * - * @param info - * information about the control flow edge to be added. - * @param successor - * the successor block to be added to the current block. - */ - private void addSuccessor(final int info, final Label successor) { - // creates and initializes an Edge object... - Edge b = new Edge(); - b.info = info; - b.successor = successor; - // ...and adds it to the successor list of the currentBlock block - b.next = currentBlock.successors; - currentBlock.successors = b; - } - - /** - * Ends the current basic block. This method must be used in the case where - * the current basic block does not have any successor. - */ - private void noSuccessor() { - if (compute == FRAMES) { - Label l = new Label(); - l.frame = new Frame(); - l.frame.owner = l; - l.resolve(this, code.length, code.data); - previousBlock.successor = l; - previousBlock = l; - } else { - currentBlock.outputStackMax = maxStackSize; - } - currentBlock = null; - } - - // ------------------------------------------------------------------------ - // Utility methods: stack map frames - // ------------------------------------------------------------------------ - - /** - * Visits a frame that has been computed from scratch. - * - * @param f - * the frame that must be visited. - */ - private void visitFrame(final Frame f) { - int i, t; - int nTop = 0; - int nLocal = 0; - int nStack = 0; - int[] locals = f.inputLocals; - int[] stacks = f.inputStack; - // computes the number of locals (ignores TOP types that are just after - // a LONG or a DOUBLE, and all trailing TOP types) - for (i = 0; i < locals.length; ++i) { - t = locals[i]; - if (t == Frame.TOP) { - ++nTop; - } else { - nLocal += nTop + 1; - nTop = 0; - } - if (t == Frame.LONG || t == Frame.DOUBLE) { - ++i; - } - } - // computes the stack size (ignores TOP types that are just after - // a LONG or a DOUBLE) - for (i = 0; i < stacks.length; ++i) { - t = stacks[i]; - ++nStack; - if (t == Frame.LONG || t == Frame.DOUBLE) { - ++i; - } - } - // visits the frame and its content - int frameIndex = startFrame(f.owner.position, nLocal, nStack); - for (i = 0; nLocal > 0; ++i, --nLocal) { - t = locals[i]; - frame[frameIndex++] = t; - if (t == Frame.LONG || t == Frame.DOUBLE) { - ++i; - } - } - for (i = 0; i < stacks.length; ++i) { - t = stacks[i]; - frame[frameIndex++] = t; - if (t == Frame.LONG || t == Frame.DOUBLE) { - ++i; - } - } - endFrame(); - } - - /** - * Visit the implicit first frame of this method. - */ - private void visitImplicitFirstFrame() { - // There can be at most descriptor.length() + 1 locals - int frameIndex = startFrame(0, descriptor.length() + 1, 0); - if ((access & Opcodes.ACC_STATIC) == 0) { - if ((access & ACC_CONSTRUCTOR) == 0) { - frame[frameIndex++] = Frame.OBJECT | cw.addType(cw.thisName); - } else { - frame[frameIndex++] = 6; // Opcodes.UNINITIALIZED_THIS; - } - } - int i = 1; - loop: while (true) { - int j = i; - switch (descriptor.charAt(i++)) { - case 'Z': - case 'C': - case 'B': - case 'S': - case 'I': - frame[frameIndex++] = 1; // Opcodes.INTEGER; - break; - case 'F': - frame[frameIndex++] = 2; // Opcodes.FLOAT; - break; - case 'J': - frame[frameIndex++] = 4; // Opcodes.LONG; - break; - case 'D': - frame[frameIndex++] = 3; // Opcodes.DOUBLE; - break; - case '[': - while (descriptor.charAt(i) == '[') { - ++i; - } - if (descriptor.charAt(i) == 'L') { - ++i; - while (descriptor.charAt(i) != ';') { - ++i; - } - } - frame[frameIndex++] = Frame.OBJECT - | cw.addType(descriptor.substring(j, ++i)); - break; - case 'L': - while (descriptor.charAt(i) != ';') { - ++i; - } - frame[frameIndex++] = Frame.OBJECT - | cw.addType(descriptor.substring(j + 1, i++)); - break; - default: - break loop; - } - } - frame[1] = frameIndex - 3; - endFrame(); - } - - /** - * Starts the visit of a stack map frame. - * - * @param offset - * the offset of the instruction to which the frame corresponds. - * @param nLocal - * the number of local variables in the frame. - * @param nStack - * the number of stack elements in the frame. - * @return the index of the next element to be written in this frame. - */ - private int startFrame(final int offset, final int nLocal, final int nStack) { - int n = 3 + nLocal + nStack; - if (frame == null || frame.length < n) { - frame = new int[n]; - } - frame[0] = offset; - frame[1] = nLocal; - frame[2] = nStack; - return 3; - } - - /** - * Checks if the visit of the current frame {@link #frame} is finished, and - * if yes, write it in the StackMapTable attribute. - */ - private void endFrame() { - if (previousFrame != null) { // do not write the first frame - if (stackMap == null) { - stackMap = new ByteVector(); - } - writeFrame(); - ++frameCount; - } - previousFrame = frame; - frame = null; - } - - /** - * Compress and writes the current frame {@link #frame} in the StackMapTable - * attribute. - */ - private void writeFrame() { - int clocalsSize = frame[1]; - int cstackSize = frame[2]; - if ((cw.version & 0xFFFF) < Opcodes.V1_6) { - stackMap.putShort(frame[0]).putShort(clocalsSize); - writeFrameTypes(3, 3 + clocalsSize); - stackMap.putShort(cstackSize); - writeFrameTypes(3 + clocalsSize, 3 + clocalsSize + cstackSize); - return; - } - int localsSize = previousFrame[1]; - int type = FULL_FRAME; - int k = 0; - int delta; - if (frameCount == 0) { - delta = frame[0]; - } else { - delta = frame[0] - previousFrame[0] - 1; - } - if (cstackSize == 0) { - k = clocalsSize - localsSize; - switch (k) { - case -3: - case -2: - case -1: - type = CHOP_FRAME; - localsSize = clocalsSize; - break; - case 0: - type = delta < 64 ? SAME_FRAME : SAME_FRAME_EXTENDED; - break; - case 1: - case 2: - case 3: - type = APPEND_FRAME; - break; - } - } else if (clocalsSize == localsSize && cstackSize == 1) { - type = delta < 63 ? SAME_LOCALS_1_STACK_ITEM_FRAME - : SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED; - } - if (type != FULL_FRAME) { - // verify if locals are the same - int l = 3; - for (int j = 0; j < localsSize; j++) { - if (frame[l] != previousFrame[l]) { - type = FULL_FRAME; - break; - } - l++; - } - } - switch (type) { - case SAME_FRAME: - stackMap.putByte(delta); - break; - case SAME_LOCALS_1_STACK_ITEM_FRAME: - stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME + delta); - writeFrameTypes(3 + clocalsSize, 4 + clocalsSize); - break; - case SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED: - stackMap.putByte(SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED).putShort( - delta); - writeFrameTypes(3 + clocalsSize, 4 + clocalsSize); - break; - case SAME_FRAME_EXTENDED: - stackMap.putByte(SAME_FRAME_EXTENDED).putShort(delta); - break; - case CHOP_FRAME: - stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta); - break; - case APPEND_FRAME: - stackMap.putByte(SAME_FRAME_EXTENDED + k).putShort(delta); - writeFrameTypes(3 + localsSize, 3 + clocalsSize); - break; - // case FULL_FRAME: - default: - stackMap.putByte(FULL_FRAME).putShort(delta).putShort(clocalsSize); - writeFrameTypes(3, 3 + clocalsSize); - stackMap.putShort(cstackSize); - writeFrameTypes(3 + clocalsSize, 3 + clocalsSize + cstackSize); - } - } - - /** - * Writes some types of the current frame {@link #frame} into the - * StackMapTableAttribute. This method converts types from the format used - * in {@link Label} to the format used in StackMapTable attributes. In - * particular, it converts type table indexes to constant pool indexes. - * - * @param start - * index of the first type in {@link #frame} to write. - * @param end - * index of last type in {@link #frame} to write (exclusive). - */ - private void writeFrameTypes(final int start, final int end) { - for (int i = start; i < end; ++i) { - int t = frame[i]; - int d = t & Frame.DIM; - if (d == 0) { - int v = t & Frame.BASE_VALUE; - switch (t & Frame.BASE_KIND) { - case Frame.OBJECT: - stackMap.putByte(7).putShort( - cw.newClass(cw.typeTable[v].strVal1)); - break; - case Frame.UNINITIALIZED: - stackMap.putByte(8).putShort(cw.typeTable[v].intVal); - break; - default: - stackMap.putByte(v); - } - } else { - StringBuilder sb = new StringBuilder(); - d >>= 28; - while (d-- > 0) { - sb.append('['); - } - if ((t & Frame.BASE_KIND) == Frame.OBJECT) { - sb.append('L'); - sb.append(cw.typeTable[t & Frame.BASE_VALUE].strVal1); - sb.append(';'); - } else { - switch (t & 0xF) { - case 1: - sb.append('I'); - break; - case 2: - sb.append('F'); - break; - case 3: - sb.append('D'); - break; - case 9: - sb.append('Z'); - break; - case 10: - sb.append('B'); - break; - case 11: - sb.append('C'); - break; - case 12: - sb.append('S'); - break; - default: - sb.append('J'); - } - } - stackMap.putByte(7).putShort(cw.newClass(sb.toString())); - } - } - } - - private void writeFrameType(final Object type) { - if (type instanceof String) { - stackMap.putByte(7).putShort(cw.newClass((String) type)); - } else if (type instanceof Integer) { - stackMap.putByte(((Integer) type).intValue()); - } else { - stackMap.putByte(8).putShort(((Label) type).position); - } - } - - // ------------------------------------------------------------------------ - // Utility methods: dump bytecode array - // ------------------------------------------------------------------------ - - /** - * Returns the size of the bytecode of this method. - * - * @return the size of the bytecode of this method. - */ - final int getSize() { - if (classReaderOffset != 0) { - return 6 + classReaderLength; - } - int size = 8; - if (code.length > 0) { - if (code.length > 65536) { - String nameString = ""; - Item nameItem = cw.findItemByIndex(name); - if (nameItem != null) nameString = nameItem.strVal1 +"'s "; - throw new RuntimeException("Method "+ nameString +"code too large!"); - } - cw.newUTF8("Code"); - size += 18 + code.length + 8 * handlerCount; - if (localVar != null) { - cw.newUTF8("LocalVariableTable"); - size += 8 + localVar.length; - } - if (localVarType != null) { - cw.newUTF8("LocalVariableTypeTable"); - size += 8 + localVarType.length; - } - if (lineNumber != null) { - cw.newUTF8("LineNumberTable"); - size += 8 + lineNumber.length; - } - if (stackMap != null) { - boolean zip = (cw.version & 0xFFFF) >= Opcodes.V1_6; - cw.newUTF8(zip ? "StackMapTable" : "StackMap"); - size += 8 + stackMap.length; - } - if (ClassReader.ANNOTATIONS && ctanns != null) { - cw.newUTF8("RuntimeVisibleTypeAnnotations"); - size += 8 + ctanns.getSize(); - } - if (ClassReader.ANNOTATIONS && ictanns != null) { - cw.newUTF8("RuntimeInvisibleTypeAnnotations"); - size += 8 + ictanns.getSize(); - } - if (cattrs != null) { - size += cattrs.getSize(cw, code.data, code.length, maxStack, - maxLocals); - } - } - if (exceptionCount > 0) { - cw.newUTF8("Exceptions"); - size += 8 + 2 * exceptionCount; - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0) { - if ((cw.version & 0xFFFF) < Opcodes.V1_5 - || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { - cw.newUTF8("Synthetic"); - size += 6; - } - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - cw.newUTF8("Deprecated"); - size += 6; - } - if (ClassReader.SIGNATURES && signature != null) { - cw.newUTF8("Signature"); - cw.newUTF8(signature); - size += 8; - } - if (methodParameters != null) { - cw.newUTF8("MethodParameters"); - size += 7 + methodParameters.length; - } - if (ClassReader.ANNOTATIONS && annd != null) { - cw.newUTF8("AnnotationDefault"); - size += 6 + annd.length; - } - if (ClassReader.ANNOTATIONS && anns != null) { - cw.newUTF8("RuntimeVisibleAnnotations"); - size += 8 + anns.getSize(); - } - if (ClassReader.ANNOTATIONS && ianns != null) { - cw.newUTF8("RuntimeInvisibleAnnotations"); - size += 8 + ianns.getSize(); - } - if (ClassReader.ANNOTATIONS && tanns != null) { - cw.newUTF8("RuntimeVisibleTypeAnnotations"); - size += 8 + tanns.getSize(); - } - if (ClassReader.ANNOTATIONS && itanns != null) { - cw.newUTF8("RuntimeInvisibleTypeAnnotations"); - size += 8 + itanns.getSize(); - } - if (ClassReader.ANNOTATIONS && panns != null) { - cw.newUTF8("RuntimeVisibleParameterAnnotations"); - size += 7 + 2 * (panns.length - synthetics); - for (int i = panns.length - 1; i >= synthetics; --i) { - size += panns[i] == null ? 0 : panns[i].getSize(); - } - } - if (ClassReader.ANNOTATIONS && ipanns != null) { - cw.newUTF8("RuntimeInvisibleParameterAnnotations"); - size += 7 + 2 * (ipanns.length - synthetics); - for (int i = ipanns.length - 1; i >= synthetics; --i) { - size += ipanns[i] == null ? 0 : ipanns[i].getSize(); - } - } - if (attrs != null) { - size += attrs.getSize(cw, null, 0, -1, -1); - } - return size; - } - - /** - * Puts the bytecode of this method in the given byte vector. - * - * @param out - * the byte vector into which the bytecode of this method must be - * copied. - */ - final void put(final ByteVector out) { - final int FACTOR = ClassWriter.TO_ACC_SYNTHETIC; - int mask = ACC_CONSTRUCTOR | Opcodes.ACC_DEPRECATED - | ClassWriter.ACC_SYNTHETIC_ATTRIBUTE - | ((access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) / FACTOR); - out.putShort(access & ~mask).putShort(name).putShort(desc); - if (classReaderOffset != 0) { - out.putByteArray(cw.cr.b, classReaderOffset, classReaderLength); - return; - } - int attributeCount = 0; - if (code.length > 0) { - ++attributeCount; - } - if (exceptionCount > 0) { - ++attributeCount; - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0) { - if ((cw.version & 0xFFFF) < Opcodes.V1_5 - || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { - ++attributeCount; - } - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - ++attributeCount; - } - if (ClassReader.SIGNATURES && signature != null) { - ++attributeCount; - } - if (methodParameters != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && annd != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && anns != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && ianns != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && tanns != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && itanns != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && panns != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && ipanns != null) { - ++attributeCount; - } - if (attrs != null) { - attributeCount += attrs.getCount(); - } - out.putShort(attributeCount); - if (code.length > 0) { - int size = 12 + code.length + 8 * handlerCount; - if (localVar != null) { - size += 8 + localVar.length; - } - if (localVarType != null) { - size += 8 + localVarType.length; - } - if (lineNumber != null) { - size += 8 + lineNumber.length; - } - if (stackMap != null) { - size += 8 + stackMap.length; - } - if (ClassReader.ANNOTATIONS && ctanns != null) { - size += 8 + ctanns.getSize(); - } - if (ClassReader.ANNOTATIONS && ictanns != null) { - size += 8 + ictanns.getSize(); - } - if (cattrs != null) { - size += cattrs.getSize(cw, code.data, code.length, maxStack, - maxLocals); - } - out.putShort(cw.newUTF8("Code")).putInt(size); - out.putShort(maxStack).putShort(maxLocals); - out.putInt(code.length).putByteArray(code.data, 0, code.length); - out.putShort(handlerCount); - if (handlerCount > 0) { - Handler h = firstHandler; - while (h != null) { - out.putShort(h.start.position).putShort(h.end.position) - .putShort(h.handler.position).putShort(h.type); - h = h.next; - } - } - attributeCount = 0; - if (localVar != null) { - ++attributeCount; - } - if (localVarType != null) { - ++attributeCount; - } - if (lineNumber != null) { - ++attributeCount; - } - if (stackMap != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && ctanns != null) { - ++attributeCount; - } - if (ClassReader.ANNOTATIONS && ictanns != null) { - ++attributeCount; - } - if (cattrs != null) { - attributeCount += cattrs.getCount(); - } - out.putShort(attributeCount); - if (localVar != null) { - out.putShort(cw.newUTF8("LocalVariableTable")); - out.putInt(localVar.length + 2).putShort(localVarCount); - out.putByteArray(localVar.data, 0, localVar.length); - } - if (localVarType != null) { - out.putShort(cw.newUTF8("LocalVariableTypeTable")); - out.putInt(localVarType.length + 2).putShort(localVarTypeCount); - out.putByteArray(localVarType.data, 0, localVarType.length); - } - if (lineNumber != null) { - out.putShort(cw.newUTF8("LineNumberTable")); - out.putInt(lineNumber.length + 2).putShort(lineNumberCount); - out.putByteArray(lineNumber.data, 0, lineNumber.length); - } - if (stackMap != null) { - boolean zip = (cw.version & 0xFFFF) >= Opcodes.V1_6; - out.putShort(cw.newUTF8(zip ? "StackMapTable" : "StackMap")); - out.putInt(stackMap.length + 2).putShort(frameCount); - out.putByteArray(stackMap.data, 0, stackMap.length); - } - if (ClassReader.ANNOTATIONS && ctanns != null) { - out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations")); - ctanns.put(out); - } - if (ClassReader.ANNOTATIONS && ictanns != null) { - out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations")); - ictanns.put(out); - } - if (cattrs != null) { - cattrs.put(cw, code.data, code.length, maxLocals, maxStack, out); - } - } - if (exceptionCount > 0) { - out.putShort(cw.newUTF8("Exceptions")).putInt( - 2 * exceptionCount + 2); - out.putShort(exceptionCount); - for (int i = 0; i < exceptionCount; ++i) { - out.putShort(exceptions[i]); - } - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0) { - if ((cw.version & 0xFFFF) < Opcodes.V1_5 - || (access & ClassWriter.ACC_SYNTHETIC_ATTRIBUTE) != 0) { - out.putShort(cw.newUTF8("Synthetic")).putInt(0); - } - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - out.putShort(cw.newUTF8("Deprecated")).putInt(0); - } - if (ClassReader.SIGNATURES && signature != null) { - out.putShort(cw.newUTF8("Signature")).putInt(2) - .putShort(cw.newUTF8(signature)); - } - if (methodParameters != null) { - out.putShort(cw.newUTF8("MethodParameters")); - out.putInt(methodParameters.length + 1).putByte( - methodParametersCount); - out.putByteArray(methodParameters.data, 0, methodParameters.length); - } - if (ClassReader.ANNOTATIONS && annd != null) { - out.putShort(cw.newUTF8("AnnotationDefault")); - out.putInt(annd.length); - out.putByteArray(annd.data, 0, annd.length); - } - if (ClassReader.ANNOTATIONS && anns != null) { - out.putShort(cw.newUTF8("RuntimeVisibleAnnotations")); - anns.put(out); - } - if (ClassReader.ANNOTATIONS && ianns != null) { - out.putShort(cw.newUTF8("RuntimeInvisibleAnnotations")); - ianns.put(out); - } - if (ClassReader.ANNOTATIONS && tanns != null) { - out.putShort(cw.newUTF8("RuntimeVisibleTypeAnnotations")); - tanns.put(out); - } - if (ClassReader.ANNOTATIONS && itanns != null) { - out.putShort(cw.newUTF8("RuntimeInvisibleTypeAnnotations")); - itanns.put(out); - } - if (ClassReader.ANNOTATIONS && panns != null) { - out.putShort(cw.newUTF8("RuntimeVisibleParameterAnnotations")); - AnnotationWriter.put(panns, synthetics, out); - } - if (ClassReader.ANNOTATIONS && ipanns != null) { - out.putShort(cw.newUTF8("RuntimeInvisibleParameterAnnotations")); - AnnotationWriter.put(ipanns, synthetics, out); - } - if (attrs != null) { - attrs.put(cw, null, 0, -1, -1, out); - } - } - - // ------------------------------------------------------------------------ - // Utility methods: instruction resizing (used to handle GOTO_W and JSR_W) - // ------------------------------------------------------------------------ - - /** - * Resizes and replaces the temporary instructions inserted by - * {@link Label#resolve} for wide forward jumps, while keeping jump offsets - * and instruction addresses consistent. This may require to resize other - * existing instructions, or even to introduce new instructions: for - * example, increasing the size of an instruction by 2 at the middle of a - * method can increases the offset of an IFEQ instruction from 32766 to - * 32768, in which case IFEQ 32766 must be replaced with IFNEQ 8 GOTO_W - * 32765. This, in turn, may require to increase the size of another jump - * instruction, and so on... All these operations are handled automatically - * by this method. - *

- * This method must be called after all the method that is being built - * has been visited. In particular, the {@link Label Label} objects used - * to construct the method are no longer valid after this method has been - * called. - */ - private void resizeInstructions() { - byte[] b = code.data; // bytecode of the method - int u, v, label; // indexes in b - int i, j; // loop indexes - /* - * 1st step: As explained above, resizing an instruction may require to - * resize another one, which may require to resize yet another one, and - * so on. The first step of the algorithm consists in finding all the - * instructions that need to be resized, without modifying the code. - * This is done by the following "fix point" algorithm: - * - * Parse the code to find the jump instructions whose offset will need - * more than 2 bytes to be stored (the future offset is computed from - * the current offset and from the number of bytes that will be inserted - * or removed between the source and target instructions). For each such - * instruction, adds an entry in (a copy of) the indexes and sizes - * arrays (if this has not already been done in a previous iteration!). - * - * If at least one entry has been added during the previous step, go - * back to the beginning, otherwise stop. - * - * In fact the real algorithm is complicated by the fact that the size - * of TABLESWITCH and LOOKUPSWITCH instructions depends on their - * position in the bytecode (because of padding). In order to ensure the - * convergence of the algorithm, the number of bytes to be added or - * removed from these instructions is over estimated during the previous - * loop, and computed exactly only after the loop is finished (this - * requires another pass to parse the bytecode of the method). - */ - int[] allIndexes = new int[0]; // copy of indexes - int[] allSizes = new int[0]; // copy of sizes - boolean[] resize; // instructions to be resized - int newOffset; // future offset of a jump instruction - - resize = new boolean[code.length]; - - // 3 = loop again, 2 = loop ended, 1 = last pass, 0 = done - int state = 3; - do { - if (state == 3) { - state = 2; - } - u = 0; - while (u < b.length) { - int opcode = b[u] & 0xFF; // opcode of current instruction - int insert = 0; // bytes to be added after this instruction - - switch (ClassWriter.TYPE[opcode]) { - case ClassWriter.NOARG_INSN: - case ClassWriter.IMPLVAR_INSN: - u += 1; - break; - case ClassWriter.LABEL_INSN: - if (opcode > 201) { - // converts temporary opcodes 202 to 217, 218 and - // 219 to IFEQ ... JSR (inclusive), IFNULL and - // IFNONNULL - opcode = opcode < 218 ? opcode - 49 : opcode - 20; - label = u + readUnsignedShort(b, u + 1); - } else { - label = u + readShort(b, u + 1); - } - newOffset = getNewOffset(allIndexes, allSizes, u, label); - if (newOffset < Short.MIN_VALUE - || newOffset > Short.MAX_VALUE) { - if (!resize[u]) { - if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) { - // two additional bytes will be required to - // replace this GOTO or JSR instruction with - // a GOTO_W or a JSR_W - insert = 2; - } else { - // five additional bytes will be required to - // replace this IFxxx instruction with - // IFNOTxxx GOTO_W , where IFNOTxxx - // is the "opposite" opcode of IFxxx (i.e., - // IFNE for IFEQ) and where designates - // the instruction just after the GOTO_W. - insert = 5; - } - resize[u] = true; - } - } - u += 3; - break; - case ClassWriter.LABELW_INSN: - u += 5; - break; - case ClassWriter.TABL_INSN: - if (state == 1) { - // true number of bytes to be added (or removed) - // from this instruction = (future number of padding - // bytes - current number of padding byte) - - // previously over estimated variation = - // = ((3 - newOffset%4) - (3 - u%4)) - u%4 - // = (-newOffset%4 + u%4) - u%4 - // = -(newOffset & 3) - newOffset = getNewOffset(allIndexes, allSizes, 0, u); - insert = -(newOffset & 3); - } else if (!resize[u]) { - // over estimation of the number of bytes to be - // added to this instruction = 3 - current number - // of padding bytes = 3 - (3 - u%4) = u%4 = u & 3 - insert = u & 3; - resize[u] = true; - } - // skips instruction - u = u + 4 - (u & 3); - u += 4 * (readInt(b, u + 8) - readInt(b, u + 4) + 1) + 12; - break; - case ClassWriter.LOOK_INSN: - if (state == 1) { - // like TABL_INSN - newOffset = getNewOffset(allIndexes, allSizes, 0, u); - insert = -(newOffset & 3); - } else if (!resize[u]) { - // like TABL_INSN - insert = u & 3; - resize[u] = true; - } - // skips instruction - u = u + 4 - (u & 3); - u += 8 * readInt(b, u + 4) + 8; - break; - case ClassWriter.WIDE_INSN: - opcode = b[u + 1] & 0xFF; - if (opcode == Opcodes.IINC) { - u += 6; - } else { - u += 4; - } - break; - case ClassWriter.VAR_INSN: - case ClassWriter.SBYTE_INSN: - case ClassWriter.LDC_INSN: - u += 2; - break; - case ClassWriter.SHORT_INSN: - case ClassWriter.LDCW_INSN: - case ClassWriter.FIELDORMETH_INSN: - case ClassWriter.TYPE_INSN: - case ClassWriter.IINC_INSN: - u += 3; - break; - case ClassWriter.ITFMETH_INSN: - case ClassWriter.INDYMETH_INSN: - u += 5; - break; - // case ClassWriter.MANA_INSN: - default: - u += 4; - break; - } - if (insert != 0) { - // adds a new (u, insert) entry in the allIndexes and - // allSizes arrays - int[] newIndexes = new int[allIndexes.length + 1]; - int[] newSizes = new int[allSizes.length + 1]; - System.arraycopy(allIndexes, 0, newIndexes, 0, - allIndexes.length); - System.arraycopy(allSizes, 0, newSizes, 0, allSizes.length); - newIndexes[allIndexes.length] = u; - newSizes[allSizes.length] = insert; - allIndexes = newIndexes; - allSizes = newSizes; - if (insert > 0) { - state = 3; - } - } - } - if (state < 3) { - --state; - } - } while (state != 0); - - // 2nd step: - // copies the bytecode of the method into a new bytevector, updates the - // offsets, and inserts (or removes) bytes as requested. - - ByteVector newCode = new ByteVector(code.length); - - u = 0; - while (u < code.length) { - int opcode = b[u] & 0xFF; - switch (ClassWriter.TYPE[opcode]) { - case ClassWriter.NOARG_INSN: - case ClassWriter.IMPLVAR_INSN: - newCode.putByte(opcode); - u += 1; - break; - case ClassWriter.LABEL_INSN: - if (opcode > 201) { - // changes temporary opcodes 202 to 217 (inclusive), 218 - // and 219 to IFEQ ... JSR (inclusive), IFNULL and - // IFNONNULL - opcode = opcode < 218 ? opcode - 49 : opcode - 20; - label = u + readUnsignedShort(b, u + 1); - } else { - label = u + readShort(b, u + 1); - } - newOffset = getNewOffset(allIndexes, allSizes, u, label); - if (resize[u]) { - // replaces GOTO with GOTO_W, JSR with JSR_W and IFxxx - // with IFNOTxxx GOTO_W , where IFNOTxxx is - // the "opposite" opcode of IFxxx (i.e., IFNE for IFEQ) - // and where designates the instruction just after - // the GOTO_W. - if (opcode == Opcodes.GOTO) { - newCode.putByte(200); // GOTO_W - } else if (opcode == Opcodes.JSR) { - newCode.putByte(201); // JSR_W - } else { - newCode.putByte(opcode <= 166 ? ((opcode + 1) ^ 1) - 1 - : opcode ^ 1); - newCode.putShort(8); // jump offset - newCode.putByte(200); // GOTO_W - // newOffset now computed from start of GOTO_W - newOffset -= 3; - } - newCode.putInt(newOffset); - } else { - newCode.putByte(opcode); - newCode.putShort(newOffset); - } - u += 3; - break; - case ClassWriter.LABELW_INSN: - label = u + readInt(b, u + 1); - newOffset = getNewOffset(allIndexes, allSizes, u, label); - newCode.putByte(opcode); - newCode.putInt(newOffset); - u += 5; - break; - case ClassWriter.TABL_INSN: - // skips 0 to 3 padding bytes - v = u; - u = u + 4 - (v & 3); - // reads and copies instruction - newCode.putByte(Opcodes.TABLESWITCH); - newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4); - label = v + readInt(b, u); - u += 4; - newOffset = getNewOffset(allIndexes, allSizes, v, label); - newCode.putInt(newOffset); - j = readInt(b, u); - u += 4; - newCode.putInt(j); - j = readInt(b, u) - j + 1; - u += 4; - newCode.putInt(readInt(b, u - 4)); - for (; j > 0; --j) { - label = v + readInt(b, u); - u += 4; - newOffset = getNewOffset(allIndexes, allSizes, v, label); - newCode.putInt(newOffset); - } - break; - case ClassWriter.LOOK_INSN: - // skips 0 to 3 padding bytes - v = u; - u = u + 4 - (v & 3); - // reads and copies instruction - newCode.putByte(Opcodes.LOOKUPSWITCH); - newCode.putByteArray(null, 0, (4 - newCode.length % 4) % 4); - label = v + readInt(b, u); - u += 4; - newOffset = getNewOffset(allIndexes, allSizes, v, label); - newCode.putInt(newOffset); - j = readInt(b, u); - u += 4; - newCode.putInt(j); - for (; j > 0; --j) { - newCode.putInt(readInt(b, u)); - u += 4; - label = v + readInt(b, u); - u += 4; - newOffset = getNewOffset(allIndexes, allSizes, v, label); - newCode.putInt(newOffset); - } - break; - case ClassWriter.WIDE_INSN: - opcode = b[u + 1] & 0xFF; - if (opcode == Opcodes.IINC) { - newCode.putByteArray(b, u, 6); - u += 6; - } else { - newCode.putByteArray(b, u, 4); - u += 4; - } - break; - case ClassWriter.VAR_INSN: - case ClassWriter.SBYTE_INSN: - case ClassWriter.LDC_INSN: - newCode.putByteArray(b, u, 2); - u += 2; - break; - case ClassWriter.SHORT_INSN: - case ClassWriter.LDCW_INSN: - case ClassWriter.FIELDORMETH_INSN: - case ClassWriter.TYPE_INSN: - case ClassWriter.IINC_INSN: - newCode.putByteArray(b, u, 3); - u += 3; - break; - case ClassWriter.ITFMETH_INSN: - case ClassWriter.INDYMETH_INSN: - newCode.putByteArray(b, u, 5); - u += 5; - break; - // case MANA_INSN: - default: - newCode.putByteArray(b, u, 4); - u += 4; - break; - } - } - - // updates the stack map frame labels - if (compute == FRAMES) { - Label l = labels; - while (l != null) { - /* - * Detects the labels that are just after an IF instruction that - * has been resized with the IFNOT GOTO_W pattern. These labels - * are now the target of a jump instruction (the IFNOT - * instruction). Note that we need the original label position - * here. getNewOffset must therefore never have been called for - * this label. - */ - u = l.position - 3; - if (u >= 0 && resize[u]) { - l.status |= Label.TARGET; - } - getNewOffset(allIndexes, allSizes, l); - l = l.successor; - } - // Update the offsets in the uninitialized types - for (i = 0; i < cw.typeTable.length; ++i) { - Item item = cw.typeTable[i]; - if (item != null && item.type == ClassWriter.TYPE_UNINIT) { - item.intVal = getNewOffset(allIndexes, allSizes, 0, - item.intVal); - } - } - // The stack map frames are not serialized yet, so we don't need - // to update them. They will be serialized in visitMaxs. - } else if (frameCount > 0) { - /* - * Resizing an existing stack map frame table is really hard. Not - * only the table must be parsed to update the offets, but new - * frames may be needed for jump instructions that were inserted by - * this method. And updating the offsets or inserting frames can - * change the format of the following frames, in case of packed - * frames. In practice the whole table must be recomputed. For this - * the frames are marked as potentially invalid. This will cause the - * whole class to be reread and rewritten with the COMPUTE_FRAMES - * option (see the ClassWriter.toByteArray method). This is not very - * efficient but is much easier and requires much less code than any - * other method I can think of. - */ - cw.invalidFrames = true; - } - // updates the exception handler block labels - Handler h = firstHandler; - while (h != null) { - getNewOffset(allIndexes, allSizes, h.start); - getNewOffset(allIndexes, allSizes, h.end); - getNewOffset(allIndexes, allSizes, h.handler); - h = h.next; - } - // updates the instructions addresses in the - // local var and line number tables - for (i = 0; i < 2; ++i) { - ByteVector bv = i == 0 ? localVar : localVarType; - if (bv != null) { - b = bv.data; - u = 0; - while (u < bv.length) { - label = readUnsignedShort(b, u); - newOffset = getNewOffset(allIndexes, allSizes, 0, label); - writeShort(b, u, newOffset); - label += readUnsignedShort(b, u + 2); - newOffset = getNewOffset(allIndexes, allSizes, 0, label) - - newOffset; - writeShort(b, u + 2, newOffset); - u += 10; - } - } - } - if (lineNumber != null) { - b = lineNumber.data; - u = 0; - while (u < lineNumber.length) { - writeShort( - b, - u, - getNewOffset(allIndexes, allSizes, 0, - readUnsignedShort(b, u))); - u += 4; - } - } - // updates the labels of the other attributes - Attribute attr = cattrs; - while (attr != null) { - Label[] labels = attr.getLabels(); - if (labels != null) { - for (i = labels.length - 1; i >= 0; --i) { - getNewOffset(allIndexes, allSizes, labels[i]); - } - } - attr = attr.next; - } - - // replaces old bytecodes with new ones - code = newCode; - } - - /** - * Reads an unsigned short value in the given byte array. - * - * @param b - * a byte array. - * @param index - * the start index of the value to be read. - * @return the read value. - */ - static int readUnsignedShort(final byte[] b, final int index) { - return ((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF); - } - - /** - * Reads a signed short value in the given byte array. - * - * @param b - * a byte array. - * @param index - * the start index of the value to be read. - * @return the read value. - */ - static short readShort(final byte[] b, final int index) { - return (short) (((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF)); - } - - /** - * Reads a signed int value in the given byte array. - * - * @param b - * a byte array. - * @param index - * the start index of the value to be read. - * @return the read value. - */ - static int readInt(final byte[] b, final int index) { - return ((b[index] & 0xFF) << 24) | ((b[index + 1] & 0xFF) << 16) - | ((b[index + 2] & 0xFF) << 8) | (b[index + 3] & 0xFF); - } - - /** - * Writes a short value in the given byte array. - * - * @param b - * a byte array. - * @param index - * where the first byte of the short value must be written. - * @param s - * the value to be written in the given byte array. - */ - static void writeShort(final byte[] b, final int index, final int s) { - b[index] = (byte) (s >>> 8); - b[index + 1] = (byte) s; - } - - /** - * Computes the future value of a bytecode offset. - *

- * Note: it is possible to have several entries for the same instruction in - * the indexes and sizes: two entries (index=a,size=b) and - * (index=a,size=b') are equivalent to a single entry (index=a,size=b+b'). - * - * @param indexes - * current positions of the instructions to be resized. Each - * instruction must be designated by the index of its last - * byte, plus one (or, in other words, by the index of the - * first byte of the next instruction). - * @param sizes - * the number of bytes to be added to the above - * instructions. More precisely, for each i < len, - * sizes[i] bytes will be added at the end of the - * instruction designated by indexes[i] or, if - * sizes[i] is negative, the last | - * sizes[i]| bytes of the instruction will be removed - * (the instruction size must not become negative or - * null). - * @param begin - * index of the first byte of the source instruction. - * @param end - * index of the first byte of the target instruction. - * @return the future value of the given bytecode offset. - */ - static int getNewOffset(final int[] indexes, final int[] sizes, - final int begin, final int end) { - int offset = end - begin; - for (int i = 0; i < indexes.length; ++i) { - if (begin < indexes[i] && indexes[i] <= end) { - // forward jump - offset += sizes[i]; - } else if (end < indexes[i] && indexes[i] <= begin) { - // backward jump - offset -= sizes[i]; - } - } - return offset; - } - - /** - * Updates the offset of the given label. - * - * @param indexes - * current positions of the instructions to be resized. Each - * instruction must be designated by the index of its last - * byte, plus one (or, in other words, by the index of the - * first byte of the next instruction). - * @param sizes - * the number of bytes to be added to the above - * instructions. More precisely, for each i < len, - * sizes[i] bytes will be added at the end of the - * instruction designated by indexes[i] or, if - * sizes[i] is negative, the last | - * sizes[i]| bytes of the instruction will be removed - * (the instruction size must not become negative or - * null). - * @param label - * the label whose offset must be updated. - */ - static void getNewOffset(final int[] indexes, final int[] sizes, - final Label label) { - if ((label.status & Label.RESIZED) == 0) { - label.position = getNewOffset(indexes, sizes, 0, label.position); - label.status |= Label.RESIZED; - } - } -} diff --git a/src/asm/scala/tools/asm/Opcodes.java b/src/asm/scala/tools/asm/Opcodes.java deleted file mode 100644 index 24eaffa717..0000000000 --- a/src/asm/scala/tools/asm/Opcodes.java +++ /dev/null @@ -1,361 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm; - -/** - * Defines the JVM opcodes, access flags and array type codes. This interface - * does not define all the JVM opcodes because some opcodes are automatically - * handled. For example, the xLOAD and xSTORE opcodes are automatically replaced - * by xLOAD_n and xSTORE_n opcodes when possible. The xLOAD_n and xSTORE_n - * opcodes are therefore not defined in this interface. Likewise for LDC, - * automatically replaced by LDC_W or LDC2_W when necessary, WIDE, GOTO_W and - * JSR_W. - * - * @author Eric Bruneton - * @author Eugene Kuleshov - */ -public interface Opcodes { - - // ASM API versions - - int ASM4 = 4 << 16 | 0 << 8 | 0; - int ASM5 = 5 << 16 | 0 << 8 | 0; - - // versions - - int V1_1 = 3 << 16 | 45; - int V1_2 = 0 << 16 | 46; - int V1_3 = 0 << 16 | 47; - int V1_4 = 0 << 16 | 48; - int V1_5 = 0 << 16 | 49; - int V1_6 = 0 << 16 | 50; - int V1_7 = 0 << 16 | 51; - int V1_8 = 0 << 16 | 52; - - // access flags - - int ACC_PUBLIC = 0x0001; // class, field, method - int ACC_PRIVATE = 0x0002; // class, field, method - int ACC_PROTECTED = 0x0004; // class, field, method - int ACC_STATIC = 0x0008; // field, method - int ACC_FINAL = 0x0010; // class, field, method, parameter - int ACC_SUPER = 0x0020; // class - int ACC_SYNCHRONIZED = 0x0020; // method - int ACC_VOLATILE = 0x0040; // field - int ACC_BRIDGE = 0x0040; // method - int ACC_VARARGS = 0x0080; // method - int ACC_TRANSIENT = 0x0080; // field - int ACC_NATIVE = 0x0100; // method - int ACC_INTERFACE = 0x0200; // class - int ACC_ABSTRACT = 0x0400; // class, method - int ACC_STRICT = 0x0800; // method - int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter - int ACC_ANNOTATION = 0x2000; // class - int ACC_ENUM = 0x4000; // class(?) field inner - int ACC_MANDATED = 0x8000; // parameter - - // ASM specific pseudo access flags - - int ACC_DEPRECATED = 0x20000; // class, field, method - - // types for NEWARRAY - - int T_BOOLEAN = 4; - int T_CHAR = 5; - int T_FLOAT = 6; - int T_DOUBLE = 7; - int T_BYTE = 8; - int T_SHORT = 9; - int T_INT = 10; - int T_LONG = 11; - - // tags for Handle - - int H_GETFIELD = 1; - int H_GETSTATIC = 2; - int H_PUTFIELD = 3; - int H_PUTSTATIC = 4; - int H_INVOKEVIRTUAL = 5; - int H_INVOKESTATIC = 6; - int H_INVOKESPECIAL = 7; - int H_NEWINVOKESPECIAL = 8; - int H_INVOKEINTERFACE = 9; - - // stack map frame types - - /** - * Represents an expanded frame. See {@link ClassReader#EXPAND_FRAMES}. - */ - int F_NEW = -1; - - /** - * Represents a compressed frame with complete frame data. - */ - int F_FULL = 0; - - /** - * Represents a compressed frame where locals are the same as the locals in - * the previous frame, except that additional 1-3 locals are defined, and - * with an empty stack. - */ - int F_APPEND = 1; - - /** - * Represents a compressed frame where locals are the same as the locals in - * the previous frame, except that the last 1-3 locals are absent and with - * an empty stack. - */ - int F_CHOP = 2; - - /** - * Represents a compressed frame with exactly the same locals as the - * previous frame and with an empty stack. - */ - int F_SAME = 3; - - /** - * Represents a compressed frame with exactly the same locals as the - * previous frame and with a single value on the stack. - */ - int F_SAME1 = 4; - - Integer TOP = new Integer(0); - Integer INTEGER = new Integer(1); - Integer FLOAT = new Integer(2); - Integer DOUBLE = new Integer(3); - Integer LONG = new Integer(4); - Integer NULL = new Integer(5); - Integer UNINITIALIZED_THIS = new Integer(6); - - // opcodes // visit method (- = idem) - - int NOP = 0; // visitInsn - int ACONST_NULL = 1; // - - int ICONST_M1 = 2; // - - int ICONST_0 = 3; // - - int ICONST_1 = 4; // - - int ICONST_2 = 5; // - - int ICONST_3 = 6; // - - int ICONST_4 = 7; // - - int ICONST_5 = 8; // - - int LCONST_0 = 9; // - - int LCONST_1 = 10; // - - int FCONST_0 = 11; // - - int FCONST_1 = 12; // - - int FCONST_2 = 13; // - - int DCONST_0 = 14; // - - int DCONST_1 = 15; // - - int BIPUSH = 16; // visitIntInsn - int SIPUSH = 17; // - - int LDC = 18; // visitLdcInsn - // int LDC_W = 19; // - - // int LDC2_W = 20; // - - int ILOAD = 21; // visitVarInsn - int LLOAD = 22; // - - int FLOAD = 23; // - - int DLOAD = 24; // - - int ALOAD = 25; // - - // int ILOAD_0 = 26; // - - // int ILOAD_1 = 27; // - - // int ILOAD_2 = 28; // - - // int ILOAD_3 = 29; // - - // int LLOAD_0 = 30; // - - // int LLOAD_1 = 31; // - - // int LLOAD_2 = 32; // - - // int LLOAD_3 = 33; // - - // int FLOAD_0 = 34; // - - // int FLOAD_1 = 35; // - - // int FLOAD_2 = 36; // - - // int FLOAD_3 = 37; // - - // int DLOAD_0 = 38; // - - // int DLOAD_1 = 39; // - - // int DLOAD_2 = 40; // - - // int DLOAD_3 = 41; // - - // int ALOAD_0 = 42; // - - // int ALOAD_1 = 43; // - - // int ALOAD_2 = 44; // - - // int ALOAD_3 = 45; // - - int IALOAD = 46; // visitInsn - int LALOAD = 47; // - - int FALOAD = 48; // - - int DALOAD = 49; // - - int AALOAD = 50; // - - int BALOAD = 51; // - - int CALOAD = 52; // - - int SALOAD = 53; // - - int ISTORE = 54; // visitVarInsn - int LSTORE = 55; // - - int FSTORE = 56; // - - int DSTORE = 57; // - - int ASTORE = 58; // - - // int ISTORE_0 = 59; // - - // int ISTORE_1 = 60; // - - // int ISTORE_2 = 61; // - - // int ISTORE_3 = 62; // - - // int LSTORE_0 = 63; // - - // int LSTORE_1 = 64; // - - // int LSTORE_2 = 65; // - - // int LSTORE_3 = 66; // - - // int FSTORE_0 = 67; // - - // int FSTORE_1 = 68; // - - // int FSTORE_2 = 69; // - - // int FSTORE_3 = 70; // - - // int DSTORE_0 = 71; // - - // int DSTORE_1 = 72; // - - // int DSTORE_2 = 73; // - - // int DSTORE_3 = 74; // - - // int ASTORE_0 = 75; // - - // int ASTORE_1 = 76; // - - // int ASTORE_2 = 77; // - - // int ASTORE_3 = 78; // - - int IASTORE = 79; // visitInsn - int LASTORE = 80; // - - int FASTORE = 81; // - - int DASTORE = 82; // - - int AASTORE = 83; // - - int BASTORE = 84; // - - int CASTORE = 85; // - - int SASTORE = 86; // - - int POP = 87; // - - int POP2 = 88; // - - int DUP = 89; // - - int DUP_X1 = 90; // - - int DUP_X2 = 91; // - - int DUP2 = 92; // - - int DUP2_X1 = 93; // - - int DUP2_X2 = 94; // - - int SWAP = 95; // - - int IADD = 96; // - - int LADD = 97; // - - int FADD = 98; // - - int DADD = 99; // - - int ISUB = 100; // - - int LSUB = 101; // - - int FSUB = 102; // - - int DSUB = 103; // - - int IMUL = 104; // - - int LMUL = 105; // - - int FMUL = 106; // - - int DMUL = 107; // - - int IDIV = 108; // - - int LDIV = 109; // - - int FDIV = 110; // - - int DDIV = 111; // - - int IREM = 112; // - - int LREM = 113; // - - int FREM = 114; // - - int DREM = 115; // - - int INEG = 116; // - - int LNEG = 117; // - - int FNEG = 118; // - - int DNEG = 119; // - - int ISHL = 120; // - - int LSHL = 121; // - - int ISHR = 122; // - - int LSHR = 123; // - - int IUSHR = 124; // - - int LUSHR = 125; // - - int IAND = 126; // - - int LAND = 127; // - - int IOR = 128; // - - int LOR = 129; // - - int IXOR = 130; // - - int LXOR = 131; // - - int IINC = 132; // visitIincInsn - int I2L = 133; // visitInsn - int I2F = 134; // - - int I2D = 135; // - - int L2I = 136; // - - int L2F = 137; // - - int L2D = 138; // - - int F2I = 139; // - - int F2L = 140; // - - int F2D = 141; // - - int D2I = 142; // - - int D2L = 143; // - - int D2F = 144; // - - int I2B = 145; // - - int I2C = 146; // - - int I2S = 147; // - - int LCMP = 148; // - - int FCMPL = 149; // - - int FCMPG = 150; // - - int DCMPL = 151; // - - int DCMPG = 152; // - - int IFEQ = 153; // visitJumpInsn - int IFNE = 154; // - - int IFLT = 155; // - - int IFGE = 156; // - - int IFGT = 157; // - - int IFLE = 158; // - - int IF_ICMPEQ = 159; // - - int IF_ICMPNE = 160; // - - int IF_ICMPLT = 161; // - - int IF_ICMPGE = 162; // - - int IF_ICMPGT = 163; // - - int IF_ICMPLE = 164; // - - int IF_ACMPEQ = 165; // - - int IF_ACMPNE = 166; // - - int GOTO = 167; // - - int JSR = 168; // - - int RET = 169; // visitVarInsn - int TABLESWITCH = 170; // visiTableSwitchInsn - int LOOKUPSWITCH = 171; // visitLookupSwitch - int IRETURN = 172; // visitInsn - int LRETURN = 173; // - - int FRETURN = 174; // - - int DRETURN = 175; // - - int ARETURN = 176; // - - int RETURN = 177; // - - int GETSTATIC = 178; // visitFieldInsn - int PUTSTATIC = 179; // - - int GETFIELD = 180; // - - int PUTFIELD = 181; // - - int INVOKEVIRTUAL = 182; // visitMethodInsn - int INVOKESPECIAL = 183; // - - int INVOKESTATIC = 184; // - - int INVOKEINTERFACE = 185; // - - int INVOKEDYNAMIC = 186; // visitInvokeDynamicInsn - int NEW = 187; // visitTypeInsn - int NEWARRAY = 188; // visitIntInsn - int ANEWARRAY = 189; // visitTypeInsn - int ARRAYLENGTH = 190; // visitInsn - int ATHROW = 191; // - - int CHECKCAST = 192; // visitTypeInsn - int INSTANCEOF = 193; // - - int MONITORENTER = 194; // visitInsn - int MONITOREXIT = 195; // - - // int WIDE = 196; // NOT VISITED - int MULTIANEWARRAY = 197; // visitMultiANewArrayInsn - int IFNULL = 198; // visitJumpInsn - int IFNONNULL = 199; // - - // int GOTO_W = 200; // - - // int JSR_W = 201; // - -} diff --git a/src/asm/scala/tools/asm/Type.java b/src/asm/scala/tools/asm/Type.java deleted file mode 100644 index c8f0048588..0000000000 --- a/src/asm/scala/tools/asm/Type.java +++ /dev/null @@ -1,896 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Method; - -/** - * A Java field or method type. This class can be used to make it easier to - * manipulate type and method descriptors. - * - * @author Eric Bruneton - * @author Chris Nokleberg - */ -public class Type { - - /** - * The sort of the void type. See {@link #getSort getSort}. - */ - public static final int VOID = 0; - - /** - * The sort of the boolean type. See {@link #getSort getSort}. - */ - public static final int BOOLEAN = 1; - - /** - * The sort of the char type. See {@link #getSort getSort}. - */ - public static final int CHAR = 2; - - /** - * The sort of the byte type. See {@link #getSort getSort}. - */ - public static final int BYTE = 3; - - /** - * The sort of the short type. See {@link #getSort getSort}. - */ - public static final int SHORT = 4; - - /** - * The sort of the int type. See {@link #getSort getSort}. - */ - public static final int INT = 5; - - /** - * The sort of the float type. See {@link #getSort getSort}. - */ - public static final int FLOAT = 6; - - /** - * The sort of the long type. See {@link #getSort getSort}. - */ - public static final int LONG = 7; - - /** - * The sort of the double type. See {@link #getSort getSort}. - */ - public static final int DOUBLE = 8; - - /** - * The sort of array reference types. See {@link #getSort getSort}. - */ - public static final int ARRAY = 9; - - /** - * The sort of object reference types. See {@link #getSort getSort}. - */ - public static final int OBJECT = 10; - - /** - * The sort of method types. See {@link #getSort getSort}. - */ - public static final int METHOD = 11; - - /** - * The void type. - */ - public static final Type VOID_TYPE = new Type(VOID, null, ('V' << 24) - | (5 << 16) | (0 << 8) | 0, 1); - - /** - * The boolean type. - */ - public static final Type BOOLEAN_TYPE = new Type(BOOLEAN, null, ('Z' << 24) - | (0 << 16) | (5 << 8) | 1, 1); - - /** - * The char type. - */ - public static final Type CHAR_TYPE = new Type(CHAR, null, ('C' << 24) - | (0 << 16) | (6 << 8) | 1, 1); - - /** - * The byte type. - */ - public static final Type BYTE_TYPE = new Type(BYTE, null, ('B' << 24) - | (0 << 16) | (5 << 8) | 1, 1); - - /** - * The short type. - */ - public static final Type SHORT_TYPE = new Type(SHORT, null, ('S' << 24) - | (0 << 16) | (7 << 8) | 1, 1); - - /** - * The int type. - */ - public static final Type INT_TYPE = new Type(INT, null, ('I' << 24) - | (0 << 16) | (0 << 8) | 1, 1); - - /** - * The float type. - */ - public static final Type FLOAT_TYPE = new Type(FLOAT, null, ('F' << 24) - | (2 << 16) | (2 << 8) | 1, 1); - - /** - * The long type. - */ - public static final Type LONG_TYPE = new Type(LONG, null, ('J' << 24) - | (1 << 16) | (1 << 8) | 2, 1); - - /** - * The double type. - */ - public static final Type DOUBLE_TYPE = new Type(DOUBLE, null, ('D' << 24) - | (3 << 16) | (3 << 8) | 2, 1); - - // ------------------------------------------------------------------------ - // Fields - // ------------------------------------------------------------------------ - - /** - * The sort of this Java type. - */ - private final int sort; - - /** - * A buffer containing the internal name of this Java type. This field is - * only used for reference types. - */ - private final char[] buf; - - /** - * The offset of the internal name of this Java type in {@link #buf buf} or, - * for primitive types, the size, descriptor and getOpcode offsets for this - * type (byte 0 contains the size, byte 1 the descriptor, byte 2 the offset - * for IALOAD or IASTORE, byte 3 the offset for all other instructions). - */ - private final int off; - - /** - * The length of the internal name of this Java type. - */ - private final int len; - - // ------------------------------------------------------------------------ - // Constructors - // ------------------------------------------------------------------------ - - /** - * Constructs a reference type. - * - * @param sort - * the sort of the reference type to be constructed. - * @param buf - * a buffer containing the descriptor of the previous type. - * @param off - * the offset of this descriptor in the previous buffer. - * @param len - * the length of this descriptor. - */ - private Type(final int sort, final char[] buf, final int off, final int len) { - this.sort = sort; - this.buf = buf; - this.off = off; - this.len = len; - } - - /** - * Returns the Java type corresponding to the given type descriptor. - * - * @param typeDescriptor - * a field or method type descriptor. - * @return the Java type corresponding to the given type descriptor. - */ - public static Type getType(final String typeDescriptor) { - return getType(typeDescriptor.toCharArray(), 0); - } - - /** - * Returns the Java type corresponding to the given internal name. - * - * @param internalName - * an internal name. - * @return the Java type corresponding to the given internal name. - */ - public static Type getObjectType(final String internalName) { - char[] buf = internalName.toCharArray(); - return new Type(buf[0] == '[' ? ARRAY : OBJECT, buf, 0, buf.length); - } - - /** - * Returns the Java type corresponding to the given method descriptor. - * Equivalent to Type.getType(methodDescriptor). - * - * @param methodDescriptor - * a method descriptor. - * @return the Java type corresponding to the given method descriptor. - */ - public static Type getMethodType(final String methodDescriptor) { - return getType(methodDescriptor.toCharArray(), 0); - } - - /** - * Returns the Java method type corresponding to the given argument and - * return types. - * - * @param returnType - * the return type of the method. - * @param argumentTypes - * the argument types of the method. - * @return the Java type corresponding to the given argument and return - * types. - */ - public static Type getMethodType(final Type returnType, - final Type... argumentTypes) { - return getType(getMethodDescriptor(returnType, argumentTypes)); - } - - /** - * Returns the Java type corresponding to the given class. - * - * @param c - * a class. - * @return the Java type corresponding to the given class. - */ - public static Type getType(final Class c) { - if (c.isPrimitive()) { - if (c == Integer.TYPE) { - return INT_TYPE; - } else if (c == Void.TYPE) { - return VOID_TYPE; - } else if (c == Boolean.TYPE) { - return BOOLEAN_TYPE; - } else if (c == Byte.TYPE) { - return BYTE_TYPE; - } else if (c == Character.TYPE) { - return CHAR_TYPE; - } else if (c == Short.TYPE) { - return SHORT_TYPE; - } else if (c == Double.TYPE) { - return DOUBLE_TYPE; - } else if (c == Float.TYPE) { - return FLOAT_TYPE; - } else /* if (c == Long.TYPE) */{ - return LONG_TYPE; - } - } else { - return getType(getDescriptor(c)); - } - } - - /** - * Returns the Java method type corresponding to the given constructor. - * - * @param c - * a {@link Constructor Constructor} object. - * @return the Java method type corresponding to the given constructor. - */ - public static Type getType(final Constructor c) { - return getType(getConstructorDescriptor(c)); - } - - /** - * Returns the Java method type corresponding to the given method. - * - * @param m - * a {@link Method Method} object. - * @return the Java method type corresponding to the given method. - */ - public static Type getType(final Method m) { - return getType(getMethodDescriptor(m)); - } - - /** - * Returns the Java types corresponding to the argument types of the given - * method descriptor. - * - * @param methodDescriptor - * a method descriptor. - * @return the Java types corresponding to the argument types of the given - * method descriptor. - */ - public static Type[] getArgumentTypes(final String methodDescriptor) { - char[] buf = methodDescriptor.toCharArray(); - int off = 1; - int size = 0; - while (true) { - char car = buf[off++]; - if (car == ')') { - break; - } else if (car == 'L') { - while (buf[off++] != ';') { - } - ++size; - } else if (car != '[') { - ++size; - } - } - Type[] args = new Type[size]; - off = 1; - size = 0; - while (buf[off] != ')') { - args[size] = getType(buf, off); - off += args[size].len + (args[size].sort == OBJECT ? 2 : 0); - size += 1; - } - return args; - } - - /** - * Returns the Java types corresponding to the argument types of the given - * method. - * - * @param method - * a method. - * @return the Java types corresponding to the argument types of the given - * method. - */ - public static Type[] getArgumentTypes(final Method method) { - Class[] classes = method.getParameterTypes(); - Type[] types = new Type[classes.length]; - for (int i = classes.length - 1; i >= 0; --i) { - types[i] = getType(classes[i]); - } - return types; - } - - /** - * Returns the Java type corresponding to the return type of the given - * method descriptor. - * - * @param methodDescriptor - * a method descriptor. - * @return the Java type corresponding to the return type of the given - * method descriptor. - */ - public static Type getReturnType(final String methodDescriptor) { - char[] buf = methodDescriptor.toCharArray(); - return getType(buf, methodDescriptor.indexOf(')') + 1); - } - - /** - * Returns the Java type corresponding to the return type of the given - * method. - * - * @param method - * a method. - * @return the Java type corresponding to the return type of the given - * method. - */ - public static Type getReturnType(final Method method) { - return getType(method.getReturnType()); - } - - /** - * Computes the size of the arguments and of the return value of a method. - * - * @param desc - * the descriptor of a method. - * @return the size of the arguments of the method (plus one for the - * implicit this argument), argSize, and the size of its return - * value, retSize, packed into a single int i = - * (argSize << 2) | retSize (argSize is therefore equal to - * i >> 2, and retSize to i & 0x03). - */ - public static int getArgumentsAndReturnSizes(final String desc) { - int n = 1; - int c = 1; - while (true) { - char car = desc.charAt(c++); - if (car == ')') { - car = desc.charAt(c); - return n << 2 - | (car == 'V' ? 0 : (car == 'D' || car == 'J' ? 2 : 1)); - } else if (car == 'L') { - while (desc.charAt(c++) != ';') { - } - n += 1; - } else if (car == '[') { - while ((car = desc.charAt(c)) == '[') { - ++c; - } - if (car == 'D' || car == 'J') { - n -= 1; - } - } else if (car == 'D' || car == 'J') { - n += 2; - } else { - n += 1; - } - } - } - - /** - * Returns the Java type corresponding to the given type descriptor. For - * method descriptors, buf is supposed to contain nothing more than the - * descriptor itself. - * - * @param buf - * a buffer containing a type descriptor. - * @param off - * the offset of this descriptor in the previous buffer. - * @return the Java type corresponding to the given type descriptor. - */ - private static Type getType(final char[] buf, final int off) { - int len; - switch (buf[off]) { - case 'V': - return VOID_TYPE; - case 'Z': - return BOOLEAN_TYPE; - case 'C': - return CHAR_TYPE; - case 'B': - return BYTE_TYPE; - case 'S': - return SHORT_TYPE; - case 'I': - return INT_TYPE; - case 'F': - return FLOAT_TYPE; - case 'J': - return LONG_TYPE; - case 'D': - return DOUBLE_TYPE; - case '[': - len = 1; - while (buf[off + len] == '[') { - ++len; - } - if (buf[off + len] == 'L') { - ++len; - while (buf[off + len] != ';') { - ++len; - } - } - return new Type(ARRAY, buf, off, len + 1); - case 'L': - len = 1; - while (buf[off + len] != ';') { - ++len; - } - return new Type(OBJECT, buf, off + 1, len - 1); - // case '(': - default: - return new Type(METHOD, buf, off, buf.length - off); - } - } - - // ------------------------------------------------------------------------ - // Accessors - // ------------------------------------------------------------------------ - - /** - * Returns the sort of this Java type. - * - * @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, {@link #CHAR CHAR}, - * {@link #BYTE BYTE}, {@link #SHORT SHORT}, {@link #INT INT}, - * {@link #FLOAT FLOAT}, {@link #LONG LONG}, {@link #DOUBLE DOUBLE}, - * {@link #ARRAY ARRAY}, {@link #OBJECT OBJECT} or {@link #METHOD - * METHOD}. - */ - public int getSort() { - return sort; - } - - /** - * Returns the number of dimensions of this array type. This method should - * only be used for an array type. - * - * @return the number of dimensions of this array type. - */ - public int getDimensions() { - int i = 1; - while (buf[off + i] == '[') { - ++i; - } - return i; - } - - /** - * Returns the type of the elements of this array type. This method should - * only be used for an array type. - * - * @return Returns the type of the elements of this array type. - */ - public Type getElementType() { - return getType(buf, off + getDimensions()); - } - - /** - * Returns the binary name of the class corresponding to this type. This - * method must not be used on method types. - * - * @return the binary name of the class corresponding to this type. - */ - public String getClassName() { - switch (sort) { - case VOID: - return "void"; - case BOOLEAN: - return "boolean"; - case CHAR: - return "char"; - case BYTE: - return "byte"; - case SHORT: - return "short"; - case INT: - return "int"; - case FLOAT: - return "float"; - case LONG: - return "long"; - case DOUBLE: - return "double"; - case ARRAY: - StringBuilder sb = new StringBuilder(getElementType().getClassName()); - for (int i = getDimensions(); i > 0; --i) { - sb.append("[]"); - } - return sb.toString(); - case OBJECT: - return new String(buf, off, len).replace('/', '.'); - default: - return null; - } - } - - /** - * Returns the internal name of the class corresponding to this object or - * array type. The internal name of a class is its fully qualified name (as - * returned by Class.getName(), where '.' are replaced by '/'. This method - * should only be used for an object or array type. - * - * @return the internal name of the class corresponding to this object type. - */ - public String getInternalName() { - return new String(buf, off, len); - } - - /** - * Returns the argument types of methods of this type. This method should - * only be used for method types. - * - * @return the argument types of methods of this type. - */ - public Type[] getArgumentTypes() { - return getArgumentTypes(getDescriptor()); - } - - /** - * Returns the return type of methods of this type. This method should only - * be used for method types. - * - * @return the return type of methods of this type. - */ - public Type getReturnType() { - return getReturnType(getDescriptor()); - } - - /** - * Returns the size of the arguments and of the return value of methods of - * this type. This method should only be used for method types. - * - * @return the size of the arguments (plus one for the implicit this - * argument), argSize, and the size of the return value, retSize, - * packed into a single - * int i = (argSize << 2) | retSize - * (argSize is therefore equal to i >> 2, - * and retSize to i & 0x03). - */ - public int getArgumentsAndReturnSizes() { - return getArgumentsAndReturnSizes(getDescriptor()); - } - - // ------------------------------------------------------------------------ - // Conversion to type descriptors - // ------------------------------------------------------------------------ - - /** - * Returns the descriptor corresponding to this Java type. - * - * @return the descriptor corresponding to this Java type. - */ - public String getDescriptor() { - StringBuffer buf = new StringBuffer(); - getDescriptor(buf); - return buf.toString(); - } - - /** - * Returns the descriptor corresponding to the given argument and return - * types. - * - * @param returnType - * the return type of the method. - * @param argumentTypes - * the argument types of the method. - * @return the descriptor corresponding to the given argument and return - * types. - */ - public static String getMethodDescriptor(final Type returnType, - final Type... argumentTypes) { - StringBuffer buf = new StringBuffer(); - buf.append('('); - for (int i = 0; i < argumentTypes.length; ++i) { - argumentTypes[i].getDescriptor(buf); - } - buf.append(')'); - returnType.getDescriptor(buf); - return buf.toString(); - } - - /** - * Appends the descriptor corresponding to this Java type to the given - * string buffer. - * - * @param buf - * the string buffer to which the descriptor must be appended. - */ - private void getDescriptor(final StringBuffer buf) { - if (this.buf == null) { - // descriptor is in byte 3 of 'off' for primitive types (buf == - // null) - buf.append((char) ((off & 0xFF000000) >>> 24)); - } else if (sort == OBJECT) { - buf.append('L'); - buf.append(this.buf, off, len); - buf.append(';'); - } else { // sort == ARRAY || sort == METHOD - buf.append(this.buf, off, len); - } - } - - // ------------------------------------------------------------------------ - // Direct conversion from classes to type descriptors, - // without intermediate Type objects - // ------------------------------------------------------------------------ - - /** - * Returns the internal name of the given class. The internal name of a - * class is its fully qualified name, as returned by Class.getName(), where - * '.' are replaced by '/'. - * - * @param c - * an object or array class. - * @return the internal name of the given class. - */ - public static String getInternalName(final Class c) { - return c.getName().replace('.', '/'); - } - - /** - * Returns the descriptor corresponding to the given Java type. - * - * @param c - * an object class, a primitive class or an array class. - * @return the descriptor corresponding to the given class. - */ - public static String getDescriptor(final Class c) { - StringBuffer buf = new StringBuffer(); - getDescriptor(buf, c); - return buf.toString(); - } - - /** - * Returns the descriptor corresponding to the given constructor. - * - * @param c - * a {@link Constructor Constructor} object. - * @return the descriptor of the given constructor. - */ - public static String getConstructorDescriptor(final Constructor c) { - Class[] parameters = c.getParameterTypes(); - StringBuffer buf = new StringBuffer(); - buf.append('('); - for (int i = 0; i < parameters.length; ++i) { - getDescriptor(buf, parameters[i]); - } - return buf.append(")V").toString(); - } - - /** - * Returns the descriptor corresponding to the given method. - * - * @param m - * a {@link Method Method} object. - * @return the descriptor of the given method. - */ - public static String getMethodDescriptor(final Method m) { - Class[] parameters = m.getParameterTypes(); - StringBuffer buf = new StringBuffer(); - buf.append('('); - for (int i = 0; i < parameters.length; ++i) { - getDescriptor(buf, parameters[i]); - } - buf.append(')'); - getDescriptor(buf, m.getReturnType()); - return buf.toString(); - } - - /** - * Appends the descriptor of the given class to the given string buffer. - * - * @param buf - * the string buffer to which the descriptor must be appended. - * @param c - * the class whose descriptor must be computed. - */ - private static void getDescriptor(final StringBuffer buf, final Class c) { - Class d = c; - while (true) { - if (d.isPrimitive()) { - char car; - if (d == Integer.TYPE) { - car = 'I'; - } else if (d == Void.TYPE) { - car = 'V'; - } else if (d == Boolean.TYPE) { - car = 'Z'; - } else if (d == Byte.TYPE) { - car = 'B'; - } else if (d == Character.TYPE) { - car = 'C'; - } else if (d == Short.TYPE) { - car = 'S'; - } else if (d == Double.TYPE) { - car = 'D'; - } else if (d == Float.TYPE) { - car = 'F'; - } else /* if (d == Long.TYPE) */{ - car = 'J'; - } - buf.append(car); - return; - } else if (d.isArray()) { - buf.append('['); - d = d.getComponentType(); - } else { - buf.append('L'); - String name = d.getName(); - int len = name.length(); - for (int i = 0; i < len; ++i) { - char car = name.charAt(i); - buf.append(car == '.' ? '/' : car); - } - buf.append(';'); - return; - } - } - } - - // ------------------------------------------------------------------------ - // Corresponding size and opcodes - // ------------------------------------------------------------------------ - - /** - * Returns the size of values of this type. This method must not be used for - * method types. - * - * @return the size of values of this type, i.e., 2 for long and - * double, 0 for void and 1 otherwise. - */ - public int getSize() { - // the size is in byte 0 of 'off' for primitive types (buf == null) - return buf == null ? (off & 0xFF) : 1; - } - - /** - * Returns a JVM instruction opcode adapted to this Java type. This method - * must not be used for method types. - * - * @param opcode - * a JVM instruction opcode. This opcode must be one of ILOAD, - * ISTORE, IALOAD, IASTORE, IADD, ISUB, IMUL, IDIV, IREM, INEG, - * ISHL, ISHR, IUSHR, IAND, IOR, IXOR and IRETURN. - * @return an opcode that is similar to the given opcode, but adapted to - * this Java type. For example, if this type is float and - * opcode is IRETURN, this method returns FRETURN. - */ - public int getOpcode(final int opcode) { - if (opcode == Opcodes.IALOAD || opcode == Opcodes.IASTORE) { - // the offset for IALOAD or IASTORE is in byte 1 of 'off' for - // primitive types (buf == null) - return opcode + (buf == null ? (off & 0xFF00) >> 8 : 4); - } else { - // the offset for other instructions is in byte 2 of 'off' for - // primitive types (buf == null) - return opcode + (buf == null ? (off & 0xFF0000) >> 16 : 4); - } - } - - // ------------------------------------------------------------------------ - // Equals, hashCode and toString - // ------------------------------------------------------------------------ - - /** - * Tests if the given object is equal to this type. - * - * @param o - * the object to be compared to this type. - * @return true if the given object is equal to this type. - */ - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (!(o instanceof Type)) { - return false; - } - Type t = (Type) o; - if (sort != t.sort) { - return false; - } - if (sort >= ARRAY) { - if (len != t.len) { - return false; - } - for (int i = off, j = t.off, end = i + len; i < end; i++, j++) { - if (buf[i] != t.buf[j]) { - return false; - } - } - } - return true; - } - - /** - * Returns a hash code value for this type. - * - * @return a hash code value for this type. - */ - @Override - public int hashCode() { - int hc = 13 * sort; - if (sort >= ARRAY) { - for (int i = off, end = i + len; i < end; i++) { - hc = 17 * (hc + buf[i]); - } - } - return hc; - } - - /** - * Returns a string representation of this type. - * - * @return the descriptor of this type. - */ - @Override - public String toString() { - return getDescriptor(); - } -} diff --git a/src/asm/scala/tools/asm/TypePath.java b/src/asm/scala/tools/asm/TypePath.java deleted file mode 100644 index d4c6f0d857..0000000000 --- a/src/asm/scala/tools/asm/TypePath.java +++ /dev/null @@ -1,193 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2013 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -package scala.tools.asm; - -/** - * The path to a type argument, wildcard bound, array element type, or static - * inner type within an enclosing type. - * - * @author Eric Bruneton - */ -public class TypePath { - - /** - * A type path step that steps into the element type of an array type. See - * {@link #getStep getStep}. - */ - public final static int ARRAY_ELEMENT = 0; - - /** - * A type path step that steps into the nested type of a class type. See - * {@link #getStep getStep}. - */ - public final static int INNER_TYPE = 1; - - /** - * A type path step that steps into the bound of a wildcard type. See - * {@link #getStep getStep}. - */ - public final static int WILDCARD_BOUND = 2; - - /** - * A type path step that steps into a type argument of a generic type. See - * {@link #getStep getStep}. - */ - public final static int TYPE_ARGUMENT = 3; - - /** - * The byte array where the path is stored, in Java class file format. - */ - byte[] b; - - /** - * The offset of the first byte of the type path in 'b'. - */ - int offset; - - /** - * Creates a new type path. - * - * @param b - * the byte array containing the type path in Java class file - * format. - * @param offset - * the offset of the first byte of the type path in 'b'. - */ - TypePath(byte[] b, int offset) { - this.b = b; - this.offset = offset; - } - - /** - * Returns the length of this path. - * - * @return the length of this path. - */ - public int getLength() { - return b[offset]; - } - - /** - * Returns the value of the given step of this path. - * - * @param index - * an index between 0 and {@link #getLength()}, exclusive. - * @return {@link #ARRAY_ELEMENT ARRAY_ELEMENT}, {@link #INNER_TYPE - * INNER_TYPE}, {@link #WILDCARD_BOUND WILDCARD_BOUND}, or - * {@link #TYPE_ARGUMENT TYPE_ARGUMENT}. - */ - public int getStep(int index) { - return b[offset + 2 * index + 1]; - } - - /** - * Returns the index of the type argument that the given step is stepping - * into. This method should only be used for steps whose value is - * {@link #TYPE_ARGUMENT TYPE_ARGUMENT}. - * - * @param index - * an index between 0 and {@link #getLength()}, exclusive. - * @return the index of the type argument that the given step is stepping - * into. - */ - public int getStepArgument(int index) { - return b[offset + 2 * index + 2]; - } - - /** - * Converts a type path in string form, in the format used by - * {@link #toString()}, into a TypePath object. - * - * @param typePath - * a type path in string form, in the format used by - * {@link #toString()}. May be null or empty. - * @return the corresponding TypePath object, or null if the path is empty. - */ - public static TypePath fromString(final String typePath) { - if (typePath == null || typePath.length() == 0) { - return null; - } - int n = typePath.length(); - ByteVector out = new ByteVector(n); - out.putByte(0); - for (int i = 0; i < n;) { - char c = typePath.charAt(i++); - if (c == '[') { - out.put11(ARRAY_ELEMENT, 0); - } else if (c == '.') { - out.put11(INNER_TYPE, 0); - } else if (c == '*') { - out.put11(WILDCARD_BOUND, 0); - } else if (c >= '0' && c <= '9') { - int typeArg = c - '0'; - while (i < n && (c = typePath.charAt(i)) >= '0' && c <= '9') { - typeArg = typeArg * 10 + c - '0'; - i += 1; - } - out.put11(TYPE_ARGUMENT, typeArg); - } - } - out.data[0] = (byte) (out.length / 2); - return new TypePath(out.data, 0); - } - - /** - * Returns a string representation of this type path. {@link #ARRAY_ELEMENT - * ARRAY_ELEMENT} steps are represented with '[', {@link #INNER_TYPE - * INNER_TYPE} steps with '.', {@link #WILDCARD_BOUND WILDCARD_BOUND} steps - * with '*' and {@link #TYPE_ARGUMENT TYPE_ARGUMENT} steps with their type - * argument index in decimal form. - */ - @Override - public String toString() { - int length = getLength(); - StringBuilder result = new StringBuilder(length * 2); - for (int i = 0; i < length; ++i) { - switch (getStep(i)) { - case ARRAY_ELEMENT: - result.append('['); - break; - case INNER_TYPE: - result.append('.'); - break; - case WILDCARD_BOUND: - result.append('*'); - break; - case TYPE_ARGUMENT: - result.append(getStepArgument(i)); - break; - default: - result.append('_'); - } - } - return result.toString(); - } -} diff --git a/src/asm/scala/tools/asm/TypeReference.java b/src/asm/scala/tools/asm/TypeReference.java deleted file mode 100644 index 118b0f6529..0000000000 --- a/src/asm/scala/tools/asm/TypeReference.java +++ /dev/null @@ -1,452 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2013 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -package scala.tools.asm; - -/** - * A reference to a type appearing in a class, field or method declaration, or - * on an instruction. Such a reference designates the part of the class where - * the referenced type is appearing (e.g. an 'extends', 'implements' or 'throws' - * clause, a 'new' instruction, a 'catch' clause, a type cast, a local variable - * declaration, etc). - * - * @author Eric Bruneton - */ -public class TypeReference { - - /** - * The sort of type references that target a type parameter of a generic - * class. See {@link #getSort getSort}. - */ - public final static int CLASS_TYPE_PARAMETER = 0x00; - - /** - * The sort of type references that target a type parameter of a generic - * method. See {@link #getSort getSort}. - */ - public final static int METHOD_TYPE_PARAMETER = 0x01; - - /** - * The sort of type references that target the super class of a class or one - * of the interfaces it implements. See {@link #getSort getSort}. - */ - public final static int CLASS_EXTENDS = 0x10; - - /** - * The sort of type references that target a bound of a type parameter of a - * generic class. See {@link #getSort getSort}. - */ - public final static int CLASS_TYPE_PARAMETER_BOUND = 0x11; - - /** - * The sort of type references that target a bound of a type parameter of a - * generic method. See {@link #getSort getSort}. - */ - public final static int METHOD_TYPE_PARAMETER_BOUND = 0x12; - - /** - * The sort of type references that target the type of a field. See - * {@link #getSort getSort}. - */ - public final static int FIELD = 0x13; - - /** - * The sort of type references that target the return type of a method. See - * {@link #getSort getSort}. - */ - public final static int METHOD_RETURN = 0x14; - - /** - * The sort of type references that target the receiver type of a method. - * See {@link #getSort getSort}. - */ - public final static int METHOD_RECEIVER = 0x15; - - /** - * The sort of type references that target the type of a formal parameter of - * a method. See {@link #getSort getSort}. - */ - public final static int METHOD_FORMAL_PARAMETER = 0x16; - - /** - * The sort of type references that target the type of an exception declared - * in the throws clause of a method. See {@link #getSort getSort}. - */ - public final static int THROWS = 0x17; - - /** - * The sort of type references that target the type of a local variable in a - * method. See {@link #getSort getSort}. - */ - public final static int LOCAL_VARIABLE = 0x40; - - /** - * The sort of type references that target the type of a resource variable - * in a method. See {@link #getSort getSort}. - */ - public final static int RESOURCE_VARIABLE = 0x41; - - /** - * The sort of type references that target the type of the exception of a - * 'catch' clause in a method. See {@link #getSort getSort}. - */ - public final static int EXCEPTION_PARAMETER = 0x42; - - /** - * The sort of type references that target the type declared in an - * 'instanceof' instruction. See {@link #getSort getSort}. - */ - public final static int INSTANCEOF = 0x43; - - /** - * The sort of type references that target the type of the object created by - * a 'new' instruction. See {@link #getSort getSort}. - */ - public final static int NEW = 0x44; - - /** - * The sort of type references that target the receiver type of a - * constructor reference. See {@link #getSort getSort}. - */ - public final static int CONSTRUCTOR_REFERENCE = 0x45; - - /** - * The sort of type references that target the receiver type of a method - * reference. See {@link #getSort getSort}. - */ - public final static int METHOD_REFERENCE = 0x46; - - /** - * The sort of type references that target the type declared in an explicit - * or implicit cast instruction. See {@link #getSort getSort}. - */ - public final static int CAST = 0x47; - - /** - * The sort of type references that target a type parameter of a generic - * constructor in a constructor call. See {@link #getSort getSort}. - */ - public final static int CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = 0x48; - - /** - * The sort of type references that target a type parameter of a generic - * method in a method call. See {@link #getSort getSort}. - */ - public final static int METHOD_INVOCATION_TYPE_ARGUMENT = 0x49; - - /** - * The sort of type references that target a type parameter of a generic - * constructor in a constructor reference. See {@link #getSort getSort}. - */ - public final static int CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = 0x4A; - - /** - * The sort of type references that target a type parameter of a generic - * method in a method reference. See {@link #getSort getSort}. - */ - public final static int METHOD_REFERENCE_TYPE_ARGUMENT = 0x4B; - - /** - * The type reference value in Java class file format. - */ - private int value; - - /** - * Creates a new TypeReference. - * - * @param typeRef - * the int encoded value of the type reference, as received in a - * visit method related to type annotations, like - * visitTypeAnnotation. - */ - public TypeReference(int typeRef) { - this.value = typeRef; - } - - /** - * Returns a type reference of the given sort. - * - * @param sort - * {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN}, - * {@link #METHOD_RECEIVER METHOD_RECEIVER}, - * {@link #LOCAL_VARIABLE LOCAL_VARIABLE}, - * {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE}, - * {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW}, - * {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, or - * {@link #METHOD_REFERENCE METHOD_REFERENCE}. - * @return a type reference of the given sort. - */ - public static TypeReference newTypeReference(int sort) { - return new TypeReference(sort << 24); - } - - /** - * Returns a reference to a type parameter of a generic class or method. - * - * @param sort - * {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or - * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}. - * @param paramIndex - * the type parameter index. - * @return a reference to the given generic class or method type parameter. - */ - public static TypeReference newTypeParameterReference(int sort, - int paramIndex) { - return new TypeReference((sort << 24) | (paramIndex << 16)); - } - - /** - * Returns a reference to a type parameter bound of a generic class or - * method. - * - * @param sort - * {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER} or - * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}. - * @param paramIndex - * the type parameter index. - * @param boundIndex - * the type bound index within the above type parameters. - * @return a reference to the given generic class or method type parameter - * bound. - */ - public static TypeReference newTypeParameterBoundReference(int sort, - int paramIndex, int boundIndex) { - return new TypeReference((sort << 24) | (paramIndex << 16) - | (boundIndex << 8)); - } - - /** - * Returns a reference to the super class or to an interface of the - * 'implements' clause of a class. - * - * @param itfIndex - * the index of an interface in the 'implements' clause of a - * class, or -1 to reference the super class of the class. - * @return a reference to the given super type of a class. - */ - public static TypeReference newSuperTypeReference(int itfIndex) { - itfIndex &= 0xFFFF; - return new TypeReference((CLASS_EXTENDS << 24) | (itfIndex << 8)); - } - - /** - * Returns a reference to the type of a formal parameter of a method. - * - * @param paramIndex - * the formal parameter index. - * - * @return a reference to the type of the given method formal parameter. - */ - public static TypeReference newFormalParameterReference(int paramIndex) { - return new TypeReference((METHOD_FORMAL_PARAMETER << 24) - | (paramIndex << 16)); - } - - /** - * Returns a reference to the type of an exception, in a 'throws' clause of - * a method. - * - * @param exceptionIndex - * the index of an exception in a 'throws' clause of a method. - * - * @return a reference to the type of the given exception. - */ - public static TypeReference newExceptionReference(int exceptionIndex) { - return new TypeReference((THROWS << 24) | (exceptionIndex << 8)); - } - - /** - * Returns a reference to the type of the exception declared in a 'catch' - * clause of a method. - * - * @param tryCatchBlockIndex - * the index of a try catch block (using the order in which they - * are visited with visitTryCatchBlock). - * - * @return a reference to the type of the given exception. - */ - public static TypeReference newTryCatchReference(int tryCatchBlockIndex) { - return new TypeReference((EXCEPTION_PARAMETER << 24) - | (tryCatchBlockIndex << 8)); - } - - /** - * Returns a reference to the type of a type argument in a constructor or - * method call or reference. - * - * @param sort - * {@link #CAST CAST}, - * {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT - * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, - * {@link #METHOD_INVOCATION_TYPE_ARGUMENT - * METHOD_INVOCATION_TYPE_ARGUMENT}, - * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT - * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or - * {@link #METHOD_REFERENCE_TYPE_ARGUMENT - * METHOD_REFERENCE_TYPE_ARGUMENT}. - * @param argIndex - * the type argument index. - * - * @return a reference to the type of the given type argument. - */ - public static TypeReference newTypeArgumentReference(int sort, int argIndex) { - return new TypeReference((sort << 24) | argIndex); - } - - /** - * Returns the sort of this type reference. - * - * @return {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER}, - * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}, - * {@link #CLASS_EXTENDS CLASS_EXTENDS}, - * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND}, - * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}, - * {@link #FIELD FIELD}, {@link #METHOD_RETURN METHOD_RETURN}, - * {@link #METHOD_RECEIVER METHOD_RECEIVER}, - * {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER}, - * {@link #THROWS THROWS}, {@link #LOCAL_VARIABLE LOCAL_VARIABLE}, - * {@link #RESOURCE_VARIABLE RESOURCE_VARIABLE}, - * {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER}, - * {@link #INSTANCEOF INSTANCEOF}, {@link #NEW NEW}, - * {@link #CONSTRUCTOR_REFERENCE CONSTRUCTOR_REFERENCE}, - * {@link #METHOD_REFERENCE METHOD_REFERENCE}, {@link #CAST CAST}, - * {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT - * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, - * {@link #METHOD_INVOCATION_TYPE_ARGUMENT - * METHOD_INVOCATION_TYPE_ARGUMENT}, - * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT - * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or - * {@link #METHOD_REFERENCE_TYPE_ARGUMENT - * METHOD_REFERENCE_TYPE_ARGUMENT}. - */ - public int getSort() { - return value >>> 24; - } - - /** - * Returns the index of the type parameter referenced by this type - * reference. This method must only be used for type references whose sort - * is {@link #CLASS_TYPE_PARAMETER CLASS_TYPE_PARAMETER}, - * {@link #METHOD_TYPE_PARAMETER METHOD_TYPE_PARAMETER}, - * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or - * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}. - * - * @return a type parameter index. - */ - public int getTypeParameterIndex() { - return (value & 0x00FF0000) >> 16; - } - - /** - * Returns the index of the type parameter bound, within the type parameter - * {@link #getTypeParameterIndex}, referenced by this type reference. This - * method must only be used for type references whose sort is - * {@link #CLASS_TYPE_PARAMETER_BOUND CLASS_TYPE_PARAMETER_BOUND} or - * {@link #METHOD_TYPE_PARAMETER_BOUND METHOD_TYPE_PARAMETER_BOUND}. - * - * @return a type parameter bound index. - */ - public int getTypeParameterBoundIndex() { - return (value & 0x0000FF00) >> 8; - } - - /** - * Returns the index of the "super type" of a class that is referenced by - * this type reference. This method must only be used for type references - * whose sort is {@link #CLASS_EXTENDS CLASS_EXTENDS}. - * - * @return the index of an interface in the 'implements' clause of a class, - * or -1 if this type reference references the type of the super - * class. - */ - public int getSuperTypeIndex() { - return (short) ((value & 0x00FFFF00) >> 8); - } - - /** - * Returns the index of the formal parameter whose type is referenced by - * this type reference. This method must only be used for type references - * whose sort is {@link #METHOD_FORMAL_PARAMETER METHOD_FORMAL_PARAMETER}. - * - * @return a formal parameter index. - */ - public int getFormalParameterIndex() { - return (value & 0x00FF0000) >> 16; - } - - /** - * Returns the index of the exception, in a 'throws' clause of a method, - * whose type is referenced by this type reference. This method must only be - * used for type references whose sort is {@link #THROWS THROWS}. - * - * @return the index of an exception in the 'throws' clause of a method. - */ - public int getExceptionIndex() { - return (value & 0x00FFFF00) >> 8; - } - - /** - * Returns the index of the try catch block (using the order in which they - * are visited with visitTryCatchBlock), whose 'catch' type is referenced by - * this type reference. This method must only be used for type references - * whose sort is {@link #EXCEPTION_PARAMETER EXCEPTION_PARAMETER} . - * - * @return the index of an exception in the 'throws' clause of a method. - */ - public int getTryCatchBlockIndex() { - return (value & 0x00FFFF00) >> 8; - } - - /** - * Returns the index of the type argument referenced by this type reference. - * This method must only be used for type references whose sort is - * {@link #CAST CAST}, {@link #CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT - * CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, - * {@link #METHOD_INVOCATION_TYPE_ARGUMENT METHOD_INVOCATION_TYPE_ARGUMENT}, - * {@link #CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT - * CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or - * {@link #METHOD_REFERENCE_TYPE_ARGUMENT METHOD_REFERENCE_TYPE_ARGUMENT}. - * - * @return a type parameter index. - */ - public int getTypeArgumentIndex() { - return value & 0xFF; - } - - /** - * Returns the int encoded value of this type reference, suitable for use in - * visit methods related to type annotations, like visitTypeAnnotation. - * - * @return the int encoded value of this type reference. - */ - public int getValue() { - return value; - } -} diff --git a/src/asm/scala/tools/asm/commons/CodeSizeEvaluator.java b/src/asm/scala/tools/asm/commons/CodeSizeEvaluator.java deleted file mode 100644 index 80c07bdae0..0000000000 --- a/src/asm/scala/tools/asm/commons/CodeSizeEvaluator.java +++ /dev/null @@ -1,238 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.commons; - -import scala.tools.asm.Handle; -import scala.tools.asm.Label; -import scala.tools.asm.MethodVisitor; -import scala.tools.asm.Opcodes; - -/** - * A {@link MethodVisitor} that can be used to approximate method size. - * - * @author Eugene Kuleshov - */ -public class CodeSizeEvaluator extends MethodVisitor implements Opcodes { - - private int minSize; - - private int maxSize; - - public CodeSizeEvaluator(final MethodVisitor mv) { - this(Opcodes.ASM5, mv); - } - - protected CodeSizeEvaluator(final int api, final MethodVisitor mv) { - super(api, mv); - } - - public int getMinSize() { - return this.minSize; - } - - public int getMaxSize() { - return this.maxSize; - } - - @Override - public void visitInsn(final int opcode) { - minSize += 1; - maxSize += 1; - if (mv != null) { - mv.visitInsn(opcode); - } - } - - @Override - public void visitIntInsn(final int opcode, final int operand) { - if (opcode == SIPUSH) { - minSize += 3; - maxSize += 3; - } else { - minSize += 2; - maxSize += 2; - } - if (mv != null) { - mv.visitIntInsn(opcode, operand); - } - } - - @Override - public void visitVarInsn(final int opcode, final int var) { - if (var < 4 && opcode != RET) { - minSize += 1; - maxSize += 1; - } else if (var >= 256) { - minSize += 4; - maxSize += 4; - } else { - minSize += 2; - maxSize += 2; - } - if (mv != null) { - mv.visitVarInsn(opcode, var); - } - } - - @Override - public void visitTypeInsn(final int opcode, final String type) { - minSize += 3; - maxSize += 3; - if (mv != null) { - mv.visitTypeInsn(opcode, type); - } - } - - @Override - public void visitFieldInsn(final int opcode, final String owner, - final String name, final String desc) { - minSize += 3; - maxSize += 3; - if (mv != null) { - mv.visitFieldInsn(opcode, owner, name, desc); - } - } - - @Deprecated - @Override - public void visitMethodInsn(final int opcode, final String owner, - final String name, final String desc) { - if (api >= Opcodes.ASM5) { - super.visitMethodInsn(opcode, owner, name, desc); - return; - } - doVisitMethodInsn(opcode, owner, name, desc, - opcode == Opcodes.INVOKEINTERFACE); - } - - @Override - public void visitMethodInsn(final int opcode, final String owner, - final String name, final String desc, final boolean itf) { - if (api < Opcodes.ASM5) { - super.visitMethodInsn(opcode, owner, name, desc, itf); - return; - } - doVisitMethodInsn(opcode, owner, name, desc, itf); - } - - private void doVisitMethodInsn(int opcode, final String owner, - final String name, final String desc, final boolean itf) { - if (opcode == INVOKEINTERFACE) { - minSize += 5; - maxSize += 5; - } else { - minSize += 3; - maxSize += 3; - } - if (mv != null) { - mv.visitMethodInsn(opcode, owner, name, desc, itf); - } - } - - @Override - public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, - Object... bsmArgs) { - minSize += 5; - maxSize += 5; - if (mv != null) { - mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); - } - } - - @Override - public void visitJumpInsn(final int opcode, final Label label) { - minSize += 3; - if (opcode == GOTO || opcode == JSR) { - maxSize += 5; - } else { - maxSize += 8; - } - if (mv != null) { - mv.visitJumpInsn(opcode, label); - } - } - - @Override - public void visitLdcInsn(final Object cst) { - if (cst instanceof Long || cst instanceof Double) { - minSize += 3; - maxSize += 3; - } else { - minSize += 2; - maxSize += 3; - } - if (mv != null) { - mv.visitLdcInsn(cst); - } - } - - @Override - public void visitIincInsn(final int var, final int increment) { - if (var > 255 || increment > 127 || increment < -128) { - minSize += 6; - maxSize += 6; - } else { - minSize += 3; - maxSize += 3; - } - if (mv != null) { - mv.visitIincInsn(var, increment); - } - } - - @Override - public void visitTableSwitchInsn(final int min, final int max, - final Label dflt, final Label... labels) { - minSize += 13 + labels.length * 4; - maxSize += 16 + labels.length * 4; - if (mv != null) { - mv.visitTableSwitchInsn(min, max, dflt, labels); - } - } - - @Override - public void visitLookupSwitchInsn(final Label dflt, final int[] keys, - final Label[] labels) { - minSize += 9 + keys.length * 8; - maxSize += 12 + keys.length * 8; - if (mv != null) { - mv.visitLookupSwitchInsn(dflt, keys, labels); - } - } - - @Override - public void visitMultiANewArrayInsn(final String desc, final int dims) { - minSize += 4; - maxSize += 4; - if (mv != null) { - mv.visitMultiANewArrayInsn(desc, dims); - } - } -} diff --git a/src/asm/scala/tools/asm/signature/SignatureReader.java b/src/asm/scala/tools/asm/signature/SignatureReader.java deleted file mode 100644 index 9c7c3880d9..0000000000 --- a/src/asm/scala/tools/asm/signature/SignatureReader.java +++ /dev/null @@ -1,228 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.signature; - -/** - * A type signature parser to make a signature visitor visit an existing - * signature. - * - * @author Thomas Hallgren - * @author Eric Bruneton - */ -public class SignatureReader { - - /** - * The signature to be read. - */ - private final String signature; - - /** - * Constructs a {@link SignatureReader} for the given signature. - * - * @param signature - * A ClassSignature, MethodTypeSignature, or - * FieldTypeSignature. - */ - public SignatureReader(final String signature) { - this.signature = signature; - } - - /** - * Makes the given visitor visit the signature of this - * {@link SignatureReader}. This signature is the one specified in the - * constructor (see {@link #SignatureReader(String) SignatureReader}). This - * method is intended to be called on a {@link SignatureReader} that was - * created using a ClassSignature (such as the signature - * parameter of the {@link scala.tools.asm.ClassVisitor#visit - * ClassVisitor.visit} method) or a MethodTypeSignature (such as the - * signature parameter of the - * {@link scala.tools.asm.ClassVisitor#visitMethod - * ClassVisitor.visitMethod} method). - * - * @param v - * the visitor that must visit this signature. - */ - public void accept(final SignatureVisitor v) { - String signature = this.signature; - int len = signature.length(); - int pos; - char c; - - if (signature.charAt(0) == '<') { - pos = 2; - do { - int end = signature.indexOf(':', pos); - v.visitFormalTypeParameter(signature.substring(pos - 1, end)); - pos = end + 1; - - c = signature.charAt(pos); - if (c == 'L' || c == '[' || c == 'T') { - pos = parseType(signature, pos, v.visitClassBound()); - } - - while ((c = signature.charAt(pos++)) == ':') { - pos = parseType(signature, pos, v.visitInterfaceBound()); - } - } while (c != '>'); - } else { - pos = 0; - } - - if (signature.charAt(pos) == '(') { - pos++; - while (signature.charAt(pos) != ')') { - pos = parseType(signature, pos, v.visitParameterType()); - } - pos = parseType(signature, pos + 1, v.visitReturnType()); - while (pos < len) { - pos = parseType(signature, pos + 1, v.visitExceptionType()); - } - } else { - pos = parseType(signature, pos, v.visitSuperclass()); - while (pos < len) { - pos = parseType(signature, pos, v.visitInterface()); - } - } - } - - /** - * Makes the given visitor visit the signature of this - * {@link SignatureReader}. This signature is the one specified in the - * constructor (see {@link #SignatureReader(String) SignatureReader}). This - * method is intended to be called on a {@link SignatureReader} that was - * created using a FieldTypeSignature, such as the - * signature parameter of the - * {@link scala.tools.asm.ClassVisitor#visitField ClassVisitor.visitField} - * or {@link scala.tools.asm.MethodVisitor#visitLocalVariable - * MethodVisitor.visitLocalVariable} methods. - * - * @param v - * the visitor that must visit this signature. - */ - public void acceptType(final SignatureVisitor v) { - parseType(this.signature, 0, v); - } - - /** - * Parses a field type signature and makes the given visitor visit it. - * - * @param signature - * a string containing the signature that must be parsed. - * @param pos - * index of the first character of the signature to parsed. - * @param v - * the visitor that must visit this signature. - * @return the index of the first character after the parsed signature. - */ - private static int parseType(final String signature, int pos, - final SignatureVisitor v) { - char c; - int start, end; - boolean visited, inner; - String name; - - switch (c = signature.charAt(pos++)) { - case 'Z': - case 'C': - case 'B': - case 'S': - case 'I': - case 'F': - case 'J': - case 'D': - case 'V': - v.visitBaseType(c); - return pos; - - case '[': - return parseType(signature, pos, v.visitArrayType()); - - case 'T': - end = signature.indexOf(';', pos); - v.visitTypeVariable(signature.substring(pos, end)); - return end + 1; - - default: // case 'L': - start = pos; - visited = false; - inner = false; - for (;;) { - switch (c = signature.charAt(pos++)) { - case '.': - case ';': - if (!visited) { - name = signature.substring(start, pos - 1); - if (inner) { - v.visitInnerClassType(name); - } else { - v.visitClassType(name); - } - } - if (c == ';') { - v.visitEnd(); - return pos; - } - start = pos; - visited = false; - inner = true; - break; - - case '<': - name = signature.substring(start, pos - 1); - if (inner) { - v.visitInnerClassType(name); - } else { - v.visitClassType(name); - } - visited = true; - top: for (;;) { - switch (c = signature.charAt(pos)) { - case '>': - break top; - case '*': - ++pos; - v.visitTypeArgument(); - break; - case '+': - case '-': - pos = parseType(signature, pos + 1, - v.visitTypeArgument(c)); - break; - default: - pos = parseType(signature, pos, - v.visitTypeArgument('=')); - break; - } - } - } - } - } - } -} diff --git a/src/asm/scala/tools/asm/signature/SignatureVisitor.java b/src/asm/scala/tools/asm/signature/SignatureVisitor.java deleted file mode 100644 index 1e16bd3f7c..0000000000 --- a/src/asm/scala/tools/asm/signature/SignatureVisitor.java +++ /dev/null @@ -1,238 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.signature; - -import scala.tools.asm.Opcodes; - -/** - * A visitor to visit a generic signature. The methods of this interface must be - * called in one of the three following orders (the last one is the only valid - * order for a {@link SignatureVisitor} that is returned by a method of this - * interface): - *

    - *
  • ClassSignature = ( visitFormalTypeParameter - * visitClassBound? visitInterfaceBound* )* ( - * visitSuperClass visitInterface* )
  • - *
  • MethodSignature = ( visitFormalTypeParameter - * visitClassBound? visitInterfaceBound* )* ( - * visitParameterType* visitReturnType - * visitExceptionType* )
  • - *
  • TypeSignature = visitBaseType | - * visitTypeVariable | visitArrayType | ( - * visitClassType visitTypeArgument* ( - * visitInnerClassType visitTypeArgument* )* visitEnd - * ) )
  • - *
- * - * @author Thomas Hallgren - * @author Eric Bruneton - */ -public abstract class SignatureVisitor { - - /** - * Wildcard for an "extends" type argument. - */ - public final static char EXTENDS = '+'; - - /** - * Wildcard for a "super" type argument. - */ - public final static char SUPER = '-'; - - /** - * Wildcard for a normal type argument. - */ - public final static char INSTANCEOF = '='; - - /** - * The ASM API version implemented by this visitor. The value of this field - * must be one of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - protected final int api; - - /** - * Constructs a new {@link SignatureVisitor}. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - public SignatureVisitor(final int api) { - if (api != Opcodes.ASM4 && api != Opcodes.ASM5) { - throw new IllegalArgumentException(); - } - this.api = api; - } - - /** - * Visits a formal type parameter. - * - * @param name - * the name of the formal parameter. - */ - public void visitFormalTypeParameter(String name) { - } - - /** - * Visits the class bound of the last visited formal type parameter. - * - * @return a non null visitor to visit the signature of the class bound. - */ - public SignatureVisitor visitClassBound() { - return this; - } - - /** - * Visits an interface bound of the last visited formal type parameter. - * - * @return a non null visitor to visit the signature of the interface bound. - */ - public SignatureVisitor visitInterfaceBound() { - return this; - } - - /** - * Visits the type of the super class. - * - * @return a non null visitor to visit the signature of the super class - * type. - */ - public SignatureVisitor visitSuperclass() { - return this; - } - - /** - * Visits the type of an interface implemented by the class. - * - * @return a non null visitor to visit the signature of the interface type. - */ - public SignatureVisitor visitInterface() { - return this; - } - - /** - * Visits the type of a method parameter. - * - * @return a non null visitor to visit the signature of the parameter type. - */ - public SignatureVisitor visitParameterType() { - return this; - } - - /** - * Visits the return type of the method. - * - * @return a non null visitor to visit the signature of the return type. - */ - public SignatureVisitor visitReturnType() { - return this; - } - - /** - * Visits the type of a method exception. - * - * @return a non null visitor to visit the signature of the exception type. - */ - public SignatureVisitor visitExceptionType() { - return this; - } - - /** - * Visits a signature corresponding to a primitive type. - * - * @param descriptor - * the descriptor of the primitive type, or 'V' for void - * . - */ - public void visitBaseType(char descriptor) { - } - - /** - * Visits a signature corresponding to a type variable. - * - * @param name - * the name of the type variable. - */ - public void visitTypeVariable(String name) { - } - - /** - * Visits a signature corresponding to an array type. - * - * @return a non null visitor to visit the signature of the array element - * type. - */ - public SignatureVisitor visitArrayType() { - return this; - } - - /** - * Starts the visit of a signature corresponding to a class or interface - * type. - * - * @param name - * the internal name of the class or interface. - */ - public void visitClassType(String name) { - } - - /** - * Visits an inner class. - * - * @param name - * the local name of the inner class in its enclosing class. - */ - public void visitInnerClassType(String name) { - } - - /** - * Visits an unbounded type argument of the last visited class or inner - * class type. - */ - public void visitTypeArgument() { - } - - /** - * Visits a type argument of the last visited class or inner class type. - * - * @param wildcard - * '+', '-' or '='. - * @return a non null visitor to visit the signature of the type argument. - */ - public SignatureVisitor visitTypeArgument(char wildcard) { - return this; - } - - /** - * Ends the visit of a signature corresponding to a class or interface type. - */ - public void visitEnd() { - } -} diff --git a/src/asm/scala/tools/asm/signature/SignatureWriter.java b/src/asm/scala/tools/asm/signature/SignatureWriter.java deleted file mode 100644 index 65756eee51..0000000000 --- a/src/asm/scala/tools/asm/signature/SignatureWriter.java +++ /dev/null @@ -1,227 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.signature; - -import scala.tools.asm.Opcodes; - -/** - * A signature visitor that generates signatures in string format. - * - * @author Thomas Hallgren - * @author Eric Bruneton - */ -public class SignatureWriter extends SignatureVisitor { - - /** - * Buffer used to construct the signature. - */ - private final StringBuffer buf = new StringBuffer(); - - /** - * Indicates if the signature contains formal type parameters. - */ - private boolean hasFormals; - - /** - * Indicates if the signature contains method parameter types. - */ - private boolean hasParameters; - - /** - * Stack used to keep track of class types that have arguments. Each element - * of this stack is a boolean encoded in one bit. The top of the stack is - * the lowest order bit. Pushing false = *2, pushing true = *2+1, popping = - * /2. - */ - private int argumentStack; - - /** - * Constructs a new {@link SignatureWriter} object. - */ - public SignatureWriter() { - super(Opcodes.ASM5); - } - - // ------------------------------------------------------------------------ - // Implementation of the SignatureVisitor interface - // ------------------------------------------------------------------------ - - @Override - public void visitFormalTypeParameter(final String name) { - if (!hasFormals) { - hasFormals = true; - buf.append('<'); - } - buf.append(name); - buf.append(':'); - } - - @Override - public SignatureVisitor visitClassBound() { - return this; - } - - @Override - public SignatureVisitor visitInterfaceBound() { - buf.append(':'); - return this; - } - - @Override - public SignatureVisitor visitSuperclass() { - endFormals(); - return this; - } - - @Override - public SignatureVisitor visitInterface() { - return this; - } - - @Override - public SignatureVisitor visitParameterType() { - endFormals(); - if (!hasParameters) { - hasParameters = true; - buf.append('('); - } - return this; - } - - @Override - public SignatureVisitor visitReturnType() { - endFormals(); - if (!hasParameters) { - buf.append('('); - } - buf.append(')'); - return this; - } - - @Override - public SignatureVisitor visitExceptionType() { - buf.append('^'); - return this; - } - - @Override - public void visitBaseType(final char descriptor) { - buf.append(descriptor); - } - - @Override - public void visitTypeVariable(final String name) { - buf.append('T'); - buf.append(name); - buf.append(';'); - } - - @Override - public SignatureVisitor visitArrayType() { - buf.append('['); - return this; - } - - @Override - public void visitClassType(final String name) { - buf.append('L'); - buf.append(name); - argumentStack *= 2; - } - - @Override - public void visitInnerClassType(final String name) { - endArguments(); - buf.append('.'); - buf.append(name); - argumentStack *= 2; - } - - @Override - public void visitTypeArgument() { - if (argumentStack % 2 == 0) { - ++argumentStack; - buf.append('<'); - } - buf.append('*'); - } - - @Override - public SignatureVisitor visitTypeArgument(final char wildcard) { - if (argumentStack % 2 == 0) { - ++argumentStack; - buf.append('<'); - } - if (wildcard != '=') { - buf.append(wildcard); - } - return this; - } - - @Override - public void visitEnd() { - endArguments(); - buf.append(';'); - } - - /** - * Returns the signature that was built by this signature writer. - * - * @return the signature that was built by this signature writer. - */ - @Override - public String toString() { - return buf.toString(); - } - - // ------------------------------------------------------------------------ - // Utility methods - // ------------------------------------------------------------------------ - - /** - * Ends the formal type parameters section of the signature. - */ - private void endFormals() { - if (hasFormals) { - hasFormals = false; - buf.append('>'); - } - } - - /** - * Ends the type arguments of a class or inner class type. - */ - private void endArguments() { - if (argumentStack % 2 != 0) { - buf.append('>'); - } - argumentStack /= 2; - } -} diff --git a/src/asm/scala/tools/asm/tree/AbstractInsnNode.java b/src/asm/scala/tools/asm/tree/AbstractInsnNode.java deleted file mode 100644 index 2ce0c8b6ee..0000000000 --- a/src/asm/scala/tools/asm/tree/AbstractInsnNode.java +++ /dev/null @@ -1,326 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import scala.tools.asm.MethodVisitor; - -/** - * A node that represents a bytecode instruction. An instruction can appear - * at most once in at most one {@link InsnList} at a time. - * - * @author Eric Bruneton - */ -public abstract class AbstractInsnNode { - - /** - * The type of {@link InsnNode} instructions. - */ - public static final int INSN = 0; - - /** - * The type of {@link IntInsnNode} instructions. - */ - public static final int INT_INSN = 1; - - /** - * The type of {@link VarInsnNode} instructions. - */ - public static final int VAR_INSN = 2; - - /** - * The type of {@link TypeInsnNode} instructions. - */ - public static final int TYPE_INSN = 3; - - /** - * The type of {@link FieldInsnNode} instructions. - */ - public static final int FIELD_INSN = 4; - - /** - * The type of {@link MethodInsnNode} instructions. - */ - public static final int METHOD_INSN = 5; - - /** - * The type of {@link InvokeDynamicInsnNode} instructions. - */ - public static final int INVOKE_DYNAMIC_INSN = 6; - - /** - * The type of {@link JumpInsnNode} instructions. - */ - public static final int JUMP_INSN = 7; - - /** - * The type of {@link LabelNode} "instructions". - */ - public static final int LABEL = 8; - - /** - * The type of {@link LdcInsnNode} instructions. - */ - public static final int LDC_INSN = 9; - - /** - * The type of {@link IincInsnNode} instructions. - */ - public static final int IINC_INSN = 10; - - /** - * The type of {@link TableSwitchInsnNode} instructions. - */ - public static final int TABLESWITCH_INSN = 11; - - /** - * The type of {@link LookupSwitchInsnNode} instructions. - */ - public static final int LOOKUPSWITCH_INSN = 12; - - /** - * The type of {@link MultiANewArrayInsnNode} instructions. - */ - public static final int MULTIANEWARRAY_INSN = 13; - - /** - * The type of {@link FrameNode} "instructions". - */ - public static final int FRAME = 14; - - /** - * The type of {@link LineNumberNode} "instructions". - */ - public static final int LINE = 15; - - /** - * The opcode of this instruction. - */ - protected int opcode; - - /** - * The runtime visible type annotations of this instruction. This field is - * only used for real instructions (i.e. not for labels, frames, or line - * number nodes). This list is a list of {@link TypeAnnotationNode} objects. - * May be null. - * - * @associates scala.tools.asm.tree.TypeAnnotationNode - * @label visible - */ - public List visibleTypeAnnotations; - - /** - * The runtime invisible type annotations of this instruction. This field is - * only used for real instructions (i.e. not for labels, frames, or line - * number nodes). This list is a list of {@link TypeAnnotationNode} objects. - * May be null. - * - * @associates scala.tools.asm.tree.TypeAnnotationNode - * @label invisible - */ - public List invisibleTypeAnnotations; - - /** - * Previous instruction in the list to which this instruction belongs. - */ - AbstractInsnNode prev; - - /** - * Next instruction in the list to which this instruction belongs. - */ - AbstractInsnNode next; - - /** - * Index of this instruction in the list to which it belongs. The value of - * this field is correct only when {@link InsnList#cache} is not null. A - * value of -1 indicates that this instruction does not belong to any - * {@link InsnList}. - */ - int index; - - /** - * Constructs a new {@link AbstractInsnNode}. - * - * @param opcode - * the opcode of the instruction to be constructed. - */ - protected AbstractInsnNode(final int opcode) { - this.opcode = opcode; - this.index = -1; - } - - /** - * Returns the opcode of this instruction. - * - * @return the opcode of this instruction. - */ - public int getOpcode() { - return opcode; - } - - /** - * Returns the type of this instruction. - * - * @return the type of this instruction, i.e. one the constants defined in - * this class. - */ - public abstract int getType(); - - /** - * Returns the previous instruction in the list to which this instruction - * belongs, if any. - * - * @return the previous instruction in the list to which this instruction - * belongs, if any. May be null. - */ - public AbstractInsnNode getPrevious() { - return prev; - } - - /** - * Returns the next instruction in the list to which this instruction - * belongs, if any. - * - * @return the next instruction in the list to which this instruction - * belongs, if any. May be null. - */ - public AbstractInsnNode getNext() { - return next; - } - - /** - * Makes the given code visitor visit this instruction. - * - * @param cv - * a code visitor. - */ - public abstract void accept(final MethodVisitor cv); - - /** - * Makes the given visitor visit the annotations of this instruction. - * - * @param mv - * a method visitor. - */ - protected final void acceptAnnotations(final MethodVisitor mv) { - int n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations - .size(); - for (int i = 0; i < n; ++i) { - TypeAnnotationNode an = visibleTypeAnnotations.get(i); - an.accept(mv.visitInsnAnnotation(an.typeRef, an.typePath, an.desc, - true)); - } - n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations - .size(); - for (int i = 0; i < n; ++i) { - TypeAnnotationNode an = invisibleTypeAnnotations.get(i); - an.accept(mv.visitInsnAnnotation(an.typeRef, an.typePath, an.desc, - false)); - } - } - - /** - * Returns a copy of this instruction. - * - * @param labels - * a map from LabelNodes to cloned LabelNodes. - * @return a copy of this instruction. The returned instruction does not - * belong to any {@link InsnList}. - */ - public abstract AbstractInsnNode clone( - final Map labels); - - /** - * Returns the clone of the given label. - * - * @param label - * a label. - * @param map - * a map from LabelNodes to cloned LabelNodes. - * @return the clone of the given label. - */ - static LabelNode clone(final LabelNode label, - final Map map) { - return map.get(label); - } - - /** - * Returns the clones of the given labels. - * - * @param labels - * a list of labels. - * @param map - * a map from LabelNodes to cloned LabelNodes. - * @return the clones of the given labels. - */ - static LabelNode[] clone(final List labels, - final Map map) { - LabelNode[] clones = new LabelNode[labels.size()]; - for (int i = 0; i < clones.length; ++i) { - clones[i] = map.get(labels.get(i)); - } - return clones; - } - - /** - * Clones the annotations of the given instruction into this instruction. - * - * @param insn - * the source instruction. - * @return this instruction. - */ - protected final AbstractInsnNode cloneAnnotations( - final AbstractInsnNode insn) { - if (insn.visibleTypeAnnotations != null) { - this.visibleTypeAnnotations = new ArrayList(); - for (int i = 0; i < insn.visibleTypeAnnotations.size(); ++i) { - TypeAnnotationNode src = insn.visibleTypeAnnotations.get(i); - TypeAnnotationNode ann = new TypeAnnotationNode(src.typeRef, - src.typePath, src.desc); - src.accept(ann); - this.visibleTypeAnnotations.add(ann); - } - } - if (insn.invisibleTypeAnnotations != null) { - this.invisibleTypeAnnotations = new ArrayList(); - for (int i = 0; i < insn.invisibleTypeAnnotations.size(); ++i) { - TypeAnnotationNode src = insn.invisibleTypeAnnotations.get(i); - TypeAnnotationNode ann = new TypeAnnotationNode(src.typeRef, - src.typePath, src.desc); - src.accept(ann); - this.invisibleTypeAnnotations.add(ann); - } - } - return this; - } -} diff --git a/src/asm/scala/tools/asm/tree/AnnotationNode.java b/src/asm/scala/tools/asm/tree/AnnotationNode.java deleted file mode 100644 index b8d5988066..0000000000 --- a/src/asm/scala/tools/asm/tree/AnnotationNode.java +++ /dev/null @@ -1,231 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.ArrayList; -import java.util.List; - -import scala.tools.asm.AnnotationVisitor; -import scala.tools.asm.Opcodes; - -/** - * A node that represents an annotationn. - * - * @author Eric Bruneton - */ -public class AnnotationNode extends AnnotationVisitor { - - /** - * The class descriptor of the annotation class. - */ - public String desc; - - /** - * The name value pairs of this annotation. Each name value pair is stored - * as two consecutive elements in the list. The name is a {@link String}, - * and the value may be a {@link Byte}, {@link Boolean}, {@link Character}, - * {@link Short}, {@link Integer}, {@link Long}, {@link Float}, - * {@link Double}, {@link String} or {@link scala.tools.asm.Type}, or an - * two elements String array (for enumeration values), a - * {@link AnnotationNode}, or a {@link List} of values of one of the - * preceding types. The list may be null if there is no name value - * pair. - */ - public List values; - - /** - * Constructs a new {@link AnnotationNode}. Subclasses must not use this - * constructor. Instead, they must use the - * {@link #AnnotationNode(int, String)} version. - * - * @param desc - * the class descriptor of the annotation class. - * @throws IllegalStateException - * If a subclass calls this constructor. - */ - public AnnotationNode(final String desc) { - this(Opcodes.ASM5, desc); - if (getClass() != AnnotationNode.class) { - throw new IllegalStateException(); - } - } - - /** - * Constructs a new {@link AnnotationNode}. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - * @param desc - * the class descriptor of the annotation class. - */ - public AnnotationNode(final int api, final String desc) { - super(api); - this.desc = desc; - } - - /** - * Constructs a new {@link AnnotationNode} to visit an array value. - * - * @param values - * where the visited values must be stored. - */ - AnnotationNode(final List values) { - super(Opcodes.ASM5); - this.values = values; - } - - // ------------------------------------------------------------------------ - // Implementation of the AnnotationVisitor abstract class - // ------------------------------------------------------------------------ - - @Override - public void visit(final String name, final Object value) { - if (values == null) { - values = new ArrayList(this.desc != null ? 2 : 1); - } - if (this.desc != null) { - values.add(name); - } - values.add(value); - } - - @Override - public void visitEnum(final String name, final String desc, - final String value) { - if (values == null) { - values = new ArrayList(this.desc != null ? 2 : 1); - } - if (this.desc != null) { - values.add(name); - } - values.add(new String[] { desc, value }); - } - - @Override - public AnnotationVisitor visitAnnotation(final String name, - final String desc) { - if (values == null) { - values = new ArrayList(this.desc != null ? 2 : 1); - } - if (this.desc != null) { - values.add(name); - } - AnnotationNode annotation = new AnnotationNode(desc); - values.add(annotation); - return annotation; - } - - @Override - public AnnotationVisitor visitArray(final String name) { - if (values == null) { - values = new ArrayList(this.desc != null ? 2 : 1); - } - if (this.desc != null) { - values.add(name); - } - List array = new ArrayList(); - values.add(array); - return new AnnotationNode(array); - } - - @Override - public void visitEnd() { - } - - // ------------------------------------------------------------------------ - // Accept methods - // ------------------------------------------------------------------------ - - /** - * Checks that this annotation node is compatible with the given ASM API - * version. This methods checks that this node, and all its nodes - * recursively, do not contain elements that were introduced in more recent - * versions of the ASM API than the given version. - * - * @param api - * an ASM API version. Must be one of {@link Opcodes#ASM4} or - * {@link Opcodes#ASM5}. - */ - public void check(final int api) { - // nothing to do - } - - /** - * Makes the given visitor visit this annotation. - * - * @param av - * an annotation visitor. Maybe null. - */ - public void accept(final AnnotationVisitor av) { - if (av != null) { - if (values != null) { - for (int i = 0; i < values.size(); i += 2) { - String name = (String) values.get(i); - Object value = values.get(i + 1); - accept(av, name, value); - } - } - av.visitEnd(); - } - } - - /** - * Makes the given visitor visit a given annotation value. - * - * @param av - * an annotation visitor. Maybe null. - * @param name - * the value name. - * @param value - * the actual value. - */ - static void accept(final AnnotationVisitor av, final String name, - final Object value) { - if (av != null) { - if (value instanceof String[]) { - String[] typeconst = (String[]) value; - av.visitEnum(name, typeconst[0], typeconst[1]); - } else if (value instanceof AnnotationNode) { - AnnotationNode an = (AnnotationNode) value; - an.accept(av.visitAnnotation(name, an.desc)); - } else if (value instanceof List) { - AnnotationVisitor v = av.visitArray(name); - List array = (List) value; - for (int j = 0; j < array.size(); ++j) { - accept(v, null, array.get(j)); - } - v.visitEnd(); - } else { - av.visit(name, value); - } - } - } -} diff --git a/src/asm/scala/tools/asm/tree/ClassNode.java b/src/asm/scala/tools/asm/tree/ClassNode.java deleted file mode 100644 index 304b4ec9f5..0000000000 --- a/src/asm/scala/tools/asm/tree/ClassNode.java +++ /dev/null @@ -1,417 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import scala.tools.asm.AnnotationVisitor; -import scala.tools.asm.Attribute; -import scala.tools.asm.ClassVisitor; -import scala.tools.asm.FieldVisitor; -import scala.tools.asm.MethodVisitor; -import scala.tools.asm.Opcodes; -import scala.tools.asm.TypePath; - -/** - * A node that represents a class. - * - * @author Eric Bruneton - */ -public class ClassNode extends ClassVisitor { - - /** - * The class version. - */ - public int version; - - /** - * The class's access flags (see {@link scala.tools.asm.Opcodes}). This - * field also indicates if the class is deprecated. - */ - public int access; - - /** - * The internal name of the class (see - * {@link scala.tools.asm.Type#getInternalName() getInternalName}). - */ - public String name; - - /** - * The signature of the class. May be null. - */ - public String signature; - - /** - * The internal of name of the super class (see - * {@link scala.tools.asm.Type#getInternalName() getInternalName}). For - * interfaces, the super class is {@link Object}. May be null, but - * only for the {@link Object} class. - */ - public String superName; - - /** - * The internal names of the class's interfaces (see - * {@link scala.tools.asm.Type#getInternalName() getInternalName}). This - * list is a list of {@link String} objects. - */ - public List interfaces; - - /** - * The name of the source file from which this class was compiled. May be - * null. - */ - public String sourceFile; - - /** - * Debug information to compute the correspondence between source and - * compiled elements of the class. May be null. - */ - public String sourceDebug; - - /** - * The internal name of the enclosing class of the class. May be - * null. - */ - public String outerClass; - - /** - * The name of the method that contains the class, or null if the - * class is not enclosed in a method. - */ - public String outerMethod; - - /** - * The descriptor of the method that contains the class, or null if - * the class is not enclosed in a method. - */ - public String outerMethodDesc; - - /** - * The runtime visible annotations of this class. This list is a list of - * {@link AnnotationNode} objects. May be null. - * - * @associates scala.tools.asm.tree.AnnotationNode - * @label visible - */ - public List visibleAnnotations; - - /** - * The runtime invisible annotations of this class. This list is a list of - * {@link AnnotationNode} objects. May be null. - * - * @associates scala.tools.asm.tree.AnnotationNode - * @label invisible - */ - public List invisibleAnnotations; - - /** - * The runtime visible type annotations of this class. This list is a list - * of {@link TypeAnnotationNode} objects. May be null. - * - * @associates scala.tools.asm.tree.TypeAnnotationNode - * @label visible - */ - public List visibleTypeAnnotations; - - /** - * The runtime invisible type annotations of this class. This list is a list - * of {@link TypeAnnotationNode} objects. May be null. - * - * @associates scala.tools.asm.tree.TypeAnnotationNode - * @label invisible - */ - public List invisibleTypeAnnotations; - - /** - * The non standard attributes of this class. This list is a list of - * {@link Attribute} objects. May be null. - * - * @associates scala.tools.asm.Attribute - */ - public List attrs; - - /** - * Informations about the inner classes of this class. This list is a list - * of {@link InnerClassNode} objects. - * - * @associates scala.tools.asm.tree.InnerClassNode - */ - public List innerClasses; - - /** - * The fields of this class. This list is a list of {@link FieldNode} - * objects. - * - * @associates scala.tools.asm.tree.FieldNode - */ - public List fields; - - /** - * The methods of this class. This list is a list of {@link MethodNode} - * objects. - * - * @associates scala.tools.asm.tree.MethodNode - */ - public List methods; - - /** - * Constructs a new {@link ClassNode}. Subclasses must not use this - * constructor. Instead, they must use the {@link #ClassNode(int)} - * version. - * - * @throws IllegalStateException - * If a subclass calls this constructor. - */ - public ClassNode() { - this(Opcodes.ASM5); - if (getClass() != ClassNode.class) { - throw new IllegalStateException(); - } - } - - /** - * Constructs a new {@link ClassNode}. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - public ClassNode(final int api) { - super(api); - this.interfaces = new ArrayList(); - this.innerClasses = new ArrayList(); - this.fields = new ArrayList(); - this.methods = new ArrayList(); - } - - // ------------------------------------------------------------------------ - // Implementation of the ClassVisitor abstract class - // ------------------------------------------------------------------------ - - @Override - public void visit(final int version, final int access, final String name, - final String signature, final String superName, - final String[] interfaces) { - this.version = version; - this.access = access; - this.name = name; - this.signature = signature; - this.superName = superName; - if (interfaces != null) { - this.interfaces.addAll(Arrays.asList(interfaces)); - } - } - - @Override - public void visitSource(final String file, final String debug) { - sourceFile = file; - sourceDebug = debug; - } - - @Override - public void visitOuterClass(final String owner, final String name, - final String desc) { - outerClass = owner; - outerMethod = name; - outerMethodDesc = desc; - } - - @Override - public AnnotationVisitor visitAnnotation(final String desc, - final boolean visible) { - AnnotationNode an = new AnnotationNode(desc); - if (visible) { - if (visibleAnnotations == null) { - visibleAnnotations = new ArrayList(1); - } - visibleAnnotations.add(an); - } else { - if (invisibleAnnotations == null) { - invisibleAnnotations = new ArrayList(1); - } - invisibleAnnotations.add(an); - } - return an; - } - - @Override - public AnnotationVisitor visitTypeAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc); - if (visible) { - if (visibleTypeAnnotations == null) { - visibleTypeAnnotations = new ArrayList(1); - } - visibleTypeAnnotations.add(an); - } else { - if (invisibleTypeAnnotations == null) { - invisibleTypeAnnotations = new ArrayList(1); - } - invisibleTypeAnnotations.add(an); - } - return an; - } - - @Override - public void visitAttribute(final Attribute attr) { - if (attrs == null) { - attrs = new ArrayList(1); - } - attrs.add(attr); - } - - @Override - public void visitInnerClass(final String name, final String outerName, - final String innerName, final int access) { - InnerClassNode icn = new InnerClassNode(name, outerName, innerName, - access); - innerClasses.add(icn); - } - - @Override - public FieldVisitor visitField(final int access, final String name, - final String desc, final String signature, final Object value) { - FieldNode fn = new FieldNode(access, name, desc, signature, value); - fields.add(fn); - return fn; - } - - @Override - public MethodVisitor visitMethod(final int access, final String name, - final String desc, final String signature, final String[] exceptions) { - MethodNode mn = new MethodNode(access, name, desc, signature, - exceptions); - methods.add(mn); - return mn; - } - - @Override - public void visitEnd() { - } - - // ------------------------------------------------------------------------ - // Accept method - // ------------------------------------------------------------------------ - - /** - * Checks that this class node is compatible with the given ASM API version. - * This methods checks that this node, and all its nodes recursively, do not - * contain elements that were introduced in more recent versions of the ASM - * API than the given version. - * - * @param api - * an ASM API version. Must be one of {@link Opcodes#ASM4} or - * {@link Opcodes#ASM5}. - */ - public void check(final int api) { - if (api == Opcodes.ASM4) { - if (visibleTypeAnnotations != null - && visibleTypeAnnotations.size() > 0) { - throw new RuntimeException(); - } - if (invisibleTypeAnnotations != null - && invisibleTypeAnnotations.size() > 0) { - throw new RuntimeException(); - } - for (FieldNode f : fields) { - f.check(api); - } - for (MethodNode m : methods) { - m.check(api); - } - } - } - - /** - * Makes the given class visitor visit this class. - * - * @param cv - * a class visitor. - */ - public void accept(final ClassVisitor cv) { - // visits header - String[] interfaces = new String[this.interfaces.size()]; - this.interfaces.toArray(interfaces); - cv.visit(version, access, name, signature, superName, interfaces); - // visits source - if (sourceFile != null || sourceDebug != null) { - cv.visitSource(sourceFile, sourceDebug); - } - // visits outer class - if (outerClass != null) { - cv.visitOuterClass(outerClass, outerMethod, outerMethodDesc); - } - // visits attributes - int i, n; - n = visibleAnnotations == null ? 0 : visibleAnnotations.size(); - for (i = 0; i < n; ++i) { - AnnotationNode an = visibleAnnotations.get(i); - an.accept(cv.visitAnnotation(an.desc, true)); - } - n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size(); - for (i = 0; i < n; ++i) { - AnnotationNode an = invisibleAnnotations.get(i); - an.accept(cv.visitAnnotation(an.desc, false)); - } - n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size(); - for (i = 0; i < n; ++i) { - TypeAnnotationNode an = visibleTypeAnnotations.get(i); - an.accept(cv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, - true)); - } - n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations - .size(); - for (i = 0; i < n; ++i) { - TypeAnnotationNode an = invisibleTypeAnnotations.get(i); - an.accept(cv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, - false)); - } - n = attrs == null ? 0 : attrs.size(); - for (i = 0; i < n; ++i) { - cv.visitAttribute(attrs.get(i)); - } - // visits inner classes - for (i = 0; i < innerClasses.size(); ++i) { - innerClasses.get(i).accept(cv); - } - // visits fields - for (i = 0; i < fields.size(); ++i) { - fields.get(i).accept(cv); - } - // visits methods - for (i = 0; i < methods.size(); ++i) { - methods.get(i).accept(cv); - } - // visits end - cv.visitEnd(); - } -} diff --git a/src/asm/scala/tools/asm/tree/FieldInsnNode.java b/src/asm/scala/tools/asm/tree/FieldInsnNode.java deleted file mode 100644 index c027de109b..0000000000 --- a/src/asm/scala/tools/asm/tree/FieldInsnNode.java +++ /dev/null @@ -1,110 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.Map; - -import scala.tools.asm.MethodVisitor; - -/** - * A node that represents a field instruction. A field instruction is an - * instruction that loads or stores the value of a field of an object. - * - * @author Eric Bruneton - */ -public class FieldInsnNode extends AbstractInsnNode { - - /** - * The internal name of the field's owner class (see - * {@link scala.tools.asm.Type#getInternalName() getInternalName}). - */ - public String owner; - - /** - * The field's name. - */ - public String name; - - /** - * The field's descriptor (see {@link scala.tools.asm.Type}). - */ - public String desc; - - /** - * Constructs a new {@link FieldInsnNode}. - * - * @param opcode - * the opcode of the type instruction to be constructed. This - * opcode must be GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD. - * @param owner - * the internal name of the field's owner class (see - * {@link scala.tools.asm.Type#getInternalName() - * getInternalName}). - * @param name - * the field's name. - * @param desc - * the field's descriptor (see {@link scala.tools.asm.Type}). - */ - public FieldInsnNode(final int opcode, final String owner, - final String name, final String desc) { - super(opcode); - this.owner = owner; - this.name = name; - this.desc = desc; - } - - /** - * Sets the opcode of this instruction. - * - * @param opcode - * the new instruction opcode. This opcode must be GETSTATIC, - * PUTSTATIC, GETFIELD or PUTFIELD. - */ - public void setOpcode(final int opcode) { - this.opcode = opcode; - } - - @Override - public int getType() { - return FIELD_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitFieldInsn(opcode, owner, name, desc); - acceptAnnotations(mv); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new FieldInsnNode(opcode, owner, name, desc) - .cloneAnnotations(this); - } -} diff --git a/src/asm/scala/tools/asm/tree/FieldNode.java b/src/asm/scala/tools/asm/tree/FieldNode.java deleted file mode 100644 index 3fb14dac4f..0000000000 --- a/src/asm/scala/tools/asm/tree/FieldNode.java +++ /dev/null @@ -1,307 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.ArrayList; -import java.util.List; - -import scala.tools.asm.AnnotationVisitor; -import scala.tools.asm.Attribute; -import scala.tools.asm.ClassVisitor; -import scala.tools.asm.FieldVisitor; -import scala.tools.asm.Opcodes; -import scala.tools.asm.TypePath; - -/** - * A node that represents a field. - * - * @author Eric Bruneton - */ -public class FieldNode extends FieldVisitor { - - /** - * The field's access flags (see {@link scala.tools.asm.Opcodes}). This - * field also indicates if the field is synthetic and/or deprecated. - */ - public int access; - - /** - * The field's name. - */ - public String name; - - /** - * The field's descriptor (see {@link scala.tools.asm.Type}). - */ - public String desc; - - /** - * The field's signature. May be null. - */ - public String signature; - - /** - * The field's initial value. This field, which may be null if the - * field does not have an initial value, must be an {@link Integer}, a - * {@link Float}, a {@link Long}, a {@link Double} or a {@link String}. - */ - public Object value; - - /** - * The runtime visible annotations of this field. This list is a list of - * {@link AnnotationNode} objects. May be null. - * - * @associates scala.tools.asm.tree.AnnotationNode - * @label visible - */ - public List visibleAnnotations; - - /** - * The runtime invisible annotations of this field. This list is a list of - * {@link AnnotationNode} objects. May be null. - * - * @associates scala.tools.asm.tree.AnnotationNode - * @label invisible - */ - public List invisibleAnnotations; - - /** - * The runtime visible type annotations of this field. This list is a list - * of {@link TypeAnnotationNode} objects. May be null. - * - * @associates scala.tools.asm.tree.TypeAnnotationNode - * @label visible - */ - public List visibleTypeAnnotations; - - /** - * The runtime invisible type annotations of this field. This list is a list - * of {@link TypeAnnotationNode} objects. May be null. - * - * @associates scala.tools.asm.tree.TypeAnnotationNode - * @label invisible - */ - public List invisibleTypeAnnotations; - - /** - * The non standard attributes of this field. This list is a list of - * {@link Attribute} objects. May be null. - * - * @associates scala.tools.asm.Attribute - */ - public List attrs; - - /** - * Constructs a new {@link FieldNode}. Subclasses must not use this - * constructor. Instead, they must use the - * {@link #FieldNode(int, int, String, String, String, Object)} version. - * - * @param access - * the field's access flags (see - * {@link scala.tools.asm.Opcodes}). This parameter also - * indicates if the field is synthetic and/or deprecated. - * @param name - * the field's name. - * @param desc - * the field's descriptor (see {@link scala.tools.asm.Type - * Type}). - * @param signature - * the field's signature. - * @param value - * the field's initial value. This parameter, which may be - * null if the field does not have an initial value, - * must be an {@link Integer}, a {@link Float}, a {@link Long}, a - * {@link Double} or a {@link String}. - * @throws IllegalStateException - * If a subclass calls this constructor. - */ - public FieldNode(final int access, final String name, final String desc, - final String signature, final Object value) { - this(Opcodes.ASM5, access, name, desc, signature, value); - if (getClass() != FieldNode.class) { - throw new IllegalStateException(); - } - } - - /** - * Constructs a new {@link FieldNode}. Subclasses must not use this - * constructor. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - * @param access - * the field's access flags (see - * {@link scala.tools.asm.Opcodes}). This parameter also - * indicates if the field is synthetic and/or deprecated. - * @param name - * the field's name. - * @param desc - * the field's descriptor (see {@link scala.tools.asm.Type - * Type}). - * @param signature - * the field's signature. - * @param value - * the field's initial value. This parameter, which may be - * null if the field does not have an initial value, - * must be an {@link Integer}, a {@link Float}, a {@link Long}, a - * {@link Double} or a {@link String}. - */ - public FieldNode(final int api, final int access, final String name, - final String desc, final String signature, final Object value) { - super(api); - this.access = access; - this.name = name; - this.desc = desc; - this.signature = signature; - this.value = value; - } - - // ------------------------------------------------------------------------ - // Implementation of the FieldVisitor abstract class - // ------------------------------------------------------------------------ - - @Override - public AnnotationVisitor visitAnnotation(final String desc, - final boolean visible) { - AnnotationNode an = new AnnotationNode(desc); - if (visible) { - if (visibleAnnotations == null) { - visibleAnnotations = new ArrayList(1); - } - visibleAnnotations.add(an); - } else { - if (invisibleAnnotations == null) { - invisibleAnnotations = new ArrayList(1); - } - invisibleAnnotations.add(an); - } - return an; - } - - @Override - public AnnotationVisitor visitTypeAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc); - if (visible) { - if (visibleTypeAnnotations == null) { - visibleTypeAnnotations = new ArrayList(1); - } - visibleTypeAnnotations.add(an); - } else { - if (invisibleTypeAnnotations == null) { - invisibleTypeAnnotations = new ArrayList(1); - } - invisibleTypeAnnotations.add(an); - } - return an; - } - - @Override - public void visitAttribute(final Attribute attr) { - if (attrs == null) { - attrs = new ArrayList(1); - } - attrs.add(attr); - } - - @Override - public void visitEnd() { - } - - // ------------------------------------------------------------------------ - // Accept methods - // ------------------------------------------------------------------------ - - /** - * Checks that this field node is compatible with the given ASM API version. - * This methods checks that this node, and all its nodes recursively, do not - * contain elements that were introduced in more recent versions of the ASM - * API than the given version. - * - * @param api - * an ASM API version. Must be one of {@link Opcodes#ASM4} or - * {@link Opcodes#ASM5}. - */ - public void check(final int api) { - if (api == Opcodes.ASM4) { - if (visibleTypeAnnotations != null - && visibleTypeAnnotations.size() > 0) { - throw new RuntimeException(); - } - if (invisibleTypeAnnotations != null - && invisibleTypeAnnotations.size() > 0) { - throw new RuntimeException(); - } - } - } - - /** - * Makes the given class visitor visit this field. - * - * @param cv - * a class visitor. - */ - public void accept(final ClassVisitor cv) { - FieldVisitor fv = cv.visitField(access, name, desc, signature, value); - if (fv == null) { - return; - } - int i, n; - n = visibleAnnotations == null ? 0 : visibleAnnotations.size(); - for (i = 0; i < n; ++i) { - AnnotationNode an = visibleAnnotations.get(i); - an.accept(fv.visitAnnotation(an.desc, true)); - } - n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size(); - for (i = 0; i < n; ++i) { - AnnotationNode an = invisibleAnnotations.get(i); - an.accept(fv.visitAnnotation(an.desc, false)); - } - n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size(); - for (i = 0; i < n; ++i) { - TypeAnnotationNode an = visibleTypeAnnotations.get(i); - an.accept(fv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, - true)); - } - n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations - .size(); - for (i = 0; i < n; ++i) { - TypeAnnotationNode an = invisibleTypeAnnotations.get(i); - an.accept(fv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, - false)); - } - n = attrs == null ? 0 : attrs.size(); - for (i = 0; i < n; ++i) { - fv.visitAttribute(attrs.get(i)); - } - fv.visitEnd(); - } -} diff --git a/src/asm/scala/tools/asm/tree/FrameNode.java b/src/asm/scala/tools/asm/tree/FrameNode.java deleted file mode 100644 index f13fc66749..0000000000 --- a/src/asm/scala/tools/asm/tree/FrameNode.java +++ /dev/null @@ -1,210 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import scala.tools.asm.MethodVisitor; -import scala.tools.asm.Opcodes; - -/** - * A node that represents a stack map frame. These nodes are pseudo instruction - * nodes in order to be inserted in an instruction list. In fact these nodes - * must(*) be inserted just before any instruction node i that - * follows an unconditionnal branch instruction such as GOTO or THROW, that is - * the target of a jump instruction, or that starts an exception handler block. - * The stack map frame types must describe the values of the local variables and - * of the operand stack elements just before i is executed.
- *
- * (*) this is mandatory only for classes whose version is greater than or equal - * to {@link Opcodes#V1_6 V1_6}. - * - * @author Eric Bruneton - */ -public class FrameNode extends AbstractInsnNode { - - /** - * The type of this frame. Must be {@link Opcodes#F_NEW} for expanded - * frames, or {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, - * {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or - * {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed frames. - */ - public int type; - - /** - * The types of the local variables of this stack map frame. Elements of - * this list can be Integer, String or LabelNode objects (for primitive, - * reference and uninitialized types respectively - see - * {@link MethodVisitor}). - */ - public List local; - - /** - * The types of the operand stack elements of this stack map frame. Elements - * of this list can be Integer, String or LabelNode objects (for primitive, - * reference and uninitialized types respectively - see - * {@link MethodVisitor}). - */ - public List stack; - - private FrameNode() { - super(-1); - } - - /** - * Constructs a new {@link FrameNode}. - * - * @param type - * the type of this frame. Must be {@link Opcodes#F_NEW} for - * expanded frames, or {@link Opcodes#F_FULL}, - * {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP}, - * {@link Opcodes#F_SAME} or {@link Opcodes#F_APPEND}, - * {@link Opcodes#F_SAME1} for compressed frames. - * @param nLocal - * number of local variables of this stack map frame. - * @param local - * the types of the local variables of this stack map frame. - * Elements of this list can be Integer, String or LabelNode - * objects (for primitive, reference and uninitialized types - * respectively - see {@link MethodVisitor}). - * @param nStack - * number of operand stack elements of this stack map frame. - * @param stack - * the types of the operand stack elements of this stack map - * frame. Elements of this list can be Integer, String or - * LabelNode objects (for primitive, reference and uninitialized - * types respectively - see {@link MethodVisitor}). - */ - public FrameNode(final int type, final int nLocal, final Object[] local, - final int nStack, final Object[] stack) { - super(-1); - this.type = type; - switch (type) { - case Opcodes.F_NEW: - case Opcodes.F_FULL: - this.local = asList(nLocal, local); - this.stack = asList(nStack, stack); - break; - case Opcodes.F_APPEND: - this.local = asList(nLocal, local); - break; - case Opcodes.F_CHOP: - this.local = Arrays.asList(new Object[nLocal]); - break; - case Opcodes.F_SAME: - break; - case Opcodes.F_SAME1: - this.stack = asList(1, stack); - break; - } - } - - @Override - public int getType() { - return FRAME; - } - - /** - * Makes the given visitor visit this stack map frame. - * - * @param mv - * a method visitor. - */ - @Override - public void accept(final MethodVisitor mv) { - switch (type) { - case Opcodes.F_NEW: - case Opcodes.F_FULL: - mv.visitFrame(type, local.size(), asArray(local), stack.size(), - asArray(stack)); - break; - case Opcodes.F_APPEND: - mv.visitFrame(type, local.size(), asArray(local), 0, null); - break; - case Opcodes.F_CHOP: - mv.visitFrame(type, local.size(), null, 0, null); - break; - case Opcodes.F_SAME: - mv.visitFrame(type, 0, null, 0, null); - break; - case Opcodes.F_SAME1: - mv.visitFrame(type, 0, null, 1, asArray(stack)); - break; - } - } - - @Override - public AbstractInsnNode clone(final Map labels) { - FrameNode clone = new FrameNode(); - clone.type = type; - if (local != null) { - clone.local = new ArrayList(); - for (int i = 0; i < local.size(); ++i) { - Object l = local.get(i); - if (l instanceof LabelNode) { - l = labels.get(l); - } - clone.local.add(l); - } - } - if (stack != null) { - clone.stack = new ArrayList(); - for (int i = 0; i < stack.size(); ++i) { - Object s = stack.get(i); - if (s instanceof LabelNode) { - s = labels.get(s); - } - clone.stack.add(s); - } - } - return clone; - } - - // ------------------------------------------------------------------------ - - private static List asList(final int n, final Object[] o) { - return Arrays.asList(o).subList(0, n); - } - - private static Object[] asArray(final List l) { - Object[] objs = new Object[l.size()]; - for (int i = 0; i < objs.length; ++i) { - Object o = l.get(i); - if (o instanceof LabelNode) { - o = ((LabelNode) o).getLabel(); - } - objs[i] = o; - } - return objs; - } -} diff --git a/src/asm/scala/tools/asm/tree/IincInsnNode.java b/src/asm/scala/tools/asm/tree/IincInsnNode.java deleted file mode 100644 index c37ac91c27..0000000000 --- a/src/asm/scala/tools/asm/tree/IincInsnNode.java +++ /dev/null @@ -1,83 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.Map; - -import scala.tools.asm.MethodVisitor; -import scala.tools.asm.Opcodes; - -/** - * A node that represents an IINC instruction. - * - * @author Eric Bruneton - */ -public class IincInsnNode extends AbstractInsnNode { - - /** - * Index of the local variable to be incremented. - */ - public int var; - - /** - * Amount to increment the local variable by. - */ - public int incr; - - /** - * Constructs a new {@link IincInsnNode}. - * - * @param var - * index of the local variable to be incremented. - * @param incr - * increment amount to increment the local variable by. - */ - public IincInsnNode(final int var, final int incr) { - super(Opcodes.IINC); - this.var = var; - this.incr = incr; - } - - @Override - public int getType() { - return IINC_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitIincInsn(var, incr); - acceptAnnotations(mv); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new IincInsnNode(var, incr).cloneAnnotations(this); - } -} diff --git a/src/asm/scala/tools/asm/tree/InnerClassNode.java b/src/asm/scala/tools/asm/tree/InnerClassNode.java deleted file mode 100644 index aa3810c759..0000000000 --- a/src/asm/scala/tools/asm/tree/InnerClassNode.java +++ /dev/null @@ -1,101 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import scala.tools.asm.ClassVisitor; - -/** - * A node that represents an inner class. - * - * @author Eric Bruneton - */ -public class InnerClassNode { - - /** - * The internal name of an inner class (see - * {@link scala.tools.asm.Type#getInternalName() getInternalName}). - */ - public String name; - - /** - * The internal name of the class to which the inner class belongs (see - * {@link scala.tools.asm.Type#getInternalName() getInternalName}). May be - * null. - */ - public String outerName; - - /** - * The (simple) name of the inner class inside its enclosing class. May be - * null for anonymous inner classes. - */ - public String innerName; - - /** - * The access flags of the inner class as originally declared in the - * enclosing class. - */ - public int access; - - /** - * Constructs a new {@link InnerClassNode}. - * - * @param name - * the internal name of an inner class (see - * {@link scala.tools.asm.Type#getInternalName() - * getInternalName}). - * @param outerName - * the internal name of the class to which the inner class - * belongs (see {@link scala.tools.asm.Type#getInternalName() - * getInternalName}). May be null. - * @param innerName - * the (simple) name of the inner class inside its enclosing - * class. May be null for anonymous inner classes. - * @param access - * the access flags of the inner class as originally declared in - * the enclosing class. - */ - public InnerClassNode(final String name, final String outerName, - final String innerName, final int access) { - this.name = name; - this.outerName = outerName; - this.innerName = innerName; - this.access = access; - } - - /** - * Makes the given class visitor visit this inner class. - * - * @param cv - * a class visitor. - */ - public void accept(final ClassVisitor cv) { - cv.visitInnerClass(name, outerName, innerName, access); - } -} diff --git a/src/asm/scala/tools/asm/tree/InsnList.java b/src/asm/scala/tools/asm/tree/InsnList.java deleted file mode 100644 index e808712e78..0000000000 --- a/src/asm/scala/tools/asm/tree/InsnList.java +++ /dev/null @@ -1,622 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.ListIterator; -import java.util.NoSuchElementException; - -import scala.tools.asm.MethodVisitor; - -/** - * A doubly linked list of {@link AbstractInsnNode} objects. This - * implementation is not thread safe. - */ -public class InsnList { - - /** - * The number of instructions in this list. - */ - private int size; - - /** - * The first instruction in this list. May be null. - */ - private AbstractInsnNode first; - - /** - * The last instruction in this list. May be null. - */ - private AbstractInsnNode last; - - /** - * A cache of the instructions of this list. This cache is used to improve - * the performance of the {@link #get} method. - */ - AbstractInsnNode[] cache; - - /** - * Returns the number of instructions in this list. - * - * @return the number of instructions in this list. - */ - public int size() { - return size; - } - - /** - * Returns the first instruction in this list. - * - * @return the first instruction in this list, or null if the list - * is empty. - */ - public AbstractInsnNode getFirst() { - return first; - } - - /** - * Returns the last instruction in this list. - * - * @return the last instruction in this list, or null if the list - * is empty. - */ - public AbstractInsnNode getLast() { - return last; - } - - /** - * Returns the instruction whose index is given. This method builds a cache - * of the instructions in this list to avoid scanning the whole list each - * time it is called. Once the cache is built, this method run in constant - * time. This cache is invalidated by all the methods that modify the list. - * - * @param index - * the index of the instruction that must be returned. - * @return the instruction whose index is given. - * @throws IndexOutOfBoundsException - * if (index < 0 || index >= size()). - */ - public AbstractInsnNode get(final int index) { - if (index < 0 || index >= size) { - throw new IndexOutOfBoundsException(); - } - if (cache == null) { - cache = toArray(); - } - return cache[index]; - } - - /** - * Returns true if the given instruction belongs to this list. This - * method always scans the instructions of this list until it finds the - * given instruction or reaches the end of the list. - * - * @param insn - * an instruction. - * @return true if the given instruction belongs to this list. - */ - public boolean contains(final AbstractInsnNode insn) { - AbstractInsnNode i = first; - while (i != null && i != insn) { - i = i.next; - } - return i != null; - } - - /** - * Returns the index of the given instruction in this list. This method - * builds a cache of the instruction indexes to avoid scanning the whole - * list each time it is called. Once the cache is built, this method run in - * constant time. The cache is invalidated by all the methods that modify - * the list. - * - * @param insn - * an instruction of this list. - * @return the index of the given instruction in this list. The result of - * this method is undefined if the given instruction does not belong - * to this list. Use {@link #contains contains} to test if an - * instruction belongs to an instruction list or not. - */ - public int indexOf(final AbstractInsnNode insn) { - if (cache == null) { - cache = toArray(); - } - return insn.index; - } - - /** - * Makes the given visitor visit all of the instructions in this list. - * - * @param mv - * the method visitor that must visit the instructions. - */ - public void accept(final MethodVisitor mv) { - AbstractInsnNode insn = first; - while (insn != null) { - insn.accept(mv); - insn = insn.next; - } - } - - /** - * Returns an iterator over the instructions in this list. - * - * @return an iterator over the instructions in this list. - */ - public ListIterator iterator() { - return iterator(0); - } - - /** - * Returns an iterator over the instructions in this list. - * - * @return an iterator over the instructions in this list. - */ - @SuppressWarnings("unchecked") - public ListIterator iterator(int index) { - return new InsnListIterator(index); - } - - /** - * Returns an array containing all of the instructions in this list. - * - * @return an array containing all of the instructions in this list. - */ - public AbstractInsnNode[] toArray() { - int i = 0; - AbstractInsnNode elem = first; - AbstractInsnNode[] insns = new AbstractInsnNode[size]; - while (elem != null) { - insns[i] = elem; - elem.index = i++; - elem = elem.next; - } - return insns; - } - - /** - * Replaces an instruction of this list with another instruction. - * - * @param location - * an instruction of this list. - * @param insn - * another instruction, which must not belong to any - * {@link InsnList}. - */ - public void set(final AbstractInsnNode location, final AbstractInsnNode insn) { - AbstractInsnNode next = location.next; - insn.next = next; - if (next != null) { - next.prev = insn; - } else { - last = insn; - } - AbstractInsnNode prev = location.prev; - insn.prev = prev; - if (prev != null) { - prev.next = insn; - } else { - first = insn; - } - if (cache != null) { - int index = location.index; - cache[index] = insn; - insn.index = index; - } else { - insn.index = 0; // insn now belongs to an InsnList - } - location.index = -1; // i no longer belongs to an InsnList - location.prev = null; - location.next = null; - } - - /** - * Adds the given instruction to the end of this list. - * - * @param insn - * an instruction, which must not belong to any - * {@link InsnList}. - */ - public void add(final AbstractInsnNode insn) { - if(insn.prev != null || insn.next != null) { - // Adding an instruction that still refers to others (in the same or another InsnList) leads to hard to debug bugs. - // Initially everything may look ok (e.g. iteration follows `next` thus a stale `prev` isn't noticed). - // However, a stale link brings the doubly-linked into disarray e.g. upon removing an element, - // which results in the `next` of a stale `prev` being updated, among other failure scenarios. - // Better fail early. - throw new RuntimeException("Instruction " + insn + " already belongs to some InsnList."); - } - ++size; - if (last == null) { - first = insn; - last = insn; - } else { - last.next = insn; - insn.prev = last; - } - last = insn; - cache = null; - insn.index = 0; // insn now belongs to an InsnList - } - - /** - * Adds the given instructions to the end of this list. - * - * @param insns - * an instruction list, which is cleared during the process. This - * list must be different from 'this'. - */ - public void add(final InsnList insns) { - if (insns.size == 0) { - return; - } - size += insns.size; - if (last == null) { - first = insns.first; - last = insns.last; - } else { - AbstractInsnNode elem = insns.first; - last.next = elem; - elem.prev = last; - last = insns.last; - } - cache = null; - insns.removeAll(false); - } - - /** - * Inserts the given instruction at the begining of this list. - * - * @param insn - * an instruction, which must not belong to any - * {@link InsnList}. - */ - public void insert(final AbstractInsnNode insn) { - ++size; - if (first == null) { - first = insn; - last = insn; - } else { - first.prev = insn; - insn.next = first; - } - first = insn; - cache = null; - insn.index = 0; // insn now belongs to an InsnList - } - - /** - * Inserts the given instructions at the begining of this list. - * - * @param insns - * an instruction list, which is cleared during the process. This - * list must be different from 'this'. - */ - public void insert(final InsnList insns) { - if (insns.size == 0) { - return; - } - size += insns.size; - if (first == null) { - first = insns.first; - last = insns.last; - } else { - AbstractInsnNode elem = insns.last; - first.prev = elem; - elem.next = first; - first = insns.first; - } - cache = null; - insns.removeAll(false); - } - - /** - * Inserts the given instruction after the specified instruction. - * - * @param location - * an instruction of this list after which insn must be - * inserted. - * @param insn - * the instruction to be inserted, which must not belong to - * any {@link InsnList}. - */ - public void insert(final AbstractInsnNode location, - final AbstractInsnNode insn) { - ++size; - AbstractInsnNode next = location.next; - if (next == null) { - last = insn; - } else { - next.prev = insn; - } - location.next = insn; - insn.next = next; - insn.prev = location; - cache = null; - insn.index = 0; // insn now belongs to an InsnList - } - - /** - * Inserts the given instructions after the specified instruction. - * - * @param location - * an instruction of this list after which the - * instructions must be inserted. - * @param insns - * the instruction list to be inserted, which is cleared during - * the process. This list must be different from 'this'. - */ - public void insert(final AbstractInsnNode location, final InsnList insns) { - if (insns.size == 0) { - return; - } - size += insns.size; - AbstractInsnNode ifirst = insns.first; - AbstractInsnNode ilast = insns.last; - AbstractInsnNode next = location.next; - if (next == null) { - last = ilast; - } else { - next.prev = ilast; - } - location.next = ifirst; - ilast.next = next; - ifirst.prev = location; - cache = null; - insns.removeAll(false); - } - - /** - * Inserts the given instruction before the specified instruction. - * - * @param location - * an instruction of this list before which insn must be - * inserted. - * @param insn - * the instruction to be inserted, which must not belong to - * any {@link InsnList}. - */ - public void insertBefore(final AbstractInsnNode location, - final AbstractInsnNode insn) { - ++size; - AbstractInsnNode prev = location.prev; - if (prev == null) { - first = insn; - } else { - prev.next = insn; - } - location.prev = insn; - insn.next = location; - insn.prev = prev; - cache = null; - insn.index = 0; // insn now belongs to an InsnList - } - - /** - * Inserts the given instructions before the specified instruction. - * - * @param location - * an instruction of this list before which the - * instructions must be inserted. - * @param insns - * the instruction list to be inserted, which is cleared during - * the process. This list must be different from 'this'. - */ - public void insertBefore(final AbstractInsnNode location, - final InsnList insns) { - if (insns.size == 0) { - return; - } - size += insns.size; - AbstractInsnNode ifirst = insns.first; - AbstractInsnNode ilast = insns.last; - AbstractInsnNode prev = location.prev; - if (prev == null) { - first = ifirst; - } else { - prev.next = ifirst; - } - location.prev = ilast; - ilast.next = location; - ifirst.prev = prev; - cache = null; - insns.removeAll(false); - } - - /** - * Removes the given instruction from this list. - * - * @param insn - * the instruction of this list that must be removed. - */ - public void remove(final AbstractInsnNode insn) { - --size; - AbstractInsnNode next = insn.next; - AbstractInsnNode prev = insn.prev; - if (next == null) { - if (prev == null) { - first = null; - last = null; - } else { - prev.next = null; - last = prev; - } - } else { - if (prev == null) { - first = next; - next.prev = null; - } else { - prev.next = next; - next.prev = prev; - } - } - cache = null; - insn.index = -1; // insn no longer belongs to an InsnList - insn.prev = null; - insn.next = null; - } - - /** - * Removes all of the instructions of this list. - * - * @param mark - * if the instructions must be marked as no longer belonging to - * any {@link InsnList}. - */ - void removeAll(final boolean mark) { - if (mark) { - AbstractInsnNode insn = first; - while (insn != null) { - AbstractInsnNode next = insn.next; - insn.index = -1; // insn no longer belongs to an InsnList - insn.prev = null; - insn.next = null; - insn = next; - } - } - size = 0; - first = null; - last = null; - cache = null; - } - - /** - * Removes all of the instructions of this list. - */ - public void clear() { - removeAll(false); - } - - /** - * Reset all labels in the instruction list. This method should be called - * before reusing same instructions list between several - * ClassWriters. - */ - public void resetLabels() { - AbstractInsnNode insn = first; - while (insn != null) { - if (insn instanceof LabelNode) { - ((LabelNode) insn).resetLabel(); - } - insn = insn.next; - } - } - - // this class is not generified because it will create bridges - private final class InsnListIterator implements ListIterator { - - AbstractInsnNode next; - - AbstractInsnNode prev; - - AbstractInsnNode remove; - - InsnListIterator(int index) { - if (index == size()) { - next = null; - prev = getLast(); - } else { - next = get(index); - prev = next.prev; - } - } - - public boolean hasNext() { - return next != null; - } - - public Object next() { - if (next == null) { - throw new NoSuchElementException(); - } - AbstractInsnNode result = next; - prev = result; - next = result.next; - remove = result; - return result; - } - - public void remove() { - if (remove != null) { - if (remove == next) { - next = next.next; - } else { - prev = prev.prev; - } - InsnList.this.remove(remove); - remove = null; - } else { - throw new IllegalStateException(); - } - } - - public boolean hasPrevious() { - return prev != null; - } - - public Object previous() { - AbstractInsnNode result = prev; - next = result; - prev = result.prev; - remove = result; - return result; - } - - public int nextIndex() { - if (next == null) { - return size(); - } - if (cache == null) { - cache = toArray(); - } - return next.index; - } - - public int previousIndex() { - if (prev == null) { - return -1; - } - if (cache == null) { - cache = toArray(); - } - return prev.index; - } - - public void add(Object o) { - InsnList.this.insertBefore(next, (AbstractInsnNode) o); - prev = (AbstractInsnNode) o; - remove = null; - } - - public void set(Object o) { - InsnList.this.set(next.prev, (AbstractInsnNode) o); - prev = (AbstractInsnNode) o; - } - } -} diff --git a/src/asm/scala/tools/asm/tree/InsnNode.java b/src/asm/scala/tools/asm/tree/InsnNode.java deleted file mode 100644 index f5313929ee..0000000000 --- a/src/asm/scala/tools/asm/tree/InsnNode.java +++ /dev/null @@ -1,88 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.Map; - -import scala.tools.asm.MethodVisitor; - -/** - * A node that represents a zero operand instruction. - * - * @author Eric Bruneton - */ -public class InsnNode extends AbstractInsnNode { - - /** - * Constructs a new {@link InsnNode}. - * - * @param opcode - * the opcode of the instruction to be constructed. This opcode - * must be NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, - * ICONST_2, ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, - * FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, - * LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, - * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, - * SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, - * DUP2_X2, SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, - * IMUL, LMUL, FMUL, DMUL, IDIV, LDIV, FDIV, DDIV, IREM, LREM, - * FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, - * IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, - * L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B, I2C, I2S, - * LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN, - * DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, - * or MONITOREXIT. - */ - public InsnNode(final int opcode) { - super(opcode); - } - - @Override - public int getType() { - return INSN; - } - - /** - * Makes the given visitor visit this instruction. - * - * @param mv - * a method visitor. - */ - @Override - public void accept(final MethodVisitor mv) { - mv.visitInsn(opcode); - acceptAnnotations(mv); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new InsnNode(opcode).cloneAnnotations(this); - } -} diff --git a/src/asm/scala/tools/asm/tree/IntInsnNode.java b/src/asm/scala/tools/asm/tree/IntInsnNode.java deleted file mode 100644 index 6bbe8d845c..0000000000 --- a/src/asm/scala/tools/asm/tree/IntInsnNode.java +++ /dev/null @@ -1,88 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.Map; - -import scala.tools.asm.MethodVisitor; - -/** - * A node that represents an instruction with a single int operand. - * - * @author Eric Bruneton - */ -public class IntInsnNode extends AbstractInsnNode { - - /** - * The operand of this instruction. - */ - public int operand; - - /** - * Constructs a new {@link IntInsnNode}. - * - * @param opcode - * the opcode of the instruction to be constructed. This opcode - * must be BIPUSH, SIPUSH or NEWARRAY. - * @param operand - * the operand of the instruction to be constructed. - */ - public IntInsnNode(final int opcode, final int operand) { - super(opcode); - this.operand = operand; - } - - /** - * Sets the opcode of this instruction. - * - * @param opcode - * the new instruction opcode. This opcode must be BIPUSH, SIPUSH - * or NEWARRAY. - */ - public void setOpcode(final int opcode) { - this.opcode = opcode; - } - - @Override - public int getType() { - return INT_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitIntInsn(opcode, operand); - acceptAnnotations(mv); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new IntInsnNode(opcode, operand).cloneAnnotations(this); - } -} diff --git a/src/asm/scala/tools/asm/tree/InvokeDynamicInsnNode.java b/src/asm/scala/tools/asm/tree/InvokeDynamicInsnNode.java deleted file mode 100644 index 0f85e60291..0000000000 --- a/src/asm/scala/tools/asm/tree/InvokeDynamicInsnNode.java +++ /dev/null @@ -1,102 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.Map; - -import scala.tools.asm.Handle; -import scala.tools.asm.MethodVisitor; -import scala.tools.asm.Opcodes; - -/** - * A node that represents an invokedynamic instruction. - * - * @author Remi Forax - */ -public class InvokeDynamicInsnNode extends AbstractInsnNode { - - /** - * Invokedynamic name. - */ - public String name; - - /** - * Invokedynamic descriptor. - */ - public String desc; - - /** - * Bootstrap method - */ - public Handle bsm; - - /** - * Bootstrap constant arguments - */ - public Object[] bsmArgs; - - /** - * Constructs a new {@link InvokeDynamicInsnNode}. - * - * @param name - * invokedynamic name. - * @param desc - * invokedynamic descriptor (see {@link scala.tools.asm.Type}). - * @param bsm - * the bootstrap method. - * @param bsmArgs - * the boostrap constant arguments. - */ - public InvokeDynamicInsnNode(final String name, final String desc, - final Handle bsm, final Object... bsmArgs) { - super(Opcodes.INVOKEDYNAMIC); - this.name = name; - this.desc = desc; - this.bsm = bsm; - this.bsmArgs = bsmArgs; - } - - @Override - public int getType() { - return INVOKE_DYNAMIC_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); - acceptAnnotations(mv); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs) - .cloneAnnotations(this); - } -} diff --git a/src/asm/scala/tools/asm/tree/JumpInsnNode.java b/src/asm/scala/tools/asm/tree/JumpInsnNode.java deleted file mode 100644 index 8b8a769204..0000000000 --- a/src/asm/scala/tools/asm/tree/JumpInsnNode.java +++ /dev/null @@ -1,97 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.Map; - -import scala.tools.asm.MethodVisitor; - -/** - * A node that represents a jump instruction. A jump instruction is an - * instruction that may jump to another instruction. - * - * @author Eric Bruneton - */ -public class JumpInsnNode extends AbstractInsnNode { - - /** - * The operand of this instruction. This operand is a label that designates - * the instruction to which this instruction may jump. - */ - public LabelNode label; - - /** - * Constructs a new {@link JumpInsnNode}. - * - * @param opcode - * the opcode of the type instruction to be constructed. This - * opcode must be IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, - * IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, - * IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL. - * @param label - * the operand of the instruction to be constructed. This operand - * is a label that designates the instruction to which the jump - * instruction may jump. - */ - public JumpInsnNode(final int opcode, final LabelNode label) { - super(opcode); - this.label = label; - } - - /** - * Sets the opcode of this instruction. - * - * @param opcode - * the new instruction opcode. This opcode must be IFEQ, IFNE, - * IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, - * IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, - * JSR, IFNULL or IFNONNULL. - */ - public void setOpcode(final int opcode) { - this.opcode = opcode; - } - - @Override - public int getType() { - return JUMP_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitJumpInsn(opcode, label.getLabel()); - acceptAnnotations(mv); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new JumpInsnNode(opcode, clone(label, labels)) - .cloneAnnotations(this); - } -} diff --git a/src/asm/scala/tools/asm/tree/LabelNode.java b/src/asm/scala/tools/asm/tree/LabelNode.java deleted file mode 100644 index 44c48c1160..0000000000 --- a/src/asm/scala/tools/asm/tree/LabelNode.java +++ /dev/null @@ -1,78 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.Map; - -import scala.tools.asm.Label; -import scala.tools.asm.MethodVisitor; - -/** - * An {@link AbstractInsnNode} that encapsulates a {@link Label}. - */ -public class LabelNode extends AbstractInsnNode { - - private Label label; - - public LabelNode() { - super(-1); - } - - public LabelNode(final Label label) { - super(-1); - this.label = label; - } - - @Override - public int getType() { - return LABEL; - } - - public Label getLabel() { - if (label == null) { - label = new Label(); - } - return label; - } - - @Override - public void accept(final MethodVisitor cv) { - cv.visitLabel(getLabel()); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return labels.get(this); - } - - public void resetLabel() { - label = null; - } -} diff --git a/src/asm/scala/tools/asm/tree/LdcInsnNode.java b/src/asm/scala/tools/asm/tree/LdcInsnNode.java deleted file mode 100644 index 1cc850bb31..0000000000 --- a/src/asm/scala/tools/asm/tree/LdcInsnNode.java +++ /dev/null @@ -1,79 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.Map; - -import scala.tools.asm.MethodVisitor; -import scala.tools.asm.Opcodes; - -/** - * A node that represents an LDC instruction. - * - * @author Eric Bruneton - */ -public class LdcInsnNode extends AbstractInsnNode { - - /** - * The constant to be loaded on the stack. This parameter must be a non null - * {@link Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a - * {@link String} or a {@link scala.tools.asm.Type}. - */ - public Object cst; - - /** - * Constructs a new {@link LdcInsnNode}. - * - * @param cst - * the constant to be loaded on the stack. This parameter must be - * a non null {@link Integer}, a {@link Float}, a {@link Long}, a - * {@link Double} or a {@link String}. - */ - public LdcInsnNode(final Object cst) { - super(Opcodes.LDC); - this.cst = cst; - } - - @Override - public int getType() { - return LDC_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitLdcInsn(cst); - acceptAnnotations(mv); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new LdcInsnNode(cst).cloneAnnotations(this); - } -} diff --git a/src/asm/scala/tools/asm/tree/LineNumberNode.java b/src/asm/scala/tools/asm/tree/LineNumberNode.java deleted file mode 100644 index 9947aa70a9..0000000000 --- a/src/asm/scala/tools/asm/tree/LineNumberNode.java +++ /dev/null @@ -1,84 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.Map; - -import scala.tools.asm.MethodVisitor; - -/** - * A node that represents a line number declaration. These nodes are pseudo - * instruction nodes in order to be inserted in an instruction list. - * - * @author Eric Bruneton - */ -public class LineNumberNode extends AbstractInsnNode { - - /** - * A line number. This number refers to the source file from which the class - * was compiled. - */ - public int line; - - /** - * The first instruction corresponding to this line number. - */ - public LabelNode start; - - /** - * Constructs a new {@link LineNumberNode}. - * - * @param line - * a line number. This number refers to the source file from - * which the class was compiled. - * @param start - * the first instruction corresponding to this line number. - */ - public LineNumberNode(final int line, final LabelNode start) { - super(-1); - this.line = line; - this.start = start; - } - - @Override - public int getType() { - return LINE; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitLineNumber(line, start.getLabel()); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new LineNumberNode(line, clone(start, labels)); - } -} diff --git a/src/asm/scala/tools/asm/tree/LocalVariableAnnotationNode.java b/src/asm/scala/tools/asm/tree/LocalVariableAnnotationNode.java deleted file mode 100644 index d05b808171..0000000000 --- a/src/asm/scala/tools/asm/tree/LocalVariableAnnotationNode.java +++ /dev/null @@ -1,157 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -package scala.tools.asm.tree; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import scala.tools.asm.Label; -import scala.tools.asm.MethodVisitor; -import scala.tools.asm.Opcodes; -import scala.tools.asm.TypePath; -import scala.tools.asm.TypeReference; - -/** - * A node that represents a type annotation on a local or resource variable. - * - * @author Eric Bruneton - */ -public class LocalVariableAnnotationNode extends TypeAnnotationNode { - - /** - * The fist instructions corresponding to the continuous ranges that make - * the scope of this local variable (inclusive). Must not be null. - */ - public List start; - - /** - * The last instructions corresponding to the continuous ranges that make - * the scope of this local variable (exclusive). This list must have the - * same size as the 'start' list. Must not be null. - */ - public List end; - - /** - * The local variable's index in each range. This list must have the same - * size as the 'start' list. Must not be null. - */ - public List index; - - /** - * Constructs a new {@link LocalVariableAnnotationNode}. Subclasses must - * not use this constructor. Instead, they must use the - * {@link #LocalVariableAnnotationNode(int, TypePath, LabelNode[], LabelNode[], int[], String)} - * version. - * - * @param typeRef - * a reference to the annotated type. See {@link TypeReference}. - * @param typePath - * the path to the annotated type argument, wildcard bound, array - * element type, or static inner type within 'typeRef'. May be - * null if the annotation targets 'typeRef' as a whole. - * @param start - * the fist instructions corresponding to the continuous ranges - * that make the scope of this local variable (inclusive). - * @param end - * the last instructions corresponding to the continuous ranges - * that make the scope of this local variable (exclusive). This - * array must have the same size as the 'start' array. - * @param index - * the local variable's index in each range. This array must have - * the same size as the 'start' array. - * @param desc - * the class descriptor of the annotation class. - */ - public LocalVariableAnnotationNode(int typeRef, TypePath typePath, - LabelNode[] start, LabelNode[] end, int[] index, String desc) { - this(Opcodes.ASM5, typeRef, typePath, start, end, index, desc); - } - - /** - * Constructs a new {@link LocalVariableAnnotationNode}. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - * @param typeRef - * a reference to the annotated type. See {@link TypeReference}. - * @param start - * the fist instructions corresponding to the continuous ranges - * that make the scope of this local variable (inclusive). - * @param end - * the last instructions corresponding to the continuous ranges - * that make the scope of this local variable (exclusive). This - * array must have the same size as the 'start' array. - * @param index - * the local variable's index in each range. This array must have - * the same size as the 'start' array. - * @param typePath - * the path to the annotated type argument, wildcard bound, array - * element type, or static inner type within 'typeRef'. May be - * null if the annotation targets 'typeRef' as a whole. - * @param desc - * the class descriptor of the annotation class. - */ - public LocalVariableAnnotationNode(int api, int typeRef, TypePath typePath, - LabelNode[] start, LabelNode[] end, int[] index, String desc) { - super(api, typeRef, typePath, desc); - this.start = new ArrayList(start.length); - this.start.addAll(Arrays.asList(start)); - this.end = new ArrayList(end.length); - this.end.addAll(Arrays.asList(end)); - this.index = new ArrayList(index.length); - for (int i : index) { - this.index.add(i); - } - } - - /** - * Makes the given visitor visit this type annotation. - * - * @param mv - * the visitor that must visit this annotation. - * @param visible - * true if the annotation is visible at runtime. - */ - public void accept(final MethodVisitor mv, boolean visible) { - Label[] start = new Label[this.start.size()]; - Label[] end = new Label[this.end.size()]; - int[] index = new int[this.index.size()]; - for (int i = 0; i < start.length; ++i) { - start[i] = this.start.get(i).getLabel(); - end[i] = this.end.get(i).getLabel(); - index[i] = this.index.get(i); - } - accept(mv.visitLocalVariableAnnotation(typeRef, typePath, start, end, - index, desc, true)); - } -} diff --git a/src/asm/scala/tools/asm/tree/LocalVariableNode.java b/src/asm/scala/tools/asm/tree/LocalVariableNode.java deleted file mode 100644 index 0d8e27356f..0000000000 --- a/src/asm/scala/tools/asm/tree/LocalVariableNode.java +++ /dev/null @@ -1,112 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import scala.tools.asm.MethodVisitor; - -/** - * A node that represents a local variable declaration. - * - * @author Eric Bruneton - */ -public class LocalVariableNode { - - /** - * The name of a local variable. - */ - public String name; - - /** - * The type descriptor of this local variable. - */ - public String desc; - - /** - * The signature of this local variable. May be null. - */ - public String signature; - - /** - * The first instruction corresponding to the scope of this local variable - * (inclusive). - */ - public LabelNode start; - - /** - * The last instruction corresponding to the scope of this local variable - * (exclusive). - */ - public LabelNode end; - - /** - * The local variable's index. - */ - public int index; - - /** - * Constructs a new {@link LocalVariableNode}. - * - * @param name - * the name of a local variable. - * @param desc - * the type descriptor of this local variable. - * @param signature - * the signature of this local variable. May be null. - * @param start - * the first instruction corresponding to the scope of this local - * variable (inclusive). - * @param end - * the last instruction corresponding to the scope of this local - * variable (exclusive). - * @param index - * the local variable's index. - */ - public LocalVariableNode(final String name, final String desc, - final String signature, final LabelNode start, final LabelNode end, - final int index) { - this.name = name; - this.desc = desc; - this.signature = signature; - this.start = start; - this.end = end; - this.index = index; - } - - /** - * Makes the given visitor visit this local variable declaration. - * - * @param mv - * a method visitor. - */ - public void accept(final MethodVisitor mv) { - mv.visitLocalVariable(name, desc, signature, start.getLabel(), - end.getLabel(), index); - } -} diff --git a/src/asm/scala/tools/asm/tree/LookupSwitchInsnNode.java b/src/asm/scala/tools/asm/tree/LookupSwitchInsnNode.java deleted file mode 100644 index 7db2f53ff4..0000000000 --- a/src/asm/scala/tools/asm/tree/LookupSwitchInsnNode.java +++ /dev/null @@ -1,118 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import scala.tools.asm.Label; -import scala.tools.asm.MethodVisitor; -import scala.tools.asm.Opcodes; - -/** - * A node that represents a LOOKUPSWITCH instruction. - * - * @author Eric Bruneton - */ -public class LookupSwitchInsnNode extends AbstractInsnNode { - - /** - * Beginning of the default handler block. - */ - public LabelNode dflt; - - /** - * The values of the keys. This list is a list of {@link Integer} objects. - */ - public List keys; - - /** - * Beginnings of the handler blocks. This list is a list of - * {@link LabelNode} objects. - */ - public List labels; - - /** - * Constructs a new {@link LookupSwitchInsnNode}. - * - * @param dflt - * beginning of the default handler block. - * @param keys - * the values of the keys. - * @param labels - * beginnings of the handler blocks. labels[i] is the - * beginning of the handler block for the keys[i] key. - */ - public LookupSwitchInsnNode(final LabelNode dflt, final int[] keys, - final LabelNode[] labels) { - super(Opcodes.LOOKUPSWITCH); - this.dflt = dflt; - this.keys = new ArrayList(keys == null ? 0 : keys.length); - this.labels = new ArrayList(labels == null ? 0 - : labels.length); - if (keys != null) { - for (int i = 0; i < keys.length; ++i) { - this.keys.add(new Integer(keys[i])); - } - } - if (labels != null) { - this.labels.addAll(Arrays.asList(labels)); - } - } - - @Override - public int getType() { - return LOOKUPSWITCH_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - int[] keys = new int[this.keys.size()]; - for (int i = 0; i < keys.length; ++i) { - keys[i] = this.keys.get(i).intValue(); - } - Label[] labels = new Label[this.labels.size()]; - for (int i = 0; i < labels.length; ++i) { - labels[i] = this.labels.get(i).getLabel(); - } - mv.visitLookupSwitchInsn(dflt.getLabel(), keys, labels); - acceptAnnotations(mv); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - LookupSwitchInsnNode clone = new LookupSwitchInsnNode(clone(dflt, - labels), null, clone(this.labels, labels)); - clone.keys.addAll(keys); - return clone.cloneAnnotations(this); - } -} diff --git a/src/asm/scala/tools/asm/tree/MethodInsnNode.java b/src/asm/scala/tools/asm/tree/MethodInsnNode.java deleted file mode 100644 index 30c7854646..0000000000 --- a/src/asm/scala/tools/asm/tree/MethodInsnNode.java +++ /dev/null @@ -1,141 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.Map; - -import scala.tools.asm.MethodVisitor; -import scala.tools.asm.Opcodes; - -/** - * A node that represents a method instruction. A method instruction is an - * instruction that invokes a method. - * - * @author Eric Bruneton - */ -public class MethodInsnNode extends AbstractInsnNode { - - /** - * The internal name of the method's owner class (see - * {@link scala.tools.asm.Type#getInternalName() getInternalName}). - * For methods of arrays, e.g., clone(), the array type descriptor. - */ - public String owner; - - /** - * The method's name. - */ - public String name; - - /** - * The method's descriptor (see {@link scala.tools.asm.Type}). - */ - public String desc; - - /** - * If the method's owner class if an interface. - */ - public boolean itf; - - /** - * Constructs a new {@link MethodInsnNode}. - * - * @param opcode - * the opcode of the type instruction to be constructed. This - * opcode must be INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or - * INVOKEINTERFACE. - * @param owner - * the internal name of the method's owner class (see - * {@link scala.tools.asm.Type#getInternalName() - * getInternalName}). - * @param name - * the method's name. - * @param desc - * the method's descriptor (see {@link scala.tools.asm.Type}). - */ - @Deprecated - public MethodInsnNode(final int opcode, final String owner, - final String name, final String desc) { - this(opcode, owner, name, desc, opcode == Opcodes.INVOKEINTERFACE); - } - - /** - * Constructs a new {@link MethodInsnNode}. - * - * @param opcode - * the opcode of the type instruction to be constructed. This - * opcode must be INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or - * INVOKEINTERFACE. - * @param owner - * the internal name of the method's owner class (see - * {@link scala.tools.asm.Type#getInternalName() - * getInternalName}). - * @param name - * the method's name. - * @param desc - * the method's descriptor (see {@link scala.tools.asm.Type}). - * @param itf - * if the method's owner class is an interface. - */ - public MethodInsnNode(final int opcode, final String owner, - final String name, final String desc, final boolean itf) { - super(opcode); - this.owner = owner; - this.name = name; - this.desc = desc; - this.itf = itf; - } - - /** - * Sets the opcode of this instruction. - * - * @param opcode - * the new instruction opcode. This opcode must be INVOKEVIRTUAL, - * INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE. - */ - public void setOpcode(final int opcode) { - this.opcode = opcode; - } - - @Override - public int getType() { - return METHOD_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitMethodInsn(opcode, owner, name, desc, itf); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new MethodInsnNode(opcode, owner, name, desc, itf); - } -} diff --git a/src/asm/scala/tools/asm/tree/MethodNode.java b/src/asm/scala/tools/asm/tree/MethodNode.java deleted file mode 100644 index 3dec50e02c..0000000000 --- a/src/asm/scala/tools/asm/tree/MethodNode.java +++ /dev/null @@ -1,839 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import scala.tools.asm.AnnotationVisitor; -import scala.tools.asm.Attribute; -import scala.tools.asm.ClassVisitor; -import scala.tools.asm.Handle; -import scala.tools.asm.Label; -import scala.tools.asm.MethodVisitor; -import scala.tools.asm.Opcodes; -import scala.tools.asm.Type; -import scala.tools.asm.TypePath; - -/** - * A node that represents a method. - * - * @author Eric Bruneton - */ -public class MethodNode extends MethodVisitor { - - /** - * The method's access flags (see {@link Opcodes}). This field also - * indicates if the method is synthetic and/or deprecated. - */ - public int access; - - /** - * The method's name. - */ - public String name; - - /** - * The method's descriptor (see {@link Type}). - */ - public String desc; - - /** - * The method's signature. May be null. - */ - public String signature; - - /** - * The internal names of the method's exception classes (see - * {@link Type#getInternalName() getInternalName}). This list is a list of - * {@link String} objects. - */ - public List exceptions; - - /** - * The method parameter info (access flags and name) - */ - public List parameters; - - /** - * The runtime visible annotations of this method. This list is a list of - * {@link AnnotationNode} objects. May be null. - * - * @associates scala.tools.asm.tree.AnnotationNode - * @label visible - */ - public List visibleAnnotations; - - /** - * The runtime invisible annotations of this method. This list is a list of - * {@link AnnotationNode} objects. May be null. - * - * @associates scala.tools.asm.tree.AnnotationNode - * @label invisible - */ - public List invisibleAnnotations; - - /** - * The runtime visible type annotations of this method. This list is a list - * of {@link TypeAnnotationNode} objects. May be null. - * - * @associates scala.tools.asm.tree.TypeAnnotationNode - * @label visible - */ - public List visibleTypeAnnotations; - - /** - * The runtime invisible type annotations of this method. This list is a - * list of {@link TypeAnnotationNode} objects. May be null. - * - * @associates scala.tools.asm.tree.TypeAnnotationNode - * @label invisible - */ - public List invisibleTypeAnnotations; - - /** - * The non standard attributes of this method. This list is a list of - * {@link Attribute} objects. May be null. - * - * @associates scala.tools.asm.Attribute - */ - public List attrs; - - /** - * The default value of this annotation interface method. This field must be - * a {@link Byte}, {@link Boolean}, {@link Character}, {@link Short}, - * {@link Integer}, {@link Long}, {@link Float}, {@link Double}, - * {@link String} or {@link Type}, or an two elements String array (for - * enumeration values), a {@link AnnotationNode}, or a {@link List} of - * values of one of the preceding types. May be null. - */ - public Object annotationDefault; - - /** - * The runtime visible parameter annotations of this method. These lists are - * lists of {@link AnnotationNode} objects. May be null. - * - * @associates scala.tools.asm.tree.AnnotationNode - * @label invisible parameters - */ - public List[] visibleParameterAnnotations; - - /** - * The runtime invisible parameter annotations of this method. These lists - * are lists of {@link AnnotationNode} objects. May be null. - * - * @associates scala.tools.asm.tree.AnnotationNode - * @label visible parameters - */ - public List[] invisibleParameterAnnotations; - - /** - * The instructions of this method. This list is a list of - * {@link AbstractInsnNode} objects. - * - * @associates scala.tools.asm.tree.AbstractInsnNode - * @label instructions - */ - public InsnList instructions; - - /** - * The try catch blocks of this method. This list is a list of - * {@link TryCatchBlockNode} objects. - * - * @associates scala.tools.asm.tree.TryCatchBlockNode - */ - public List tryCatchBlocks; - - /** - * The maximum stack size of this method. - */ - public int maxStack; - - /** - * The maximum number of local variables of this method. - */ - public int maxLocals; - - /** - * The local variables of this method. This list is a list of - * {@link LocalVariableNode} objects. May be null - * - * @associates scala.tools.asm.tree.LocalVariableNode - */ - public List localVariables; - - /** - * The visible local variable annotations of this method. This list is a - * list of {@link LocalVariableAnnotationNode} objects. May be null - * - * @associates scala.tools.asm.tree.LocalVariableAnnotationNode - */ - public List visibleLocalVariableAnnotations; - - /** - * The invisible local variable annotations of this method. This list is a - * list of {@link LocalVariableAnnotationNode} objects. May be null - * - * @associates scala.tools.asm.tree.LocalVariableAnnotationNode - */ - public List invisibleLocalVariableAnnotations; - - /** - * If the accept method has been called on this object. - */ - private boolean visited; - - /** - * Constructs an uninitialized {@link MethodNode}. Subclasses must not - * use this constructor. Instead, they must use the - * {@link #MethodNode(int)} version. - * - * @throws IllegalStateException - * If a subclass calls this constructor. - */ - public MethodNode() { - this(Opcodes.ASM5); - if (getClass() != MethodNode.class) { - throw new IllegalStateException(); - } - } - - /** - * Constructs an uninitialized {@link MethodNode}. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - */ - public MethodNode(final int api) { - super(api); - this.instructions = new InsnList(); - } - - /** - * Constructs a new {@link MethodNode}. Subclasses must not use this - * constructor. Instead, they must use the - * {@link #MethodNode(int, int, String, String, String, String[])} version. - * - * @param access - * the method's access flags (see {@link Opcodes}). This - * parameter also indicates if the method is synthetic and/or - * deprecated. - * @param name - * the method's name. - * @param desc - * the method's descriptor (see {@link Type}). - * @param signature - * the method's signature. May be null. - * @param exceptions - * the internal names of the method's exception classes (see - * {@link Type#getInternalName() getInternalName}). May be - * null. - * @throws IllegalStateException - * If a subclass calls this constructor. - */ - public MethodNode(final int access, final String name, final String desc, - final String signature, final String[] exceptions) { - this(Opcodes.ASM5, access, name, desc, signature, exceptions); - if (getClass() != MethodNode.class) { - throw new IllegalStateException(); - } - } - - /** - * Constructs a new {@link MethodNode}. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - * @param access - * the method's access flags (see {@link Opcodes}). This - * parameter also indicates if the method is synthetic and/or - * deprecated. - * @param name - * the method's name. - * @param desc - * the method's descriptor (see {@link Type}). - * @param signature - * the method's signature. May be null. - * @param exceptions - * the internal names of the method's exception classes (see - * {@link Type#getInternalName() getInternalName}). May be - * null. - */ - public MethodNode(final int api, final int access, final String name, - final String desc, final String signature, final String[] exceptions) { - super(api); - this.access = access; - this.name = name; - this.desc = desc; - this.signature = signature; - this.exceptions = new ArrayList(exceptions == null ? 0 - : exceptions.length); - boolean isAbstract = (access & Opcodes.ACC_ABSTRACT) != 0; - if (!isAbstract) { - this.localVariables = new ArrayList(5); - } - this.tryCatchBlocks = new ArrayList(); - if (exceptions != null) { - this.exceptions.addAll(Arrays.asList(exceptions)); - } - this.instructions = new InsnList(); - } - - // ------------------------------------------------------------------------ - // Implementation of the MethodVisitor abstract class - // ------------------------------------------------------------------------ - - @Override - public void visitParameter(String name, int access) { - if (parameters == null) { - parameters = new ArrayList(5); - } - parameters.add(new ParameterNode(name, access)); - } - - @Override - @SuppressWarnings("serial") - public AnnotationVisitor visitAnnotationDefault() { - return new AnnotationNode(new ArrayList(0) { - @Override - public boolean add(final Object o) { - annotationDefault = o; - return super.add(o); - } - }); - } - - @Override - public AnnotationVisitor visitAnnotation(final String desc, - final boolean visible) { - AnnotationNode an = new AnnotationNode(desc); - if (visible) { - if (visibleAnnotations == null) { - visibleAnnotations = new ArrayList(1); - } - visibleAnnotations.add(an); - } else { - if (invisibleAnnotations == null) { - invisibleAnnotations = new ArrayList(1); - } - invisibleAnnotations.add(an); - } - return an; - } - - @Override - public AnnotationVisitor visitTypeAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc); - if (visible) { - if (visibleTypeAnnotations == null) { - visibleTypeAnnotations = new ArrayList(1); - } - visibleTypeAnnotations.add(an); - } else { - if (invisibleTypeAnnotations == null) { - invisibleTypeAnnotations = new ArrayList(1); - } - invisibleTypeAnnotations.add(an); - } - return an; - } - - @Override - public AnnotationVisitor visitParameterAnnotation(final int parameter, - final String desc, final boolean visible) { - AnnotationNode an = new AnnotationNode(desc); - if (visible) { - if (visibleParameterAnnotations == null) { - int params = Type.getArgumentTypes(this.desc).length; - visibleParameterAnnotations = (List[]) new List[params]; - } - if (visibleParameterAnnotations[parameter] == null) { - visibleParameterAnnotations[parameter] = new ArrayList( - 1); - } - visibleParameterAnnotations[parameter].add(an); - } else { - if (invisibleParameterAnnotations == null) { - int params = Type.getArgumentTypes(this.desc).length; - invisibleParameterAnnotations = (List[]) new List[params]; - } - if (invisibleParameterAnnotations[parameter] == null) { - invisibleParameterAnnotations[parameter] = new ArrayList( - 1); - } - invisibleParameterAnnotations[parameter].add(an); - } - return an; - } - - @Override - public void visitAttribute(final Attribute attr) { - if (attrs == null) { - attrs = new ArrayList(1); - } - attrs.add(attr); - } - - @Override - public void visitCode() { - } - - @Override - public void visitFrame(final int type, final int nLocal, - final Object[] local, final int nStack, final Object[] stack) { - instructions.add(new FrameNode(type, nLocal, local == null ? null - : getLabelNodes(local), nStack, stack == null ? null - : getLabelNodes(stack))); - } - - @Override - public void visitInsn(final int opcode) { - instructions.add(new InsnNode(opcode)); - } - - @Override - public void visitIntInsn(final int opcode, final int operand) { - instructions.add(new IntInsnNode(opcode, operand)); - } - - @Override - public void visitVarInsn(final int opcode, final int var) { - instructions.add(new VarInsnNode(opcode, var)); - } - - @Override - public void visitTypeInsn(final int opcode, final String type) { - instructions.add(new TypeInsnNode(opcode, type)); - } - - @Override - public void visitFieldInsn(final int opcode, final String owner, - final String name, final String desc) { - instructions.add(new FieldInsnNode(opcode, owner, name, desc)); - } - - @Deprecated - @Override - public void visitMethodInsn(int opcode, String owner, String name, - String desc) { - if (api >= Opcodes.ASM5) { - super.visitMethodInsn(opcode, owner, name, desc); - return; - } - instructions.add(new MethodInsnNode(opcode, owner, name, desc)); - } - - @Override - public void visitMethodInsn(int opcode, String owner, String name, - String desc, boolean itf) { - if (api < Opcodes.ASM5) { - super.visitMethodInsn(opcode, owner, name, desc, itf); - return; - } - instructions.add(new MethodInsnNode(opcode, owner, name, desc, itf)); - } - - @Override - public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, - Object... bsmArgs) { - instructions.add(new InvokeDynamicInsnNode(name, desc, bsm, bsmArgs)); - } - - @Override - public void visitJumpInsn(final int opcode, final Label label) { - instructions.add(new JumpInsnNode(opcode, getLabelNode(label))); - } - - @Override - public void visitLabel(final Label label) { - instructions.add(getLabelNode(label)); - } - - @Override - public void visitLdcInsn(final Object cst) { - instructions.add(new LdcInsnNode(cst)); - } - - @Override - public void visitIincInsn(final int var, final int increment) { - instructions.add(new IincInsnNode(var, increment)); - } - - @Override - public void visitTableSwitchInsn(final int min, final int max, - final Label dflt, final Label... labels) { - instructions.add(new TableSwitchInsnNode(min, max, getLabelNode(dflt), - getLabelNodes(labels))); - } - - @Override - public void visitLookupSwitchInsn(final Label dflt, final int[] keys, - final Label[] labels) { - instructions.add(new LookupSwitchInsnNode(getLabelNode(dflt), keys, - getLabelNodes(labels))); - } - - @Override - public void visitMultiANewArrayInsn(final String desc, final int dims) { - instructions.add(new MultiANewArrayInsnNode(desc, dims)); - } - - @Override - public AnnotationVisitor visitInsnAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - // Finds the last real instruction, i.e. the instruction targeted by - // this annotation. - AbstractInsnNode insn = instructions.getLast(); - while (insn.getOpcode() == -1) { - insn = insn.getPrevious(); - } - // Adds the annotation to this instruction. - TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc); - if (visible) { - if (insn.visibleTypeAnnotations == null) { - insn.visibleTypeAnnotations = new ArrayList( - 1); - } - insn.visibleTypeAnnotations.add(an); - } else { - if (insn.invisibleTypeAnnotations == null) { - insn.invisibleTypeAnnotations = new ArrayList( - 1); - } - insn.invisibleTypeAnnotations.add(an); - } - return an; - } - - @Override - public void visitTryCatchBlock(final Label start, final Label end, - final Label handler, final String type) { - tryCatchBlocks.add(new TryCatchBlockNode(getLabelNode(start), - getLabelNode(end), getLabelNode(handler), type)); - } - - @Override - public AnnotationVisitor visitTryCatchAnnotation(int typeRef, - TypePath typePath, String desc, boolean visible) { - TryCatchBlockNode tcb = tryCatchBlocks.get((typeRef & 0x00FFFF00) >> 8); - TypeAnnotationNode an = new TypeAnnotationNode(typeRef, typePath, desc); - if (visible) { - if (tcb.visibleTypeAnnotations == null) { - tcb.visibleTypeAnnotations = new ArrayList( - 1); - } - tcb.visibleTypeAnnotations.add(an); - } else { - if (tcb.invisibleTypeAnnotations == null) { - tcb.invisibleTypeAnnotations = new ArrayList( - 1); - } - tcb.invisibleTypeAnnotations.add(an); - } - return an; - } - - @Override - public void visitLocalVariable(final String name, final String desc, - final String signature, final Label start, final Label end, - final int index) { - localVariables.add(new LocalVariableNode(name, desc, signature, - getLabelNode(start), getLabelNode(end), index)); - } - - @Override - public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, - TypePath typePath, Label[] start, Label[] end, int[] index, - String desc, boolean visible) { - LocalVariableAnnotationNode an = new LocalVariableAnnotationNode( - typeRef, typePath, getLabelNodes(start), getLabelNodes(end), - index, desc); - if (visible) { - if (visibleLocalVariableAnnotations == null) { - visibleLocalVariableAnnotations = new ArrayList( - 1); - } - visibleLocalVariableAnnotations.add(an); - } else { - if (invisibleLocalVariableAnnotations == null) { - invisibleLocalVariableAnnotations = new ArrayList( - 1); - } - invisibleLocalVariableAnnotations.add(an); - } - return an; - } - - @Override - public void visitLineNumber(final int line, final Label start) { - instructions.add(new LineNumberNode(line, getLabelNode(start))); - } - - @Override - public void visitMaxs(final int maxStack, final int maxLocals) { - this.maxStack = maxStack; - this.maxLocals = maxLocals; - } - - @Override - public void visitEnd() { - } - - /** - * Returns the LabelNode corresponding to the given Label. Creates a new - * LabelNode if necessary. The default implementation of this method uses - * the {@link Label#info} field to store associations between labels and - * label nodes. - * - * @param l - * a Label. - * @return the LabelNode corresponding to l. - */ - protected LabelNode getLabelNode(final Label l) { - if (!(l.info instanceof LabelNode)) { - l.info = new LabelNode(l); - } - return (LabelNode) l.info; - } - - private LabelNode[] getLabelNodes(final Label[] l) { - LabelNode[] nodes = new LabelNode[l.length]; - for (int i = 0; i < l.length; ++i) { - nodes[i] = getLabelNode(l[i]); - } - return nodes; - } - - private Object[] getLabelNodes(final Object[] objs) { - Object[] nodes = new Object[objs.length]; - for (int i = 0; i < objs.length; ++i) { - Object o = objs[i]; - if (o instanceof Label) { - o = getLabelNode((Label) o); - } - nodes[i] = o; - } - return nodes; - } - - // ------------------------------------------------------------------------ - // Accept method - // ------------------------------------------------------------------------ - - /** - * Checks that this method node is compatible with the given ASM API - * version. This methods checks that this node, and all its nodes - * recursively, do not contain elements that were introduced in more recent - * versions of the ASM API than the given version. - * - * @param api - * an ASM API version. Must be one of {@link Opcodes#ASM4} or - * {@link Opcodes#ASM5}. - */ - public void check(final int api) { - if (api == Opcodes.ASM4) { - if (visibleTypeAnnotations != null - && visibleTypeAnnotations.size() > 0) { - throw new RuntimeException(); - } - if (invisibleTypeAnnotations != null - && invisibleTypeAnnotations.size() > 0) { - throw new RuntimeException(); - } - int n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size(); - for (int i = 0; i < n; ++i) { - TryCatchBlockNode tcb = tryCatchBlocks.get(i); - if (tcb.visibleTypeAnnotations != null - && tcb.visibleTypeAnnotations.size() > 0) { - throw new RuntimeException(); - } - if (tcb.invisibleTypeAnnotations != null - && tcb.invisibleTypeAnnotations.size() > 0) { - throw new RuntimeException(); - } - } - for (int i = 0; i < instructions.size(); ++i) { - AbstractInsnNode insn = instructions.get(i); - if (insn.visibleTypeAnnotations != null - && insn.visibleTypeAnnotations.size() > 0) { - throw new RuntimeException(); - } - if (insn.invisibleTypeAnnotations != null - && insn.invisibleTypeAnnotations.size() > 0) { - throw new RuntimeException(); - } - if (insn instanceof MethodInsnNode) { - boolean itf = ((MethodInsnNode) insn).itf; - if (itf != (insn.opcode == Opcodes.INVOKEINTERFACE)) { - throw new RuntimeException(); - } - } - } - if (visibleLocalVariableAnnotations != null - && visibleLocalVariableAnnotations.size() > 0) { - throw new RuntimeException(); - } - if (invisibleLocalVariableAnnotations != null - && invisibleLocalVariableAnnotations.size() > 0) { - throw new RuntimeException(); - } - } - } - - /** - * Makes the given class visitor visit this method. - * - * @param cv - * a class visitor. - */ - public void accept(final ClassVisitor cv) { - String[] exceptions = new String[this.exceptions.size()]; - this.exceptions.toArray(exceptions); - MethodVisitor mv = cv.visitMethod(access, name, desc, signature, - exceptions); - if (mv != null) { - accept(mv); - } - } - - /** - * Makes the given method visitor visit this method. - * - * @param mv - * a method visitor. - */ - public void accept(final MethodVisitor mv) { - // visits the method parameters - int i, j, n; - n = parameters == null ? 0 : parameters.size(); - for (i = 0; i < n; i++) { - ParameterNode parameter = parameters.get(i); - mv.visitParameter(parameter.name, parameter.access); - } - // visits the method attributes - if (annotationDefault != null) { - AnnotationVisitor av = mv.visitAnnotationDefault(); - AnnotationNode.accept(av, null, annotationDefault); - if (av != null) { - av.visitEnd(); - } - } - n = visibleAnnotations == null ? 0 : visibleAnnotations.size(); - for (i = 0; i < n; ++i) { - AnnotationNode an = visibleAnnotations.get(i); - an.accept(mv.visitAnnotation(an.desc, true)); - } - n = invisibleAnnotations == null ? 0 : invisibleAnnotations.size(); - for (i = 0; i < n; ++i) { - AnnotationNode an = invisibleAnnotations.get(i); - an.accept(mv.visitAnnotation(an.desc, false)); - } - n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations.size(); - for (i = 0; i < n; ++i) { - TypeAnnotationNode an = visibleTypeAnnotations.get(i); - an.accept(mv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, - true)); - } - n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations - .size(); - for (i = 0; i < n; ++i) { - TypeAnnotationNode an = invisibleTypeAnnotations.get(i); - an.accept(mv.visitTypeAnnotation(an.typeRef, an.typePath, an.desc, - false)); - } - n = visibleParameterAnnotations == null ? 0 - : visibleParameterAnnotations.length; - for (i = 0; i < n; ++i) { - List l = visibleParameterAnnotations[i]; - if (l == null) { - continue; - } - for (j = 0; j < l.size(); ++j) { - AnnotationNode an = (AnnotationNode) l.get(j); - an.accept(mv.visitParameterAnnotation(i, an.desc, true)); - } - } - n = invisibleParameterAnnotations == null ? 0 - : invisibleParameterAnnotations.length; - for (i = 0; i < n; ++i) { - List l = invisibleParameterAnnotations[i]; - if (l == null) { - continue; - } - for (j = 0; j < l.size(); ++j) { - AnnotationNode an = (AnnotationNode) l.get(j); - an.accept(mv.visitParameterAnnotation(i, an.desc, false)); - } - } - if (visited) { - instructions.resetLabels(); - } - n = attrs == null ? 0 : attrs.size(); - for (i = 0; i < n; ++i) { - mv.visitAttribute(attrs.get(i)); - } - // visits the method's code - if (instructions.size() > 0) { - mv.visitCode(); - // visits try catch blocks - n = tryCatchBlocks == null ? 0 : tryCatchBlocks.size(); - for (i = 0; i < n; ++i) { - tryCatchBlocks.get(i).updateIndex(i); - tryCatchBlocks.get(i).accept(mv); - } - // visits instructions - instructions.accept(mv); - // visits local variables - n = localVariables == null ? 0 : localVariables.size(); - for (i = 0; i < n; ++i) { - localVariables.get(i).accept(mv); - } - // visits local variable annotations - n = visibleLocalVariableAnnotations == null ? 0 - : visibleLocalVariableAnnotations.size(); - for (i = 0; i < n; ++i) { - visibleLocalVariableAnnotations.get(i).accept(mv, true); - } - n = invisibleLocalVariableAnnotations == null ? 0 - : invisibleLocalVariableAnnotations.size(); - for (i = 0; i < n; ++i) { - invisibleLocalVariableAnnotations.get(i).accept(mv, false); - } - // visits maxs - mv.visitMaxs(maxStack, maxLocals); - visited = true; - } - mv.visitEnd(); - } -} diff --git a/src/asm/scala/tools/asm/tree/MultiANewArrayInsnNode.java b/src/asm/scala/tools/asm/tree/MultiANewArrayInsnNode.java deleted file mode 100644 index a8339a20b5..0000000000 --- a/src/asm/scala/tools/asm/tree/MultiANewArrayInsnNode.java +++ /dev/null @@ -1,84 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.Map; - -import scala.tools.asm.MethodVisitor; -import scala.tools.asm.Opcodes; - -/** - * A node that represents a MULTIANEWARRAY instruction. - * - * @author Eric Bruneton - */ -public class MultiANewArrayInsnNode extends AbstractInsnNode { - - /** - * An array type descriptor (see {@link scala.tools.asm.Type}). - */ - public String desc; - - /** - * Number of dimensions of the array to allocate. - */ - public int dims; - - /** - * Constructs a new {@link MultiANewArrayInsnNode}. - * - * @param desc - * an array type descriptor (see {@link scala.tools.asm.Type}). - * @param dims - * number of dimensions of the array to allocate. - */ - public MultiANewArrayInsnNode(final String desc, final int dims) { - super(Opcodes.MULTIANEWARRAY); - this.desc = desc; - this.dims = dims; - } - - @Override - public int getType() { - return MULTIANEWARRAY_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitMultiANewArrayInsn(desc, dims); - acceptAnnotations(mv); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new MultiANewArrayInsnNode(desc, dims).cloneAnnotations(this); - } - -} diff --git a/src/asm/scala/tools/asm/tree/ParameterNode.java b/src/asm/scala/tools/asm/tree/ParameterNode.java deleted file mode 100644 index a3e55d5629..0000000000 --- a/src/asm/scala/tools/asm/tree/ParameterNode.java +++ /dev/null @@ -1,76 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import scala.tools.asm.MethodVisitor; - -/** - * A node that represents a parameter access and name. - * - * @author Remi Forax - */ -public class ParameterNode { - /** - * The parameter's name. - */ - public String name; - - /** - * The parameter's access flags (see {@link scala.tools.asm.Opcodes}). - * Valid values are ACC_FINAL, ACC_SYNTHETIC and - * ACC_MANDATED. - */ - public int access; - - /** - * Constructs a new {@link ParameterNode}. - * - * @param access - * The parameter's access flags. Valid values are - * ACC_FINAL, ACC_SYNTHETIC or/and - * ACC_MANDATED (see {@link scala.tools.asm.Opcodes}). - * @param name - * the parameter's name. - */ - public ParameterNode(final String name, final int access) { - this.name = name; - this.access = access; - } - - /** - * Makes the given visitor visit this parameter declaration. - * - * @param mv - * a method visitor. - */ - public void accept(final MethodVisitor mv) { - mv.visitParameter(name, access); - } -} diff --git a/src/asm/scala/tools/asm/tree/TableSwitchInsnNode.java b/src/asm/scala/tools/asm/tree/TableSwitchInsnNode.java deleted file mode 100644 index fb17b9e2e9..0000000000 --- a/src/asm/scala/tools/asm/tree/TableSwitchInsnNode.java +++ /dev/null @@ -1,114 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import scala.tools.asm.Label; -import scala.tools.asm.MethodVisitor; -import scala.tools.asm.Opcodes; - -/** - * A node that represents a TABLESWITCH instruction. - * - * @author Eric Bruneton - */ -public class TableSwitchInsnNode extends AbstractInsnNode { - - /** - * The minimum key value. - */ - public int min; - - /** - * The maximum key value. - */ - public int max; - - /** - * Beginning of the default handler block. - */ - public LabelNode dflt; - - /** - * Beginnings of the handler blocks. This list is a list of - * {@link LabelNode} objects. - */ - public List labels; - - /** - * Constructs a new {@link TableSwitchInsnNode}. - * - * @param min - * the minimum key value. - * @param max - * the maximum key value. - * @param dflt - * beginning of the default handler block. - * @param labels - * beginnings of the handler blocks. labels[i] is the - * beginning of the handler block for the min + i key. - */ - public TableSwitchInsnNode(final int min, final int max, - final LabelNode dflt, final LabelNode... labels) { - super(Opcodes.TABLESWITCH); - this.min = min; - this.max = max; - this.dflt = dflt; - this.labels = new ArrayList(); - if (labels != null) { - this.labels.addAll(Arrays.asList(labels)); - } - } - - @Override - public int getType() { - return TABLESWITCH_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - Label[] labels = new Label[this.labels.size()]; - for (int i = 0; i < labels.length; ++i) { - labels[i] = this.labels.get(i).getLabel(); - } - mv.visitTableSwitchInsn(min, max, dflt.getLabel(), labels); - acceptAnnotations(mv); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new TableSwitchInsnNode(min, max, clone(dflt, labels), clone( - this.labels, labels)).cloneAnnotations(this); - } -} diff --git a/src/asm/scala/tools/asm/tree/TryCatchBlockNode.java b/src/asm/scala/tools/asm/tree/TryCatchBlockNode.java deleted file mode 100644 index c639b9aa8b..0000000000 --- a/src/asm/scala/tools/asm/tree/TryCatchBlockNode.java +++ /dev/null @@ -1,153 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.List; - -import scala.tools.asm.MethodVisitor; - -/** - * A node that represents a try catch block. - * - * @author Eric Bruneton - */ -public class TryCatchBlockNode { - - /** - * Beginning of the exception handler's scope (inclusive). - */ - public LabelNode start; - - /** - * End of the exception handler's scope (exclusive). - */ - public LabelNode end; - - /** - * Beginning of the exception handler's code. - */ - public LabelNode handler; - - /** - * Internal name of the type of exceptions handled by the handler. May be - * null to catch any exceptions (for "finally" blocks). - */ - public String type; - - /** - * The runtime visible type annotations on the exception handler type. This - * list is a list of {@link TypeAnnotationNode} objects. May be - * null. - * - * @associates scala.tools.asm.tree.TypeAnnotationNode - * @label visible - */ - public List visibleTypeAnnotations; - - /** - * The runtime invisible type annotations on the exception handler type. - * This list is a list of {@link TypeAnnotationNode} objects. May be - * null. - * - * @associates scala.tools.asm.tree.TypeAnnotationNode - * @label invisible - */ - public List invisibleTypeAnnotations; - - /** - * Constructs a new {@link TryCatchBlockNode}. - * - * @param start - * beginning of the exception handler's scope (inclusive). - * @param end - * end of the exception handler's scope (exclusive). - * @param handler - * beginning of the exception handler's code. - * @param type - * internal name of the type of exceptions handled by the - * handler, or null to catch any exceptions (for - * "finally" blocks). - */ - public TryCatchBlockNode(final LabelNode start, final LabelNode end, - final LabelNode handler, final String type) { - this.start = start; - this.end = end; - this.handler = handler; - this.type = type; - } - - /** - * Updates the index of this try catch block in the method's list of try - * catch block nodes. This index maybe stored in the 'target' field of the - * type annotations of this block. - * - * @param index - * the new index of this try catch block in the method's list of - * try catch block nodes. - */ - public void updateIndex(final int index) { - int newTypeRef = 0x42000000 | (index << 8); - if (visibleTypeAnnotations != null) { - for (TypeAnnotationNode tan : visibleTypeAnnotations) { - tan.typeRef = newTypeRef; - } - } - if (invisibleTypeAnnotations != null) { - for (TypeAnnotationNode tan : invisibleTypeAnnotations) { - tan.typeRef = newTypeRef; - } - } - } - - /** - * Makes the given visitor visit this try catch block. - * - * @param mv - * a method visitor. - */ - public void accept(final MethodVisitor mv) { - mv.visitTryCatchBlock(start.getLabel(), end.getLabel(), - handler == null ? null : handler.getLabel(), type); - int n = visibleTypeAnnotations == null ? 0 : visibleTypeAnnotations - .size(); - for (int i = 0; i < n; ++i) { - TypeAnnotationNode an = visibleTypeAnnotations.get(i); - an.accept(mv.visitTryCatchAnnotation(an.typeRef, an.typePath, - an.desc, true)); - } - n = invisibleTypeAnnotations == null ? 0 : invisibleTypeAnnotations - .size(); - for (int i = 0; i < n; ++i) { - TypeAnnotationNode an = invisibleTypeAnnotations.get(i); - an.accept(mv.visitTryCatchAnnotation(an.typeRef, an.typePath, - an.desc, false)); - } - } -} diff --git a/src/asm/scala/tools/asm/tree/TypeAnnotationNode.java b/src/asm/scala/tools/asm/tree/TypeAnnotationNode.java deleted file mode 100644 index 73b29624f7..0000000000 --- a/src/asm/scala/tools/asm/tree/TypeAnnotationNode.java +++ /dev/null @@ -1,100 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import scala.tools.asm.Opcodes; -import scala.tools.asm.TypePath; -import scala.tools.asm.TypeReference; - -/** - * A node that represents a type annotationn. - * - * @author Eric Bruneton - */ -public class TypeAnnotationNode extends AnnotationNode { - - /** - * A reference to the annotated type. See {@link TypeReference}. - */ - public int typeRef; - - /** - * The path to the annotated type argument, wildcard bound, array element - * type, or static outer type within the referenced type. May be - * null if the annotation targets 'typeRef' as a whole. - */ - public TypePath typePath; - - /** - * Constructs a new {@link AnnotationNode}. Subclasses must not use this - * constructor. Instead, they must use the - * {@link #TypeAnnotationNode(int, int, TypePath, String)} version. - * - * @param typeRef - * a reference to the annotated type. See {@link TypeReference}. - * @param typePath - * the path to the annotated type argument, wildcard bound, array - * element type, or static inner type within 'typeRef'. May be - * null if the annotation targets 'typeRef' as a whole. - * @param desc - * the class descriptor of the annotation class. - * @throws IllegalStateException - * If a subclass calls this constructor. - */ - public TypeAnnotationNode(final int typeRef, final TypePath typePath, - final String desc) { - this(Opcodes.ASM5, typeRef, typePath, desc); - if (getClass() != TypeAnnotationNode.class) { - throw new IllegalStateException(); - } - } - - /** - * Constructs a new {@link AnnotationNode}. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - * @param typeRef - * a reference to the annotated type. See {@link TypeReference}. - * @param typePath - * the path to the annotated type argument, wildcard bound, array - * element type, or static inner type within 'typeRef'. May be - * null if the annotation targets 'typeRef' as a whole. - * @param desc - * the class descriptor of the annotation class. - */ - public TypeAnnotationNode(final int api, final int typeRef, - final TypePath typePath, final String desc) { - super(api, desc); - this.typeRef = typeRef; - this.typePath = typePath; - } -} diff --git a/src/asm/scala/tools/asm/tree/TypeInsnNode.java b/src/asm/scala/tools/asm/tree/TypeInsnNode.java deleted file mode 100644 index 401400c3cb..0000000000 --- a/src/asm/scala/tools/asm/tree/TypeInsnNode.java +++ /dev/null @@ -1,91 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.Map; - -import scala.tools.asm.MethodVisitor; - -/** - * A node that represents a type instruction. A type instruction is an - * instruction that takes a type descriptor as parameter. - * - * @author Eric Bruneton - */ -public class TypeInsnNode extends AbstractInsnNode { - - /** - * The operand of this instruction. This operand is an internal name (see - * {@link scala.tools.asm.Type}). - */ - public String desc; - - /** - * Constructs a new {@link TypeInsnNode}. - * - * @param opcode - * the opcode of the type instruction to be constructed. This - * opcode must be NEW, ANEWARRAY, CHECKCAST or INSTANCEOF. - * @param desc - * the operand of the instruction to be constructed. This operand - * is an internal name (see {@link scala.tools.asm.Type}). - */ - public TypeInsnNode(final int opcode, final String desc) { - super(opcode); - this.desc = desc; - } - - /** - * Sets the opcode of this instruction. - * - * @param opcode - * the new instruction opcode. This opcode must be NEW, - * ANEWARRAY, CHECKCAST or INSTANCEOF. - */ - public void setOpcode(final int opcode) { - this.opcode = opcode; - } - - @Override - public int getType() { - return TYPE_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitTypeInsn(opcode, desc); - acceptAnnotations(mv); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new TypeInsnNode(opcode, desc).cloneAnnotations(this); - } -} diff --git a/src/asm/scala/tools/asm/tree/VarInsnNode.java b/src/asm/scala/tools/asm/tree/VarInsnNode.java deleted file mode 100644 index 685e4fce2c..0000000000 --- a/src/asm/scala/tools/asm/tree/VarInsnNode.java +++ /dev/null @@ -1,94 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree; - -import java.util.Map; - -import scala.tools.asm.MethodVisitor; - -/** - * A node that represents a local variable instruction. A local variable - * instruction is an instruction that loads or stores the value of a local - * variable. - * - * @author Eric Bruneton - */ -public class VarInsnNode extends AbstractInsnNode { - - /** - * The operand of this instruction. This operand is the index of a local - * variable. - */ - public int var; - - /** - * Constructs a new {@link VarInsnNode}. - * - * @param opcode - * the opcode of the local variable instruction to be - * constructed. This opcode must be ILOAD, LLOAD, FLOAD, DLOAD, - * ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET. - * @param var - * the operand of the instruction to be constructed. This operand - * is the index of a local variable. - */ - public VarInsnNode(final int opcode, final int var) { - super(opcode); - this.var = var; - } - - /** - * Sets the opcode of this instruction. - * - * @param opcode - * the new instruction opcode. This opcode must be ILOAD, LLOAD, - * FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or - * RET. - */ - public void setOpcode(final int opcode) { - this.opcode = opcode; - } - - @Override - public int getType() { - return VAR_INSN; - } - - @Override - public void accept(final MethodVisitor mv) { - mv.visitVarInsn(opcode, var); - acceptAnnotations(mv); - } - - @Override - public AbstractInsnNode clone(final Map labels) { - return new VarInsnNode(opcode, var).cloneAnnotations(this); - } -} diff --git a/src/asm/scala/tools/asm/tree/analysis/Analyzer.java b/src/asm/scala/tools/asm/tree/analysis/Analyzer.java deleted file mode 100644 index ff840aabde..0000000000 --- a/src/asm/scala/tools/asm/tree/analysis/Analyzer.java +++ /dev/null @@ -1,549 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree.analysis; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import scala.tools.asm.Opcodes; -import scala.tools.asm.Type; -import scala.tools.asm.tree.AbstractInsnNode; -import scala.tools.asm.tree.IincInsnNode; -import scala.tools.asm.tree.InsnList; -import scala.tools.asm.tree.JumpInsnNode; -import scala.tools.asm.tree.LabelNode; -import scala.tools.asm.tree.LookupSwitchInsnNode; -import scala.tools.asm.tree.MethodNode; -import scala.tools.asm.tree.TableSwitchInsnNode; -import scala.tools.asm.tree.TryCatchBlockNode; -import scala.tools.asm.tree.VarInsnNode; - -/** - * A semantic bytecode analyzer. This class does not fully check that JSR and - * RET instructions are valid. - * - * @param - * type of the Value used for the analysis. - * - * @author Eric Bruneton - */ -public class Analyzer implements Opcodes { - - private final Interpreter interpreter; - - private int n; - - private InsnList insns; - - private List[] handlers; - - private Frame[] frames; - - private Subroutine[] subroutines; - - private boolean[] queued; - - private int[] queue; - - private int top; - - /** - * Constructs a new {@link Analyzer}. - * - * @param interpreter - * the interpreter to be used to symbolically interpret the - * bytecode instructions. - */ - public Analyzer(final Interpreter interpreter) { - this.interpreter = interpreter; - } - - /** - * Analyzes the given method. - * - * @param owner - * the internal name of the class to which the method belongs. - * @param m - * the method to be analyzed. - * @return the symbolic state of the execution stack frame at each bytecode - * instruction of the method. The size of the returned array is - * equal to the number of instructions (and labels) of the method. A - * given frame is null if and only if the corresponding - * instruction cannot be reached (dead code). - * @throws AnalyzerException - * if a problem occurs during the analysis. - */ - public Frame[] analyze(final String owner, final MethodNode m) - throws AnalyzerException { - if ((m.access & (ACC_ABSTRACT | ACC_NATIVE)) != 0) { - frames = (Frame[]) new Frame[0]; - return frames; - } - n = m.instructions.size(); - insns = m.instructions; - handlers = (List[]) new List[n]; - frames = (Frame[]) new Frame[n]; - subroutines = new Subroutine[n]; - queued = new boolean[n]; - queue = new int[n]; - top = 0; - - // computes exception handlers for each instruction - for (int i = 0; i < m.tryCatchBlocks.size(); ++i) { - TryCatchBlockNode tcb = m.tryCatchBlocks.get(i); - int begin = insns.indexOf(tcb.start); - int end = insns.indexOf(tcb.end); - for (int j = begin; j < end; ++j) { - List insnHandlers = handlers[j]; - if (insnHandlers == null) { - insnHandlers = new ArrayList(); - handlers[j] = insnHandlers; - } - insnHandlers.add(tcb); - } - } - - // computes the subroutine for each instruction: - Subroutine main = new Subroutine(null, m.maxLocals, null); - List subroutineCalls = new ArrayList(); - Map subroutineHeads = new HashMap(); - findSubroutine(0, main, subroutineCalls); - while (!subroutineCalls.isEmpty()) { - JumpInsnNode jsr = (JumpInsnNode) subroutineCalls.remove(0); - Subroutine sub = subroutineHeads.get(jsr.label); - if (sub == null) { - sub = new Subroutine(jsr.label, m.maxLocals, jsr); - subroutineHeads.put(jsr.label, sub); - findSubroutine(insns.indexOf(jsr.label), sub, subroutineCalls); - } else { - sub.callers.add(jsr); - } - } - for (int i = 0; i < n; ++i) { - if (subroutines[i] != null && subroutines[i].start == null) { - subroutines[i] = null; - } - } - - // initializes the data structures for the control flow analysis - Frame current = newFrame(m.maxLocals, m.maxStack); - Frame handler = newFrame(m.maxLocals, m.maxStack); - current.setReturn(interpreter.newValue(Type.getReturnType(m.desc))); - Type[] args = Type.getArgumentTypes(m.desc); - int local = 0; - if ((m.access & ACC_STATIC) == 0) { - Type ctype = Type.getObjectType(owner); - current.setLocal(local++, interpreter.newValue(ctype)); - } - for (int i = 0; i < args.length; ++i) { - current.setLocal(local++, interpreter.newValue(args[i])); - if (args[i].getSize() == 2) { - current.setLocal(local++, interpreter.newValue(null)); - } - } - while (local < m.maxLocals) { - current.setLocal(local++, interpreter.newValue(null)); - } - merge(0, current, null); - - init(owner, m); - - // control flow analysis - while (top > 0) { - int insn = queue[--top]; - Frame f = frames[insn]; - Subroutine subroutine = subroutines[insn]; - queued[insn] = false; - - AbstractInsnNode insnNode = null; - try { - insnNode = m.instructions.get(insn); - int insnOpcode = insnNode.getOpcode(); - int insnType = insnNode.getType(); - - if (insnType == AbstractInsnNode.LABEL - || insnType == AbstractInsnNode.LINE - || insnType == AbstractInsnNode.FRAME) { - merge(insn + 1, f, subroutine); - newControlFlowEdge(insn, insn + 1); - } else { - current.init(f).execute(insnNode, interpreter); - subroutine = subroutine == null ? null : subroutine.copy(); - - if (insnNode instanceof JumpInsnNode) { - JumpInsnNode j = (JumpInsnNode) insnNode; - if (insnOpcode != GOTO && insnOpcode != JSR) { - merge(insn + 1, current, subroutine); - newControlFlowEdge(insn, insn + 1); - } - int jump = insns.indexOf(j.label); - if (insnOpcode == JSR) { - merge(jump, current, new Subroutine(j.label, - m.maxLocals, j)); - } else { - merge(jump, current, subroutine); - } - newControlFlowEdge(insn, jump); - } else if (insnNode instanceof LookupSwitchInsnNode) { - LookupSwitchInsnNode lsi = (LookupSwitchInsnNode) insnNode; - int jump = insns.indexOf(lsi.dflt); - merge(jump, current, subroutine); - newControlFlowEdge(insn, jump); - for (int j = 0; j < lsi.labels.size(); ++j) { - LabelNode label = lsi.labels.get(j); - jump = insns.indexOf(label); - merge(jump, current, subroutine); - newControlFlowEdge(insn, jump); - } - } else if (insnNode instanceof TableSwitchInsnNode) { - TableSwitchInsnNode tsi = (TableSwitchInsnNode) insnNode; - int jump = insns.indexOf(tsi.dflt); - merge(jump, current, subroutine); - newControlFlowEdge(insn, jump); - for (int j = 0; j < tsi.labels.size(); ++j) { - LabelNode label = tsi.labels.get(j); - jump = insns.indexOf(label); - merge(jump, current, subroutine); - newControlFlowEdge(insn, jump); - } - } else if (insnOpcode == RET) { - if (subroutine == null) { - throw new AnalyzerException(insnNode, - "RET instruction outside of a sub routine"); - } - for (int i = 0; i < subroutine.callers.size(); ++i) { - JumpInsnNode caller = subroutine.callers.get(i); - int call = insns.indexOf(caller); - if (frames[call] != null) { - merge(call + 1, frames[call], current, - subroutines[call], subroutine.access); - newControlFlowEdge(insn, call + 1); - } - } - } else if (insnOpcode != ATHROW - && (insnOpcode < IRETURN || insnOpcode > RETURN)) { - if (subroutine != null) { - if (insnNode instanceof VarInsnNode) { - int var = ((VarInsnNode) insnNode).var; - subroutine.access[var] = true; - if (insnOpcode == LLOAD || insnOpcode == DLOAD - || insnOpcode == LSTORE - || insnOpcode == DSTORE) { - subroutine.access[var + 1] = true; - } - } else if (insnNode instanceof IincInsnNode) { - int var = ((IincInsnNode) insnNode).var; - subroutine.access[var] = true; - } - } - merge(insn + 1, current, subroutine); - newControlFlowEdge(insn, insn + 1); - } - } - - List insnHandlers = handlers[insn]; - if (insnHandlers != null) { - for (int i = 0; i < insnHandlers.size(); ++i) { - TryCatchBlockNode tcb = insnHandlers.get(i); - Type type; - if (tcb.type == null) { - type = Type.getObjectType("java/lang/Throwable"); - } else { - type = Type.getObjectType(tcb.type); - } - int jump = insns.indexOf(tcb.handler); - if (newControlFlowExceptionEdge(insn, tcb)) { - handler.init(f); - handler.clearStack(); - handler.push(interpreter.newValue(type)); - merge(jump, handler, subroutine); - } - } - } - } catch (AnalyzerException e) { - throw new AnalyzerException(e.node, "Error at instruction " - + insn + ": " + e.getMessage(), e); - } catch (Exception e) { - throw new AnalyzerException(insnNode, "Error at instruction " - + insn + ": " + e.getMessage(), e); - } - } - - return frames; - } - - private void findSubroutine(int insn, final Subroutine sub, - final List calls) throws AnalyzerException { - while (true) { - if (insn < 0 || insn >= n) { - throw new AnalyzerException(null, - "Execution can fall off end of the code"); - } - if (subroutines[insn] != null) { - return; - } - subroutines[insn] = sub.copy(); - AbstractInsnNode node = insns.get(insn); - - // calls findSubroutine recursively on normal successors - if (node instanceof JumpInsnNode) { - if (node.getOpcode() == JSR) { - // do not follow a JSR, it leads to another subroutine! - calls.add(node); - } else { - JumpInsnNode jnode = (JumpInsnNode) node; - findSubroutine(insns.indexOf(jnode.label), sub, calls); - } - } else if (node instanceof TableSwitchInsnNode) { - TableSwitchInsnNode tsnode = (TableSwitchInsnNode) node; - findSubroutine(insns.indexOf(tsnode.dflt), sub, calls); - for (int i = tsnode.labels.size() - 1; i >= 0; --i) { - LabelNode l = tsnode.labels.get(i); - findSubroutine(insns.indexOf(l), sub, calls); - } - } else if (node instanceof LookupSwitchInsnNode) { - LookupSwitchInsnNode lsnode = (LookupSwitchInsnNode) node; - findSubroutine(insns.indexOf(lsnode.dflt), sub, calls); - for (int i = lsnode.labels.size() - 1; i >= 0; --i) { - LabelNode l = lsnode.labels.get(i); - findSubroutine(insns.indexOf(l), sub, calls); - } - } - - // calls findSubroutine recursively on exception handler successors - List insnHandlers = handlers[insn]; - if (insnHandlers != null) { - for (int i = 0; i < insnHandlers.size(); ++i) { - TryCatchBlockNode tcb = insnHandlers.get(i); - findSubroutine(insns.indexOf(tcb.handler), sub, calls); - } - } - - // if insn does not falls through to the next instruction, return. - switch (node.getOpcode()) { - case GOTO: - case RET: - case TABLESWITCH: - case LOOKUPSWITCH: - case IRETURN: - case LRETURN: - case FRETURN: - case DRETURN: - case ARETURN: - case RETURN: - case ATHROW: - return; - } - insn++; - } - } - - /** - * Returns the symbolic stack frame for each instruction of the last - * recently analyzed method. - * - * @return the symbolic state of the execution stack frame at each bytecode - * instruction of the method. The size of the returned array is - * equal to the number of instructions (and labels) of the method. A - * given frame is null if the corresponding instruction - * cannot be reached, or if an error occurred during the analysis of - * the method. - */ - public Frame[] getFrames() { - return frames; - } - - /** - * Returns the exception handlers for the given instruction. - * - * @param insn - * the index of an instruction of the last recently analyzed - * method. - * @return a list of {@link TryCatchBlockNode} objects. - */ - public List getHandlers(final int insn) { - return handlers[insn]; - } - - /** - * Initializes this analyzer. This method is called just before the - * execution of control flow analysis loop in #analyze. The default - * implementation of this method does nothing. - * - * @param owner - * the internal name of the class to which the method belongs. - * @param m - * the method to be analyzed. - * @throws AnalyzerException - * if a problem occurs. - */ - protected void init(String owner, MethodNode m) throws AnalyzerException { - } - - /** - * Constructs a new frame with the given size. - * - * @param nLocals - * the maximum number of local variables of the frame. - * @param nStack - * the maximum stack size of the frame. - * @return the created frame. - */ - protected Frame newFrame(final int nLocals, final int nStack) { - return new Frame(nLocals, nStack); - } - - /** - * Constructs a new frame that is identical to the given frame. - * - * @param src - * a frame. - * @return the created frame. - */ - protected Frame newFrame(final Frame src) { - return new Frame(src); - } - - /** - * Creates a control flow graph edge. The default implementation of this - * method does nothing. It can be overridden in order to construct the - * control flow graph of a method (this method is called by the - * {@link #analyze analyze} method during its visit of the method's code). - * - * @param insn - * an instruction index. - * @param successor - * index of a successor instruction. - */ - protected void newControlFlowEdge(final int insn, final int successor) { - } - - /** - * Creates a control flow graph edge corresponding to an exception handler. - * The default implementation of this method does nothing. It can be - * overridden in order to construct the control flow graph of a method (this - * method is called by the {@link #analyze analyze} method during its visit - * of the method's code). - * - * @param insn - * an instruction index. - * @param successor - * index of a successor instruction. - * @return true if this edge must be considered in the data flow analysis - * performed by this analyzer, or false otherwise. The default - * implementation of this method always returns true. - */ - protected boolean newControlFlowExceptionEdge(final int insn, - final int successor) { - return true; - } - - /** - * Creates a control flow graph edge corresponding to an exception handler. - * The default implementation of this method delegates to - * {@link #newControlFlowExceptionEdge(int, int) - * newControlFlowExceptionEdge(int, int)}. It can be overridden in order to - * construct the control flow graph of a method (this method is called by - * the {@link #analyze analyze} method during its visit of the method's - * code). - * - * @param insn - * an instruction index. - * @param tcb - * TryCatchBlockNode corresponding to this edge. - * @return true if this edge must be considered in the data flow analysis - * performed by this analyzer, or false otherwise. The default - * implementation of this method delegates to - * {@link #newControlFlowExceptionEdge(int, int) - * newControlFlowExceptionEdge(int, int)}. - */ - protected boolean newControlFlowExceptionEdge(final int insn, - final TryCatchBlockNode tcb) { - return newControlFlowExceptionEdge(insn, insns.indexOf(tcb.handler)); - } - - // ------------------------------------------------------------------------- - - private void merge(final int insn, final Frame frame, - final Subroutine subroutine) throws AnalyzerException { - Frame oldFrame = frames[insn]; - Subroutine oldSubroutine = subroutines[insn]; - boolean changes; - - if (oldFrame == null) { - frames[insn] = newFrame(frame); - changes = true; - } else { - changes = oldFrame.merge(frame, interpreter); - } - - if (oldSubroutine == null) { - if (subroutine != null) { - subroutines[insn] = subroutine.copy(); - changes = true; - } - } else { - if (subroutine != null) { - changes |= oldSubroutine.merge(subroutine); - } - } - if (changes && !queued[insn]) { - queued[insn] = true; - queue[top++] = insn; - } - } - - private void merge(final int insn, final Frame beforeJSR, - final Frame afterRET, final Subroutine subroutineBeforeJSR, - final boolean[] access) throws AnalyzerException { - Frame oldFrame = frames[insn]; - Subroutine oldSubroutine = subroutines[insn]; - boolean changes; - - afterRET.merge(beforeJSR, access); - - if (oldFrame == null) { - frames[insn] = newFrame(afterRET); - changes = true; - } else { - changes = oldFrame.merge(afterRET, interpreter); - } - - if (oldSubroutine != null && subroutineBeforeJSR != null) { - changes |= oldSubroutine.merge(subroutineBeforeJSR); - } - if (changes && !queued[insn]) { - queued[insn] = true; - queue[top++] = insn; - } - } -} diff --git a/src/asm/scala/tools/asm/tree/analysis/AnalyzerException.java b/src/asm/scala/tools/asm/tree/analysis/AnalyzerException.java deleted file mode 100644 index 52b2a11d6f..0000000000 --- a/src/asm/scala/tools/asm/tree/analysis/AnalyzerException.java +++ /dev/null @@ -1,62 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree.analysis; - -import scala.tools.asm.tree.AbstractInsnNode; - -/** - * Thrown if a problem occurs during the analysis of a method. - * - * @author Bing Ran - * @author Eric Bruneton - */ -@SuppressWarnings("serial") -public class AnalyzerException extends Exception { - - public final AbstractInsnNode node; - - public AnalyzerException(final AbstractInsnNode node, final String msg) { - super(msg); - this.node = node; - } - - public AnalyzerException(final AbstractInsnNode node, final String msg, - final Throwable exception) { - super(msg, exception); - this.node = node; - } - - public AnalyzerException(final AbstractInsnNode node, final String msg, - final Object expected, final Value encountered) { - super((msg == null ? "Expected " : msg + ": expected ") + expected - + ", but found " + encountered); - this.node = node; - } -} diff --git a/src/asm/scala/tools/asm/tree/analysis/BasicInterpreter.java b/src/asm/scala/tools/asm/tree/analysis/BasicInterpreter.java deleted file mode 100644 index 7d0b7b0694..0000000000 --- a/src/asm/scala/tools/asm/tree/analysis/BasicInterpreter.java +++ /dev/null @@ -1,358 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree.analysis; - -import java.util.List; - -import scala.tools.asm.Handle; -import scala.tools.asm.Opcodes; -import scala.tools.asm.Type; -import scala.tools.asm.tree.AbstractInsnNode; -import scala.tools.asm.tree.FieldInsnNode; -import scala.tools.asm.tree.IntInsnNode; -import scala.tools.asm.tree.InvokeDynamicInsnNode; -import scala.tools.asm.tree.LdcInsnNode; -import scala.tools.asm.tree.MethodInsnNode; -import scala.tools.asm.tree.MultiANewArrayInsnNode; -import scala.tools.asm.tree.TypeInsnNode; - -/** - * An {@link Interpreter} for {@link BasicValue} values. - * - * @author Eric Bruneton - * @author Bing Ran - */ -public class BasicInterpreter extends Interpreter implements - Opcodes { - - public BasicInterpreter() { - super(ASM5); - } - - protected BasicInterpreter(final int api) { - super(api); - } - - @Override - public BasicValue newValue(final Type type) { - if (type == null) { - return BasicValue.UNINITIALIZED_VALUE; - } - switch (type.getSort()) { - case Type.VOID: - return null; - case Type.BOOLEAN: - case Type.CHAR: - case Type.BYTE: - case Type.SHORT: - case Type.INT: - return BasicValue.INT_VALUE; - case Type.FLOAT: - return BasicValue.FLOAT_VALUE; - case Type.LONG: - return BasicValue.LONG_VALUE; - case Type.DOUBLE: - return BasicValue.DOUBLE_VALUE; - case Type.ARRAY: - case Type.OBJECT: - return BasicValue.REFERENCE_VALUE; - default: - throw new Error("Internal error"); - } - } - - @Override - public BasicValue newOperation(final AbstractInsnNode insn) - throws AnalyzerException { - switch (insn.getOpcode()) { - case ACONST_NULL: - return newValue(Type.getObjectType("null")); - case ICONST_M1: - case ICONST_0: - case ICONST_1: - case ICONST_2: - case ICONST_3: - case ICONST_4: - case ICONST_5: - return BasicValue.INT_VALUE; - case LCONST_0: - case LCONST_1: - return BasicValue.LONG_VALUE; - case FCONST_0: - case FCONST_1: - case FCONST_2: - return BasicValue.FLOAT_VALUE; - case DCONST_0: - case DCONST_1: - return BasicValue.DOUBLE_VALUE; - case BIPUSH: - case SIPUSH: - return BasicValue.INT_VALUE; - case LDC: - Object cst = ((LdcInsnNode) insn).cst; - if (cst instanceof Integer) { - return BasicValue.INT_VALUE; - } else if (cst instanceof Float) { - return BasicValue.FLOAT_VALUE; - } else if (cst instanceof Long) { - return BasicValue.LONG_VALUE; - } else if (cst instanceof Double) { - return BasicValue.DOUBLE_VALUE; - } else if (cst instanceof String) { - return newValue(Type.getObjectType("java/lang/String")); - } else if (cst instanceof Type) { - int sort = ((Type) cst).getSort(); - if (sort == Type.OBJECT || sort == Type.ARRAY) { - return newValue(Type.getObjectType("java/lang/Class")); - } else if (sort == Type.METHOD) { - return newValue(Type - .getObjectType("java/lang/invoke/MethodType")); - } else { - throw new IllegalArgumentException("Illegal LDC constant " - + cst); - } - } else if (cst instanceof Handle) { - return newValue(Type - .getObjectType("java/lang/invoke/MethodHandle")); - } else { - throw new IllegalArgumentException("Illegal LDC constant " - + cst); - } - case JSR: - return BasicValue.RETURNADDRESS_VALUE; - case GETSTATIC: - return newValue(Type.getType(((FieldInsnNode) insn).desc)); - case NEW: - return newValue(Type.getObjectType(((TypeInsnNode) insn).desc)); - default: - throw new Error("Internal error."); - } - } - - @Override - public BasicValue copyOperation(final AbstractInsnNode insn, - final BasicValue value) throws AnalyzerException { - return value; - } - - @Override - public BasicValue unaryOperation(final AbstractInsnNode insn, - final BasicValue value) throws AnalyzerException { - switch (insn.getOpcode()) { - case INEG: - case IINC: - case L2I: - case F2I: - case D2I: - case I2B: - case I2C: - case I2S: - return BasicValue.INT_VALUE; - case FNEG: - case I2F: - case L2F: - case D2F: - return BasicValue.FLOAT_VALUE; - case LNEG: - case I2L: - case F2L: - case D2L: - return BasicValue.LONG_VALUE; - case DNEG: - case I2D: - case L2D: - case F2D: - return BasicValue.DOUBLE_VALUE; - case IFEQ: - case IFNE: - case IFLT: - case IFGE: - case IFGT: - case IFLE: - case TABLESWITCH: - case LOOKUPSWITCH: - case IRETURN: - case LRETURN: - case FRETURN: - case DRETURN: - case ARETURN: - case PUTSTATIC: - return null; - case GETFIELD: - return newValue(Type.getType(((FieldInsnNode) insn).desc)); - case NEWARRAY: - switch (((IntInsnNode) insn).operand) { - case T_BOOLEAN: - return newValue(Type.getType("[Z")); - case T_CHAR: - return newValue(Type.getType("[C")); - case T_BYTE: - return newValue(Type.getType("[B")); - case T_SHORT: - return newValue(Type.getType("[S")); - case T_INT: - return newValue(Type.getType("[I")); - case T_FLOAT: - return newValue(Type.getType("[F")); - case T_DOUBLE: - return newValue(Type.getType("[D")); - case T_LONG: - return newValue(Type.getType("[J")); - default: - throw new AnalyzerException(insn, "Invalid array type"); - } - case ANEWARRAY: - String desc = ((TypeInsnNode) insn).desc; - return newValue(Type.getType("[" + Type.getObjectType(desc))); - case ARRAYLENGTH: - return BasicValue.INT_VALUE; - case ATHROW: - return null; - case CHECKCAST: - desc = ((TypeInsnNode) insn).desc; - return newValue(Type.getObjectType(desc)); - case INSTANCEOF: - return BasicValue.INT_VALUE; - case MONITORENTER: - case MONITOREXIT: - case IFNULL: - case IFNONNULL: - return null; - default: - throw new Error("Internal error."); - } - } - - @Override - public BasicValue binaryOperation(final AbstractInsnNode insn, - final BasicValue value1, final BasicValue value2) - throws AnalyzerException { - switch (insn.getOpcode()) { - case IALOAD: - case BALOAD: - case CALOAD: - case SALOAD: - case IADD: - case ISUB: - case IMUL: - case IDIV: - case IREM: - case ISHL: - case ISHR: - case IUSHR: - case IAND: - case IOR: - case IXOR: - return BasicValue.INT_VALUE; - case FALOAD: - case FADD: - case FSUB: - case FMUL: - case FDIV: - case FREM: - return BasicValue.FLOAT_VALUE; - case LALOAD: - case LADD: - case LSUB: - case LMUL: - case LDIV: - case LREM: - case LSHL: - case LSHR: - case LUSHR: - case LAND: - case LOR: - case LXOR: - return BasicValue.LONG_VALUE; - case DALOAD: - case DADD: - case DSUB: - case DMUL: - case DDIV: - case DREM: - return BasicValue.DOUBLE_VALUE; - case AALOAD: - return BasicValue.REFERENCE_VALUE; - case LCMP: - case FCMPL: - case FCMPG: - case DCMPL: - case DCMPG: - return BasicValue.INT_VALUE; - case IF_ICMPEQ: - case IF_ICMPNE: - case IF_ICMPLT: - case IF_ICMPGE: - case IF_ICMPGT: - case IF_ICMPLE: - case IF_ACMPEQ: - case IF_ACMPNE: - case PUTFIELD: - return null; - default: - throw new Error("Internal error."); - } - } - - @Override - public BasicValue ternaryOperation(final AbstractInsnNode insn, - final BasicValue value1, final BasicValue value2, - final BasicValue value3) throws AnalyzerException { - return null; - } - - @Override - public BasicValue naryOperation(final AbstractInsnNode insn, - final List values) throws AnalyzerException { - int opcode = insn.getOpcode(); - if (opcode == MULTIANEWARRAY) { - return newValue(Type.getType(((MultiANewArrayInsnNode) insn).desc)); - } else if (opcode == INVOKEDYNAMIC) { - return newValue(Type - .getReturnType(((InvokeDynamicInsnNode) insn).desc)); - } else { - return newValue(Type.getReturnType(((MethodInsnNode) insn).desc)); - } - } - - @Override - public void returnOperation(final AbstractInsnNode insn, - final BasicValue value, final BasicValue expected) - throws AnalyzerException { - } - - @Override - public BasicValue merge(final BasicValue v, final BasicValue w) { - if (!v.equals(w)) { - return BasicValue.UNINITIALIZED_VALUE; - } - return v; - } -} diff --git a/src/asm/scala/tools/asm/tree/analysis/BasicValue.java b/src/asm/scala/tools/asm/tree/analysis/BasicValue.java deleted file mode 100644 index 439941fb9f..0000000000 --- a/src/asm/scala/tools/asm/tree/analysis/BasicValue.java +++ /dev/null @@ -1,111 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree.analysis; - -import scala.tools.asm.Type; - -/** - * A {@link Value} that is represented by its type in a seven types type system. - * This type system distinguishes the UNINITIALZED, INT, FLOAT, LONG, DOUBLE, - * REFERENCE and RETURNADDRESS types. - * - * @author Eric Bruneton - */ -public class BasicValue implements Value { - - public static final BasicValue UNINITIALIZED_VALUE = new BasicValue(null); - - public static final BasicValue INT_VALUE = new BasicValue(Type.INT_TYPE); - - public static final BasicValue FLOAT_VALUE = new BasicValue(Type.FLOAT_TYPE); - - public static final BasicValue LONG_VALUE = new BasicValue(Type.LONG_TYPE); - - public static final BasicValue DOUBLE_VALUE = new BasicValue( - Type.DOUBLE_TYPE); - - public static final BasicValue REFERENCE_VALUE = new BasicValue( - Type.getObjectType("java/lang/Object")); - - public static final BasicValue RETURNADDRESS_VALUE = new BasicValue( - Type.VOID_TYPE); - - private final Type type; - - public BasicValue(final Type type) { - this.type = type; - } - - public Type getType() { - return type; - } - - public int getSize() { - return type == Type.LONG_TYPE || type == Type.DOUBLE_TYPE ? 2 : 1; - } - - public boolean isReference() { - return type != null - && (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY); - } - - @Override - public boolean equals(final Object value) { - if (value == this) { - return true; - } else if (value instanceof BasicValue) { - if (type == null) { - return ((BasicValue) value).type == null; - } else { - return type.equals(((BasicValue) value).type); - } - } else { - return false; - } - } - - @Override - public int hashCode() { - return type == null ? 0 : type.hashCode(); - } - - @Override - public String toString() { - if (this == UNINITIALIZED_VALUE) { - return "."; - } else if (this == RETURNADDRESS_VALUE) { - return "A"; - } else if (this == REFERENCE_VALUE) { - return "R"; - } else { - return type.getDescriptor(); - } - } -} diff --git a/src/asm/scala/tools/asm/tree/analysis/BasicVerifier.java b/src/asm/scala/tools/asm/tree/analysis/BasicVerifier.java deleted file mode 100644 index b852f20acf..0000000000 --- a/src/asm/scala/tools/asm/tree/analysis/BasicVerifier.java +++ /dev/null @@ -1,433 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree.analysis; - -import java.util.List; - -import scala.tools.asm.Type; -import scala.tools.asm.tree.AbstractInsnNode; -import scala.tools.asm.tree.FieldInsnNode; -import scala.tools.asm.tree.InvokeDynamicInsnNode; -import scala.tools.asm.tree.MethodInsnNode; - -/** - * An extended {@link BasicInterpreter} that checks that bytecode instructions - * are correctly used. - * - * @author Eric Bruneton - * @author Bing Ran - */ -public class BasicVerifier extends BasicInterpreter { - - public BasicVerifier() { - super(ASM5); - } - - protected BasicVerifier(final int api) { - super(api); - } - - @Override - public BasicValue copyOperation(final AbstractInsnNode insn, - final BasicValue value) throws AnalyzerException { - Value expected; - switch (insn.getOpcode()) { - case ILOAD: - case ISTORE: - expected = BasicValue.INT_VALUE; - break; - case FLOAD: - case FSTORE: - expected = BasicValue.FLOAT_VALUE; - break; - case LLOAD: - case LSTORE: - expected = BasicValue.LONG_VALUE; - break; - case DLOAD: - case DSTORE: - expected = BasicValue.DOUBLE_VALUE; - break; - case ALOAD: - if (!value.isReference()) { - throw new AnalyzerException(insn, null, "an object reference", - value); - } - return value; - case ASTORE: - if (!value.isReference() - && !BasicValue.RETURNADDRESS_VALUE.equals(value)) { - throw new AnalyzerException(insn, null, - "an object reference or a return address", value); - } - return value; - default: - return value; - } - if (!expected.equals(value)) { - throw new AnalyzerException(insn, null, expected, value); - } - return value; - } - - @Override - public BasicValue unaryOperation(final AbstractInsnNode insn, - final BasicValue value) throws AnalyzerException { - BasicValue expected; - switch (insn.getOpcode()) { - case INEG: - case IINC: - case I2F: - case I2L: - case I2D: - case I2B: - case I2C: - case I2S: - case IFEQ: - case IFNE: - case IFLT: - case IFGE: - case IFGT: - case IFLE: - case TABLESWITCH: - case LOOKUPSWITCH: - case IRETURN: - case NEWARRAY: - case ANEWARRAY: - expected = BasicValue.INT_VALUE; - break; - case FNEG: - case F2I: - case F2L: - case F2D: - case FRETURN: - expected = BasicValue.FLOAT_VALUE; - break; - case LNEG: - case L2I: - case L2F: - case L2D: - case LRETURN: - expected = BasicValue.LONG_VALUE; - break; - case DNEG: - case D2I: - case D2F: - case D2L: - case DRETURN: - expected = BasicValue.DOUBLE_VALUE; - break; - case GETFIELD: - expected = newValue(Type - .getObjectType(((FieldInsnNode) insn).owner)); - break; - case CHECKCAST: - if (!value.isReference()) { - throw new AnalyzerException(insn, null, "an object reference", - value); - } - return super.unaryOperation(insn, value); - case ARRAYLENGTH: - if (!isArrayValue(value)) { - throw new AnalyzerException(insn, null, "an array reference", - value); - } - return super.unaryOperation(insn, value); - case ARETURN: - case ATHROW: - case INSTANCEOF: - case MONITORENTER: - case MONITOREXIT: - case IFNULL: - case IFNONNULL: - if (!value.isReference()) { - throw new AnalyzerException(insn, null, "an object reference", - value); - } - return super.unaryOperation(insn, value); - case PUTSTATIC: - expected = newValue(Type.getType(((FieldInsnNode) insn).desc)); - break; - default: - throw new Error("Internal error."); - } - if (!isSubTypeOf(value, expected)) { - throw new AnalyzerException(insn, null, expected, value); - } - return super.unaryOperation(insn, value); - } - - @Override - public BasicValue binaryOperation(final AbstractInsnNode insn, - final BasicValue value1, final BasicValue value2) - throws AnalyzerException { - BasicValue expected1; - BasicValue expected2; - switch (insn.getOpcode()) { - case IALOAD: - expected1 = newValue(Type.getType("[I")); - expected2 = BasicValue.INT_VALUE; - break; - case BALOAD: - if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) { - expected1 = newValue(Type.getType("[Z")); - } else { - expected1 = newValue(Type.getType("[B")); - } - expected2 = BasicValue.INT_VALUE; - break; - case CALOAD: - expected1 = newValue(Type.getType("[C")); - expected2 = BasicValue.INT_VALUE; - break; - case SALOAD: - expected1 = newValue(Type.getType("[S")); - expected2 = BasicValue.INT_VALUE; - break; - case LALOAD: - expected1 = newValue(Type.getType("[J")); - expected2 = BasicValue.INT_VALUE; - break; - case FALOAD: - expected1 = newValue(Type.getType("[F")); - expected2 = BasicValue.INT_VALUE; - break; - case DALOAD: - expected1 = newValue(Type.getType("[D")); - expected2 = BasicValue.INT_VALUE; - break; - case AALOAD: - expected1 = newValue(Type.getType("[Ljava/lang/Object;")); - expected2 = BasicValue.INT_VALUE; - break; - case IADD: - case ISUB: - case IMUL: - case IDIV: - case IREM: - case ISHL: - case ISHR: - case IUSHR: - case IAND: - case IOR: - case IXOR: - case IF_ICMPEQ: - case IF_ICMPNE: - case IF_ICMPLT: - case IF_ICMPGE: - case IF_ICMPGT: - case IF_ICMPLE: - expected1 = BasicValue.INT_VALUE; - expected2 = BasicValue.INT_VALUE; - break; - case FADD: - case FSUB: - case FMUL: - case FDIV: - case FREM: - case FCMPL: - case FCMPG: - expected1 = BasicValue.FLOAT_VALUE; - expected2 = BasicValue.FLOAT_VALUE; - break; - case LADD: - case LSUB: - case LMUL: - case LDIV: - case LREM: - case LAND: - case LOR: - case LXOR: - case LCMP: - expected1 = BasicValue.LONG_VALUE; - expected2 = BasicValue.LONG_VALUE; - break; - case LSHL: - case LSHR: - case LUSHR: - expected1 = BasicValue.LONG_VALUE; - expected2 = BasicValue.INT_VALUE; - break; - case DADD: - case DSUB: - case DMUL: - case DDIV: - case DREM: - case DCMPL: - case DCMPG: - expected1 = BasicValue.DOUBLE_VALUE; - expected2 = BasicValue.DOUBLE_VALUE; - break; - case IF_ACMPEQ: - case IF_ACMPNE: - expected1 = BasicValue.REFERENCE_VALUE; - expected2 = BasicValue.REFERENCE_VALUE; - break; - case PUTFIELD: - FieldInsnNode fin = (FieldInsnNode) insn; - expected1 = newValue(Type.getObjectType(fin.owner)); - expected2 = newValue(Type.getType(fin.desc)); - break; - default: - throw new Error("Internal error."); - } - if (!isSubTypeOf(value1, expected1)) { - throw new AnalyzerException(insn, "First argument", expected1, - value1); - } else if (!isSubTypeOf(value2, expected2)) { - throw new AnalyzerException(insn, "Second argument", expected2, - value2); - } - if (insn.getOpcode() == AALOAD) { - return getElementValue(value1); - } else { - return super.binaryOperation(insn, value1, value2); - } - } - - @Override - public BasicValue ternaryOperation(final AbstractInsnNode insn, - final BasicValue value1, final BasicValue value2, - final BasicValue value3) throws AnalyzerException { - BasicValue expected1; - BasicValue expected3; - switch (insn.getOpcode()) { - case IASTORE: - expected1 = newValue(Type.getType("[I")); - expected3 = BasicValue.INT_VALUE; - break; - case BASTORE: - if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) { - expected1 = newValue(Type.getType("[Z")); - } else { - expected1 = newValue(Type.getType("[B")); - } - expected3 = BasicValue.INT_VALUE; - break; - case CASTORE: - expected1 = newValue(Type.getType("[C")); - expected3 = BasicValue.INT_VALUE; - break; - case SASTORE: - expected1 = newValue(Type.getType("[S")); - expected3 = BasicValue.INT_VALUE; - break; - case LASTORE: - expected1 = newValue(Type.getType("[J")); - expected3 = BasicValue.LONG_VALUE; - break; - case FASTORE: - expected1 = newValue(Type.getType("[F")); - expected3 = BasicValue.FLOAT_VALUE; - break; - case DASTORE: - expected1 = newValue(Type.getType("[D")); - expected3 = BasicValue.DOUBLE_VALUE; - break; - case AASTORE: - expected1 = value1; - expected3 = BasicValue.REFERENCE_VALUE; - break; - default: - throw new Error("Internal error."); - } - if (!isSubTypeOf(value1, expected1)) { - throw new AnalyzerException(insn, "First argument", "a " - + expected1 + " array reference", value1); - } else if (!BasicValue.INT_VALUE.equals(value2)) { - throw new AnalyzerException(insn, "Second argument", - BasicValue.INT_VALUE, value2); - } else if (!isSubTypeOf(value3, expected3)) { - throw new AnalyzerException(insn, "Third argument", expected3, - value3); - } - return null; - } - - @Override - public BasicValue naryOperation(final AbstractInsnNode insn, - final List values) throws AnalyzerException { - int opcode = insn.getOpcode(); - if (opcode == MULTIANEWARRAY) { - for (int i = 0; i < values.size(); ++i) { - if (!BasicValue.INT_VALUE.equals(values.get(i))) { - throw new AnalyzerException(insn, null, - BasicValue.INT_VALUE, values.get(i)); - } - } - } else { - int i = 0; - int j = 0; - if (opcode != INVOKESTATIC && opcode != INVOKEDYNAMIC) { - Type owner = Type.getObjectType(((MethodInsnNode) insn).owner); - if (!isSubTypeOf(values.get(i++), newValue(owner))) { - throw new AnalyzerException(insn, "Method owner", - newValue(owner), values.get(0)); - } - } - String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc - : ((MethodInsnNode) insn).desc; - Type[] args = Type.getArgumentTypes(desc); - while (i < values.size()) { - BasicValue expected = newValue(args[j++]); - BasicValue encountered = values.get(i++); - if (!isSubTypeOf(encountered, expected)) { - throw new AnalyzerException(insn, "Argument " + j, - expected, encountered); - } - } - } - return super.naryOperation(insn, values); - } - - @Override - public void returnOperation(final AbstractInsnNode insn, - final BasicValue value, final BasicValue expected) - throws AnalyzerException { - if (!isSubTypeOf(value, expected)) { - throw new AnalyzerException(insn, "Incompatible return type", - expected, value); - } - } - - protected boolean isArrayValue(final BasicValue value) { - return value.isReference(); - } - - protected BasicValue getElementValue(final BasicValue objectArrayValue) - throws AnalyzerException { - return BasicValue.REFERENCE_VALUE; - } - - protected boolean isSubTypeOf(final BasicValue value, - final BasicValue expected) { - return value.equals(expected); - } -} diff --git a/src/asm/scala/tools/asm/tree/analysis/Frame.java b/src/asm/scala/tools/asm/tree/analysis/Frame.java deleted file mode 100644 index 0b7f4ba53b..0000000000 --- a/src/asm/scala/tools/asm/tree/analysis/Frame.java +++ /dev/null @@ -1,738 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree.analysis; - -import java.util.ArrayList; -import java.util.List; - -import scala.tools.asm.Opcodes; -import scala.tools.asm.Type; -import scala.tools.asm.tree.AbstractInsnNode; -import scala.tools.asm.tree.IincInsnNode; -import scala.tools.asm.tree.InvokeDynamicInsnNode; -import scala.tools.asm.tree.MethodInsnNode; -import scala.tools.asm.tree.MultiANewArrayInsnNode; -import scala.tools.asm.tree.VarInsnNode; - -/** - * A symbolic execution stack frame. A stack frame contains a set of local - * variable slots, and an operand stack. Warning: long and double values are - * represented by two slots in local variables, and by one slot in - * the operand stack. - * - * @param - * type of the Value used for the analysis. - * - * @author Eric Bruneton - */ -public class Frame { - - /** - * The expected return type of the analyzed method, or null if the - * method returns void. - */ - private V returnValue; - - /** - * The local variables and operand stack of this frame. - */ - private V[] values; - - /** - * The number of local variables of this frame. - */ - private int locals; - - /** - * The number of elements in the operand stack. - */ - private int top; - - /** - * Constructs a new frame with the given size. - * - * @param nLocals - * the maximum number of local variables of the frame. - * @param nStack - * the maximum stack size of the frame. - */ - public Frame(final int nLocals, final int nStack) { - this.values = (V[]) new Value[nLocals + nStack]; - this.locals = nLocals; - } - - /** - * Constructs a new frame that is identical to the given frame. - * - * @param src - * a frame. - */ - public Frame(final Frame src) { - this(src.locals, src.values.length - src.locals); - init(src); - } - - /** - * Copies the state of the given frame into this frame. - * - * @param src - * a frame. - * @return this frame. - */ - public Frame init(final Frame src) { - returnValue = src.returnValue; - System.arraycopy(src.values, 0, values, 0, values.length); - top = src.top; - return this; - } - - /** - * Sets the expected return type of the analyzed method. - * - * @param v - * the expected return type of the analyzed method, or - * null if the method returns void. - */ - public void setReturn(final V v) { - returnValue = v; - } - - /** - * Returns the maximum number of local variables of this frame. - * - * @return the maximum number of local variables of this frame. - */ - public int getLocals() { - return locals; - } - - /** - * Returns the maximum stack size of this frame. - * - * @return the maximum stack size of this frame. - */ - public int getMaxStackSize() { - return values.length - locals; - } - - /** - * Returns the value of the given local variable. - * - * @param i - * a local variable index. - * @return the value of the given local variable. - * @throws IndexOutOfBoundsException - * if the variable does not exist. - */ - public V getLocal(final int i) throws IndexOutOfBoundsException { - if (i >= locals) { - throw new IndexOutOfBoundsException( - "Trying to access an inexistant local variable"); - } - return values[i]; - } - - /** - * Sets the value of the given local variable. - * - * @param i - * a local variable index. - * @param value - * the new value of this local variable. - * @throws IndexOutOfBoundsException - * if the variable does not exist. - */ - public void setLocal(final int i, final V value) - throws IndexOutOfBoundsException { - if (i >= locals) { - throw new IndexOutOfBoundsException( - "Trying to access an inexistant local variable " + i); - } - values[i] = value; - } - - /** - * Returns the number of values in the operand stack of this frame. Long and - * double values are treated as single values. - * - * @return the number of values in the operand stack of this frame. - */ - public int getStackSize() { - return top; - } - - /** - * Returns the value of the given operand stack slot. - * - * @param i - * the index of an operand stack slot. - * @return the value of the given operand stack slot. - * @throws IndexOutOfBoundsException - * if the operand stack slot does not exist. - */ - public V getStack(final int i) throws IndexOutOfBoundsException { - return values[i + locals]; - } - - /** - * Clears the operand stack of this frame. - */ - public void clearStack() { - top = 0; - } - - /** - * Pops a value from the operand stack of this frame. - * - * @return the value that has been popped from the stack. - * @throws IndexOutOfBoundsException - * if the operand stack is empty. - */ - public V pop() throws IndexOutOfBoundsException { - if (top == 0) { - throw new IndexOutOfBoundsException( - "Cannot pop operand off an empty stack."); - } - return values[--top + locals]; - } - - /** - * Pushes a value into the operand stack of this frame. - * - * @param value - * the value that must be pushed into the stack. - * @throws IndexOutOfBoundsException - * if the operand stack is full. - */ - public void push(final V value) throws IndexOutOfBoundsException { - if (top + locals >= values.length) { - throw new IndexOutOfBoundsException( - "Insufficient maximum stack size."); - } - values[top++ + locals] = value; - } - - public void execute(final AbstractInsnNode insn, - final Interpreter interpreter) throws AnalyzerException { - V value1, value2, value3, value4; - List values; - int var; - - switch (insn.getOpcode()) { - case Opcodes.NOP: - break; - case Opcodes.ACONST_NULL: - case Opcodes.ICONST_M1: - case Opcodes.ICONST_0: - case Opcodes.ICONST_1: - case Opcodes.ICONST_2: - case Opcodes.ICONST_3: - case Opcodes.ICONST_4: - case Opcodes.ICONST_5: - case Opcodes.LCONST_0: - case Opcodes.LCONST_1: - case Opcodes.FCONST_0: - case Opcodes.FCONST_1: - case Opcodes.FCONST_2: - case Opcodes.DCONST_0: - case Opcodes.DCONST_1: - case Opcodes.BIPUSH: - case Opcodes.SIPUSH: - case Opcodes.LDC: - push(interpreter.newOperation(insn)); - break; - case Opcodes.ILOAD: - case Opcodes.LLOAD: - case Opcodes.FLOAD: - case Opcodes.DLOAD: - case Opcodes.ALOAD: - push(interpreter.copyOperation(insn, - getLocal(((VarInsnNode) insn).var))); - break; - case Opcodes.IALOAD: - case Opcodes.LALOAD: - case Opcodes.FALOAD: - case Opcodes.DALOAD: - case Opcodes.AALOAD: - case Opcodes.BALOAD: - case Opcodes.CALOAD: - case Opcodes.SALOAD: - value2 = pop(); - value1 = pop(); - push(interpreter.binaryOperation(insn, value1, value2)); - break; - case Opcodes.ISTORE: - case Opcodes.LSTORE: - case Opcodes.FSTORE: - case Opcodes.DSTORE: - case Opcodes.ASTORE: - value1 = interpreter.copyOperation(insn, pop()); - var = ((VarInsnNode) insn).var; - setLocal(var, value1); - if (value1.getSize() == 2) { - setLocal(var + 1, interpreter.newValue(null)); - } - if (var > 0) { - Value local = getLocal(var - 1); - if (local != null && local.getSize() == 2) { - setLocal(var - 1, interpreter.newValue(null)); - } - } - break; - case Opcodes.IASTORE: - case Opcodes.LASTORE: - case Opcodes.FASTORE: - case Opcodes.DASTORE: - case Opcodes.AASTORE: - case Opcodes.BASTORE: - case Opcodes.CASTORE: - case Opcodes.SASTORE: - value3 = pop(); - value2 = pop(); - value1 = pop(); - interpreter.ternaryOperation(insn, value1, value2, value3); - break; - case Opcodes.POP: - if (pop().getSize() == 2) { - throw new AnalyzerException(insn, "Illegal use of POP"); - } - break; - case Opcodes.POP2: - if (pop().getSize() == 1) { - if (pop().getSize() != 1) { - throw new AnalyzerException(insn, "Illegal use of POP2"); - } - } - break; - case Opcodes.DUP: - value1 = pop(); - if (value1.getSize() != 1) { - throw new AnalyzerException(insn, "Illegal use of DUP"); - } - push(value1); - push(interpreter.copyOperation(insn, value1)); - break; - case Opcodes.DUP_X1: - value1 = pop(); - value2 = pop(); - if (value1.getSize() != 1 || value2.getSize() != 1) { - throw new AnalyzerException(insn, "Illegal use of DUP_X1"); - } - push(interpreter.copyOperation(insn, value1)); - push(value2); - push(value1); - break; - case Opcodes.DUP_X2: - value1 = pop(); - if (value1.getSize() == 1) { - value2 = pop(); - if (value2.getSize() == 1) { - value3 = pop(); - if (value3.getSize() == 1) { - push(interpreter.copyOperation(insn, value1)); - push(value3); - push(value2); - push(value1); - break; - } - } else { - push(interpreter.copyOperation(insn, value1)); - push(value2); - push(value1); - break; - } - } - throw new AnalyzerException(insn, "Illegal use of DUP_X2"); - case Opcodes.DUP2: - value1 = pop(); - if (value1.getSize() == 1) { - value2 = pop(); - if (value2.getSize() == 1) { - push(value2); - push(value1); - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - break; - } - } else { - push(value1); - push(interpreter.copyOperation(insn, value1)); - break; - } - throw new AnalyzerException(insn, "Illegal use of DUP2"); - case Opcodes.DUP2_X1: - value1 = pop(); - if (value1.getSize() == 1) { - value2 = pop(); - if (value2.getSize() == 1) { - value3 = pop(); - if (value3.getSize() == 1) { - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - push(value3); - push(value2); - push(value1); - break; - } - } - } else { - value2 = pop(); - if (value2.getSize() == 1) { - push(interpreter.copyOperation(insn, value1)); - push(value2); - push(value1); - break; - } - } - throw new AnalyzerException(insn, "Illegal use of DUP2_X1"); - case Opcodes.DUP2_X2: - value1 = pop(); - if (value1.getSize() == 1) { - value2 = pop(); - if (value2.getSize() == 1) { - value3 = pop(); - if (value3.getSize() == 1) { - value4 = pop(); - if (value4.getSize() == 1) { - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - push(value4); - push(value3); - push(value2); - push(value1); - break; - } - } else { - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - push(value3); - push(value2); - push(value1); - break; - } - } - } else { - value2 = pop(); - if (value2.getSize() == 1) { - value3 = pop(); - if (value3.getSize() == 1) { - push(interpreter.copyOperation(insn, value1)); - push(value3); - push(value2); - push(value1); - break; - } - } else { - push(interpreter.copyOperation(insn, value1)); - push(value2); - push(value1); - break; - } - } - throw new AnalyzerException(insn, "Illegal use of DUP2_X2"); - case Opcodes.SWAP: - value2 = pop(); - value1 = pop(); - if (value1.getSize() != 1 || value2.getSize() != 1) { - throw new AnalyzerException(insn, "Illegal use of SWAP"); - } - push(interpreter.copyOperation(insn, value2)); - push(interpreter.copyOperation(insn, value1)); - break; - case Opcodes.IADD: - case Opcodes.LADD: - case Opcodes.FADD: - case Opcodes.DADD: - case Opcodes.ISUB: - case Opcodes.LSUB: - case Opcodes.FSUB: - case Opcodes.DSUB: - case Opcodes.IMUL: - case Opcodes.LMUL: - case Opcodes.FMUL: - case Opcodes.DMUL: - case Opcodes.IDIV: - case Opcodes.LDIV: - case Opcodes.FDIV: - case Opcodes.DDIV: - case Opcodes.IREM: - case Opcodes.LREM: - case Opcodes.FREM: - case Opcodes.DREM: - value2 = pop(); - value1 = pop(); - push(interpreter.binaryOperation(insn, value1, value2)); - break; - case Opcodes.INEG: - case Opcodes.LNEG: - case Opcodes.FNEG: - case Opcodes.DNEG: - push(interpreter.unaryOperation(insn, pop())); - break; - case Opcodes.ISHL: - case Opcodes.LSHL: - case Opcodes.ISHR: - case Opcodes.LSHR: - case Opcodes.IUSHR: - case Opcodes.LUSHR: - case Opcodes.IAND: - case Opcodes.LAND: - case Opcodes.IOR: - case Opcodes.LOR: - case Opcodes.IXOR: - case Opcodes.LXOR: - value2 = pop(); - value1 = pop(); - push(interpreter.binaryOperation(insn, value1, value2)); - break; - case Opcodes.IINC: - var = ((IincInsnNode) insn).var; - setLocal(var, interpreter.unaryOperation(insn, getLocal(var))); - break; - case Opcodes.I2L: - case Opcodes.I2F: - case Opcodes.I2D: - case Opcodes.L2I: - case Opcodes.L2F: - case Opcodes.L2D: - case Opcodes.F2I: - case Opcodes.F2L: - case Opcodes.F2D: - case Opcodes.D2I: - case Opcodes.D2L: - case Opcodes.D2F: - case Opcodes.I2B: - case Opcodes.I2C: - case Opcodes.I2S: - push(interpreter.unaryOperation(insn, pop())); - break; - case Opcodes.LCMP: - case Opcodes.FCMPL: - case Opcodes.FCMPG: - case Opcodes.DCMPL: - case Opcodes.DCMPG: - value2 = pop(); - value1 = pop(); - push(interpreter.binaryOperation(insn, value1, value2)); - break; - case Opcodes.IFEQ: - case Opcodes.IFNE: - case Opcodes.IFLT: - case Opcodes.IFGE: - case Opcodes.IFGT: - case Opcodes.IFLE: - interpreter.unaryOperation(insn, pop()); - break; - case Opcodes.IF_ICMPEQ: - case Opcodes.IF_ICMPNE: - case Opcodes.IF_ICMPLT: - case Opcodes.IF_ICMPGE: - case Opcodes.IF_ICMPGT: - case Opcodes.IF_ICMPLE: - case Opcodes.IF_ACMPEQ: - case Opcodes.IF_ACMPNE: - value2 = pop(); - value1 = pop(); - interpreter.binaryOperation(insn, value1, value2); - break; - case Opcodes.GOTO: - break; - case Opcodes.JSR: - push(interpreter.newOperation(insn)); - break; - case Opcodes.RET: - break; - case Opcodes.TABLESWITCH: - case Opcodes.LOOKUPSWITCH: - interpreter.unaryOperation(insn, pop()); - break; - case Opcodes.IRETURN: - case Opcodes.LRETURN: - case Opcodes.FRETURN: - case Opcodes.DRETURN: - case Opcodes.ARETURN: - value1 = pop(); - interpreter.unaryOperation(insn, value1); - interpreter.returnOperation(insn, value1, returnValue); - break; - case Opcodes.RETURN: - if (returnValue != null) { - throw new AnalyzerException(insn, "Incompatible return type"); - } - break; - case Opcodes.GETSTATIC: - push(interpreter.newOperation(insn)); - break; - case Opcodes.PUTSTATIC: - interpreter.unaryOperation(insn, pop()); - break; - case Opcodes.GETFIELD: - push(interpreter.unaryOperation(insn, pop())); - break; - case Opcodes.PUTFIELD: - value2 = pop(); - value1 = pop(); - interpreter.binaryOperation(insn, value1, value2); - break; - case Opcodes.INVOKEVIRTUAL: - case Opcodes.INVOKESPECIAL: - case Opcodes.INVOKESTATIC: - case Opcodes.INVOKEINTERFACE: { - values = new ArrayList(); - String desc = ((MethodInsnNode) insn).desc; - for (int i = Type.getArgumentTypes(desc).length; i > 0; --i) { - values.add(0, pop()); - } - if (insn.getOpcode() != Opcodes.INVOKESTATIC) { - values.add(0, pop()); - } - if (Type.getReturnType(desc) == Type.VOID_TYPE) { - interpreter.naryOperation(insn, values); - } else { - push(interpreter.naryOperation(insn, values)); - } - break; - } - case Opcodes.INVOKEDYNAMIC: { - values = new ArrayList(); - String desc = ((InvokeDynamicInsnNode) insn).desc; - for (int i = Type.getArgumentTypes(desc).length; i > 0; --i) { - values.add(0, pop()); - } - if (Type.getReturnType(desc) == Type.VOID_TYPE) { - interpreter.naryOperation(insn, values); - } else { - push(interpreter.naryOperation(insn, values)); - } - break; - } - case Opcodes.NEW: - push(interpreter.newOperation(insn)); - break; - case Opcodes.NEWARRAY: - case Opcodes.ANEWARRAY: - case Opcodes.ARRAYLENGTH: - push(interpreter.unaryOperation(insn, pop())); - break; - case Opcodes.ATHROW: - interpreter.unaryOperation(insn, pop()); - break; - case Opcodes.CHECKCAST: - case Opcodes.INSTANCEOF: - push(interpreter.unaryOperation(insn, pop())); - break; - case Opcodes.MONITORENTER: - case Opcodes.MONITOREXIT: - interpreter.unaryOperation(insn, pop()); - break; - case Opcodes.MULTIANEWARRAY: - values = new ArrayList(); - for (int i = ((MultiANewArrayInsnNode) insn).dims; i > 0; --i) { - values.add(0, pop()); - } - push(interpreter.naryOperation(insn, values)); - break; - case Opcodes.IFNULL: - case Opcodes.IFNONNULL: - interpreter.unaryOperation(insn, pop()); - break; - default: - throw new RuntimeException("Illegal opcode " + insn.getOpcode()); - } - } - - /** - * Merges this frame with the given frame. - * - * @param frame - * a frame. - * @param interpreter - * the interpreter used to merge values. - * @return true if this frame has been changed as a result of the - * merge operation, or false otherwise. - * @throws AnalyzerException - * if the frames have incompatible sizes. - */ - public boolean merge(final Frame frame, - final Interpreter interpreter) throws AnalyzerException { - if (top != frame.top) { - throw new AnalyzerException(null, "Incompatible stack heights"); - } - boolean changes = false; - for (int i = 0; i < locals + top; ++i) { - V v = interpreter.merge(values[i], frame.values[i]); - if (!v.equals(values[i])) { - values[i] = v; - changes = true; - } - } - return changes; - } - - /** - * Merges this frame with the given frame (case of a RET instruction). - * - * @param frame - * a frame - * @param access - * the local variables that have been accessed by the subroutine - * to which the RET instruction corresponds. - * @return true if this frame has been changed as a result of the - * merge operation, or false otherwise. - */ - public boolean merge(final Frame frame, final boolean[] access) { - boolean changes = false; - for (int i = 0; i < locals; ++i) { - if (!access[i] && !values[i].equals(frame.values[i])) { - values[i] = frame.values[i]; - changes = true; - } - } - return changes; - } - - /** - * Returns a string representation of this frame. - * - * @return a string representation of this frame. - */ - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < getLocals(); ++i) { - sb.append(getLocal(i)); - } - sb.append(' '); - for (int i = 0; i < getStackSize(); ++i) { - sb.append(getStack(i).toString()); - } - return sb.toString(); - } -} diff --git a/src/asm/scala/tools/asm/tree/analysis/Interpreter.java b/src/asm/scala/tools/asm/tree/analysis/Interpreter.java deleted file mode 100644 index 00fe6c8bff..0000000000 --- a/src/asm/scala/tools/asm/tree/analysis/Interpreter.java +++ /dev/null @@ -1,226 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree.analysis; - -import java.util.List; - -import scala.tools.asm.Type; -import scala.tools.asm.tree.AbstractInsnNode; - -/** - * A semantic bytecode interpreter. More precisely, this interpreter only - * manages the computation of values from other values: it does not manage the - * transfer of values to or from the stack, and to or from the local variables. - * This separation allows a generic bytecode {@link Analyzer} to work with - * various semantic interpreters, without needing to duplicate the code to - * simulate the transfer of values. - * - * @param - * type of the Value used for the analysis. - * - * @author Eric Bruneton - */ -public abstract class Interpreter { - - protected final int api; - - protected Interpreter(final int api) { - this.api = api; - } - - /** - * Creates a new value that represents the given type. - * - * Called for method parameters (including this), exception - * handler variable and with null type for variables reserved - * by long and double types. - * - * @param type - * a primitive or reference type, or null to represent - * an uninitialized value. - * @return a value that represents the given type. The size of the returned - * value must be equal to the size of the given type. - */ - public abstract V newValue(Type type); - - /** - * Interprets a bytecode instruction without arguments. This method is - * called for the following opcodes: - * - * ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, - * ICONST_5, LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, - * DCONST_1, BIPUSH, SIPUSH, LDC, JSR, GETSTATIC, NEW - * - * @param insn - * the bytecode instruction to be interpreted. - * @return the result of the interpretation of the given instruction. - * @throws AnalyzerException - * if an error occurred during the interpretation. - */ - public abstract V newOperation(AbstractInsnNode insn) - throws AnalyzerException; - - /** - * Interprets a bytecode instruction that moves a value on the stack or to - * or from local variables. This method is called for the following opcodes: - * - * ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, - * ASTORE, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP - * - * @param insn - * the bytecode instruction to be interpreted. - * @param value - * the value that must be moved by the instruction. - * @return the result of the interpretation of the given instruction. The - * returned value must be equal to the given value. - * @throws AnalyzerException - * if an error occurred during the interpretation. - */ - public abstract V copyOperation(AbstractInsnNode insn, V value) - throws AnalyzerException; - - /** - * Interprets a bytecode instruction with a single argument. This method is - * called for the following opcodes: - * - * INEG, LNEG, FNEG, DNEG, IINC, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, - * F2D, D2I, D2L, D2F, I2B, I2C, I2S, IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, - * TABLESWITCH, LOOKUPSWITCH, IRETURN, LRETURN, FRETURN, DRETURN, ARETURN, - * PUTSTATIC, GETFIELD, NEWARRAY, ANEWARRAY, ARRAYLENGTH, ATHROW, CHECKCAST, - * INSTANCEOF, MONITORENTER, MONITOREXIT, IFNULL, IFNONNULL - * - * @param insn - * the bytecode instruction to be interpreted. - * @param value - * the argument of the instruction to be interpreted. - * @return the result of the interpretation of the given instruction. - * @throws AnalyzerException - * if an error occurred during the interpretation. - */ - public abstract V unaryOperation(AbstractInsnNode insn, V value) - throws AnalyzerException; - - /** - * Interprets a bytecode instruction with two arguments. This method is - * called for the following opcodes: - * - * IALOAD, LALOAD, FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IADD, - * LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, - * LDIV, FDIV, DDIV, IREM, LREM, FREM, DREM, ISHL, LSHL, ISHR, LSHR, IUSHR, - * LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, LCMP, FCMPL, FCMPG, DCMPL, - * DCMPG, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, - * IF_ACMPEQ, IF_ACMPNE, PUTFIELD - * - * @param insn - * the bytecode instruction to be interpreted. - * @param value1 - * the first argument of the instruction to be interpreted. - * @param value2 - * the second argument of the instruction to be interpreted. - * @return the result of the interpretation of the given instruction. - * @throws AnalyzerException - * if an error occurred during the interpretation. - */ - public abstract V binaryOperation(AbstractInsnNode insn, V value1, V value2) - throws AnalyzerException; - - /** - * Interprets a bytecode instruction with three arguments. This method is - * called for the following opcodes: - * - * IASTORE, LASTORE, FASTORE, DASTORE, AASTORE, BASTORE, CASTORE, SASTORE - * - * @param insn - * the bytecode instruction to be interpreted. - * @param value1 - * the first argument of the instruction to be interpreted. - * @param value2 - * the second argument of the instruction to be interpreted. - * @param value3 - * the third argument of the instruction to be interpreted. - * @return the result of the interpretation of the given instruction. - * @throws AnalyzerException - * if an error occurred during the interpretation. - */ - public abstract V ternaryOperation(AbstractInsnNode insn, V value1, - V value2, V value3) throws AnalyzerException; - - /** - * Interprets a bytecode instruction with a variable number of arguments. - * This method is called for the following opcodes: - * - * INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE, - * MULTIANEWARRAY and INVOKEDYNAMIC - * - * @param insn - * the bytecode instruction to be interpreted. - * @param values - * the arguments of the instruction to be interpreted. - * @return the result of the interpretation of the given instruction. - * @throws AnalyzerException - * if an error occurred during the interpretation. - */ - public abstract V naryOperation(AbstractInsnNode insn, - List values) throws AnalyzerException; - - /** - * Interprets a bytecode return instruction. This method is called for the - * following opcodes: - * - * IRETURN, LRETURN, FRETURN, DRETURN, ARETURN - * - * @param insn - * the bytecode instruction to be interpreted. - * @param value - * the argument of the instruction to be interpreted. - * @param expected - * the expected return type of the analyzed method. - * @throws AnalyzerException - * if an error occurred during the interpretation. - */ - public abstract void returnOperation(AbstractInsnNode insn, V value, - V expected) throws AnalyzerException; - - /** - * Merges two values. The merge operation must return a value that - * represents both values (for instance, if the two values are two types, - * the merged value must be a common super type of the two types. If the two - * values are integer intervals, the merged value must be an interval that - * contains the previous ones. Likewise for other types of values). - * - * @param v - * a value. - * @param w - * another value. - * @return the merged value. If the merged value is equal to v, - * this method must return v. - */ - public abstract V merge(V v, V w); -} diff --git a/src/asm/scala/tools/asm/tree/analysis/SimpleVerifier.java b/src/asm/scala/tools/asm/tree/analysis/SimpleVerifier.java deleted file mode 100644 index a345981f36..0000000000 --- a/src/asm/scala/tools/asm/tree/analysis/SimpleVerifier.java +++ /dev/null @@ -1,320 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree.analysis; - -import java.util.List; - -import scala.tools.asm.Type; - -/** - * An extended {@link BasicVerifier} that performs more precise verifications. - * This verifier computes exact class types, instead of using a single "object - * reference" type (as done in the {@link BasicVerifier}). - * - * @author Eric Bruneton - * @author Bing Ran - */ -public class SimpleVerifier extends BasicVerifier { - - /** - * The class that is verified. - */ - private final Type currentClass; - - /** - * The super class of the class that is verified. - */ - private final Type currentSuperClass; - - /** - * The interfaces implemented by the class that is verified. - */ - private final List currentClassInterfaces; - - /** - * If the class that is verified is an interface. - */ - private final boolean isInterface; - - /** - * The loader to use for referenced classes. - */ - private ClassLoader loader = getClass().getClassLoader(); - - /** - * Constructs a new {@link SimpleVerifier}. - */ - public SimpleVerifier() { - this(null, null, false); - } - - /** - * Constructs a new {@link SimpleVerifier} to verify a specific class. This - * class will not be loaded into the JVM since it may be incorrect. - * - * @param currentClass - * the class that is verified. - * @param currentSuperClass - * the super class of the class that is verified. - * @param isInterface - * if the class that is verified is an interface. - */ - public SimpleVerifier(final Type currentClass, - final Type currentSuperClass, final boolean isInterface) { - this(currentClass, currentSuperClass, null, isInterface); - } - - /** - * Constructs a new {@link SimpleVerifier} to verify a specific class. This - * class will not be loaded into the JVM since it may be incorrect. - * - * @param currentClass - * the class that is verified. - * @param currentSuperClass - * the super class of the class that is verified. - * @param currentClassInterfaces - * the interfaces implemented by the class that is verified. - * @param isInterface - * if the class that is verified is an interface. - */ - public SimpleVerifier(final Type currentClass, - final Type currentSuperClass, - final List currentClassInterfaces, final boolean isInterface) { - this(ASM5, currentClass, currentSuperClass, currentClassInterfaces, - isInterface); - } - - protected SimpleVerifier(final int api, final Type currentClass, - final Type currentSuperClass, - final List currentClassInterfaces, final boolean isInterface) { - super(api); - this.currentClass = currentClass; - this.currentSuperClass = currentSuperClass; - this.currentClassInterfaces = currentClassInterfaces; - this.isInterface = isInterface; - } - - /** - * Set the ClassLoader which will be used to load referenced - * classes. This is useful if you are verifying multiple interdependent - * classes. - * - * @param loader - * a ClassLoader to use - */ - public void setClassLoader(final ClassLoader loader) { - this.loader = loader; - } - - @Override - public BasicValue newValue(final Type type) { - if (type == null) { - return BasicValue.UNINITIALIZED_VALUE; - } - - boolean isArray = type.getSort() == Type.ARRAY; - if (isArray) { - switch (type.getElementType().getSort()) { - case Type.BOOLEAN: - case Type.CHAR: - case Type.BYTE: - case Type.SHORT: - return new BasicValue(type); - } - } - - BasicValue v = super.newValue(type); - if (BasicValue.REFERENCE_VALUE.equals(v)) { - if (isArray) { - v = newValue(type.getElementType()); - String desc = v.getType().getDescriptor(); - for (int i = 0; i < type.getDimensions(); ++i) { - desc = '[' + desc; - } - v = new BasicValue(Type.getType(desc)); - } else { - v = new BasicValue(type); - } - } - return v; - } - - @Override - protected boolean isArrayValue(final BasicValue value) { - Type t = value.getType(); - return t != null - && ("Lnull;".equals(t.getDescriptor()) || t.getSort() == Type.ARRAY); - } - - @Override - protected BasicValue getElementValue(final BasicValue objectArrayValue) - throws AnalyzerException { - Type arrayType = objectArrayValue.getType(); - if (arrayType != null) { - if (arrayType.getSort() == Type.ARRAY) { - return newValue(Type.getType(arrayType.getDescriptor() - .substring(1))); - } else if ("Lnull;".equals(arrayType.getDescriptor())) { - return objectArrayValue; - } - } - throw new Error("Internal error"); - } - - @Override - protected boolean isSubTypeOf(final BasicValue value, - final BasicValue expected) { - Type expectedType = expected.getType(); - Type type = value.getType(); - switch (expectedType.getSort()) { - case Type.INT: - case Type.FLOAT: - case Type.LONG: - case Type.DOUBLE: - return type.equals(expectedType); - case Type.ARRAY: - case Type.OBJECT: - if ("Lnull;".equals(type.getDescriptor())) { - return true; - } else if (type.getSort() == Type.OBJECT - || type.getSort() == Type.ARRAY) { - return isAssignableFrom(expectedType, type); - } else { - return false; - } - default: - throw new Error("Internal error"); - } - } - - @Override - public BasicValue merge(final BasicValue v, final BasicValue w) { - if (!v.equals(w)) { - Type t = v.getType(); - Type u = w.getType(); - if (t != null - && (t.getSort() == Type.OBJECT || t.getSort() == Type.ARRAY)) { - if (u != null - && (u.getSort() == Type.OBJECT || u.getSort() == Type.ARRAY)) { - if ("Lnull;".equals(t.getDescriptor())) { - return w; - } - if ("Lnull;".equals(u.getDescriptor())) { - return v; - } - if (isAssignableFrom(t, u)) { - return v; - } - if (isAssignableFrom(u, t)) { - return w; - } - // TODO case of array classes of the same dimension - // TODO should we look also for a common super interface? - // problem: there may be several possible common super - // interfaces - do { - if (t == null || isInterface(t)) { - return BasicValue.REFERENCE_VALUE; - } - t = getSuperClass(t); - if (isAssignableFrom(t, u)) { - return newValue(t); - } - } while (true); - } - } - return BasicValue.UNINITIALIZED_VALUE; - } - return v; - } - - protected boolean isInterface(final Type t) { - if (currentClass != null && t.equals(currentClass)) { - return isInterface; - } - return getClass(t).isInterface(); - } - - protected Type getSuperClass(final Type t) { - if (currentClass != null && t.equals(currentClass)) { - return currentSuperClass; - } - Class c = getClass(t).getSuperclass(); - return c == null ? null : Type.getType(c); - } - - protected boolean isAssignableFrom(final Type t, final Type u) { - if (t.equals(u)) { - return true; - } - if (currentClass != null && t.equals(currentClass)) { - if (getSuperClass(u) == null) { - return false; - } else { - if (isInterface) { - return u.getSort() == Type.OBJECT - || u.getSort() == Type.ARRAY; - } - return isAssignableFrom(t, getSuperClass(u)); - } - } - if (currentClass != null && u.equals(currentClass)) { - if (isAssignableFrom(t, currentSuperClass)) { - return true; - } - if (currentClassInterfaces != null) { - for (int i = 0; i < currentClassInterfaces.size(); ++i) { - Type v = currentClassInterfaces.get(i); - if (isAssignableFrom(t, v)) { - return true; - } - } - } - return false; - } - Class tc = getClass(t); - if (tc.isInterface()) { - tc = Object.class; - } - return tc.isAssignableFrom(getClass(u)); - } - - protected Class getClass(final Type t) { - try { - if (t.getSort() == Type.ARRAY) { - return Class.forName(t.getDescriptor().replace('/', '.'), - false, loader); - } - return Class.forName(t.getClassName(), false, loader); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e.toString()); - } - } -} diff --git a/src/asm/scala/tools/asm/tree/analysis/SmallSet.java b/src/asm/scala/tools/asm/tree/analysis/SmallSet.java deleted file mode 100644 index 205878d18c..0000000000 --- a/src/asm/scala/tools/asm/tree/analysis/SmallSet.java +++ /dev/null @@ -1,134 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree.analysis; - -import java.util.AbstractSet; -import java.util.HashSet; -import java.util.Iterator; -import java.util.NoSuchElementException; -import java.util.Set; - -/** - * A set of at most two elements. - * - * @author Eric Bruneton - */ -class SmallSet extends AbstractSet implements Iterator { - - // if e1 is null, e2 must be null; otherwise e2 must be different from e1 - - E e1, e2; - - static final Set emptySet() { - return new SmallSet(null, null); - } - - SmallSet(final E e1, final E e2) { - this.e1 = e1; - this.e2 = e2; - } - - // ------------------------------------------------------------------------- - // Implementation of inherited abstract methods - // ------------------------------------------------------------------------- - - @Override - public Iterator iterator() { - return new SmallSet(e1, e2); - } - - @Override - public int size() { - return e1 == null ? 0 : (e2 == null ? 1 : 2); - } - - // ------------------------------------------------------------------------- - // Implementation of the Iterator interface - // ------------------------------------------------------------------------- - - public boolean hasNext() { - return e1 != null; - } - - public E next() { - if (e1 == null) { - throw new NoSuchElementException(); - } - E e = e1; - e1 = e2; - e2 = null; - return e; - } - - public void remove() { - } - - // ------------------------------------------------------------------------- - // Utility methods - // ------------------------------------------------------------------------- - - Set union(final SmallSet s) { - if ((s.e1 == e1 && s.e2 == e2) || (s.e1 == e2 && s.e2 == e1)) { - return this; // if the two sets are equal, return this - } - if (s.e1 == null) { - return this; // if s is empty, return this - } - if (e1 == null) { - return s; // if this is empty, return s - } - if (s.e2 == null) { // s contains exactly one element - if (e2 == null) { - return new SmallSet(e1, s.e1); // necessarily e1 != s.e1 - } else if (s.e1 == e1 || s.e1 == e2) { // s is included in this - return this; - } - } - if (e2 == null) { // this contains exactly one element - // if (s.e2 == null) { // cannot happen - // return new SmallSet(e1, s.e1); // necessarily e1 != s.e1 - // } else - if (e1 == s.e1 || e1 == s.e2) { // this in included in s - return s; - } - } - // here we know that there are at least 3 distinct elements - HashSet r = new HashSet(4); - r.add(e1); - if (e2 != null) { - r.add(e2); - } - r.add(s.e1); - if (s.e2 != null) { - r.add(s.e2); - } - return r; - } -} diff --git a/src/asm/scala/tools/asm/tree/analysis/SourceInterpreter.java b/src/asm/scala/tools/asm/tree/analysis/SourceInterpreter.java deleted file mode 100644 index 7d739d3df9..0000000000 --- a/src/asm/scala/tools/asm/tree/analysis/SourceInterpreter.java +++ /dev/null @@ -1,198 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree.analysis; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import scala.tools.asm.Opcodes; -import scala.tools.asm.Type; -import scala.tools.asm.tree.AbstractInsnNode; -import scala.tools.asm.tree.FieldInsnNode; -import scala.tools.asm.tree.InvokeDynamicInsnNode; -import scala.tools.asm.tree.LdcInsnNode; -import scala.tools.asm.tree.MethodInsnNode; - -/** - * An {@link Interpreter} for {@link SourceValue} values. - * - * @author Eric Bruneton - */ -public class SourceInterpreter extends Interpreter implements - Opcodes { - - public SourceInterpreter() { - super(ASM5); - } - - protected SourceInterpreter(final int api) { - super(api); - } - - @Override - public SourceValue newValue(final Type type) { - if (type == Type.VOID_TYPE) { - return null; - } - return new SourceValue(type == null ? 1 : type.getSize()); - } - - @Override - public SourceValue newOperation(final AbstractInsnNode insn) { - int size; - switch (insn.getOpcode()) { - case LCONST_0: - case LCONST_1: - case DCONST_0: - case DCONST_1: - size = 2; - break; - case LDC: - Object cst = ((LdcInsnNode) insn).cst; - size = cst instanceof Long || cst instanceof Double ? 2 : 1; - break; - case GETSTATIC: - size = Type.getType(((FieldInsnNode) insn).desc).getSize(); - break; - default: - size = 1; - } - return new SourceValue(size, insn); - } - - @Override - public SourceValue copyOperation(final AbstractInsnNode insn, - final SourceValue value) { - return new SourceValue(value.getSize(), insn); - } - - @Override - public SourceValue unaryOperation(final AbstractInsnNode insn, - final SourceValue value) { - int size; - switch (insn.getOpcode()) { - case LNEG: - case DNEG: - case I2L: - case I2D: - case L2D: - case F2L: - case F2D: - case D2L: - size = 2; - break; - case GETFIELD: - size = Type.getType(((FieldInsnNode) insn).desc).getSize(); - break; - default: - size = 1; - } - return new SourceValue(size, insn); - } - - @Override - public SourceValue binaryOperation(final AbstractInsnNode insn, - final SourceValue value1, final SourceValue value2) { - int size; - switch (insn.getOpcode()) { - case LALOAD: - case DALOAD: - case LADD: - case DADD: - case LSUB: - case DSUB: - case LMUL: - case DMUL: - case LDIV: - case DDIV: - case LREM: - case DREM: - case LSHL: - case LSHR: - case LUSHR: - case LAND: - case LOR: - case LXOR: - size = 2; - break; - default: - size = 1; - } - return new SourceValue(size, insn); - } - - @Override - public SourceValue ternaryOperation(final AbstractInsnNode insn, - final SourceValue value1, final SourceValue value2, - final SourceValue value3) { - return new SourceValue(1, insn); - } - - @Override - public SourceValue naryOperation(final AbstractInsnNode insn, - final List values) { - int size; - int opcode = insn.getOpcode(); - if (opcode == MULTIANEWARRAY) { - size = 1; - } else { - String desc = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc - : ((MethodInsnNode) insn).desc; - size = Type.getReturnType(desc).getSize(); - } - return new SourceValue(size, insn); - } - - @Override - public void returnOperation(final AbstractInsnNode insn, - final SourceValue value, final SourceValue expected) { - } - - @Override - public SourceValue merge(final SourceValue d, final SourceValue w) { - if (d.insns instanceof SmallSet && w.insns instanceof SmallSet) { - Set s = ((SmallSet) d.insns) - .union((SmallSet) w.insns); - if (s == d.insns && d.size == w.size) { - return d; - } else { - return new SourceValue(Math.min(d.size, w.size), s); - } - } - if (d.size != w.size || !d.insns.containsAll(w.insns)) { - HashSet s = new HashSet(); - s.addAll(d.insns); - s.addAll(w.insns); - return new SourceValue(Math.min(d.size, w.size), s); - } - return d; - } -} diff --git a/src/asm/scala/tools/asm/tree/analysis/SourceValue.java b/src/asm/scala/tools/asm/tree/analysis/SourceValue.java deleted file mode 100644 index 40d6b68180..0000000000 --- a/src/asm/scala/tools/asm/tree/analysis/SourceValue.java +++ /dev/null @@ -1,97 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree.analysis; - -import java.util.Set; - -import scala.tools.asm.tree.AbstractInsnNode; - -/** - * A {@link Value} that is represented by its type in a two types type system. - * This type system distinguishes the ONEWORD and TWOWORDS types. - * - * @author Eric Bruneton - */ -public class SourceValue implements Value { - - /** - * The size of this value. - */ - public final int size; - - /** - * The instructions that can produce this value. For example, for the Java - * code below, the instructions that can produce the value of i at - * line 5 are the txo ISTORE instructions at line 1 and 3: - * - *
-     * 1: i = 0;
-     * 2: if (...) {
-     * 3:   i = 1;
-     * 4: }
-     * 5: return i;
-     * 
- * - * This field is a set of {@link AbstractInsnNode} objects. - */ - public final Set insns; - - public SourceValue(final int size) { - this(size, SmallSet. emptySet()); - } - - public SourceValue(final int size, final AbstractInsnNode insn) { - this.size = size; - this.insns = new SmallSet(insn, null); - } - - public SourceValue(final int size, final Set insns) { - this.size = size; - this.insns = insns; - } - - public int getSize() { - return size; - } - - @Override - public boolean equals(final Object value) { - if (!(value instanceof SourceValue)) { - return false; - } - SourceValue v = (SourceValue) value; - return size == v.size && insns.equals(v.insns); - } - - @Override - public int hashCode() { - return insns.hashCode(); - } -} diff --git a/src/asm/scala/tools/asm/tree/analysis/Subroutine.java b/src/asm/scala/tools/asm/tree/analysis/Subroutine.java deleted file mode 100644 index d734bbd499..0000000000 --- a/src/asm/scala/tools/asm/tree/analysis/Subroutine.java +++ /dev/null @@ -1,90 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree.analysis; - -import java.util.ArrayList; -import java.util.List; - -import scala.tools.asm.tree.JumpInsnNode; -import scala.tools.asm.tree.LabelNode; - -/** - * A method subroutine (corresponds to a JSR instruction). - * - * @author Eric Bruneton - */ -class Subroutine { - - LabelNode start; - - boolean[] access; - - List callers; - - private Subroutine() { - } - - Subroutine(final LabelNode start, final int maxLocals, - final JumpInsnNode caller) { - this.start = start; - this.access = new boolean[maxLocals]; - this.callers = new ArrayList(); - callers.add(caller); - } - - public Subroutine copy() { - Subroutine result = new Subroutine(); - result.start = start; - result.access = new boolean[access.length]; - System.arraycopy(access, 0, result.access, 0, access.length); - result.callers = new ArrayList(callers); - return result; - } - - public boolean merge(final Subroutine subroutine) throws AnalyzerException { - boolean changes = false; - for (int i = 0; i < access.length; ++i) { - if (subroutine.access[i] && !access[i]) { - access[i] = true; - changes = true; - } - } - if (subroutine.start == start) { - for (int i = 0; i < subroutine.callers.size(); ++i) { - JumpInsnNode caller = subroutine.callers.get(i); - if (!callers.contains(caller)) { - callers.add(caller); - changes = true; - } - } - } - return changes; - } -} diff --git a/src/asm/scala/tools/asm/tree/analysis/Value.java b/src/asm/scala/tools/asm/tree/analysis/Value.java deleted file mode 100644 index 1edf475ce7..0000000000 --- a/src/asm/scala/tools/asm/tree/analysis/Value.java +++ /dev/null @@ -1,45 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.tree.analysis; - -/** - * An immutable symbolic value for semantic interpretation of bytecode. - * - * @author Eric Bruneton - */ -public interface Value { - - /** - * Returns the size of this value in words. - * - * @return either 1 or 2. - */ - int getSize(); -} diff --git a/src/asm/scala/tools/asm/util/ASMifiable.java b/src/asm/scala/tools/asm/util/ASMifiable.java deleted file mode 100644 index 95cc6e3a74..0000000000 --- a/src/asm/scala/tools/asm/util/ASMifiable.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.util; - -import java.util.Map; - -import scala.tools.asm.Label; - -/** - * An {@link scala.tools.asm.Attribute Attribute} that can print the ASM code - * to create an equivalent attribute. - * - * @author Eugene Kuleshov - */ -public interface ASMifiable { - - /** - * Prints the ASM code to create an attribute equal to this attribute. - * - * @param buf - * a buffer used for printing Java code. - * @param varName - * name of the variable in a printed code used to store attribute - * instance. - * @param labelNames - * map of label instances to their names. - */ - void asmify(StringBuffer buf, String varName, Map labelNames); -} diff --git a/src/asm/scala/tools/asm/util/ASMifier.java b/src/asm/scala/tools/asm/util/ASMifier.java deleted file mode 100644 index 521e07541b..0000000000 --- a/src/asm/scala/tools/asm/util/ASMifier.java +++ /dev/null @@ -1,1284 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.util; - -import java.io.FileInputStream; -import java.io.PrintWriter; -import java.util.HashMap; -import java.util.Map; - -import scala.tools.asm.Attribute; -import scala.tools.asm.ClassReader; -import scala.tools.asm.Handle; -import scala.tools.asm.Label; -import scala.tools.asm.Opcodes; -import scala.tools.asm.Type; -import scala.tools.asm.TypePath; - -/** - * A {@link Printer} that prints the ASM code to generate the classes if visits. - * - * @author Eric Bruneton - */ -public class ASMifier extends Printer { - - /** - * The name of the visitor variable in the produced code. - */ - protected final String name; - - /** - * Identifier of the annotation visitor variable in the produced code. - */ - protected final int id; - - /** - * The label names. This map associates String values to Label keys. It is - * used only in ASMifierMethodVisitor. - */ - protected Map labelNames; - - /** - * Pseudo access flag used to distinguish class access flags. - */ - private static final int ACCESS_CLASS = 262144; - - /** - * Pseudo access flag used to distinguish field access flags. - */ - private static final int ACCESS_FIELD = 524288; - - /** - * Pseudo access flag used to distinguish inner class flags. - */ - private static final int ACCESS_INNER = 1048576; - - /** - * Constructs a new {@link ASMifier}. Subclasses must not use this - * constructor. Instead, they must use the - * {@link #ASMifier(int, String, int)} version. - * - * @throws IllegalStateException - * If a subclass calls this constructor. - */ - public ASMifier() { - this(Opcodes.ASM5, "cw", 0); - if (getClass() != ASMifier.class) { - throw new IllegalStateException(); - } - } - - /** - * Constructs a new {@link ASMifier}. - * - * @param api - * the ASM API version implemented by this class. Must be one of - * {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - * @param name - * the name of the visitor variable in the produced code. - * @param id - * identifier of the annotation visitor variable in the produced - * code. - */ - protected ASMifier(final int api, final String name, final int id) { - super(api); - this.name = name; - this.id = id; - } - - /** - * Prints the ASM source code to generate the given class to the standard - * output. - *

- * Usage: ASMifier [-debug] <binary class name or class file name> - * - * @param args - * the command line arguments. - * - * @throws Exception - * if the class cannot be found, or if an IO exception occurs. - */ - public static void main(final String[] args) throws Exception { - int i = 0; - int flags = ClassReader.SKIP_DEBUG; - - boolean ok = true; - if (args.length < 1 || args.length > 2) { - ok = false; - } - if (ok && "-debug".equals(args[0])) { - i = 1; - flags = 0; - if (args.length != 2) { - ok = false; - } - } - if (!ok) { - System.err - .println("Prints the ASM code to generate the given class."); - System.err.println("Usage: ASMifier [-debug] " - + ""); - return; - } - ClassReader cr; - if (args[i].endsWith(".class") || args[i].indexOf('\\') > -1 - || args[i].indexOf('/') > -1) { - cr = new ClassReader(new FileInputStream(args[i])); - } else { - cr = new ClassReader(args[i]); - } - cr.accept(new TraceClassVisitor(null, new ASMifier(), new PrintWriter( - System.out)), flags); - } - - // ------------------------------------------------------------------------ - // Classes - // ------------------------------------------------------------------------ - - @Override - public void visit(final int version, final int access, final String name, - final String signature, final String superName, - final String[] interfaces) { - String simpleName; - int n = name.lastIndexOf('/'); - if (n == -1) { - simpleName = name; - } else { - text.add("package asm." + name.substring(0, n).replace('/', '.') - + ";\n"); - simpleName = name.substring(n + 1); - } - text.add("import java.util.*;\n"); - text.add("import scala.tools.asm.*;\n"); - text.add("public class " + simpleName + "Dump implements Opcodes {\n\n"); - text.add("public static byte[] dump () throws Exception {\n\n"); - text.add("ClassWriter cw = new ClassWriter(0);\n"); - text.add("FieldVisitor fv;\n"); - text.add("MethodVisitor mv;\n"); - text.add("AnnotationVisitor av0;\n\n"); - - buf.setLength(0); - buf.append("cw.visit("); - switch (version) { - case Opcodes.V1_1: - buf.append("V1_1"); - break; - case Opcodes.V1_2: - buf.append("V1_2"); - break; - case Opcodes.V1_3: - buf.append("V1_3"); - break; - case Opcodes.V1_4: - buf.append("V1_4"); - break; - case Opcodes.V1_5: - buf.append("V1_5"); - break; - case Opcodes.V1_6: - buf.append("V1_6"); - break; - case Opcodes.V1_7: - buf.append("V1_7"); - break; - default: - buf.append(version); - break; - } - buf.append(", "); - appendAccess(access | ACCESS_CLASS); - buf.append(", "); - appendConstant(name); - buf.append(", "); - appendConstant(signature); - buf.append(", "); - appendConstant(superName); - buf.append(", "); - if (interfaces != null && interfaces.length > 0) { - buf.append("new String[] {"); - for (int i = 0; i < interfaces.length; ++i) { - buf.append(i == 0 ? " " : ", "); - appendConstant(interfaces[i]); - } - buf.append(" }"); - } else { - buf.append("null"); - } - buf.append(");\n\n"); - text.add(buf.toString()); - } - - @Override - public void visitSource(final String file, final String debug) { - buf.setLength(0); - buf.append("cw.visitSource("); - appendConstant(file); - buf.append(", "); - appendConstant(debug); - buf.append(");\n\n"); - text.add(buf.toString()); - } - - @Override - public void visitOuterClass(final String owner, final String name, - final String desc) { - buf.setLength(0); - buf.append("cw.visitOuterClass("); - appendConstant(owner); - buf.append(", "); - appendConstant(name); - buf.append(", "); - appendConstant(desc); - buf.append(");\n\n"); - text.add(buf.toString()); - } - - @Override - public ASMifier visitClassAnnotation(final String desc, - final boolean visible) { - return visitAnnotation(desc, visible); - } - - @Override - public ASMifier visitClassTypeAnnotation(final int typeRef, - final TypePath typePath, final String desc, final boolean visible) { - return visitTypeAnnotation(typeRef, typePath, desc, visible); - } - - @Override - public void visitClassAttribute(final Attribute attr) { - visitAttribute(attr); - } - - @Override - public void visitInnerClass(final String name, final String outerName, - final String innerName, final int access) { - buf.setLength(0); - buf.append("cw.visitInnerClass("); - appendConstant(name); - buf.append(", "); - appendConstant(outerName); - buf.append(", "); - appendConstant(innerName); - buf.append(", "); - appendAccess(access | ACCESS_INNER); - buf.append(");\n\n"); - text.add(buf.toString()); - } - - @Override - public ASMifier visitField(final int access, final String name, - final String desc, final String signature, final Object value) { - buf.setLength(0); - buf.append("{\n"); - buf.append("fv = cw.visitField("); - appendAccess(access | ACCESS_FIELD); - buf.append(", "); - appendConstant(name); - buf.append(", "); - appendConstant(desc); - buf.append(", "); - appendConstant(signature); - buf.append(", "); - appendConstant(value); - buf.append(");\n"); - text.add(buf.toString()); - ASMifier a = createASMifier("fv", 0); - text.add(a.getText()); - text.add("}\n"); - return a; - } - - @Override - public ASMifier visitMethod(final int access, final String name, - final String desc, final String signature, final String[] exceptions) { - buf.setLength(0); - buf.append("{\n"); - buf.append("mv = cw.visitMethod("); - appendAccess(access); - buf.append(", "); - appendConstant(name); - buf.append(", "); - appendConstant(desc); - buf.append(", "); - appendConstant(signature); - buf.append(", "); - if (exceptions != null && exceptions.length > 0) { - buf.append("new String[] {"); - for (int i = 0; i < exceptions.length; ++i) { - buf.append(i == 0 ? " " : ", "); - appendConstant(exceptions[i]); - } - buf.append(" }"); - } else { - buf.append("null"); - } - buf.append(");\n"); - text.add(buf.toString()); - ASMifier a = createASMifier("mv", 0); - text.add(a.getText()); - text.add("}\n"); - return a; - } - - @Override - public void visitClassEnd() { - text.add("cw.visitEnd();\n\n"); - text.add("return cw.toByteArray();\n"); - text.add("}\n"); - text.add("}\n"); - } - - // ------------------------------------------------------------------------ - // Annotations - // ------------------------------------------------------------------------ - - @Override - public void visit(final String name, final Object value) { - buf.setLength(0); - buf.append("av").append(id).append(".visit("); - appendConstant(buf, name); - buf.append(", "); - appendConstant(buf, value); - buf.append(");\n"); - text.add(buf.toString()); - } - - @Override - public void visitEnum(final String name, final String desc, - final String value) { - buf.setLength(0); - buf.append("av").append(id).append(".visitEnum("); - appendConstant(buf, name); - buf.append(", "); - appendConstant(buf, desc); - buf.append(", "); - appendConstant(buf, value); - buf.append(");\n"); - text.add(buf.toString()); - } - - @Override - public ASMifier visitAnnotation(final String name, final String desc) { - buf.setLength(0); - buf.append("{\n"); - buf.append("AnnotationVisitor av").append(id + 1).append(" = av"); - buf.append(id).append(".visitAnnotation("); - appendConstant(buf, name); - buf.append(", "); - appendConstant(buf, desc); - buf.append(");\n"); - text.add(buf.toString()); - ASMifier a = createASMifier("av", id + 1); - text.add(a.getText()); - text.add("}\n"); - return a; - } - - @Override - public ASMifier visitArray(final String name) { - buf.setLength(0); - buf.append("{\n"); - buf.append("AnnotationVisitor av").append(id + 1).append(" = av"); - buf.append(id).append(".visitArray("); - appendConstant(buf, name); - buf.append(");\n"); - text.add(buf.toString()); - ASMifier a = createASMifier("av", id + 1); - text.add(a.getText()); - text.add("}\n"); - return a; - } - - @Override - public void visitAnnotationEnd() { - buf.setLength(0); - buf.append("av").append(id).append(".visitEnd();\n"); - text.add(buf.toString()); - } - - // ------------------------------------------------------------------------ - // Fields - // ------------------------------------------------------------------------ - - @Override - public ASMifier visitFieldAnnotation(final String desc, - final boolean visible) { - return visitAnnotation(desc, visible); - } - - @Override - public ASMifier visitFieldTypeAnnotation(final int typeRef, - final TypePath typePath, final String desc, final boolean visible) { - return visitTypeAnnotation(typeRef, typePath, desc, visible); - } - - @Override - public void visitFieldAttribute(final Attribute attr) { - visitAttribute(attr); - } - - @Override - public void visitFieldEnd() { - buf.setLength(0); - buf.append(name).append(".visitEnd();\n"); - text.add(buf.toString()); - } - - // ------------------------------------------------------------------------ - // Methods - // ------------------------------------------------------------------------ - - @Override - public void visitParameter(String parameterName, int access) { - buf.setLength(0); - buf.append(name).append(".visitParameter("); - appendString(buf, parameterName); - buf.append(", "); - appendAccess(access); - text.add(buf.append(");\n").toString()); - } - - @Override - public ASMifier visitAnnotationDefault() { - buf.setLength(0); - buf.append("{\n").append("av0 = ").append(name) - .append(".visitAnnotationDefault();\n"); - text.add(buf.toString()); - ASMifier a = createASMifier("av", 0); - text.add(a.getText()); - text.add("}\n"); - return a; - } - - @Override - public ASMifier visitMethodAnnotation(final String desc, - final boolean visible) { - return visitAnnotation(desc, visible); - } - - @Override - public ASMifier visitMethodTypeAnnotation(final int typeRef, - final TypePath typePath, final String desc, final boolean visible) { - return visitTypeAnnotation(typeRef, typePath, desc, visible); - } - - @Override - public ASMifier visitParameterAnnotation(final int parameter, - final String desc, final boolean visible) { - buf.setLength(0); - buf.append("{\n").append("av0 = ").append(name) - .append(".visitParameterAnnotation(").append(parameter) - .append(", "); - appendConstant(desc); - buf.append(", ").append(visible).append(");\n"); - text.add(buf.toString()); - ASMifier a = createASMifier("av", 0); - text.add(a.getText()); - text.add("}\n"); - return a; - } - - @Override - public void visitMethodAttribute(final Attribute attr) { - visitAttribute(attr); - } - - @Override - public void visitCode() { - text.add(name + ".visitCode();\n"); - } - - @Override - public void visitFrame(final int type, final int nLocal, - final Object[] local, final int nStack, final Object[] stack) { - buf.setLength(0); - switch (type) { - case Opcodes.F_NEW: - case Opcodes.F_FULL: - declareFrameTypes(nLocal, local); - declareFrameTypes(nStack, stack); - if (type == Opcodes.F_NEW) { - buf.append(name).append(".visitFrame(Opcodes.F_NEW, "); - } else { - buf.append(name).append(".visitFrame(Opcodes.F_FULL, "); - } - buf.append(nLocal).append(", new Object[] {"); - appendFrameTypes(nLocal, local); - buf.append("}, ").append(nStack).append(", new Object[] {"); - appendFrameTypes(nStack, stack); - buf.append('}'); - break; - case Opcodes.F_APPEND: - declareFrameTypes(nLocal, local); - buf.append(name).append(".visitFrame(Opcodes.F_APPEND,") - .append(nLocal).append(", new Object[] {"); - appendFrameTypes(nLocal, local); - buf.append("}, 0, null"); - break; - case Opcodes.F_CHOP: - buf.append(name).append(".visitFrame(Opcodes.F_CHOP,") - .append(nLocal).append(", null, 0, null"); - break; - case Opcodes.F_SAME: - buf.append(name).append( - ".visitFrame(Opcodes.F_SAME, 0, null, 0, null"); - break; - case Opcodes.F_SAME1: - declareFrameTypes(1, stack); - buf.append(name).append( - ".visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {"); - appendFrameTypes(1, stack); - buf.append('}'); - break; - } - buf.append(");\n"); - text.add(buf.toString()); - } - - @Override - public void visitInsn(final int opcode) { - buf.setLength(0); - buf.append(name).append(".visitInsn(").append(OPCODES[opcode]) - .append(");\n"); - text.add(buf.toString()); - } - - @Override - public void visitIntInsn(final int opcode, final int operand) { - buf.setLength(0); - buf.append(name) - .append(".visitIntInsn(") - .append(OPCODES[opcode]) - .append(", ") - .append(opcode == Opcodes.NEWARRAY ? TYPES[operand] : Integer - .toString(operand)).append(");\n"); - text.add(buf.toString()); - } - - @Override - public void visitVarInsn(final int opcode, final int var) { - buf.setLength(0); - buf.append(name).append(".visitVarInsn(").append(OPCODES[opcode]) - .append(", ").append(var).append(");\n"); - text.add(buf.toString()); - } - - @Override - public void visitTypeInsn(final int opcode, final String type) { - buf.setLength(0); - buf.append(name).append(".visitTypeInsn(").append(OPCODES[opcode]) - .append(", "); - appendConstant(type); - buf.append(");\n"); - text.add(buf.toString()); - } - - @Override - public void visitFieldInsn(final int opcode, final String owner, - final String name, final String desc) { - buf.setLength(0); - buf.append(this.name).append(".visitFieldInsn(") - .append(OPCODES[opcode]).append(", "); - appendConstant(owner); - buf.append(", "); - appendConstant(name); - buf.append(", "); - appendConstant(desc); - buf.append(");\n"); - text.add(buf.toString()); - } - - @Deprecated - @Override - public void visitMethodInsn(final int opcode, final String owner, - final String name, final String desc) { - if (api >= Opcodes.ASM5) { - super.visitMethodInsn(opcode, owner, name, desc); - return; - } - doVisitMethodInsn(opcode, owner, name, desc, - opcode == Opcodes.INVOKEINTERFACE); - } - - @Override - public void visitMethodInsn(final int opcode, final String owner, - final String name, final String desc, final boolean itf) { - if (api < Opcodes.ASM5) { - super.visitMethodInsn(opcode, owner, name, desc, itf); - return; - } - doVisitMethodInsn(opcode, owner, name, desc, itf); - } - - private void doVisitMethodInsn(final int opcode, final String owner, - final String name, final String desc, final boolean itf) { - buf.setLength(0); - buf.append(this.name).append(".visitMethodInsn(") - .append(OPCODES[opcode]).append(", "); - appendConstant(owner); - buf.append(", "); - appendConstant(name); - buf.append(", "); - appendConstant(desc); - buf.append(", "); - buf.append(itf ? "true" : "false"); - buf.append(");\n"); - text.add(buf.toString()); - } - - @Override - public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, - Object... bsmArgs) { - buf.setLength(0); - buf.append(this.name).append(".visitInvokeDynamicInsn("); - appendConstant(name); - buf.append(", "); - appendConstant(desc); - buf.append(", "); - appendConstant(bsm); - buf.append(", new Object[]{"); - for (int i = 0; i < bsmArgs.length; ++i) { - appendConstant(bsmArgs[i]); - if (i != bsmArgs.length - 1) { - buf.append(", "); - } - } - buf.append("});\n"); - text.add(buf.toString()); - } - - @Override - public void visitJumpInsn(final int opcode, final Label label) { - buf.setLength(0); - declareLabel(label); - buf.append(name).append(".visitJumpInsn(").append(OPCODES[opcode]) - .append(", "); - appendLabel(label); - buf.append(");\n"); - text.add(buf.toString()); - } - - @Override - public void visitLabel(final Label label) { - buf.setLength(0); - declareLabel(label); - buf.append(name).append(".visitLabel("); - appendLabel(label); - buf.append(");\n"); - text.add(buf.toString()); - } - - @Override - public void visitLdcInsn(final Object cst) { - buf.setLength(0); - buf.append(name).append(".visitLdcInsn("); - appendConstant(cst); - buf.append(");\n"); - text.add(buf.toString()); - } - - @Override - public void visitIincInsn(final int var, final int increment) { - buf.setLength(0); - buf.append(name).append(".visitIincInsn(").append(var).append(", ") - .append(increment).append(");\n"); - text.add(buf.toString()); - } - - @Override - public void visitTableSwitchInsn(final int min, final int max, - final Label dflt, final Label... labels) { - buf.setLength(0); - for (int i = 0; i < labels.length; ++i) { - declareLabel(labels[i]); - } - declareLabel(dflt); - - buf.append(name).append(".visitTableSwitchInsn(").append(min) - .append(", ").append(max).append(", "); - appendLabel(dflt); - buf.append(", new Label[] {"); - for (int i = 0; i < labels.length; ++i) { - buf.append(i == 0 ? " " : ", "); - appendLabel(labels[i]); - } - buf.append(" });\n"); - text.add(buf.toString()); - } - - @Override - public void visitLookupSwitchInsn(final Label dflt, final int[] keys, - final Label[] labels) { - buf.setLength(0); - for (int i = 0; i < labels.length; ++i) { - declareLabel(labels[i]); - } - declareLabel(dflt); - - buf.append(name).append(".visitLookupSwitchInsn("); - appendLabel(dflt); - buf.append(", new int[] {"); - for (int i = 0; i < keys.length; ++i) { - buf.append(i == 0 ? " " : ", ").append(keys[i]); - } - buf.append(" }, new Label[] {"); - for (int i = 0; i < labels.length; ++i) { - buf.append(i == 0 ? " " : ", "); - appendLabel(labels[i]); - } - buf.append(" });\n"); - text.add(buf.toString()); - } - - @Override - public void visitMultiANewArrayInsn(final String desc, final int dims) { - buf.setLength(0); - buf.append(name).append(".visitMultiANewArrayInsn("); - appendConstant(desc); - buf.append(", ").append(dims).append(");\n"); - text.add(buf.toString()); - } - - @Override - public ASMifier visitInsnAnnotation(final int typeRef, - final TypePath typePath, final String desc, final boolean visible) { - return visitTypeAnnotation("visitInsnAnnotation", typeRef, typePath, - desc, visible); - } - - @Override - public void visitTryCatchBlock(final Label start, final Label end, - final Label handler, final String type) { - buf.setLength(0); - declareLabel(start); - declareLabel(end); - declareLabel(handler); - buf.append(name).append(".visitTryCatchBlock("); - appendLabel(start); - buf.append(", "); - appendLabel(end); - buf.append(", "); - appendLabel(handler); - buf.append(", "); - appendConstant(type); - buf.append(");\n"); - text.add(buf.toString()); - } - - @Override - public ASMifier visitTryCatchAnnotation(final int typeRef, - final TypePath typePath, final String desc, final boolean visible) { - return visitTypeAnnotation("visitTryCatchAnnotation", typeRef, - typePath, desc, visible); - } - - @Override - public void visitLocalVariable(final String name, final String desc, - final String signature, final Label start, final Label end, - final int index) { - buf.setLength(0); - buf.append(this.name).append(".visitLocalVariable("); - appendConstant(name); - buf.append(", "); - appendConstant(desc); - buf.append(", "); - appendConstant(signature); - buf.append(", "); - appendLabel(start); - buf.append(", "); - appendLabel(end); - buf.append(", ").append(index).append(");\n"); - text.add(buf.toString()); - } - - @Override - public Printer visitLocalVariableAnnotation(int typeRef, TypePath typePath, - Label[] start, Label[] end, int[] index, String desc, - boolean visible) { - buf.setLength(0); - buf.append("{\n").append("av0 = ").append(name) - .append(".visitLocalVariableAnnotation("); - buf.append(typeRef); - buf.append(", TypePath.fromString(\"").append(typePath).append("\"), "); - buf.append("new Label[] {"); - for (int i = 0; i < start.length; ++i) { - buf.append(i == 0 ? " " : ", "); - appendLabel(start[i]); - } - buf.append(" }, new Label[] {"); - for (int i = 0; i < end.length; ++i) { - buf.append(i == 0 ? " " : ", "); - appendLabel(end[i]); - } - buf.append(" }, new int[] {"); - for (int i = 0; i < index.length; ++i) { - buf.append(i == 0 ? " " : ", ").append(index[i]); - } - buf.append(" }, "); - appendConstant(desc); - buf.append(", ").append(visible).append(");\n"); - text.add(buf.toString()); - ASMifier a = createASMifier("av", 0); - text.add(a.getText()); - text.add("}\n"); - return a; - } - - @Override - public void visitLineNumber(final int line, final Label start) { - buf.setLength(0); - buf.append(name).append(".visitLineNumber(").append(line).append(", "); - appendLabel(start); - buf.append(");\n"); - text.add(buf.toString()); - } - - @Override - public void visitMaxs(final int maxStack, final int maxLocals) { - buf.setLength(0); - buf.append(name).append(".visitMaxs(").append(maxStack).append(", ") - .append(maxLocals).append(");\n"); - text.add(buf.toString()); - } - - @Override - public void visitMethodEnd() { - buf.setLength(0); - buf.append(name).append(".visitEnd();\n"); - text.add(buf.toString()); - } - - // ------------------------------------------------------------------------ - // Common methods - // ------------------------------------------------------------------------ - - public ASMifier visitAnnotation(final String desc, final boolean visible) { - buf.setLength(0); - buf.append("{\n").append("av0 = ").append(name) - .append(".visitAnnotation("); - appendConstant(desc); - buf.append(", ").append(visible).append(");\n"); - text.add(buf.toString()); - ASMifier a = createASMifier("av", 0); - text.add(a.getText()); - text.add("}\n"); - return a; - } - - public ASMifier visitTypeAnnotation(final int typeRef, - final TypePath typePath, final String desc, final boolean visible) { - return visitTypeAnnotation("visitTypeAnnotation", typeRef, typePath, - desc, visible); - } - - public ASMifier visitTypeAnnotation(final String method, final int typeRef, - final TypePath typePath, final String desc, final boolean visible) { - buf.setLength(0); - buf.append("{\n").append("av0 = ").append(name).append(".") - .append(method).append("("); - buf.append(typeRef); - buf.append(", TypePath.fromString(\"").append(typePath).append("\"), "); - appendConstant(desc); - buf.append(", ").append(visible).append(");\n"); - text.add(buf.toString()); - ASMifier a = createASMifier("av", 0); - text.add(a.getText()); - text.add("}\n"); - return a; - } - - public void visitAttribute(final Attribute attr) { - buf.setLength(0); - buf.append("// ATTRIBUTE ").append(attr.type).append('\n'); - if (attr instanceof ASMifiable) { - if (labelNames == null) { - labelNames = new HashMap(); - } - buf.append("{\n"); - ((ASMifiable) attr).asmify(buf, "attr", labelNames); - buf.append(name).append(".visitAttribute(attr);\n"); - buf.append("}\n"); - } - text.add(buf.toString()); - } - - // ------------------------------------------------------------------------ - // Utility methods - // ------------------------------------------------------------------------ - - protected ASMifier createASMifier(final String name, final int id) { - return new ASMifier(Opcodes.ASM5, name, id); - } - - /** - * Appends a string representation of the given access modifiers to - * {@link #buf buf}. - * - * @param access - * some access modifiers. - */ - void appendAccess(final int access) { - boolean first = true; - if ((access & Opcodes.ACC_PUBLIC) != 0) { - buf.append("ACC_PUBLIC"); - first = false; - } - if ((access & Opcodes.ACC_PRIVATE) != 0) { - buf.append("ACC_PRIVATE"); - first = false; - } - if ((access & Opcodes.ACC_PROTECTED) != 0) { - buf.append("ACC_PROTECTED"); - first = false; - } - if ((access & Opcodes.ACC_FINAL) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_FINAL"); - first = false; - } - if ((access & Opcodes.ACC_STATIC) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_STATIC"); - first = false; - } - if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) { - if (!first) { - buf.append(" + "); - } - if ((access & ACCESS_CLASS) == 0) { - buf.append("ACC_SYNCHRONIZED"); - } else { - buf.append("ACC_SUPER"); - } - first = false; - } - if ((access & Opcodes.ACC_VOLATILE) != 0 - && (access & ACCESS_FIELD) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_VOLATILE"); - first = false; - } - if ((access & Opcodes.ACC_BRIDGE) != 0 && (access & ACCESS_CLASS) == 0 - && (access & ACCESS_FIELD) == 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_BRIDGE"); - first = false; - } - if ((access & Opcodes.ACC_VARARGS) != 0 && (access & ACCESS_CLASS) == 0 - && (access & ACCESS_FIELD) == 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_VARARGS"); - first = false; - } - if ((access & Opcodes.ACC_TRANSIENT) != 0 - && (access & ACCESS_FIELD) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_TRANSIENT"); - first = false; - } - if ((access & Opcodes.ACC_NATIVE) != 0 && (access & ACCESS_CLASS) == 0 - && (access & ACCESS_FIELD) == 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_NATIVE"); - first = false; - } - if ((access & Opcodes.ACC_ENUM) != 0 - && ((access & ACCESS_CLASS) != 0 - || (access & ACCESS_FIELD) != 0 || (access & ACCESS_INNER) != 0)) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_ENUM"); - first = false; - } - if ((access & Opcodes.ACC_ANNOTATION) != 0 - && ((access & ACCESS_CLASS) != 0 || (access & ACCESS_INNER) != 0)) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_ANNOTATION"); - first = false; - } - if ((access & Opcodes.ACC_ABSTRACT) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_ABSTRACT"); - first = false; - } - if ((access & Opcodes.ACC_INTERFACE) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_INTERFACE"); - first = false; - } - if ((access & Opcodes.ACC_STRICT) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_STRICT"); - first = false; - } - if ((access & Opcodes.ACC_SYNTHETIC) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_SYNTHETIC"); - first = false; - } - if ((access & Opcodes.ACC_DEPRECATED) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_DEPRECATED"); - first = false; - } - if ((access & Opcodes.ACC_MANDATED) != 0) { - if (!first) { - buf.append(" + "); - } - buf.append("ACC_MANDATED"); - first = false; - } - if (first) { - buf.append('0'); - } - } - - /** - * Appends a string representation of the given constant to the given - * buffer. - * - * @param cst - * an {@link Integer}, {@link Float}, {@link Long}, - * {@link Double} or {@link String} object. May be null. - */ - protected void appendConstant(final Object cst) { - appendConstant(buf, cst); - } - - /** - * Appends a string representation of the given constant to the given - * buffer. - * - * @param buf - * a string buffer. - * @param cst - * an {@link Integer}, {@link Float}, {@link Long}, - * {@link Double} or {@link String} object. May be null. - */ - static void appendConstant(final StringBuffer buf, final Object cst) { - if (cst == null) { - buf.append("null"); - } else if (cst instanceof String) { - appendString(buf, (String) cst); - } else if (cst instanceof Type) { - buf.append("Type.getType(\""); - buf.append(((Type) cst).getDescriptor()); - buf.append("\")"); - } else if (cst instanceof Handle) { - buf.append("new Handle("); - Handle h = (Handle) cst; - buf.append("Opcodes.").append(HANDLE_TAG[h.getTag()]) - .append(", \""); - buf.append(h.getOwner()).append("\", \""); - buf.append(h.getName()).append("\", \""); - buf.append(h.getDesc()).append("\")"); - } else if (cst instanceof Byte) { - buf.append("new Byte((byte)").append(cst).append(')'); - } else if (cst instanceof Boolean) { - buf.append(((Boolean) cst).booleanValue() ? "Boolean.TRUE" - : "Boolean.FALSE"); - } else if (cst instanceof Short) { - buf.append("new Short((short)").append(cst).append(')'); - } else if (cst instanceof Character) { - int c = ((Character) cst).charValue(); - buf.append("new Character((char)").append(c).append(')'); - } else if (cst instanceof Integer) { - buf.append("new Integer(").append(cst).append(')'); - } else if (cst instanceof Float) { - buf.append("new Float(\"").append(cst).append("\")"); - } else if (cst instanceof Long) { - buf.append("new Long(").append(cst).append("L)"); - } else if (cst instanceof Double) { - buf.append("new Double(\"").append(cst).append("\")"); - } else if (cst instanceof byte[]) { - byte[] v = (byte[]) cst; - buf.append("new byte[] {"); - for (int i = 0; i < v.length; i++) { - buf.append(i == 0 ? "" : ",").append(v[i]); - } - buf.append('}'); - } else if (cst instanceof boolean[]) { - boolean[] v = (boolean[]) cst; - buf.append("new boolean[] {"); - for (int i = 0; i < v.length; i++) { - buf.append(i == 0 ? "" : ",").append(v[i]); - } - buf.append('}'); - } else if (cst instanceof short[]) { - short[] v = (short[]) cst; - buf.append("new short[] {"); - for (int i = 0; i < v.length; i++) { - buf.append(i == 0 ? "" : ",").append("(short)").append(v[i]); - } - buf.append('}'); - } else if (cst instanceof char[]) { - char[] v = (char[]) cst; - buf.append("new char[] {"); - for (int i = 0; i < v.length; i++) { - buf.append(i == 0 ? "" : ",").append("(char)") - .append((int) v[i]); - } - buf.append('}'); - } else if (cst instanceof int[]) { - int[] v = (int[]) cst; - buf.append("new int[] {"); - for (int i = 0; i < v.length; i++) { - buf.append(i == 0 ? "" : ",").append(v[i]); - } - buf.append('}'); - } else if (cst instanceof long[]) { - long[] v = (long[]) cst; - buf.append("new long[] {"); - for (int i = 0; i < v.length; i++) { - buf.append(i == 0 ? "" : ",").append(v[i]).append('L'); - } - buf.append('}'); - } else if (cst instanceof float[]) { - float[] v = (float[]) cst; - buf.append("new float[] {"); - for (int i = 0; i < v.length; i++) { - buf.append(i == 0 ? "" : ",").append(v[i]).append('f'); - } - buf.append('}'); - } else if (cst instanceof double[]) { - double[] v = (double[]) cst; - buf.append("new double[] {"); - for (int i = 0; i < v.length; i++) { - buf.append(i == 0 ? "" : ",").append(v[i]).append('d'); - } - buf.append('}'); - } - } - - private void declareFrameTypes(final int n, final Object[] o) { - for (int i = 0; i < n; ++i) { - if (o[i] instanceof Label) { - declareLabel((Label) o[i]); - } - } - } - - private void appendFrameTypes(final int n, final Object[] o) { - for (int i = 0; i < n; ++i) { - if (i > 0) { - buf.append(", "); - } - if (o[i] instanceof String) { - appendConstant(o[i]); - } else if (o[i] instanceof Integer) { - switch (((Integer) o[i]).intValue()) { - case 0: - buf.append("Opcodes.TOP"); - break; - case 1: - buf.append("Opcodes.INTEGER"); - break; - case 2: - buf.append("Opcodes.FLOAT"); - break; - case 3: - buf.append("Opcodes.DOUBLE"); - break; - case 4: - buf.append("Opcodes.LONG"); - break; - case 5: - buf.append("Opcodes.NULL"); - break; - case 6: - buf.append("Opcodes.UNINITIALIZED_THIS"); - break; - } - } else { - appendLabel((Label) o[i]); - } - } - } - - /** - * Appends a declaration of the given label to {@link #buf buf}. This - * declaration is of the form "Label lXXX = new Label();". Does nothing if - * the given label has already been declared. - * - * @param l - * a label. - */ - protected void declareLabel(final Label l) { - if (labelNames == null) { - labelNames = new HashMap(); - } - String name = labelNames.get(l); - if (name == null) { - name = "l" + labelNames.size(); - labelNames.put(l, name); - buf.append("Label ").append(name).append(" = new Label();\n"); - } - } - - /** - * Appends the name of the given label to {@link #buf buf}. The given label - * must already have a name. One way to ensure this is to always call - * {@link #declareLabel declared} before calling this method. - * - * @param l - * a label. - */ - protected void appendLabel(final Label l) { - buf.append(labelNames.get(l)); - } -} diff --git a/src/asm/scala/tools/asm/util/CheckAnnotationAdapter.java b/src/asm/scala/tools/asm/util/CheckAnnotationAdapter.java deleted file mode 100644 index 70441d1df4..0000000000 --- a/src/asm/scala/tools/asm/util/CheckAnnotationAdapter.java +++ /dev/null @@ -1,136 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.util; - -import scala.tools.asm.AnnotationVisitor; -import scala.tools.asm.Opcodes; -import scala.tools.asm.Type; - -/** - * An {@link AnnotationVisitor} that checks that its methods are properly used. - * - * @author Eric Bruneton - */ -public class CheckAnnotationAdapter extends AnnotationVisitor { - - private final boolean named; - - private boolean end; - - public CheckAnnotationAdapter(final AnnotationVisitor av) { - this(av, true); - } - - CheckAnnotationAdapter(final AnnotationVisitor av, final boolean named) { - super(Opcodes.ASM5, av); - this.named = named; - } - - @Override - public void visit(final String name, final Object value) { - checkEnd(); - checkName(name); - if (!(value instanceof Byte || value instanceof Boolean - || value instanceof Character || value instanceof Short - || value instanceof Integer || value instanceof Long - || value instanceof Float || value instanceof Double - || value instanceof String || value instanceof Type - || value instanceof byte[] || value instanceof boolean[] - || value instanceof char[] || value instanceof short[] - || value instanceof int[] || value instanceof long[] - || value instanceof float[] || value instanceof double[])) { - throw new IllegalArgumentException("Invalid annotation value"); - } - if (value instanceof Type) { - int sort = ((Type) value).getSort(); - if (sort == Type.METHOD) { - throw new IllegalArgumentException("Invalid annotation value"); - } - } - if (av != null) { - av.visit(name, value); - } - } - - @Override - public void visitEnum(final String name, final String desc, - final String value) { - checkEnd(); - checkName(name); - CheckMethodAdapter.checkDesc(desc, false); - if (value == null) { - throw new IllegalArgumentException("Invalid enum value"); - } - if (av != null) { - av.visitEnum(name, desc, value); - } - } - - @Override - public AnnotationVisitor visitAnnotation(final String name, - final String desc) { - checkEnd(); - checkName(name); - CheckMethodAdapter.checkDesc(desc, false); - return new CheckAnnotationAdapter(av == null ? null - : av.visitAnnotation(name, desc)); - } - - @Override - public AnnotationVisitor visitArray(final String name) { - checkEnd(); - checkName(name); - return new CheckAnnotationAdapter(av == null ? null - : av.visitArray(name), false); - } - - @Override - public void visitEnd() { - checkEnd(); - end = true; - if (av != null) { - av.visitEnd(); - } - } - - private void checkEnd() { - if (end) { - throw new IllegalStateException( - "Cannot call a visit method after visitEnd has been called"); - } - } - - private void checkName(final String name) { - if (named && name == null) { - throw new IllegalArgumentException( - "Annotation value name must not be null"); - } - } -} diff --git a/src/asm/scala/tools/asm/util/CheckClassAdapter.java b/src/asm/scala/tools/asm/util/CheckClassAdapter.java deleted file mode 100644 index 88afdb0441..0000000000 --- a/src/asm/scala/tools/asm/util/CheckClassAdapter.java +++ /dev/null @@ -1,1009 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.util; - -import java.io.FileInputStream; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import scala.tools.asm.AnnotationVisitor; -import scala.tools.asm.Attribute; -import scala.tools.asm.ClassReader; -import scala.tools.asm.ClassVisitor; -import scala.tools.asm.FieldVisitor; -import scala.tools.asm.Label; -import scala.tools.asm.MethodVisitor; -import scala.tools.asm.Opcodes; -import scala.tools.asm.Type; -import scala.tools.asm.TypePath; -import scala.tools.asm.TypeReference; -import scala.tools.asm.tree.ClassNode; -import scala.tools.asm.tree.MethodNode; -import scala.tools.asm.tree.analysis.Analyzer; -import scala.tools.asm.tree.analysis.BasicValue; -import scala.tools.asm.tree.analysis.Frame; -import scala.tools.asm.tree.analysis.SimpleVerifier; - -/** - * A {@link ClassVisitor} that checks that its methods are properly used. More - * precisely this class adapter checks each method call individually, based - * only on its arguments, but does not check the sequence - * of method calls. For example, the invalid sequence - * visitField(ACC_PUBLIC, "i", "I", null) visitField(ACC_PUBLIC, - * "i", "D", null) will not be detected by this class adapter. - * - *

- * CheckClassAdapter can be also used to verify bytecode - * transformations in order to make sure transformed bytecode is sane. For - * example: - * - *

- *   InputStream is = ...; // get bytes for the source class
- *   ClassReader cr = new ClassReader(is);
- *   ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
- *   ClassVisitor cv = new MyClassAdapter(new CheckClassAdapter(cw));
- *   cr.accept(cv, 0);
- *
- *   StringWriter sw = new StringWriter();
- *   PrintWriter pw = new PrintWriter(sw);
- *   CheckClassAdapter.verify(new ClassReader(cw.toByteArray()), false, pw);
- *   assertTrue(sw.toString(), sw.toString().length()==0);
- * 
- * - * Above code runs transformed bytecode trough the - * CheckClassAdapter. It won't be exactly the same verification as - * JVM does, but it run data flow analysis for the code of each method and - * checks that expectations are met for each method instruction. - * - *

- * If method bytecode has errors, assertion text will show the erroneous - * instruction number and dump of the failed method with information about - * locals and stack slot for each instruction. For example (format is - - * insnNumber locals : stack): - * - *

- * org.objectweb.asm.tree.analysis.AnalyzerException: Error at instruction 71: Expected I, but found .
- *   at org.objectweb.asm.tree.analysis.Analyzer.analyze(Analyzer.java:289)
- *   at org.objectweb.asm.util.CheckClassAdapter.verify(CheckClassAdapter.java:135)
- * ...
- * remove()V
- * 00000 LinkedBlockingQueue$Itr . . . . . . . .  :
- *   ICONST_0
- * 00001 LinkedBlockingQueue$Itr . . . . . . . .  : I
- *   ISTORE 2
- * 00001 LinkedBlockingQueue$Itr . I . . . . . .  :
- * ...
- *
- * 00071 LinkedBlockingQueue$Itr . I . . . . . .  :
- *   ILOAD 1
- * 00072 ?
- *   INVOKESPECIAL java/lang/Integer.<init> (I)V
- * ...
- * 
- * - * In the above output you can see that variable 1 loaded by - * ILOAD 1 instruction at position 00071 is not - * initialized. You can also see that at the beginning of the method (code - * inserted by the transformation) variable 2 is initialized. - * - *

- * Note that when used like that, CheckClassAdapter.verify() can - * trigger additional class loading, because it is using - * SimpleVerifier. - * - * @author Eric Bruneton - */ -public class CheckClassAdapter extends ClassVisitor { - - /** - * The class version number. - */ - private int version; - - /** - * true if the visit method has been called. - */ - private boolean start; - - /** - * true if the visitSource method has been called. - */ - private boolean source; - - /** - * true if the visitOuterClass method has been called. - */ - private boolean outer; - - /** - * true if the visitEnd method has been called. - */ - private boolean end; - - /** - * The already visited labels. This map associate Integer values to Label - * keys. - */ - private Map labels; - - /** - * true if the method code must be checked with a BasicVerifier. - */ - private boolean checkDataFlow; - - /** - * Checks a given class. - *

- * Usage: CheckClassAdapter <binary class name or class file name> - * - * @param args - * the command line arguments. - * - * @throws Exception - * if the class cannot be found, or if an IO exception occurs. - */ - public static void main(final String[] args) throws Exception { - if (args.length != 1) { - System.err.println("Verifies the given class."); - System.err.println("Usage: CheckClassAdapter " - + ""); - return; - } - ClassReader cr; - if (args[0].endsWith(".class")) { - cr = new ClassReader(new FileInputStream(args[0])); - } else { - cr = new ClassReader(args[0]); - } - - verify(cr, false, new PrintWriter(System.err)); - } - - /** - * Checks a given class. - * - * @param cr - * a ClassReader that contains bytecode for the - * analysis. - * @param loader - * a ClassLoader which will be used to load - * referenced classes. This is useful if you are verifiying - * multiple interdependent classes. - * @param dump - * true if bytecode should be printed out not only when errors - * are found. - * @param pw - * write where results going to be printed - */ - public static void verify(final ClassReader cr, final ClassLoader loader, - final boolean dump, final PrintWriter pw) { - ClassNode cn = new ClassNode(); - cr.accept(new CheckClassAdapter(cn, false), ClassReader.SKIP_DEBUG); - - Type syperType = cn.superName == null ? null : Type - .getObjectType(cn.superName); - List methods = cn.methods; - - List interfaces = new ArrayList(); - for (Iterator i = cn.interfaces.iterator(); i.hasNext();) { - interfaces.add(Type.getObjectType(i.next())); - } - - for (int i = 0; i < methods.size(); ++i) { - MethodNode method = methods.get(i); - SimpleVerifier verifier = new SimpleVerifier( - Type.getObjectType(cn.name), syperType, interfaces, - (cn.access & Opcodes.ACC_INTERFACE) != 0); - Analyzer a = new Analyzer(verifier); - if (loader != null) { - verifier.setClassLoader(loader); - } - try { - a.analyze(cn.name, method); - if (!dump) { - continue; - } - } catch (Exception e) { - e.printStackTrace(pw); - } - printAnalyzerResult(method, a, pw); - } - pw.flush(); - } - - /** - * Checks a given class - * - * @param cr - * a ClassReader that contains bytecode for the - * analysis. - * @param dump - * true if bytecode should be printed out not only when errors - * are found. - * @param pw - * write where results going to be printed - */ - public static void verify(final ClassReader cr, final boolean dump, - final PrintWriter pw) { - verify(cr, null, dump, pw); - } - - static void printAnalyzerResult(MethodNode method, Analyzer a, - final PrintWriter pw) { - Frame[] frames = a.getFrames(); - Textifier t = new Textifier(); - TraceMethodVisitor mv = new TraceMethodVisitor(t); - - pw.println(method.name + method.desc); - for (int j = 0; j < method.instructions.size(); ++j) { - method.instructions.get(j).accept(mv); - - StringBuilder sb = new StringBuilder(); - Frame f = frames[j]; - if (f == null) { - sb.append('?'); - } else { - for (int k = 0; k < f.getLocals(); ++k) { - sb.append(getShortName(f.getLocal(k).toString())) - .append(' '); - } - sb.append(" : "); - for (int k = 0; k < f.getStackSize(); ++k) { - sb.append(getShortName(f.getStack(k).toString())) - .append(' '); - } - } - while (sb.length() < method.maxStack + method.maxLocals + 1) { - sb.append(' '); - } - pw.print(Integer.toString(j + 100000).substring(1)); - pw.print(" " + sb + " : " + t.text.get(t.text.size() - 1)); - } - for (int j = 0; j < method.tryCatchBlocks.size(); ++j) { - method.tryCatchBlocks.get(j).accept(mv); - pw.print(" " + t.text.get(t.text.size() - 1)); - } - pw.println(); - } - - private static String getShortName(final String name) { - int n = name.lastIndexOf('/'); - int k = name.length(); - if (name.charAt(k - 1) == ';') { - k--; - } - return n == -1 ? name : name.substring(n + 1, k); - } - - /** - * Constructs a new {@link CheckClassAdapter}. Subclasses must not use - * this constructor. Instead, they must use the - * {@link #CheckClassAdapter(int, ClassVisitor, boolean)} version. - * - * @param cv - * the class visitor to which this adapter must delegate calls. - */ - public CheckClassAdapter(final ClassVisitor cv) { - this(cv, true); - } - - /** - * Constructs a new {@link CheckClassAdapter}. Subclasses must not use - * this constructor. Instead, they must use the - * {@link #CheckClassAdapter(int, ClassVisitor, boolean)} version. - * - * @param cv - * the class visitor to which this adapter must delegate calls. - * @param checkDataFlow - * true to perform basic data flow checks, or - * false to not perform any data flow check (see - * {@link CheckMethodAdapter}). This option requires valid - * maxLocals and maxStack values. - * @throws IllegalStateException - * If a subclass calls this constructor. - */ - public CheckClassAdapter(final ClassVisitor cv, final boolean checkDataFlow) { - this(Opcodes.ASM5, cv, checkDataFlow); - if (getClass() != CheckClassAdapter.class) { - throw new IllegalStateException(); - } - } - - /** - * Constructs a new {@link CheckClassAdapter}. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - * @param cv - * the class visitor to which this adapter must delegate calls. - * @param checkDataFlow - * true to perform basic data flow checks, or - * false to not perform any data flow check (see - * {@link CheckMethodAdapter}). This option requires valid - * maxLocals and maxStack values. - */ - protected CheckClassAdapter(final int api, final ClassVisitor cv, - final boolean checkDataFlow) { - super(api, cv); - this.labels = new HashMap(); - this.checkDataFlow = checkDataFlow; - } - - // ------------------------------------------------------------------------ - // Implementation of the ClassVisitor interface - // ------------------------------------------------------------------------ - - @Override - public void visit(final int version, final int access, final String name, - final String signature, final String superName, - final String[] interfaces) { - if (start) { - throw new IllegalStateException("visit must be called only once"); - } - start = true; - checkState(); - checkAccess(access, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL - + Opcodes.ACC_SUPER + Opcodes.ACC_INTERFACE - + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC - + Opcodes.ACC_ANNOTATION + Opcodes.ACC_ENUM - + Opcodes.ACC_DEPRECATED + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE - if (name == null || !name.endsWith("package-info")) { - CheckMethodAdapter.checkInternalName(name, "class name"); - } - if ("java/lang/Object".equals(name)) { - if (superName != null) { - throw new IllegalArgumentException( - "The super class name of the Object class must be 'null'"); - } - } else { - CheckMethodAdapter.checkInternalName(superName, "super class name"); - } - if (signature != null) { - checkClassSignature(signature); - } - if ((access & Opcodes.ACC_INTERFACE) != 0) { - if (!"java/lang/Object".equals(superName)) { - throw new IllegalArgumentException( - "The super class name of interfaces must be 'java/lang/Object'"); - } - } - if (interfaces != null) { - for (int i = 0; i < interfaces.length; ++i) { - CheckMethodAdapter.checkInternalName(interfaces[i], - "interface name at index " + i); - } - } - this.version = version; - super.visit(version, access, name, signature, superName, interfaces); - } - - @Override - public void visitSource(final String file, final String debug) { - checkState(); - if (source) { - throw new IllegalStateException( - "visitSource can be called only once."); - } - source = true; - super.visitSource(file, debug); - } - - @Override - public void visitOuterClass(final String owner, final String name, - final String desc) { - checkState(); - if (outer) { - throw new IllegalStateException( - "visitOuterClass can be called only once."); - } - outer = true; - if (owner == null) { - throw new IllegalArgumentException("Illegal outer class owner"); - } - if (desc != null) { - CheckMethodAdapter.checkMethodDesc(desc); - } - super.visitOuterClass(owner, name, desc); - } - - @Override - public void visitInnerClass(final String name, final String outerName, - final String innerName, final int access) { - checkState(); - CheckMethodAdapter.checkInternalName(name, "class name"); - if (outerName != null) { - CheckMethodAdapter.checkInternalName(outerName, "outer class name"); - } - if (innerName != null) { - int start = 0; - while (start < innerName.length() - && Character.isDigit(innerName.charAt(start))) { - start++; - } - if (start == 0 || start < innerName.length()) { - CheckMethodAdapter.checkIdentifier(innerName, start, -1, - "inner class name"); - } - } - checkAccess(access, Opcodes.ACC_PUBLIC + Opcodes.ACC_PRIVATE - + Opcodes.ACC_PROTECTED + Opcodes.ACC_STATIC - + Opcodes.ACC_FINAL + Opcodes.ACC_INTERFACE - + Opcodes.ACC_ABSTRACT + Opcodes.ACC_SYNTHETIC - + Opcodes.ACC_ANNOTATION + Opcodes.ACC_ENUM); - super.visitInnerClass(name, outerName, innerName, access); - } - - @Override - public FieldVisitor visitField(final int access, final String name, - final String desc, final String signature, final Object value) { - checkState(); - checkAccess(access, Opcodes.ACC_PUBLIC + Opcodes.ACC_PRIVATE - + Opcodes.ACC_PROTECTED + Opcodes.ACC_STATIC - + Opcodes.ACC_FINAL + Opcodes.ACC_VOLATILE - + Opcodes.ACC_TRANSIENT + Opcodes.ACC_SYNTHETIC - + Opcodes.ACC_ENUM + Opcodes.ACC_DEPRECATED + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE - CheckMethodAdapter.checkUnqualifiedName(version, name, "field name"); - CheckMethodAdapter.checkDesc(desc, false); - if (signature != null) { - checkFieldSignature(signature); - } - if (value != null) { - CheckMethodAdapter.checkConstant(value); - } - FieldVisitor av = super - .visitField(access, name, desc, signature, value); - return new CheckFieldAdapter(av); - } - - @Override - public MethodVisitor visitMethod(final int access, final String name, - final String desc, final String signature, final String[] exceptions) { - checkState(); - checkAccess(access, Opcodes.ACC_PUBLIC + Opcodes.ACC_PRIVATE - + Opcodes.ACC_PROTECTED + Opcodes.ACC_STATIC - + Opcodes.ACC_FINAL + Opcodes.ACC_SYNCHRONIZED - + Opcodes.ACC_BRIDGE + Opcodes.ACC_VARARGS + Opcodes.ACC_NATIVE - + Opcodes.ACC_ABSTRACT + Opcodes.ACC_STRICT - + Opcodes.ACC_SYNTHETIC + Opcodes.ACC_DEPRECATED + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE - if (!"".equals(name) && !"".equals(name)) { - CheckMethodAdapter.checkMethodIdentifier(version, name, - "method name"); - } - CheckMethodAdapter.checkMethodDesc(desc); - if (signature != null) { - checkMethodSignature(signature); - } - if (exceptions != null) { - for (int i = 0; i < exceptions.length; ++i) { - CheckMethodAdapter.checkInternalName(exceptions[i], - "exception name at index " + i); - } - } - CheckMethodAdapter cma; - if (checkDataFlow) { - cma = new CheckMethodAdapter(access, name, desc, super.visitMethod( - access, name, desc, signature, exceptions), labels); - } else { - cma = new CheckMethodAdapter(super.visitMethod(access, name, desc, - signature, exceptions), labels); - } - cma.version = version; - return cma; - } - - @Override - public AnnotationVisitor visitAnnotation(final String desc, - final boolean visible) { - checkState(); - CheckMethodAdapter.checkDesc(desc, false); - return new CheckAnnotationAdapter(super.visitAnnotation(desc, visible)); - } - - @Override - public AnnotationVisitor visitTypeAnnotation(final int typeRef, - final TypePath typePath, final String desc, final boolean visible) { - checkState(); - int sort = typeRef >>> 24; - if (sort != TypeReference.CLASS_TYPE_PARAMETER - && sort != TypeReference.CLASS_TYPE_PARAMETER_BOUND - && sort != TypeReference.CLASS_EXTENDS) { - throw new IllegalArgumentException("Invalid type reference sort 0x" - + Integer.toHexString(sort)); - } - checkTypeRefAndPath(typeRef, typePath); - CheckMethodAdapter.checkDesc(desc, false); - return new CheckAnnotationAdapter(super.visitTypeAnnotation(typeRef, - typePath, desc, visible)); - } - - @Override - public void visitAttribute(final Attribute attr) { - checkState(); - if (attr == null) { - throw new IllegalArgumentException( - "Invalid attribute (must not be null)"); - } - super.visitAttribute(attr); - } - - @Override - public void visitEnd() { - checkState(); - end = true; - super.visitEnd(); - } - - // ------------------------------------------------------------------------ - // Utility methods - // ------------------------------------------------------------------------ - - /** - * Checks that the visit method has been called and that visitEnd has not - * been called. - */ - private void checkState() { - if (!start) { - throw new IllegalStateException( - "Cannot visit member before visit has been called."); - } - if (end) { - throw new IllegalStateException( - "Cannot visit member after visitEnd has been called."); - } - } - - /** - * Checks that the given access flags do not contain invalid flags. This - * method also checks that mutually incompatible flags are not set - * simultaneously. - * - * @param access - * the access flags to be checked - * @param possibleAccess - * the valid access flags. - */ - static void checkAccess(final int access, final int possibleAccess) { - if ((access & ~possibleAccess) != 0) { - throw new IllegalArgumentException("Invalid access flags: " - + access); - } - int pub = (access & Opcodes.ACC_PUBLIC) == 0 ? 0 : 1; - int pri = (access & Opcodes.ACC_PRIVATE) == 0 ? 0 : 1; - int pro = (access & Opcodes.ACC_PROTECTED) == 0 ? 0 : 1; - if (pub + pri + pro > 1) { - throw new IllegalArgumentException( - "public private and protected are mutually exclusive: " - + access); - } - int fin = (access & Opcodes.ACC_FINAL) == 0 ? 0 : 1; - int abs = (access & Opcodes.ACC_ABSTRACT) == 0 ? 0 : 1; - if (fin + abs > 1) { - throw new IllegalArgumentException( - "final and abstract are mutually exclusive: " + access); - } - } - - /** - * Checks a class signature. - * - * @param signature - * a string containing the signature that must be checked. - */ - public static void checkClassSignature(final String signature) { - // ClassSignature: - // FormalTypeParameters? ClassTypeSignature ClassTypeSignature* - - int pos = 0; - if (getChar(signature, 0) == '<') { - pos = checkFormalTypeParameters(signature, pos); - } - pos = checkClassTypeSignature(signature, pos); - while (getChar(signature, pos) == 'L') { - pos = checkClassTypeSignature(signature, pos); - } - if (pos != signature.length()) { - throw new IllegalArgumentException(signature + ": error at index " - + pos); - } - } - - /** - * Checks a method signature. - * - * @param signature - * a string containing the signature that must be checked. - */ - public static void checkMethodSignature(final String signature) { - // MethodTypeSignature: - // FormalTypeParameters? ( TypeSignature* ) ( TypeSignature | V ) ( - // ^ClassTypeSignature | ^TypeVariableSignature )* - - int pos = 0; - if (getChar(signature, 0) == '<') { - pos = checkFormalTypeParameters(signature, pos); - } - pos = checkChar('(', signature, pos); - while ("ZCBSIFJDL[T".indexOf(getChar(signature, pos)) != -1) { - pos = checkTypeSignature(signature, pos); - } - pos = checkChar(')', signature, pos); - if (getChar(signature, pos) == 'V') { - ++pos; - } else { - pos = checkTypeSignature(signature, pos); - } - while (getChar(signature, pos) == '^') { - ++pos; - if (getChar(signature, pos) == 'L') { - pos = checkClassTypeSignature(signature, pos); - } else { - pos = checkTypeVariableSignature(signature, pos); - } - } - if (pos != signature.length()) { - throw new IllegalArgumentException(signature + ": error at index " - + pos); - } - } - - /** - * Checks a field signature. - * - * @param signature - * a string containing the signature that must be checked. - */ - public static void checkFieldSignature(final String signature) { - int pos = checkFieldTypeSignature(signature, 0); - if (pos != signature.length()) { - throw new IllegalArgumentException(signature + ": error at index " - + pos); - } - } - - /** - * Checks the reference to a type in a type annotation. - * - * @param typeRef - * a reference to an annotated type. - * @param typePath - * the path to the annotated type argument, wildcard bound, array - * element type, or static inner type within 'typeRef'. May be - * null if the annotation targets 'typeRef' as a whole. - */ - static void checkTypeRefAndPath(int typeRef, TypePath typePath) { - int mask = 0; - switch (typeRef >>> 24) { - case TypeReference.CLASS_TYPE_PARAMETER: - case TypeReference.METHOD_TYPE_PARAMETER: - case TypeReference.METHOD_FORMAL_PARAMETER: - mask = 0xFFFF0000; - break; - case TypeReference.FIELD: - case TypeReference.METHOD_RETURN: - case TypeReference.METHOD_RECEIVER: - case TypeReference.LOCAL_VARIABLE: - case TypeReference.RESOURCE_VARIABLE: - case TypeReference.INSTANCEOF: - case TypeReference.NEW: - case TypeReference.CONSTRUCTOR_REFERENCE: - case TypeReference.METHOD_REFERENCE: - mask = 0xFF000000; - break; - case TypeReference.CLASS_EXTENDS: - case TypeReference.CLASS_TYPE_PARAMETER_BOUND: - case TypeReference.METHOD_TYPE_PARAMETER_BOUND: - case TypeReference.THROWS: - case TypeReference.EXCEPTION_PARAMETER: - mask = 0xFFFFFF00; - break; - case TypeReference.CAST: - case TypeReference.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: - case TypeReference.METHOD_INVOCATION_TYPE_ARGUMENT: - case TypeReference.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT: - case TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT: - mask = 0xFF0000FF; - break; - default: - throw new IllegalArgumentException("Invalid type reference sort 0x" - + Integer.toHexString(typeRef >>> 24)); - } - if ((typeRef & ~mask) != 0) { - throw new IllegalArgumentException("Invalid type reference 0x" - + Integer.toHexString(typeRef)); - } - if (typePath != null) { - for (int i = 0; i < typePath.getLength(); ++i) { - int step = typePath.getStep(i); - if (step != TypePath.ARRAY_ELEMENT - && step != TypePath.INNER_TYPE - && step != TypePath.TYPE_ARGUMENT - && step != TypePath.WILDCARD_BOUND) { - throw new IllegalArgumentException( - "Invalid type path step " + i + " in " + typePath); - } - if (step != TypePath.TYPE_ARGUMENT - && typePath.getStepArgument(i) != 0) { - throw new IllegalArgumentException( - "Invalid type path step argument for step " + i - + " in " + typePath); - } - } - } - } - - /** - * Checks the formal type parameters of a class or method signature. - * - * @param signature - * a string containing the signature that must be checked. - * @param pos - * index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkFormalTypeParameters(final String signature, int pos) { - // FormalTypeParameters: - // < FormalTypeParameter+ > - - pos = checkChar('<', signature, pos); - pos = checkFormalTypeParameter(signature, pos); - while (getChar(signature, pos) != '>') { - pos = checkFormalTypeParameter(signature, pos); - } - return pos + 1; - } - - /** - * Checks a formal type parameter of a class or method signature. - * - * @param signature - * a string containing the signature that must be checked. - * @param pos - * index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkFormalTypeParameter(final String signature, int pos) { - // FormalTypeParameter: - // Identifier : FieldTypeSignature? (: FieldTypeSignature)* - - pos = checkIdentifier(signature, pos); - pos = checkChar(':', signature, pos); - if ("L[T".indexOf(getChar(signature, pos)) != -1) { - pos = checkFieldTypeSignature(signature, pos); - } - while (getChar(signature, pos) == ':') { - pos = checkFieldTypeSignature(signature, pos + 1); - } - return pos; - } - - /** - * Checks a field type signature. - * - * @param signature - * a string containing the signature that must be checked. - * @param pos - * index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkFieldTypeSignature(final String signature, int pos) { - // FieldTypeSignature: - // ClassTypeSignature | ArrayTypeSignature | TypeVariableSignature - // - // ArrayTypeSignature: - // [ TypeSignature - - switch (getChar(signature, pos)) { - case 'L': - return checkClassTypeSignature(signature, pos); - case '[': - return checkTypeSignature(signature, pos + 1); - default: - return checkTypeVariableSignature(signature, pos); - } - } - - /** - * Checks a class type signature. - * - * @param signature - * a string containing the signature that must be checked. - * @param pos - * index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkClassTypeSignature(final String signature, int pos) { - // ClassTypeSignature: - // L Identifier ( / Identifier )* TypeArguments? ( . Identifier - // TypeArguments? )* ; - - pos = checkChar('L', signature, pos); - pos = checkIdentifier(signature, pos); - while (getChar(signature, pos) == '/') { - pos = checkIdentifier(signature, pos + 1); - } - if (getChar(signature, pos) == '<') { - pos = checkTypeArguments(signature, pos); - } - while (getChar(signature, pos) == '.') { - pos = checkIdentifier(signature, pos + 1); - if (getChar(signature, pos) == '<') { - pos = checkTypeArguments(signature, pos); - } - } - return checkChar(';', signature, pos); - } - - /** - * Checks the type arguments in a class type signature. - * - * @param signature - * a string containing the signature that must be checked. - * @param pos - * index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkTypeArguments(final String signature, int pos) { - // TypeArguments: - // < TypeArgument+ > - - pos = checkChar('<', signature, pos); - pos = checkTypeArgument(signature, pos); - while (getChar(signature, pos) != '>') { - pos = checkTypeArgument(signature, pos); - } - return pos + 1; - } - - /** - * Checks a type argument in a class type signature. - * - * @param signature - * a string containing the signature that must be checked. - * @param pos - * index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkTypeArgument(final String signature, int pos) { - // TypeArgument: - // * | ( ( + | - )? FieldTypeSignature ) - - char c = getChar(signature, pos); - if (c == '*') { - return pos + 1; - } else if (c == '+' || c == '-') { - pos++; - } - return checkFieldTypeSignature(signature, pos); - } - - /** - * Checks a type variable signature. - * - * @param signature - * a string containing the signature that must be checked. - * @param pos - * index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkTypeVariableSignature(final String signature, - int pos) { - // TypeVariableSignature: - // T Identifier ; - - pos = checkChar('T', signature, pos); - pos = checkIdentifier(signature, pos); - return checkChar(';', signature, pos); - } - - /** - * Checks a type signature. - * - * @param signature - * a string containing the signature that must be checked. - * @param pos - * index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkTypeSignature(final String signature, int pos) { - // TypeSignature: - // Z | C | B | S | I | F | J | D | FieldTypeSignature - - switch (getChar(signature, pos)) { - case 'Z': - case 'C': - case 'B': - case 'S': - case 'I': - case 'F': - case 'J': - case 'D': - return pos + 1; - default: - return checkFieldTypeSignature(signature, pos); - } - } - - /** - * Checks an identifier. - * - * @param signature - * a string containing the signature that must be checked. - * @param pos - * index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkIdentifier(final String signature, int pos) { - if (!Character.isJavaIdentifierStart(getChar(signature, pos))) { - throw new IllegalArgumentException(signature - + ": identifier expected at index " + pos); - } - ++pos; - while (Character.isJavaIdentifierPart(getChar(signature, pos))) { - ++pos; - } - return pos; - } - - /** - * Checks a single character. - * - * @param signature - * a string containing the signature that must be checked. - * @param pos - * index of first character to be checked. - * @return the index of the first character after the checked part. - */ - private static int checkChar(final char c, final String signature, int pos) { - if (getChar(signature, pos) == c) { - return pos + 1; - } - throw new IllegalArgumentException(signature + ": '" + c - + "' expected at index " + pos); - } - - /** - * Returns the signature car at the given index. - * - * @param signature - * a signature. - * @param pos - * an index in signature. - * @return the character at the given index, or 0 if there is no such - * character. - */ - private static char getChar(final String signature, int pos) { - return pos < signature.length() ? signature.charAt(pos) : (char) 0; - } -} diff --git a/src/asm/scala/tools/asm/util/CheckFieldAdapter.java b/src/asm/scala/tools/asm/util/CheckFieldAdapter.java deleted file mode 100644 index e682df47af..0000000000 --- a/src/asm/scala/tools/asm/util/CheckFieldAdapter.java +++ /dev/null @@ -1,122 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.util; - -import scala.tools.asm.AnnotationVisitor; -import scala.tools.asm.Attribute; -import scala.tools.asm.FieldVisitor; -import scala.tools.asm.Opcodes; -import scala.tools.asm.TypePath; -import scala.tools.asm.TypeReference; - -/** - * A {@link FieldVisitor} that checks that its methods are properly used. - */ -public class CheckFieldAdapter extends FieldVisitor { - - private boolean end; - - /** - * Constructs a new {@link CheckFieldAdapter}. Subclasses must not use - * this constructor. Instead, they must use the - * {@link #CheckFieldAdapter(int, FieldVisitor)} version. - * - * @param fv - * the field visitor to which this adapter must delegate calls. - * @throws IllegalStateException - * If a subclass calls this constructor. - */ - public CheckFieldAdapter(final FieldVisitor fv) { - this(Opcodes.ASM5, fv); - if (getClass() != CheckFieldAdapter.class) { - throw new IllegalStateException(); - } - } - - /** - * Constructs a new {@link CheckFieldAdapter}. - * - * @param api - * the ASM API version implemented by this visitor. Must be one - * of {@link Opcodes#ASM4} or {@link Opcodes#ASM5}. - * @param fv - * the field visitor to which this adapter must delegate calls. - */ - protected CheckFieldAdapter(final int api, final FieldVisitor fv) { - super(api, fv); - } - - @Override - public AnnotationVisitor visitAnnotation(final String desc, - final boolean visible) { - checkEnd(); - CheckMethodAdapter.checkDesc(desc, false); - return new CheckAnnotationAdapter(super.visitAnnotation(desc, visible)); - } - - @Override - public AnnotationVisitor visitTypeAnnotation(final int typeRef, - final TypePath typePath, final String desc, final boolean visible) { - checkEnd(); - int sort = typeRef >>> 24; - if (sort != TypeReference.FIELD) { - throw new IllegalArgumentException("Invalid type reference sort 0x" - + Integer.toHexString(sort)); - } - CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath); - CheckMethodAdapter.checkDesc(desc, false); - return new CheckAnnotationAdapter(super.visitTypeAnnotation(typeRef, - typePath, desc, visible)); - } - - @Override - public void visitAttribute(final Attribute attr) { - checkEnd(); - if (attr == null) { - throw new IllegalArgumentException( - "Invalid attribute (must not be null)"); - } - super.visitAttribute(attr); - } - - @Override - public void visitEnd() { - checkEnd(); - end = true; - super.visitEnd(); - } - - private void checkEnd() { - if (end) { - throw new IllegalStateException( - "Cannot call a visit method after visitEnd has been called"); - } - } -} diff --git a/src/asm/scala/tools/asm/util/CheckMethodAdapter.java b/src/asm/scala/tools/asm/util/CheckMethodAdapter.java deleted file mode 100644 index 131dfa5e5b..0000000000 --- a/src/asm/scala/tools/asm/util/CheckMethodAdapter.java +++ /dev/null @@ -1,1542 +0,0 @@ -/*** - * ASM: a very small and fast Java bytecode manipulation framework - * Copyright (c) 2000-2011 INRIA, France Telecom - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ -package scala.tools.asm.util; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import scala.tools.asm.AnnotationVisitor; -import scala.tools.asm.Attribute; -import scala.tools.asm.Handle; -import scala.tools.asm.Label; -import scala.tools.asm.MethodVisitor; -import scala.tools.asm.Opcodes; -import scala.tools.asm.Type; -import scala.tools.asm.TypePath; -import scala.tools.asm.TypeReference; -import scala.tools.asm.tree.MethodNode; -import scala.tools.asm.tree.analysis.Analyzer; -import scala.tools.asm.tree.analysis.BasicValue; -import scala.tools.asm.tree.analysis.BasicVerifier; - -/** - * A {@link MethodVisitor} that checks that its methods are properly used. More - * precisely this method adapter checks each instruction individually, i.e., - * each visit method checks some preconditions based only on its - * arguments - such as the fact that the given opcode is correct for a given - * visit method. This adapter can also perform some basic data flow checks (more - * precisely those that can be performed without the full class hierarchy - see - * {@link scala.tools.asm.tree.analysis.BasicVerifier}). For instance in a - * method whose signature is void m (), the invalid instruction - * IRETURN, or the invalid sequence IADD L2I will be detected if the data flow - * checks are enabled. These checks are enabled by using the - * {@link #CheckMethodAdapter(int,String,String,MethodVisitor,Map)} constructor. - * They are not performed if any other constructor is used. - * - * @author Eric Bruneton - */ -public class CheckMethodAdapter extends MethodVisitor { - - /** - * The class version number. - */ - public int version; - - /** - * The access flags of the method. - */ - private int access; - - /** - * true if the visitCode method has been called. - */ - private boolean startCode; - - /** - * true if the visitMaxs method has been called. - */ - private boolean endCode; - - /** - * true if the visitEnd method has been called. - */ - private boolean endMethod; - - /** - * Number of visited instructions. - */ - private int insnCount; - - /** - * The already visited labels. This map associate Integer values to pseudo - * code offsets. - */ - private final Map labels; - - /** - * The labels used in this method. Every used label must be visited with - * visitLabel before the end of the method (i.e. should be in #labels). - */ - private Set