code manipulation : annotation processor #1

This commit is contained in:
haerong22
2021-02-22 15:45:37 +09:00
parent 9df40d2578
commit 2f6598a763
7 changed files with 171 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>annotation-processor</artifactId>
<version>1.0-SNAPSHOT</version>
<name>annotation-processor</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>magic-annotation</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,8 @@
package org.example;
public class App {
public static void main( String[] args ) {
// Moja moja = new MojaFactory();
// System.out.println(moja.pullOut());
}
}

View File

@@ -0,0 +1,7 @@
package org.example;
@Magic
public interface Moja {
String pullOut();
}

View File

@@ -0,0 +1,20 @@
package org.example;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
/**
* Unit test for simple App.
*/
public class AppTest
{
/**
* Rigorous Test :-)
*/
@Test
public void shouldAnswerWithTrue()
{
assertTrue( true );
}
}

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>magic-annotation</artifactId>
<version>1.0-SNAPSHOT</version>
<name>magic-annotation</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.auto.service</groupId>
<artifactId>auto-service</artifactId>
<version>1.0-rc6</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,11 @@
package org.example;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE) // Interface, Class, Enum
@Retention(RetentionPolicy.SOURCE)
public @interface Magic {
}

View File

@@ -0,0 +1,51 @@
package org.example;
import com.google.auto.service.AutoService;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.Name;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import java.util.Set;
@AutoService(Processor.class)
public class MagicMojaProcessor extends AbstractProcessor {
// 애노테이션 지정
@Override
public Set<String> getSupportedAnnotationTypes() {
return Set.of(Magic.class.getName());
}
// 소스 코드 버전 지정
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
// 처리할 프로세스
// -> true 를 리턴 할 경우 애노테이션 타입 처리가 끝.(다른 프로세서들은 처리 하지 않는다.)
// element -> 소스코드의 구성 요소들
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(Magic.class);
// 애노테이션의 위치가 interface 일 경우에만 동작
for (Element element: elements) {
Name elementName = element.getSimpleName();
if (element.getKind() != ElementKind.INTERFACE) {
// 인터페이스가 아닌 경우 에러 메시지 출력
processingEnv.getMessager()
.printMessage(Diagnostic.Kind.ERROR, "Magic annotation can not be used on " + elementName);
} else {
processingEnv.getMessager()
.printMessage(Diagnostic.Kind.NOTE, "Processing " + elementName);
}
}
return true;
}
}