O que é e para o que serve o PPO?

O que é o arquivo PPO de compilação gerado durante o processo de compilação de um código fonte ADVPL?

O arquivo PPO é o código fonte ADVPL após a pré-compilação.


Como assim?

Um código ADVPL pode conter ou não diretivas de compilação, e essas que sofrem mudanças após a pré-compilação.


Quais diretivas?
  • #command
    • #define
    • #ifdef
    • #ifndef
    • #include
    • #translate
    • #xcommand
    • #xtranslate

Existem muitas diretivas já prontas nos arquivos .CH do Protheus, tais como: CRLF, Default

Essas por suas vez, são transformadas em código ADVPL após a pré-compilação:

CRLF - Essa diretiva se transforma nas funções Chr(13) + Chr(10), ou seja, uma quebra de linha.

Default - Essa aqui se transforma numa espécie de operador ternário, ele verifica o valor e se estiver nulo ele retorna o valor informado no default, caso contrário o valor permanece o mesmo.


Aquelas interfaces que são criadas com DEFINE, ou com @, acabam também sofrendo transformações, normalmente é o método new de alguma classe de interface.

Outro exemplo são aquelas constantes que você usa, como CLR_BLACK, MODEL_OPERATION_INSERT do MVC.

Classes? Sim, tudo é feito por pré-compilação, inclusive o código de uma classe em ADVPL puro, é BEM diferente:

Classe original:

class Classe from longnameclass
    data propriedade as char
    method new()
endclass

method new() class Classe
return self

method getPropriedade() class Classe
return ::propriedade

Classe pré-compilada:


_ObjNewClass( Classe ,longnameclass )
    _ObjClassData( propriedade,char, , )
    _ObjClassMethod(new,, )
_ObjEndClass( )

Function ___Classe____new( )
return self

Function ___Classe____getPropriedade( )
return Self:propriedade

Perceba que até o :: é uma forma resumida de self:, que é transformado durante a pré-compilação.

E o mais legal... A user function, ela se transforma em uma função U_, por isso ao invocar uma user function você colocar o U_ na frente da função criada! =)


Posso criar minha diretiva?

Claro que sim, inclusive é possível criar diretamente no fonte ADVPL:


#include "protheus.ch"

#define VERDADEIRO .T.
#define FALSO .F.
#define OU .Or.
#define E .And.
#define SMILE "=)"
#xcommand PRINT <param> => ConOut( <param> )

//-------------------------------------------------------------------
/*{Protheus.doc} U_Condicoes
Exemplo de utilização de #define

@author Daniel Mendes
@since 05/06/2020
@version 1.0
*/
//-------------------------------------------------------------------
function U_Condicoes()

if ( VERDADEIRO OU FALSO ) E VERDADEIRO
    PRINT SMILE
endif

return nil

O arquivo PPO desse exemplo ficará da seguinte forma:


function U_Condicoes()

if ( .T.  .Or.  .F.  ) .And.  .T. 
    ConOut( "=)" )
endif

return nil


Documentação:

https://tdn.totvs.com/display/tec/AdvPL+-+Compiler+Directives

Bah! Tchê!
Muito bom essa resposta Daniel!

PRINT SMILE

Adorei a explicação e a forma como foi apresentada. Com certeza se alguém me perguntar já terei o link pronto para enviar a pessoa. Parabéns Daniel! PRINT SMILE

Grato Daniel, acho que você pode escrever um livro, advpl super simples. Melhor explicação que já vi nos ultimos tempos.