Jose Alberto Fernandez wrote, On 30/07/2003 21.14:

Guys,

I think that using C++ or C# as the model for ANT inheritance would be very bad.
As I remember, the rules for resolving multiple inheritance in C++ are
very complicated.

Furthermore I don't know them ;-)

I would propose using the XSLT model. It is much more simple, it may not
allow for the example posted below as is, but I think it provides a well
defined model and a simple set of rules.

I like the idea, I remember JP talking about it, but I gave up at some point because targets and matches have different semantics... let's see.


In escense, the idea is to associate a precedence to each target (template in XSLT)
and when we say target X in a dependency, what is meant is the highest precedence X.
No renaming necessary. Additionally, XSLT has an <apply-imports/> which would be equivalent to having a task like: <call-import/> which evaluates a target with the same name as the current target but comming from the
imported files (not taking into account the current target, nor targets on files
importing this build file).


How to associate precedences, very easy. If we have something like:

        a+---b---c   (1)
       \---d-+--e  (2)
        \--g  \-f  (3)

target precedence on each file will be:
  c=1 b=2 e=3 f=4 d=5 g=6 a=7

So if X is defined in c, e, and f; everybody will finish using the one in f.

Wait a second, does this mean that there is crosstalk between the lines 1, 2, 3?


This is the only issue that we now have with import I know of, and the above doesn't seem to solve it. Instead, it shows IIUC that xslt has the same -lets's call it- "issue"?

If X calls <call-import/> then it will call the X in e, since it is the highest 
definition
lower than the X in f.

Notice that there is no need for renaming anything, just adding a precedence 
attribute
to each target. And precedences are assigned in a depth-first-search manner.

But this is a step back it seems. With naming it's much easier to call the selected target without checking import orders.


I can say: call the f.X target, because I know that I want what f's X does, without having to check the hierarchy.

XSLT forces <imports> to be at the top of the file, which simplifies precedence 
computation.
We could enforce the same (what it really means, is no imports inside targets).

Well, AFAIK if we put imports at the top, what you show is what happens, as each import is executes recursively.


Well, hope you consider this, as an alternative. I think it is much more easy 
to handle
and if XSLTs do not need more that this, I do not see why ANT will need much 
more.

From this mail it still seems to me that renaming is easier to use and les ambiguous.


What remains is the possible issue of intra-buildfile crosstalk.
This makes it even more important to have an importable=true attribute in the project file, as this has to be taken into account.


It still seems that shielding buildfiles between import lines is the most intuitive way of working for the users... let's see.

It can be summarized as:
"
 Each import will insert the imported file in the importing file.
 If there are name clashes, the importing file targets take precedence,
 and those imported targets is available as importedfilename.targetname.
"

-->Which makes me think BTW that properties should be renamed in the same fashion.<--

The above description is seems clear, concise and intuitive.

The problem is: what if I want to use one of the common imported targets that I did no redefine?

Let's say that I want to use the "init" target in the below example. Which one is called?

Ha.

So using the xslt-like method, it becomes:

"
 Each import will insert the imported file in the importing file.
 If there are name clashes, the importing file targets take precedence,
 and those imported targets is available as importedfilename.targetname.
 If there are multiple copies from the same target, the last definition
 takes precedence. Note that the target that takes precedence will be
 used in all dependencies, regardless to which buildfile they came from.
"

We would need to further document it like this:

  Warning:
        The import task is not made to reuse current builfiles as
        building blocks, as it does not provide a way of shielding
        the files between themselves from side-effects of name
        clashes. Be sure to check the buildfile you import so
        that it attains to certain rules [define which].

  Note: Multiple Inheritance Issues
        If you import two files that have a same target, and
        that target is not in your base file, the target used
        by both will be the last one to be declared.
        In other words, the last target definition with the same
        name is the one that will be used by *all* files.

  Suggestion:
        To prevent this, use fully qualified target names, or
        remember to redefine the target in your base buildfile
        in the manner you see fit.

  Example:

File a.xml

        <project name="first">
           <target name="a" depends="init">
              <echo value="inita">
           </target>
           <target name="init">
              <echo value="initb">
           </target>
        </project>

File b.xml

        <project name="second">
           <target name="b" depends="init">
              <echo value="b">
           </target>
           <target name="init">
              <echo value="inita">
           </target>
        </project>

file build.xml

        <project name="main" default="run">
           <import file="a.xml" />
           <import file="b.xml" />
           <target name="run" depends="a,b"/>
        </project>

Running build.xml will yield this sequence during import:

    import a.xml
       added target a
       added target first.a
       added target init
       added target first.init

[targets: run, a, first.a, init(==first.init), first.init ]

    import b.xml
       added target b
       added target second.b
   --> redefine target init with second.init <--
       added target second.init

[targets: run, a, first.a, first.init
               b, second.a, init(==second.init), second.init ]

Since dependencies are not redefined, the init target that the global buildfile will use is second.init.

To prevent this:

Filw a.xml

        <project name="first">
           <target name="a" depends="init">
              <echo value="inita"></target>
           <target name="my.organization.namespace.a.init">
              <echo value="inita"></target>
        </project>

File b.xml

        <project name="second">
           <target name="b" depends="init">
              <echo value="b"></target>
           <target name="my.organization.namespace.b.init">
              <echo value="initb"></target>
        </project>

file build.xml

        <project name="main" default="run">
           <import file="a.xml" />
           <import file="b.xml" />
           <target name="run" depends="a,b"/>
        </project>

Running build.xml will yield this sequence:

    import a.xml
       added target a
       added target first.a
       added target my.organization.namespace.a.init
       added target first.my.organization.namespace.a.init

[targets: run, a, first.a,
          my.organization.namespace.a.init,
          first.my.organization.namespace.a.init ]

    import b.xml
       added target b
       added target second.b
       added target my.organization.namespace.a.init
       added target first.my.organization.namespace.a.init

[targets: run, a, first.a,
          my.organization.namespace.a.init,
          first.my.organization.namespace.a.init
          b, second.b,
          my.organization.namespace.b.init,
          second.my.organization.namespace.b.init ]

--
Nicola Ken Barozzi                   [EMAIL PROTECTED]
            - verba volant, scripta manent -
   (discussions get forgotten, just code remains)
---------------------------------------------------------------------



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to