diff --git a/src/java_bytecode/java_bytecode_convert_class.cpp b/src/java_bytecode/java_bytecode_convert_class.cpp index 93a473cf9b4..2d6d2d5d814 100644 --- a/src/java_bytecode/java_bytecode_convert_class.cpp +++ b/src/java_bytecode/java_bytecode_convert_class.cpp @@ -310,6 +310,18 @@ void java_bytecode_convert_classt::convert(const classt &c) } } + // now do lambda method handles (bootstrap methods) + for(const auto &lambda_entry : c.lambda_method_handle_map) + { + // if the handle is of unknown type, we still need to store it to preserve + // the correct indexing (invokedynamic instructions will retrieve + // method handles by index) + lambda_entry.second.is_unknown_handle() + ? class_type.add_unknown_lambda_method_handle() + : class_type.add_lambda_method_handle( + "java::" + id2string(lambda_entry.second.lambda_method_ref)); + } + // produce class symbol symbolt new_symbol; new_symbol.base_name=c.name; diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 7d4007add8a..d801c67aaed 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -306,6 +306,25 @@ code_typet member_type_lazy( return to_code_type(member_type_from_descriptor); } +/// Retrieves the symbol of the lambda method associated with the given +/// lambda method handle (bootstrap method). +/// \param lambda_method_handles Vector of lambda method handles (bootstrap +/// methods) of the class where the lambda is called +/// \param index Index of the lambda method handle in the vector +/// \return Symbol of the lambda method if the method handle does not have an +/// unknown type +optionalt java_bytecode_convert_methodt::get_lambda_method_symbol( + const java_class_typet::java_lambda_method_handlest &lambda_method_handles, + const size_t &index) +{ + const symbol_exprt &lambda_method_handle = lambda_method_handles.at(index); + // If the lambda method handle has an unknown type, it does not refer to + // any symbol (it is a symbol expression with empty identifier) + if(!lambda_method_handle.get_identifier().empty()) + return symbol_table.lookup_ref(lambda_method_handle.get_identifier()); + return {}; +} + /// This creates a method symbol in the symtab, but doesn't actually perform /// method conversion just yet. The caller should call /// java_bytecode_convert_method later to give the symbol/method a body. @@ -555,7 +574,11 @@ void java_bytecode_convert_methodt::convert( current_method=method_symbol.name; method_has_this=code_type.has_this(); if((!m.is_abstract) && (!m.is_native)) - method_symbol.value=convert_instructions(m, code_type, method_symbol.name); + method_symbol.value = convert_instructions( + m, + code_type, + method_symbol.name, + to_java_class_type(class_symbol.type).lambda_method_handles()); } const bytecode_infot &java_bytecode_convert_methodt::get_bytecode_info( @@ -926,7 +949,8 @@ static unsigned get_bytecode_type_width(const typet &ty) codet java_bytecode_convert_methodt::convert_instructions( const methodt &method, const code_typet &method_type, - const irep_idt &method_name) + const irep_idt &method_name, + const java_class_typet::java_lambda_method_handlest &lambda_method_handles) { const instructionst &instructions=method.instructions; @@ -1211,7 +1235,19 @@ codet java_bytecode_convert_methodt::convert_instructions( else if(statement=="invokedynamic") { // not used in Java - code_typet &code_type=to_code_type(arg0.type()); + code_typet &code_type = to_code_type(arg0.type()); + + const optionalt &lambda_method_symbol = get_lambda_method_symbol( + lambda_method_handles, + code_type.get_int(ID_java_lambda_method_handle_index)); + if(lambda_method_symbol.has_value()) + debug() << "Converting invokedynamic for lambda: " + << lambda_method_symbol.value().name << eom; + else + debug() << "Converting invokedynamic for lambda with unknown handle " + "type" + << eom; + const code_typet::parameterst ¶meters(code_type.parameters()); pop(parameters.size()); diff --git a/src/java_bytecode/java_bytecode_convert_method_class.h b/src/java_bytecode/java_bytecode_convert_method_class.h index 930bc62ae62..aa3a008faaf 100644 --- a/src/java_bytecode/java_bytecode_convert_method_class.h +++ b/src/java_bytecode/java_bytecode_convert_method_class.h @@ -235,13 +235,18 @@ class java_bytecode_convert_methodt:public messaget const address_mapt &amap, bool allow_merge=true); + optionalt get_lambda_method_symbol( + const java_class_typet::java_lambda_method_handlest &lambda_method_handles, + const size_t &index); + // conversion void convert(const symbolt &class_symbol, const methodt &); codet convert_instructions( const methodt &, const code_typet &, - const irep_idt &); + const irep_idt &, + const java_class_typet::java_lambda_method_handlest &); const bytecode_infot &get_bytecode_info(const irep_idt &statement); diff --git a/src/java_bytecode/java_bytecode_parse_tree.h b/src/java_bytecode/java_bytecode_parse_tree.h index 09d96ac0356..844104a1e1e 100644 --- a/src/java_bytecode/java_bytecode_parse_tree.h +++ b/src/java_bytecode/java_bytecode_parse_tree.h @@ -189,6 +189,7 @@ class java_bytecode_parse_treet public: method_handle_typet handle_type; irep_idt lambda_method_name; + irep_idt lambda_method_ref; irep_idt interface_type; irep_idt method_type; u2_valuest u2_values; @@ -204,6 +205,11 @@ class java_bytecode_parse_treet lambda_method_handle.u2_values = std::move(params); return lambda_method_handle; } + + bool is_unknown_handle() const + { + return handle_type == method_handle_typet::UNKNOWN_HANDLE; + } }; // TODO(tkiley): This map shouldn't be interacted with directly (instead diff --git a/src/java_bytecode/java_bytecode_parser.cpp b/src/java_bytecode/java_bytecode_parser.cpp index e721962cde6..46ab444d380 100644 --- a/src/java_bytecode/java_bytecode_parser.cpp +++ b/src/java_bytecode/java_bytecode_parser.cpp @@ -843,6 +843,7 @@ void java_bytecode_parsert::rconstant_pool() it->expr.id("invokedynamic"); const pool_entryt &nameandtype_entry=pool_entry(it->ref2); typet type=type_entry(nameandtype_entry.ref2); + type.set(ID_java_lambda_method_handle_index, it->ref1); it->expr.type()=type; } break; @@ -1776,9 +1777,9 @@ java_bytecode_parsert::parse_method_handle(const method_handle_infot &entry) const name_and_type_infot &name_and_type = ref_entry.get_name_and_type(pool_entry_lambda); - const std::string method_name = + const std::string method_ref = class_entry.get_name(pool_entry_lambda) + "." + - name_and_type.get_name(pool_entry_lambda) + + name_and_type.get_name(pool_entry_lambda) + ':' + name_and_type.get_descriptor(pool_entry_lambda); lambda_method_handlet lambda_method_handle; @@ -1791,6 +1792,7 @@ java_bytecode_parsert::parse_method_handle(const method_handle_infot &entry) // "new" when it is a class variable, instantiated in lambda_method_handle.lambda_method_name = name_and_type.get_name(pool_entry_lambda); + lambda_method_handle.lambda_method_ref = method_ref; lambda_method_handle.handle_type = method_handle_typet::LAMBDA_METHOD_HANDLE; diff --git a/src/java_bytecode/java_types.h b/src/java_bytecode/java_types.h index 59a2e0e146d..aba2e12a820 100644 --- a/src/java_bytecode/java_types.h +++ b/src/java_bytecode/java_types.h @@ -17,6 +17,7 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include class java_class_typet:public class_typet { @@ -30,6 +31,30 @@ class java_class_typet:public class_typet { return set(ID_access, access); } + + typedef std::vector java_lambda_method_handlest; + + const java_lambda_method_handlest &lambda_method_handles() const + { + return (const java_lambda_method_handlest &)find( + ID_java_lambda_method_handles) + .get_sub(); + } + + java_lambda_method_handlest &lambda_method_handles() + { + return (java_lambda_method_handlest &)add(ID_java_lambda_method_handles) + .get_sub(); + } + + void add_lambda_method_handle(const irep_idt &identifier) + { + lambda_method_handles().emplace_back(identifier); + } + void add_unknown_lambda_method_handle() + { + lambda_method_handles().emplace_back(); + } }; inline const java_class_typet &to_java_class_type(const typet &type) diff --git a/src/util/irep_ids.def b/src/util/irep_ids.def index ca224b6114e..643377bf4fc 100644 --- a/src/util/irep_ids.def +++ b/src/util/irep_ids.def @@ -836,6 +836,8 @@ IREP_ID_TWO(C_java_generic_symbol, #java_generic_symbol) IREP_ID_TWO(generic_types, #generic_types) IREP_ID_TWO(implicit_generic_types, #implicit_generic_types) IREP_ID_TWO(type_variables, #type_variables) +IREP_ID_TWO(java_lambda_method_handle_index, lambda_method_handle_index) +IREP_ID_TWO(java_lambda_method_handles, lambda_method_handles) IREP_ID_ONE(havoc_object) IREP_ID_TWO(overflow_shl, overflow-shl) IREP_ID_TWO(C_no_initialization_required, #no_initialization_required) diff --git a/unit/Makefile b/unit/Makefile index 540410f56c1..c3872f7a98b 100644 --- a/unit/Makefile +++ b/unit/Makefile @@ -23,6 +23,8 @@ SRC += unit_tests.cpp \ java_bytecode/java_bytecode_convert_class/convert_abstract_class.cpp \ java_bytecode/java_bytecode_parse_generics/parse_generic_class.cpp \ java_bytecode/java_object_factory/gen_nondet_string_init.cpp \ + java_bytecode/java_bytecode_parse_lambdas/java_bytecode_parse_lambda_method_table.cpp \ + java_bytecode/java_bytecode_parse_lambdas/java_bytecode_convert_class_lambda_method_handles.cpp \ miniBDD_new.cpp \ java_bytecode/java_string_library_preprocess/convert_exprt_to_string_exprt.cpp \ java_bytecode/java_utils_test.cpp \ diff --git a/unit/java_bytecode/ci_lazy_methods/lazy_load_lambdas.cpp b/unit/java_bytecode/ci_lazy_methods/lazy_load_lambdas.cpp index 67d993a3304..e83fa65af09 100644 --- a/unit/java_bytecode/ci_lazy_methods/lazy_load_lambdas.cpp +++ b/unit/java_bytecode/ci_lazy_methods/lazy_load_lambdas.cpp @@ -18,7 +18,7 @@ SCENARIO( { const symbol_tablet symbol_table = load_java_class_lazy( "LocalLambdas", - "./java_bytecode/java_bytecode_parser/lambda_examples/", + "./java_bytecode/java_bytecode_parse_lambdas/lambda_examples/", "LocalLambdas.test"); THEN("Then the lambdas should be loaded") @@ -68,7 +68,7 @@ SCENARIO( { const symbol_tablet symbol_table = load_java_class_lazy( "MemberLambdas", - "./java_bytecode/java_bytecode_parser/lambda_examples/", + "./java_bytecode/java_bytecode_parse_lambdas/lambda_examples/", "MemberLambdas.test"); THEN("Then the lambdas should be loaded") @@ -117,7 +117,7 @@ SCENARIO( { const symbol_tablet symbol_table = load_java_class_lazy( "StaticLambdas", - "./java_bytecode/java_bytecode_parser/lambda_examples/", + "./java_bytecode/java_bytecode_parse_lambdas/lambda_examples/", "StaticLambdas.test"); THEN("Then the lambdas should be loaded") @@ -166,7 +166,7 @@ SCENARIO( { const symbol_tablet symbol_table = load_java_class_lazy( "OuterMemberLambdas$Inner", - "./java_bytecode/java_bytecode_parser/lambda_examples/", + "./java_bytecode/java_bytecode_parse_lambdas/lambda_examples/", "OuterMemberLambdas$Inner.test"); THEN("Then the lambdas should be loaded") @@ -192,7 +192,7 @@ SCENARIO( { const symbol_tablet symbol_table = load_java_class_lazy( "ExternalLambdaAccessor", - "./java_bytecode/java_bytecode_parser/lambda_examples/", + "./java_bytecode/java_bytecode_parse_lambdas/lambda_examples/", "ExternalLambdaAccessor.test"); THEN("Then the lambdas should be loaded") diff --git a/unit/java_bytecode/java_bytecode_parse_lambdas/java_bytecode_convert_class_lambda_method_handles.cpp b/unit/java_bytecode/java_bytecode_parse_lambdas/java_bytecode_convert_class_lambda_method_handles.cpp new file mode 100644 index 00000000000..f83dfc4341f --- /dev/null +++ b/unit/java_bytecode/java_bytecode_parse_lambdas/java_bytecode_convert_class_lambda_method_handles.cpp @@ -0,0 +1,262 @@ +/*******************************************************************\ + + Module: Unit tests for parsing generic classes + + Author: Diffblue Ltd. + +\*******************************************************************/ + +#include + +#include +#include +#include +#include + +SCENARIO( + "Static lambdas in class symbol", + "[core][java_bytecode][java_bytecode_convert_class_lambda_method_handles]") +{ + // NOLINTNEXTLINE(whitespace/braces) + run_test_with_compilers([](const std::string &compiler) { + GIVEN( + "A class with static lambda variables from " + compiler + " compiler.") + { + const symbol_tablet &new_symbol_table = load_java_class( + "StaticLambdas", + "./java_bytecode/java_bytecode_parse_lambdas/lambda_examples/" + + compiler + "_classes/"); + + std::string class_prefix = "java::StaticLambdas"; + REQUIRE(new_symbol_table.has_symbol(class_prefix)); + + const symbolt &class_symbol = new_symbol_table.lookup_ref(class_prefix); + + THEN("The class has the correct list of lambda method handles") + { + std::vector lambda_identifiers; + if(compiler == "eclipse") + { + // NOLINTNEXTLINE(whitespace/braces) + lambda_identifiers = { + "java::StaticLambdas.lambda$0:()V", + "java::StaticLambdas.lambda$1:(ILjava/lang/Object;LDummyGeneric;)V", + "java::StaticLambdas.lambda$2:([I[Ljava/lang/" + "Object;[LDummyGeneric;)V", + "java::StaticLambdas.lambda$3:()I", + "java::StaticLambdas.lambda$4:()Ljava/lang/Object;", + "java::StaticLambdas.lambda$5:()LDummyGeneric;", + "java::StaticLambdas.lambda$6:()[I", + "java::StaticLambdas.lambda$7:()[Ljava/lang/Object;", + "java::StaticLambdas.lambda$8:()[LDummyGeneric;", + "java::StaticLambdas.lambda$9:()I", + "java::StaticLambdas.lambda$10:()Ljava/lang/Object;", + "java::StaticLambdas.lambda$11:()LDummyGeneric;"}; + } + else + { + // NOLINTNEXTLINE(whitespace/braces) + lambda_identifiers = { + "java::StaticLambdas.lambda$static$0:()V", + "java::StaticLambdas.lambda$static$1:(ILjava/lang/" + "Object;LDummyGeneric;)V", + "java::StaticLambdas.lambda$static$2:([I[Ljava/lang/" + "Object;[LDummyGeneric;)V", + "java::StaticLambdas.lambda$static$3:()I", + "java::StaticLambdas.lambda$static$4:()Ljava/lang/Object;", + "java::StaticLambdas.lambda$static$5:()LDummyGeneric;", + "java::StaticLambdas.lambda$static$6:()[I", + "java::StaticLambdas.lambda$static$7:()[Ljava/lang/Object;", + "java::StaticLambdas.lambda$static$8:()[LDummyGeneric;", + "java::StaticLambdas.lambda$static$9:()I", + "java::StaticLambdas.lambda$static$10:()Ljava/lang/Object;", + "java::StaticLambdas.lambda$static$11:()LDummyGeneric;"}; + } + require_type::require_lambda_method_handles( + to_java_class_type(class_symbol.type), lambda_identifiers); + } + } + }); +} + +SCENARIO( + "Local lambdas in class symbol", + "[core][java_bytecode][java_bytecode_convert_class_lambda_method_handles]") +{ + // NOLINTNEXTLINE(whitespace/braces) + run_test_with_compilers([](const std::string &compiler) { + GIVEN( + "A class with static lambda variables from " + compiler + " compiler.") + { + const symbol_tablet &new_symbol_table = load_java_class( + "LocalLambdas", + "./java_bytecode/java_bytecode_parse_lambdas/lambda_examples/" + + compiler + "_classes/"); + + std::string class_prefix = "java::LocalLambdas"; + REQUIRE(new_symbol_table.has_symbol(class_prefix)); + + const symbolt &class_symbol = new_symbol_table.lookup_ref(class_prefix); + + THEN("The class has the correct list of lambda method handles") + { + std::vector lambda_identifiers; + if(compiler == "eclipse") + { + // NOLINTNEXTLINE(whitespace/braces) + lambda_identifiers = { + "java::LocalLambdas.lambda$0:()V", + "java::LocalLambdas.lambda$1:(ILjava/lang/Object;" + "LDummyGeneric;)V", + "java::LocalLambdas.lambda$2:([I[Ljava/lang/Object;" + "[LDummyGeneric;)V", + "java::LocalLambdas.lambda$3:()I", + "java::LocalLambdas.lambda$4:()Ljava/lang/Object;", + "java::LocalLambdas.lambda$5:()LDummyGeneric;", + "java::LocalLambdas.lambda$6:()[I", + "java::LocalLambdas.lambda$7:()[Ljava/lang/Object;", + "java::LocalLambdas.lambda$8:()[LDummyGeneric;", + "java::LocalLambdas.lambda$9:(I)I", + "java::LocalLambdas.lambda$10:(Ljava/lang/Object;)" + "Ljava/lang/Object;", + "java::LocalLambdas.lambda$11:(LDummyGeneric;)" + "LDummyGeneric;"}; + } + else + { + // NOLINTNEXTLINE(whitespace/braces) + lambda_identifiers = { + "java::LocalLambdas.lambda$test$0:()V", + "java::LocalLambdas.lambda$test$1:(ILjava/lang/Object;" + "LDummyGeneric;)V", + "java::LocalLambdas.lambda$test$2:([I[Ljava/lang/Object;" + "[LDummyGeneric;)V", + "java::LocalLambdas.lambda$test$3:()I", + "java::LocalLambdas.lambda$test$4:()Ljava/lang/Object;", + "java::LocalLambdas.lambda$test$5:()LDummyGeneric;", + "java::LocalLambdas.lambda$test$6:()[I", + "java::LocalLambdas.lambda$test$7:()[Ljava/lang/Object;", + "java::LocalLambdas.lambda$test$8:()[LDummyGeneric;", + "java::LocalLambdas.lambda$test$9:(I)I", + "java::LocalLambdas.lambda$test$10:(Ljava/lang/Object;)" + "Ljava/lang/Object;", + "java::LocalLambdas.lambda$test$11:(LDummyGeneric;)" + "LDummyGeneric;"}; + } + require_type::require_lambda_method_handles( + to_java_class_type(class_symbol.type), lambda_identifiers); + } + } + }); +} + +SCENARIO( + "Member lambdas in class symbol", + "[core][java_bytecode][java_bytecode_convert_class_lambda_method_handles]") +{ + // NOLINTNEXTLINE(whitespace/braces) + run_test_with_compilers([](const std::string &compiler) { + GIVEN( + "A class with static lambda variables from " + compiler + " compiler.") + { + const symbol_tablet &new_symbol_table = load_java_class( + "MemberLambdas", + "./java_bytecode/java_bytecode_parse_lambdas/lambda_examples/" + + compiler + "_classes/"); + + std::string class_prefix = "java::MemberLambdas"; + REQUIRE(new_symbol_table.has_symbol(class_prefix)); + + const symbolt &class_symbol = new_symbol_table.lookup_ref(class_prefix); + + THEN("The class has the correct list of lambda method handles") + { + std::vector lambda_identifiers; + if(compiler == "eclipse") + { + // NOLINTNEXTLINE(whitespace/braces) + lambda_identifiers = { + "java::MemberLambdas.lambda$0:()V", + "java::MemberLambdas.lambda$1:(ILjava/lang/Object;LDummyGeneric;)V", + "java::MemberLambdas.lambda$2:([I[Ljava/lang/" + "Object;[LDummyGeneric;)V", + "java::MemberLambdas.lambda$3:()I", + "java::MemberLambdas.lambda$4:()Ljava/lang/Object;", + "java::MemberLambdas.lambda$5:()LDummyGeneric;", + "java::MemberLambdas.lambda$6:()[I", + "java::MemberLambdas.lambda$7:()[Ljava/lang/Object;", + "java::MemberLambdas.lambda$8:()[LDummyGeneric;", + "java::MemberLambdas.lambda$9:()I", + "java::MemberLambdas.lambda$10:()Ljava/lang/Object;", + "java::MemberLambdas.lambda$11:()LDummyGeneric;"}; + } + else + { + // NOLINTNEXTLINE(whitespace/braces) + lambda_identifiers = { + "java::MemberLambdas.lambda$new$0:()V", + "java::MemberLambdas.lambda$new$1:(ILjava/lang/" + "Object;LDummyGeneric;)V", + "java::MemberLambdas.lambda$new$2:([I[Ljava/lang/" + "Object;[LDummyGeneric;)V", + "java::MemberLambdas.lambda$new$3:()I", + "java::MemberLambdas.lambda$new$4:()Ljava/lang/Object;", + "java::MemberLambdas.lambda$new$5:()LDummyGeneric;", + "java::MemberLambdas.lambda$new$6:()[I", + "java::MemberLambdas.lambda$new$7:()[Ljava/lang/Object;", + "java::MemberLambdas.lambda$new$8:()[LDummyGeneric;", + "java::MemberLambdas.lambda$new$9:()I", + "java::MemberLambdas.lambda$new$10:()Ljava/lang/Object;", + "java::MemberLambdas.lambda$new$11:()LDummyGeneric;"}; + } + require_type::require_lambda_method_handles( + to_java_class_type(class_symbol.type), lambda_identifiers); + } + } + }); +} + +SCENARIO( + "Member lambdas capturing outer class variables in class symbol", + "[core][java_bytecode][java_bytecode_convert_class_lambda_method_handles]") +{ + // NOLINTNEXTLINE(whitespace/braces) + run_test_with_compilers([](const std::string &compiler) { + GIVEN( + "A class with static lambda variables from " + compiler + " compiler.") + { + const symbol_tablet &new_symbol_table = load_java_class( + "OuterMemberLambdas$Inner", + "./java_bytecode/java_bytecode_parse_lambdas/lambda_examples/" + + compiler + "_classes/"); + + std::string class_prefix = "java::OuterMemberLambdas$Inner"; + REQUIRE(new_symbol_table.has_symbol(class_prefix)); + + const symbolt &class_symbol = new_symbol_table.lookup_ref(class_prefix); + + THEN("The class has the correct list of lambda method handles") + { + std::vector lambda_identifiers; + if(compiler == "eclipse") + { + // NOLINTNEXTLINE(whitespace/braces) + lambda_identifiers = { + "java::OuterMemberLambdas$Inner.lambda$0:()I", + "java::OuterMemberLambdas$Inner.lambda$1:()Ljava/lang/Object;", + "java::OuterMemberLambdas$Inner.lambda$2:()LDummyGeneric;"}; + } + else + { + // NOLINTNEXTLINE(whitespace/braces) + lambda_identifiers = { + "java::OuterMemberLambdas$Inner.lambda$new$0:()I", + "java::OuterMemberLambdas$Inner.lambda$new$1:()Ljava/lang/Object;", + "java::OuterMemberLambdas$Inner.lambda$new$2:()LDummyGeneric;"}; + } + require_type::require_lambda_method_handles( + to_java_class_type(class_symbol.type), lambda_identifiers); + } + } + }); +} diff --git a/unit/java_bytecode/java_bytecode_parser/java_bytecode_parse_lambda_method_table.cpp b/unit/java_bytecode/java_bytecode_parse_lambdas/java_bytecode_parse_lambda_method_table.cpp similarity index 63% rename from unit/java_bytecode/java_bytecode_parser/java_bytecode_parse_lambda_method_table.cpp rename to unit/java_bytecode/java_bytecode_parse_lambdas/java_bytecode_parse_lambda_method_table.cpp index 20c93c4da81..5b6eb8a8ddf 100644 --- a/unit/java_bytecode/java_bytecode_parser/java_bytecode_parse_lambda_method_table.cpp +++ b/unit/java_bytecode/java_bytecode_parse_lambdas/java_bytecode_parse_lambda_method_table.cpp @@ -18,19 +18,11 @@ #include #include +#include typedef java_bytecode_parse_treet::classt::lambda_method_handlet lambda_method_handlet; -void run_test_with_compilers( - const std::function &test_with_compiler) -{ - test_with_compiler("openjdk_8"); - test_with_compiler("eclipse"); - test_with_compiler("oracle_8"); - test_with_compiler("oracle_9"); -} - SCENARIO( "lambda_method_handle_map with static lambdas", "[core][java_bytecode][java_bytecode_parse_lambda_method_handle]") @@ -43,8 +35,8 @@ SCENARIO( { java_bytecode_parse_treet parse_tree; java_bytecode_parse( - "./java_bytecode/java_bytecode_parser/lambda_examples/" + compiler + - "_classes/StaticLambdas.class", + "./java_bytecode/java_bytecode_parse_lambdas/lambda_examples/" + + compiler + "_classes/StaticLambdas.class", parse_tree, message_handler); WHEN("Parsing that class") @@ -61,180 +53,212 @@ SCENARIO( "returns and the method it references should have an appropriate " "descriptor") { + const std::string lambda_method_ref = + compiler == "eclipse" ? "StaticLambdas.lambda$0:()V" + : "StaticLambdas.lambda$static$0:()V"; + const std::string method_type = "()V"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, "()V"); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method(parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == "()V"); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } // Parameter lambdas THEN( "There should be an entry for the lambda that takes parameters and " - "the " - "method it references should have an appropriate descriptor") + "the method it references should have an appropriate descriptor") { - std::string descriptor = "(ILjava/lang/Object;LDummyGeneric;)V"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "StaticLambdas.lambda$1:(ILjava/lang/Object;LDummyGeneric;)V" + : "StaticLambdas.lambda$static$1:(ILjava/lang/" + "Object;LDummyGeneric;)V"; + const std::string method_type = + "(ILjava/lang/Object;LDummyGeneric;)V"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method(parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } THEN( "There should be an entry for the lambda that takes array " - "parameters " - "and the method it references should have an appropriate " + "parameters and the method it references should have an appropriate " "descriptor") { - std::string descriptor = "([I[Ljava/lang/Object;[LDummyGeneric;)V"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "StaticLambdas.lambda$2:([I[Ljava/lang/Object;[LDummyGeneric;)V" + : "StaticLambdas.lambda$static$2:([I[Ljava/lang/" + "Object;[LDummyGeneric;)V"; + const std::string method_type = + "([I[Ljava/lang/Object;[LDummyGeneric;)V"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method(parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } // Return lambdas THEN( "There should be an entry for the lambda that returns a primitive " - "and " - "the method it references should have an appropriate descriptor") + "and the method it references should have an appropriate descriptor") { - std::string descriptor = "()I"; + const std::string lambda_method_ref = + compiler == "eclipse" ? "StaticLambdas.lambda$3:()I" + : "StaticLambdas.lambda$static$3:()I"; + const std::string method_type = "()I"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method(parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } THEN( "There should be an entry for the lambda that returns a reference " - "type " - "and the method it references should have an appropriate " + "type and the method it references should have an appropriate " "descriptor") { - std::string descriptor = "()Ljava/lang/Object;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "StaticLambdas.lambda$4:()Ljava/lang/Object;" + : "StaticLambdas.lambda$static$4:()Ljava/lang/Object;"; + const std::string method_type = "()Ljava/lang/Object;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method(parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } THEN( "There should be an entry for the lambda that returns a " - "specialised " - "generic type and the method it references should have an " - "appropriate " - "descriptor") + "specialised generic type and the method it references should have " + "an appropriate descriptor") { - std::string descriptor = "()LDummyGeneric;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "StaticLambdas.lambda$5:()LDummyGeneric;" + : "StaticLambdas.lambda$static$5:()LDummyGeneric;"; + const std::string method_type = "()LDummyGeneric;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method(parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } // Array returning lambdas THEN( "There should be an entry for the lambda that returns an array of " "primitives and the method it references should have an " - "appropriate " - "descriptor") + "appropriate descriptor") { - std::string descriptor = "()[I"; + const std::string lambda_method_ref = + compiler == "eclipse" ? "StaticLambdas.lambda$6:()[I" + : "StaticLambdas.lambda$static$6:()[I"; + const std::string method_type = "()[I"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method(parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } THEN( "There should be an entry for the lambda that returns an array of " "reference types and the method it references should have an " "appropriate descriptor") { - std::string descriptor = "()[Ljava/lang/Object;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "StaticLambdas.lambda$7:()[Ljava/lang/Object;" + : "StaticLambdas.lambda$static$7:()[Ljava/lang/Object;"; + const std::string method_type = "()[Ljava/lang/Object;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method(parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } THEN( "There should be an entry for the lambda that returns an array of " "specialised generic types and the method it references should " - "have an " - "appropriate descriptor") + "have an appropriate descriptor") { - std::string descriptor = "()[LDummyGeneric;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "StaticLambdas.lambda$8:()[LDummyGeneric;" + : "StaticLambdas.lambda$static$8:()[LDummyGeneric;"; + const std::string method_type = "()[LDummyGeneric;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method(parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } // Capturing lamdbas THEN( "There should be an entry for the lambda that returns a primitive " - "and " - "the method it references should have an appropriate descriptor") + "and the method it references should have an appropriate descriptor") { - std::string descriptor = "()I"; + const std::string lambda_method_ref = + compiler == "eclipse" ? "StaticLambdas.lambda$9:()I" + : "StaticLambdas.lambda$static$9:()I"; + const std::string method_type = "()I"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor, 1); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method(parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); const typet primitive_type = java_int_type(); fieldref_exprt fieldref{// NOLINT(whitespace/braces) primitive_type, "staticPrimitive", - "java::StaticLambdas"}; + "StaticLambdas"}; std::vector expected_instructions{{"getstatic", {fieldref}}, {"ireturn", {}}}; @@ -244,27 +268,30 @@ SCENARIO( } THEN( "There should be an entry for the lambda that returns a reference " - "type " - "and the method it references should have an appropriate " + "type and the method it references should have an appropriate " "descriptor") { - std::string descriptor = "()Ljava/lang/Object;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "StaticLambdas.lambda$10:()Ljava/lang/Object;" + : "StaticLambdas.lambda$static$10:()Ljava/lang/Object;"; + const std::string method_type = "()Ljava/lang/Object;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor, 1); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method(parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); const reference_typet dummy_generic_reference_type = - java_reference_type(symbol_typet{"java::java.lang.Object"}); + java_reference_type(symbol_typet{"java.lang.Object"}); - fieldref_exprt fieldref{dummy_generic_reference_type, - "staticReference", - "java::StaticLambdas"}; + // NOLINTNEXTLINE(whitespace/braces) + fieldref_exprt fieldref{ + dummy_generic_reference_type, "staticReference", "StaticLambdas"}; std::vector expected_instructions{{"getstatic", {fieldref}}, {"areturn", {}}}; @@ -274,28 +301,30 @@ SCENARIO( } THEN( "There should be an entry for the lambda that returns a " - "specialised " - "generic type and the method it references should have an " - "appropriate " - "descriptor") + "specialised generic type and the method it references should have " + "an appropriate descriptor") { - std::string descriptor = "()LDummyGeneric;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "StaticLambdas.lambda$11:()LDummyGeneric;" + : "StaticLambdas.lambda$static$11:()LDummyGeneric;"; + const std::string method_type = "()LDummyGeneric;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor, 1); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const java_bytecode_parse_treet::methodt &lambda_method = require_parse_tree::require_method(parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); const reference_typet dummy_generic_reference_type = - java_reference_type(symbol_typet{"java::DummyGeneric"}); + java_reference_type(symbol_typet{"DummyGeneric"}); fieldref_exprt fieldref{dummy_generic_reference_type, "staticSpecalisedGeneric", - "java::StaticLambdas"}; + "StaticLambdas"}; std::vector expected_instructions{{"getstatic", {fieldref}}, {"areturn", {}}}; @@ -318,8 +347,8 @@ SCENARIO( { java_bytecode_parse_treet parse_tree; java_bytecode_parse( - "./java_bytecode/java_bytecode_parser/lambda_examples/" + compiler + - "_classes/LocalLambdas.class", + "./java_bytecode/java_bytecode_parse_lambdas/lambda_examples/" + + compiler + "_classes/LocalLambdas.class", parse_tree, message_handler); WHEN("Parsing that class") @@ -336,155 +365,187 @@ SCENARIO( "returns and the method it references should have an appropriate " "descriptor") { + const std::string lambda_method_ref = + compiler == "eclipse" ? "LocalLambdas.lambda$0:()V" + : "LocalLambdas.lambda$test$0:()V"; + const std::string method_type = "()V"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, "()V"); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method( parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == "()V"); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } // Parameter lambdas THEN( "There should be an entry for the lambda that takes parameters and " - "the " - "method it references should have an appropriate descriptor") + "the method it references should have an appropriate descriptor") { - std::string descriptor = "(ILjava/lang/Object;LDummyGeneric;)V"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "LocalLambdas.lambda$1:(ILjava/lang/Object;LDummyGeneric;)V" + : "LocalLambdas.lambda$test$1:(ILjava/lang/" + "Object;LDummyGeneric;)V"; + const std::string method_type = + "(ILjava/lang/Object;LDummyGeneric;)V"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method( parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } THEN( "There should be an entry for the lambda that takes array " - "parameters " - "and the method it references should have an appropriate " - "descriptor") + "parameters and the method it references should have an " + "appropriate descriptor") { - std::string descriptor = "([I[Ljava/lang/Object;[LDummyGeneric;)V"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "LocalLambdas.lambda$2:([I[Ljava/lang/" + "Object;[LDummyGeneric;)V" + : "LocalLambdas.lambda$test$2:([I[Ljava/lang/" + "Object;[LDummyGeneric;)V"; + const std::string method_type = + "([I[Ljava/lang/Object;[LDummyGeneric;)V"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method( parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } // Return lambdas THEN( "There should be an entry for the lambda that returns a primitive " - "and " - "the method it references should have an appropriate descriptor") + "and the method it references should have an appropriate " + "descriptor") { - std::string descriptor = "()I"; + const std::string lambda_method_ref = + compiler == "eclipse" ? "LocalLambdas.lambda$3:()I" + : "LocalLambdas.lambda$test$3:()I"; + const std::string method_type = "()I"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method( parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } THEN( "There should be an entry for the lambda that returns a reference " - "type " - "and the method it references should have an appropriate " + "type and the method it references should have an appropriate " "descriptor") { - std::string descriptor = "()Ljava/lang/Object;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "LocalLambdas.lambda$4:()Ljava/lang/Object;" + : "LocalLambdas.lambda$test$4:()Ljava/lang/Object;"; + const std::string method_type = "()Ljava/lang/Object;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method( parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } THEN( "There should be an entry for the lambda that returns a " - "specialised " - "generic type and the method it references should have an " - "appropriate " - "descriptor") + "specialised generic type and the method it references should have " + "an appropriate descriptor") { - std::string descriptor = "()LDummyGeneric;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "LocalLambdas.lambda$5:()LDummyGeneric;" + : "LocalLambdas.lambda$test$5:()LDummyGeneric;"; + const std::string method_type = "()LDummyGeneric;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method( parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } // Array returning lambdas THEN( "There should be an entry for the lambda that returns an array of " "primitives and the method it references should have an " - "appropriate " - "descriptor") + "appropriate descriptor") { - std::string descriptor = "()[I"; + const std::string lambda_method_ref = + compiler == "eclipse" ? "LocalLambdas.lambda$6:()[I" + : "LocalLambdas.lambda$test$6:()[I"; + const std::string method_type = "()[I"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method( parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } THEN( "There should be an entry for the lambda that returns an array of " "reference types and the method it references should have an " "appropriate descriptor") { - std::string descriptor = "()[Ljava/lang/Object;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "LocalLambdas.lambda$7:()[Ljava/lang/Object;" + : "LocalLambdas.lambda$test$7:()[Ljava/lang/Object;"; + const std::string method_type = "()[Ljava/lang/Object;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method( parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } THEN( "There should be an entry for the lambda that returns an array of " "specialised generic types and the method it references should " - "have an " - "appropriate descriptor") + "have an appropriate descriptor") { - std::string descriptor = "()[LDummyGeneric;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "LocalLambdas.lambda$8:()[LDummyGeneric;" + : "LocalLambdas.lambda$test$8:()[LDummyGeneric;"; + const std::string method_type = "()[LDummyGeneric;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method( parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } // Capturing lamdbas @@ -493,10 +554,13 @@ SCENARIO( "local variable and the method it references should have an " "appropriate descriptor") { - std::string descriptor = "()I"; + const std::string lambda_method_ref = + compiler == "eclipse" ? "LocalLambdas.lambda$9:(I)I" + : "LocalLambdas.lambda$test$9:(I)I"; + const std::string method_type = "()I"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor, 1); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; @@ -514,16 +578,21 @@ SCENARIO( } THEN( "There should be an entry for the lambda that returns a reference " - "type " - "local variable and the method it references should have an " + "type local variable and the method it references should have an " "appropriate descriptor") { // Since it is a local variable, the corresponding method takes the // captured variable as an input - std::string descriptor = "()Ljava/lang/Object;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "LocalLambdas.lambda$10:(Ljava/lang/Object;)Ljava/" + "lang/Object;" + : "LocalLambdas.lambda$test$10:(Ljava/lang/Object;)Ljava/" + "lang/Object;"; + const std::string method_type = "()Ljava/lang/Object;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor, 1); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; @@ -541,17 +610,19 @@ SCENARIO( } THEN( "There should be an entry for the lambda that returns a " - "specialised " - "generic type local variable and the method it references should " - "have " - "an appropriate descriptor") + "specialised generic type local variable and the method it " + "references should have an appropriate descriptor") { // Since it is a local variable, the corresponding method takes the // captured variable as an input - std::string descriptor = "()LDummyGeneric;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "LocalLambdas.lambda$11:(LDummyGeneric;)LDummyGeneric;" + : "LocalLambdas.lambda$test$11:(LDummyGeneric;)LDummyGeneric;"; + const std::string method_type = "()LDummyGeneric;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor, 1); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; @@ -586,8 +657,8 @@ SCENARIO( { java_bytecode_parse_treet parse_tree; java_bytecode_parse( - "./java_bytecode/java_bytecode_parser/lambda_examples/" + compiler + - "_classes/MemberLambdas.class", + "./java_bytecode/java_bytecode_parse_lambdas/lambda_examples/" + + compiler + "_classes/MemberLambdas.class", parse_tree, message_handler); WHEN("Parsing that class") @@ -604,155 +675,186 @@ SCENARIO( "returns and the method it references should have an appropriate " "descriptor") { + const std::string lambda_method_ref = + compiler == "eclipse" ? "MemberLambdas.lambda$0:()V" + : "MemberLambdas.lambda$new$0:()V"; + const std::string method_type = "()V"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, "()V"); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method( parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == "()V"); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } // Parameter lambdas THEN( "There should be an entry for the lambda that takes parameters and " - "the " - "method it references should have an appropriate descriptor") + "the method it references should have an appropriate descriptor") { - std::string descriptor = "(ILjava/lang/Object;LDummyGeneric;)V"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "MemberLambdas.lambda$1:(ILjava/lang/Object;LDummyGeneric;)V" + : "MemberLambdas.lambda$new$1:(ILjava/lang/" + "Object;LDummyGeneric;)V"; + const std::string method_type = + "(ILjava/lang/Object;LDummyGeneric;)V"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method( parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } THEN( "There should be an entry for the lambda that takes array " - "parameters " - "and the method it references should have an appropriate " - "descriptor") + "parameters and the method it references should have an " + "appropriate descriptor") { - std::string descriptor = "([I[Ljava/lang/Object;[LDummyGeneric;)V"; + const std::string lambda_method_ref = + compiler == "eclipse" ? "MemberLambdas.lambda$2:([I[Ljava/lang/" + "Object;[LDummyGeneric;)V" + : "MemberLambdas.lambda$new$2:([I[Ljava/" + "lang/Object;[LDummyGeneric;)V"; + const std::string method_type = + "([I[Ljava/lang/Object;[LDummyGeneric;)V"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method( parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } // Return lambdas THEN( "There should be an entry for the lambda that returns a primitive " - "and " - "the method it references should have an appropriate descriptor") + "and the method it references should have an appropriate " + "descriptor") { - std::string descriptor = "()I"; + const std::string lambda_method_ref = + compiler == "eclipse" ? "MemberLambdas.lambda$3:()I" + : "MemberLambdas.lambda$new$3:()I"; + const std::string method_type = "()I"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method( parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } THEN( "There should be an entry for the lambda that returns a reference " - "type " - "and the method it references should have an appropriate " + "type and the method it references should have an appropriate " "descriptor") { - std::string descriptor = "()Ljava/lang/Object;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "MemberLambdas.lambda$4:()Ljava/lang/Object;" + : "MemberLambdas.lambda$new$4:()Ljava/lang/Object;"; + const std::string method_type = "()Ljava/lang/Object;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method( parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } THEN( "There should be an entry for the lambda that returns a " - "specialised " - "generic type and the method it references should have an " - "appropriate " - "descriptor") + "specialised generic type and the method it references should have " + "an appropriate descriptor") { - std::string descriptor = "()LDummyGeneric;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "MemberLambdas.lambda$5:()LDummyGeneric;" + : "MemberLambdas.lambda$new$5:()LDummyGeneric;"; + const std::string method_type = "()LDummyGeneric;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method( parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } // Array returning lambdas THEN( "There should be an entry for the lambda that returns an array of " "primitives and the method it references should have an " - "appropriate " - "descriptor") + "appropriate descriptor") { - std::string descriptor = "()[I"; + const std::string lambda_method_ref = + compiler == "eclipse" ? "MemberLambdas.lambda$6:()[I" + : "MemberLambdas.lambda$new$6:()[I"; + const std::string method_type = "()[I"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method( parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } THEN( "There should be an entry for the lambda that returns an array of " "reference types and the method it references should have an " "appropriate descriptor") { - std::string descriptor = "()[Ljava/lang/Object;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "MemberLambdas.lambda$7:()[Ljava/lang/Object;" + : "MemberLambdas.lambda$new$7:()[Ljava/lang/Object;"; + const std::string method_type = "()[Ljava/lang/Object;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method( parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } THEN( "There should be an entry for the lambda that returns an array of " "specialised generic types and the method it references should " - "have an " - "appropriate descriptor") + "have an appropriate descriptor") { - std::string descriptor = "()[LDummyGeneric;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "MemberLambdas.lambda$8:()[LDummyGeneric;" + : "MemberLambdas.lambda$new$8:()[LDummyGeneric;"; + const std::string method_type = "()[LDummyGeneric;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; const auto lambda_method = require_parse_tree::require_method( parsed_class, lambda_impl_name); - REQUIRE(id2string(lambda_method.descriptor) == descriptor); + REQUIRE(id2string(lambda_method.descriptor) == method_type); } // Capturing lamdbas @@ -761,10 +863,13 @@ SCENARIO( "local variable and the method it references should have an " "appropriate descriptor") { - std::string descriptor = "()I"; + const std::string lambda_method_ref = + compiler == "eclipse" ? "MemberLambdas.lambda$9:()I" + : "MemberLambdas.lambda$new$9:()I"; + const std::string method_type = "()I"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor, 1); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; @@ -778,7 +883,7 @@ SCENARIO( const fieldref_exprt primitive_fieldref{// NOLINT(whitespace/braces) java_int_type(), "memberPrimitive", - "java::MemberLambdas"}; + "MemberLambdas"}; std::vector expected_instructions{{"aload_0", {}}, // load this of stack @@ -790,16 +895,19 @@ SCENARIO( } THEN( "There should be an entry for the lambda that returns a reference " - "type " - "local variable and the method it references should have an " + "type local variable and the method it references should have an " "appropriate descriptor") { // Since it is a local variable, the corresponding method takes the // captured variable as an input - std::string descriptor = "()Ljava/lang/Object;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "MemberLambdas.lambda$10:()Ljava/lang/Object;" + : "MemberLambdas.lambda$new$10:()Ljava/lang/Object;"; + const std::string method_type = "()Ljava/lang/Object;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor, 1); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; @@ -810,13 +918,11 @@ SCENARIO( REQUIRE_FALSE(lambda_method.is_static); const reference_typet dummy_generic_reference_type = - java_reference_type(symbol_typet{"java::java.lang.Object"}); + java_reference_type(symbol_typet{"java.lang.Object"}); // NOLINTNEXTLINE(whitespace/braces) const fieldref_exprt reference_fieldref{ - dummy_generic_reference_type, - "memberReference", - "java::MemberLambdas"}; + dummy_generic_reference_type, "memberReference", "MemberLambdas"}; std::vector expected_instructions{{"aload_0", {}}, // load this of stack @@ -828,17 +934,19 @@ SCENARIO( } THEN( "There should be an entry for the lambda that returns a " - "specialised " - "generic type local variable and the method it references should " - "have " - "an appropriate descriptor") + "specialised generic type local variable and the method it " + "references should have an appropriate descriptor") { // Since it is a local variable, the corresponding method takes the // captured variable as an input - std::string descriptor = "()LDummyGeneric;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "MemberLambdas.lambda$11:()LDummyGeneric;" + : "MemberLambdas.lambda$new$11:()LDummyGeneric;"; + const std::string method_type = "()LDummyGeneric;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor, 1); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; @@ -849,13 +957,13 @@ SCENARIO( REQUIRE_FALSE(lambda_method.is_static); const reference_typet dummy_generic_reference_type = - java_reference_type(symbol_typet{"java::DummyGeneric"}); + java_reference_type(symbol_typet{"DummyGeneric"}); // NOLINTNEXTLINE(whitespace/braces) const fieldref_exprt generic_reference_fieldref{ dummy_generic_reference_type, "memberSpecalisedGeneric", - "java::MemberLambdas"}; + "MemberLambdas"}; // since just returning the parameter, nothing to put on the stack std::vector @@ -885,8 +993,8 @@ SCENARIO( { java_bytecode_parse_treet parse_tree; java_bytecode_parse( - "./java_bytecode/java_bytecode_parser/lambda_examples/" + compiler + - "_classes/OuterMemberLambdas$Inner.class", + "./java_bytecode/java_bytecode_parse_lambdas/lambda_examples/" + + compiler + "_classes/OuterMemberLambdas$Inner.class", parse_tree, message_handler); WHEN("Parsing that class") @@ -899,20 +1007,24 @@ SCENARIO( // Field ref for getting the outer class const reference_typet outer_class_reference_type = - java_reference_type(symbol_typet{"java::OuterMemberLambdas"}); - const fieldref_exprt outer_fieldref{outer_class_reference_type, - "this$0", - "java::OuterMemberLambdas$Inner"}; + java_reference_type(symbol_typet{"OuterMemberLambdas"}); + // NOLINTNEXTLINE(whitespace/braces) + const fieldref_exprt outer_fieldref{ + outer_class_reference_type, "this$0", "OuterMemberLambdas$Inner"}; THEN( "There should be an entry for the lambda that returns a primitive " "local variable and the method it references should have an " "appropriate descriptor") { - std::string descriptor = "()I"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "OuterMemberLambdas$Inner.lambda$0:()I" + : "OuterMemberLambdas$Inner.lambda$new$0:()I"; + const std::string method_type = "()I"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; @@ -925,7 +1037,7 @@ SCENARIO( // NOLINTNEXTLINE(whitespace/braces) const fieldref_exprt primitive_fieldref{ - java_int_type(), "memberPrimitive", "java::OuterMemberLambdas"}; + java_int_type(), "memberPrimitive", "OuterMemberLambdas"}; std::vector expected_instructions{{"aload_0", {}}, // load this of stack @@ -938,16 +1050,19 @@ SCENARIO( } THEN( "There should be an entry for the lambda that returns a reference " - "type " - "local variable and the method it references should have an " + "type local variable and the method it references should have an " "appropriate descriptor") { // Since it is a local variable, the corresponding method takes the // captured variable as an input - std::string descriptor = "()Ljava/lang/Object;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "OuterMemberLambdas$Inner.lambda$1:()Ljava/lang/Object;" + : "OuterMemberLambdas$Inner.lambda$new$1:()Ljava/lang/Object;"; + const std::string method_type = "()Ljava/lang/Object;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; @@ -958,13 +1073,13 @@ SCENARIO( REQUIRE_FALSE(lambda_method.is_static); const reference_typet dummy_generic_reference_type = - java_reference_type(symbol_typet{"java::java.lang.Object"}); + java_reference_type(symbol_typet{"java.lang.Object"}); // NOLINTNEXTLINE(whitespace/braces) const fieldref_exprt reference_fieldref{ dummy_generic_reference_type, "memberReference", - "java::OuterMemberLambdas"}; + "OuterMemberLambdas"}; std::vector expected_instructions{{"aload_0", {}}, // load this of stack @@ -977,17 +1092,19 @@ SCENARIO( } THEN( "There should be an entry for the lambda that returns a " - "specialised " - "generic type local variable and the method it references should " - "have " - "an appropriate descriptor") + "specialised generic type local variable and the method it " + "references should have an appropriate descriptor") { // Since it is a local variable, the corresponding method takes the // captured variable as an input - std::string descriptor = "()LDummyGeneric;"; + const std::string lambda_method_ref = + compiler == "eclipse" + ? "OuterMemberLambdas$Inner.lambda$2:()LDummyGeneric;" + : "OuterMemberLambdas$Inner.lambda$new$2:()LDummyGeneric;"; + const std::string method_type = "()LDummyGeneric;"; const lambda_method_handlet &lambda_entry = require_parse_tree::require_lambda_entry_for_descriptor( - parsed_class, descriptor); + parsed_class, lambda_method_ref, method_type); const irep_idt &lambda_impl_name = lambda_entry.lambda_method_name; @@ -998,13 +1115,13 @@ SCENARIO( REQUIRE_FALSE(lambda_method.is_static); const reference_typet dummy_generic_reference_type = - java_reference_type(symbol_typet{"java::DummyGeneric"}); + java_reference_type(symbol_typet{"DummyGeneric"}); // NOLINTNEXTLINE(whitespace/braces) const fieldref_exprt generic_reference_fieldref{ dummy_generic_reference_type, "memberSpecalisedGeneric", - "java::OuterMemberLambdas"}; + "OuterMemberLambdas"}; // since just returning the parameter, nothing to put on the stack std::vector diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/ExternalLambdaAccessor.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/ExternalLambdaAccessor.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/ExternalLambdaAccessor.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/ExternalLambdaAccessor.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/ExternalLambdaAccessor.java b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/ExternalLambdaAccessor.java similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/ExternalLambdaAccessor.java rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/ExternalLambdaAccessor.java diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/ExternalLambdas.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/ExternalLambdas.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/ExternalLambdas.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/ExternalLambdas.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/LambdaInterfaces.java b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/LambdaInterfaces.java similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/LambdaInterfaces.java rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/LambdaInterfaces.java diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/LocalLambdas.java b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/LocalLambdas.java similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/LocalLambdas.java rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/LocalLambdas.java diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/MemberLambdas.java b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/MemberLambdas.java similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/MemberLambdas.java rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/MemberLambdas.java diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/OuterMemberLambdas.java b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/OuterMemberLambdas.java similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/OuterMemberLambdas.java rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/OuterMemberLambdas.java diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/StaticLambdas.java b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/StaticLambdas.java similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/StaticLambdas.java rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/StaticLambdas.java diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/ArrayParameterLambda.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/ArrayParameterLambda.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/ArrayParameterLambda.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/ArrayParameterLambda.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/DummyGeneric.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/DummyGeneric.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/DummyGeneric.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/DummyGeneric.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/LocalLambdas.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/LocalLambdas.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/LocalLambdas.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/LocalLambdas.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/MemberLambdas.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/MemberLambdas.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/MemberLambdas.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/MemberLambdas.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/OuterMemberLambdas$Inner.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/OuterMemberLambdas$Inner.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/OuterMemberLambdas$Inner.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/OuterMemberLambdas$Inner.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/OuterMemberLambdas.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/OuterMemberLambdas.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/OuterMemberLambdas.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/OuterMemberLambdas.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/ParameterLambda.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/ParameterLambda.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/ParameterLambda.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/ParameterLambda.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/ReturningLambdaPrimitive.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/ReturningLambdaPrimitive.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/ReturningLambdaPrimitive.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/ReturningLambdaPrimitive.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/ReturningLambdaPrimitiveArray.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/ReturningLambdaPrimitiveArray.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/ReturningLambdaPrimitiveArray.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/ReturningLambdaPrimitiveArray.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/ReturningLambdaReference.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/ReturningLambdaReference.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/ReturningLambdaReference.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/ReturningLambdaReference.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/ReturningLambdaReferenceArray.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/ReturningLambdaReferenceArray.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/ReturningLambdaReferenceArray.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/ReturningLambdaReferenceArray.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/ReturningLambdaSpecalisedGeneric.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/ReturningLambdaSpecalisedGeneric.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/ReturningLambdaSpecalisedGeneric.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/ReturningLambdaSpecalisedGeneric.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/ReturningLambdaSpecalisedGenericArray.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/ReturningLambdaSpecalisedGenericArray.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/ReturningLambdaSpecalisedGenericArray.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/ReturningLambdaSpecalisedGenericArray.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/SimpleLambda.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/SimpleLambda.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/SimpleLambda.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/SimpleLambda.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/StaticLambdas.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/StaticLambdas.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/eclipse_classes/StaticLambdas.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/eclipse_classes/StaticLambdas.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/ArrayParameterLambda.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/ArrayParameterLambda.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/ArrayParameterLambda.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/ArrayParameterLambda.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/DummyGeneric.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/DummyGeneric.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/DummyGeneric.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/DummyGeneric.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/LocalLambdas.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/LocalLambdas.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/LocalLambdas.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/LocalLambdas.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/MemberLambdas.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/MemberLambdas.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/MemberLambdas.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/MemberLambdas.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/OuterMemberLambdas$Inner.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/OuterMemberLambdas$Inner.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/OuterMemberLambdas$Inner.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/OuterMemberLambdas$Inner.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/OuterMemberLambdas.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/OuterMemberLambdas.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/OuterMemberLambdas.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/OuterMemberLambdas.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/ParameterLambda.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/ParameterLambda.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/ParameterLambda.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/ParameterLambda.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/ReturningLambdaPrimitive.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/ReturningLambdaPrimitive.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/ReturningLambdaPrimitive.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/ReturningLambdaPrimitive.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/ReturningLambdaPrimitiveArray.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/ReturningLambdaPrimitiveArray.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/ReturningLambdaPrimitiveArray.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/ReturningLambdaPrimitiveArray.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/ReturningLambdaReference.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/ReturningLambdaReference.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/ReturningLambdaReference.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/ReturningLambdaReference.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/ReturningLambdaReferenceArray.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/ReturningLambdaReferenceArray.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/ReturningLambdaReferenceArray.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/ReturningLambdaReferenceArray.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/ReturningLambdaSpecalisedGeneric.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/ReturningLambdaSpecalisedGeneric.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/ReturningLambdaSpecalisedGeneric.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/ReturningLambdaSpecalisedGeneric.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/ReturningLambdaSpecalisedGenericArray.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/ReturningLambdaSpecalisedGenericArray.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/ReturningLambdaSpecalisedGenericArray.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/ReturningLambdaSpecalisedGenericArray.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/SimpleLambda.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/SimpleLambda.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/SimpleLambda.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/SimpleLambda.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/StaticLambdas.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/StaticLambdas.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/openjdk_8_classes/StaticLambdas.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/openjdk_8_classes/StaticLambdas.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/ArrayParameterLambda.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/ArrayParameterLambda.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/ArrayParameterLambda.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/ArrayParameterLambda.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/DummyGeneric.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/DummyGeneric.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/DummyGeneric.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/DummyGeneric.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/LocalLambdas.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/LocalLambdas.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/LocalLambdas.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/LocalLambdas.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/MemberLambdas.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/MemberLambdas.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/MemberLambdas.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/MemberLambdas.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/OuterMemberLambdas$Inner.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/OuterMemberLambdas$Inner.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/OuterMemberLambdas$Inner.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/OuterMemberLambdas$Inner.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/OuterMemberLambdas.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/OuterMemberLambdas.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/OuterMemberLambdas.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/OuterMemberLambdas.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/ParameterLambda.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/ParameterLambda.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/ParameterLambda.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/ParameterLambda.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/ReturningLambdaPrimitive.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/ReturningLambdaPrimitive.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/ReturningLambdaPrimitive.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/ReturningLambdaPrimitive.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/ReturningLambdaPrimitiveArray.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/ReturningLambdaPrimitiveArray.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/ReturningLambdaPrimitiveArray.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/ReturningLambdaPrimitiveArray.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/ReturningLambdaReference.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/ReturningLambdaReference.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/ReturningLambdaReference.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/ReturningLambdaReference.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/ReturningLambdaReferenceArray.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/ReturningLambdaReferenceArray.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/ReturningLambdaReferenceArray.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/ReturningLambdaReferenceArray.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/ReturningLambdaSpecalisedGeneric.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/ReturningLambdaSpecalisedGeneric.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/ReturningLambdaSpecalisedGeneric.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/ReturningLambdaSpecalisedGeneric.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/ReturningLambdaSpecalisedGenericArray.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/ReturningLambdaSpecalisedGenericArray.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/ReturningLambdaSpecalisedGenericArray.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/ReturningLambdaSpecalisedGenericArray.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/SimpleLambda.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/SimpleLambda.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/SimpleLambda.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/SimpleLambda.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/StaticLambdas.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/StaticLambdas.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_8_classes/StaticLambdas.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_8_classes/StaticLambdas.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/ArrayParameterLambda.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/ArrayParameterLambda.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/ArrayParameterLambda.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/ArrayParameterLambda.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/DummyGeneric.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/DummyGeneric.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/DummyGeneric.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/DummyGeneric.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/LocalLambdas.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/LocalLambdas.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/LocalLambdas.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/LocalLambdas.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/MemberLambdas.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/MemberLambdas.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/MemberLambdas.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/MemberLambdas.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/OuterMemberLambdas$Inner.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/OuterMemberLambdas$Inner.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/OuterMemberLambdas$Inner.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/OuterMemberLambdas$Inner.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/OuterMemberLambdas.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/OuterMemberLambdas.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/OuterMemberLambdas.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/OuterMemberLambdas.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/ParameterLambda.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/ParameterLambda.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/ParameterLambda.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/ParameterLambda.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/ReturningLambdaPrimitive.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/ReturningLambdaPrimitive.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/ReturningLambdaPrimitive.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/ReturningLambdaPrimitive.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/ReturningLambdaPrimitiveArray.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/ReturningLambdaPrimitiveArray.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/ReturningLambdaPrimitiveArray.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/ReturningLambdaPrimitiveArray.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/ReturningLambdaReference.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/ReturningLambdaReference.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/ReturningLambdaReference.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/ReturningLambdaReference.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/ReturningLambdaReferenceArray.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/ReturningLambdaReferenceArray.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/ReturningLambdaReferenceArray.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/ReturningLambdaReferenceArray.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/ReturningLambdaSpecalisedGeneric.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/ReturningLambdaSpecalisedGeneric.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/ReturningLambdaSpecalisedGeneric.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/ReturningLambdaSpecalisedGeneric.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/ReturningLambdaSpecalisedGenericArray.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/ReturningLambdaSpecalisedGenericArray.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/ReturningLambdaSpecalisedGenericArray.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/ReturningLambdaSpecalisedGenericArray.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/SimpleLambda.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/SimpleLambda.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/SimpleLambda.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/SimpleLambda.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/StaticLambdas.class b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/StaticLambdas.class similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/oracle_9_classes/StaticLambdas.class rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/oracle_9_classes/StaticLambdas.class diff --git a/unit/java_bytecode/java_bytecode_parser/lambda_examples/readme.md b/unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/readme.md similarity index 100% rename from unit/java_bytecode/java_bytecode_parser/lambda_examples/readme.md rename to unit/java_bytecode/java_bytecode_parse_lambdas/lambda_examples/readme.md diff --git a/unit/testing-utils/Makefile b/unit/testing-utils/Makefile index 659842f178f..1c873d58084 100644 --- a/unit/testing-utils/Makefile +++ b/unit/testing-utils/Makefile @@ -4,7 +4,10 @@ SRC = \ load_java_class.cpp \ require_expr.cpp \ require_goto_statements.cpp \ + require_parse_tree.cpp \ + require_symbol.cpp \ require_type.cpp \ + run_test_with_compilers.cpp \ # Empty last line (please keep above list sorted!) INCLUDES = -I .. -I . -I ../../src diff --git a/unit/testing-utils/require_parse_tree.cpp b/unit/testing-utils/require_parse_tree.cpp index 0fd71261be3..6534e478a2b 100644 --- a/unit/testing-utils/require_parse_tree.cpp +++ b/unit/testing-utils/require_parse_tree.cpp @@ -11,48 +11,38 @@ /// Find in the parsed class a specific entry within the /// lambda_method_handle_map with a matching descriptor. Will fail if no /// matching lambda entry found. -/// \param parsed_class: the class to inspect -/// \param descriptor: the descriptor the lambda method should have -/// \param entry_index: the number to skip (i.e. if multiple entries with the -/// same descriptor +/// \param parsed_class the class to inspect +/// \param lambda_method_ref the reference/descriptor of the lambda method +/// to which this lambda entry points to, must be unique +/// \param method_type the descriptor the lambda method should have /// \return require_parse_tree::lambda_method_handlet require_parse_tree::require_lambda_entry_for_descriptor( const java_bytecode_parse_treet::classt &parsed_class, - const std::string &descriptor, - const size_t entry_index) + const std::string &lambda_method_ref, + const std::string &method_type) { - REQUIRE(entry_index < parsed_class.lambda_method_handle_map.size()); typedef java_bytecode_parse_treet::classt::lambda_method_handle_mapt:: value_type lambda_method_entryt; - size_t matches_found = 0; - - const auto matching_lambda_entry = std::find_if( + INFO( + "Looking for entry with lambda_method_ref: " << lambda_method_ref + << " and method_type: " + << method_type); + std::vector matches; + std::copy_if( parsed_class.lambda_method_handle_map.begin(), parsed_class.lambda_method_handle_map.end(), - [&descriptor, &matches_found, &entry_index]( - const lambda_method_entryt &entry) { - if(entry.second.method_type == descriptor) - { - ++matches_found; - return matches_found == entry_index + 1; - } - return false; + back_inserter(matches), + [&method_type, + &lambda_method_ref](const lambda_method_entryt &entry) { //NOLINT + return ( + entry.second.method_type == method_type && + entry.second.lambda_method_ref == lambda_method_ref); }); - - INFO("Looking for descriptor: " << descriptor); - std::ostringstream found_entries; - for(const auto entry : parsed_class.lambda_method_handle_map) - { - found_entries << id2string(entry.first.first) << ": " - << id2string(entry.second.method_type) << std::endl; - } - INFO("Found descriptors:\n" << found_entries.str()); - - REQUIRE(matching_lambda_entry != parsed_class.lambda_method_handle_map.end()); - - return matching_lambda_entry->second; + INFO("Number of matching lambda method entries: " << matches.size()); + REQUIRE(matches.size() == 1); + return matches.at(0).second; } /// Finds a specific method in the parsed class with a matching name. diff --git a/unit/testing-utils/require_parse_tree.h b/unit/testing-utils/require_parse_tree.h index c7fc17ec819..adda800c122 100644 --- a/unit/testing-utils/require_parse_tree.h +++ b/unit/testing-utils/require_parse_tree.h @@ -23,8 +23,8 @@ typedef java_bytecode_parse_treet::classt::lambda_method_handlet lambda_method_handlet require_lambda_entry_for_descriptor( const java_bytecode_parse_treet::classt &parsed_class, - const std::string &descriptor, - const size_t entry_index = 0); + const std::string &lambda_method_ref, + const std::string &method_type); typedef java_bytecode_parse_treet::methodt methodt; @@ -46,8 +46,8 @@ struct expected_instructiont java_bytecode_parse_treet::instructiont actual_instruction) const; private: - const irep_idt instruction_mnemoic; - const std::vector instruction_arguments; + irep_idt instruction_mnemoic; + std::vector instruction_arguments; }; typedef std::vector expected_instructionst; diff --git a/unit/testing-utils/require_type.cpp b/unit/testing-utils/require_type.cpp index 0ea4bf2e1b2..b405cf25bd4 100644 --- a/unit/testing-utils/require_type.cpp +++ b/unit/testing-utils/require_type.cpp @@ -480,3 +480,31 @@ java_generic_symbol_typet require_type::require_java_generic_symbol_type( return generic_base_type; } + +/// Verify that the lambda method handles of a class match the given +/// expectation. +/// \param class_struct class type to be verified +/// \param expected_identifiers expected list of lambda method handle +/// references +/// \return lambda method handles of the class +require_type::java_lambda_method_handlest +require_type::require_lambda_method_handles( + const java_class_typet &class_type, + const std::vector &expected_identifiers) +{ + const require_type::java_lambda_method_handlest &lambda_method_handles = + class_type.lambda_method_handles(); + REQUIRE(lambda_method_handles.size() == expected_identifiers.size()); + + REQUIRE( + std::equal( + lambda_method_handles.begin(), + lambda_method_handles.end(), + expected_identifiers.begin(), + []( + const symbol_exprt &lambda_method_handle, + const std::string &expected_identifier) { //NOLINT + return lambda_method_handle.get_identifier() == expected_identifier; + })); + return lambda_method_handles; +} diff --git a/unit/testing-utils/require_type.h b/unit/testing-utils/require_type.h index 66c76940a7a..204c6f5c2fb 100644 --- a/unit/testing-utils/require_type.h +++ b/unit/testing-utils/require_type.h @@ -115,6 +115,13 @@ java_generic_symbol_typet require_java_generic_symbol_type( const typet &type, const std::string &identifier, const require_type::expected_type_argumentst &type_expectations); + +typedef java_class_typet::java_lambda_method_handlest + java_lambda_method_handlest; + +java_lambda_method_handlest require_lambda_method_handles( + const java_class_typet &class_type, + const std::vector &expected_identifiers); } #endif // CPROVER_TESTING_UTILS_REQUIRE_TYPE_H diff --git a/unit/testing-utils/run_test_with_compilers.cpp b/unit/testing-utils/run_test_with_compilers.cpp new file mode 100644 index 00000000000..07ab9c2f3ac --- /dev/null +++ b/unit/testing-utils/run_test_with_compilers.cpp @@ -0,0 +1,18 @@ +/*******************************************************************\ + + Module: Unit test utilities + + Author: Diffblue Ltd. + +\*******************************************************************/ + +#include "run_test_with_compilers.h" + +void run_test_with_compilers( + const std::function &test_with_compiler) +{ + test_with_compiler(std::string("openjdk_8")); + test_with_compiler(std::string("eclipse")); + test_with_compiler(std::string("oracle_8")); + test_with_compiler(std::string("oracle_9")); +} diff --git a/unit/testing-utils/run_test_with_compilers.h b/unit/testing-utils/run_test_with_compilers.h new file mode 100644 index 00000000000..2cee404f680 --- /dev/null +++ b/unit/testing-utils/run_test_with_compilers.h @@ -0,0 +1,21 @@ +/*******************************************************************\ + + Module: Unit test utilities + + Author: Diffblue Ltd. + +\*******************************************************************/ + +/// \file +/// Utility for running a test with different compilers. + +#ifndef CPROVER_TESTING_UTILS_RUN_TEST_WITH_COMPILERS_H +#define CPROVER_TESTING_UTILS_RUN_TEST_WITH_COMPILERS_H + +#include +#include + +void run_test_with_compilers( + const std::function &test_with_compiler); + +#endif // CPROVER_TESTING_UTILS_RUN_TEST_WITH_COMPILERS_H