gobo-eiffel / gobo

The Gobo Eiffel Project provides the Eiffel community with free and portable Eiffel tools and libraries.
https://sourceforge.net/projects/gobo-eiffel/
Other
59 stars 24 forks source link

Q: how to find all the renamed attributes of a (AST processed) class in the gec compiler ? #70

Open mw66 opened 4 months ago

mw66 commented 4 months ago

Hi,

I want to find all the renamed attributes of a (AST processed) class in the gec compiler:

I have checked et_class.e

and found this navigation:

ET_CLASS.queries: ET_QUERY_LIST

ET_QUERY.is_attribute

but where to find if the attribute is a renamed one?

Thanks.

ebezault commented 4 months ago

This needs to be double-checked in the code, but if I recall correctly you have to look at first_precursor and other_precursors. If they are not Void, then see whether their names are the same as in the current class or not.

mw66 commented 4 months ago

Thanks. I also found this navigation:

pwd: /gobo/tool/gec

../../library/tools/src/eiffel/compilation/et_feature_flattener.e flatten_inherited_feature (a_feature: ET_INHERITED_FEATURE)

../../library/tools/src/eiffel/ast/feature/et_inherited_feature.e ET_INHERITED_FEATURE flattened_parent: ET_PARENT_FEATURE -- Parent feature from which `flattened_feature' is resulting

../../library/tools/src/eiffel/ast/feature/et_parent_feature.e precursor_feature: ET_FEATURE -- Feature inherited from `parent'

../../library/tools/src/eiffel/ast/feature/et_feature.e is_attribute: BOOLEAN -- Is feature an attribute?

