Partilhar via


GDL Namespaces

O analisador GDL não permitirá que um modelo com o mesmo nome seja definido mais de uma vez. Dois arquivos de modelo escritos independentemente podem usar inadvertidamente o mesmo nome para um modelo e impedir que você inclua ambos os arquivos de modelo no arquivo GDL.

Para evitar problemas de colisão de nome, a GDL dá suporte a namespaces. O autor de um arquivo de cabeçalho pode especificar a qual namespace cada modelo e definição de macro devem pertencer colocando toda a definição em um constructo *DefineInNameSpace. O símbolo fornecido como o nome da instância desse constructo se tornará o namespace ao qual todas as definições incluídas pertencerão. Se uma definição residir dentro de dois ou mais constructos *DefineInNameSpace aninhados, ela pertencerá apenas ao namespace definido pelo constructo innermost *DefineInNameSpace. Se uma definição não residir em nenhum constructo *DefineInNameSpace, ela será atribuída ao namespace padrão ou "sem nome".

Se as entradas que compõem o corpo de um modelo ou construção de macro forem colocadas dentro de constructos *DefineInNameSpace separados, o analisador não colocará essas entradas individuais no novo namespace porque as entradas individuais não são uma definição separada, portanto, elas não podem residir em um namespace diferente. As macros de bloco permitem definições de macro aninhadas e essas definições aninhadas podem ser atribuídas a outros namespaces. No entanto, alterar o namespace de uma definição aninhada não estende seu tempo de vida. Uma definição de macro aninhada só pode ser referenciada dentro do nível de aninhamento em que foi definida.

Um modelo ou nome de macro pode ser referenciado em um formulário qualificado ou não qualificado em um namespace. Para qualificar um modelo ou nome de macro, o nome do namespace é simplesmente prefixado para o modelo ou nome da macro com um caractere de dois-pontos intervindo (por exemplo, Namespace:MacroName).

Nota O nome do símbolo fornecido como o valor de *Template, *Macros ou *Definições blockMacro não pode ser qualificado por um namespace. O namespace de uma definição só pode ser definido usando *DefineInNameSpace.

Por exemplo, depois que um modelo chamado "TEMPNAME" tiver sido definido em um namespace chamado "NSName", esse modelo poderá ser referenciado por outra definição de modelo usando o formulário qualificado de namespace, como mostra o exemplo de código a seguir.

*DefineInNameSpace: NSName
{
    *Template:  TEMPNAME
    {
        *%  member attributes
    }
}

Este modelo agora pode ser referenciado de outro modelo usando a sintaxe qualificada do namespace, como mostra o exemplo de código a seguir.

*Template:  ANOTHER_TEMPLATE
{
    *Inherits: NSName:TEMPNAME
}

Se a maioria das referências de modelo fizer referência ao mesmo namespace ou se não houver nenhuma colisão de nome entre nomes de modelo referenciados em dois ou mais namespaces, você poderá omitir o qualificador de namespace e fornecer apenas o nome do modelo e contar com o analisador para pesquisar uma lista de namespaces até que um modelo correspondente seja encontrado.

A lista de namespaces é especificada colocando uma ou mais entradas GDL em *Constructos UsingNameSpace. Se qualquer uma dessas entradas contiver referências não qualificadas a um modelo ou macro, a resolução dessas referências será afetada pelos constructos *UsingNameSpace. O símbolo fornecido como o nome da instância desse constructo identifica o namespace a ser pesquisado.

Você pode especificar vários namespaces aninhando vários constructos. A ordem de pesquisa começa com o constructo innermost *UsingNameSpace e prossegue para fora. Se uma definição de modelo for encontrada em um namespace especificado, a pesquisa será interrompida e esse modelo será usado. Se nenhuma correspondência tiver sido encontrada depois que todos os namespaces especificados explicitamente tiverem sido pesquisados, o analisador pesquisará o namespace que é nomeado em cada constructo *DefineInNameSpace entre as partes internas. E se essa pesquisa não resolve a referência, ela tentará pesquisar o namespace "sem nome".

Nota Se você precisar isolar a ordem de pesquisa de namespace de influências externas, todos os namespaces necessários para resolve referências devem ser especificados usando *Constructos UsingNameSpace.

Você não deve contar com o constructo *DefineInNameSpace para estabelecer a ordem de pesquisa porque o host pode cercar o arquivo incluído com construções adicionais *UsingNameSpace e os namespaces especificados pelo host serão pesquisados antes dos namespaces nomeados pelos constructos *DefineInNameSpace.

Por exemplo, o modelo que foi definido anteriormente mostrou dois namespaces que foram explicitamente especificados para serem usados para resolução de nomes de modelo. Qualquer namespace nomeado por *UsingNameSpace deve ter sido definido anteriormente por *DefineInNameSpace. A exceção é o namespace "sem nome", que sempre existe e é nomeado pelo símbolo NULL.

O exemplo de código a seguir mostra como especificar o namespace "sem nome" para definir a ordem de pesquisa.

*UsingNameSpace: NSName2
{
    *UsingNameSpace:  *%%%%%  omitting symbol specifies the  Unnamed 
*%  Namespace.
    {
        *UsingNameSpace: NSName
        {
            *Template:  ANOTHER_TEMPLATE
            {
                *Inherits: TEMPNAME
            }
        }
    }
}

No exemplo anterior, o namespace "sem nome" será pesquisado depois que todas as pesquisas no namespace especificado explicitamente falharem, mas o exemplo especifica explicitamente que o namespace "sem nome" será pesquisado antes do namespace NSName2.

Como as entradas de dados GDL nunca referenciam explicitamente nomes de modelo, o uso de *UsingNameSpace não afetará qual modelo é atribuído a cada entrada de dados. No entanto, a ordem de pesquisa de namespace que *UsingNameSpace especifica (que está em vigor no momento em que a primeira entrada de dados GDL é analisada) é usada na pesquisa para o modelo ROOT. Se você estiver incluindo um ou mais arquivos de cabeçalho GDL, verifique se eles não se tornam inadvertidamente os primeiros a definir uma entrada de dados e, portanto, determinar qual namespace é usado para localizar o modelo ROOT.

Nota As definições de macro são limitadas por escopo pelo nível de aninhamento delimitador. No entanto, os níveis de aninhamento de namespace não limitam o escopo das definições de macro porque você não precisa definir uma macro para pertencer a um namespace específico se o escopo da macro não for grande o suficiente para ficar visível fora desse namespace.

Os constructos de namespace podem ser intercalados entre outros tipos de constructos. Quase não há nenhuma restrição sobre onde um constructo de namespace pode aparecer. Os constructos não namespace não afetam a resolução de namespace.