Projeto de PLP (2005.1)
Extensão da Linguagem OA1 (2003.1)
Alunos:
Alberto Costa Neto (acn)
Manoel Messias da Silva Menezes Júnior (mmsmj)
Rafael Leão da Fonseca (rlf)
Agenda
•
•
•
BNF/API de OA1
Ambientes de Execução e Compilação
Extensões da Linguagem OA1
1.
2.
3.
4.
5.
6.
7.
8.
•
•
Acrescentar Join Points para leitura/escrita de atributos
Introdução de atributos e métodos
Implementação do operador not em PointcutExpressao
Implementação de cflow e cflowbelow
Implementação de within e withincode
Uso de Matching na definição de Pointcuts
Advice com pointcut anônimo
Inclusão de objeto thisJoinPoint
Conclusões
Trabalhos Futuros
BNF/API de OA1
Ambientes de Execução e Compilação
Ambiente de Execução
• Componentes herdados de LOO1
– uma pilha de mapeamentos de identificadores
(incluindo this) em valores (incluindo referências).
– um mapeamento de referências em objetos.
– a referência para a próxima célula a ser alocada.
– um mapeamento de identificadores em definições de
classes.
– listas de valores de entrada e saída.
• Componentes adicionais
– Gerenciador de aspectos.
– Pilha de interceptáveis (join points).
Ambiente de Execução
• Gerenciador de Aspectos
– Mapeamento de identificador de pointcut em
pointcut
– Mapeamento de identificador de pointcut em
um grupo de advices
Ambiente de Compilação
• Componentes herdados de LOO1
– uma pilha de mapeamentos de identificadores
em tipos.
– um mapeamento de identificadores em
definições de classes.
– listas de valores de entrada.
Extensão da Linguagem OA1
Extensão da linguagem OA1
 Propostas
