mirror of
https://github.com/pocoproject/poco.git
synced 2024-12-12 18:20:26 +01:00
feat(CppParser): C++11 attributes support
This commit is contained in:
parent
ad07839db9
commit
568b0fca8e
@ -32,8 +32,8 @@ class CppParser_API Attributes
|
||||
/// name and values are strings.
|
||||
{
|
||||
public:
|
||||
typedef std::map<std::string, std::string> AttrMap;
|
||||
typedef AttrMap::const_iterator Iterator;
|
||||
using AttrMap = std::map<std::string, std::string>;
|
||||
using Iterator = AttrMap::const_iterator;
|
||||
|
||||
Attributes();
|
||||
/// Creates the Attributes object.
|
||||
|
@ -46,6 +46,8 @@ public:
|
||||
{
|
||||
OP_OPENBRACKET = 1, // [
|
||||
OP_CLOSBRACKET, // ]
|
||||
OP_DBL_OPENBRACKET, // [[
|
||||
OP_DBL_CLOSBRACKET, // ]]
|
||||
OP_OPENPARENT, // (
|
||||
OP_CLOSPARENT, // )
|
||||
OP_OPENBRACE, // {
|
||||
@ -101,7 +103,7 @@ public:
|
||||
int asInteger() const;
|
||||
|
||||
private:
|
||||
typedef std::map<std::string, int> OpMap;
|
||||
using OpMap = std::map<std::string, int>;
|
||||
|
||||
OpMap _opMap;
|
||||
};
|
||||
@ -112,7 +114,7 @@ class CppParser_API IdentifierToken: public CppToken
|
||||
public:
|
||||
enum Keywords
|
||||
{
|
||||
KW_ALIGNAS = 1,
|
||||
KW_ALIGNAS = 100, // Note: start with 100 to avoid overlapping definitions with operators
|
||||
KW_ALIGNOF,
|
||||
KW_AND,
|
||||
KW_AND_EQ,
|
||||
@ -206,7 +208,7 @@ public:
|
||||
int asInteger() const;
|
||||
|
||||
private:
|
||||
typedef std::map<std::string, int> KWMap;
|
||||
using KWMap = std::map<std::string, int>;
|
||||
|
||||
KWMap _kwMap;
|
||||
};
|
||||
|
@ -28,7 +28,7 @@ namespace CppParser {
|
||||
|
||||
class CppParser_API Decl: public Symbol
|
||||
/// This class represents a simple declaration in a C++ source file.
|
||||
/// It is a base class for Function, TypeDef or Variable.
|
||||
/// It is a base class for Function, TypeDef, Using or Variable.
|
||||
{
|
||||
public:
|
||||
Decl(const std::string& decl, NameSpace* pNameSpace);
|
||||
|
@ -37,8 +37,8 @@ class CppParser_API Enum: public Symbol
|
||||
/// a collection of EnumValues.
|
||||
{
|
||||
public:
|
||||
typedef std::vector<EnumValue*> Values;
|
||||
typedef Values::const_iterator Iterator;
|
||||
using Values = std::vector<EnumValue*>;
|
||||
using Iterator = Values::const_iterator;
|
||||
|
||||
enum Flags
|
||||
{
|
||||
|
@ -49,8 +49,8 @@ public:
|
||||
FN_DELETE = 1024 /// The function has been deleted.
|
||||
};
|
||||
|
||||
typedef std::vector<Parameter*> Parameters;
|
||||
typedef Parameters::const_iterator Iterator;
|
||||
using Parameters = std::vector<Parameter*>;
|
||||
using Iterator = Parameters::const_iterator;
|
||||
|
||||
Function(const std::string& decl, NameSpace* pNameSpace);
|
||||
/// Creates the Function.
|
||||
|
@ -33,10 +33,10 @@ class CppParser_API NameSpace: public Symbol
|
||||
/// This class represents a namespace.
|
||||
{
|
||||
public:
|
||||
typedef std::multimap<std::string, Symbol*> SymbolTable;
|
||||
typedef SymbolTable::const_iterator Iterator;
|
||||
typedef std::map<std::string, std::string> AliasMap;
|
||||
typedef std::vector<std::string> NameSpaceVec;
|
||||
using SymbolTable = std::multimap<std::string, Symbol*>;
|
||||
using Iterator = SymbolTable::const_iterator;
|
||||
using AliasMap = std::map<std::string, std::string>;
|
||||
using NameSpaceVec = std::vector<std::string>;
|
||||
|
||||
NameSpace();
|
||||
/// Creates the NameSpace.
|
||||
|
@ -73,7 +73,7 @@ protected:
|
||||
const Poco::Token* parseExtern(const Poco::Token* pNext);
|
||||
const Poco::Token* parseTypeDef(const Poco::Token* pNext);
|
||||
const Poco::Token* parseUsing(const Poco::Token* pNext);
|
||||
const Poco::Token* parseFunc(const Poco::Token* pNext, std::string& decl);
|
||||
const Poco::Token* parseFunc(const Poco::Token* pNext, const std::string& attrs, std::string& decl);
|
||||
const Poco::Token* parseParameters(const Poco::Token* pNext, Function* pFunc);
|
||||
const Poco::Token* parseBlock(const Poco::Token* pNext);
|
||||
const Poco::Token* parseEnum(const Poco::Token* pNext);
|
||||
@ -82,6 +82,7 @@ protected:
|
||||
const Poco::Token* parseClassMembers(const Poco::Token* pNext, Struct* pClass);
|
||||
const Poco::Token* parseAccess(const Poco::Token* pNext);
|
||||
const Poco::Token* parseIdentifier(const Poco::Token* pNext, std::string& id);
|
||||
const Poco::Token* parseAttributes(const Poco::Token* pNext, std::string& attrs);
|
||||
|
||||
void addSymbol(Symbol* pSymbol, int lineNumber, bool addGST = true);
|
||||
void pushNameSpace(NameSpace* pNameSpace, int lineNumber, bool addGST = true);
|
||||
@ -102,7 +103,7 @@ protected:
|
||||
const Poco::Token* nextToken();
|
||||
|
||||
private:
|
||||
typedef std::vector<NameSpace*> NSStack;
|
||||
using NSStack = std::vector<NameSpace*>;
|
||||
|
||||
NameSpace::SymbolTable& _gst;
|
||||
Poco::CountingInputStream _istr;
|
||||
|
@ -51,13 +51,13 @@ public:
|
||||
Struct* pClass;
|
||||
};
|
||||
|
||||
typedef std::vector<Base> BaseClasses;
|
||||
typedef BaseClasses::const_iterator BaseIterator;
|
||||
typedef std::vector<Struct*> StructVec;
|
||||
typedef StructVec::const_iterator DerivedIterator;
|
||||
typedef std::vector<Function*> Functions;
|
||||
typedef std::set<Function*> FunctionSet;
|
||||
typedef std::set<Struct*> StructSet;
|
||||
using BaseClasses = std::vector<Base>;
|
||||
using BaseIterator = BaseClasses::const_iterator;
|
||||
using StructVec = std::vector<Struct*>;
|
||||
using DerivedIterator = StructVec::const_iterator;
|
||||
using Functions = std::vector<Function*>;
|
||||
using FunctionSet = std::set<Function*>;
|
||||
using StructSet = std::set<Struct*>;
|
||||
|
||||
Struct(const std::string& decl, bool isClass, NameSpace* pNameSpace);
|
||||
/// Creates the Struct.
|
||||
|
@ -85,6 +85,13 @@ public:
|
||||
Access getAccess() const;
|
||||
/// Returns the symbol's access.
|
||||
|
||||
void setAttributeList(const std::string& attrs);
|
||||
/// Sets the C++11 attribute list, e.g. "[[noreturn]]".
|
||||
|
||||
const std::string& getAttributeList() const;
|
||||
/// Returns the C++11 attribute list, or an empty string
|
||||
/// if the symbol does not have one.
|
||||
|
||||
void setDocumentation(const std::string& text);
|
||||
/// Sets the symbol's documentation.
|
||||
|
||||
@ -169,6 +176,7 @@ private:
|
||||
std::string _package;
|
||||
std::string _library;
|
||||
Attributes _attrs;
|
||||
std::string _attributeList;
|
||||
|
||||
static int _nextId;
|
||||
};
|
||||
@ -189,6 +197,12 @@ inline const std::string& Symbol::name() const
|
||||
}
|
||||
|
||||
|
||||
inline const std::string& Symbol::getAttributeList() const
|
||||
{
|
||||
return _attributeList;
|
||||
}
|
||||
|
||||
|
||||
inline const std::string& Symbol::getDocumentation() const
|
||||
{
|
||||
return _documentation;
|
||||
|
@ -49,9 +49,11 @@ void CppToken::syntaxError(const std::string& expected, const std::string& actua
|
||||
|
||||
OperatorToken::OperatorToken()
|
||||
{
|
||||
int i = 1;
|
||||
int i = OP_OPENBRACKET;
|
||||
_opMap["["] = i++;
|
||||
_opMap["]"] = i++;
|
||||
_opMap["[["] = i++;
|
||||
_opMap["]]"] = i++;
|
||||
_opMap["("] = i++;
|
||||
_opMap[")"] = i++;
|
||||
_opMap["{"] = i++;
|
||||
@ -159,13 +161,23 @@ void OperatorToken::finish(std::istream& istr)
|
||||
case ')':
|
||||
case '{':
|
||||
case '}':
|
||||
case '[':
|
||||
case ']':
|
||||
case ';':
|
||||
case '?':
|
||||
case '~':
|
||||
case ',':
|
||||
break;
|
||||
case '[':
|
||||
if (next == '[')
|
||||
{
|
||||
_value += (char) istr.get();
|
||||
}
|
||||
break;
|
||||
case ']':
|
||||
if (next == ']')
|
||||
{
|
||||
_value += (char) istr.get();
|
||||
}
|
||||
break;
|
||||
case '.':
|
||||
if (next == '.')
|
||||
{
|
||||
@ -231,7 +243,7 @@ int OperatorToken::asInteger() const
|
||||
|
||||
IdentifierToken::IdentifierToken()
|
||||
{
|
||||
int i = 1;
|
||||
int i = KW_ALIGNAS;
|
||||
_kwMap["alignas"] = i++;
|
||||
_kwMap["alignof"] = i++;
|
||||
_kwMap["and"] = i++;
|
||||
|
@ -39,6 +39,7 @@ using Poco::NumberFormatter;
|
||||
using Poco::SyntaxException;
|
||||
using Poco::icompare;
|
||||
using Poco::trimInPlace;
|
||||
using namespace std::string_literals;
|
||||
|
||||
|
||||
namespace Poco {
|
||||
@ -117,6 +118,8 @@ inline void Parser::append(std::string& decl, const std::string& token)
|
||||
token != "," &&
|
||||
token != "[" &&
|
||||
token != "]" &&
|
||||
token != "[[" &&
|
||||
token != "]]" &&
|
||||
last != '~' &&
|
||||
last != ':' &&
|
||||
last != '(' &&
|
||||
@ -380,7 +383,7 @@ const Token* Parser::parseClassMembers(const Token* pNext, Struct* /*pClass*/)
|
||||
poco_assert (isOperator(pNext, OperatorToken::OP_OPENBRACE));
|
||||
|
||||
pNext = next();
|
||||
while (pNext->is(Token::IDENTIFIER_TOKEN) || pNext->is(Token::KEYWORD_TOKEN) || isOperator(pNext, OperatorToken::OP_COMPL) || isOperator(pNext, OperatorToken::OP_DBL_COLON))
|
||||
while (pNext->is(Token::IDENTIFIER_TOKEN) || pNext->is(Token::KEYWORD_TOKEN) || isOperator(pNext, OperatorToken::OP_COMPL) || isOperator(pNext, OperatorToken::OP_DBL_COLON) || isOperator(pNext, OperatorToken::OP_DBL_OPENBRACKET))
|
||||
{
|
||||
switch (pNext->asInteger())
|
||||
{
|
||||
@ -575,6 +578,11 @@ const Token* Parser::parseVarFunc(const Token* pNext)
|
||||
const Token* Parser::parseVarFunc(const Token* pNext, std::string& decl)
|
||||
{
|
||||
_pCurrentSymbol = 0;
|
||||
std::string attrs;
|
||||
if (isOperator(pNext, OperatorToken::OP_DBL_OPENBRACKET))
|
||||
{
|
||||
pNext = parseAttributes(pNext, attrs);
|
||||
}
|
||||
if (isKeyword(pNext, IdentifierToken::KW_EXTERN))
|
||||
{
|
||||
pNext = parseExtern(pNext);
|
||||
@ -596,6 +604,7 @@ const Token* Parser::parseVarFunc(const Token* pNext, std::string& decl)
|
||||
if (!currentNameSpace()->lookup(name))
|
||||
{
|
||||
Variable* pVar = new Variable(decl, currentNameSpace());
|
||||
pVar->setAttributeList(attrs);
|
||||
addSymbol(pVar, static_cast<int>(_istr.getCurrentLineNumber()));
|
||||
}
|
||||
pNext = next();
|
||||
@ -611,7 +620,7 @@ const Token* Parser::parseVarFunc(const Token* pNext, std::string& decl)
|
||||
pNext = next();
|
||||
expectOperator(pNext, OperatorToken::OP_OPENPARENT, "(");
|
||||
}
|
||||
pNext = parseFunc(pNext, decl);
|
||||
pNext = parseFunc(pNext, attrs, decl);
|
||||
}
|
||||
}
|
||||
_pCurrentSymbol = 0;
|
||||
@ -641,7 +650,7 @@ const Token* Parser::parseExtern(const Token* pNext)
|
||||
}
|
||||
|
||||
|
||||
const Token* Parser::parseFunc(const Token* pNext, std::string& decl)
|
||||
const Token* Parser::parseFunc(const Token* pNext, const std::string& attrs, std::string& decl)
|
||||
{
|
||||
poco_assert (isOperator(pNext, OperatorToken::OP_OPENPARENT));
|
||||
|
||||
@ -651,6 +660,7 @@ const Token* Parser::parseFunc(const Token* pNext, std::string& decl)
|
||||
if (name.find(':') == std::string::npos)
|
||||
{
|
||||
pFunc = new Function(decl, currentNameSpace());
|
||||
pFunc->setAttributeList(attrs);
|
||||
addSymbol(pFunc, line);
|
||||
}
|
||||
pNext = parseParameters(pNext, pFunc);
|
||||
@ -909,6 +919,25 @@ const Token* Parser::parseIdentifier(const Token* pNext, std::string& id)
|
||||
}
|
||||
|
||||
|
||||
const Poco::Token* Parser::parseAttributes(const Poco::Token* pNext, std::string& attrs)
|
||||
{
|
||||
poco_assert (isOperator(pNext, OperatorToken::OP_DBL_OPENBRACKET));
|
||||
append(attrs, pNext);
|
||||
pNext = next();
|
||||
while (pNext && !isOperator(pNext, OperatorToken::OP_DBL_CLOSBRACKET))
|
||||
{
|
||||
append(attrs, pNext);
|
||||
pNext = next();
|
||||
}
|
||||
if (pNext)
|
||||
{
|
||||
append(attrs, pNext);
|
||||
pNext = next();
|
||||
}
|
||||
return pNext;
|
||||
}
|
||||
|
||||
|
||||
void Parser::addSymbol(Symbol* pSymbol, int lineNumber, bool addGST)
|
||||
{
|
||||
pSymbol->setLineNumber(lineNumber);
|
||||
|
@ -59,6 +59,12 @@ void Symbol::setAccess(Access access)
|
||||
}
|
||||
|
||||
|
||||
void Symbol::setAttributeList(const std::string& attrs)
|
||||
{
|
||||
_attributeList = attrs;
|
||||
}
|
||||
|
||||
|
||||
void Symbol::setDocumentation(const std::string& text)
|
||||
{
|
||||
_documentation = text;
|
||||
|
Loading…
Reference in New Issue
Block a user