Jass - Java with assertions Sérgio Soares
zAssertions descrevem propriedades que devem ser verdadeiras em determinados pontos da execução do programa yEspecificação formal como parte da linguagem yEspecificação documentada no código Jass
zChecagem em tempo de execução yPrecondições e poscondições yInvariantes (de classe e de loop) e variantes (de loop) yTratamento de violação de assertions (rescue e retry) zExceções indicam violação das condições. zPrecompilador traduz assertions em comandos Java. Jass
zrequire precondição zensure poscondição zìnvariant de classe ou loop zvariant de loop (deve ser positivo e decrescente com a execução do loop) zcheck verifica assertions em qualquer parte do código zrescue bloco executado caso assertion seja false zretry executa novamente o método (só pode ser utilizado dentro do bloco rescue) Comandos de Jass
Exemplos de Assertions /** require a!=0 **/ /** require a!=0; isEven(a) **/ /** require -1 > c.m() **/
zDefinições recursivas yChamar o método que declara a assertion direta ou indiretamente. zSe um método é chamado durante a avaliação de uma assertion e neste método é declarada uma assertion, está não é avaliada. Restrições de Assertions
Construtores especiais zOld(poscondição) yrepresenta o estado inicial do objeto antes da execução do método yo método clone deve ser implementado zchangeonly (poscondição) ylimita a alteração de atributos da classe yos atributos do objeto são comparados com os de Old pelo método equals, o qual deve ser rescrito
public void addElement (Object o) { /** require !isFull(); o != null; **/ buffer[in % buffer.length] = o; in++; /** ensure changeonly{in,buffer}; Old.in == in - 1; **/ } Exemplo de Assertion
Implementação das assertions zNo caso de chamada de métodos na definição da assertion yO corpo do método é copiado em uma versão sem assertions zO invariante de classe vira um método que é chamado na precondição e na poscondição. zEm loops o invariante é checado a cada execução e é criada uma variável para armazenar o variante. zChecks são expandidos como macros
Refinamento zPara cada método sobrescrito: ySe o método abstrato e aplicável o concreto também pode ser chamado yO método concreto é mais determinístico yO invariante da superclasse deve ser válido onde o da subclasse se aplique
Refinamento zEnfraquecer a precondição ypre_a -> pre_c zFortalecer a poscondição ymais 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 zImplementar a interface jass.runtime.refinement zImplementar a função de “abstração” jassGetSuperState()
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; } Passos para refinar métodos
Referencias zJass: Java with assertions, May oldenburg.de/~jass.