1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #include <cmajor/binder/AttributeBinder.hpp>
  7 #include <cmajor/binder/JsonAttributeProcessor.hpp>
  8 #include <cmajor/binder/SystemDefaultAttributeProcessor.hpp>
  9 #include <cmajor/binder/XmlAttributeProcessor.hpp>
 10 #include <cmajor/binder/BoundCompileUnit.hpp>
 11 #include <cmajor/binder/StatementBinder.hpp>
 12 #include <cmajor/symbols/Exception.hpp>
 13 #include <soulng/util/Unicode.hpp>
 14 
 15 namespace cmajor {namespace binder {
 16 
 17 using namespace soulng::unicode;
 18 using namespace cmajor::symbols;
 19 
 20 AttributeProcessor::AttributeProcessor(const std::u32string& attributeName_) : attributeName(attributeName_)
 21 {
 22 }
 23 
 24 AttributeProcessor::~AttributeProcessor()
 25 {
 26 }
 27 
 28 void AttributeProcessor::TypeCheck(AttributeNode* attributeSymbol* symbol)
 29 {
 30     throw Exception("attribute '" + ToUtf8(attribute->Name()) + "' for symbol type '" + symbol->TypeString() + "' not supported"attribute->GetSpan()attribute->ModuleId()
 31         symbol->GetSpan()symbol->SourceModuleId());
 32 }
 33 
 34 void AttributeProcessor::GenerateSymbols(AttributeNode* attributeSymbol* symbolBoundCompileUnit& boundCompileUnitContainerScope* containerScope)
 35 {
 36 }
 37 
 38 void AttributeProcessor::GenerateImplementation(AttributeNode* attributeSymbol* symbolStatementBinder* statementBinder)
 39 {
 40 }
 41 
 42 AttributeBinder::AttributeBinder(Module* module)
 43 {
 44     AttributeProcessor* jsonAttributeProcessor = new JsonAttributeProcessor(module);
 45     attributeProcessors.push_back(std::unique_ptr<AttributeProcessor>(jsonAttributeProcessor));
 46     JsonFieldNameAttributeProcessor* jsonFieldNameAttributeProcessor = new JsonFieldNameAttributeProcessor();
 47     attributeProcessors.push_back(std::unique_ptr<AttributeProcessor>(jsonFieldNameAttributeProcessor));
 48     AttributeProcessor* systemDefaultAttributeProcessor = new SystemDefaultAttributeProcessor();
 49     attributeProcessors.push_back(std::unique_ptr<AttributeProcessor>(systemDefaultAttributeProcessor));
 50     AttributeProcessor* xmlAttributeProcessor = new XmlAttributeProcessor();
 51     attributeProcessors.push_back(std::unique_ptr<AttributeProcessor>(xmlAttributeProcessor));
 52     for (const std::std::unique_ptr<AttributeProcessor>&attributeProcessor : attributeProcessors)
 53     {
 54         attributeProcessorMap[attributeProcessor->AttributeName()] = attributeProcessor.get();
 55     }
 56 }
 57 
 58 void AttributeBinder::BindAttributes(AttributesNode* attrsSymbol* symbolBoundCompileUnit& boundCompileUnitContainerScope* containerScope)
 59 {
 60     if (!attrs) return;
 61     const std::std::vector<std::std::unique_ptr<AttributeNode>>&attributes=attrs->GetAttributes();
 62     for (const std::std::unique_ptr<AttributeNode>&attribute : attributes)
 63     {
 64         const std::u32string& attrName = attribute->Name();
 65         auto it = attributeProcessorMap.find(attrName);
 66         if (it != attributeProcessorMap.cend())
 67         {
 68             AttributeProcessor* processor = it->second;
 69             processor->TypeCheck(attribute.get()symbol);
 70             processor->GenerateSymbols(attribute.get()symbolboundCompileUnitcontainerScope);
 71         }
 72         else
 73         {
 74             throw Exception("unknown attribute '" + ToUtf8(attrName) + "'"attribute->GetSpan()attribute->ModuleId());
 75         }
 76     }
 77     CloneContext cloneContext;
 78     symbol->SetAttributes(std::unique_ptr<AttributesNode>(static_cast<AttributesNode*>(attrs->Clone(cloneContext))));
 79 }
 80 
 81 void AttributeBinder::GenerateImplementation(AttributesNode* attrsSymbol* symbolStatementBinder* statementBinder)
 82 {
 83     if (!attrs) return;
 84     const std::std::vector<std::std::unique_ptr<AttributeNode>>&attributes=attrs->GetAttributes();
 85     for (const std::std::unique_ptr<AttributeNode>&attribute : attributes)
 86     {
 87         const std::u32string& attrName = attribute->Name();
 88         auto it = attributeProcessorMap.find(attrName);
 89         if (it != attributeProcessorMap.cend())
 90         {
 91             AttributeProcessor* processor = it->second;
 92             processor->GenerateImplementation(attribute.get()symbolstatementBinder);
 93         }
 94         else
 95         {
 96             throw Exception("unknown attribute '" + ToUtf8(attrName) + "'"attribute->GetSpan()attribute->ModuleId());
 97         }
 98     }
 99 }
100 
101 } } // namespace cmajor::binder