Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
979b395
add Makefile detect_diamond.py src/gedoc_field_rename_format.e
yilabs Mar 8, 2024
56d7966
add test/rename/
yilabs Mar 8, 2024
2772083
add field_rename
yilabs Mar 8, 2024
0a525f1
add find_longest_common_ancestors_len() to find diamond core
yilabs Mar 8, 2024
71154f0
Merge branch 'master' into detect_diamond
yilabs Mar 9, 2024
e1453da
process sys.argv
yilabs Mar 10, 2024
7071297
mv test/rename example/
yilabs Mar 10, 2024
d394589
add ISE finalize mode
yilabs Mar 10, 2024
57b5e8b
mv src/gedoc_field_rename_format.e src/gedoc_attr_rename_format.e
yilabs Mar 11, 2024
0eecede
mv src/gedoc_field_rename_format.e src/gedoc_attr_rename_format.e
yilabs Mar 11, 2024
0736ba6
refine output
yilabs Mar 11, 2024
c0b3dc5
add README.md
yilabs Mar 11, 2024
fce5be8
change field_rename to attr_rename
yilabs Mar 11, 2024
f207ad6
change field_rename to attr_rename
yilabs Mar 11, 2024
1b1281c
change field_rename to attr_rename update
yilabs Mar 11, 2024
d416022
update
yilabs Mar 11, 2024
d833d23
update
yilabs Mar 11, 2024
e0953fa
update
yilabs Mar 11, 2024
22b34c9
update
yilabs Mar 11, 2024
74f1dc3
update summary
yilabs Mar 11, 2024
63fdde3
update ###
yilabs Mar 11, 2024
c3775c9
update doc
yilabs Mar 11, 2024
06884bc
update doc
yilabs Mar 11, 2024
0645716
update doc
yilabs Mar 11, 2024
399a0e8
update
yilabs Mar 11, 2024
8383895
update
yilabs Mar 11, 2024
4e6c694
update
yilabs Mar 11, 2024
e7d7205
Merge branch 'gobo-eiffel:master' into detect_diamond
ddifi Mar 11, 2024
b7580ef
Merge branch 'master' into detect_diamond
yilabs Mar 11, 2024
d4249b5
update
yilabs Mar 11, 2024
6ce8656
Merge branch 'detect_diamond' of https://github.com/joortcom/gobo int…
yilabs Mar 11, 2024
8b30c39
update
yilabs Mar 11, 2024
21e5198
update
yilabs Mar 11, 2024
b58a313
update
yilabs Mar 11, 2024
ff5eec4
update
yilabs Mar 11, 2024
55c54d1
update
yilabs Mar 11, 2024
61f856c
update
yilabs Mar 11, 2024
34e2444
fix typo
yilabs Mar 11, 2024
8b27dd1
fix typo
yilabs Mar 11, 2024
d4d33ad
highlight THIS branch
yilabs Mar 11, 2024
2e7d20a
refine
yilabs Mar 11, 2024
3580913
refine
yilabs Mar 11, 2024
a8d00d9
add path_string()
yilabs Apr 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions tool/gedoc/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
OPT=-finalize
DIR=F_code
DIR=W_code
ise:
ec -freeze -c_compile -config src/system.ecf

clean_ise:
ec -clean -config src/system.ecf


OPT= --gc=no --capability=concurrency=none # --finalize --no-benchmark
gobo: # does not work: https://github.com/gobo-eiffel/gobo/issues/71
gec $(OPT) src/system.ecf

fmt=implicit_converts
fmt=attr_rename

demo_ecf = ./test/tool/system.ecf
demo_ecf = src/system.ecf
demo:
gedoc --format=$(fmt) $(demo_ecf) > inherited_fields.path

clean:
$(RM) -fr *.c *.o *.make *.h *.sh EIFGENs/
244 changes: 244 additions & 0 deletions tool/gedoc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
# New tool: Detect attribute (i.e field) renaming in diamond inheritance

## Background:

We discovered a semantic problem in Eiffel's attribute renaming mechanism when applied to the diamond problem of multiple inheritance,
and confirmed it by showing divergent and problematic outputs for the same example code in three major different
Eiffel compilers.

