WHLSLNameContext.cpp [plain text]
#include "config.h"
#include "WHLSLNameContext.h"
#if ENABLE(WEBGPU)
#include "WHLSLEnumerationDefinition.h"
#include "WHLSLFunctionDefinition.h"
#include "WHLSLNativeFunctionDeclaration.h"
#include "WHLSLNativeTypeDeclaration.h"
#include "WHLSLStructureDefinition.h"
#include "WHLSLTypeDefinition.h"
#include "WHLSLVariableDeclaration.h"
namespace WebCore {
namespace WHLSL {
NameContext::NameContext(NameContext* parent)
: m_parent(parent)
{
}
Expected<void, Error> NameContext::add(AST::TypeDefinition& typeDefinition)
{
if (auto existing = topLevelExists(typeDefinition.name()))
return makeUnexpected(Error("Duplicate name in program", *existing));
typeDefinition.setNameSpace(m_currentNameSpace);
auto index = static_cast<unsigned>(m_currentNameSpace);
auto result = m_types[index].add(typeDefinition.name(), Vector<std::reference_wrapper<AST::NamedType>, 1>());
ASSERT(result.isNewEntry);
result.iterator->value.append(typeDefinition);
return { };
}
Expected<void, Error> NameContext::add(AST::StructureDefinition& structureDefinition)
{
if (auto existing = topLevelExists(structureDefinition.name()))
return makeUnexpected(Error("Duplicate name in program.", *existing));
structureDefinition.setNameSpace(m_currentNameSpace);
auto index = static_cast<unsigned>(m_currentNameSpace);
auto result = m_types[index].add(structureDefinition.name(), Vector<std::reference_wrapper<AST::NamedType>, 1>());
ASSERT(result.isNewEntry);
result.iterator->value.append(structureDefinition);
return { };
}
Expected<void, Error> NameContext::add(AST::EnumerationDefinition& enumerationDefinition)
{
if (auto existing = topLevelExists(enumerationDefinition.name()))
return makeUnexpected(Error("Duplicate name in program.", *existing));
enumerationDefinition.setNameSpace(m_currentNameSpace);
auto index = static_cast<unsigned>(m_currentNameSpace);
auto result = m_types[index].add(enumerationDefinition.name(), Vector<std::reference_wrapper<AST::NamedType>, 1>());
ASSERT(result.isNewEntry);
result.iterator->value.append(enumerationDefinition);
return { };
}
Expected<void, Error> NameContext::add(AST::FunctionDefinition& functionDefinition)
{
auto index = static_cast<unsigned>(m_currentNameSpace);
if (auto* type = searchTypes(functionDefinition.name()))
return makeUnexpected(Error("Duplicate name in program.", type->codeLocation()));
functionDefinition.setNameSpace(m_currentNameSpace);
auto result = m_functions[index].add(functionDefinition.name(), Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>());
result.iterator->value.append(functionDefinition);
return { };
}
Expected<void, Error> NameContext::add(AST::NativeFunctionDeclaration& nativeFunctionDeclaration)
{
auto index = static_cast<unsigned>(m_currentNameSpace);
if (auto* type = searchTypes(nativeFunctionDeclaration.name()))
return makeUnexpected(Error("Duplicate name in program.", type->codeLocation()));
nativeFunctionDeclaration.setNameSpace(m_currentNameSpace);
auto result = m_functions[index].add(nativeFunctionDeclaration.name(), Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>());
result.iterator->value.append(nativeFunctionDeclaration);
return { };
}
Expected<void, Error> NameContext::add(AST::NativeTypeDeclaration& nativeTypeDeclaration)
{
auto index = static_cast<unsigned>(m_currentNameSpace);
if (auto* function = searchFunctions(nativeTypeDeclaration.name()))
return makeUnexpected(Error("Duplicate name in program.", function->codeLocation()));
nativeTypeDeclaration.setNameSpace(m_currentNameSpace);
auto result = m_types[index].add(nativeTypeDeclaration.name(), Vector<std::reference_wrapper<AST::NamedType>, 1>());
result.iterator->value.append(nativeTypeDeclaration);
return { };
}
Expected<void, Error> NameContext::add(AST::VariableDeclaration& variableDeclaration)
{
if (variableDeclaration.name().isNull())
return { };
if (auto* declaration = localExists(variableDeclaration.name()))
return makeUnexpected(Error("Duplicate name in program.", declaration->codeLocation()));
auto result = m_variables.add(String(variableDeclaration.name()), &variableDeclaration);
ASSERT_UNUSED(result, result.isNewEntry);
return { };
}
Vector<std::reference_wrapper<AST::NamedType>, 1> NameContext::getTypes(const String& name, AST::NameSpace fromNamespace)
{
if (m_parent)
return m_parent->getTypes(name, fromNamespace);
Vector<std::reference_wrapper<AST::NamedType>, 1> result;
unsigned index = static_cast<unsigned>(fromNamespace);
auto iterator = m_types[index].find(name);
if (iterator != m_types[index].end()) {
for (auto type : iterator->value)
result.append(type);
}
if (fromNamespace != AST::NameSpace::StandardLibrary) {
index = static_cast<unsigned>(AST::NameSpace::StandardLibrary);
iterator = m_types[index].find(name);
if (iterator != m_types[index].end()) {
for (auto type : iterator->value)
result.append(type);
}
}
return result;
}
Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1> NameContext::getFunctions(const String& name, AST::NameSpace fromNamespace)
{
if (m_parent)
return m_parent->getFunctions(name, fromNamespace);
Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1> result;
unsigned index = static_cast<unsigned>(fromNamespace);
auto iterator = m_functions[index].find(name);
if (iterator != m_functions[index].end()) {
for (auto type : iterator->value)
result.append(type);
}
if (fromNamespace != AST::NameSpace::StandardLibrary) {
index = static_cast<unsigned>(AST::NameSpace::StandardLibrary);
iterator = m_functions[index].find(name);
if (iterator != m_functions[index].end()) {
for (auto type : iterator->value)
result.append(type);
}
}
return result;
}
AST::VariableDeclaration* NameContext::getVariable(const String& name)
{
auto iterator = m_variables.find(name);
if (iterator == m_variables.end()) {
if (m_parent)
return m_parent->getVariable(name);
return nullptr;
}
return iterator->value;
}
AST::NamedType* NameContext::searchTypes(String& name) const
{
ASSERT(!m_parent);
if (m_currentNameSpace == AST::NameSpace::StandardLibrary) {
for (auto& types : m_types) {
auto iter = types.find(name);
if (iter != types.end())
return &iter->value[0].get();
}
return nullptr;
}
auto index = static_cast<unsigned>(m_currentNameSpace);
auto iter = m_types[index].find(name);
if (iter != m_types[index].end())
return &iter->value[0].get();
index = static_cast<unsigned>(AST::NameSpace::StandardLibrary);
iter = m_types[index].find(name);
if (iter != m_types[index].end())
return &iter->value[0].get();
return nullptr;
}
AST::FunctionDeclaration* NameContext::searchFunctions(String& name) const
{
ASSERT(!m_parent);
if (m_currentNameSpace == AST::NameSpace::StandardLibrary) {
for (auto& functions : m_functions) {
auto iter = functions.find(name);
if (iter != functions.end())
return &iter->value[0].get();
}
return nullptr;
}
auto index = static_cast<unsigned>(m_currentNameSpace);
auto iter = m_functions[index].find(name);
if (iter != m_functions[index].end())
return &iter->value[0].get();
index = static_cast<unsigned>(AST::NameSpace::StandardLibrary);
iter = m_functions[index].find(name);
if (iter != m_functions[index].end())
return &iter->value[0].get();
return nullptr;
}
Optional<CodeLocation> NameContext::topLevelExists(String& name) const
{
if (auto* type = searchTypes(name))
return type->codeLocation();
if (auto* function = searchFunctions(name))
return function->codeLocation();
return WTF::nullopt;
}
AST::VariableDeclaration* NameContext::localExists(String& name) const
{
ASSERT(m_parent);
auto iter = m_variables.find(name);
if (iter != m_variables.end())
return iter->value;
return nullptr;
}
}
}
#endif // ENABLE(WEBGPU)