diff --git a/Changelog.md b/Changelog.md index f084baf39..cd79af81f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,7 +4,9 @@ Breaking Changes: * Assembler: The artificial ASSIGNIMMUTABLE opcode and the corresponding builtin in the "EVM with object access" dialect of Yul take the base offset of the code to modify as additional argument. * Code Generator: All arithmetic is checked by default. These checks can be disabled using ``unchecked { ... }``. * Code Generator: Cause a panic if a byte array in storage is accessed whose length is encoded incorrectly. + * Command Line Interface: Remove the legacy ``--ast-json`` option. Only the ``--ast-compact-json`` option is supported now. * General: Remove global functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4``. + * Standard JSON: Remove the ``legacyAST`` option. * Type Checker: Function call options can only be given once. * Type System: Unary negation can only be used on signed integers, not on unsigned integers. * Type System: Disallow explicit conversions from negative literals and literals larger than ``type(uint160).max`` to ``address`` type. diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 7adf712cf..5ae2bd934 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -327,7 +327,6 @@ Input Description // // File level (needs empty string as contract name): // ast - AST of all source files - // legacyAST - legacy AST of all source files // // Contract level (needs the contract name or "*"): // abi - ABI @@ -430,8 +429,6 @@ Output Description "id": 1, // The AST object "ast": {}, - // The legacy AST object - "legacyAST": {} } }, // This contains the contract-level outputs. diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp index 6c574e39a..ef066a803 100644 --- a/libsolidity/ast/ASTJsonConverter.cpp +++ b/libsolidity/ast/ASTJsonConverter.cpp @@ -70,8 +70,7 @@ void addIfSet(std::vector>& _attributes, string const& namespace solidity::frontend { -ASTJsonConverter::ASTJsonConverter(bool _legacy, CompilerStack::State _stackState, map _sourceIndices): - m_legacy(_legacy), +ASTJsonConverter::ASTJsonConverter(CompilerStack::State _stackState, map _sourceIndices): m_stackState(_stackState), m_sourceIndices(std::move(_sourceIndices)) { @@ -100,60 +99,9 @@ void ASTJsonConverter::setJsonNode( m_currentValue = Json::objectValue; m_currentValue["id"] = nodeId(_node); m_currentValue["src"] = sourceLocationToString(_node.location()); - if (!m_legacy) - { - m_currentValue["nodeType"] = _nodeType; - for (auto& e: _attributes) - m_currentValue[e.first] = std::move(e.second); - } - else - { - m_currentValue["name"] = _nodeType; - Json::Value attrs(Json::objectValue); - if ( - //these nodeTypes need to have a children-node even if it is empty - (_nodeType == "VariableDeclaration") || - (_nodeType == "ParameterList") || - (_nodeType == "Block") || - (_nodeType == "InlineAssembly") || - (_nodeType == "Throw") - ) - m_currentValue["children"] = Json::arrayValue; - - for (auto& e: _attributes) - { - if ((!e.second.isNull()) && ( - (e.second.isObject() && e.second.isMember("name")) || - (e.second.isArray() && e.second[0].isObject() && e.second[0].isMember("name")) || - (e.first == "declarations") // (in the case (_,x)= ... there's a nullpointer at [0] - )) - { - if (e.second.isObject()) - { - if (!m_currentValue["children"].isArray()) - m_currentValue["children"] = Json::arrayValue; - appendMove(m_currentValue["children"], std::move(e.second)); - } - if (e.second.isArray()) - for (auto& child: e.second) - if (!child.isNull()) - { - if (!m_currentValue["children"].isArray()) - m_currentValue["children"] = Json::arrayValue; - appendMove(m_currentValue["children"], std::move(child)); - } - } - else - { - if (e.first == "typeDescriptions") - attrs["type"] = Json::Value(e.second["typeString"]); - else - attrs[e.first] = std::move(e.second); - } - } - if (!attrs.empty()) - m_currentValue["attributes"] = std::move(attrs); - } + m_currentValue["nodeType"] = _nodeType; + for (auto& e: _attributes) + m_currentValue[e.first] = std::move(e.second); } size_t ASTJsonConverter::sourceIndexFromLocation(SourceLocation const& _location) const @@ -285,7 +233,7 @@ bool ASTJsonConverter::visit(ImportDirective const& _node) { std::vector> attributes = { make_pair("file", _node.path()), - make_pair(m_legacy ? "SourceUnit" : "sourceUnit", idOrNull(_node.annotation().sourceUnit)), + make_pair("sourceUnit", idOrNull(_node.annotation().sourceUnit)), make_pair("scope", idOrNull(_node.scope())) }; @@ -442,8 +390,6 @@ bool ASTJsonConverter::visit(FunctionDefinition const& _node) attributes.emplace_back("functionSelector", _node.externalIdentifierHex()); if (!_node.annotation().baseFunctions.empty()) attributes.emplace_back(make_pair("baseFunctions", getContainerIds(_node.annotation().baseFunctions, true))); - if (m_legacy) - attributes.emplace_back("isConstructor", _node.isConstructor()); setJsonNode(_node, "FunctionDefinition", std::move(attributes)); return false; } @@ -586,9 +532,7 @@ bool ASTJsonConverter::visit(InlineAssembly const& _node) externalReferencesJson.append(std::move(it.second)); setJsonNode(_node, "InlineAssembly", { - m_legacy ? - make_pair("operations", Json::Value(yul::AsmPrinter()(_node.operations()))) : - make_pair("AST", Json::Value(yul::AsmJsonConverter(sourceIndexFromLocation(_node.location()))(_node.operations()))), + make_pair("AST", Json::Value(yul::AsmJsonConverter(sourceIndexFromLocation(_node.location()))(_node.operations()))), make_pair("externalReferences", std::move(externalReferencesJson)), make_pair("evmVersion", dynamic_cast(_node.dialect()).evmVersion().name()) }); @@ -794,14 +738,7 @@ bool ASTJsonConverter::visit(FunctionCall const& _node) if (_node.annotation().kind.set()) { FunctionCallKind nodeKind = *_node.annotation().kind; - - if (m_legacy) - { - attributes.emplace_back("isStructConstructorCall", nodeKind == FunctionCallKind::StructConstructorCall); - attributes.emplace_back("type_conversion", nodeKind == FunctionCallKind::TypeConversion); - } - else - attributes.emplace_back("kind", functionCallKind(nodeKind)); + attributes.emplace_back("kind", functionCallKind(nodeKind)); } appendExpressionAttributes(attributes, _node.annotation()); @@ -839,7 +776,7 @@ bool ASTJsonConverter::visit(NewExpression const& _node) bool ASTJsonConverter::visit(MemberAccess const& _node) { std::vector> attributes = { - make_pair(m_legacy ? "member_name" : "memberName", _node.memberName()), + make_pair("memberName", _node.memberName()), make_pair("expression", toJson(_node.expression())), make_pair("referencedDeclaration", idOrNull(_node.annotation().referencedDeclaration)), }; @@ -877,7 +814,7 @@ bool ASTJsonConverter::visit(Identifier const& _node) for (auto const& dec: _node.annotation().overloadedDeclarations) overloads.append(nodeId(*dec)); setJsonNode(_node, "Identifier", { - make_pair(m_legacy ? "value" : "name", _node.name()), + make_pair("name", _node.name()), make_pair("referencedDeclaration", idOrNull(_node.annotation().referencedDeclaration)), make_pair("overloadedDeclarations", overloads), make_pair("typeDescriptions", typePointerToJson(_node.annotation().type)), @@ -889,7 +826,7 @@ bool ASTJsonConverter::visit(Identifier const& _node) bool ASTJsonConverter::visit(ElementaryTypeNameExpression const& _node) { std::vector> attributes = { - make_pair(m_legacy ? "value" : "typeName", toJson(_node.type())) + make_pair("typeName", toJson(_node.type())) }; appendExpressionAttributes(attributes, _node.annotation()); setJsonNode(_node, "ElementaryTypeNameExpression", std::move(attributes)); @@ -903,9 +840,9 @@ bool ASTJsonConverter::visit(Literal const& _node) value = Json::nullValue; Token subdenomination = Token(_node.subDenomination()); std::vector> attributes = { - make_pair(m_legacy ? "token" : "kind", literalTokenKind(_node.token())), + make_pair("kind", literalTokenKind(_node.token())), make_pair("value", value), - make_pair(m_legacy ? "hexvalue" : "hexValue", util::toHex(util::asBytes(_node.value()))), + make_pair("hexValue", util::toHex(util::asBytes(_node.value()))), make_pair( "subdenomination", subdenomination == Token::Illegal ? diff --git a/libsolidity/ast/ASTJsonConverter.h b/libsolidity/ast/ASTJsonConverter.h index 59cd7dafb..641383e00 100644 --- a/libsolidity/ast/ASTJsonConverter.h +++ b/libsolidity/ast/ASTJsonConverter.h @@ -51,11 +51,9 @@ class ASTJsonConverter: public ASTConstVisitor { public: /// Create a converter to JSON for the given abstract syntax tree. - /// @a _legacy if true, use legacy format /// @a _stackState state of the compiler stack to avoid outputting incomplete data /// @a _sourceIndices is used to abbreviate source names in source locations. explicit ASTJsonConverter( - bool _legacy, CompilerStack::State _stackState, std::map _sourceIndices = std::map() ); @@ -192,7 +190,6 @@ private: _array.append(std::move(_value)); } - bool m_legacy = false; ///< if true, use legacy format CompilerStack::State m_stackState = CompilerStack::State::Empty; ///< Used to only access information that already exists bool m_inEvent = false; ///< whether we are currently inside an event or not Json::Value m_currentValue; diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index f3ba7db35..fd4f23487 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1086,9 +1086,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting Json::Value sourceResult = Json::objectValue; sourceResult["id"] = sourceIndex++; if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, "", "ast", wildcardMatchesExperimental)) - sourceResult["ast"] = ASTJsonConverter(false, compilerStack.state(), compilerStack.sourceIndices()).toJson(compilerStack.ast(sourceName)); - if (isArtifactRequested(_inputsAndSettings.outputSelection, sourceName, "", "legacyAST", wildcardMatchesExperimental)) - sourceResult["legacyAST"] = ASTJsonConverter(true, compilerStack.state(), compilerStack.sourceIndices()).toJson(compilerStack.ast(sourceName)); + sourceResult["ast"] = ASTJsonConverter(compilerStack.state(), compilerStack.sourceIndices()).toJson(compilerStack.ast(sourceName)); output["sources"][sourceName] = sourceResult; } diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index b74cc224f..842da5ecc 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -1679,11 +1679,10 @@ void CommandLineInterface::handleCombinedJSON() if (requests.count(g_strAst)) { - bool legacyFormat = !requests.count(g_strCompactJSON); output[g_strSources] = Json::Value(Json::objectValue); for (auto const& sourceCode: m_sourceCodes) { - ASTJsonConverter converter(legacyFormat, m_compiler->state(), m_compiler->sourceIndices()); + ASTJsonConverter converter(m_compiler->state(), m_compiler->sourceIndices()); output[g_strSources][sourceCode.first] = Json::Value(Json::objectValue); output[g_strSources][sourceCode.first]["AST"] = converter.toJson(m_compiler->ast(sourceCode.first)); } @@ -1698,45 +1697,34 @@ void CommandLineInterface::handleCombinedJSON() sout() << json << endl; } -void CommandLineInterface::handleAst(string const& _argStr) +void CommandLineInterface::handleAst() { - string title; + if (!m_args.count(g_argAstCompactJson)) + return; - if (_argStr == g_argAstJson) - title = "JSON AST:"; - else if (_argStr == g_argAstCompactJson) - title = "JSON AST (compact format):"; - else - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Illegal argStr for AST")); + vector asts; + for (auto const& sourceCode: m_sourceCodes) + asts.push_back(&m_compiler->ast(sourceCode.first)); - // do we need AST output? - if (m_args.count(_argStr)) + if (m_args.count(g_argOutputDir)) { - vector asts; for (auto const& sourceCode: m_sourceCodes) - asts.push_back(&m_compiler->ast(sourceCode.first)); - - bool legacyFormat = !m_args.count(g_argAstCompactJson); - if (m_args.count(g_argOutputDir)) { - for (auto const& sourceCode: m_sourceCodes) - { - stringstream data; - string postfix = ""; - ASTJsonConverter(legacyFormat, m_compiler->state(), m_compiler->sourceIndices()).print(data, m_compiler->ast(sourceCode.first)); - postfix += "_json"; - boost::filesystem::path path(sourceCode.first); - createFile(path.filename().string() + postfix + ".ast", data.str()); - } + stringstream data; + string postfix = ""; + ASTJsonConverter(m_compiler->state(), m_compiler->sourceIndices()).print(data, m_compiler->ast(sourceCode.first)); + postfix += "_json"; + boost::filesystem::path path(sourceCode.first); + createFile(path.filename().string() + postfix + ".ast", data.str()); } - else + } + else + { + sout() << "JSON AST (compact format):" << endl << endl; + for (auto const& sourceCode: m_sourceCodes) { - sout() << title << endl << endl; - for (auto const& sourceCode: m_sourceCodes) - { - sout() << endl << "======= " << sourceCode.first << " =======" << endl; - ASTJsonConverter(legacyFormat, m_compiler->state(), m_compiler->sourceIndices()).print(sout(), m_compiler->ast(sourceCode.first)); - } + sout() << endl << "======= " << sourceCode.first << " =======" << endl; + ASTJsonConverter(m_compiler->state(), m_compiler->sourceIndices()).print(sout(), m_compiler->ast(sourceCode.first)); } } } @@ -2002,8 +1990,7 @@ void CommandLineInterface::outputCompilationResults() handleCombinedJSON(); // do we need AST output? - handleAst(g_argAstJson); - handleAst(g_argAstCompactJson); + handleAst(); if ( !m_compiler->compilationSuccessful() && diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index f7abb0524..d68fc587f 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -67,7 +67,7 @@ private: void outputCompilationResults(); void handleCombinedJSON(); - void handleAst(std::string const& _argStr); + void handleAst(); void handleBinary(std::string const& _contract); void handleOpcode(std::string const& _contract); void handleIR(std::string const& _contract); diff --git a/test/libsolidity/ASTJSONTest.h b/test/libsolidity/ASTJSONTest.h index c01235631..4e9f3881d 100644 --- a/test/libsolidity/ASTJSONTest.h +++ b/test/libsolidity/ASTJSONTest.h @@ -68,7 +68,6 @@ private: std::string m_expectationParseOnly; std::string m_astFilename; std::string m_astParseOnlyFilename; - std::string m_legacyAstFilename; std::string m_result; std::string m_resultLegacy; std::string m_resultParseOnly;