Skip to content

Commit

Permalink
Add FMLModType and bundle annotations and runtime together
Browse files Browse the repository at this point in the history
  • Loading branch information
lukebemish committed Nov 19, 2023
1 parent 59a9ecb commit 10fbd9a
Show file tree
Hide file tree
Showing 22 changed files with 37 additions and 79 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ jobs:
uses: mikepenz/[email protected]
with:
gradle-build-module: |-
:opensesame-annotations
:opensesame-runtime
:opensesame-core
:opensesame-compile
:opensesame-groovy
:opensesame-javac
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/snapshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ jobs:
uses: mikepenz/[email protected]
with:
gradle-build-module: |-
:opensesame-annotations
:opensesame-runtime
:opensesame-core
:opensesame-compile
:opensesame-groovy
:opensesame-javac
Expand Down
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# OpenSesame

[![javadoc](https://img.shields.io/maven-central/v/dev.lukebemish.opensesame/opensesame-annotations?style=for-the-badge&label=javadoc%20(annotations)&color=green)](https://javadoc.io/doc/dev.lukebemish.opensesame/opensesame-annotations)
[![javadoc](https://img.shields.io/maven-central/v/dev.lukebemish.opensesame/opensesame-core?style=for-the-badge&label=javadoc&color=green)](https://javadoc.io/doc/dev.lukebemish.opensesame/opensesame-core)

OpenSesame provides a tool to break through basically any form of encapsulation in the JVM, in a way that allows you to work with simple accessor method in your code, instead of worrying about `MethodHandle`s or reflection. These accessors are turned
into `INVOKEDYNAMIC` instructions at compile time which call a lightweight runtime component; the use of `INVOKEDYNAMIC` allows the runtime dependency to be extremely lightweight, and for the JVM to inline calls to members you are accessing when the
call site is first evaluated, assuring that your code runs as fast as code accessing your target without breaking encapsulation. Normally, OpenSesame simply breaks though access control, but it can be told to break through module boundaries as well.
OpenSesame requires Java 17 or higher.

## Setup

Expand All @@ -26,12 +27,12 @@ dependencies {
}
```

If you do not need the ASTT present at runtime, you may split the dependency and at runtime depend only on `opensesame-runtime`:
If you do not need the ASTT present at runtime, you may split the dependency and at runtime depend only on `opensesame-core`:

```gradle
dependencies {
compileOnly 'dev.lukebemish.opensesame:opensesame-groovy:<version>'
runtimeOnly 'dev.lukebemish.opensesame:opensesame-runtime:<version>'
runtimeOnly 'dev.lukebemish.opensesame:opensesame-core:<version>'
}
```

Expand All @@ -43,7 +44,7 @@ plugin present at runtime, you will likely want to split it into its runtime and
```gradle
dependencies {
compileOnly 'dev.lukebemish.opensesame:opensesame-javac:<version>'
runtimeOnly 'dev.lukebemish.opensesame:opensesame-runtime:<version>'
runtimeOnly 'dev.lukebemish.opensesame:opensesame-core:<version>'
}
tasks.named('compileJava', JavaCompile).configure {
Expand Down Expand Up @@ -87,7 +88,7 @@ can use `@Coerce` annotation to specify the real type of an argument or return t

If you are using Groovy, OpenSesame has several useful additional features. The first is `@OpenClass`, which gets rid of the need for accessor methods when accessing public classes:

```java
```groovy
class Target {
private static void someMethod() {
...
Expand Down
44 changes: 0 additions & 44 deletions annotations/build.gradle

This file was deleted.

3 changes: 2 additions & 1 deletion buildSrc/src/main/groovy/opensesame.conventions.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ jar {
'Specification-Version' : rootProject.version,
'Implementation-Commit-Time': managedVersioning.timestamp.get(),
'Implementation-Commit': managedVersioning.hash.get(),
'Automatic-Module-Name' : "dev.lukebemish.opensesame.${project.name.replace("opensesame-", "")}".toString()
'Automatic-Module-Name' : "dev.lukebemish.opensesame.${project.name.replace("opensesame-", "")}".toString(),
'FMLModType': 'LIBRARY'
])
}
}
Expand Down
4 changes: 2 additions & 2 deletions compile/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ java.withSourcesJar()
java.withJavadocJar()

dependencies {
implementation project(':opensesame-annotations')
implementation project(':opensesame-core')
}

tasks.named('compileJava', JavaCompile).configure {
Expand All @@ -19,7 +19,7 @@ publishing {
pom {
name = "OpenSesame - Compile"
packaging = 'jar'
description = 'Compile-time abstractions for OpenSesame, a tool for typesafe access normally inacessible members'
description = 'Compile-time abstractions for OpenSesame, a tool for typesafe access to normally inacessible members'
url = 'https://github.com/lukebemish/OpenSesame'
inceptionYear = '2023'

Expand Down
4 changes: 2 additions & 2 deletions runtime/build.gradle → core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ publishing {
publications {
mavenJava(MavenPublication) {
pom {
name = "OpenSesame - Runtime"
name = "OpenSesame - Core"
packaging = 'jar'
description = 'Runtime metafactory used for OpenSesame, a tool for typesafe access normally inacessible members'
description = 'Core annotations and runtime metafactory used for OpenSesame, a tool for typesafe access to normally inacessible members'
url = 'https://github.com/lukebemish/OpenSesame'
inceptionYear = '2023'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@
@Target({ElementType.METHOD, ElementType.PARAMETER})
public @interface Coerce {
/**
* @return the internal name or descriptor of the target class, or the name ot be passed to {@link #targetProvider()}
* {@return the internal name or descriptor of the target class, or the name ot be passed to {@link #targetProvider()}}
*/
String targetName() default "";

/**
* @return the target class
* {@return the target class}
*/
Class<?> targetClass() default Void.class;
Class<?> targetClass() default void.class;

/**
* @return a class implementing {@link dev.lukebemish.opensesame.runtime.ClassProvider} with a no-arg constructor
* {@return a class implementing {@link dev.lukebemish.opensesame.runtime.ClassProvider} with a no-arg constructor
* that returns the target class. This function will be passed {@link #targetName()} if it is specified, or
* null otherwise. On groovy, may be a closure
* null otherwise. On groovy, may be a closure}
*/
Class<?> targetProvider() default ErrorProvider.class;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,34 @@
@Target(ElementType.METHOD)
public @interface Open {
/**
* @return the name of the target method, constructor, or field operation
* {@return the name of the target method, constructor, or field operation}
*/
String name() default "";

/**
* @return the internal name or descriptor of the target class, or the name ot be passed to {@link #targetProvider()}
* {@return the internal name or descriptor of the target class, or the name ot be passed to {@link #targetProvider()}}
*/
String targetName() default "";

/**
* @return the target class
* {@return the target class}
*/
Class<?> targetClass() default Void.class;
Class<?> targetClass() default void.class;

/**
* @return a class implementing {@link dev.lukebemish.opensesame.runtime.ClassProvider} with a no-arg constructor
* {@return a class implementing {@link dev.lukebemish.opensesame.runtime.ClassProvider} with a no-arg constructor
* that returns the target class. This function will be passed {@link #targetName()} if it is specified, or
* null otherwise. On groovy, may be a closure
* null otherwise. On groovy, may be a closure}
*/
Class<?> targetProvider() default ErrorProvider.class;

/**
* @return the type of member o the target class to invoke
* {@return the type of member o the target class to invoke}
*/
Type type();

/**
* @return whether this invocation should be done unsafely, breaking module boundaries
* {@return whether this invocation should be done unsafely, breaking module boundaries}
*/
boolean unsafe() default false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,11 @@ private MethodHandles.Lookup getImplLookup() throws Exception {
var implLookupField = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
Method staticFieldBase = unsafe.getDeclaredMethod("staticFieldBase", Field.class);
Method staticFieldOffset = unsafe.getDeclaredMethod("staticFieldOffset", Field.class);
Object base = staticFieldBase.invoke(theUnsafe, implLookupField);
long offset = (long) staticFieldOffset.invoke(theUnsafe, implLookupField);
Method getObject = unsafe.getDeclaredMethod("getObject", Object.class, long.class);
return (MethodHandles.Lookup)
getObject.invoke(theUnsafe, staticFieldBase.invoke(theUnsafe, implLookupField), staticFieldOffset.invoke(theUnsafe, implLookupField));
getObject.invoke(theUnsafe, base, offset);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
requires static org.jetbrains.annotations;

exports dev.lukebemish.opensesame.runtime;
exports dev.lukebemish.opensesame.annotations;

uses dev.lukebemish.opensesame.runtime.RuntimeRemapper;
}
4 changes: 2 additions & 2 deletions groovy/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ tasks.register('groovydocJar', Jar) {
dependencies {
implementation libs.groovy.core
implementation project(':opensesame-compile')
api project(':opensesame-annotations')
api project(':opensesame-core')
}

tasks.named('compileGroovy', GroovyCompile).configure {
Expand Down Expand Up @@ -89,7 +89,7 @@ publishing {
pom {
name = "OpenSesame - Groovy Transform"
packaging = 'jar'
description = 'Compile-time groovy ASTT used for OpenSesame, a tool for typesafe access normally inacessible members'
description = 'Compile-time groovy ASTT used for OpenSesame, a tool for typesafe access to normally inacessible members'
url = 'https://github.com/lukebemish/OpenSesame'
inceptionYear = '2023'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
})
public @interface OpenClass {
/**
* The classes to open.
* {@return The classes to open.}
*/
Class<?>[] value();
}
4 changes: 2 additions & 2 deletions javac/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ java.withJavadocJar()

dependencies {
implementation project(':opensesame-compile')
api project(':opensesame-annotations')
api project(':opensesame-core')
implementation libs.asm
}

Expand Down Expand Up @@ -81,7 +81,7 @@ publishing {
pom {
name = "OpenSesame - Javac Compiler Plugin"
packaging = 'jar'
description = 'javac compiler plugin for OpenSesame, a tool for typesafe access normally inacessible members'
description = 'javac compiler plugin for OpenSesame, a tool for typesafe access to normally inacessible members'
url = 'https://github.com/lukebemish/OpenSesame'
inceptionYear = '2023'

Expand Down
3 changes: 1 addition & 2 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ gradleEnterprise {
rootProject.name = 'opensesame'

def subprojects = [
'annotations',
'runtime',
'core',
'compile',
'groovy',
'javac'
Expand Down

0 comments on commit 10fbd9a

Please sign in to comment.