Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-dev] Dynamically defining fields

Gregor Kiczales wrote:

As you've noticed, AspectJ won't do this for you automatically.

In general, ApectJ's code generation facilities are limited. That
was done intentionally. The AspectJ focus is on AOP.

But there is a way that AspectJ may be useful to you as part of your
solution.  Several people have done this before, so its not novel,
but I don't know if its written down.

A common problem with the kind of code generation you are talking
about is that the generated code is scattered (and tangled) across
a number of files.  That can get you into complex compile structures,
because you want to avoid having the generator output to the original
sources etc.

So the trick is to have the generator output a modular aspect, and
then let the AspectJ compiler weave the definitions into a number
of output class files.

One way to think about this is as a two stage compiler. The first
stage goes from a high-level statement that the existence of certain
methods implies the existence of certain fields, and generates a
declaration for each such field, in a single aspect. The second stage
then weaves those fields throughout the code.
You're absolutely right - this would work, assuming that the second stage worked off of _source code_ and not compiled class files, since user code may utilize the variables which are to be weaved, and thus the code will not compile until *after* the weaving has taken place.

Given this. there are two choices (maybe more?). One is that each stage is a separate process, the first parsing the source code and creating an aj file, the other process would then parse the source code+aj, and weaving a .class file. The other choice merges the two stages into a single process, in effect, creating a 2 pass compiler. I assume (please correct me if I'm wrong - my compiler theory is a little rusty!) that ajc (and javac for that matter) is a two-pass (or at least a 1.5 pass) compiler. That is, because there is no requirement in java to forward delcare variables, a compiler must resolve references after the parsing has completed. Given that references are resolved after-the-fact, I could imagine that a reference be artificially created during the first pass, and successfully resolved in the second pass.

The question becomes (to which I don't know the answer, perhaps someone else does?), does AJC only work on code that successfully compiled *prior* to weaving, or is it possible to write a method that won't compile, and an aspect that completely overrides that method, run ajc on the source+aj, and produce a valid .class file?

I recognize that this is not the "usual" use case for aspects, because it isn't really cross-cutting. I know that there were tools designed specifically for pre-processor type of behavior. Usually, these tools require modifications to the language (eg, added keywords). AspectJ is at least a post-processor (possibly a pre-processor (in effect, at least), depending on the answer above), but defines it's own language, keeping the java language pristine. Having a tool which acts as a pre-processor (in effect, at least) without having a pre-processor, and modifying the language accordingly. Given that we already utilize AspectJ for other cross-cutting concerns, we were hoping to utilize (or expand) on some of the other use-cases for which a pre-processor may be used.

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature


Back to the top