Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
listing affected files - was Re: [aspectj-users] iajc ANT Task

Hi Ron -

You're trying to get reasonable compile times for your large
project by minimizing the number of files compiled by ajc,
so you'd like to be able to list the affected files that
you should include in your ajc compile.

Below is some code to list the files by traversing the
structure model after a compile completes.  Of note:

- You should recreate the list of affected files whenever
  you change your pointcuts or inter-type declarations.

- I don't think this detects pointcut dependencies.

- It's written for the revised model coming out in 1.1.1,
  so compile it against the 1.1.1 aspectjtools.jar.
  (See the dev list for links to release candidates.)

- I've only minimally tested it, and it's my first
  foray into the new structure model. *smile*

I'll also put this code in the sample code repository
to be published soon.

Wes
---------- AffectedFilesReporter.java

package org.aspectj.samples;

import org.aspectj.tools.ajc.Main;
import org.aspectj.asm.*;
import org.aspectj.bridge.*;

import java.io.*;
import java.util.*;


/**
 * Run ajc and list files affected by advice or inter-type declarations
 * (including the aspects themselves).
 *
 * WARNING: Does not list files based on uses-pointcut dependency.
 * @author Wes Isberg
 */
public class AffectedFilesReporter implements Runnable {
    /*
     * Walk down asm hierarchy, looking for source files,
     * and check if any of their children has a relation of
     * kind ADVICE or INTER_TYPE_DECLARATION
     */

    /**
     * Wrapper for ajc that emits list of affected files.
     * @param args the String[] of args for ajc,
     *        optionally prefixed with -to {file}
     * @throws IOException if unable to write to {file}
     */
    public static void main(String[] args) throws IOException {
        Main main = new Main();
        PrintStream toConfig = System.out;
        FileOutputStream fin = null;
        if ((args.length > 1) && ("-to".equals(args[0]))) {
            File config = new File(args[1]);
            fin = new FileOutputStream(config);
            toConfig = new PrintStream(fin, true);
            String[] temp = new String[args.length-2];
            System.arraycopy(args, 2, temp, 0, temp.length);
            args = temp;
        }
        Runnable runner = new AffectedFilesReporter(toConfig);
        main.setCompletionRunner(runner);
        // should add -emacssym to args if not already there
        main.runMain(args, false);
        if (null != fin) {
            fin.close();
        }
    }

    final PrintStream sink;

    public AffectedFilesReporter(PrintStream sink) {
        this.sink = (null == sink ? System.out : sink);
    }

    public void run() {
        IHierarchy hierarchy = AsmManager.getDefault().getHierarchy();
        if (null == hierarchy) { // XXX is this how it's detected?
            sink.println("# no structure model - use -emacssym option");
            return;
        }
        List /*IProgramElement*/ nodes = new ArrayList();
        List /*IProgramElement*/ newNodes = new ArrayList();
        // root is config file or blank - either way, use kids
        nodes.addAll(hierarchy.getRoot().getChildren());
        while (0 < nodes.size()) {
            for (ListIterator it = nodes.listIterator();
                  it.hasNext();) {
                IProgramElement node = (IProgramElement) it.next();
                if (node.getKind().isSourceFileKind()) {
                    if (isAffected(node)) {
                        ISourceLocation loc = node.getSourceLocation();
                        sink.println(loc.getSourceFile().getPath());
                    }
                } else {
                    // XXX uncertain of structure - traverse all??
                    newNodes.addAll(node.getChildren());
                }
                it.remove();
            }
            nodes.addAll(newNodes);
            newNodes.clear();
        }
    }

