Browse Source

Merge branch 'develop' of https://github.com/ethereum/cpp-ethereum into develop

cl-refactor
winsvega 10 years ago
parent
commit
a93b8f06c5
  1. 7
      BuildInfo.h.in
  2. 55
      BuildInfo.sh
  3. 7
      CMakeLists.txt
  4. 14
      cmake/EthDependencies.cmake
  5. 24
      cmake/EthUtils.cmake
  6. 48
      cmake/scripts/buildinfo.cmake
  7. 14
      cmake/scripts/configure.cmake
  8. 36
      cmake/scripts/jsonrpcstub.cmake
  9. 4
      libethcore/CommonEth.cpp
  10. 2
      libnatspec/NatspecExpressionEvaluator.h
  11. 9
      libsolidity/AST.cpp
  12. 41
      libsolidity/ExpressionCompiler.cpp
  13. 3
      libsolidity/ExpressionCompiler.h
  14. 6
      libsolidity/GlobalContext.cpp
  15. 10
      libsolidity/Scanner.cpp
  16. 5
      libsolidity/Token.h
  17. 25
      libsolidity/Types.cpp
  18. 14
      libsolidity/Types.h
  19. 7
      libweb3jsonrpc/CMakeLists.txt
  20. 2
      mix/AppContext.cpp
  21. 1
      mix/ClientModel.cpp
  22. 35
      mix/qml/BasicContent.qml
  23. 3
      mix/qml/CodeEditor.qml
  24. 14
      mix/qml/CodeEditorStyle.qml
  25. 19
      mix/qml/Debugger.qml
  26. 15
      mix/qml/DebuggerPaneStyle.qml
  27. 26
      mix/qml/FilesSection.qml
  28. 5
      mix/qml/ItemDelegateDataDump.qml
  29. 15
      mix/qml/ProjectFilesStyle.qml
  30. 21
      mix/qml/ProjectList.qml
  31. 26
      mix/qml/ProjectModel.qml
  32. 3
      mix/qml/StateDialog.qml
  33. 3
      mix/qml/StateList.qml
  34. 14
      mix/qml/StateStyle.qml
  35. 5
      mix/qml/StatusPane.qml
  36. 15
      mix/qml/StatusPaneStyle.qml
  37. 8
      mix/qml/js/ProjectModel.js
  38. 27
      mix/qml/main.qml
  39. 5
      mix/qml/qmldir
  40. 7
      mix/res.qrc
  41. 53
      test/SolidityEndToEndTest.cpp
  42. 18
      test/SolidityNameAndTypeResolution.cpp
  43. 11
      test/SolidityParser.cpp
  44. 3
      test/TestHelper.cpp
  45. 3
      test/TestHelper.h

7
BuildInfo.h.in

@ -0,0 +1,7 @@
#pragma once
#define ETH_COMMIT_HASH @ETH_COMMIT_HASH@
#define ETH_CLEAN_REPO @ETH_CLEAN_REPO@
#define ETH_BUILD_TYPE @ETH_BUILD_TYPE@
#define ETH_BUILD_PLATFORM @ETH_BUILD_PLATFORM@

55
BuildInfo.sh

@ -1,55 +0,0 @@
CURRENT_SOURCE_DIR=$1
CURRENT_BINARY_DIR=$2
BUILD_TYPE=$3
BUILD_PLATFORM=$4
echo "Current source dir: $CURRENT_SOURCE_DIR"
echo "Current binary dir: $CURRENT_BINARY_DIR"
echo "Build type: $BUILD_TYPE"
echo "Build platform: $BUILD_PLATFORM"
if [[ -e "$CURRENT_SOURCE_DIR/BuildInfo.h" ]]
then
echo "Using existing BuildInfo.h"
cp $CURRENT_SOURCE_DIR/BuildInfo.h $CURRENT_BINARY_DIR/BuildInfo.h.tmp
else
if [[ -e "$CURRENT_SOURCE_DIR/.git" ]]
then
ETH_COMMIT_HASH=$(git --git-dir=$CURRENT_SOURCE_DIR/.git --work-tree=$CURRENT_SOURCE_DIR rev-parse HEAD)
ETH_LOCAL_CHANGES=$(git --git-dir=$CURRENT_SOURCE_DIR/.git --work-tree=$CURRENT_SOURCE_DIR diff --shortstat)
if [[ -z "$ETH_LOCAL_CHANGES" ]]
then
ETH_CLEAN_REPO=1
else
ETH_CLEAN_REPO=0
fi
echo "Commit hash: ${ETH_COMMIT_HASH} (Clean: ${ETH_CLEAN_REPO} - ${ETH_LOCAL_CHANGES})"
else
echo "Unknown repo."
ETH_COMMIT_HASH=0
ETH_CLEAN_REPO=1
fi
echo "// This file was automatically generated by cmake" > $CURRENT_BINARY_DIR/BuildInfo.h.tmp
echo "" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp
echo "#pragma once" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp
echo "" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp
echo "#define ETH_COMMIT_HASH $ETH_COMMIT_HASH" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp
echo "#define ETH_CLEAN_REPO $ETH_CLEAN_REPO" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp
echo "#define ETH_BUILD_TYPE $BUILD_TYPE" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp
echo "#define ETH_BUILD_PLATFORM $BUILD_PLATFORM" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp
fi
if [[ -e "$CURRENT_BINARY_DIR/BuildInfo.h" ]]
then
DIFF=$(diff $CURRENT_BINARY_DIR/BuildInfo.h $CURRENT_BINARY_DIR/BuildInfo.h.tmp)
if [[ -z "$DIFF" ]]
then
rm $CURRENT_BINARY_DIR/BuildInfo.h.tmp
else
mv $CURRENT_BINARY_DIR/BuildInfo.h.tmp $CURRENT_BINARY_DIR/BuildInfo.h
fi
else
mv $CURRENT_BINARY_DIR/BuildInfo.h.tmp $CURRENT_BINARY_DIR/BuildInfo.h
fi

7
CMakeLists.txt

@ -86,7 +86,12 @@ function(createBuildInfo)
endif()
# Generate header file containing useful build information
add_custom_target(BuildInfo.h ALL COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/BuildInfo.sh ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${_cmake_build_type} ${ETH_BUILD_PLATFORM})
add_custom_target(BuildInfo.h ALL
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMAND ${CMAKE_COMMAND} -DETH_SOURCE_DIR="${CMAKE_SOURCE_DIR}" -DETH_DST_DIR="${CMAKE_BINARY_DIR}"
-DETH_BUILD_TYPE="${_cmake_build_type}" -DETH_BUILD_PLATFORM="${ETH_BUILD_PLATFORM}"
-P "${ETH_SCRIPTS_DIR}/buildinfo.cmake"
)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
set(CMAKE_INCLUDE_CURRENT_DIR ON)

14
cmake/EthDependencies.cmake

