aboutsummaryrefslogtreecommitdiffstats
path: root/docs/progGuideDB/implementation.adoc
diff options
context:
space:
mode:
authorAlexander Kriegisch <Alexander@Kriegisch.name>2022-01-08 11:50:55 +0700
committerAlexander Kriegisch <Alexander@Kriegisch.name>2024-01-06 10:09:11 +0100
commitd4a6906b3012fac6e4dbaca5854fc59ba0d67e47 (patch)
treec78540555837c12cfaef7f9cc95842668a3ee7f9 /docs/progGuideDB/implementation.adoc
parent9735e858af48ff0bce152ea489800a86a151b08d (diff)
downloadaspectj-d4a6906b3012fac6e4dbaca5854fc59ba0d67e47.tar.gz
aspectj-d4a6906b3012fac6e4dbaca5854fc59ba0d67e47.zip
Rename '*GuideDB' directories to their actual HTML site target names
Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
Diffstat (limited to 'docs/progGuideDB/implementation.adoc')
-rw-r--r--docs/progGuideDB/implementation.adoc265
1 files changed, 0 insertions, 265 deletions
diff --git a/docs/progGuideDB/implementation.adoc b/docs/progGuideDB/implementation.adoc
deleted file mode 100644
index 42ee2e37e..000000000
--- a/docs/progGuideDB/implementation.adoc
+++ /dev/null
@@ -1,265 +0,0 @@
-[[implementation]]
-== Implementation Notes
-
-=== Compiler Notes
-
-The initial implementations of AspectJ have all been compiler-based
-implementations. Certain elements of AspectJ's semantics are difficult
-to implement without making modifications to the virtual machine, which
-a compiler-based implementation cannot do. One way to deal with this
-problem would be to specify only the behavior that is easiest to
-implement. We have chosen a somewhat different approach, which is to
-specify an ideal language semantics, as well as a clearly defined way in
-which implementations are allowed to deviate from that semantics. This
-makes it possible to develop conforming AspectJ implementations today,
-while still making it clear what later, and presumably better,
-implementations should do tomorrow.
-
-According to the AspectJ language semantics, the declaration
-
-[source, java]
-....
-before(): get(int Point.x) { System.out.println("got x"); }
-....
-
-should advise all accesses of a field of type `int` and name `x` from
-instances of type (or subtype of) `Point`. It should do this regardless of
-whether all the source code performing the access was available at the
-time the aspect containing this advice was compiled, whether changes
-were made later, etc.
-
-But AspectJ implementations are permitted to deviate from this in a
-well-defined way -- they are permitted to advise only accesses in _code
-the implementation controls_. Each implementation is free within certain
-bounds to provide its own definition of what it means to control code.
-
-In the current AspectJ compiler, _ajc_, control of the code means having
-bytecode for any aspects and all the code they should affect available
-during the compile. This means that if some class `Client` contains code
-with the expression `new Point().x` (which results in a field get join point at runtime), the
-current AspectJ compiler will fail to advise that access, unless
-`Client.java` or `Client.class` is compiled as well. It also means that join
-points associated with code in native methods (including their execution
-join points) cannot be advised.
-
-Different join points have different requirements. Method and
-constructor call join points can be advised only if _ajc_ controls the
-bytecode for the caller. Field reference or assignment join points can
-be advised only if _ajc_ controls the bytecode for the "caller", the code
-actually making the reference or assignment. Initialization join points
-can be advised only if _ajc_ controls the bytecode of the type being
-initialized, and execution join points can be advised only if _ajc_
-controls the bytecode for the method or constructor body in question.
-The end of an exception handler is underdetermined in bytecode, so _ajc_
-will not implement after or around advice on handler join points.
-Similarly, _ajc_ cannot implement `around` advice on `initialization` or
-`preinitialization` join points. In cases where _ajc_ cannot implement
-advice, it will emit a compile-time error noting this as a compiler
-limitation.
-
-Aspects that are defined `perthis` or `pertarget` also have restrictions
-based on control of the code. In particular, at a join point where the
-bytecode for the currently executing object is not available, an aspect
-defined `perthis` of that join point will not be associated. So aspects
-defined `perthis(Object)` will not create aspect instances for every
-object unless `Object` is part of the compile. Similar restrictions apply
-to `pertarget` aspects.
-
-Inter-type declarations such as `declare parents` also have restrictions
-based on control of the code. If the bytecode for the target of an
-inter-type declaration is not available, then the inter-type declaration
-is not made on that target. So, `declare parents : String implements MyInterface`
-will not work for `java.lang.String`, unless `java.lang.String` is part of the compile.
-
-When declaring members on interfaces, the implementation must control
-both the interface and the top-level implementors of that interface (the
-classes that implement the interface but do not have a superclass that
-implements the interface). You may weave these separately, but be aware
-that you will get runtime exceptions if you run the affected top-level
-classes without the interface as produced by the same _ajc_
-implementation. Any intertype declaration of an `abstract` method on an
-interface must be specified as `public`, you will get a compile time error
-message indicating this is a compiler limitation if you do not specify
-`public`. A non-`abstract` method declared on an interface can use any
-access modifier except protected. Note that this is different to normal
-Java rules where all members declared in an interface are implicitly
-`public`. Finally, note that one cannot define `static` fields or methods on
-interfaces.
-
-When declaring methods on target types, only methods declared `public` are
-recognizable in the bytecode, so methods must be declared `public` to be
-overridden in any subtype or to be called from code in a later compile
-using the target type as a library.
-
-Other AspectJ implementations, indeed, future versions of _ajc_, may
-define _code the implementation controls_ more liberally or
-restrictively, so long as they comport with the Java language. For
-example, the `call` pointcut does not pick out reflective calls to a
-method implemented in
-`java.lang.reflect.Method.invoke(Object, Object[])`. Some suggest that
-the call "happens" and the call pointcut should pick it out, but the
-AspectJ language shouldn't anticipate what happens in code outside the
-control of the implementation, even when it is a well-defined API in a
-Java standard library.
-
-The important thing to remember is that core concepts of AspectJ, such
-as the join point, are unchanged, regardless of which implementation is
-used. During your development, you will have to be aware of the
-limitations of the _ajc_ compiler you're using, but these limitations
-should not drive the design of your aspects.
-
-=== Bytecode Notes
-
-[[the-class-expression-and-string-plus]]
-==== The `.class` expression and `String` `+`
-
-The java language form `Foo.class` is implemented in bytecode with a
-call to `Class.forName` guarded by an exception handler catching a
-`ClassNotFoundException`.
-
-The java language `+` operator, when applied to `String` arguments, is
-implemented in bytecode by calls to `StringBuffer.append`.
-
-In both of these cases, the current AspectJ compiler operates on the
-bytecode implementation of these language features; in short, it
-operates on what is really happening rather than what was written in
-source code. This means that there may be call join points to
-`Class.forName` or `StringBuffer.append` from programs that do not, at
-first glance, appear to contain such calls:
-
-[source, java]
-....
-class Test {
- void main(String[] args) {
- System.out.println(Test.class); // calls Class.forName
- System.out.println(args[0] + args[1]); // calls StringBuffer.append
- }
-}
-....
-
-In short, the join point model of the current AspectJ compiler considers
-these as valid join points.
-
-==== The `handler()` join point
-
-The end of exception handlers cannot reliably be found in Java bytecode.
-Instead of removing the `handler` join point entirely, the current AspectJ
-compiler restricts what can be done with the `handler` join point:
-
-* `after` and `around` advice cannot apply to `handler` join points.
-* The control flow of a `handler` join point cannot be detected.
-
-The first of these is relatively straightforward. If any piece of `after`
-advice (returning, throwing, or "finally") would normally apply to a
-`handler` join point, it will not in code output by the current AspectJ
-compiler. A compiler warning is generated, whenever this is detected to
-be the case. `before` advice is allowed.
-
-The second is that the control flow of a `handler` join point is not
-picked out. For example, the following pointcut
-
-[source, java]
-....
-cflow(call(void foo()) || handler(java.io.IOException))
-....
-
-will capture all join points in the control flow of a call to
-`void foo()`, but it will _not_ capture those in the control flow of an
-`IOException` handler. It is equivalent to `cflow(call(void foo()))`. In
-general, `cflow(handler(Type))` will not pick out any join points, the
-one exception to this is join points that occur during the execution of
-any before advice on the handler.
-
-This does not restrict programs from placing before advice on handlers
-inside _other_ control flows. This advice, for example, is perfectly
-fine:
-
-[source, java]
-....
-before(): handler(java.io.IOException) && cflow(void parse()) {
- System.out.println("about to handle an exception while parsing");
-}
-....
-
-A source-code implementation of AspectJ (such as AspectJ 1.0.6) is able
-to detect the endpoint of a handler join point, and as such will likely
-have fewer such restrictions.
-
-==== Initializers and Inter-type Constructors
-
-The code for Java initializers, such as the assignment to the field `d` in
-
-[source, java]
-....
-class C {
- double d = Math.sqrt(2);
-}
-....
-
-are considered part of constructors by the time AspectJ gets ahold of
-bytecode. That is, the assignment of `d` to the square root of two happens
-_inside_ the default constructor of `C`.
-
-Thus inter-type constructors will not necessarily run a target type's
-initialization code. In particular, if the inter-type constructor calls
-a super-constructor (as opposed to a `this` constructor), the target
-type's initialization code will _not_ be run when that inter-type
-constructor is called.
-
-[source, java]
-....
-aspect A {
- C.new(Object o) {} // implicitly calls super()
-
- public static void main(String[] args) {
- System.out.println((new C() ).d); // prints 1.414...
- System.out.println((new C(null)).d); // prints 0.0
- }
-}
-....
-
-It is the job of an inter-type constructor to do all the required
-initialization, or to delegate to a `this` constructor if necessary.
-
-=== Annotation-style Notes
-
-Writing aspects in annotation-style is subject to the same bytecode
-limitations since the binary aspects take the same form and are woven in
-the same way. However, the implementation differences (e.g., the
-mechanism for implementing `around` advice) may be apparent at runtime.
-See the documentation on annotation-style for more information.
-
-=== Summary of implementation requirements
-
-This summarizes the requirements of our implementation of AspectJ. For
-more details, see the relevant sections of this guide.
-
-* The invoking code must be under the control of _ajc_ for the following
-join points:
-** `call` join point
-** `get` join point
-** `set` join point
-* The declaring/target code must be under the control of _ajc_ for the
-following join points and inter-type declarations:
-** `execution` join point
-** `adviceexecution` join point
-** `handler` join point
-** `initialization` join point
-** `preinitialiaztion` join point
-** `staticinitialization` join point
-** `perthis` aspect
-** `pertarget` aspect
-** `declare _parents_`
-** `declare _method_ | _field_` (see interface caveats below)
-* Implementation Caveats
-** The `initialization` and `preinitialization` join points do not support
-`around` advice
-** The `handler` join point does not support...
-*** `after advice`
-*** `around` advice
-*** `cflow(handler(..))`
-** Declaring members on an interface in an aspect affects only the
-topmost implementing classes the implementation controls.
-** `cflow` and `cflowbelow` pointcuts work within a single thread.
-** Runtime `ClassCastException` may result from supplying a supertype of
-the actual type as an argument to `proceed(..)` in `around` advice.