    /**
     * Return true if this file node is affected by any aspects.
     * This only detects when the node or some child is in a
     * relationship of kind ADVICE or DECLARE_INTER_TYPE.
     * @param node the IProgramElementNode for a source file
     * @return true if affected.
     */
    private boolean isAffected(final IProgramElement fileNode) {
        final IRelationshipMap map  =
            AsmManager.getDefault().getRelationshipMap();
        List /*IProgramElement*/ nodes = new ArrayList();
        List /*IProgramElement*/ newNodes = new ArrayList();
        nodes.add(fileNode);
        while (0 < nodes.size()) {
            for (ListIterator iter = nodes.listIterator();
                 iter.hasNext();) {
                IProgramElement node = (IProgramElement) iter.next();
                List relations = map.get(node);
                if (null != relations) {
                    for (Iterator riter = relations.iterator();
                        riter.hasNext();) {
                        IRelationship.Kind kind =
                        ((IRelationship) riter.next()).getKind();
                        if ((kind == IRelationship.Kind.ADVICE)
             || (kind == IRelationship.Kind.DECLARE_INTER_TYPE)) {
                            return true;
                        }
                    }
                }
                iter.remove();
                newNodes.addAll(node.getChildren());
            }
            nodes.addAll(newNodes);
            newNodes.clear();
        }
        return false;
    }
}

DiFrango, Ron wrote:

Wes,

As another note, I would add that it would be nice to have an option to dump
out the code in source format.  I have not found a de-compiler that can
correctly generate the code that has been aspected.

The only reason I use this is to confirm what is getting affected in my
initial testing.  Please note I am the guy that can not use AJDT because our
project is too large (1500+ classes) and crashes Eclipse.  So to me this
verification step is a nice confirmation until AJDT is fixed to handle large
projects properly.

Thanks,

Ron DiFrango


-----Original Message-----
From: DiFrango, Ron Sent: Friday, September 05, 2003 3:09 PM
To: 'aspectj-users@xxxxxxxxxxx'
Subject: RE: [aspectj-users] iajc ANT Task


I was talking about the -preprocess option which appears to be no longer
supported.  So if I understand the FAQ and your comment correctly, when I
pass in a listing file with .java files (and the .class on the class path),
ajc first compiles them, then performs the weaving and drops them in to
output folder?

Thanks,

Ron DiFrango


-----Original Message-----
From: Wes Isberg [mailto:wes@xxxxxxxxxxxxxx] Sent: Friday, September 05, 2003 2:26 PM
To: aspectj-users@xxxxxxxxxxx
Subject: Re: [aspectj-users] iajc ANT Task


It's not clear what you meant by "the output of the weaving"
- preprocessed source files?

Our implementation of AspectJ 1.1 uses bytecode weaving, not source weaving,
so -preprocess is not supported.  See the README for 1.1:
http://dev.eclipse.org/viewcvs/indextech.cgi/~checkout~/aspectj-home/doc/REA
DME-11.html#NO_SOURCE

If instead you want to redirect the messages from ajc, you
can set up a MessageHandler in the ant task and do whatever
you like with the results.  See the ant task docs entry for
"Programmatically handling compiler messages":

http://dev.eclipse.org/viewcvs/indextech.cgi/~checkout~/aspectj-home/doc/dev
guide/antTasks.html

Wes

DiFrango, Ron wrote:

No because that just dumps it out to the console.  Now I could
re-direct to a log file, but that would have everything in it. Under the old task, it dumped out the individual source files in source format with the aspected code dropped in.

Thanks,

Ron DiFrango


-----Original Message-----
From: SADER, KEITH D (Contractor) [mailto:KEITH.D.SADER@xxxxxxxx]
Sent: Friday, September 05, 2003 10:04 AM
To: aspectj-users@xxxxxxxxxxx
Subject: RE: [aspectj-users] iajc ANT Task


Is the -verbose option not sufficient for you?  I.e. in the ant task
set the verbose=true attribute.



-----Original Message-----
From: DiFrango, Ron [mailto:ron.difrango@xxxxxxxxxxxxxx]
Sent: Friday, September 05, 2003 8:00 AM
To: 'aspectj-users@xxxxxxxxxxx'
Subject: [aspectj-users] iajc ANT Task


All,

(Please not this is a re-send, but with the correct subject.)  Under
the old aspectj ANT task, there was an option to output the result of
the weaving,
but under the new task (iajc) there does not appear to be this option. Is
this true or am I missing something?

Thanks in advance,

Ron

<snip>




Back to the top