Как я могу использовать аннотацию Java в Scala? - PullRequest
1 голос
/ 07 апреля 2020

У меня есть пользовательская аннотация Java, которая генерирует файл при компиляции тестовых источников. Но когда я импортирую эту аннотацию в класс Scala и использую ее так же, как в Java, Scala не обрабатывает ее.

Java Аннотация

@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Trace {
    public String key() default "";
    public byte step() default 0;
    public String url() default "";
}

@SupportedAnnotationTypes("com.custom.annotations.Trace")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
@AutoService(Processor.class)
public class TraceProcessor extends AbstractProcessor {

    public static final String DEFAULT_FILE_PATH = "target/";
    public static final String DEFAULT_FILE_NAME = "trazability.txt";

    private Messager messager;

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        Set<? extends Element> annotatedElements = getTraceAnnotatedElements(roundEnv);
        if(annotatedElements.size() == 0) {
            return true; // If there is not annotation, fast exist.
        }

        System.out.println("Processing @Trace annotations...");
        try {
            generateTraceFile(annotatedElements);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return true;
    }

    @Override
    public void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);

        // get messager for printing errors
        messager = processingEnvironment.getMessager();
    }

    private Set<? extends Element> getTraceAnnotatedElements(RoundEnvironment roundEnv) {
        return roundEnv.getElementsAnnotatedWith(Trace.class);
    }

    private void generateTraceFile(Set<? extends Element> annotatedElements) throws FileNotFoundException {
        PrintWriter out = new PrintWriter(DEFAULT_FILE_PATH + DEFAULT_FILE_NAME);

        System.out.println("Annotated elements with @Trace: " + annotatedElements.size());
        for (Element element : annotatedElements) {
            if (element.getKind() == ElementKind.CLASS || element.getKind() == ElementKind.METHOD) {
                String key = element.getAnnotation(Trace.class).key();
                int step = element.getAnnotation(Trace.class).step();

                if(element.getKind() == ElementKind.METHOD) {
                    String className = ((TypeElement) element.getEnclosingElement()).getQualifiedName().toString();
                    String methodName = element.getSimpleName().toString();
                    System.out.println("Add " + element.getKind().name() + " with key: " + key + " step: " + step + " class: " + className + " method: " + methodName);
                    out.print(key + ";" + step + ";" + className + "." + methodName);
                } else {
                    String packageName = ((Symbol) element).getQualifiedName().toString();
                    String className = packageName + "." + element.getSimpleName().toString();
                    System.out.println("Add " + element.getKind().name() + " with key: " + key + " step: " + step + " class: " + className);
                    out.print(key + ";" + step + ";" +  className);
                }
                out.println();
            }
        }
        out.println();
        out.close();
        System.out.println("File trazability generated into target folder");
    }

    private void printError(Element element, String message) {
        messager.printMessage(Diagnostic.Kind.ERROR, message, element);
    }

}

Scala

import com.custom.annotations.Trace

@Trace(key = "ECI-12")
class Simulation1 extends Simulation {}

Когда я использую аннотацию java в источнике Java, аннотация Trace обрабатывается TraceProcessor и файл создан. Но когда я делаю то же самое с Scala, это не работает.

Ответы [ 2 ]

0 голосов
/ 07 апреля 2020

Использование java аннотаций в коде scala может привести к непредсказуемым результатам, большинство из них просто не будут работать. Пожалуйста, не используйте их в своем коде Scala, потому что этим вы получаете ненависть как к парням Java, так и Scala. Слияние ваших любимых библиотек из мира java с scala не дает вам лучшего, что вы можете получить из scala, но поднимает кучу проблем, которые редко рассматриваются на разных ресурсах. У Scala есть своя собственная экосистема, и лучше избегать использования библиотек java, пока вы можете решить проблему с библиотекой scala, даже если вы обладаете сверхспособностями с java.

Java аннотации, обычно используемые для сброса шаблонов, которые обеспечиваются подробным синтаксисом java и системой плохого типа. Scala имеет собственную структуру метапрограммирования (макрос черного ящика, макрос белого ящика, аннотации макросов и неявный макрос) и многие другие абстракции, такие как система мощных типов с HKT и всемогущий механизм неявного поиска. Таким образом, вам определенно не нужны макроаннотации для большинства случаев.

Более того, для вашей проблемы может существовать решение scala. Кто-то может найти его для вас, если вы решите описать проблему, а не использовать стену кода.

0 голосов
/ 07 апреля 2020

Аннотация Java будет работать только с компиляторами Java, поскольку процессор должен работать с Java AST. Вы должны написать собственную макроаннотацию для Scala, в которой используется компилятор, несовместимый с процессорами аннотаций Java. Смотрите здесь: https://docs.scala-lang.org/overviews/macros/annotations.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...