KEMBAR78
Desenvolva plugins para o compilador do Java 8 | PPTX
Desenvolva plugins para o
compilador do Java 8
JustJava 2013
Marcelo de Castro
marcelo@castro.eti.br
@mcastroinfo
Plugin para o javac 8
0101010101011111000000000101001110001
1100011100000001111010101010110001110
1001001010000101001010101011010110111
• Por quê, para quê, desenvolver
plugins para o compilador do
Java?
– Adicionar checagem extras em tempo
de compilação
– Adicionar transformações de código
– Customizar análise do código fonte
Este código compila?
Teste.java
public class Teste {
public static final int var = 0;
public static void main(String[] args) {
int i = 0; System.out.println("#JustJava2013");
try{
i++;
}catch(Exception Ex){
}
}
public static void method(int a, int b, int c, int d,
int e, int f, int g, int h, int i, int j, int k){
}
class inner{}
}
Jogo dos 5 erros(!?)
public class Teste {
public static final int var = 0;
public static void main(String[] args) {
int i = 0; System.out.println("#JustJava2013");
try{
i++;
}catch(Exception Ex){
}
}
public static void method(int a, int b, int c, int d,
int e, int f, int g, int h, int i, int j, int k){
}
class inner{}
}
VAR
ex
Inner
vazio
Muitos
parâmetros
Compilar ou não compilar
?????
public class Teste {
public static final int var = 0;
public static void main(String[] args) {
int i = 0; System.out.println("#JustJava2013");
try{
i++;
}catch(Exception Ex){
}
}
public static void method(int a, int b, int c, int d,
int e, int f, int g, int h, int i, int j, int k){
}
class inner{}
}
Alterando o
comportamento do javac
1. Usar Java 8 (tools.jar no CLASSPATH)
2. Implementar Plugin(*)
3. Implementar TaskListener
4. Implementar a lógica desejada
– (TreePathScanner, TreeScanner, TreeVisitor)
– Ex: Não aceitar bloco catch vazio
5. Gerar o jar do Plugin
– META-INF/services/
• com.sun.source.util.Plugin
– NomeTotalmenteQualificadoDoPlugin(*)
6. Compilar usando o plugin
– javac -processorpath CodeCheckPlugin.jar -
Xplugin:CodeCheckPlugin Teste.java
API
0101010101011111000000000101001110001
1100011100000001111010101010110001110
1001001010000101001010101011010110111
interfaces
com.sun.source.util
• Plugin
– permite definir um plugin para o
compilador
• SourcePositions
– fornece métodos para obter a
posição corrente da compilação
• TaskListener
– fornece um listener para monitorar
atividades do javac
interface Plugin
public class CodeCheckPlugin implements Plugin {
@Override
public String getName() {
return "CodeCheckPlugin";
}
@Override
public void init(JavacTask task, String... strings) {
System.out.println("Iniciando plugin!");
task.setTaskListener(new CheckTaskListener(task));
}
}
interface TaskListener
public class CheckTaskListener implements TaskListener{
@Override
public void started(TaskEvent taskEvent) {
if(taskEvent.getKind().equals(TaskEvent.Kind.ANALYZE)) {
CompilationUnitTree compUnit =
taskEvent.getCompilationUnit();
TreePathScanner emptyCacthVisitor =
new EmptyCacthVisitor(task);
emptyCacthVisitor.scan(compUnit, null);
}
}
@Override
public void finished(TaskEvent te) {
}
}
TaskEvent.Kind
•PARSE
•ENTER
•ANNOTATION_PROCESSING
•ANNOTATION_PROCESSING_ROUND
•ANALYZE
•GENERATE
Source File
Teste.java
Byte Code
Teste.class
Abstract Syntax Trees
Exemplo da Gramática da Linguagem Java
normalClassDeclaration
: 'class' Identifier typeParameters?
('extends' type)?
('implements' typeList)?
classBody
public class Teste
extends TesteBase{
}
class TesteBase{}
*AST: abstract syntax tree
interface SourcePositions
SourcePositions sourcePositions =
trees.getSourcePositions();
sourcePositions.getStartPosition
(compilationUnitTree, tree);
sourcePositions.getEndPosition
(compilationUnitTree, tree);
Classes (Syntax Trees)
com.sun.source.util
com.sun.source.tree
• public abstract class Trees
• public abstract class DocTrees extends Trees
• public interface Tree
• public enum Tree.Kind
• public interface CompilationUnitTree extends Tree
• public interface MethodTree extends Tree
• public interface BlockTree extends Tree
• public interface CatchTree extends Tree
• public interface StatementTree extends Tree
• public interface ModifiersTree extends Tree
• public interface VariableTree extends Tree
• public interface PrimitiveTypeTree extends Tree
• + um montão de Tree
DEMO
0101010101011111000000000101001110001
1100011100000001111010101010110001110
1001001010000101001010101011010110111
Referências
• OpenJDK 8 http://openjdk.java.net/
• Javadoc (javac b74)
http://download.java.net/lambda/b74/docs/jdk/api/javac/tree/
• Compiler Grammar http://openjdk.java.net/projects/compiler-grammar/
• Hacking the Java Compiler for Fun and Profit By Raoul-Gabriel Urma
• “Java Compiler Plugins”, Oracle Java Magazine January/February 2013,
Raoul-Gabriel Urma& Jonathan Gibbons http://www.oraclejavamagazine-
digital.com/javamagazine/20130102?sub_id=jFwJyABK25xj#pg56
OBRIGADO
Marcelo de Castro
marcelo@castro.eti.br
@mcastroinfo