Do you think this is good enough to scan all the renamed attribute (I don't care about methods)?

ebezault commented 4 months ago

I think it would work, except that ET_INHERITED_FEATURE objects are intermediate objects only used in the feature flattener. They are not kept in the AST objects.

So with the former solution, you can call the code of gec up to Degree 4 included, and then write your own code (without having to modify any line of code in the Gobo library) to navigate through the resulting AST (ET_CLASS.queries.item(...).first_precursor).

With the latter solution, you would probably have to modify the feature flattener class to intercept the ET_INHERITED_FEATURE objects on the fly when they are processed. Because they are thrown away after being processed.

mw66 commented 4 months ago

Which solution is easiest to implement in your estimate?

(You know: "There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies.")

I want to take the simple way 🙂

ebezault commented 4 months ago

Simplest way is the former solution: no need to modify Gobo's code, so no risk to break it. Just call the Gobo code from your code to generate the AST, and then traverse the AST (ET_CLASS, ET_FEATURE, precursors, ...) still from your code.

mw66 commented 4 months ago

Thanks.

I will use tool/gedoc/src/gedoc_implicit_converts_format.e as a template for quick start.

mw66 commented 4 months ago

Hi @ebezault

I did a quick experiment using tool/gedoc/src/gedoc_implicit_converts_format.e as a template:

https://github.com/joortcom/gobo/blob/eiffel_rename/tool/gedoc/src/gedoc_field_rename_format.e#L119-L176

only two new methods:

process_et_feature

process_implicit_converts

Since gec cannot build this project (ref #71), I added a Makefile to build using ISE's ec:

https://github.com/joortcom/gobo/blob/eiffel_rename/tool/gedoc/Makefile

$ cd /gobo/tool/gedoc
$ make ise  # build gedoc

$ cd test/rename/

$ make demo  # try the new build
../../gedoc --format=field_rename app.ecf
Degree 6: 0/0/0 0:0:0.149
Degree 5: 0/0/0 0:0:7.063
Degree 4: 0/0/0 0:0:2.403
[renamed field] READABLE_INDEXABLE.upper => STRING_8.count

[renamed field] READABLE_INDEXABLE.upper => READABLE_STRING_8.count

[renamed field] READABLE_INDEXABLE.upper => STRING_32.count

[renamed field] TWO_WAY_LIST.first_element => TWO_WAY_TREE.first_child

[renamed field] TWO_WAY_LIST.last_element => TWO_WAY_TREE.last_child

[renamed field] LINKED_LIST.after => TWO_WAY_TREE.child_after

[renamed field] LINKED_LIST.first_element => LINKED_TREE.first_child

[renamed field] LINKED_LIST.before => TWO_WAY_TREE.child_before

[renamed field] LINKED_LIST.count => TWO_WAY_TREE.arity

[renamed field] LINKABLE.right => TWO_WAY_TREE.right_sibling

[renamed field] LINKED_LIST.after => LINKED_TREE.child_after

[renamed field] BI_LINKABLE.left => TWO_WAY_TREE.left_sibling

[renamed field] LINKED_LIST.active => TWO_WAY_TREE.child

[renamed field] LINKED_LIST.before => LINKED_TREE.child_before

[renamed field] LINKED_LIST.count => LINKED_TREE.arity

[renamed field] TWO_WAY_LIST_ITERATION_CURSOR.active => TWO_WAY_TREE_ITERATION_CURSOR.node

[renamed field] LINKABLE.right => LINKED_TREE.right_sibling

[renamed field] LINKED_LIST_ITERATION_CURSOR.active => LINKED_TREE_ITERATION_CURSOR.node

[renamed field] GENERAL_SPECIAL_ITERATION_CURSOR.area => SPECIAL_ITERATION_CURSOR.target

[renamed field] LINKED_LIST.active => LINKED_TREE.child

[renamed field] INDEXABLE_ITERATION_CURSOR.target_index => HASH_TABLE_ITERATION_CURSOR.iteration_position

[renamed field] READABLE_INDEXABLE.upper => DIRECTORY_NAME.count

[renamed field] IO_MEDIUM.handle_available => PLAIN_TEXT_FILE.descriptor_available

[renamed field] IO_MEDIUM.handle_available => RAW_FILE.descriptor_available

[renamed field] READABLE_INDEXABLE.upper => FILE_NAME.count

[renamed field] IO_MEDIUM.handle_available => FILE.descriptor_available

[renamed field] IO_MEDIUM.handle_available => CONSOLE.descriptor_available

[renamed field] READABLE_INDEXABLE.upper => PATH_NAME.count

[renamed field] READABLE_INDEXABLE.upper => READABLE_STRING_32.count

[renamed field] HASH_TABLE.count => SED_OBJECTS_TABLE.capacity

Total Time: 0/0/0 0:0:10.252

However in the test file research_assistant.e has two fields addr renames, but why it's not reported in the above output?

BTW:

$ cd test/rename/
$ make gobo  # the test app program can be compiled by gec, and executed fine.

So what's going wrong? why some of the class / queries not visited?

Can you help me to make this output research_assistant.e's renamed fields?

Thanks.

mw66 commented 4 months ago

In particular: looks like it does not scan from the <root class="APP" feature="make"/> class?

https://github.com/joortcom/gobo/blob/eiffel_rename/tool/gedoc/test/rename/app.ecf#L4

ebezault commented 4 months ago

Before looking at the rename issue, I have a couple of remarks:

    ec  -config src/system.ecf
    cd EIFGENs/gedoc/$(DIR)/ && finish_freezing

with:

    ec  -c_compile -config src/system.ecf
ebezault commented 4 months ago

For class RESEARCH_ASSISTANT, assuming that this is this code:

class RESEARCH_ASSISTANT
inherit
    STUDENT rename addr as student_addr end  -- field student_addr inherit the dorm semantics
    FACULTY rename addr as faculty_addr end  -- field faculty_addr inherit the lab  semantics
    -- then select, NOTE: not needed by SmartEiffel, but needed by GOBO and ISE compiler
    PERSON  select addr end

I can see that there are replications. It means that from 1 attribute addr, you created 2 new attributes (student_addr and faculty_addr) to end up with 3 attributes in class RESEARCH_ASSISTANT. The attributes student_addr and faculty_addr have no precursors (at least not in the internals of the compiler) because the selected version is the one inherited from PERSON. It's as if two new attributes had been created in class RESEARCH_ASSISTANT. So using first_precursor and other_precursors will not help in this case because it will not catch renaming occurring on a replicated attribute.

Another solution could be to traverse ET_CLASS.parent_clauses, go down to the rename clauses (ET_PARENT.renames), look at the new name (ET_RENAME.new_name.feature_name) and see whether it is an attribute in the current class (ET_CLASS.named_query (...).is_attribute).

This should compile with no CAT-call warnings with gec :-)

mw66 commented 4 months ago

with:

  ec  -c_compile -config src/system.ecf

I tried this, the command runs fine without any error, but the executable EIFGENs/gedoc/W_code/gedoc is not updated.

mw66 commented 4 months ago

Another solution could be to traverse ET_CLASS.parent_clauses, go down to the rename clauses (ET_PARENT.renames), look at the new name (ET_RENAME.new_name.feature_name) and see whether it is an attribute in the current class (ET_CLASS.named_query (...).is_attribute).

Thanks, the navigation from ET_CLASS.parent_clauses worked:

[renamed field] STUDENT.addr => RESEARCH_ASSISTANT.student_addr
[renamed field] FACULTY.addr => RESEARCH_ASSISTANT.faculty_addr
mw66 commented 4 months ago

I've got the renamed fields path. Now, how do I get inherited (instead of self-declared) fields path? i.e.

PERSON.addr => STUDENT.addr  (since STUDENT does not declare .addr in itself, but inherited from PERSON)
PERSON.addr => FACULTY.addr  (same as above)
ebezault commented 4 months ago

with:

    ec  -c_compile -config src/system.ecf

I tried this, the command runs fine without any error, but the executable EIFGENs/gedoc/W_code/gedoc is not updated.

Forcing the C compilation by calling finish_freezing will regenerate the same executable. What is updated after an incremental compilation is the .melted file, not the C files. If you want the C files to be updated, add the command-line option -freeze.

ebezault commented 4 months ago

I got the renamed fields path. Now, how do I get inherited (instead of self-declared) fields path? i.e.

PERSON.addr => STUDENT.addr  (since STUDENT does not declare .addr in itself, but inherited from PERSON)
PERSON.addr => FACULTY.addr  (same as above)

OK, so you are not just interested in renamed attributes anymore, but in all inherited attributes! Perhaps you should combine the two implementations (traversing the parent clauses for the renamings, and the first and other precursors to detect those which are not renamed). If it has a precursor, it means that it is inherited. The reverse is not true as we could see in case of replication.

Otherwise, in ET_CLASS.queries, the queries between 1 and `declared_count' are declared in the current class, and above they are inherited. But be careful, declared in the current class does not mean that they have been introduced in this class. It can also mean that they are inherited and redefined.

ebezault commented 4 months ago

I'm sorry that the solution is not as easy as it could be. This code has been written for the specific needs of gec, so it might be missing some metadata which were not needed by gec. But hopefully it should be possible to reconstruct what you need by combining several approaches, as suggested above.

mw66 commented 4 months ago

I'm still interested in renamed attributes, but need to dig deeper: basically I want to detect renamed attributes that coming from the same origin (e.g. in the case of diamond problem).

So:

[renamed field] STUDENT.addr => RESEARCH_ASSISTANT.student_addr
[renamed field] FACULTY.addr => RESEARCH_ASSISTANT.faculty_addr

I need to dig deeper:

PERSON.addr => STUDENT.addr  (since STUDENT does not declare .addr in itself, but inherited from PERSON)
PERSON.addr => FACULTY.addr  (same as above)

and find out RESEARCH_ASSISTANT.student_addr and RESEARCH_ASSISTANT.faculty_addr are both originated from the same PERSON.addr. This is the goal I want to detect.

Sounds like I need to take this 1st approach:

Perhaps you should combine the two implementations (traversing the parent clauses for the renamings, and the first and other precursors to detect those which are not renamed). If it has a precursor, it means that it is inherited. The reverse is not true as we could see in case of replication.

I will give it a try.

ebezault commented 4 months ago

I just remembered that there is another data at your disposal (which you can use in combination with all the above):

mw66 commented 4 months ago
  • ET_FEATURE.implementation_class tells you where the current feature was written,

what does "where the current feature was written" esp "written" mean? first time introduced? or last time (final)?

ebezault commented 4 months ago
  • ET_FEATURE.implementation_class tells you where the current feature was written,

what does "where the current feature was written" esp "written" mean? first time introduced? or last time (final)?

Last time. "Written" means in which class file can I find its text. So if I have:

class A
feature
     f
          do
                ...
          end
end

class B
inherit
      A
             redefine
                    f
             end
feature
      f
          do
                ...
          end
end

class C
inherit
       B
end      

then feature C.f is written in class B.

And a more complicated example:

class D
feature
     f
          do
                ...
          end
end

class E
inherit
       D
            undefine
                  f
           end
       C
end

then E.f is written in class B (because the version from D is undefined).

mw66 commented 4 months ago

Tried this, but it's not working for PERSON.addr:

If it has a precursor, it means that it is inherited.

My code is here: https://github.com/joortcom/gobo/blob/eiffel_rename/tool/gedoc/src/gedoc_field_rename_format.e#L125-L136

output is here: https://github.com/joortcom/gobo/blob/eiffel_rename/tool/gedoc/test/rename/inherited_fields.path

it worked for things like this one:

https://github.com/joortcom/gobo/blob/a3af3982a213fdbf3886d1e4c52a505f2697be9b/tool/gedoc/test/rename/inherited_fields.path#L43

but not for PERSON.addr => FACULTY.addr.

Will continue try the other method ET_FEATURE.implementation_class.

ebezault commented 4 months ago

If it has a precursor, it means that it is inherited. The reverse is not true

So we are unfortunately in the case where "the reverse is not true" (no precursor does not mean that it is not inherited).

ebezault commented 4 months ago

Looking at your code, I still recommend using:

if l_first_precursor.name.same_feature_name(query.name) then

instead of:

if l_lower_name.is_equal(query.lower_name) then

It's CAT-call free.

mw66 commented 4 months ago

I just remembered that there is another data at your disposal (which you can use in combination with all the above):

  • ET_FEATURE.implementation_class tells you where the current feature was written,
  • ET_FEATURE.implementation_feature is the object of this feature in ET_FEATURE.implementation_class (which might be different from the object of this feature in the current class, in case of renaming for example, but it can also be when joining or when changing the export status among other things).

This approach worked:

??? field: PERSON.addr => FACULTY.addr
[renamed field] STUDENT.addr => RESEARCH_ASSISTANT.student_addr
??? field: PERSON.addr => STUDENT.addr
[renamed field] FACULTY.addr => RESEARCH_ASSISTANT.faculty_addr
??? field: PERSON.addr => RESEARCH_ASSISTANT.student_addr
??? field: PERSON.addr => RESEARCH_ASSISTANT.faculty_addr
??? field: PERSON.addr => RESEARCH_ASSISTANT.addr

But now, I want to filter out non-direct super-sub-class relationship, i.e filter out:

??? field: PERSON.addr => RESEARCH_ASSISTANT.student_addr
??? field: PERSON.addr => RESEARCH_ASSISTANT.faculty_addr

So how to get a ET_CLASS's direct super-classes / sub-classes?

ebezault commented 4 months ago

So how to get a ET_CLASS's direct super-classes / sub-classes?

You get the direct super-classes with ET_CLASS.parent_clauses. For the direct sub-classes, you will have to build them yourself. You can have a look at ET_CLASS.descendants which builds all sub-classes (direct and indirect).

mw66 commented 4 months ago

Is there a way to get rid of this: is_equal for class name:

https://github.com/joortcom/gobo/blob/eiffel_rename/tool/gedoc/src/gedoc_field_rename_format.e#L124

            if not query.implementation_class.upper_name.is_equal(a_class.upper_name) then
ebezault commented 4 months ago
if not query.implementation_class.name.same_class_name (a_class.name) then
ebezault commented 4 months ago

You can also write:

if query.implementation_class /= a_class then

which is probably better because it is possible to have two classes with the same name from different libraries.

mw66 commented 4 months ago

And how about compare:

a ET_CLASS and a parent.type is the same class?

ebezault commented 4 months ago

And how about compare:

a ET_CLASS and a parent.type is the same class?

if l_parent.type.base_class = l_class then
mw66 commented 4 months ago

You get the direct super-classes with ET_CLASS.parent_clauses.

https://github.com/joortcom/gobo/blob/eiffel_rename/tool/gedoc/src/gedoc_field_rename_format.e#L119-L142

I added is_direct_parent() check, but the output still is the same, did not filter out direct non-direct output.

Something is wrong?

ebezault commented 4 months ago

Something is wrong?

RESEARCH_ASSISTANT is a direct sub-class of PERSON:

class RESEARCH_ASSISTANT
inherit
    STUDENT rename addr as student_addr end  -- field student_addr inherit the dorm semantics
    FACULTY rename addr as faculty_addr end  -- field faculty_addr inherit the lab  semantics
    -- then select, NOTE: not needed by SmartEiffel, but needed by GOBO and ISE compiler
HERE --> PERSON  select addr end   <-- HERE
mw66 commented 4 months ago

Ahh! hehe, I'm so concentrated on the PERSON => FACULTY => RESEARCH_ASSISTANT path :-(

Thanks for all the help.

I can go from here. (Process the generated output text separately).

It's quite late now in France.

Good night!

ebezault commented 4 months ago

??? field: PERSON.addr => RESEARCH_ASSISTANT.student_addr ??? field: PERSON.addr => RESEARCH_ASSISTANT.faculty_addr

Do you really want to filter out non-direct super-sub-class relationship, or filter out the attribute renaming (because you got them through another means)?

ebezault commented 4 months ago

It's quite late now in France.

Midnight.

mw66 commented 4 months ago

??? field: PERSON.addr => RESEARCH_ASSISTANT.student_addr ??? field: PERSON.addr => RESEARCH_ASSISTANT.faculty_addr

Do you really want to filter out non-direct super-sub-class relationship, or filter out the attribute renaming (because you got them through another means)?

Basically I want to build the step-wise attribute inheritance migration graph the programmer directly wrote in the code, instead of the graph what the compiler has consolidated.

Therefore, I want to filter out these:

??? field: PERSON.addr => RESEARCH_ASSISTANT.student_addr ??? field: PERSON.addr => RESEARCH_ASSISTANT.faculty_addr

But now I think I can do as post-processing step to remove these from the output, e.g. I only need the following step-wise arrows (edges):

??? field: PERSON.addr => FACULTY.addr
??? field: PERSON.addr => STUDENT.addr
[renamed field] STUDENT.addr => RESEARCH_ASSISTANT.student_addr
[renamed field] FACULTY.addr => RESEARCH_ASSISTANT.faculty_addr
??? field: PERSON.addr => RESEARCH_ASSISTANT.addr
ebezault commented 4 months ago

Basically I want to build the step-wise attribute inheritance migration graph the programmer directly wrote in the code, instead of the graph what the compiler has consolidated.

That way we don't have the view consolidated by the compiler, but the view that we have in the programmer's class texts.

mw66 commented 4 months ago

OK, thanks. Will do for another exercise. I will just use the output I got so far for now.

mw66 commented 4 months ago

I build a small tool to detect fields migration in diamond inheritance:

https://github.com/joortcom/gobo/blob/eiffel_rename/tool/gedoc/detect_diamond.py

after building the new gedoc

$ cd <your dir>/gobo/tool/gedoc/test/rename
$ make demo 
../../gedoc --format=field_rename app.ecf > inherited_fields.path
../../detect_diamond.py
total fields:  486
diamond:  PERSON.addr  =>  RESEARCH_ASSISTANT
   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')}

I want to try this tool on some bigger projects, so what is the biggest open source Eiffel projects that GOBO (esp. gedoc) is known to work with? @ebezault

Thanks.

ebezault commented 4 months ago

I want to try this tool on some bigger projects, so what is the biggest open source Eiffel projects that GOBO (esp. gedoc) is known to work with?

At work we had an Eiffel project made up of 23 000 classes, but it's not open source. So I would try on Gobo itself. You can use this ECF file. I use it to compile all Gobo Eiffel classes.

The Gobo tools are also able to work on projects written with ISE Eiffel, but I could not check many of them, so there might be some unknown issues.

mw66 commented 4 months ago

I want to try this tool on some bigger projects, so what is the biggest open source Eiffel projects that GOBO (esp. gedoc) is known to work with?

At work we had an Eiffel project made up of 23 000 classes, but it's not open source. So I would try on Gobo itself. You can use this ECF file. I use it to compile all Gobo Eiffel classes.

The Gobo tools are also able to work on projects written with ISE Eiffel, but I could not check many of them, so there might be some unknown issues.

I have tried both the GOBO compiler's ecf and this integration.ecf file, the tool didn't report any diamond, which is good. I think you (and other GOBO developers) are careful to avoid diamond.

(update: I have added process_all_ecf() to scan all the ecf files under current dir: https://github.com/joortcom/gobo/blob/eiffel_rename/tool/gedoc/detect_diamond.py#L75

Now, it's simple:

$ <install_dir>/gobo/tool/gedoc/detect_diamond.py

)

Do you mind to run the tool on your own code at work? and see if it can find anything? If it find anything, can you give me a summary, or extract the problem (structure) into some examples? (My gut feeling is that it won't find anything as above :-))

I only want to improve the tool, and the Eiffel language (just as the other issue).

Appreciated.

mw66 commented 4 months ago

The Gobo tools are also able to work on projects written with ISE Eiffel

Is it known that GOBO compiler can compile e.g. ISE Eiffel_23.09/library/vision2/ code?

ebezault commented 4 months ago

I don't know if it can compile everything in EiffelVision2, but I have an application which uses some parts of it and I managed to compile and run it under Windows. I can see that you are under Linux (I guess). I never tried to compile an application using EiffelVision2 on this platform.

mw66 commented 4 months ago

FYI: I found a potential problem here:

/Eiffel_23.09/examples/docking/simple

======================================== docking_simple.ecf total fields:  3240
diamond:  EV_SENSITIVE.implementation  =>  SD_PLACE_HOLDER_ZONE
   implementation {('EV_SENSITIVE.implementation', 'EV_WIDGET.implementation', 'EV_CONTAINER.implementation', 'SD_PLACE_HOLDER_ZONE.implementation')}
   implementation_upper_zone {('EV_SENSITIVE.implementation', 'EV_WIDGET.implementation', 'SD_PLACE_HOLDER_ZONE.implementation_upper_zone')}
=============================

I'm manually checking the source code right now:

This navigation verified the 2nd renamed path:

SD_PLACE_HOLDER_ZONE inherit SD_UPPER_ZONE

SD_UPPER_ZONE inherit EV_CONTAINER rename implementation as implementation_upper_zone

EV_CONTAINER inherit EV_WIDGET redefine implementation

And the 1st un-renamed path is:

SD_PLACE_HOLDER_ZONE inherit SD_DOCKING_ZONE

SD_DOCKING_ZONE inherit EV_CELL

EV_CELL inherit EV_CONTAINER

@ebezault while the updated gedoc reported the correct diamond path, but it did not report the direct step-wise edge.

attached if the generated file:

inherited_fields.path.txt diamond.txt

you can also run

/gobo/tool/gedoc/detect_diamond.py > diamond.txt

to generate them yourself.

ebezault commented 4 months ago

while the updated gedoc reported the correct diamond path, but it did not report the direct step-wise edge.

It's probably time to try to implement the alternative implementation that I had suggested:

mw66 commented 4 months ago

I don't know if it can compile everything in EiffelVision2, but I have an application which uses some parts of it and I managed to compile and run it under Windows. I can see that you are under Linux (I guess). I never tried to compile an application using EiffelVision2 on this platform.

Can you let me know which part of EiffelVision2 you can build on Windows? I will give it a try with gec.

I have scanned all the Eiffel23.09 dir, looks like all the diamonds reported are in EV library, so if gec can build any of the /Eiffel_23.09/examples/ that uses EV_ library, we can compare the result of gec and ec.

ebezault commented 4 months ago

If you want to compare the result of gec and ec, you can build your own (non-GUI) small example (like RESEARCH STUDENT).

mw66 commented 4 months ago

If you want to compare the result of gec and ec, you can build your own (non-GUI) small example (like RESEARCH STUDENT).

I want to build on the real code in Eiffel_23.09 distributed files.

mw66 commented 4 months ago

It's probably time to try to implement the alternative implementation that I had suggested:

@ebezault Now, I want your opinion on this:

Ultimately I want this functionality to be contributed back to the GOBO toolchain, but what's the best place to put it?

1) in the gec compiler (diamond field rename warning message), or 2) separate tool like gedoc, or even geck (means checker) 3) both 1) and 2) 4) both 1) and 2), and even like gedoc tool's --force option to auto-transform the code as the first method in the paper, and overwrite user's source code.

For me, I can do a prototype for option 2).

For other options 1), 3), 4) probably you want do it since no one knows the interals of the GOBO compiler better than you.

What do you think?

ebezault commented 4 months ago

You will have to let me a few days to think about it. I still did not have time to read your paper. There is a 5th solution:

  1. in gedoc, both to generate the warning, and an option to auto-transform the code.

As for gec, I would rather change it to behave like ISE Eiffel. The idea is that code which compiles and works with ISE Eiffel should compile and behave the same with Gobo Eiffel, and vice-versa.