35
Semana da Tecnologia 2016

Turbinando o compilador do Java 8

Embed Size (px)

Citation preview

Page 1: Turbinando o compilador do Java 8

Semana da Tecnologia 2016

Page 2: Turbinando o compilador do Java 8

Turbinando o compilador do Java 8

Semana da Tecnologia 2016

Page 4: Turbinando o compilador do Java 8

Plugin para o javac 8

010101010101111100000000010100111000111000111000000011110101010101100011101001001010000101001010101011010110111

Page 5: Turbinando o compilador do Java 8

• 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

Page 6: Turbinando o compilador do Java 8

Este código compila?Teste.java

package br.unip.sicc;

public class Teste {

public static final int var = 0;

public static void main(String[] args) {

int i = 0;

System.out.println("UNIP");

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{}

}

Page 7: Turbinando o compilador do Java 8

Jogo dos 5 erros(!?)Teste.java

package br.unip.sicc;

public class Teste {

public static final int var = 0;

public static void main(String[] args) {

int i = 0;

System.out.println("UNIP");

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{}

}

Page 8: Turbinando o compilador do Java 8

Java Code Conventions

Page 9: Turbinando o compilador do Java 8

Java Code Conventions

Page 10: Turbinando o compilador do Java 8

Jogo dos 5 erros(!?)Teste.java

package br.unip.sicc;

public class Teste {

public static final int var = 0;

public static void main(String[] args) {

int i = 0;

System.out.println("UNIP");

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{}

}

Inner

Page 11: Turbinando o compilador do Java 8

Java Code Conventions

Page 12: Turbinando o compilador do Java 8

Jogo dos 5 erros(!?)Teste.java

package br.unip.sicc;

public class Teste {

public static final int var = 0;

public static void main(String[] args) {

int i = 0;

System.out.println("UNIP");

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{}

}

ex

Page 13: Turbinando o compilador do Java 8

Java Code Conventions

Page 14: Turbinando o compilador do Java 8

Jogo dos 5 erros(!?)Teste.java

package br.unip.sicc;

public class Teste {

public static final int var = 0;

public static void main(String[] args) {

int i = 0;

System.out.println("UNIP");

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

Page 15: Turbinando o compilador do Java 8

Effective Java

Page 16: Turbinando o compilador do Java 8

Jogo dos 5 erros(!?)Teste.java

package br.unip.sicc;

public class Teste {

public static final int var = 0;

public static void main(String[] args) {

int i = 0;

System.out.println("UNIP");

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{}

}

vazio

Page 17: Turbinando o compilador do Java 8

Effective Java

Page 18: Turbinando o compilador do Java 8

Jogo dos 5 erros(!?)Teste.java

package br.unip.sicc;

public class Teste {

public static final int var = 0;

public static void main(String[] args) {

int i = 0;

System.out.println("UNIP");

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{}

}

Muitos

parâmetros

Page 19: Turbinando o compilador do Java 8

Jogo dos 5 erros(!?)Teste.java

package br.unip.sicc;

public class Teste {

public static final int var = 0;

public static void main(String[] args) {

int i = 0;

System.out.println("UNIP");

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

Page 20: Turbinando o compilador do Java 8

Compilar ou não compilarTeste.java

package br.unip.sicc;

public class Teste {

public static final int var = 0;

public static void main(String[] args) {

int i = 0;

System.out.println("UNIP");

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{}

}

Page 21: Turbinando o compilador do Java 8

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

Page 22: Turbinando o compilador do Java 8

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

Page 23: Turbinando o compilador do Java 8

DEMO

010101010101111100000000010100111000111000111000000011110101010101100011101001001010000101001010101011010110111

Page 24: Turbinando o compilador do Java 8

API

010101010101111100000000010100111000111000111000000011110101010101100011101001001010000101001010101011010110111

Page 25: Turbinando o compilador do Java 8

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

Page 26: Turbinando o compilador do Java 8

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));

}

}

Page 27: Turbinando o compilador do Java 8

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) {

}

}

Page 28: Turbinando o compilador do Java 8

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) {

}

}

Page 29: Turbinando o compilador do Java 8

TaskEvent.Kind

•PARSE

•ENTER

•ANNOTATION_PROCESSING

•ANNOTATION_PROCESSING_ROUND

•ANALYZE

•GENERATE

Source File

Teste.java

Byte Code

Teste.class

Page 30: Turbinando o compilador do Java 8

interface SourcePositions

SourcePositions sourcePositions = trees.getSourcePositions();

sourcePositions.getStartPosition

(compilationUnitTree, tree);

sourcePositions.getEndPosition

(compilationUnitTree, tree);

Page 31: Turbinando o compilador do Java 8

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

Page 32: Turbinando o compilador do Java 8

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{}

Abstract

Syntax Tree

Page 33: Turbinando o compilador do Java 8

SHOW ME THE CODE

010101010101111100000000010100111000111000111000000011110101010101100011101001001010000101001010101011010110111

Page 34: Turbinando o compilador do Java 8

Referências

• OpenJDK 8 http://openjdk.java.net/

• API Specification, The Java Programming Language Compiler http://docs.oracle.com/javase/8/docs/jdk/api/javac/tree/index.html

• Sun Microsystems, Java Code Conventions, 1997

• Compiler Grammar http://openjdk.java.net/projects/compiler-grammar/

• Effective Java by Joshua Block, 2008

• 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