Skip to content

refactor(annotations)!: improve annotation-based plugin generation #337

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -434,3 +434,7 @@ ij_markdown_min_lines_around_header = 1
ij_markdown_min_lines_between_paragraphs = 1
ij_markdown_wrap_text_if_long = true
ij_markdown_wrap_text_inside_blockquotes = true

[*.java.vm]
indent_size = 4
tab_width = 4
12 changes: 10 additions & 2 deletions annotations/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,19 @@ plugins {

dependencies {
implementation(projects.chameleonApi)
implementation(libs.javapoet)

// Escape Velocity (class templating)
implementation(libs.escapeVelocity)

// GSON and YAML (resource generation)
implementation(libs.gson)
implementation(libs.yaml) {
exclude(group = "joda-time", module = "joda-time")
exclude(group = "junit", module = "joda-time")
exclude(group = "org.apache", module = "velocity")
}
implementation(libs.gson)

// Auto service
compileOnly(libs.autoService.annotations)
annotationProcessor(libs.autoService.processor)
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,42 +25,47 @@

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.jetbrains.annotations.NotNull;

/**
* Platform Dependency.
* Plugin Dependency.
*
* @see Plugin
*/
@Retention(RetentionPolicy.SOURCE)
@Target({})
public @interface Dependency {

/**
* The ID or name of the dependency.
* Returns the name or ID of this dependency.
*
* @return the dependency's ID or name.
* @return dependency name or ID.
*/
@NotNull String name();

/**
* The version, or a maven range, that represents the versions of this dependency.
* This is required for Sponge support.
* Returns the version, or a maven version range, that represents the compatible versions of
* this dependency.
* <p><strong>This is required for Sponge support.</strong></p>
*
* @return the required version of this dependency.
*/
@NotNull String version() default "";

/**
* Whether this dependency is not required to load the dependant.
* By default, this is {@code false}, meaning the dependency is required.
* Returns whether this dependency is optional for loading the dependant plugin.
* <p>Defaults to {@code false}, meaning the dependency is not required.</p>
*
* @return {@code true} if the dependency is not required for the dependant to load.
* @return {@code true} if the dependency is not required when loading the dependant plugin.
*/
boolean soft() default false;
boolean optional() default false;

/**
* The platforms this dependency is loaded on.
* Returns the platforms this dependency applies to.
* <p>Defaults to all platforms.</p>
*
* @return the platforms this dependency should be loaded on.
* @return dependency platforms.
*/
@NotNull String[] platforms() default {};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,67 +38,77 @@
public @interface Plugin {

/**
* The plugin's unique identifier.
* Returns the unique identifier of this plugin.
*
* @return the plugin's ID.
* @return plugin ID.
*/
@NotNull String id();

/**
* The plugin's human-readable name.
* Returns the human-readable display name of this plugin.
*
* @return the plugin's name, or an empty string.
* @return plugin name.
*/
@NotNull String name() default "";

/**
* The plugin's version.
* Returns the version of this plugin.
*
* @return the plugin's version.
* @return plugin version.
*/
@NotNull String version();

/**
* The plugin's description, generally a short explanation of what the plugin is used for.
* Returns the license this plugin is distributed under.
* <p>This is currently only used for Sponge support.</p>
*
* @return the plugin's description, or an empty string.
* @return plugin license.
*/
@NotNull String license() default "";

/**
* Returns a short description of this plugin.
*
* @return plugin description.
*/
@NotNull String description() default "";

/**
* The plugin's website or download URL.
* Returns the website or download URL of this plugin.
*
* @return the plugin's url, or an empty string.
* @return plugin URL.
*/
@NotNull String url() default "";

/**
* The plugin's author(s).
* Returns the authors of this plugin.
*
* @return the plugin's authors.
* @return plugin authors.
*/
@NotNull String[] authors() default {};

/**
* The plugin's dependencies.
* Returns the dependencies of this plugin.
*
* @return the plugin's dependencies.
* @return plugin dependencies.
*/
@NotNull Dependency[] dependencies() default {};

/**
* The platforms this plugin can run on.
* <p>This is used by Chameleon Annotations to determine what generators should be run.</p>
* <p>Defaults to all platforms.</p>
* Returns the platforms this plugin can run on.
*
* <p>This is used internally to decide which platform plugin generators to run.</p>
*
* @return the platforms this plugin can run on.
*/
@NotNull String[] platforms() default {};

/**
* Returns the plugin bootstrap to use when bootstrapping Chameleon.
* <p><strong>If this is not provided, the annotated class must have a public constructor with a
* single Chameleon parameter.</strong></p>
*
* <p>The provided bootstrap must have a public constructor with no parameters.</p>
* <p><strong>If this is not provided, the annotated class must have a public constructor with
* a single Chameleon parameter.</strong></p>
*
* @return plugin bootstrap class.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* This file is a part of the Chameleon Framework, licensed under the MIT License.
*
* Copyright (c) 2021-2023 The Chameleon Framework Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package dev.hypera.chameleon.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.jetbrains.annotations.NotNull;

/**
* Platform plugin generator options.
*
* @see dev.hypera.chameleon.annotations.generator.platform.PlatformPluginGenerator
*/
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface PluginGeneratorOptions {

/**
* Returns the generated platform class name format.
* <p>Defaults to {@code {name}{platform}}, e.g. {@code ChameleonExampleBukkit}.</p>
*
* <p>The following placeholders will be replaced in this string:</p>
* <ul>
* <li>{@code {name}} - Name of the ChameleonPlugin class, e.g. {@code ChameleonExample}.</li>
* <li>{@code {platform}} - Platform identifier, e.g. {@code Bukkit}, {@code Velocity}.</li>
* </ul>
*
* @return generated platform class name.
*/
@NotNull String generatedClassName() default "{name}{platform}";

/**
* Returns the package generated platform classes should be placed in.
* <p>Defaults to {@code {package}.platform.{platform}}, e.g.
* {@code com.example.platform.bukkit}</p>
*
* <p>The following placeholders will be replaced in this string:</p>
* <ul>
* <li>{@code {package}} - Name of the package the ChameleonPlugin is in.</li>
* <li>{@code {platform}} - Platform identifier, e.g. {@code bukkit}, {@code velocity}.</li>
* </ul>
*
* @return platform package name.
*/
@NotNull String generatedPackageName() default "{package}.platform.{platform}";

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,50 +24,56 @@
package dev.hypera.chameleon.annotations.exception;

import dev.hypera.chameleon.exception.ChameleonRuntimeException;
import org.jetbrains.annotations.ApiStatus.Internal;

/**
* Chameleon extension exception.
*/
public class ChameleonAnnotationException extends ChameleonRuntimeException {
public final class ChameleonAnnotationException extends ChameleonRuntimeException {

private static final long serialVersionUID = 3638644893311787308L;

/**
* {@link ChameleonAnnotationException} constructor.
* Chameleon annotation exception constructor.
*/
@Internal
public ChameleonAnnotationException() {
super();
}

/**
* {@link ChameleonAnnotationException} constructor.
* Chameleon annotation exception constructor.
*
* @param message Exception message.
*/
@Internal
public ChameleonAnnotationException(String message) {
super(message);
}

/**
* {@link ChameleonAnnotationException} constructor.
* Chameleon annotation exception constructor.
*
* @param message Exception message.
* @param cause Exception cause.
*/
@Internal
public ChameleonAnnotationException(String message, Throwable cause) {
super(message, cause);
}

/**
* {@link ChameleonAnnotationException} constructor.
* Chameleon annotation exception constructor.
*
* @param cause Exception cause.
*/
@Internal
public ChameleonAnnotationException(Throwable cause) {
super(cause);
}

protected ChameleonAnnotationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
@Internal
ChameleonAnnotationException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,27 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package dev.hypera.chameleon.annotations.utils;
package dev.hypera.chameleon.annotations.generator;

import java.util.HashMap;
import org.jetbrains.annotations.NotNull;

/**
* Map builder utility.
*
* @param <K> Key type.
* @param <V> Value type.
* Represents a generated class.
*/
public final class MapBuilder<K, V> extends HashMap<K, V> {

private static final long serialVersionUID = 5845273231221036448L;
public interface GeneratedClass {

/**
* Add object to Map.
* Returns the fully-qualified class name.
*
* @param k Key.
* @param v Value.
* @return fully-qualified class name.
*/
@NotNull String fqcn();

/**
* Returns the content of the class.
*
* @return {@code this}.
* @return class content.
*/
public @NotNull MapBuilder<K, V> add(@NotNull K k, @NotNull V v) {
put(k, v);
return this;
}
@NotNull String content();

}
Loading