1. Acrescentar Join Points para leitura/escrita de
atributos
2. Introdução de atributos e métodos
3. Implementação do operador not em
PointcutExpressao
4. Implementação de cflow e cflowbelow
5. Implementação de within e withincode
6. Uso de Matching na definição de Pointcuts
7. Inclusão de objeto thisJoinPoint
8. Modificar advice para usar PointcutExpressao
ao invés de um simples Id (advice com
pointcut anônimo)
Extensão da linguagem OA1
classe Ponto {
int x = 0, int y = 0;
proc setX(int x) { this.x := x },
proc setY(int y) { this.y := y},
proc mover(int offsetX, int offsetY) {
this.x := this.x + offsetX;
this.y := this.y + offsetY
},
proc printX() { write(“x:” ++ this.x) },
proc printY() { write(“y:” ++ this.y) },
proc print() { printX(); printY() }
}
Extensão da linguagem OA1
1. Introdução dos Join Points (get e set)
– get: Captura leitura de um atributo
– set: Captura modificação de um atributo
aspect PontoLog {
pointcut leitura: get(Ponto.x),
pointcut escrita: set(Ponto.x);
after : leitura { write(“leitura de Ponto.x”) },
after : escrita { write(“escrita em Ponto.x”) }
};
Extensão da linguagem OA1
2. Introdução de atributos e métodos
aspect PontoLog {
proc Ponto.moverX(int offsetX) {
this.x := this.x + offsetX
},
proc Ponto.moverY(int offsetY) {
this.y := this.y + offsetY
}
}
Extensão da linguagem OA1
3. Implementação do operador not em
PointcutExpressao
•
Negação de qualquer PointcutExpressao.
Extensão da linguagem OA1
4. Implementação de cflow e cflowbellow
– cflow(Pointcut): intercepta qualquer join
point no fluxo de controle de qualquer join
point P interceptado por Pointcut, incluindo
P.
aspect PontoLog {
pointcut noFluxoDePrint: cflow(Ponto.print());
before : noFluxoDePrint {
write("JP no fluxo de controle de print()")
}
};
Extensão da linguagem OA1
– cflowbelow(Pointcut): intercepta qualquer
join point no fluxo de controle de qualquer
join point P interceptado por Pointcut,
sem incluir P.
aspect PontoLog {
pointcut noFluxoDePrint: cflowbelow(Ponto.print());
before : noFluxoDePrint {
write("JP no fluxo de controle abaixo de print()")
}
};
Extensão da linguagem OA1
• Pilha / Cache de Join Points
Pilha de Join Points
Cache de Join Points
Extensão da linguagem OA1
1. Chamada à Ponto.print()
Pilha de Join Points
Cache de Join Points
Ponto.print() = 1
Ponto.print()
Extensão da linguagem OA1
2. Execução do Advice de PontoLog
Pilha de Join Points
Cache de Join Points
Ponto.print() = 1
PontoLog = 1
PontoLog
Ponto.print()
Extensão da linguagem OA1
3. Fim da execução do Advice
Pilha de Join Points
Cache de Join Points
Ponto.print() = 1
Ponto.print()
Extensão da linguagem OA1
4. Chamada a Ponto.printX()
Pilha de Join Points
Cache de Join Points
Ponto.print() = 1
Ponto.printX() = 1
Ponto.printX()
Ponto.print()
Extensão da linguagem OA1
5. Execução do Advice de PontoLog
Pilha de Join Points
Cache de Join Points
Ponto.print() = 1
Ponto.printX() = 1
PontoLog = 1
PontoLog
Ponto.printX()
Ponto.print()
Extensão da linguagem OA1
6. Fim da execução do Advice
Pilha de Join Points
Cache de Join Points
Ponto.print() = 1
Ponto.printX() = 1
Ponto.printX()
Ponto.print()
Extensão da linguagem OA1
7. Acesso a Ponto.x
Pilha de Join Points
Cache de Join Points
Ponto.print() = 1
Ponto.printX() = 1
Ponto.x = 1
Ponto.x
Ponto.printX()
Ponto.print()
Extensão da linguagem OA1
8. Execução do Advice de PontoLog
Pilha de Join Points
Cache de Join Points
Ponto.print() = 1
Ponto.printX() = 1
PontoLog
Ponto.x = 1
Ponto.x
PontoLog = 1
Ponto.printX()
Ponto.print()
Extensão da linguagem OA1
9. Fim da execução do Advice
Pilha de Join Points
Cache de Join Points
Ponto.print() = 1
Ponto.printX() = 1
Ponto.x = 1
Ponto.x
Ponto.printX()
Ponto.print()
Extensão da linguagem OA1
10. Remoção de Acesso a Ponto.x
Pilha de Join Points
Cache de Join Points
Ponto.print() = 1
Ponto.printX() = 1
Ponto.printX()
Ponto.print()
Extensão da linguagem OA1
11. Remoção de Chamada a Ponto.printX()
Pilha de Join Points
Cache de Join Points
Ponto.print() = 1
Ponto.print()
Extensão da linguagem OA1
12. Chamada à Ponto.printY()
– Executa de forma similar à chamada de
Ponto.printX().
– Intercepta dois join points: Ponto.printY() e
get(Ponto.y), executando o advice de
PontoLog duas vezes.
Extensão da linguagem OA1
13. Remoção de Chamada a Ponto.print()
Pilha de Join Points
Cache de Join Points
Extensão da linguagem OA1
5. Implementação de within e
withincode
– within(PadrãoCasamento) : intercepta os
join points nos quais o código em
execução é definido na declaração de um
dos tipos de PadrãoCasamento.
– withincode(PadrãoCasamentoMetodo) :
intercepta cada join point onde o código
em execução é definido na declaração do
método especificado.
Extensão da linguagem OA1
{
aspect PontoLog {
pointcut noFluxoDePrintEForaDePontoLog:
cflow(Ponto.print()) and not within(PontoLog),
pointcut withincodePrint: withincode(Ponto.print());
before : noFluxoDePrintEForaDePontoLog {
write(“No fluxo de controle de print() e not Within PontoLog”)
},
before : withincodePrint {
write("Withincode Ponto.print()")
}
}
Extensão da linguagem OA1
•
Uso da pilha
–
–
Within: Checa o nome da classe/aspecto do join
point que está abaixo do elemento no topo da pilha
Withincode: Checa o join point que está abaixo do
elemento no topo da pilha, que deve ser uma
chamada de método e casar com a fornecida
Pilha de Join Points
Cache de Join Points
Ponto.print() = 1
Ponto.printX()
Ponto.print()
Ponto.printX() = 1
Extensão da linguagem OA1
6. Uso de Matching na definição de
Pointcuts
aspect PontoLog {
pointcut movimento:Ponto.se*(*) or
Ponto.mover(..);
after : movimento {
write(“O ponto mudou de posicao.")
};
Extensão da linguagem OA1
• Exemplos de Matching
– get/set/cflow(below)
• get(*.*), get(*.x), get(Ponto.*), get(P*.*), get(*o.*),
get(P*o.*), cflow(*.*), cflowbelow(*.x)
– within
• within(*), within(P*), within(*to), within(Po*o)
– Chamada de método/withincode/cflow(below)
• *.*(int, string), *.*(*), *.*(..), *.*(..,int), *.*(int,..),
*.*(..,int,..)
• *.*(..,..,..), *.*(..,..,int,..,..)
Extensão da linguagem OA1
7. Uso de PointcutExpressao na
definição de Advice
aspect PontoLog {
pointcut setX : Ponto.setX(int);
after : setX or Ponto.setY(*) or Ponto.mover(..)
{
write("O ponto mudou de posicao.")
}
}
Extensão da linguagem OA1
8. Inclusão de objeto thisJoinPoint
– Dá acesso a metadados sobre o join
point interceptado durante a execução de
um advice.
– Oferece os seguintes atributos:
•
•
kind: string com tipo do join point
signature: string com a assinatura do método
Extensão da linguagem OA1
• Uso de thisJoinPoint na definição de
Advice
aspect PontoLog {
before : Ponto.setX(*) or Ponto.setY(*) {
write(thisJoinPoint.signature);
write(thisJoinPoint.kind)
}
}
Conclusões
Conclusões
•
A introdução do conceito de aspectos tornou a
implementação do interpretador relativamente
complexa
– Se usássemos AspectJ na implementação do
interpretador, seria mais simples
•
A introdução de aspectos na LOO1 faz com
que expressões tenham efeitos colaterais
– Execução dos advices ativados por um pointcut
designators get
Conclusões
• A implementação interpretada exige que
para cada comando ou expressão
interceptável seja feita a avaliação de
todos os pointcuts
• Essa abordagem é bastante lenta,
principalmente quando utiliza-se
cflow/cflowbelow
– O cache de join points implementados ajuda,
mas não no caso de matching
Conclusões
• A utilização de Generics na
implementação das pilhas e
mapeamentos permitiu
– melhor reutilização de código
– checagem estática
• Otimização das pilhas para permitir
navegação sem desempilhar/empilhar
Trabalhos Futuros
Trabalhos Futuros
• Estender o ambiente de compilação para
permitir a verificação estática das
declarações de aspectos
• Retirar obrigatoriedade de haver um
pointcut e um advice no aspecto
• Permitir declarações de atributos e
métodos nos aspectos
Trabalhos Futuros
• Controlar a instanciação de aspectos por
cflow (percflow), cflowbelow
(percflowbelow), this (perthis), target
(pertarget) e única (issingleton)
• Implementação dos poincut designators
adviceexecution e if de AspectJ
• Permitir o uso de anotações ao estilo de
AspectJ 5
Trabalhos Futuros
•
Estender LOO1 com conceitos como: função,
herança, array e type casting.
– Isso permitiria, implementar outros pointcut
designators
•
•
Permitir que um método ou atributo introduzido
em uma classe não seja utilizado apenas
dentro do aspecto que realizou a introdução
Implementar a precedência entre os
operadores and e or.
Download

Apresentação