@ -7,6 +7,14 @@ string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name)
set (ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}")
set (CMAKE_PREFIX_PATH ${ETH_DEPENDENCY_INSTALL_DIR})
# setup directory for cmake generated files and include it globally
# it's not used yet, but if we have more generated files, consider moving them to ETH_GENERATED_DIR
set(ETH_GENERATED_DIR "${PROJECT_BINARY_DIR}/gen")
include_directories(${ETH_GENERATED_DIR})
# custom cmake scripts
set(ETH_SCRIPTS_DIR ${CMAKE_SOURCE_DIR}/cmake/scripts)
# Qt5 requires opengl
# TODO use proper version of windows SDK (32 vs 64)
# TODO make it possible to use older versions of windows SDK (7.0+ should also work)
@ -87,6 +95,10 @@ find_package (CURL)
message(" - curl header: ${CURL_INCLUDE_DIRS}")
message(" - curl lib : ${CURL_LIBRARIES}")
# find location of jsonrpcstub
find_program(ETH_JSON_RPC_STUB jsonrpcstub)
message(" - jsonrpcstub location : ${ETH_JSON_RPC_STUB}")
# do not compile GUI
if (NOT HEADLESS)
@ -122,8 +134,6 @@ if (NOT HEADLESS)
string(REGEX REPLACE "npm" "" ETH_NPM_DIRECTORY ${ETH_NPM})
message(" - npm location : ${ETH_NPM}")
find_program(ETH_JSON_RPC_STUB jsonrpcstub)
endif() #HEADLESS
# use multithreaded boost libraries, with -mt suffix

24
cmake/EthUtils.cmake

@ -0,0 +1,24 @@
#
# renames the file if it is different from its destination
include(CMakeParseArguments)
#
macro(replace_if_different SOURCE DST)
set(extra_macro_args ${ARGN})
set(options CREATE)
set(one_value_args)
set(multi_value_args)
cmake_parse_arguments(REPLACE_IF_DIFFERENT "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}")
if (REPLACE_IF_DIFFERENT_CREATE AND (NOT (EXISTS "${DST}")))
file(WRITE "${DST}" "")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files "${SOURCE}" "${DST}" RESULT_VARIABLE DIFFERENT)
if (DIFFERENT)
execute_process(COMMAND ${CMAKE_COMMAND} -E rename "${SOURCE}" "${DST}")
else()
execute_process(COMMAND ${CMAKE_COMMAND} -E remove "${SOURCE}")
endif()
endmacro()

48
cmake/scripts/buildinfo.cmake

@ -0,0 +1,48 @@
# generates BuildInfo.h
#
# this module expects
# ETH_SOURCE_DIR - main CMAKE_SOURCE_DIR
# ETH_DST_DIR - main CMAKE_BINARY_DIR
# ETH_BUILD_TYPE
# ETH_BUILD_PLATFORM
#
# example usage:
# cmake -DETH_SOURCE_DIR=. -DETH_DST_DIR=build -DETH_BUILD_TYPE=Debug -DETH_BUILD_PLATFORM=mac -P scripts/buildinfo.cmake
if (NOT ETH_BUILD_TYPE)
set(ETH_BUILD_TYPE "unknown")
endif()
if (NOT ETH_BUILD_PLATFORM)
set(ETH_BUILD_PLATFORM "unknown")
endif()
execute_process(
COMMAND git --git-dir=${ETH_SOURCE_DIR}/.git --work-tree=${ETH_SOURCE_DIR} rev-parse HEAD
OUTPUT_VARIABLE ETH_COMMIT_HASH OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET
)
if (NOT ETH_COMMIT_HASH)
set(ETH_COMMIT_HASH 0)
endif()
execute_process(
COMMAND git --git-dir=${ETH_SOURCE_DIR}/.git --work-tree=${ETH_SOURCE_DIR} diff --shortstat
OUTPUT_VARIABLE ETH_LOCAL_CHANGES OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET
)
if (ETH_LOCAL_CHANGES)
set(ETH_CLEAN_REPO 0)
else()
set(ETH_CLEAN_REPO 1)
endif()
set(INFILE "${ETH_SOURCE_DIR}/BuildInfo.h.in")
set(TMPFILE "${ETH_DST_DIR}/BuildInfo.h.tmp")
set(OUTFILE "${ETH_DST_DIR}/BuildInfo.h")
configure_file("${INFILE}" "${TMPFILE}")
include("${ETH_SOURCE_DIR}/cmake/EthUtils.cmake")
replace_if_different("${TMPFILE}" "${OUTFILE}" CREATE)

14
cmake/scripts/configure.cmake

@ -0,0 +1,14 @@
# adds possibility to run configure_file as buildstep
# reference:
# http://www.cmake.org/pipermail/cmake/2012-May/050227.html
#
# This module expects
# INFILE
# OUTFILE
# other custom vars
#
# example usage:
# cmake -DINFILE=blah.in -DOUTFILE=blah.out -Dvar1=value1 -Dvar2=value2 -P scripts/configure.cmake
configure_file(${INFILE} ${OUTFILE})

36
cmake/scripts/jsonrpcstub.cmake

@ -0,0 +1,36 @@
# generates JSONRPC Stub Server && Client
#
# this script expects
# ETH_SOURCE_DIR - main CMAKE_SOURCE_DIR
# ETH_SPEC_PATH
# ETH_SERVER_DIR
# ETH_CLIENT_DIR
# ETH_SERVER_NAME
# ETH_CLIENT_NAME
# ETH_JSON_RPC_STUB
#
# example usage:
# cmake -DETH_SPEC_PATH=spec.json -DETH_SERVER_DIR=libweb3jsonrpc -DETH_CLIENT_DIR=test
# -DETH_SERVER_NAME=AbstractWebThreeStubServer -DETH_CLIENT_NAME=WebThreeStubClient -DETH_JSON_RPC_STUB=/usr/local/bin/jsonrpcstub
# by default jsonrpcstub produces files in lowercase, we want to stick to this
string(TOLOWER ${ETH_SERVER_NAME} ETH_SERVER_NAME_LOWER)
string(TOLOWER ${ETH_CLIENT_NAME} ETH_CLIENT_NAME_LOWER)
# setup names
set(SERVER_TMPFILE "${ETH_SERVER_DIR}/${ETH_SERVER_NAME_LOWER}.h.tmp")
set(SERVER_OUTFILE "${ETH_SERVER_DIR}/${ETH_SERVER_NAME_LOWER}.h")
set(CLIENT_TMPFILE "${ETH_CLIENT_DIR}/${ETH_CLIENT_NAME_LOWER}.h.tmp")
set(CLIENT_OUTFILE "${ETH_CLIENT_DIR}/${ETH_CLIENT_NAME_LOWER}.h")
# create tmp files
execute_process(
COMMAND ${ETH_JSON_RPC_STUB} ${ETH_SPEC_PATH}
--cpp-server=${ETH_SERVER_NAME} --cpp-server-file=${SERVER_TMPFILE}
--cpp-client=${ETH_CLIENT_NAME} --cpp-client-file=${CLIENT_TMPFILE}
)
include("${ETH_SOURCE_DIR}/cmake/EthUtils.cmake")
replace_if_different("${SERVER_TMPFILE}" "${SERVER_OUTFILE}")
replace_if_different("${CLIENT_TMPFILE}" "${CLIENT_OUTFILE}")

4
libethcore/CommonEth.cpp

@ -35,12 +35,12 @@ namespace eth
const unsigned c_protocolVersion = 53;
const unsigned c_databaseVersion = 5;
template <size_t n> constexpr u256 exp10()
template <size_t n> u256 exp10()
{
return exp10<n - 1>() * u256(10);
}
template <> constexpr u256 exp10<0>()
template <> u256 exp10<0>()
{
return u256(1);
}

