== doSmth == fun doSmth() {} --------------------- ===================== == doSmth1 == fun doSmth1() {} --------------------- ===================== == doSmth2 == fun doSmth2() {} --------------------- ===================== == cond == fun cond() {} --------------------- ===================== == testCopy1 == fun testCopy1() : Int { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { return 1 } } --------------------- : {<: NullPointerException /* = NullPointerException */} NEW: magic[FAKE_INITIALIZER](e: NullPointerException) -> : {<: Exception /* = Exception */} NEW: magic[FAKE_INITIALIZER](e: Exception) -> doSmth() : * NEW: call(doSmth(), doSmth) -> { doSmth() } : * COPY doSmth1() : * NEW: call(doSmth1(), doSmth1) -> { doSmth1() } : * COPY doSmth2() : * NEW: call(doSmth2(), doSmth2) -> { doSmth2() } : * COPY 1 : Int NEW: r(1) -> return 1 !: * { return 1 } !: * COPY try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { return 1 } : * NEW: merge(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { return 1 }|, , ) -> { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { return 1 } } : * COPY ===================== == testCopy2 == fun testCopy2() { while (cond()) { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } } } --------------------- : {<: NullPointerException /* = NullPointerException */} NEW: magic[FAKE_INITIALIZER](e: NullPointerException) -> : {<: Exception /* = Exception */} NEW: magic[FAKE_INITIALIZER](e: Exception) -> cond() : Boolean NEW: call(cond(), cond) -> doSmth() : * NEW: call(doSmth(), doSmth) -> { doSmth() } : * COPY doSmth1() : * NEW: call(doSmth1(), doSmth1) -> { doSmth1() } : * COPY doSmth2() : * NEW: call(doSmth2(), doSmth2) -> { doSmth2() } : * COPY cond() : Boolean NEW: call(cond(), cond) -> return !: * continue !: * if (cond()) return else continue : * NEW: merge(if (cond()) return else continue|!, !) -> { if (cond()) return else continue } : * COPY try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } : * NEW: merge(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue }|, , ) -> { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } } : * COPY while (cond()) { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } } !: * { while (cond()) { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { if (cond()) return else continue } } } !: * COPY ===================== == testCopy3 == fun testCopy3() { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { while (cond()); } } --------------------- : {<: NullPointerException /* = NullPointerException */} NEW: magic[FAKE_INITIALIZER](e: NullPointerException) -> : {<: Exception /* = Exception */} NEW: magic[FAKE_INITIALIZER](e: Exception) -> doSmth() : * NEW: call(doSmth(), doSmth) -> { doSmth() } : * COPY doSmth1() : * NEW: call(doSmth1(), doSmth1) -> { doSmth1() } : * COPY doSmth2() : * NEW: call(doSmth2(), doSmth2) -> { doSmth2() } : * COPY cond() : Boolean NEW: call(cond(), cond) -> while (cond()) !: * { while (cond()); } !: * COPY try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { while (cond()); } : * NEW: merge(try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { while (cond()); }|, , ) -> { try { doSmth() } catch (e: NullPointerException) { doSmth1() } catch (e: Exception) { doSmth2() } finally { while (cond()); } } : * COPY ===================== == doTestCopy4 == fun doTestCopy4(list: List?) : Int { try { doSmth() } finally { if(list != null) { } } } --------------------- : {<: List?} NEW: magic[FAKE_INITIALIZER](list: List?) -> doSmth() : * NEW: call(doSmth(), doSmth) -> { doSmth() } : * COPY list : * NEW: r(list) -> null : * NEW: r(null) -> list != null : Boolean NEW: call(list != null, equals|, ) -> { } !: * if(list != null) { } : * NEW: merge(if(list != null) { }|!) -> { if(list != null) { } } : * COPY try { doSmth() } finally { if(list != null) { } } : * NEW: merge(try { doSmth() } finally { if(list != null) { } }|) -> { try { doSmth() } finally { if(list != null) { } } } : * COPY =====================