Desenvolva plugins para o compilador do Java 8

  • 1.
    Desenvolva plugins parao compilador do Java 8 JustJava 2013
  • 2.
  • 3.
    Plugin para ojavac 8 0101010101011111000000000101001110001 1100011100000001111010101010110001110 1001001010000101001010101011010110111
  • 4.
    • Por quê,para quê, desenvolver plugins para o compilador do Java? – Adicionar checagem extras em tempo de compilação – Adicionar transformações de código – Customizar análise do código fonte
  • 5.
    Este código compila? Teste.java publicclass Teste { public static final int var = 0; public static void main(String[] args) { int i = 0; System.out.println("#JustJava2013"); try{ i++; }catch(Exception Ex){ } } public static void method(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k){ } class inner{} }
  • 6.
    Jogo dos 5erros(!?) public class Teste { public static final int var = 0; public static void main(String[] args) { int i = 0; System.out.println("#JustJava2013"); try{ i++; }catch(Exception Ex){ } } public static void method(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k){ } class inner{} } VAR ex Inner vazio Muitos parâmetros
  • 7.
    Compilar ou nãocompilar ????? public class Teste { public static final int var = 0; public static void main(String[] args) { int i = 0; System.out.println("#JustJava2013"); try{ i++; }catch(Exception Ex){ } } public static void method(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k){ } class inner{} }
  • 8.
    Alterando o comportamento dojavac 1. Usar Java 8 (tools.jar no CLASSPATH) 2. Implementar Plugin(*) 3. Implementar TaskListener 4. Implementar a lógica desejada – (TreePathScanner, TreeScanner, TreeVisitor) – Ex: Não aceitar bloco catch vazio 5. Gerar o jar do Plugin – META-INF/services/ • com.sun.source.util.Plugin – NomeTotalmenteQualificadoDoPlugin(*) 6. Compilar usando o plugin – javac -processorpath CodeCheckPlugin.jar - Xplugin:CodeCheckPlugin Teste.java
  • 9.
  • 10.
    interfaces com.sun.source.util • Plugin – permitedefinir um plugin para o compilador • SourcePositions – fornece métodos para obter a posição corrente da compilação • TaskListener – fornece um listener para monitorar atividades do javac
  • 11.
    interface Plugin public classCodeCheckPlugin implements Plugin { @Override public String getName() { return "CodeCheckPlugin"; } @Override public void init(JavacTask task, String... strings) { System.out.println("Iniciando plugin!"); task.setTaskListener(new CheckTaskListener(task)); } }
  • 12.
    interface TaskListener public classCheckTaskListener implements TaskListener{ @Override public void started(TaskEvent taskEvent) { if(taskEvent.getKind().equals(TaskEvent.Kind.ANALYZE)) { CompilationUnitTree compUnit = taskEvent.getCompilationUnit(); TreePathScanner emptyCacthVisitor = new EmptyCacthVisitor(task); emptyCacthVisitor.scan(compUnit, null); } } @Override public void finished(TaskEvent te) { } }
  • 13.
  • 14.
    Abstract Syntax Trees Exemploda Gramática da Linguagem Java normalClassDeclaration : 'class' Identifier typeParameters? ('extends' type)? ('implements' typeList)? classBody public class Teste extends TesteBase{ } class TesteBase{} *AST: abstract syntax tree
  • 15.
    interface SourcePositions SourcePositions sourcePositions= trees.getSourcePositions(); sourcePositions.getStartPosition (compilationUnitTree, tree); sourcePositions.getEndPosition (compilationUnitTree, tree);
  • 16.
    Classes (Syntax Trees) com.sun.source.util com.sun.source.tree •public abstract class Trees • public abstract class DocTrees extends Trees • public interface Tree • public enum Tree.Kind • public interface CompilationUnitTree extends Tree • public interface MethodTree extends Tree • public interface BlockTree extends Tree • public interface CatchTree extends Tree • public interface StatementTree extends Tree • public interface ModifiersTree extends Tree • public interface VariableTree extends Tree • public interface PrimitiveTypeTree extends Tree • + um montão de Tree
  • 17.
  • 18.
    Referências • OpenJDK 8http://openjdk.java.net/ • Javadoc (javac b74) http://download.java.net/lambda/b74/docs/jdk/api/javac/tree/ • Compiler Grammar http://openjdk.java.net/projects/compiler-grammar/ • Hacking the Java Compiler for Fun and Profit By Raoul-Gabriel Urma • “Java Compiler Plugins”, Oracle Java Magazine January/February 2013, Raoul-Gabriel Urma& Jonathan Gibbons http://www.oraclejavamagazine- digital.com/javamagazine/20130102?sub_id=jFwJyABK25xj#pg56
  • 19.