2
libnatspec/NatspecExpressionEvaluator.h

@ -19,6 +19,8 @@
* @date 2015
*/
#pragma once
#include <QtCore/QObject>
#include <QtCore/QtCore>
#include <QtQml/QJSEngine>

9
libsolidity/AST.cpp

@ -497,20 +497,21 @@ void FunctionCall::checkTypeRequirements()
// and then ask if that is implicitly convertible to the struct represented by the
// function parameters
TypePointers const& parameterTypes = functionType->getParameterTypes();
if (functionType->getLocation() != FunctionType::Location::SHA3 && parameterTypes.size() != m_arguments.size())
if (!functionType->takesArbitraryParameters() && parameterTypes.size() != m_arguments.size())
BOOST_THROW_EXCEPTION(createTypeError("Wrong argument count for function call."));
if (m_names.empty())
{
for (size_t i = 0; i < m_arguments.size(); ++i)
if (functionType->getLocation() != FunctionType::Location::SHA3 &&
if (!functionType->takesArbitraryParameters() &&
!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[i]))
BOOST_THROW_EXCEPTION(m_arguments[i]->createTypeError("Invalid type for argument in function call."));
}
else
{
if (functionType->getLocation() == FunctionType::Location::SHA3)
BOOST_THROW_EXCEPTION(createTypeError("Named arguments cannnot be used for SHA3."));
if (functionType->takesArbitraryParameters())
BOOST_THROW_EXCEPTION(createTypeError("Named arguments cannnot be used for functions "
"that take arbitrary parameters."));
auto const& parameterNames = functionType->getParameterNames();
if (parameterNames.size() != m_names.size())
BOOST_THROW_EXCEPTION(createTypeError("Some argument names are missing."));

41
libsolidity/ExpressionCompiler.cpp

@ -206,7 +206,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
TypePointers const& parameterTypes = function.getParameterTypes();
vector<ASTPointer<Expression const>> const& callArguments = _functionCall.getArguments();
vector<ASTPointer<ASTString>> const& callArgumentNames = _functionCall.getNames();
if (function.getLocation() != Location::SHA3)
if (!function.takesArbitraryParameters())
solAssert(callArguments.size() == parameterTypes.size(), "");
vector<ASTPointer<Expression const>> arguments;
@ -318,7 +318,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
appendTypeConversion(*arguments.front()->getType(),
*function.getParameterTypes().front(), true);
appendExternalFunctionCall(FunctionType(TypePointers{}, TypePointers{},
Location::External, true, true), {}, true);
Location::External, false, true, true), {}, true);
break;
case Location::Suicide:
arguments.front()->accept(*this);
@ -327,7 +327,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
break;
case Location::SHA3:
{
unsigned length = appendArgumentsCopyToMemory(arguments, TypePointers(), 0, false);
unsigned length = appendArgumentsCopyToMemory(arguments, TypePointers(), 0, function.padArguments());
m_context << u256(length) << u256(0) << eth::Instruction::SHA3;
break;
}
@ -650,6 +650,9 @@ void ExpressionCompiler::appendArithmeticOperatorCode(Token::Value _operator, Ty
case Token::Mod:
m_context << (c_isSigned ? eth::Instruction::SMOD : eth::Instruction::MOD);
break;
case Token::Exp:
m_context << eth::Instruction::EXP;
break;
default:
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown arithmetic operator."));
}
@ -700,21 +703,30 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con
if (stackTypeCategory == Type::Category::String)
{
StaticStringType const& typeOnStack = dynamic_cast<StaticStringType const&>(_typeOnStack);
if (targetTypeCategory == Type::Category::Integer)
{
// conversion from string to hash. no need to clean the high bit
// only to shift right because of opposite alignment
IntegerType const& targetIntegerType = dynamic_cast<IntegerType const&>(_targetType);
StaticStringType const& typeOnStack = dynamic_cast<StaticStringType const&>(_typeOnStack);
solAssert(targetIntegerType.isHash(), "Only conversion between String and Hash is allowed.");
solAssert(targetIntegerType.getNumBits() == typeOnStack.getNumBytes() * 8, "The size should be the same.");
m_context << (u256(1) << (256 - typeOnStack.getNumBytes() * 8)) << eth::Instruction::SWAP1 << eth::Instruction::DIV;
}
else
{
// clear lower-order bytes for conversion to shorter strings - we always clean
solAssert(targetTypeCategory == Type::Category::String, "Invalid type conversion requested.");
// nothing to do, strings are high-order-bit-aligned
//@todo clear lower-order bytes if we allow explicit conversion to shorter strings
StaticStringType const& targetType = dynamic_cast<StaticStringType const&>(_targetType);
if (targetType.getNumBytes() < typeOnStack.getNumBytes())
{
if (targetType.getNumBytes() == 0)
m_context << eth::Instruction::DUP1 << eth::Instruction::XOR;
else
m_context << (u256(1) << (256 - targetType.getNumBytes() * 8))
<< eth::Instruction::DUP1 << eth::Instruction::SWAP2
<< eth::Instruction::DIV << eth::Instruction::MUL;
}
}
}
else if (stackTypeCategory == Type::Category::Integer || stackTypeCategory == Type::Category::Contract ||
@ -776,7 +788,8 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio
vector<ASTPointer<Expression const>> const& _arguments,
bool bare)
{
solAssert(_arguments.size() == _functionType.getParameterTypes().size(), "");
solAssert(_functionType.takesArbitraryParameters() ||
_arguments.size() == _functionType.getParameterTypes().size(), "");
// Assumed stack content here:
// <stack top>
@ -800,7 +813,10 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio
// reserve space for the function identifier
unsigned dataOffset = bare ? 0 : CompilerUtils::dataStartOffset;
dataOffset += appendArgumentsCopyToMemory(_arguments, _functionType.getParameterTypes(), dataOffset);
// For bare call, activate "4 byte pad exception": If the first argument has exactly 4 bytes,
// do not pad it to 32 bytes.
dataOffset += appendArgumentsCopyToMemory(_arguments, _functionType.getParameterTypes(), dataOffset,
_functionType.padArguments(), bare);
//@todo only return the first return value for now
Type const* firstType = _functionType.getReturnParameterTypes().empty() ? nullptr :
@ -839,7 +855,8 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio
unsigned ExpressionCompiler::appendArgumentsCopyToMemory(vector<ASTPointer<Expression const>> const& _arguments,
TypePointers const& _types,
unsigned _memoryOffset,
bool _padToWordBoundaries)
bool _padToWordBoundaries,
bool _padExceptionIfFourBytes)
{
solAssert(_types.empty() || _types.size() == _arguments.size(), "");
unsigned length = 0;
@ -848,8 +865,12 @@ unsigned ExpressionCompiler::appendArgumentsCopyToMemory(vector<ASTPointer<Expre
_arguments[i]->accept(*this);
TypePointer const& expectedType = _types.empty() ? _arguments[i]->getType()->getRealType() : _types[i];
appendTypeConversion(*_arguments[i]->getType(), *expectedType, true);
bool pad = _padToWordBoundaries;
// Do not pad if the first argument has exactly four bytes
if (i == 0 && pad && _padExceptionIfFourBytes && expectedType->getCalldataEncodedSize() == 4)
pad = false;
length += appendTypeMoveToMemory(*expectedType, _arguments[i]->getLocation(),
_memoryOffset + length, _padToWordBoundaries);
_memoryOffset + length, pad);
}
return length;
}

