DevNotes #1 - Identificadores entre aspas
Alguns dias atrás, descobri que o ZPA não estava tratando corretamente os identificadores entre aspas. Especificamente, o componente responsável pela criação da tabela de símbolos não estava identificando e contando corretamente os usos de identificadores entre aspas. Isso levava a resultados imprecisos, que poderiam afetar a qualidade da análise de código.
No Oracle
SQL, "quoted user-defined identifiers"
são identificadores que estão entre aspas duplas. Identificadores entre aspas são case-sensitive, o que significa que
"My Table"
e "my table"
são considerados identificadores diferentes. É diferente dos outros identificadores sem
aspas, que são case-insensitive (onde letras maiúsculas e minúsculas não importam).
No entanto, há um detalhe: se um identificador entre aspas, sem suas aspas duplas, for um identificador de usuário comum
válido (começa com uma letra e contém apenas letras, dígitos, $
, #
e _
) e estiver em letras maiúsculas, então ele
é tratado como um identificador não entre aspas. A definição parece longa, mas, na prática, isso significa que
MY_TABLE
, my_table
e "MY_TABLE"
são considerados o mesmo identificador.
Portanto, vamos considerar o seguinte exemplo:
DECLARE
"HELLO" VARCHAR2(15) := 'UPPERCASE';
"Hello" VARCHAR2(15) := 'Initial Capital';
"hello" VARCHAR2(15) := 'lowercase';
BEGIN
DBMS_OUTPUT.PUT_LINE("HELLO");
DBMS_OUTPUT.PUT_LINE("Hello");
DBMS_OUTPUT.PUT_LINE("hello");
DBMS_OUTPUT.PUT_LINE(hello);
END;
Neste exemplo, temos três variáveis declaradas com identificadores entre aspas: "HELLO"
, "Hello"
e "hello"
. Todas
as três são consideradas identificadores diferentes porque têm diferentes capitalizações.
A última linha com DBMS_OUTPUT.PUT_LINE(hello);
é interessante porque o identificador está sem aspas. Este hello
está se referindo à variável declarada com o identificador entre aspas "HELLO"
. Como o identificador entre aspas
"HELLO"
se encaixa na situação descrita anteriormente, ele é tratado como se não tivesse aspas e é case-insensitive.
Enquanto eu trabalhava no ZPA, notei que na tabela de símbolos esse tipo de identificador não estava tratado corretamente e causava falsos positivos nas regras UnusedVariable, UnusedCursor, UnusedParameter e VariableHiding.
Testando este trecho de código com o ZPA Toolkit 3.5.1, podemos ver que as três variáveis declaradas com identificadores
entre aspas estão sendo relatadas incorretamente como usos de "HELLO"
e a última referência não entre aspas nem mesmo
é considerada.
Após as correções, o ZPA passou a considerar corretamente todas as situações: