mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Introduce experimental analysis basic infrastructure
This commit is contained in:
+14
-1
@@ -1019,15 +1019,28 @@ std::tuple<Token, unsigned, unsigned> Scanner::scanIdentifierOrKeyword()
|
||||
while (isIdentifierPart(m_char) || (m_char == '.' && m_kind == ScannerKind::Yul))
|
||||
addLiteralCharAndAdvance();
|
||||
literal.complete();
|
||||
|
||||
auto const token = TokenTraits::fromIdentifierOrKeyword(m_tokens[NextNext].literal);
|
||||
if (m_kind == ScannerKind::Yul)
|
||||
switch (m_kind)
|
||||
{
|
||||
case ScannerKind::Solidity:
|
||||
// Turn experimental Solidity keywords that are not keywords in legacy Solidity into identifiers.
|
||||
if (TokenTraits::isExperimentalSolidityOnlyKeyword(std::get<0>(token)))
|
||||
return std::make_tuple(Token::Identifier, 0, 0);
|
||||
break;
|
||||
case ScannerKind::Yul:
|
||||
// Turn Solidity identifier into a Yul keyword
|
||||
if (m_tokens[NextNext].literal == "leave")
|
||||
return std::make_tuple(Token::Leave, 0, 0);
|
||||
// Turn non-Yul keywords into identifiers.
|
||||
if (!TokenTraits::isYulKeyword(std::get<0>(token)))
|
||||
return std::make_tuple(Token::Identifier, 0, 0);
|
||||
break;
|
||||
case ScannerKind::ExperimentalSolidity:
|
||||
// Turn legacy Solidity keywords that are not keywords in experimental Solidity into identifiers.
|
||||
if (!TokenTraits::isExperimentalSolidityKeyword(std::get<0>(token)))
|
||||
return std::make_tuple(Token::Identifier, 0, 0);
|
||||
break;
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,8 @@ class ParserRecorder;
|
||||
enum class ScannerKind
|
||||
{
|
||||
Solidity,
|
||||
Yul
|
||||
Yul,
|
||||
ExperimentalSolidity
|
||||
};
|
||||
|
||||
enum class ScannerError
|
||||
|
||||
@@ -268,6 +268,8 @@ namespace solidity::langutil
|
||||
/* Yul-specific tokens, but not keywords. */ \
|
||||
T(Leave, "leave", 0) \
|
||||
\
|
||||
T(NonExperimentalEnd, nullptr, 0) /* used as non-experimental enum end marker */ \
|
||||
T(ExperimentalEnd, nullptr, 0) /* used as experimental enum end marker */ \
|
||||
/* Illegal token - not able to scan. */ \
|
||||
T(Illegal, "ILLEGAL", 0) \
|
||||
\
|
||||
@@ -323,6 +325,39 @@ namespace TokenTraits
|
||||
tok == Token::TrueLiteral || tok == Token::FalseLiteral || tok == Token::HexStringLiteral || tok == Token::Hex;
|
||||
}
|
||||
|
||||
constexpr bool isExperimentalSolidityKeyword(Token token)
|
||||
{
|
||||
return
|
||||
token == Token::Assembly ||
|
||||
token == Token::Contract ||
|
||||
token == Token::External ||
|
||||
token == Token::Fallback ||
|
||||
token == Token::Pragma ||
|
||||
token == Token::Import ||
|
||||
token == Token::As ||
|
||||
token == Token::Function ||
|
||||
token == Token::Let ||
|
||||
token == Token::Return ||
|
||||
token == Token::Type ||
|
||||
token == Token::If ||
|
||||
token == Token::Else ||
|
||||
token == Token::Do ||
|
||||
token == Token::While ||
|
||||
token == Token::For ||
|
||||
token == Token::Continue ||
|
||||
token == Token::Break;
|
||||
// TODO: see isExperimentalSolidityKeyword below
|
||||
// || (token > Token::NonExperimentalEnd && token < Token::ExperimentalEnd);
|
||||
}
|
||||
|
||||
constexpr bool isExperimentalSolidityOnlyKeyword(Token)
|
||||
{
|
||||
// TODO: use token > Token::NonExperimentalEnd && token < Token::ExperimentalEnd
|
||||
// as soon as other experimental tokens are added. For now the comparison generates
|
||||
// a warning from clang because it is always false.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isYulKeyword(std::string const& _literal);
|
||||
|
||||
Token AssignmentToBinaryOp(Token op);
|
||||
|
||||
Reference in New Issue
Block a user