3
libsolidity/ExpressionCompiler.h

@ -97,7 +97,8 @@ private:
unsigned appendArgumentsCopyToMemory(std::vector<ASTPointer<Expression const>> const& _arguments,
TypePointers const& _types = {},
unsigned _memoryOffset = 0,
bool _padToWordBoundaries = true);
bool _padToWordBoundaries = true,
bool _padExceptionIfFourBytes = false);
/// Appends code that moves a stack element of the given type to memory
/// @returns the number of bytes moved to memory
unsigned appendTypeMoveToMemory(Type const& _type, Location const& _location, unsigned _memoryOffset,

6
libsolidity/GlobalContext.cpp

@ -40,7 +40,7 @@ m_magicVariables(vector<shared_ptr<MagicVariableDeclaration const>>{make_shared<
make_shared<MagicVariableDeclaration>("suicide",
make_shared<FunctionType>(strings{"address"}, strings{}, FunctionType::Location::Suicide)),
make_shared<MagicVariableDeclaration>("sha3",
make_shared<FunctionType>(strings{"hash"}, strings{"hash"}, FunctionType::Location::SHA3)),
make_shared<FunctionType>(strings(), strings{"hash"}, FunctionType::Location::SHA3, true)),
make_shared<MagicVariableDeclaration>("log0",
make_shared<FunctionType>(strings{"hash"},strings{}, FunctionType::Location::Log0)),
make_shared<MagicVariableDeclaration>("log1",
@ -52,11 +52,11 @@ m_magicVariables(vector<shared_ptr<MagicVariableDeclaration const>>{make_shared<
make_shared<MagicVariableDeclaration>("log4",
make_shared<FunctionType>(strings{"hash", "hash", "hash", "hash", "hash"},strings{}, FunctionType::Location::Log4)),
make_shared<MagicVariableDeclaration>("sha256",
make_shared<FunctionType>(strings{"hash"}, strings{"hash"}, FunctionType::Location::SHA256)),
make_shared<FunctionType>(strings(), strings{"hash"}, FunctionType::Location::SHA256, true)),
make_shared<MagicVariableDeclaration>("ecrecover",
make_shared<FunctionType>(strings{"hash", "hash8", "hash", "hash"}, strings{"address"}, FunctionType::Location::ECRecover)),
make_shared<MagicVariableDeclaration>("ripemd160",
make_shared<FunctionType>(strings{"hash"}, strings{"hash160"}, FunctionType::Location::RIPEMD160))})
make_shared<FunctionType>(strings(), strings{"hash160"}, FunctionType::Location::RIPEMD160, true))})
{
}

10
libsolidity/Scanner.cpp

@ -465,8 +465,14 @@ void Scanner::scanToken()
token = Token::Sub;
break;
case '*':
// * *=
token = selectToken('=', Token::AssignMul, Token::Mul);
// * ** *=
advance();
if (m_char == '*')
token = selectToken(Token::Exp);
else if (m_char == '=')
token = selectToken(Token::AssignMul);
else
token = Token::Mul;
break;
case '%':
// % %=

5
libsolidity/Token.h

@ -118,6 +118,7 @@ namespace solidity
T(Mul, "*", 13) \
T(Div, "/", 13) \
T(Mod, "%", 13) \
T(Exp, "**", 14) \
\
/* Compare operators sorted by precedence. */ \
/* IsCompareOp() relies on this block of enum values */ \
@ -361,10 +362,10 @@ public:
// Predicates
static bool isElementaryTypeName(Value tok) { return Int <= tok && tok < TypesEnd; }
static bool isAssignmentOp(Value tok) { return Assign <= tok && tok <= AssignMod; }
static bool isBinaryOp(Value op) { return Comma <= op && op <= Mod; }
static bool isBinaryOp(Value op) { return Comma <= op && op <= Exp; }
static bool isCommutativeOp(Value op) { return op == BitOr || op == BitXor || op == BitAnd ||
op == Add || op == Mul || op == Equal || op == NotEqual; }
static bool isArithmeticOp(Value op) { return Add <= op && op <= Mod; }
static bool isArithmeticOp(Value op) { return Add <= op && op <= Exp; }
static bool isCompareOp(Value op) { return Equal <= op && op <= In; }
static Value AssignmentToBinaryOp(Value op)

25
libsolidity/Types.cpp

@ -26,6 +26,8 @@
#include <libsolidity/Types.h>
#include <libsolidity/AST.h>
#include <limits>
using namespace std;
namespace dev
@ -210,10 +212,7 @@ TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointe
const MemberList IntegerType::AddressMemberList =
MemberList({{"balance", make_shared<IntegerType >(256)},
{"callstring32", make_shared<FunctionType>(strings{"string32"}, strings{},
FunctionType::Location::Bare)},
{"callstring32string32", make_shared<FunctionType>(strings{"string32", "string32"},
strings{}, FunctionType::Location::Bare)},
{"call", make_shared<FunctionType>(strings(), strings(), FunctionType::Location::Bare, true)},
{"send", make_shared<FunctionType>(strings{"uint"}, strings{}, FunctionType::Location::Send)}});
IntegerConstantType::IntegerConstantType(Literal const& _literal)
@ -323,6 +322,14 @@ TypePointer IntegerConstantType::binaryOperatorResult(Token::Value _operator, Ty
return TypePointer();
value = m_value % other.m_value;
break;
case Token::Exp:
if (other.m_value < 0)
return TypePointer();
else if (other.m_value > std::numeric_limits<unsigned int>::max())
return TypePointer();
else
value = boost::multiprecision::pow(m_value, other.m_value.convert_to<unsigned int>());
break;
default:
return TypePointer();
}
@ -401,13 +408,16 @@ bool StaticStringType::isImplicitlyConvertibleTo(Type const& _convertTo) const
bool StaticStringType::isExplicitlyConvertibleTo(Type const& _convertTo) const
{
if (_convertTo.getCategory() == getCategory())
return true;
if (_convertTo.getCategory() == Category::Integer)
{
IntegerType const& convertTo = dynamic_cast<IntegerType const&>(_convertTo);
if (convertTo.isHash() && (m_bytes * 8 == convertTo.getNumBits()))
return true;
}
return isImplicitlyConvertibleTo(_convertTo);
return false;
}
bool StaticStringType::operator==(Type const& _other) const
@ -766,10 +776,10 @@ MemberList const& FunctionType::getMembers() const
map<string, TypePointer> members{
{"gas", make_shared<FunctionType>(parseElementaryTypeVector({"uint"}),
TypePointers{copyAndSetGasOrValue(true, false)},
Location::SetGas, m_gasSet, m_valueSet)},
Location::SetGas, false, m_gasSet, m_valueSet)},
{"value", make_shared<FunctionType>(parseElementaryTypeVector({"uint"}),
TypePointers{copyAndSetGasOrValue(false, true)},
Location::SetValue, m_gasSet, m_valueSet)}};
Location::SetValue, false, m_gasSet, m_valueSet)}};
if (m_location == Location::Creation)
members.erase("gas");
m_members.reset(new MemberList(members));
@ -808,6 +818,7 @@ TypePointers FunctionType::parseElementaryTypeVector(strings const& _types)
TypePointer FunctionType::copyAndSetGasOrValue(bool _setGas, bool _setValue) const
{
return make_shared<FunctionType>(m_parameterTypes, m_returnParameterTypes, m_location,
m_arbitraryParameters,
m_gasSet || _setGas, m_valueSet || _setValue);
}

