diff --git a/build.gradle b/build.gradle index eda1dfcc12..ed35d5be2f 100644 --- a/build.gradle +++ b/build.gradle @@ -39,7 +39,7 @@ subprojects { ext.quasarJar = "${rootProject.projectDir}/quasar-core/build/libs/quasar-core-${version}${ext.java8 ? "-jdk8" : ""}.jar" // project(':quasar-core').jar.archivePath ext.asmVer = '5.0.4' - ext.kotlinVer = '0.13.1513' + ext.kotlinVer = '0.13.1514' if (!project.hasProperty("sonatypeUsername") || !project.hasProperty("sonatypePassword")) { println "sonatype username or password not set" diff --git a/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/CheckInstrumentationVisitor.java b/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/CheckInstrumentationVisitor.java index 1bd0248826..48cd33d27c 100644 --- a/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/CheckInstrumentationVisitor.java +++ b/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/CheckInstrumentationVisitor.java @@ -44,6 +44,7 @@ import co.paralleluniverse.fibers.SuspendExecution; import static co.paralleluniverse.fibers.instrument.Classes.ALREADY_INSTRUMENTED_DESC; import static co.paralleluniverse.fibers.instrument.Classes.ANNOTATION_DESC; +import static co.paralleluniverse.fibers.instrument.Classes.KOTLIN_ANNOTATION_DESC; import static co.paralleluniverse.fibers.instrument.QuasarInstrumentor.ASMAPI; import co.paralleluniverse.fibers.instrument.MethodDatabase.ClassEntry; import co.paralleluniverse.fibers.instrument.MethodDatabase.SuspendableType; @@ -114,7 +115,7 @@ public void visitSource(String source, String debug) { public AnnotationVisitor visitAnnotation(String desc, boolean visible) { if (desc.equals(ALREADY_INSTRUMENTED_DESC)) this.alreadyInstrumented = true; - else if (isInterface && desc.equals(ANNOTATION_DESC)) + else if (isInterface && (desc.equals(ANNOTATION_DESC) || desc.equals(KOTLIN_ANNOTATION_DESC))) this.suspendableInterface = true; return null; } @@ -145,7 +146,7 @@ public MethodVisitor visitMethod(final int access, final String name, final Stri @Override public AnnotationVisitor visitAnnotation(String adesc, boolean visible) { - if (adesc.equals(ANNOTATION_DESC)) + if (adesc.equals(ANNOTATION_DESC) || adesc.equals(KOTLIN_ANNOTATION_DESC)) susp = true; return null; } diff --git a/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/Classes.java b/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/Classes.java index 756456fc04..d44cf1daf9 100644 --- a/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/Classes.java +++ b/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/Classes.java @@ -24,6 +24,7 @@ final class Classes { static final String RUNTIME_SUSPEND_EXECUTION_NAME = "co/paralleluniverse/fibers/RuntimeSuspendExecution"; static final String UNDECLARED_THROWABLE_NAME = "java/lang/reflect/UndeclaredThrowableException"; static final String ANNOTATION_NAME = "co/paralleluniverse/fibers/Suspendable"; + static final String KOTLIN_ANNOTATION_NAME = "co/paralleluniverse/kotlin/fibers/Suspendable"; static final String DONT_INSTRUMENT_ANNOTATION_NAME = "co/paralleluniverse/fibers/instrument/DontInstrument"; static final String FIBER_CLASS_NAME = "co/paralleluniverse/fibers/Fiber"; //Type.getInternalName(COROUTINE_CLASS); private static final String STRAND_NAME = "co/paralleluniverse/strands/Strand"; //Type.getInternalName(COROUTINE_CLASS); @@ -37,6 +38,7 @@ final class Classes { // computed // static final String EXCEPTION_DESC = "L" + SUSPEND_EXECUTION_NAME + ";"; static final String ANNOTATION_DESC = "L" + ANNOTATION_NAME + ";"; + static final String KOTLIN_ANNOTATION_DESC = "L" + KOTLIN_ANNOTATION_NAME + ";"; static final String DONT_INSTRUMENT_ANNOTATION_DESC = "L" + DONT_INSTRUMENT_ANNOTATION_NAME + ";"; static final String ALREADY_INSTRUMENTED_DESC = Type.getDescriptor(Instrumented.class); diff --git a/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/InstrumentClass.java b/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/InstrumentClass.java index a2c875df4d..6bb3bd00a0 100644 --- a/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/InstrumentClass.java +++ b/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/InstrumentClass.java @@ -41,10 +41,7 @@ */ package co.paralleluniverse.fibers.instrument; -import static co.paralleluniverse.fibers.instrument.Classes.ALREADY_INSTRUMENTED_DESC; -import static co.paralleluniverse.fibers.instrument.Classes.ANNOTATION_DESC; -import static co.paralleluniverse.fibers.instrument.Classes.DONT_INSTRUMENT_ANNOTATION_DESC; -import static co.paralleluniverse.fibers.instrument.Classes.isYieldMethod; +import static co.paralleluniverse.fibers.instrument.Classes.*; import static co.paralleluniverse.fibers.instrument.QuasarInstrumentor.ASMAPI; import co.paralleluniverse.fibers.instrument.MethodDatabase.ClassEntry; import co.paralleluniverse.fibers.instrument.MethodDatabase.SuspendableType; @@ -135,7 +132,7 @@ public boolean hasSuspendableMethods() { public AnnotationVisitor visitAnnotation(String desc, boolean visible) { if (desc.equals(ALREADY_INSTRUMENTED_DESC)) this.alreadyInstrumented = true; - else if (isInterface && desc.equals(ANNOTATION_DESC)) + else if (isInterface && (desc.equals(ANNOTATION_DESC) || desc.equals(KOTLIN_ANNOTATION_DESC))) this.suspendableInterface = true; return super.visitAnnotation(desc, visible); @@ -167,7 +164,7 @@ public MethodVisitor visitMethod(final int access, final String name, final Stri @Override public AnnotationVisitor visitAnnotation(String adesc, boolean visible) { // look for @Suspendable or @DontInstrument annotation - if (adesc.equals(ANNOTATION_DESC)) + if (adesc.equals(ANNOTATION_DESC) || adesc.equals(KOTLIN_ANNOTATION_DESC)) susp = SuspendableType.SUSPENDABLE; else if (adesc.equals(DONT_INSTRUMENT_ANNOTATION_DESC)) susp = SuspendableType.NON_SUSPENDABLE; @@ -296,7 +293,7 @@ private boolean hasAnnotation(MethodNode mn) { if (ans == null) return false; for (AnnotationNode an : ans) { - if (an.desc.equals(ANNOTATION_DESC)) + if (an.desc.equals(ANNOTATION_DESC) || an.desc.equals(KOTLIN_ANNOTATION_DESC)) return true; } return false; diff --git a/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/SuspendablesScanner.java b/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/SuspendablesScanner.java index 1ccf7e38db..0e7a429df4 100644 --- a/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/SuspendablesScanner.java +++ b/quasar-core/src/main/java/co/paralleluniverse/fibers/instrument/SuspendablesScanner.java @@ -16,9 +16,8 @@ import co.paralleluniverse.common.reflection.ClassLoaderUtil; import static co.paralleluniverse.common.reflection.ClassLoaderUtil.isClassFile; import static co.paralleluniverse.common.reflection.ClassLoaderUtil.classToResource; -import static co.paralleluniverse.fibers.instrument.Classes.ANNOTATION_DESC; -import static co.paralleluniverse.fibers.instrument.Classes.DONT_INSTRUMENT_ANNOTATION_DESC; -import static co.paralleluniverse.fibers.instrument.Classes.SUSPEND_EXECUTION_NAME; +import static co.paralleluniverse.fibers.instrument.Classes.*; + import co.paralleluniverse.fibers.instrument.MethodDatabase.SuspendableType; import com.google.common.base.Function; import java.io.File; @@ -320,7 +319,7 @@ public void visit(int version, int access, String name, String signature, String @Override public AnnotationVisitor visitAnnotation(String adesc, boolean visible) { final AnnotationVisitor av = super.visitAnnotation(adesc, visible); - if (adesc.equals(ANNOTATION_DESC)) + if (adesc.equals(ANNOTATION_DESC) || adesc.equals(KOTLIN_ANNOTATION_DESC)) suspendableClass = true; return av; } @@ -350,6 +349,7 @@ public AnnotationVisitor visitAnnotation(String adesc, boolean visible) { switch (adesc) { case ANNOTATION_DESC: + case KOTLIN_ANNOTATION_DESC: susp = noImpl ? SuspendableType.SUSPENDABLE_SUPER : SuspendableType.SUSPENDABLE; break; case DONT_INSTRUMENT_ANNOTATION_DESC: diff --git a/quasar-kotlin/src/main/kotlin/co/paralleluniverse/kotlin/fibers/Suspendable.kt b/quasar-kotlin/src/main/kotlin/co/paralleluniverse/kotlin/fibers/Suspendable.kt new file mode 100644 index 0000000000..2a3136a87c --- /dev/null +++ b/quasar-kotlin/src/main/kotlin/co/paralleluniverse/kotlin/fibers/Suspendable.kt @@ -0,0 +1,11 @@ +package co.paralleluniverse.kotlin.fibers + +import kotlin.annotation.Retention +import kotlin.annotation.Target + +@Retention // Defaults to RUNTIME +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, + AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.CLASS, + AnnotationTarget.FILE, AnnotationTarget.EXPRESSION) + +annotation public class Suspendable \ No newline at end of file diff --git a/quasar-kotlin/src/test/kotlin/co/paralleluniverse/kotlin/fibers/lang/FunTest.kt b/quasar-kotlin/src/test/kotlin/co/paralleluniverse/kotlin/fibers/lang/FunTest.kt index 261ddcd122..942949d72f 100644 --- a/quasar-kotlin/src/test/kotlin/co/paralleluniverse/kotlin/fibers/lang/FunTest.kt +++ b/quasar-kotlin/src/test/kotlin/co/paralleluniverse/kotlin/fibers/lang/FunTest.kt @@ -14,8 +14,9 @@ package co.paralleluniverse.kotlin.fibers.lang import co.paralleluniverse.fibers.Fiber -import co.paralleluniverse.fibers.Suspendable import co.paralleluniverse.fibers.FiberForkJoinScheduler +import co.paralleluniverse.fibers.Suspendable +import co.paralleluniverse.kotlin.fibers import org.junit.Assert.assertTrue import co.paralleluniverse.strands.SuspendableCallable import org.junit.Test @@ -54,6 +55,21 @@ fun seq(f: () -> Unit, g: () -> Unit): () -> Unit { public class FunTest { val scheduler = FiberForkJoinScheduler("test", 4, null, false) + @Test fun testKotlinAnnotation() { + assertTrue(Fiber(scheduler, object : SuspendableCallable { + @Suspendable override fun run(): Boolean { + @fibers.Suspendable { + println("quick pre-sleep") + Fiber.sleep(10) + println("quick after-sleep") + Fiber.sleep(10) + println("quick after-sleep") + }() + return true + } + }).start().get()) + } + @Test fun testSimpleFun() { assertTrue(Fiber(scheduler, object : SuspendableCallable { @Suspendable override fun run(): Boolean {