150 likes | 305 Views
Jass - Java with assertions. Sérgio Soares. Jass. Assertions descrevem propriedades que devem ser verdadeiras em determinados pontos da execução do programa Especificação formal como parte da linguagem Especificação documentada no código. Jass. Checagem em tempo de execução
E N D
Jass - Java with assertions Sérgio Soares
Jass • Assertions descrevem propriedades que devem ser verdadeiras em determinados pontos da execução do programa • Especificação formal como parte da linguagem • Especificação documentada no código
Jass • Checagem em tempo de execução • Precondições e poscondições • Invariantes (de classe e de loop) e variantes (de loop) • Tratamento de violação de assertions (rescue e retry) • Exceções indicam violação das condições. • Precompilador traduz assertions em comandos Java.
Comandos de Jass • require precondição • ensure poscondição • ìnvariant de classe ou loop • variant de loop (deve ser positivo e decrescente com a execução do loop) • check verifica assertions em qualquer parte do código • rescue bloco executado caso assertion seja false • retry executa novamente o método (só pode ser utilizado dentro do bloco rescue)
Exemplos de Assertions /** require a!=0 **/ /** require a!=0; isEven(a) **/ /** require -1 > c.m() **/
Restrições de Assertions • Definições recursivas • Chamar o método que declara a assertion direta ou indiretamente. • Se um método é chamado durante a avaliação de uma assertion e neste método é declarada uma assertion, está não é avaliada.
Construtores especiais • Old (poscondição) • representa o estado inicial do objeto antes da execução do método • o método clone deve ser implementado • changeonly (poscondição) • limita a alteração de atributos da classe • os atributos do objeto são comparados com os de Old pelo método equals, o qual deve ser rescrito
Exemplo de Assertion public void addElement (Object o) { /** require !isFull(); o != null; **/ buffer[in % buffer.length] = o; in++; /** ensure changeonly{in,buffer}; Old.in == in - 1; **/ }
Implementação das assertions • No caso de chamada de métodos na definição da assertion • O corpo do método é copiado em uma versão sem assertions • O invariante de classe vira um método que é chamado na precondição e na poscondição. • Em loops o invariante é checado a cada execução e é criada uma variável para armazenar o variante. • Checks são expandidos como macros
Refinamento • Para cada método sobrescrito: • Se o método abstrato e aplicável o concreto também pode ser chamado • O método concreto é mais determinístico • O invariante da superclasse deve ser válido onde o da subclasse se aplique
Refinamento • Enfraquecer a precondição • pre_a -> pre_c • Fortalecer a poscondição • mais restrições (determinismo)
public void addElement (Object o) { /** require !isFull(); o != null; **/ buffer[in % buffer.length] = o; in++; /** ensure changeonly{in,buffer}; Old.in == in - 1; **/ } public void addElement (Object o) { /** require !isFull(); **/ if (o==null) buffer[in % buffer.length] = new Default(); else buffer[in % buffer.length] = o; in++; /** ensure changeonly{in,buffer}; Old.in == in - 1; o!=null ? contains(o) : true; **/ }
Passos para refinar métodos • Implementar a interface jass.runtime.refinement • Implementar a função de “abstração” jassGetSuperState()
Passos para refinar métodos public class UnlimitedBuffer { ... private Buffer jassGetSuperState() { Buffer b = new Buffer(v.size()+1); b.in = v.size(); b.out = 0; for (int i = 0; i < b.buffer.length-1; i++) b.buffer[i] = v.elementAt(i); return b; } }
Referencias • Jass: Java with assertions, May 1999. http://semantik.informatik.uni-oldenburg.de/~jass.