From 30b325fdc148d5014f04fd238362e3a1df10310f Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 17 Nov 2015 00:06:57 +0100 Subject: Allow "new expressions" also for general type names. Breaking change: If you want to send value with a contract creation, you have to use parentheses now: `(new ContractName).value(2 ether)(arg1, arg2)` --- libsolidity/analysis/TypeChecker.cpp | 67 ++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 26 deletions(-) (limited to 'libsolidity/analysis/TypeChecker.cpp') diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 0990a9e4..13c2235a 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1045,34 +1045,43 @@ bool TypeChecker::visit(FunctionCall const& _functionCall) void TypeChecker::endVisit(NewExpression const& _newExpression) { - auto contract = dynamic_cast(&dereference(_newExpression.contractName())); - - if (!contract) - fatalTypeError(_newExpression.location(), "Identifier is not a contract."); - if (!contract->annotation().isFullyImplemented) - typeError(_newExpression.location(), "Trying to create an instance of an abstract contract."); - - auto scopeContract = _newExpression.contractName().annotation().contractScope; - scopeContract->annotation().contractDependencies.insert(contract); - solAssert( - !contract->annotation().linearizedBaseContracts.empty(), - "Linearized base contracts not yet available." - ); - if (contractDependenciesAreCyclic(*scopeContract)) - typeError( - _newExpression.location(), - "Circular reference for contract creation (cannot create instance of derived or same contract)." + if (auto contractName = dynamic_cast(&_newExpression.typeName())) + { + auto contract = dynamic_cast(&dereference(*contractName)); + + if (!contract) + fatalTypeError(_newExpression.location(), "Identifier is not a contract."); + if (!contract->annotation().isFullyImplemented) + typeError(_newExpression.location(), "Trying to create an instance of an abstract contract."); + + auto scopeContract = contractName->annotation().contractScope; + scopeContract->annotation().contractDependencies.insert(contract); + solAssert( + !contract->annotation().linearizedBaseContracts.empty(), + "Linearized base contracts not yet available." ); + if (contractDependenciesAreCyclic(*scopeContract)) + typeError( + _newExpression.location(), + "Circular reference for contract creation (cannot create instance of derived or same contract)." + ); - auto contractType = make_shared(*contract); - TypePointers const& parameterTypes = contractType->constructorType()->parameterTypes(); - _newExpression.annotation().type = make_shared( - parameterTypes, - TypePointers{contractType}, - strings(), - strings(), - FunctionType::Location::Creation - ); + auto contractType = make_shared(*contract); + TypePointers const& parameterTypes = contractType->constructorType()->parameterTypes(); + _newExpression.annotation().type = make_shared( + parameterTypes, + TypePointers{contractType}, + strings(), + strings(), + FunctionType::Location::Creation + ); + } + else if (auto arrayTypeName = dynamic_cast(&_newExpression.typeName())) + { + solAssert(false, "Not yet implemented."); + } + else + fatalTypeError(_newExpression.location(), "Contract or array type expected."); } bool TypeChecker::visit(MemberAccess const& _memberAccess) @@ -1288,6 +1297,12 @@ Declaration const& TypeChecker::dereference(Identifier const& _identifier) return *_identifier.annotation().referencedDeclaration; } +Declaration const& TypeChecker::dereference(UserDefinedTypeName const& _typeName) +{ + solAssert(!!_typeName.annotation().referencedDeclaration, "Declaration not stored."); + return *_typeName.annotation().referencedDeclaration; +} + void TypeChecker::expectType(Expression const& _expression, Type const& _expectedType) { _expression.accept(*this); -- cgit v1.2.3