14
libsolidity/Types.h

@ -367,14 +367,15 @@ public:
explicit FunctionType(VariableDeclaration const& _varDecl);
explicit FunctionType(EventDefinition const& _event);
FunctionType(strings const& _parameterTypes, strings const& _returnParameterTypes,
Location _location = Location::Internal):
Location _location = Location::Internal, bool _arbitraryParameters = false):
FunctionType(parseElementaryTypeVector(_parameterTypes), parseElementaryTypeVector(_returnParameterTypes),
_location) {}
_location, _arbitraryParameters) {}
FunctionType(TypePointers const& _parameterTypes, TypePointers const& _returnParameterTypes,
Location _location = Location::Internal,
bool _gasSet = false, bool _valueSet = false):
bool _arbitraryParameters = false, bool _gasSet = false, bool _valueSet = false):
m_parameterTypes(_parameterTypes), m_returnParameterTypes(_returnParameterTypes),
m_location(_location), m_gasSet(_gasSet), m_valueSet(_valueSet) {}
m_location(_location),
m_arbitraryParameters(_arbitraryParameters), m_gasSet(_gasSet), m_valueSet(_valueSet) {}
TypePointers const& getParameterTypes() const { return m_parameterTypes; }
std::vector<std::string> const& getParameterNames() const { return m_parameterNames; }
@ -407,6 +408,9 @@ public:
/// Can contain a nullptr in which case indicates absence of documentation
ASTPointer<ASTString> getDocumentation() const;
/// true iff arguments are to be padded to multiples of 32 bytes for external calls
bool padArguments() const { return !(m_location == Location::SHA3 || m_location == Location::SHA256 || m_location == Location::RIPEMD160); }
bool takesArbitraryParameters() const { return m_arbitraryParameters; }
bool gasSet() const { return m_gasSet; }
bool valueSet() const { return m_valueSet; }
@ -422,6 +426,8 @@ private:
std::vector<std::string> m_parameterNames;
std::vector<std::string> m_returnParameterNames;
Location const m_location;
/// true iff the function takes an arbitrary number of arguments of arbitrary types
bool const m_arbitraryParameters = false;
bool const m_gasSet = false; ///< true iff the gas value to be used is on the stack
bool const m_valueSet = false; ///< true iff the value to be sent is on the stack
bool m_isConstant;

7
libweb3jsonrpc/CMakeLists.txt

@ -37,8 +37,11 @@ if (ETH_JSON_RPC_STUB)
add_custom_command(TARGET jsonrpcstub
POST_BUILD
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND ${ETH_JSON_RPC_STUB} spec.json --cpp-server=AbstractWebThreeStubServer --cpp-client=WebThreeStubClient
COMMAND cmake -E rename webthreestubclient.h ../test/webthreestubclient.h
COMMAND ${CMAKE_COMMAND} -DETH_SPEC_PATH="${CMAKE_CURRENT_SOURCE_DIR}/spec.json" -DETH_SOURCE_DIR="${CMAKE_SOURCE_DIR}"
-DETH_SERVER_DIR="${CMAKE_CURRENT_SOURCE_DIR}" -DETH_CLIENT_DIR="${CMAKE_SOURCE_DIR}/test"
-DETH_SERVER_NAME=AbstractWebThreeStubServer -DETH_CLIENT_NAME=WebThreeStubClient
-DETH_JSON_RPC_STUB="${ETH_JSON_RPC_STUB}"
-P "${ETH_SCRIPTS_DIR}/jsonrpcstub.cmake"
)
add_dependencies(${EXECUTABLE} jsonrpcstub)
endif()

2
mix/AppContext.cpp

@ -81,6 +81,8 @@ void AppContext::load()
BOOST_THROW_EXCEPTION(exception);
}
m_applicationEngine->rootContext()->setContextProperty("projectModel", projectModel);
QFont f;
m_applicationEngine->rootContext()->setContextProperty("systemPointSize", f.pointSize());
qmlRegisterType<CodeEditorExtensionManager>("CodeEditorExtensionManager", 1, 0, "CodeEditorExtensionManager");
qmlRegisterType<HttpServer>("HttpServer", 1, 0, "HttpServer");
m_applicationEngine->load(QUrl("qrc:/qml/main.qml"));

1
mix/ClientModel.cpp

@ -89,7 +89,6 @@ ClientModel::ClientModel(AppContext* _context):
m_web3Server.reset(new Web3Server(*m_rpcConnector.get(), std::vector<dev::KeyPair> { m_client->userAccount() }, m_client.get()));
connect(m_web3Server.get(), &Web3Server::newTransaction, this, &ClientModel::onNewTransaction, Qt::DirectConnection);
_context->appEngine()->rootContext()->setContextProperty("clientModel", this);
}

35
mix/qml/BasicContent.qml

@ -1,35 +0,0 @@
import QtQuick 2.2
import QtQuick.Controls 1.1
Rectangle {
anchors.fill: parent
width: parent.width
height: parent.height
color: "lightgray"
Text {
font.pointSize: 9
anchors.left: parent.left
anchors.top: parent.top
anchors.topMargin: 3
anchors.leftMargin: 3
height: 9
font.family: "Monospace"
objectName: "status"
id: status
}
TextArea {
readOnly: true
anchors.left: parent.left
anchors.leftMargin: 10
anchors.top: status.bottom
anchors.topMargin: 3
font.pointSize: 9
font.family: "Monospace"
height: parent.height * 0.8
width: parent.width - 20
wrapMode: Text.Wrap
backgroundVisible: false
objectName: "content"
id: content
}
}

3
mix/qml/CodeEditor.qml

