Skip to content

Commit

Permalink
Merge pull request #9364 from ethereum/stopafter
Browse files Browse the repository at this point in the history
Stop after parsing.
  • Loading branch information
chriseth authored Sep 30, 2020
2 parents 5cf84c0 + fda8bde commit 729ffc6
Show file tree
Hide file tree
Showing 76 changed files with 5,449 additions and 115 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Compiler Features:
* SMTChecker: Support ``addmod`` and ``mulmod``.
* Optimizer: Optimize ``exp`` when base is -1.
* Code generator: Implemented events with function type as one of its indexed parameters.
* General: Option to stop compilation after parsing stage. Can be used with ``solc --stop-after parsing``


### 0.7.2 (2020-09-28)
Expand Down
2 changes: 2 additions & 0 deletions docs/using-the-compiler.rst
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ Input Description
// Optional
"settings":
{
// Optional: Stop compilation after the given stage. Currently only "parsing" is valid here
"stopAfter": "parsing",
// Optional: Sorted list of remappings
"remappings": [ ":g=/dir" ],
// Optional: Optimizer settings
Expand Down
54 changes: 34 additions & 20 deletions libsolidity/ast/ASTJsonConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <libsolidity/ast/ASTJsonConverter.h>

#include <libsolidity/ast/AST.h>
#include <libsolidity/ast/TypeProvider.h>

#include <libyul/AsmJsonConverter.h>
#include <libyul/AsmData.h>
Expand Down Expand Up @@ -69,8 +70,9 @@ void addIfSet(std::vector<pair<string, Json::Value>>& _attributes, string const&
namespace solidity::frontend
{

ASTJsonConverter::ASTJsonConverter(bool _legacy, map<string, unsigned> _sourceIndices):
ASTJsonConverter::ASTJsonConverter(bool _legacy, CompilerStack::State _stackState, map<string, unsigned> _sourceIndices):
m_legacy(_legacy),
m_stackState(_stackState),
m_sourceIndices(std::move(_sourceIndices))
{
}
Expand Down Expand Up @@ -204,14 +206,16 @@ void ASTJsonConverter::appendExpressionAttributes(
{
std::vector<pair<string, Json::Value>> exprAttributes = {
make_pair("typeDescriptions", typePointerToJson(_annotation.type)),
make_pair("lValueRequested", _annotation.willBeWrittenTo),
make_pair("argumentTypes", typePointerToJson(_annotation.arguments))
};

addIfSet(exprAttributes, "isLValue", _annotation.isLValue);
addIfSet(exprAttributes, "isPure", _annotation.isPure);
addIfSet(exprAttributes, "isConstant", _annotation.isConstant);

if (m_stackState > CompilerStack::State::ParsedAndImported)
exprAttributes.emplace_back("lValueRequested", _annotation.willBeWrittenTo);

_attributes += exprAttributes;
}

Expand Down Expand Up @@ -260,6 +264,7 @@ bool ASTJsonConverter::visit(SourceUnit const& _node)
addIfSet(attributes, "absolutePath", _node.annotation().path);

setJsonNode(_node, "SourceUnit", std::move(attributes));

return false;
}

Expand All @@ -268,7 +273,7 @@ bool ASTJsonConverter::visit(PragmaDirective const& _node)
Json::Value literals(Json::arrayValue);
for (auto const& literal: _node.literals())
literals.append(literal);
setJsonNode( _node, "PragmaDirective", {
setJsonNode(_node, "PragmaDirective", {
make_pair("literals", std::move(literals))
});
return false;
Expand All @@ -278,7 +283,7 @@ bool ASTJsonConverter::visit(ImportDirective const& _node)
{
std::vector<pair<string, Json::Value>> attributes = {
make_pair("file", _node.path()),
make_pair(m_legacy ? "SourceUnit" : "sourceUnit", nodeId(*_node.annotation().sourceUnit)),
make_pair(m_legacy ? "SourceUnit" : "sourceUnit", idOrNull(_node.annotation().sourceUnit)),
make_pair("scope", idOrNull(_node.scope()))
};

Expand Down Expand Up @@ -395,18 +400,11 @@ bool ASTJsonConverter::visit(OverrideSpecifier const& _node)

bool ASTJsonConverter::visit(FunctionDefinition const& _node)
{
Visibility visibility;
if (_node.isConstructor())
visibility = _node.annotation().contract->abstract() ? Visibility::Internal : Visibility::Public;
else
visibility = _node.visibility();

std::vector<pair<string, Json::Value>> attributes = {
make_pair("name", _node.name()),
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
make_pair("kind", _node.isFree() ? "freeFunction" : TokenTraits::toString(_node.kind())),
make_pair("stateMutability", stateMutabilityToString(_node.stateMutability())),
make_pair("visibility", Declaration::visibilityToString(visibility)),
make_pair("virtual", _node.markedVirtual()),
make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json::nullValue),
make_pair("parameters", toJson(_node.parameterList())),
Expand All @@ -417,7 +415,19 @@ bool ASTJsonConverter::visit(FunctionDefinition const& _node)
make_pair("scope", idOrNull(_node.scope()))
};

if (_node.isPartOfExternalInterface())
optional<Visibility> visibility;
if (_node.isConstructor())
{
if (_node.annotation().contract)
visibility = _node.annotation().contract->abstract() ? Visibility::Internal : Visibility::Public;
}
else
visibility = _node.visibility();

if (visibility)
attributes.emplace_back("visibility", Declaration::visibilityToString(*visibility));

if (_node.isPartOfExternalInterface() && m_stackState > CompilerStack::State::ParsedAndImported)
attributes.emplace_back("functionSelector", _node.externalIdentifierHex());
if (!_node.annotation().baseFunctions.empty())
attributes.emplace_back(make_pair("baseFunctions", getContainerIds(_node.annotation().baseFunctions, true)));
Expand Down Expand Up @@ -718,7 +728,7 @@ bool ASTJsonConverter::visit(Assignment const& _node)
make_pair("rightHandSide", toJson(_node.rightHandSide()))
};
appendExpressionAttributes(attributes, _node.annotation());
setJsonNode( _node, "Assignment", std::move(attributes));
setJsonNode(_node, "Assignment", std::move(attributes));
return false;
}

Expand Down Expand Up @@ -770,15 +780,19 @@ bool ASTJsonConverter::visit(FunctionCall const& _node)
make_pair("tryCall", _node.annotation().tryCall)
};

FunctionCallKind nodeKind = *_node.annotation().kind;

if (m_legacy)
if (_node.annotation().kind.set())
{
attributes.emplace_back("isStructConstructorCall", nodeKind == FunctionCallKind::StructConstructorCall);
attributes.emplace_back("type_conversion", nodeKind == FunctionCallKind::TypeConversion);
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));
}
else
attributes.emplace_back("kind", functionCallKind(nodeKind));

appendExpressionAttributes(attributes, _node.annotation());
setJsonNode(_node, "FunctionCall", std::move(attributes));
return false;
Expand Down
4 changes: 4 additions & 0 deletions libsolidity/ast/ASTJsonConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include <libsolidity/ast/ASTAnnotations.h>
#include <libsolidity/ast/ASTVisitor.h>
#include <libsolidity/interface/CompilerStack.h>
#include <liblangutil/Exceptions.h>

#include <json/json.h>
Expand All @@ -51,9 +52,11 @@ 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<std::string, unsigned> _sourceIndices = std::map<std::string, unsigned>()
);
/// Output the json representation of the AST to _stream.
Expand Down Expand Up @@ -189,6 +192,7 @@ class ASTJsonConverter: public ASTConstVisitor
}

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;
std::map<std::string, unsigned> m_sourceIndices;
Expand Down
4 changes: 3 additions & 1 deletion libsolidity/ast/Types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,9 @@ util::Result<TypePointers> transformParametersToExternal(TypePointers const& _pa

for (auto const& type: _parameters)
{
if (TypePointer ext = type->interfaceType(_inLibrary).get())
if (!type)
return util::Result<TypePointers>::err("Type information not present.");
else if (TypePointer ext = type->interfaceType(_inLibrary).get())
transformed.push_back(ext);
else
return util::Result<TypePointers>::err("Parameter should have external type.");
Expand Down
Loading

0 comments on commit 729ffc6

Please sign in to comment.