将动态参数传递给在编译时处理的注释

时间:2016-08-31 08:06:48

标签: java annotations annotation-processing

考虑这个例子,我正在寻找这种问题的一般解决方案。

我正在开发一个为类创建接口的注释处理器,基本上复制了所有公共方法。可以使用String参数配置接口的名称(和包)。但由于注释为@Inherited,因此应该能够定义将子类名称映射到其接口名称的InterfaceNamingStrategy

我尝试在this answer之后使用动态注释参数。

/**
 * Generates an interface that contains all public member mehtods of the annotated class.
 * This can only be used on top-level classes.
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
@Inherited
@Documented
public @interface GenerateInterface {

    /**
     * Name of the generated interface. If this is not specified, the {@link #namingStrategy()}
     * is used to retrieve the interface name.
     * If the name is not fully qualified, the interface will have the same package
     * as the annotated class.
     */
    String value() default "";

    /**
     * An implementation of {@link InterfaceNamingStrategy} that returns the interface name
     * for a given annotated class. It must be accessible and contain a public no-arg constructor.
     */
    Class<? extends InterfaceNamingStrategy> namingStrategy() default InterfaceNamingStrategy.PrefixI.class;

}

/**
 * Naming strategy to be used with {@link GenerateInterface}.
 */
public interface InterfaceNamingStrategy {

    /**
     * @param impl TypeElement representing the annotated class
     * @return the name of the generated interface. See {@link GenerateInterface#value()}.
     */
    String getInterfaceName(TypeElement impl);

    /**
     * Will create the interface {@code Foo} for the annotated class {@code FooImpl}
     */
    public static class ExceptLastFourChars implements InterfaceNamingStrategy {
        @Override
        public String getInterfaceName(TypeElement impl) {
            return impl.getSimpleName().toString().substring(0, impl.getSimpleName().length()-4);
        }
    }

    /**
     * Will create the interface {@code IFoo} for the annotated class {@code Foo}
     */
    public static class PrefixI implements InterfaceNamingStrategy {
        @Override
        public String getInterfaceName(TypeElement impl) {
            return "I" + impl.getSimpleName();
        }
    }
}

但是,这在编译时处理注释时不起作用,因为您无法实例化InterfaceNamingStrategy中所述function isString(value: any): value is string { return typeof value === 'string' || value instanceof String; } function foo(param: string | Foo) { if (isString(param)) { // param is string } else { // param is Foo } } 的实现。

有没有办法将动态参数传递给在编译时处理的注释?

我目前的解决方案是使用String参数和this question。但我更喜欢使用实际经过类型检查的Java代码的解决方案。

0 个答案:

没有答案