@ -3,6 +3,7 @@ import QtQuick.Window 2.0
import QtQuick.Layouts 1.0
import QtQuick.Controls 1.0
import QtQuick.Controls.Styles 1.1
import "."
Item {
signal editorTextChanged
@ -65,7 +66,7 @@ Item {
height: parent.height
font.family: "Monospace"
font.pointSize: 12
font.pointSize: CodeEditorStyle.general.basicFontSize
width: parent.width
tabChangesFocus: false

14
mix/qml/CodeEditorStyle.qml

@ -0,0 +1,14 @@
pragma Singleton
import QtQuick 2.0
QtObject {
function absoluteSize(rel)
{
return systemPointSize + rel;
}
property QtObject general: QtObject {
property int basicFontSize: absoluteSize(1)
}
}

19
mix/qml/Debugger.qml

@ -6,6 +6,7 @@ import QtQuick.Layouts 1.1
import Qt.labs.settings 1.0
import "js/Debugger.js" as Debugger
import "js/ErrorLocationFormater.js" as ErrorLocationFormater
import "."
Rectangle {
id: debugPanel
@ -346,7 +347,7 @@ Rectangle {
color: "#b2b3ae"
text: styleData.value.split(' ')[0]
font.family: "monospace"
font.pointSize: 9
font.pointSize: DebuggerPaneStyle.general.basicFontSize
wrapMode: Text.NoWrap
id: id
}
@ -356,7 +357,7 @@ Rectangle {
color: styleData.selected ? "white" : "black"
font.family: "monospace"
text: styleData.value.replace(styleData.value.split(' ')[0], '')
font.pointSize: 9
font.pointSize: DebuggerPaneStyle.general.basicFontSize
}
}
}
@ -425,11 +426,11 @@ Rectangle {
Layout.minimumHeight: parent.height
Text {
anchors.centerIn: parent
anchors.leftMargin: 5
anchors.leftMargin: 5()
font.family: "monospace"
color: "#4a4a4a"
text: styleData.row;
font.pointSize: 9
font.pointSize: DebuggerPaneStyle.general.basicFontSize
}
}
@ -447,7 +448,7 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter
color: "#4a4a4a"
text: styleData.value
font.pointSize: 9
font.pointSize: DebuggerPaneStyle.general.basicFontSize
}
}
}
@ -514,7 +515,7 @@ Rectangle {
anchors.leftMargin: 5
color: "#4a4a4a"
text: styleData.row;
font.pointSize: 9
font.pointSize: DebuggerPaneStyle.general.basicFontSize
width: parent.width - 5
elide: Text.ElideRight
}
@ -535,7 +536,7 @@ Rectangle {
color: "#4a4a4a"
text: styleData.value;
elide: Text.ElideRight
font.pointSize: 9
font.pointSize: DebuggerPaneStyle.general.basicFontSize
}
}
}
@ -585,7 +586,7 @@ Rectangle {
anchors.leftMargin: 5
color: "#4a4a4a"
text: styleData.value.split('\t')[0];
font.pointSize: 9
font.pointSize: DebuggerPaneStyle.general.basicFontSize
width: parent.width - 5
elide: Text.ElideRight
}
@ -606,7 +607,7 @@ Rectangle {
color: "#4a4a4a"
text: styleData.value.split('\t')[1];
elide: Text.ElideRight
font.pointSize: 9
font.pointSize: DebuggerPaneStyle.general.basicFontSize
}
}
}

15
mix/qml/DebuggerPaneStyle.qml

@ -0,0 +1,15 @@
pragma Singleton
import QtQuick 2.0
QtObject {
function absoluteSize(rel)
{
return systemPointSize + rel;
}
property QtObject general: QtObject {
property int basicFontSize: absoluteSize(-2)
property int dataDumpFontSize: absoluteSize(-3)
}
}

26
mix/qml/FilesSection.qml

