mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9428 from ethereum/removeVar
Remove special treatment of ``var``.
This commit is contained in:
commit
10f93fbd8a
@ -25,6 +25,7 @@ Language Features:
|
||||
* Inheritance: Allow overrides to have stricter state mutability: ``view`` can override ``nonpayable`` and ``pure`` can override ``view``.
|
||||
|
||||
Compiler Features:
|
||||
* Variable declarations using the ``var`` keyword are not recognized anymore.
|
||||
|
||||
|
||||
Bugfixes:
|
||||
|
@ -189,7 +189,6 @@ namespace solidity::langutil
|
||||
K(Throw, "throw", 0) \
|
||||
K(Type, "type", 0) \
|
||||
K(Using, "using", 0) \
|
||||
K(Var, "var", 0) \
|
||||
K(View, "view", 0) \
|
||||
K(Virtual, "virtual", 0) \
|
||||
K(While, "while", 0) \
|
||||
@ -265,6 +264,7 @@ namespace solidity::langutil
|
||||
K(Typedef, "typedef", 0) \
|
||||
K(TypeOf, "typeof", 0) \
|
||||
K(Unchecked, "unchecked", 0) \
|
||||
K(Var, "var", 0) \
|
||||
\
|
||||
/* Illegal token - not able to scan. */ \
|
||||
T(Illegal, "ILLEGAL", 0) \
|
||||
|
@ -293,15 +293,6 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable)
|
||||
"The \"immutable\" keyword can only be used for state variables."
|
||||
);
|
||||
|
||||
if (!_variable.typeName())
|
||||
{
|
||||
// This can still happen in very unusual cases where a developer uses constructs, such as
|
||||
// `var a;`, however, such code will have generated errors already.
|
||||
// However, we cannot blindingly solAssert() for that here, as the TypeChecker (which is
|
||||
// invoking ReferencesResolver) is generating it, so the error is most likely(!) generated
|
||||
// after this step.
|
||||
return;
|
||||
}
|
||||
using Location = VariableDeclaration::Location;
|
||||
Location varLoc = _variable.referenceLocation();
|
||||
DataLocation typeLoc = DataLocation::Memory;
|
||||
@ -382,7 +373,7 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable)
|
||||
solAssert(!_variable.hasReferenceOrMappingType(), "Data location not properly set.");
|
||||
}
|
||||
|
||||
TypePointer type = _variable.typeName()->annotation().type;
|
||||
TypePointer type = _variable.typeName().annotation().type;
|
||||
if (auto ref = dynamic_cast<ReferenceType const*>(type))
|
||||
{
|
||||
bool isPointer = !_variable.isStateVariable();
|
||||
|
@ -466,8 +466,7 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
|
||||
|
||||
bool TypeChecker::visit(VariableDeclaration const& _variable)
|
||||
{
|
||||
if (_variable.typeName())
|
||||
_variable.typeName()->accept(*this);
|
||||
_variable.typeName().accept(*this);
|
||||
|
||||
// type is filled either by ReferencesResolver directly from the type name or by
|
||||
// TypeChecker at the VariableDeclarationStatement level.
|
||||
@ -591,15 +590,11 @@ bool TypeChecker::visit(VariableDeclaration const& _variable)
|
||||
if (_variable.isStateVariable())
|
||||
m_errorReporter.warning(3408_error, _variable.location(), collisionMessage(_variable.name(), true));
|
||||
else
|
||||
m_errorReporter.warning(
|
||||
2332_error,
|
||||
_variable.typeName() ? _variable.typeName()->location() : _variable.location(),
|
||||
collisionMessage(varType->canonicalName(), false)
|
||||
);
|
||||
m_errorReporter.warning(2332_error, _variable.typeName().location(), collisionMessage(varType->canonicalName(), false));
|
||||
}
|
||||
vector<Type const*> oversizedSubtypes = frontend::oversizedSubtypes(*varType);
|
||||
for (Type const* subtype: oversizedSubtypes)
|
||||
m_errorReporter.warning(7325_error, _variable.typeName()->location(), collisionMessage(subtype->canonicalName(), false));
|
||||
m_errorReporter.warning(7325_error, _variable.typeName().location(), collisionMessage(subtype->canonicalName(), false));
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -1106,81 +1101,23 @@ void TypeChecker::endVisit(EmitStatement const& _emit)
|
||||
m_errorReporter.typeError(9292_error, _emit.eventCall().expression().location(), "Expression has to be an event invocation.");
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
/**
|
||||
* @returns a suggested left-hand-side of a multi-variable declaration contairing
|
||||
* the variable declarations given in @a _decls.
|
||||
*/
|
||||
string createTupleDecl(vector<ASTPointer<VariableDeclaration>> const& _decls)
|
||||
{
|
||||
vector<string> components;
|
||||
for (ASTPointer<VariableDeclaration> const& decl: _decls)
|
||||
if (decl)
|
||||
{
|
||||
solAssert(decl->annotation().type, "");
|
||||
components.emplace_back(decl->annotation().type->toString(false) + " " + decl->name());
|
||||
}
|
||||
else
|
||||
components.emplace_back();
|
||||
|
||||
if (_decls.size() == 1)
|
||||
return components.front();
|
||||
else
|
||||
return "(" + boost::algorithm::join(components, ", ") + ")";
|
||||
}
|
||||
|
||||
bool typeCanBeExpressed(vector<ASTPointer<VariableDeclaration>> const& decls)
|
||||
{
|
||||
for (ASTPointer<VariableDeclaration> const& decl: decls)
|
||||
{
|
||||
// skip empty tuples (they can be expressed of course)
|
||||
if (!decl)
|
||||
continue;
|
||||
|
||||
if (!decl->annotation().type)
|
||||
return false;
|
||||
|
||||
if (auto functionType = dynamic_cast<FunctionType const*>(decl->annotation().type))
|
||||
if (
|
||||
functionType->kind() != FunctionType::Kind::Internal &&
|
||||
functionType->kind() != FunctionType::Kind::External
|
||||
)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
|
||||
{
|
||||
if (!_statement.initialValue())
|
||||
{
|
||||
// No initial value is only permitted for single variables with specified type.
|
||||
// This usually already results in a parser error.
|
||||
if (_statement.declarations().size() != 1 || !_statement.declarations().front())
|
||||
{
|
||||
if (std::all_of(
|
||||
_statement.declarations().begin(),
|
||||
_statement.declarations().end(),
|
||||
[](ASTPointer<VariableDeclaration> const& declaration) { return declaration == nullptr; }
|
||||
))
|
||||
{
|
||||
// The syntax checker has already generated an error for this case (empty LHS tuple).
|
||||
solAssert(m_errorReporter.hasErrors(), "");
|
||||
solAssert(m_errorReporter.hasErrors(), "");
|
||||
|
||||
// It is okay to return here, as there are no named components on the
|
||||
// left-hand-side that could cause any damage later.
|
||||
return false;
|
||||
}
|
||||
else
|
||||
// Bailing out *fatal* here, as those (untyped) vars may be used later, and diagnostics wouldn't be helpful then.
|
||||
m_errorReporter.fatalTypeError(4626_error, _statement.location(), "Use of the \"var\" keyword is disallowed.");
|
||||
// It is okay to return here, as there are no named components on the
|
||||
// left-hand-side that could cause any damage later.
|
||||
return false;
|
||||
}
|
||||
|
||||
VariableDeclaration const& varDecl = *_statement.declarations().front();
|
||||
if (!varDecl.annotation().type)
|
||||
m_errorReporter.fatalTypeError(6983_error, _statement.location(), "Use of the \"var\" keyword is disallowed.");
|
||||
solAssert(varDecl.annotation().type, "");
|
||||
|
||||
if (dynamic_cast<MappingType const*>(type(varDecl)))
|
||||
m_errorReporter.typeError(
|
||||
@ -1217,8 +1154,6 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
|
||||
")."
|
||||
);
|
||||
|
||||
bool autoTypeDeductionNeeded = false;
|
||||
|
||||
for (size_t i = 0; i < min(variables.size(), valueTypes.size()); ++i)
|
||||
{
|
||||
if (!variables[i])
|
||||
@ -1227,95 +1162,45 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
|
||||
solAssert(!var.value(), "Value has to be tied to statement.");
|
||||
TypePointer const& valueComponentType = valueTypes[i];
|
||||
solAssert(!!valueComponentType, "");
|
||||
if (!var.annotation().type)
|
||||
{
|
||||
autoTypeDeductionNeeded = true;
|
||||
solAssert(var.annotation().type, "");
|
||||
|
||||
// Infer type from value.
|
||||
solAssert(!var.typeName(), "");
|
||||
var.annotation().type = valueComponentType->mobileType();
|
||||
if (!var.annotation().type)
|
||||
{
|
||||
if (valueComponentType->category() == Type::Category::RationalNumber)
|
||||
m_errorReporter.fatalTypeError(
|
||||
6963_error,
|
||||
_statement.initialValue()->location(),
|
||||
"Invalid rational " +
|
||||
valueComponentType->toString() +
|
||||
" (absolute value too large or division by zero)."
|
||||
);
|
||||
else
|
||||
solAssert(false, "");
|
||||
}
|
||||
else if (*var.annotation().type == *TypeProvider::emptyTuple())
|
||||
solAssert(false, "Cannot declare variable with void (empty tuple) type.");
|
||||
else if (valueComponentType->category() == Type::Category::RationalNumber)
|
||||
{
|
||||
string typeName = var.annotation().type->toString(true);
|
||||
string extension;
|
||||
if (auto type = dynamic_cast<IntegerType const*>(var.annotation().type))
|
||||
{
|
||||
unsigned numBits = type->numBits();
|
||||
bool isSigned = type->isSigned();
|
||||
solAssert(numBits > 0, "");
|
||||
string minValue;
|
||||
string maxValue;
|
||||
if (isSigned)
|
||||
{
|
||||
numBits--;
|
||||
minValue = "-" + bigint(bigint(1) << numBits).str();
|
||||
}
|
||||
else
|
||||
minValue = "0";
|
||||
maxValue = bigint((bigint(1) << numBits) - 1).str();
|
||||
extension = ", which can hold values between " + minValue + " and " + maxValue;
|
||||
}
|
||||
else
|
||||
solAssert(dynamic_cast<FixedPointType const*>(var.annotation().type), "Unknown type.");
|
||||
}
|
||||
|
||||
var.accept(*this);
|
||||
}
|
||||
else
|
||||
var.accept(*this);
|
||||
BoolResult result = valueComponentType->isImplicitlyConvertibleTo(*var.annotation().type);
|
||||
if (!result)
|
||||
{
|
||||
var.accept(*this);
|
||||
BoolResult result = valueComponentType->isImplicitlyConvertibleTo(*var.annotation().type);
|
||||
if (!result)
|
||||
auto errorMsg = "Type " +
|
||||
valueComponentType->toString() +
|
||||
" is not implicitly convertible to expected type " +
|
||||
var.annotation().type->toString();
|
||||
if (
|
||||
valueComponentType->category() == Type::Category::RationalNumber &&
|
||||
dynamic_cast<RationalNumberType const&>(*valueComponentType).isFractional() &&
|
||||
valueComponentType->mobileType()
|
||||
)
|
||||
{
|
||||
auto errorMsg = "Type " +
|
||||
valueComponentType->toString() +
|
||||
" is not implicitly convertible to expected type " +
|
||||
var.annotation().type->toString();
|
||||
if (
|
||||
valueComponentType->category() == Type::Category::RationalNumber &&
|
||||
dynamic_cast<RationalNumberType const&>(*valueComponentType).isFractional() &&
|
||||
valueComponentType->mobileType()
|
||||
)
|
||||
{
|
||||
if (var.annotation().type->operator==(*valueComponentType->mobileType()))
|
||||
m_errorReporter.typeError(
|
||||
5107_error,
|
||||
_statement.location(),
|
||||
errorMsg + ", but it can be explicitly converted."
|
||||
);
|
||||
else
|
||||
m_errorReporter.typeError(
|
||||
4486_error,
|
||||
_statement.location(),
|
||||
errorMsg +
|
||||
". Try converting to type " +
|
||||
valueComponentType->mobileType()->toString() +
|
||||
" or use an explicit conversion."
|
||||
);
|
||||
}
|
||||
else
|
||||
m_errorReporter.typeErrorConcatenateDescriptions(
|
||||
9574_error,
|
||||
if (var.annotation().type->operator==(*valueComponentType->mobileType()))
|
||||
m_errorReporter.typeError(
|
||||
5107_error,
|
||||
_statement.location(),
|
||||
errorMsg + ".",
|
||||
result.message()
|
||||
errorMsg + ", but it can be explicitly converted."
|
||||
);
|
||||
else
|
||||
m_errorReporter.typeError(
|
||||
4486_error,
|
||||
_statement.location(),
|
||||
errorMsg +
|
||||
". Try converting to type " +
|
||||
valueComponentType->mobileType()->toString() +
|
||||
" or use an explicit conversion."
|
||||
);
|
||||
}
|
||||
else
|
||||
m_errorReporter.typeErrorConcatenateDescriptions(
|
||||
9574_error,
|
||||
_statement.location(),
|
||||
errorMsg + ".",
|
||||
result.message()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1327,24 +1212,6 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
|
||||
BOOST_THROW_EXCEPTION(FatalError());
|
||||
}
|
||||
|
||||
if (autoTypeDeductionNeeded)
|
||||
{
|
||||
if (!typeCanBeExpressed(variables))
|
||||
m_errorReporter.syntaxError(
|
||||
3478_error,
|
||||
_statement.location(),
|
||||
"Use of the \"var\" keyword is disallowed. "
|
||||
"Type cannot be expressed in syntax."
|
||||
);
|
||||
else
|
||||
m_errorReporter.syntaxError(
|
||||
1719_error,
|
||||
_statement.location(),
|
||||
"Use of the \"var\" keyword is disallowed. "
|
||||
"Use explicit declaration `" + createTupleDecl(variables) + " = ...´ instead."
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -614,9 +614,8 @@ bool VariableDeclaration::isEventParameter() const
|
||||
|
||||
bool VariableDeclaration::hasReferenceOrMappingType() const
|
||||
{
|
||||
solAssert(typeName(), "");
|
||||
solAssert(typeName()->annotation().type, "Can only be called after reference resolution");
|
||||
Type const* type = typeName()->annotation().type;
|
||||
solAssert(typeName().annotation().type, "Can only be called after reference resolution");
|
||||
Type const* type = typeName().annotation().type;
|
||||
return type->category() == Type::Category::Mapping || dynamic_cast<ReferenceType const*>(type);
|
||||
}
|
||||
|
||||
@ -642,22 +641,8 @@ set<VariableDeclaration::Location> VariableDeclaration::allowedDataLocations() c
|
||||
return locations;
|
||||
}
|
||||
else if (isLocalVariable())
|
||||
{
|
||||
solAssert(typeName(), "");
|
||||
auto dataLocations = [](TypePointer _type, auto&& _recursion) -> set<Location> {
|
||||
solAssert(_type, "Can only be called after reference resolution");
|
||||
switch (_type->category())
|
||||
{
|
||||
case Type::Category::Array:
|
||||
return _recursion(dynamic_cast<ArrayType const*>(_type)->baseType(), _recursion);
|
||||
case Type::Category::Mapping:
|
||||
return set<Location>{ Location::Storage };
|
||||
default:
|
||||
return set<Location>{ Location::Memory, Location::Storage, Location::CallData };
|
||||
}
|
||||
};
|
||||
return dataLocations(typeName()->annotation().type, dataLocations);
|
||||
}
|
||||
// Further restrictions will be imposed later on.
|
||||
return set<Location>{ Location::Memory, Location::Storage, Location::CallData };
|
||||
else
|
||||
// Struct members etc.
|
||||
return set<Location>{ Location::Unspecified };
|
||||
|
@ -895,13 +895,16 @@ public:
|
||||
m_isIndexed(_isIndexed),
|
||||
m_mutability(_mutability),
|
||||
m_overrides(std::move(_overrides)),
|
||||
m_location(_referenceLocation) {}
|
||||
m_location(_referenceLocation)
|
||||
{
|
||||
solAssert(m_typeName, "");
|
||||
}
|
||||
|
||||
|
||||
void accept(ASTVisitor& _visitor) override;
|
||||
void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
TypeName* typeName() const { return m_typeName.get(); }
|
||||
TypeName const& typeName() const { return *m_typeName; }
|
||||
ASTPointer<Expression> const& value() const { return m_value; }
|
||||
|
||||
bool isLValue() const override;
|
||||
@ -964,7 +967,7 @@ protected:
|
||||
Visibility defaultVisibility() const override { return Visibility::Internal; }
|
||||
|
||||
private:
|
||||
ASTPointer<TypeName> m_typeName; ///< can be empty ("var")
|
||||
ASTPointer<TypeName> m_typeName;
|
||||
/// Initially assigned value, can be missing. For local variables, this is stored inside
|
||||
/// VariableDeclarationStatement and not here.
|
||||
ASTPointer<Expression> m_value;
|
||||
|
@ -386,7 +386,7 @@ bool ASTJsonConverter::visit(VariableDeclaration const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
make_pair("name", _node.name()),
|
||||
make_pair("typeName", toJsonOrNull(_node.typeName())),
|
||||
make_pair("typeName", toJson(_node.typeName())),
|
||||
make_pair("constant", _node.isConstant()),
|
||||
make_pair("mutability", VariableDeclaration::mutabilityToString(_node.mutability())),
|
||||
make_pair("stateVariable", _node.isStateVariable()),
|
||||
|
@ -677,16 +677,10 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
|
||||
RecursionGuard recursionGuard(*this);
|
||||
ASTNodeFactory nodeFactory = _lookAheadArrayType ?
|
||||
ASTNodeFactory(*this, _lookAheadArrayType) : ASTNodeFactory(*this);
|
||||
ASTPointer<TypeName> type;
|
||||
|
||||
ASTPointer<StructuredDocumentation> const documentation = parseStructuredDocumentation();
|
||||
if (_lookAheadArrayType)
|
||||
type = _lookAheadArrayType;
|
||||
else
|
||||
{
|
||||
type = parseTypeName(_options.allowVar);
|
||||
if (type != nullptr)
|
||||
nodeFactory.setEndPositionFromNode(type);
|
||||
}
|
||||
ASTPointer<TypeName> type = _lookAheadArrayType ? _lookAheadArrayType : parseTypeName();
|
||||
nodeFactory.setEndPositionFromNode(type);
|
||||
|
||||
if (!_options.isStateVariable && documentation != nullptr)
|
||||
parserError(2837_error, "Only state variables can have a docstring.");
|
||||
@ -753,8 +747,6 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
|
||||
{
|
||||
if (location != VariableDeclaration::Location::Unspecified)
|
||||
parserError(3548_error, "Location already specified.");
|
||||
else if (!type)
|
||||
parserError(7439_error, "Location specifier needs explicit type name.");
|
||||
else
|
||||
{
|
||||
switch (token)
|
||||
@ -781,10 +773,7 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
|
||||
}
|
||||
|
||||
if (_options.allowEmptyName && m_scanner->currentToken() != Token::Identifier)
|
||||
{
|
||||
identifier = make_shared<ASTString>("");
|
||||
solAssert(!_options.allowVar, ""); // allowEmptyName && allowVar makes no sense
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeFactory.markEndPosition();
|
||||
@ -908,7 +897,7 @@ ASTPointer<UsingForDirective> Parser::parseUsingDirective()
|
||||
if (m_scanner->currentToken() == Token::Mul)
|
||||
m_scanner->next();
|
||||
else
|
||||
typeName = parseTypeName(false);
|
||||
typeName = parseTypeName();
|
||||
nodeFactory.markEndPosition();
|
||||
expectToken(Token::Semicolon);
|
||||
return nodeFactory.createNode<UsingForDirective>(library, typeName);
|
||||
@ -971,7 +960,7 @@ ASTPointer<TypeName> Parser::parseTypeNameSuffix(ASTPointer<TypeName> type, ASTN
|
||||
return type;
|
||||
}
|
||||
|
||||
ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
|
||||
ASTPointer<TypeName> Parser::parseTypeName()
|
||||
{
|
||||
RecursionGuard recursionGuard(*this);
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
@ -1004,12 +993,6 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
|
||||
}
|
||||
type = nodeFactory.createNode<ElementaryTypeName>(elemTypeName, stateMutability);
|
||||
}
|
||||
else if (token == Token::Var)
|
||||
{
|
||||
if (!_allowVar)
|
||||
parserError(7059_error, "Expected explicit type name.");
|
||||
m_scanner->next();
|
||||
}
|
||||
else if (token == Token::Function)
|
||||
type = parseFunctionType();
|
||||
else if (token == Token::Mapping)
|
||||
@ -1019,9 +1002,10 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
|
||||
else
|
||||
fatalParserError(3546_error, "Expected type name");
|
||||
|
||||
if (type)
|
||||
// Parse "[...]" postfixes for arrays.
|
||||
type = parseTypeNameSuffix(type, nodeFactory);
|
||||
solAssert(type, "");
|
||||
// Parse "[...]" postfixes for arrays.
|
||||
type = parseTypeNameSuffix(type, nodeFactory);
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
@ -1062,8 +1046,7 @@ ASTPointer<Mapping> Parser::parseMapping()
|
||||
else
|
||||
fatalParserError(1005_error, "Expected elementary type name or identifier for mapping key type");
|
||||
expectToken(Token::Arrow);
|
||||
bool const allowVar = false;
|
||||
ASTPointer<TypeName> valueType = parseTypeName(allowVar);
|
||||
ASTPointer<TypeName> valueType = parseTypeName();
|
||||
nodeFactory.markEndPosition();
|
||||
expectToken(Token::RParen);
|
||||
return nodeFactory.createNode<Mapping>(keyType, valueType);
|
||||
@ -1544,53 +1527,14 @@ ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStateme
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
if (_lookAheadArrayType)
|
||||
nodeFactory.setLocation(_lookAheadArrayType->location());
|
||||
|
||||
VarDeclParserOptions options;
|
||||
options.allowLocationSpecifier = true;
|
||||
vector<ASTPointer<VariableDeclaration>> variables;
|
||||
variables.emplace_back(parseVariableDeclaration(options, _lookAheadArrayType));
|
||||
nodeFactory.setEndPositionFromNode(variables.back());
|
||||
|
||||
ASTPointer<Expression> value;
|
||||
if (
|
||||
!_lookAheadArrayType &&
|
||||
m_scanner->currentToken() == Token::Var &&
|
||||
m_scanner->peekNextToken() == Token::LParen
|
||||
)
|
||||
{
|
||||
// Parse `var (a, b, ,, c) = ...` into a single VariableDeclarationStatement with multiple variables.
|
||||
m_scanner->next();
|
||||
m_scanner->next();
|
||||
if (m_scanner->currentToken() != Token::RParen)
|
||||
while (true)
|
||||
{
|
||||
ASTPointer<VariableDeclaration> var;
|
||||
if (
|
||||
m_scanner->currentToken() != Token::Comma &&
|
||||
m_scanner->currentToken() != Token::RParen
|
||||
)
|
||||
{
|
||||
ASTNodeFactory varDeclNodeFactory(*this);
|
||||
varDeclNodeFactory.markEndPosition();
|
||||
ASTPointer<ASTString> name = expectIdentifierToken();
|
||||
var = varDeclNodeFactory.createNode<VariableDeclaration>(
|
||||
ASTPointer<TypeName>(),
|
||||
name,
|
||||
ASTPointer<Expression>(),
|
||||
Visibility::Default
|
||||
);
|
||||
}
|
||||
variables.push_back(var);
|
||||
if (m_scanner->currentToken() == Token::RParen)
|
||||
break;
|
||||
else
|
||||
expectToken(Token::Comma);
|
||||
}
|
||||
nodeFactory.markEndPosition();
|
||||
m_scanner->next();
|
||||
}
|
||||
else
|
||||
{
|
||||
VarDeclParserOptions options;
|
||||
options.allowVar = true;
|
||||
options.allowLocationSpecifier = true;
|
||||
variables.push_back(parseVariableDeclaration(options, _lookAheadArrayType));
|
||||
nodeFactory.setEndPositionFromNode(variables.back());
|
||||
}
|
||||
if (m_scanner->currentToken() == Token::Assign)
|
||||
{
|
||||
m_scanner->next();
|
||||
@ -1704,11 +1648,8 @@ ASTPointer<Expression> Parser::parseLeftHandSideExpression(
|
||||
else if (m_scanner->currentToken() == Token::New)
|
||||
{
|
||||
expectToken(Token::New);
|
||||
ASTPointer<TypeName> typeName(parseTypeName(false));
|
||||
if (typeName)
|
||||
nodeFactory.setEndPositionFromNode(typeName);
|
||||
else
|
||||
nodeFactory.markEndPosition();
|
||||
ASTPointer<TypeName> typeName(parseTypeName());
|
||||
nodeFactory.setEndPositionFromNode(typeName);
|
||||
expression = nodeFactory.createNode<NewExpression>(typeName);
|
||||
}
|
||||
else if (m_scanner->currentToken() == Token::Payable)
|
||||
@ -2048,7 +1989,7 @@ Parser::LookAheadInfo Parser::peekStatementType() const
|
||||
Token token(m_scanner->currentToken());
|
||||
bool mightBeTypeName = (TokenTraits::isElementaryTypeName(token) || token == Token::Identifier);
|
||||
|
||||
if (token == Token::Mapping || token == Token::Function || token == Token::Var)
|
||||
if (token == Token::Mapping || token == Token::Function)
|
||||
return LookAheadInfo::VariableDeclaration;
|
||||
if (mightBeTypeName)
|
||||
{
|
||||
|
@ -57,7 +57,6 @@ private:
|
||||
// https://stackoverflow.com/questions/17430377
|
||||
VarDeclParserOptions() {}
|
||||
|
||||
bool allowVar = false;
|
||||
bool isStateVariable = false;
|
||||
bool allowIndexed = false;
|
||||
bool allowEmptyName = false;
|
||||
@ -107,7 +106,7 @@ private:
|
||||
ASTPointer<Identifier> parseIdentifier();
|
||||
ASTPointer<UserDefinedTypeName> parseUserDefinedTypeName();
|
||||
ASTPointer<TypeName> parseTypeNameSuffix(ASTPointer<TypeName> type, ASTNodeFactory& nodeFactory);
|
||||
ASTPointer<TypeName> parseTypeName(bool _allowVar);
|
||||
ASTPointer<TypeName> parseTypeName();
|
||||
ASTPointer<FunctionTypeName> parseFunctionType();
|
||||
ASTPointer<Mapping> parseMapping();
|
||||
ASTPointer<ParameterList> parseParameterList(
|
||||
|
@ -4,10 +4,10 @@
|
||||
{
|
||||
"C":
|
||||
[
|
||||
8
|
||||
9
|
||||
]
|
||||
},
|
||||
"id": 9,
|
||||
"id": 10,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes":
|
||||
[
|
||||
@ -17,10 +17,10 @@
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"fullyImplemented": true,
|
||||
"id": 8,
|
||||
"id": 9,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
8
|
||||
9
|
||||
],
|
||||
"name": "C",
|
||||
"nodeType": "ContractDefinition",
|
||||
@ -29,48 +29,60 @@
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"id": 6,
|
||||
"id": 7,
|
||||
"nodeType": "Block",
|
||||
"src": "33:20:1",
|
||||
"src": "33:30:1",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"assignments":
|
||||
[
|
||||
3
|
||||
4
|
||||
],
|
||||
"declarations":
|
||||
[
|
||||
{
|
||||
"constant": false,
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"mutability": "mutable",
|
||||
"name": "x",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 6,
|
||||
"src": "35:5:1",
|
||||
"scope": 7,
|
||||
"src": "35:15:1",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"storageLocation": "memory",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_string_memory_ptr",
|
||||
"typeString": "string"
|
||||
},
|
||||
"typeName":
|
||||
{
|
||||
"id": 3,
|
||||
"name": "string",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "35:6:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_string_storage_ptr",
|
||||
"typeString": "string"
|
||||
}
|
||||
},
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"id": 5,
|
||||
"id": 6,
|
||||
"initialValue":
|
||||
{
|
||||
"hexValue": "ff",
|
||||
"id": 4,
|
||||
"id": 5,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "string",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "43:7:1",
|
||||
"src": "53:7:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_stringliteral_8b1a944cf13a9a1c08facb2c9e98623ef3254d2ddb48113885c3e8e97fec8db9",
|
||||
@ -78,12 +90,12 @@
|
||||
}
|
||||
},
|
||||
"nodeType": "VariableDeclarationStatement",
|
||||
"src": "35:15:1"
|
||||
"src": "35:25:1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"functionSelector": "26121ff0",
|
||||
"id": 7,
|
||||
"id": 8,
|
||||
"implemented": true,
|
||||
"kind": "function",
|
||||
"modifiers": [],
|
||||
@ -103,16 +115,16 @@
|
||||
"parameters": [],
|
||||
"src": "33:0:1"
|
||||
},
|
||||
"scope": 8,
|
||||
"src": "13:40:1",
|
||||
"scope": 9,
|
||||
"src": "13:50:1",
|
||||
"stateMutability": "nonpayable",
|
||||
"virtual": false,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 9,
|
||||
"src": "0:55:1"
|
||||
"scope": 10,
|
||||
"src": "0:65:1"
|
||||
}
|
||||
],
|
||||
"src": "0:56:1"
|
||||
"src": "0:66:1"
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
contract C { function f() public { var x = hex"ff"; } }
|
||||
contract C { function f() public { string memory x = hex"ff"; } }
|
||||
|
||||
// ----
|
||||
|
@ -6,7 +6,7 @@
|
||||
{
|
||||
"C":
|
||||
[
|
||||
8
|
||||
9
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -28,10 +28,10 @@
|
||||
"fullyImplemented": true,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
8
|
||||
9
|
||||
],
|
||||
"name": "C",
|
||||
"scope": 9
|
||||
"scope": 10
|
||||
},
|
||||
"children":
|
||||
[
|
||||
@ -47,7 +47,7 @@
|
||||
null
|
||||
],
|
||||
"name": "f",
|
||||
"scope": 8,
|
||||
"scope": 9,
|
||||
"stateMutability": "nonpayable",
|
||||
"virtual": false,
|
||||
"visibility": "public"
|
||||
@ -88,7 +88,7 @@
|
||||
{
|
||||
"assignments":
|
||||
[
|
||||
3
|
||||
4
|
||||
]
|
||||
},
|
||||
"children":
|
||||
@ -99,16 +99,28 @@
|
||||
"constant": false,
|
||||
"mutability": "mutable",
|
||||
"name": "x",
|
||||
"scope": 6,
|
||||
"scope": 7,
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"storageLocation": "memory",
|
||||
"type": "string",
|
||||
"visibility": "internal"
|
||||
},
|
||||
"children": [],
|
||||
"id": 3,
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"name": "string",
|
||||
"type": "string"
|
||||
},
|
||||
"id": 3,
|
||||
"name": "ElementaryTypeName",
|
||||
"src": "35:6:1"
|
||||
}
|
||||
],
|
||||
"id": 4,
|
||||
"name": "VariableDeclaration",
|
||||
"src": "35:5:1"
|
||||
"src": "35:15:1"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
@ -121,32 +133,32 @@
|
||||
"token": "string",
|
||||
"type": "literal_string (contains invalid UTF-8 sequence at position 0)"
|
||||
},
|
||||
"id": 4,
|
||||
"id": 5,
|
||||
"name": "Literal",
|
||||
"src": "43:7:1"
|
||||
"src": "53:7:1"
|
||||
}
|
||||
],
|
||||
"id": 5,
|
||||
"id": 6,
|
||||
"name": "VariableDeclarationStatement",
|
||||
"src": "35:15:1"
|
||||
"src": "35:25:1"
|
||||
}
|
||||
],
|
||||
"id": 6,
|
||||
"id": 7,
|
||||
"name": "Block",
|
||||
"src": "33:20:1"
|
||||
"src": "33:30:1"
|
||||
}
|
||||
],
|
||||
"id": 7,
|
||||
"id": 8,
|
||||
"name": "FunctionDefinition",
|
||||
"src": "13:40:1"
|
||||
"src": "13:50:1"
|
||||
}
|
||||
],
|
||||
"id": 8,
|
||||
"id": 9,
|
||||
"name": "ContractDefinition",
|
||||
"src": "0:55:1"
|
||||
"src": "0:65:1"
|
||||
}
|
||||
],
|
||||
"id": 9,
|
||||
"id": 10,
|
||||
"name": "SourceUnit",
|
||||
"src": "0:56:1"
|
||||
"src": "0:66:1"
|
||||
}
|
||||
|
@ -4,10 +4,10 @@
|
||||
{
|
||||
"C":
|
||||
[
|
||||
11
|
||||
12
|
||||
]
|
||||
},
|
||||
"id": 12,
|
||||
"id": 13,
|
||||
"nodeType": "SourceUnit",
|
||||
"nodes":
|
||||
[
|
||||
@ -17,10 +17,10 @@
|
||||
"contractDependencies": [],
|
||||
"contractKind": "contract",
|
||||
"fullyImplemented": true,
|
||||
"id": 11,
|
||||
"id": 12,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
11
|
||||
12
|
||||
],
|
||||
"name": "C",
|
||||
"nodeType": "ContractDefinition",
|
||||
@ -29,48 +29,60 @@
|
||||
{
|
||||
"body":
|
||||
{
|
||||
"id": 9,
|
||||
"id": 10,
|
||||
"nodeType": "Block",
|
||||
"src": "26:19:1",
|
||||
"src": "26:20:1",
|
||||
"statements":
|
||||
[
|
||||
{
|
||||
"assignments":
|
||||
[
|
||||
3
|
||||
4
|
||||
],
|
||||
"declarations":
|
||||
[
|
||||
{
|
||||
"constant": false,
|
||||
"id": 3,
|
||||
"id": 4,
|
||||
"mutability": "mutable",
|
||||
"name": "x",
|
||||
"nodeType": "VariableDeclaration",
|
||||
"scope": 9,
|
||||
"src": "28:5:1",
|
||||
"scope": 10,
|
||||
"src": "28:6:1",
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_uint8",
|
||||
"typeString": "uint8"
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
},
|
||||
"typeName":
|
||||
{
|
||||
"id": 3,
|
||||
"name": "uint",
|
||||
"nodeType": "ElementaryTypeName",
|
||||
"src": "28:4:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"visibility": "internal"
|
||||
}
|
||||
],
|
||||
"id": 5,
|
||||
"id": 6,
|
||||
"initialValue":
|
||||
{
|
||||
"hexValue": "32",
|
||||
"id": 4,
|
||||
"id": 5,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": true,
|
||||
"kind": "number",
|
||||
"lValueRequested": false,
|
||||
"nodeType": "Literal",
|
||||
"src": "36:1:1",
|
||||
"src": "37:1:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_rational_2_by_1",
|
||||
@ -79,12 +91,12 @@
|
||||
"value": "2"
|
||||
},
|
||||
"nodeType": "VariableDeclarationStatement",
|
||||
"src": "28:9:1"
|
||||
"src": "28:10:1"
|
||||
},
|
||||
{
|
||||
"expression":
|
||||
{
|
||||
"id": 7,
|
||||
"id": 8,
|
||||
"isConstant": false,
|
||||
"isLValue": false,
|
||||
"isPure": false,
|
||||
@ -92,35 +104,35 @@
|
||||
"nodeType": "UnaryOperation",
|
||||
"operator": "++",
|
||||
"prefix": false,
|
||||
"src": "39:3:1",
|
||||
"src": "40:3:1",
|
||||
"subExpression":
|
||||
{
|
||||
"id": 6,
|
||||
"id": 7,
|
||||
"name": "x",
|
||||
"nodeType": "Identifier",
|
||||
"overloadedDeclarations": [],
|
||||
"referencedDeclaration": 3,
|
||||
"src": "39:1:1",
|
||||
"referencedDeclaration": 4,
|
||||
"src": "40:1:1",
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_uint8",
|
||||
"typeString": "uint8"
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"typeDescriptions":
|
||||
{
|
||||
"typeIdentifier": "t_uint8",
|
||||
"typeString": "uint8"
|
||||
"typeIdentifier": "t_uint256",
|
||||
"typeString": "uint256"
|
||||
}
|
||||
},
|
||||
"id": 8,
|
||||
"id": 9,
|
||||
"nodeType": "ExpressionStatement",
|
||||
"src": "39:3:1"
|
||||
"src": "40:3:1"
|
||||
}
|
||||
]
|
||||
},
|
||||
"functionSelector": "26121ff0",
|
||||
"id": 10,
|
||||
"id": 11,
|
||||
"implemented": true,
|
||||
"kind": "function",
|
||||
"modifiers": [],
|
||||
@ -140,16 +152,16 @@
|
||||
"parameters": [],
|
||||
"src": "26:0:1"
|
||||
},
|
||||
"scope": 11,
|
||||
"src": "13:32:1",
|
||||
"scope": 12,
|
||||
"src": "13:33:1",
|
||||
"stateMutability": "nonpayable",
|
||||
"virtual": false,
|
||||
"visibility": "public"
|
||||
}
|
||||
],
|
||||
"scope": 12,
|
||||
"src": "0:47:1"
|
||||
"scope": 13,
|
||||
"src": "0:48:1"
|
||||
}
|
||||
],
|
||||
"src": "0:48:1"
|
||||
"src": "0:49:1"
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
contract C { function f() { var x = 2; x++; } }
|
||||
contract C { function f() { uint x = 2; x++; } }
|
||||
|
||||
// ----
|
||||
|
@ -6,7 +6,7 @@
|
||||
{
|
||||
"C":
|
||||
[
|
||||
11
|
||||
12
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -28,10 +28,10 @@
|
||||
"fullyImplemented": true,
|
||||
"linearizedBaseContracts":
|
||||
[
|
||||
11
|
||||
12
|
||||
],
|
||||
"name": "C",
|
||||
"scope": 12
|
||||
"scope": 13
|
||||
},
|
||||
"children":
|
||||
[
|
||||
@ -47,7 +47,7 @@
|
||||
null
|
||||
],
|
||||
"name": "f",
|
||||
"scope": 11,
|
||||
"scope": 12,
|
||||
"stateMutability": "nonpayable",
|
||||
"virtual": false,
|
||||
"visibility": "public"
|
||||
@ -88,7 +88,7 @@
|
||||
{
|
||||
"assignments":
|
||||
[
|
||||
3
|
||||
4
|
||||
]
|
||||
},
|
||||
"children":
|
||||
@ -99,16 +99,28 @@
|
||||
"constant": false,
|
||||
"mutability": "mutable",
|
||||
"name": "x",
|
||||
"scope": 9,
|
||||
"scope": 10,
|
||||
"stateVariable": false,
|
||||
"storageLocation": "default",
|
||||
"type": "uint8",
|
||||
"type": "uint256",
|
||||
"visibility": "internal"
|
||||
},
|
||||
"children": [],
|
||||
"id": 3,
|
||||
"children":
|
||||
[
|
||||
{
|
||||
"attributes":
|
||||
{
|
||||
"name": "uint",
|
||||
"type": "uint256"
|
||||
},
|
||||
"id": 3,
|
||||
"name": "ElementaryTypeName",
|
||||
"src": "28:4:1"
|
||||
}
|
||||
],
|
||||
"id": 4,
|
||||
"name": "VariableDeclaration",
|
||||
"src": "28:5:1"
|
||||
"src": "28:6:1"
|
||||
},
|
||||
{
|
||||
"attributes":
|
||||
@ -122,14 +134,14 @@
|
||||
"type": "int_const 2",
|
||||
"value": "2"
|
||||
},
|
||||
"id": 4,
|
||||
"id": 5,
|
||||
"name": "Literal",
|
||||
"src": "36:1:1"
|
||||
"src": "37:1:1"
|
||||
}
|
||||
],
|
||||
"id": 5,
|
||||
"id": 6,
|
||||
"name": "VariableDeclarationStatement",
|
||||
"src": "28:9:1"
|
||||
"src": "28:10:1"
|
||||
},
|
||||
{
|
||||
"children":
|
||||
@ -143,7 +155,7 @@
|
||||
"lValueRequested": false,
|
||||
"operator": "++",
|
||||
"prefix": false,
|
||||
"type": "uint8"
|
||||
"type": "uint256"
|
||||
},
|
||||
"children":
|
||||
[
|
||||
@ -154,41 +166,41 @@
|
||||
[
|
||||
null
|
||||
],
|
||||
"referencedDeclaration": 3,
|
||||
"type": "uint8",
|
||||
"referencedDeclaration": 4,
|
||||
"type": "uint256",
|
||||
"value": "x"
|
||||
},
|
||||
"id": 6,
|
||||
"id": 7,
|
||||
"name": "Identifier",
|
||||
"src": "39:1:1"
|
||||
"src": "40:1:1"
|
||||
}
|
||||
],
|
||||
"id": 7,
|
||||
"id": 8,
|
||||
"name": "UnaryOperation",
|
||||
"src": "39:3:1"
|
||||
"src": "40:3:1"
|
||||
}
|
||||
],
|
||||
"id": 8,
|
||||
"id": 9,
|
||||
"name": "ExpressionStatement",
|
||||
"src": "39:3:1"
|
||||
"src": "40:3:1"
|
||||
}
|
||||
],
|
||||
"id": 9,
|
||||
"id": 10,
|
||||
"name": "Block",
|
||||
"src": "26:19:1"
|
||||
"src": "26:20:1"
|
||||
}
|
||||
],
|
||||
"id": 10,
|
||||
"id": 11,
|
||||
"name": "FunctionDefinition",
|
||||
"src": "13:32:1"
|
||||
"src": "13:33:1"
|
||||
}
|
||||
],
|
||||
"id": 11,
|
||||
"id": 12,
|
||||
"name": "ContractDefinition",
|
||||
"src": "0:47:1"
|
||||
"src": "0:48:1"
|
||||
}
|
||||
],
|
||||
"id": 12,
|
||||
"id": 13,
|
||||
"name": "SourceUnit",
|
||||
"src": "0:48:1"
|
||||
"src": "0:49:1"
|
||||
}
|
||||
|
@ -253,7 +253,7 @@ BOOST_AUTO_TEST_CASE(natspec_comment_in_function_body)
|
||||
contract test {
|
||||
/// fun1 description
|
||||
function fun1(uint256 a) {
|
||||
var b;
|
||||
uint b;
|
||||
// I should not interfere with actual natspec comments (natspec comments on local variables not allowed anymore)
|
||||
uint256 c;
|
||||
mapping(address=>bytes32) d;
|
||||
@ -285,7 +285,7 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_between_keyword_and_signature)
|
||||
uint256 stateVar;
|
||||
function ///I am in the wrong place
|
||||
fun1(uint256 a) {
|
||||
var b;
|
||||
uint b;
|
||||
// I should not interfere with actual natspec comments (natspec comments on local variables not allowed anymore)
|
||||
uint256 c;
|
||||
mapping(address=>bytes32) d;
|
||||
@ -311,7 +311,7 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_after_signature)
|
||||
uint256 stateVar;
|
||||
function fun1(uint256 a) {
|
||||
// I should have been above the function signature (natspec comments on local variables not allowed anymore)
|
||||
var b;
|
||||
uint b;
|
||||
// I should not interfere with actual natspec comments (natspec comments on local variables not allowed anymore)
|
||||
uint256 c;
|
||||
mapping(address=>bytes32) d;
|
||||
@ -334,7 +334,7 @@ BOOST_AUTO_TEST_CASE(variable_definition)
|
||||
char const* text = R"(
|
||||
contract test {
|
||||
function fun(uint256 a) {
|
||||
var b;
|
||||
uint b;
|
||||
uint256 c;
|
||||
mapping(address=>bytes32) d;
|
||||
customtype varname;
|
||||
@ -349,7 +349,7 @@ BOOST_AUTO_TEST_CASE(variable_definition_with_initialization)
|
||||
char const* text = R"(
|
||||
contract test {
|
||||
function fun(uint256 a) {
|
||||
var b = 2;
|
||||
uint b = 2;
|
||||
uint256 c = 0x87;
|
||||
mapping(address=>bytes32) d;
|
||||
bytes7 name = "Solidity";
|
||||
@ -403,7 +403,7 @@ BOOST_AUTO_TEST_CASE(type_conversion_to_dynamic_array)
|
||||
char const* text = R"(
|
||||
contract test {
|
||||
function fun() {
|
||||
var x = uint64[](3);
|
||||
uint x = uint64[](3);
|
||||
}
|
||||
}
|
||||
)";
|
||||
|
@ -1,8 +1,8 @@
|
||||
contract C
|
||||
{
|
||||
function f ( ) public {
|
||||
var i = ( ( 1 ( 3 ) ) , 2 );
|
||||
( ( 1 ( 3 ) ) , 2 );
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 5704: (61-68): Type is not callable
|
||||
// TypeError 5704: (53-60): Type is not callable
|
||||
|
@ -4,4 +4,4 @@
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 6651: (91-136): Data location must be "storage" for variable, but "memory" was given.
|
||||
// TypeError 4061: (91-136): Type mapping(string => uint24)[1] is only valid in storage because it contains a (nested) mapping.
|
||||
|
@ -4,12 +4,11 @@ contract b {
|
||||
}
|
||||
|
||||
c d;
|
||||
function e() public {
|
||||
var d = d;
|
||||
function e() public view {
|
||||
c storage x = d;
|
||||
x.a[0];
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning 2519: (105-110): This declaration shadows an existing declaration.
|
||||
// Warning 3408: (66-69): Variable "d" covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.
|
||||
// Warning 2332: (105-110): Type "b.c" covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.
|
||||
// SyntaxError 1719: (105-114): Use of the "var" keyword is disallowed. Use explicit declaration `struct b.c storage pointer d = ...´ instead.
|
||||
// Warning 2332: (110-111): Type "b.c" covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.
|
||||
|
@ -4,4 +4,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 6651: (47-77): Data location must be "storage" for variable, but "memory" was given.
|
||||
// TypeError 4061: (47-77): Type mapping(uint256 => uint256)[] is only valid in storage because it contains a (nested) mapping.
|
||||
|
@ -2,8 +2,8 @@ contract C {
|
||||
struct S { uint a; uint b; mapping(uint=>uint) c; }
|
||||
|
||||
function f() public {
|
||||
S memory s = S({a: 1});
|
||||
S({a: 1});
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 9515: (117-126): Struct containing a (nested) mapping cannot be constructed.
|
||||
// TypeError 9515: (104-113): Struct containing a (nested) mapping cannot be constructed.
|
||||
|
@ -2,4 +2,4 @@ contract Foo {
|
||||
function f() { var memory x; }
|
||||
}
|
||||
// ----
|
||||
// ParserError 7439: (35-41): Location specifier needs explicit type name.
|
||||
// ParserError 6933: (31-34): Expected primary expression.
|
||||
|
@ -4,4 +4,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// ParserError 7059: (35-38): Expected explicit type name.
|
||||
// ParserError 3546: (35-38): Expected type name
|
||||
|
@ -1,25 +0,0 @@
|
||||
contract C {
|
||||
function f() returns(var) {}
|
||||
function f() returns(var x) {}
|
||||
function f() returns(var x, uint y) {}
|
||||
function f() returns(uint x, var y) {}
|
||||
function f() returns(var x, var y) {}
|
||||
function f() public pure returns (var storage) {}
|
||||
function f() public pure returns (var storage x) {}
|
||||
function f() public pure returns (var storage x, var storage y) {}
|
||||
}
|
||||
// ----
|
||||
// ParserError 7059: (38-41): Expected explicit type name.
|
||||
// ParserError 7059: (71-74): Expected explicit type name.
|
||||
// ParserError 7059: (106-109): Expected explicit type name.
|
||||
// ParserError 7059: (157-160): Expected explicit type name.
|
||||
// ParserError 7059: (192-195): Expected explicit type name.
|
||||
// ParserError 7059: (199-202): Expected explicit type name.
|
||||
// ParserError 7059: (247-250): Expected explicit type name.
|
||||
// ParserError 7439: (251-258): Location specifier needs explicit type name.
|
||||
// ParserError 7059: (301-304): Expected explicit type name.
|
||||
// ParserError 7439: (305-312): Location specifier needs explicit type name.
|
||||
// ParserError 7059: (357-360): Expected explicit type name.
|
||||
// ParserError 7439: (361-368): Location specifier needs explicit type name.
|
||||
// ParserError 7059: (372-375): Expected explicit type name.
|
||||
// ParserError 7439: (376-383): Location specifier needs explicit type name.
|
@ -1,7 +1,7 @@
|
||||
contract C {
|
||||
function f() {
|
||||
var a = (2 2);
|
||||
uint a = (2 2);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// ParserError 2314: (42-43): Expected ',' but got 'Number'
|
||||
// ParserError 2314: (43-44): Expected ',' but got 'Number'
|
||||
|
@ -2,4 +2,4 @@ contract Foo {
|
||||
function f() { var[] a; }
|
||||
}
|
||||
// ----
|
||||
// ParserError 2314: (34-35): Expected identifier but got '['
|
||||
// ParserError 6933: (31-34): Expected primary expression.
|
||||
|
@ -1,25 +0,0 @@
|
||||
contract C {
|
||||
function f(var) public pure {}
|
||||
function f(var x) public pure {}
|
||||
function f(var x, var y) public pure {}
|
||||
function f(uint x, var y) public pure {}
|
||||
function f(var x, uint y) public pure {}
|
||||
function f(var storage) public pure {}
|
||||
function f(var storage x) public pure {}
|
||||
function f(var storage x, var storage y) public pure {}
|
||||
}
|
||||
// ----
|
||||
// ParserError 7059: (28-31): Expected explicit type name.
|
||||
// ParserError 7059: (63-66): Expected explicit type name.
|
||||
// ParserError 7059: (100-103): Expected explicit type name.
|
||||
// ParserError 7059: (107-110): Expected explicit type name.
|
||||
// ParserError 7059: (152-155): Expected explicit type name.
|
||||
// ParserError 7059: (189-192): Expected explicit type name.
|
||||
// ParserError 7059: (234-237): Expected explicit type name.
|
||||
// ParserError 7439: (238-245): Location specifier needs explicit type name.
|
||||
// ParserError 7059: (277-280): Expected explicit type name.
|
||||
// ParserError 7439: (281-288): Location specifier needs explicit type name.
|
||||
// ParserError 7059: (322-325): Expected explicit type name.
|
||||
// ParserError 7439: (326-333): Location specifier needs explicit type name.
|
||||
// ParserError 7059: (337-340): Expected explicit type name.
|
||||
// ParserError 7439: (341-348): Location specifier needs explicit type name.
|
@ -1,7 +0,0 @@
|
||||
contract C {
|
||||
struct S {
|
||||
var x;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// ParserError 7059: (27-30): Expected explicit type name.
|
@ -6,4 +6,4 @@ contract c {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 6651: (81-113): Data location must be "storage" for variable, but "calldata" was given.
|
||||
// TypeError 4061: (81-113): Type mapping(uint256 => uint256) is only valid in storage because it contains a (nested) mapping.
|
||||
|
@ -6,4 +6,4 @@ contract c {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 6651: (81-104): Data location must be "storage" for variable, but none was given.
|
||||
// TypeError 6651: (81-104): Data location must be "storage", "memory" or "calldata" for variable, but none was given.
|
||||
|
@ -6,4 +6,4 @@ contract c {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 6651: (81-111): Data location must be "storage" for variable, but "memory" was given.
|
||||
// TypeError 4061: (81-111): Type mapping(uint256 => uint256) is only valid in storage because it contains a (nested) mapping.
|
||||
|
@ -4,13 +4,11 @@ contract C {
|
||||
function h() internal pure returns (uint, uint) { return (1, 2); }
|
||||
|
||||
function test() internal pure {
|
||||
var () = f();
|
||||
var () = g();
|
||||
var (,) = h();
|
||||
() = f();
|
||||
() = g();
|
||||
(,) = h();
|
||||
}
|
||||
}
|
||||
|
||||
// ----
|
||||
// SyntaxError 3299: (223-235): The use of the "var" keyword is disallowed. The declaration part of the statement can be removed, since it is empty.
|
||||
// SyntaxError 3299: (245-257): The use of the "var" keyword is disallowed. The declaration part of the statement can be removed, since it is empty.
|
||||
// SyntaxError 3299: (267-280): The use of the "var" keyword is disallowed. The declaration part of the statement can be removed, since it is empty.
|
||||
// ParserError 6933: (224-225): Expected primary expression.
|
||||
|
@ -3,13 +3,14 @@ contract n
|
||||
fallback() external
|
||||
{
|
||||
// Used to cause a segfault
|
||||
var (x,y) = (1);
|
||||
var (z) = ();
|
||||
(uint x, ) = (1);
|
||||
(uint z) = ();
|
||||
|
||||
assembly {
|
||||
mstore(y, z)
|
||||
mstore(x, z)
|
||||
}
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 7364: (69-84): Different number of components on the left hand side (2) than on the right hand side (1).
|
||||
// TypeError 7364: (69-85): Different number of components on the left hand side (2) than on the right hand side (1).
|
||||
// TypeError 7364: (89-102): Different number of components on the left hand side (1) than on the right hand side (0).
|
||||
|
@ -1,9 +0,0 @@
|
||||
contract C {
|
||||
function f() public pure {
|
||||
var ();
|
||||
var (,);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// SyntaxError 3299: (52-58): The use of the "var" keyword is disallowed. The declaration part of the statement can be removed, since it is empty.
|
||||
// SyntaxError 3299: (68-75): The use of the "var" keyword is disallowed. The declaration part of the statement can be removed, since it is empty.
|
@ -5,4 +5,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 6983: (52-57): Use of the "var" keyword is disallowed.
|
||||
// ParserError 6933: (52-55): Expected primary expression.
|
||||
|
@ -6,4 +6,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 4626: (52-62): Use of the "var" keyword is disallowed.
|
||||
// ParserError 6933: (52-55): Expected primary expression.
|
||||
|
@ -4,4 +4,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 4626: (52-63): Use of the "var" keyword is disallowed.
|
||||
// ParserError 6933: (52-55): Expected primary expression.
|
||||
|
@ -1,8 +1,8 @@
|
||||
contract C {
|
||||
function f() internal pure {
|
||||
var i = 31415999999999999999999999999999999999999999999999999999999999999999933**3;
|
||||
var unreachable = 123;
|
||||
uint i = 31415999999999999999999999999999999999999999999999999999999999999999933**3;
|
||||
uint unreachable = 123;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError 6963: (62-136): Invalid rational int_const 3100...(204 digits omitted)...9237 (absolute value too large or division by zero).
|
||||
// TypeError 9574: (54-137): Type int_const 3100...(204 digits omitted)...9237 is not implicitly convertible to expected type uint256. Literal is too large to fit in uint256.
|
||||
|
@ -1,30 +0,0 @@
|
||||
contract C {
|
||||
function h() internal pure returns (uint, uint, uint) {
|
||||
return (1, 2, 4);
|
||||
}
|
||||
function g(uint x) internal pure returns (uint) {
|
||||
return x;
|
||||
}
|
||||
function f() internal pure {
|
||||
var s = -31415;
|
||||
var i = 31415;
|
||||
var t = "string";
|
||||
var g2 = g;
|
||||
var myblockhash = block.blockhash;
|
||||
var (a, b) = (2, "troi");
|
||||
var (x,, z) = h();
|
||||
var (c, d) = ("");
|
||||
var (k, l) = (2);
|
||||
var (m, n) = 1;
|
||||
var (o, p) = "";
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// SyntaxError 1719: (224-238): Use of the "var" keyword is disallowed. Use explicit declaration `int16 s = ...´ instead.
|
||||
// SyntaxError 1719: (248-261): Use of the "var" keyword is disallowed. Use explicit declaration `uint16 i = ...´ instead.
|
||||
// SyntaxError 1719: (271-287): Use of the "var" keyword is disallowed. Use explicit declaration `string memory t = ...´ instead.
|
||||
// SyntaxError 1719: (297-307): Use of the "var" keyword is disallowed. Use explicit declaration `function (uint256) pure returns (uint256) g2 = ...´ instead.
|
||||
// SyntaxError 3478: (317-350): Use of the "var" keyword is disallowed. Type cannot be expressed in syntax.
|
||||
// SyntaxError 1719: (360-384): Use of the "var" keyword is disallowed. Use explicit declaration `(uint8 a, string memory b) = ...´ instead.
|
||||
// SyntaxError 1719: (394-411): Use of the "var" keyword is disallowed. Use explicit declaration `(uint256 x, , uint256 z) = ...´ instead.
|
||||
// TypeError 7364: (421-438): Different number of components on the left hand side (2) than on the right hand side (1).
|
Loading…
Reference in New Issue
Block a user