Please check the detail here:
[https://github.com/joortcom/eiffel\_rename](https://github.com/joortcom/eiffel_rename)

and doc here: [https://github.com/joortcom/eiffel\_rename/blob/main/eiffel\_rename.pdf](https://github.com/joortcom/eiffel_rename/blob/main/eiffel_rename.pdf)

### Executive summary:
For the time being (before Eiffel's attribute renaming semantics is settled & fixed
-- which most likely will be a *breaking* change of existing code),
please avoid attribute renaming in any diamond inheritance.

### A bit more detail:

In [ECMA-367 (specification for the Eiffel programming language)](https://www.ecma-international.org/wp-content/uploads/ECMA-367_2nd_edition_june_2006.pdf)

1) by 8.16.2 “Any two of these features inherited under a different name yield two features of D”:
which means replicated (i.e. separated copies) features (attributes in particular) in the diamond bottom class D;

2) while by 8.6.16 “Semantics: Renaming principle”: “Renaming does not affect the semantics of an inherited feature”:
which is not a very precise description.

So in the actual compiler implementations:

* ISE compiler (tested the lastest version 23.09):
* In workbench mode: implemented (2) 8.6.16 as reference identity semantics: i.e renamed attributes are all reference equal!
* In finalized mode: skipped (2) 8.6.16, only implemented (1) 8.16.2: i.e renamed attributes are replicated.
* GOBO compiler (tested the lastest version 22.01):
* skipped (2) 8.6.16, only implemented (1) 8.16.2: i.e renamed attributes are replicated.
* SmartEiffel compiler (tested the last known ECMA compilant version 1.1):
* skipped (2) 8.6.16, only implemented (1) 8.16.2: i.e renamed attributes are replicated.


## Goal:

Help Eiffel programmers to detect and avoid attribute renaming in a diamond inheritance.

## Usage:

Tool is here: [detect\_diamond.py](https://github.com/joortcom/gobo/blob/detect_diamond/tool/gedoc/detect_diamond.py)

```
$GOBO/tool/gedoc/detect_diamond.py <single_file.ecf> or <dir (which will be recursively scanned for all the .ecf files)>
```

## Demo:

First, from *THIS branch* build all the GOBO tools, esp `gec` and `gedoc` as you usually do.

Then, run the `detect_diamond.py` tool

```
$ cd $GOBO/tool/gedoc/example/rename
$ $GOBO/tool/gedoc/detect_diamond.py app.ecf
check: app.ecf
======================================== app.ecf total fields: 966
diamond found, full paths: PERSON.addr => RESEARCH_ASSISTANT.{student_addr, faculty_addr, addr}
student_addr {('PERSON.addr', 'STUDENT.addr', 'RESEARCH_ASSISTANT.student_addr')}
faculty_addr {('PERSON.addr', 'FACULTY.addr', 'RESEARCH_ASSISTANT.faculty_addr')}
addr {('PERSON.addr', 'RESEARCH_ASSISTANT.addr')}
new_fields: RESEARCH_ASSISTANT.{student_addr, faculty_addr, addr}
diamond core: PERSON.addr => RESEARCH_ASSISTANT.{student_addr, faculty_addr, addr}
student_addr [('PERSON.addr', 'STUDENT.addr', 'RESEARCH_ASSISTANT.student_addr')]
faculty_addr [('PERSON.addr', 'FACULTY.addr', 'RESEARCH_ASSISTANT.faculty_addr')]
addr [('PERSON.addr', 'RESEARCH_ASSISTANT.addr')]
```

And, run the compiler to see different outputs for the *same* code:

* ISE compiler implements the reference identity semantics in workbench mode
* ISE compiler implements the replica semantics in finalize mode
* GOGO compiler implements the replica semantics

```
$ cd $GOBO/tool/gedoc/example/rename # the same dir as above
$ make ise
============================================================================================
NOTE: ISE compiler implements the troublesome reference identity semantics in workbench mode
============================================================================================

ec -clean -full app.e

...

C compilation completed
chmod +x ./app
mv app app_w
============================================================================================
./app_w > ise_w.out
cat ise_w.out
ResAssis has 3 addresses: <home, home, home>
PERSON size: 32
STUDENT size: 32
FACULTY size: 32
RESEARCH_ASSISTANT size: 48
ResAssis do_benchwork in the: home
ResAssis take_rest in the: home
-- print_student|faculty_addr_direct_field
ResAssis as STUDENT.addr: home
ResAssis as FACULTY.addr: home
-- print_student|faculty_addr_via_accessor
ResAssis as STUDENT.addr: home
ResAssis as FACULTY.addr: home
-- check reference identity
ra.addr = ra.faculty_addr
ra.addr = ra.student_addr
ra.student_addr = ra.faculty_addr
-- test some assignment: suppose ra moved both lab2 and dorm2
ResAssis has 3 addresses: <lab2, lab2, lab2>
ResAssis has 3 addresses: <dorm2, dorm2, dorm2>
============================== Press enter to continue ==============================


============================================================================================
***NOTE***: ISE compiler implements the replica semantics in finalize mode
============================================================================================
ec -clean -finalize -full app.e
C compilation completed
chmod +x ./app
mv app app_f
============================================================================================
./app_f > ise_f.out
cat ise_f.out
ResAssis has 3 addresses: <home, dorm, lab>
PERSON size: 32
STUDENT size: 32
FACULTY size: 32
RESEARCH_ASSISTANT size: 48
ResAssis do_benchwork in the: home
ResAssis take_rest in the: home
-- print_student|faculty_addr_direct_field
ResAssis as STUDENT.addr: home
ResAssis as FACULTY.addr: home
-- print_student|faculty_addr_via_accessor
ResAssis as STUDENT.addr: home
ResAssis as FACULTY.addr: home
-- check reference identity
ra.addr != ra.faculty_addr
ra.addr != ra.student_addr
ra.student_addr != ra.faculty_addr
-- test some assignment: suppose ra moved both lab2 and dorm2
ResAssis has 3 addresses: <lab2, dorm, lab>
ResAssis has 3 addresses: <dorm2, dorm, lab>

$ make gobo
<your gobo dir>/bin/gec app.ecf
...
============================================================================================
./app > gobo.out
cat gobo.out
ResAssis has 3 addresses: <home, dorm, lab>
PERSON size: 32
STUDENT size: 32
FACULTY size: 32
RESEARCH_ASSISTANT size: 48
ResAssis do_benchwork in the: home
ResAssis take_rest in the: home
-- print_student|faculty_addr_direct_field
ResAssis as STUDENT.addr: home
ResAssis as FACULTY.addr: home
-- print_student|faculty_addr_via_accessor
ResAssis as STUDENT.addr: home
ResAssis as FACULTY.addr: home
-- check reference identity
ra.addr != ra.faculty_addr
ra.addr != ra.student_addr
ra.student_addr != ra.faculty_addr
-- test some assignment: suppose ra moved both lab2 and dorm2
ResAssis has 3 addresses: <lab2, dorm, lab>
ResAssis has 3 addresses: <dorm2, dorm, lab>

```

## Diamonds found in real code:

In ISE 23.09:

```
$ cd $ISE_EIFFEL/examples/docking/simple/
$ $GOBO/tool/gedoc/detect_diamond.py .
check: .

...

======================================== ./docking_simple.ecf total fields: 15892
diamond found, full paths: EV_PIXMAPABLE.implementation => SD_PLACE_HOLDER_ZONE.{implementation, implementation_upper_zone}
implementation {('EV_PIXMAPABLE.implementation', 'EV_CONTAINER.implementation', 'EV_CELL.implementation', 'SD_DOCKING_ZONE.implementation', 'SD_PLACE_HOLDER_ZONE.implementation')}
implementation_upper_zone {('EV_PIXMAPABLE.implementation', 'EV_CONTAINER.implementation', 'SD_UPPER_ZONE.implementation_upper_zone', 'SD_PLACE_HOLDER_ZONE.implementation_upper_zone')}
new_fields: SD_PLACE_HOLDER_ZONE.{implementation, implementation_upper_zone}
diamond core: EV_CONTAINER.implementation => SD_PLACE_HOLDER_ZONE.{implementation, implementation_upper_zone}
implementation [('EV_CONTAINER.implementation', 'EV_CELL.implementation', 'SD_DOCKING_ZONE.implementation', 'SD_PLACE_HOLDER_ZONE.implementation')]
implementation_upper_zone [('EV_CONTAINER.implementation', 'SD_UPPER_ZONE.implementation_upper_zone', 'SD_PLACE_HOLDER_ZONE.implementation_upper_zone')]
```

And if you run the workbench build, it will run normally:
```
/Eiffel_23.09/examples/docking/simple$ ./EIFGENs/docking_simple/W_code/docking_simple
```

but if you run the finalized build, it will fail (Ubuntu 22.04.3 LTS, x86_64), it will fail:
```
/Eiffel_23.09/examples/docking/simple$ ./EIFGENs/docking_simple/F_code/docking_simple

docking_simple: system execution failed.
Following is the set of recorded exceptions:

******************************** Thread exception *****************************
In thread Root thread 0x0 (thread id)
*******************************************************************************
-------------------------------------------------------------------------------
Class / Object Routine Nature of exception Effect
-------------------------------------------------------------------------------
VISION2_APPLICATION root's creation Segmentation fault:
<00007FC1A8207558> Operating system signal. Exit
-------------------------------------------------------------------------------
VISION2_APPLICATION root's creation
<00007FC1A8207558> Routine failure. Exit
-------------------------------------------------------------------------------
```

## TODO & Feedbacks:

Right now this tool is still a prototype, but good enough to detect problems in the real code.
Eric Bezault has kindly agreed to properly integrate into `gedoc` in the near future
[https://github.com/gobo-eiffel/gobo/pull/77#issuecomment-1986971690](https://github.com/gobo-eiffel/gobo/pull/77#issuecomment-1986971690).
Many thanks to Eric for his help in developing this prototype!

But everybody is busy, if you are good at (GOBO) Eiffel and can help, please
[follow the suggestions by Eric](https://github.com/gobo-eiffel/gobo/pull/77#issuecomment-1986805714)
and create a new PR for Eric to review.

If you have questions, comments, or just want to inform us the problems found in your own code
by using this tool, please log an issue *in the other repo* (*NOT* here in this GOBO repo)
[https://github.com/joortcom/eiffel\_rename](https://github.com/joortcom/eiffel_rename),
So everything regarding Eiffel `rename` (not *GOBO*) can be easily tracked *there*.

Thanks!

Loading