@ -20,17 +20,17 @@ ColumnLayout {
function hiddenHeightTopLevel()
{
return section.state === "hidden" ? Style.documentsList.height : Style.documentsList.fileNameHeight * model.count + Style.documentsList.height;
return section.state === "hidden" ? ProjectFilesStyle.documentsList.height : ProjectFilesStyle.documentsList.fileNameHeight * model.count + ProjectFilesStyle.documentsList.height;
}
function hiddenHeightRepeater()
{
return section.state === "hidden" ? 0 : Style.documentsList.fileNameHeight * wrapperItem.model.count;
return section.state === "hidden" ? 0 : ProjectFilesStyle.documentsList.fileNameHeight * wrapperItem.model.count;
}
function hiddenHeightElement()
{
return section.state === "hidden" ? 0 : Style.documentsList.fileNameHeight;
return section.state === "hidden" ? 0 : ProjectFilesStyle.documentsList.fileNameHeight;
}
function getDocumentIndex(documentId)
@ -65,7 +65,7 @@ ColumnLayout {
anchors.top: parent.top
id: rowCol
width: parent.width
height: Style.documentsList.height
height: ProjectFilesStyle.documentsList.height
Image {
source: "qrc:/qml/img/opentriangleindicator_filesproject.png"
@ -83,15 +83,15 @@ ColumnLayout {
id: section
text: sectionName
anchors.left: parent.left
anchors.leftMargin: Style.general.leftMargin
color: Style.documentsList.sectionColor
anchors.leftMargin: ProjectFilesStyle.general.leftMargin
color: ProjectFilesStyle.documentsList.sectionColor
font.family: boldFont.name
font.pointSize: Style.documentsList.sectionFontSize
font.pointSize: ProjectFilesStyle.documentsList.sectionFontSize
states: [
State {
name: "hidden"
PropertyChanges { target: filesList; visible: false; }
PropertyChanges { target: rowCol; Layout.minimumHeight: Style.documentsList.height; Layout.maximumHeight: Style.documentsList.height; height: Style.documentsList.height; }
PropertyChanges { target: rowCol; Layout.minimumHeight: ProjectFilesStyle.documentsList.height; Layout.maximumHeight: ProjectFilesStyle.documentsList.height; height: ProjectFilesStyle.documentsList.height; }
PropertyChanges { target: imgArrow; source: "qrc:/qml/img/closedtriangleindicator_filesproject.png" }
}
]
@ -132,21 +132,21 @@ ColumnLayout {
Layout.preferredHeight: wrapperItem.hiddenHeightElement()
Layout.maximumHeight: wrapperItem.hiddenHeightElement()
height: wrapperItem.hiddenHeightElement()
color: isSelected ? Style.documentsList.highlightColor : Style.documentsList.background
color: isSelected ? ProjectFilesStyle.documentsList.highlightColor : ProjectFilesStyle.documentsList.background
property bool isSelected
property bool renameMode
Text {
id: nameText
height: parent.height
visible: !renameMode
color: rootItem.isSelected ? Style.documentsList.selectedColor : Style.documentsList.color
color: rootItem.isSelected ? ProjectFilesStyle.documentsList.selectedColor : ProjectFilesStyle.documentsList.color
text: name;
font.family: fileNameFont.name
font.pointSize: Style.documentsList.fontSize
font.pointSize: ProjectFilesStyle.documentsList.fontSize
anchors.verticalCenter: parent.verticalCenter
verticalAlignment: Text.AlignVCenter
anchors.left: parent.left
anchors.leftMargin: Style.general.leftMargin + 2
anchors.leftMargin: ProjectFilesStyle.general.leftMargin + 2
width: parent.width
Connections
{
@ -171,7 +171,7 @@ ColumnLayout {
visible: renameMode
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: Style.general.leftMargin
anchors.leftMargin: ProjectFilesStyle.general.leftMargin
MouseArea {
id: textMouseArea
anchors.fill: parent

5
mix/qml/ItemDelegateDataDump.qml

@ -2,6 +2,7 @@ import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.0
import QtQuick.Controls.Styles 1.1
import "."
Rectangle {
anchors.fill: parent
@ -27,7 +28,7 @@ Rectangle {
font.bold: true
color: "#4a4a4a"
text: modelData[0]
font.pointSize: 8;
font.pointSize: DebuggerPaneStyle.general.dataDumpFontSize;
}
}
@ -46,7 +47,7 @@ Rectangle {
anchors.leftMargin: 4
color: "#4a4a4a"
text: modelData[1]
font.pointSize: 8
font.pointSize: DebuggerPaneStyle.general.dataDumpFontSize
}
}
}

15
mix/qml/Style.qml → mix/qml/ProjectFilesStyle.qml

@ -1,10 +1,13 @@
pragma Singleton
import QtQuick 2.0
/*
* Project Files
*/
QtObject {
function absoluteSize(rel)
{
return systemPointSize + rel;
}
property QtObject general: QtObject {
property int leftMargin: 45
}
@ -13,7 +16,7 @@ QtObject {
property string color: "#808080"
property string background: "#f0f0f0"
property int height: 55
property int pointSize: 18
property int fontSize: absoluteSize(7);// 18
}
property QtObject documentsList: QtObject {
@ -24,7 +27,7 @@ QtObject {
property string highlightColor: "#4a90e2"
property int height: 25
property int fileNameHeight: 30
property int fontSize: 13
property int sectionFontSize: 13
property int fontSize: absoluteSize(2)// 13
property int sectionFontSize: absoluteSize(2)// 13
}
}

21
mix/qml/ProjectList.qml

@ -20,8 +20,8 @@ Item {
Rectangle
{
color: Style.title.background
height: Style.title.height
color: ProjectFilesStyle.title.background
height: ProjectFilesStyle.title.height
Layout.fillWidth: true
Image {
id: projectIcon
@ -35,14 +35,14 @@ Item {
Text
{
id: projectTitle
color: Style.title.color
color: ProjectFilesStyle.title.color
text: projectModel.projectTitle
anchors.verticalCenter: parent.verticalCenter
visible: !projectModel.isEmpty;
anchors.left: parent.left
anchors.leftMargin: Style.general.leftMargin
anchors.leftMargin: ProjectFilesStyle.general.leftMargin
font.family: srcSansProLight.name
font.pointSize: Style.title.pointSize
font.pointSize: ProjectFilesStyle.title.fontSize
font.weight: Font.Light
}
@ -52,7 +52,7 @@ Item {
anchors.right: parent.right
anchors.rightMargin: 15
font.family: srcSansProLight.name
font.pointSize: Style.title.pointSize
font.pointSize: ProjectFilesStyle.title.fontSize
anchors.verticalCenter: parent.verticalCenter
font.weight: Font.Light
}
@ -62,7 +62,7 @@ Item {
{
Layout.fillWidth: true
height: 10
color: Style.documentsList.background
color: ProjectFilesStyle.documentsList.background
}
@ -71,7 +71,7 @@ Item {
{
Layout.fillWidth: true
Layout.fillHeight: true
color: Style.documentsList.background
color: ProjectFilesStyle.documentsList.background
ColumnLayout
{
@ -137,7 +137,12 @@ Item {
sectionModel.clear();
}
onProjectClosed: {
sectionModel.clear();
}
onProjectLoaded: {
sectionModel.clear();
addDocToSubModel();
if (modelData === "Contracts")
{

26
mix/qml/ProjectModel.qml

@ -34,11 +34,9 @@ Item {
//interface
function saveAll() { ProjectModelCode.saveAll(); }
function createProject() { ProjectModelCode.createProject(); }
function browseProject() { ProjectModelCode.browseProject(); }
function closeProject() { ProjectModelCode.closeProject(); }
function saveProject() { ProjectModelCode.saveProject(); }
function loadProject(path) { ProjectModelCode.loadProject(path); }
function addExistingFile() { ProjectModelCode.addExistingFile(); }
function newHtmlFile() { ProjectModelCode.newHtmlFile(); }
function newJsFile() { ProjectModelCode.newJsFile(); }
function newCssFile() { ProjectModelCode.newCssFile(); }
@ -50,6 +48,7 @@ Item {
function removeDocument(documentId) { ProjectModelCode.removeDocument(documentId); }
function getDocument(documentId) { return ProjectModelCode.getDocument(documentId); }
function getDocumentIndex(documentId) { return ProjectModelCode.getDocumentIndex(documentId); }
function doAddExistingFiles(paths) { ProjectModelCode.doAddExistingFiles(paths); }
Connections {
target: appContext
@ -96,27 +95,4 @@ Item {
id: projectSettings
property string lastProjectPath;
}
FileDialog {
id: openProjectFileDialog
visible: false
title: qsTr("Open a Project")
selectFolder: true
onAccepted: {
var path = openProjectFileDialog.fileUrl.toString();
path += "/";
loadProject(path);
}
}
FileDialog {
id: addExistingFileDialog
visible: false
title: qsTr("Add a File")
selectFolder: false
onAccepted: {
var paths = addExistingFileDialog.fileUrls;
ProjectModelCode.doAddExistingFiles(paths);
}
}
}

3
mix/qml/StateDialog.qml

@ -5,6 +5,7 @@ import QtQuick.Window 2.0
import org.ethereum.qml.QEther 1.0
import "js/QEtherHelper.js" as QEtherHelper
import "js/TransactionHelper.js" as TransactionHelper
import "."
Window {
id: modalStateDialog
@ -158,7 +159,7 @@ Window {
Layout.fillWidth: true
Layout.fillHeight: true
text: functionId
font.pointSize: 12
font.pointSize: StateStyle.general.basicFontSize //12
verticalAlignment: Text.AlignBottom
}
ToolButton {

3
mix/qml/StateList.qml

@ -4,6 +4,7 @@ import QtQuick.Controls 1.1
import QtQuick.Dialogs 1.1
import QtQuick.Layouts 1.1
import QtQuick.Window 2.0
import "."
Window {
id: stateListContainer
@ -45,7 +46,7 @@ Window {
Layout.fillWidth: true
Layout.fillHeight: true
text: styleData.value
font.pointSize: 12
font.pointSize: StateStyle.general.basicFontSize
verticalAlignment: Text.AlignBottom
}
ToolButton {

14
mix/qml/StateStyle.qml

@ -0,0 +1,14 @@
pragma Singleton
import QtQuick 2.0
QtObject {
function absoluteSize(rel)
{
return systemPointSize + rel;
}
property QtObject general: QtObject {
property int basicFontSize: absoluteSize(1)
}
}

5
mix/qml/StatusPane.qml

@ -2,6 +2,7 @@ import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import "js/ErrorLocationFormater.js" as ErrorLocationFormater
import "."
Rectangle {
id: statusHeader
@ -59,7 +60,7 @@ Rectangle {
spacing: 5
Text {
font.pointSize: 10
font.pointSize: StatusPaneStyle.general.statusFontSize
height: 9
font.family: "sans serif"
objectName: "status"
@ -81,7 +82,7 @@ Rectangle {
Text {
visible: false
font.pointSize: 9
font.pointSize: StatusPaneStyle.general.logLinkFontSize
height: 9
text: qsTr("See Log.")
font.family: "Monospace"

15
mix/qml/StatusPaneStyle.qml

@ -0,0 +1,15 @@
pragma Singleton
import QtQuick 2.0
QtObject {
function absoluteSize(rel)
{
return systemPointSize + rel;
}
property QtObject general: QtObject {
property int statusFontSize: absoluteSize(-1)
property int logLinkFontSize: absoluteSize(-2)
}
}

8
mix/qml/js/ProjectModel.js

@ -28,10 +28,6 @@ function createProject() {
newProjectDialog.open();
}
function browseProject() {
openProjectFileDialog.open();
}
function closeProject() {
if (!isEmpty) {
if (haveUnsavedChanges)
@ -77,10 +73,6 @@ function loadProject(path) {
projectLoaded()
}
function addExistingFile() {
addExistingFileDialog.open();
}
function addFile(fileName) {
var p = projectPath + fileName;
var extension = fileName.substring(fileName.lastIndexOf("."), fileName.length);

27
mix/qml/main.qml

@ -203,7 +203,19 @@ ApplicationWindow {
text: qsTr("&Open Project")
shortcut: "Ctrl+O"
enabled: true;
onTriggered: projectModel.browseProject();
onTriggered: openProjectFileDialog.open()
}
FileDialog {
id: openProjectFileDialog
visible: false
title: qsTr("Open a Project")
selectFolder: true
onAccepted: {
var path = openProjectFileDialog.fileUrl.toString();
path += "/";
projectModel.loadProject(path);
}
}
Action {
@ -243,7 +255,18 @@ ApplicationWindow {
text: qsTr("Add Existing File")
shortcut: "Ctrl+Alt+A"
enabled: !projectModel.isEmpty
onTriggered: projectModel.addExistingFile();
onTriggered: addExistingFileDialog.open()
}
FileDialog {
id: addExistingFileDialog
visible: false
title: qsTr("Add a File")
selectFolder: false
onAccepted: {
var paths = addExistingFileDialog.fileUrls;
projectModel.doAddExistingFiles(paths);
}
}
Action {

5
mix/qml/qmldir

@ -1 +1,4 @@
singleton Style 1.0 Style.qml
singleton ProjectFilesStyle 1.0 ProjectFilesStyle.qml
singleton DebuggerPaneStyle 1.0 DebuggerPaneStyle.qml
singleton StateStyle 1.0 StateStyle.qml
singleton StatusPaneStyle 1.0 StatusPaneStyle.qml

7
mix/res.qrc

@ -2,7 +2,6 @@
<qresource prefix="/">
<file>qml/main.qml</file>
<file>qml/AlertMessageDialog.qml</file>
<file>qml/BasicContent.qml</file>
<file>qml/BasicMessage.qml</file>
<file>qml/Debugger.qml</file>
<file>qml/MainContent.qml</file>
@ -62,7 +61,6 @@
<file>qml/TransactionLog.qml</file>
<file>res/mix_256x256x32.png</file>
<file>qml/QVariableDeclaration.qml</file>
<file>qml/Style.qml</file>
<file>qml/qmldir</file>
<file>qml/FilesSection.qml</file>
<file>qml/fonts/SourceSansPro-Black.ttf</file>
@ -83,5 +81,10 @@
<file>qml/img/closedtriangleindicator_filesproject.png</file>
<file>qml/img/opentriangleindicator_filesproject.png</file>
<file>qml/img/projecticon.png</file>
<file>qml/ProjectFilesStyle.qml</file>
<file>qml/DebuggerPaneStyle.qml</file>
<file>qml/CodeEditorStyle.qml</file>
<file>qml/StatusPaneStyle.qml</file>
<file>qml/StateStyle.qml</file>
</qresource>
</RCC>

53
test/SolidityEndToEndTest.cpp

@ -56,6 +56,36 @@ BOOST_AUTO_TEST_CASE(empty_contract)
BOOST_CHECK(callContractFunction("i_am_not_there()", bytes()).empty());
}
BOOST_AUTO_TEST_CASE(exp_operator)
{
char const* sourceCode = R"(
contract test {
function f(uint a) returns(uint d) { return 2 ** a; }
})";
compileAndRun(sourceCode);
testSolidityAgainstCppOnRange("f(uint256)", [](u256 const& a) -> u256 { return u256(1 << a.convert_to<int>()); }, 0, 16);
}
BOOST_AUTO_TEST_CASE(exp_operator_const)
{
char const* sourceCode = R"(
contract test {
function f() returns(uint d) { return 2 ** 3; }
})";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("f()", bytes()) == toBigEndian(u256(8)));
}
BOOST_AUTO_TEST_CASE(exp_operator_const_signed)
{
char const* sourceCode = R"(
contract test {
function f() returns(int d) { return (-2) ** 3; }
})";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("f()", bytes()) == toBigEndian(u256(-8)));
}
BOOST_AUTO_TEST_CASE(recursive_calls)
{
char const* sourceCode = "contract test {\n"
@ -2201,6 +2231,29 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_string_literals)
bytes({0x66, 0x6f, 0x6f}))));
}
BOOST_AUTO_TEST_CASE(generic_call)
{
char const* sourceCode = R"**(
contract receiver {
uint public received;
function receive(uint256 x) { received = x; }
}
contract sender {
function doSend(address rec) returns (uint d)
{
string4 signature = string4(string32(sha3("receive(uint256)")));
rec.call.value(2)(signature, 23);
return receiver(rec).received();
}
}
)**";
compileAndRun(sourceCode, 0, "receiver");
u160 const c_receiverAddress = m_contractAddress;
compileAndRun(sourceCode, 50, "sender");
BOOST_REQUIRE(callContractFunction("doSend(address)", c_receiverAddress) == encodeArgs(23));
BOOST_CHECK_EQUAL(m_state.balance(m_contractAddress), 50 - 2);
}
BOOST_AUTO_TEST_SUITE_END()
}

18
test/SolidityNameAndTypeResolution.cpp

@ -974,6 +974,24 @@ BOOST_AUTO_TEST_CASE(overflow_caused_by_ether_units)
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
}
BOOST_AUTO_TEST_CASE(exp_operator_negative_exponent)
{
char const* sourceCode = R"(
contract test {
function f() returns(uint d) { return 2 ** -3; }
})";
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
}
BOOST_AUTO_TEST_CASE(exp_operator_exponent_too_big)
{
char const* sourceCode = R"(
contract test {
function f() returns(uint d) { return 2 ** 10000000000; }
})";
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
}
BOOST_AUTO_TEST_SUITE_END()
}

11
test/SolidityParser.cpp

@ -387,6 +387,17 @@ BOOST_AUTO_TEST_CASE(complex_expression)
BOOST_CHECK_NO_THROW(parseText(text));
}
BOOST_AUTO_TEST_CASE(exp_expression)
{
char const* text = R"(
contract test {
function fun(uint256 a) {
uint256 x = 3 ** a;
}
})";
BOOST_CHECK_NO_THROW(parseText(text));
}
BOOST_AUTO_TEST_CASE(while_loop)
{
char const* text = "contract test {\n"

3
test/TestHelper.cpp

@ -64,6 +64,9 @@ void connectClients(Client& c1, Client& c2)
namespace test
{
struct ValueTooLarge: virtual Exception {};
bigint const c_max256plus1 = bigint(1) << 256;
ImportTest::ImportTest(json_spirit::mObject& _o, bool isFiller): m_TestObject(_o)
{
importEnv(_o["env"].get_obj());

3
test/TestHelper.h

@ -42,9 +42,6 @@ void connectClients(Client& c1, Client& c2);
namespace test
{
struct ValueTooLarge: virtual Exception {};
bigint const c_max256plus1 = bigint(1) << 256;
class ImportTest
{
public:

Loading…
Cancel
Save