]> source.dussan.org Git - aspectj.git/commitdiff
Fix for Bugzilla 37899: Document or address limitations on handler pointcut/joinpoints
authorehilsdal <ehilsdal>
Tue, 2 Dec 2003 19:31:52 +0000 (19:31 +0000)
committerehilsdal <ehilsdal>
Tue, 2 Dec 2003 19:31:52 +0000 (19:31 +0000)
 * changed "Implementation Limitations" to "Implementation Notes" inside ProgGuide
 * added section on bytecode limitations, headed by handler issues.

docs/dist/doc/README-11.html
docs/dist/doc/index.html
docs/faq/faq.xml
docs/progGuideDB/implementation.xml [new file with mode: 0644]
docs/progGuideDB/limitations.xml [deleted file]
docs/progGuideDB/preface.xml
docs/progGuideDB/progguide.xml
docs/progGuideDB/semantics.xml

index ff29e5d5b1a10e1baca73222a80f99cb6f683c57..f1d4f507f0e754eab4b8160be261ac21597363f0 100644 (file)
@@ -1532,8 +1532,8 @@ These might be fixed during the 1.1 release cycle; find them using the query
               http://bugs.eclipse.org/bugs/buglist.cgi?product=AspectJ&keywords=info</a>
 
 For ajc's 1.1 implementation limitations, see 
-  <a href="progguide/limitations.html">
-   Programming Guide Appendix C, "Implementation Limitations"</a>.
+  <a href="progguide/implementation.html">
+   Programming Guide Appendix: "Implementation Notes"</a>.
   
 </p>
 </body> </html>
index 3eb29ffa5a1e1fef6465b452f067934dc7e38204..b157b34fc055d96c3c7d0d767cfbf10ec8f93598 100644 (file)
@@ -83,7 +83,8 @@
      summarizes AspectJ syntax,
      the <a href="progguide/semantics.html">Language Semantics</a>
      best describes AspectJ usage, and 
-     <a href="progguide/limitations.html">Implementation Limitations</a> notes that
+     <a href="progguide/implementation.html">Implementation Notes</a>
+     describes how
      the current version is limited to code the compiler controls.</td>
      </tr>
 
     As you learn,
     use the compiler's <code>-Xlint</code> flags to catch some common 
     mistakes.  (Understand that the 
-    <a href="progguide/limitations.html">current implementation</a>
+    <a href="progguide/implementation.html">current implementation</a>
     is limited to code the compiler controls.)
 <p>
    To plan how to adopt AspectJ into a project, read the 
index 3a1a4b351b00d49a7b73c11ab691d16e09471e99..bdf74142b11d7c22ca373cb8489653d4ed8da9b0 100644 (file)
@@ -1452,8 +1452,8 @@ aspect PublicErrorLogging {
           </para>
           <para>
           To find out about known issues, see the
-          <ulink url="progguide/limitations.html">
-          AspectJ Programming Guide Appendix, "Limitations"</ulink>
+          <ulink url="progguide/implementation.html">
+          AspectJ Programming Guide Appendix, "Implementation Notes"</ulink>
           and the AspectJ bugs in the database at
           <ulink url="http://bugs.eclipse.org/bugs">http://bugs.eclipse.org/bugs</ulink>
           (using the product <literal>AspectJ</literal>).  Here are direct links to
@@ -3678,8 +3678,8 @@ vmparam -Xmx384m
           a system, so AspectJ program semantics may be limited to code
           the implementation controls.  For our implementation, these 
           limitations are stated in 
-          <ulink url="progguide/limitations.html">
-             Programming Guide Appendix C</ulink>.
+          <ulink url="progguide/implementation.html">
+             Programming Guide Appendix:  Implementation Notes</ulink>.
                  Aside from understanding the use and limitations of the 
                  implementation, there is no need to understand the underlying 
                  technology when writing AspectJ programs.
diff --git a/docs/progGuideDB/implementation.xml b/docs/progGuideDB/implementation.xml
new file mode 100644 (file)
index 0000000..314c574
--- /dev/null
@@ -0,0 +1,178 @@
+<appendix id="implementation" xreflabel="Implementation Notes">
+
+  <title>Implementation Notes</title>
+
+<sect1>
+  <title>Compiler Notes</title>
+
+  <para> 
+    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.
+  </para>
+
+  <para>
+    According to the AspectJ language semantics, the declaration
+  </para>
+
+<programlisting><![CDATA[
+  before(): get(int Point.x) { System.out.println("got x"); }
+]]></programlisting>
+
+  <para>
+    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.
+  </para>
+
+  <para>   
+    But AspectJ implementations are permitted to deviate from this in
+    a well-defined way -- they are permitted to advise only accesses
+    in <emphasis>code the implementation controls</emphasis>.  Each
+    implementation is free within certain bounds to provide its own
+    definition of what it means to control code.
+  </para>
+
+  <para>
+    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 <literal>new
+    Point().x</literal> (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.
+  </para>
+
+  <para>
+    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.
+  </para>
+
+  <para>
+    Aspects that are defined <literal>perthis</literal> or
+    <literal>pertarget</literal> 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 <literal>perthis</literal> of that join point will
+    not be associated.  So aspects defined
+    <literal>perthis(Object)</literal> will not create aspect
+    instances for every object unless <literal>Object</literal>is part
+    of the compile.  Similar restrictions apply to
+    <literal>pertarget</literal> aspects.
+  </para>
+
+  <para>
+    Inter-type declarations such as <literal>declare parents</literal>
+    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, <literal>declare parents : String implements
+    MyInterface</literal> will not work for
+    <literal>java.lang.String</literal> unless
+    <literal>java.lang.String</literal> is part of the compile.
+  </para>
+  
+  <para>
+    Other AspectJ implementations, indeed, future versions of ajc, may
+    define <emphasis>code the implementation controls</emphasis> more
+    liberally or restrictively.
+  </para>
+
+  <para>
+    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.
+  </para>
+</sect1>
+
+<sect1>
+  <title>Bytecode Notes</title>
+
+  <para>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:
+  </para>
+
+  <itemizedlist>
+    <listitem>After and around advice cannot apply to handler
+    join points.</listitem>
+
+    <listitem>The control flow of a handler join point cannot be
+    detected. </listitem>
+  </itemizedlist>
+
+  <para>
+  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.
+  </para>
+
+  <para> The second is that the control flow of a handler join point
+  is not picked out.  For example, the following pointcut
+  </para>
+
+<programlisting><![CDATA[
+  cflow(call(void foo()) || handler(java.io.IOException))
+]]></programlisting>
+
+  <para> will capture all join points in the control flow of a call to
+  <literal>void foo()</literal>, but it will <emphasis>not</emphasis>
+  capture those in the control flow of an
+  <literal>IOException</literal> handler.  It is equivalent to
+  <literal>cflow(call(void foo()))</literal>.  In general,
+  <literal>cflow(handler(<replaceable>Type</replaceable>))</literal>
+  will pick out no join points.
+  </para>
+
+  <para> This does not restrict programs from placing before advice on
+  handlers inside <emphasis>other</emphasis> control flows.  This
+  advice, for example, is perfectly fine:
+  </para>
+
+<programlisting><![CDATA[
+  before(): handler(java.io.IOException) && cflow(void parse()) {
+      System.out.println("about to handle an exception while parsing");
+  }
+]]></programlisting>
+
+  <para>
+    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.
+  </para>
+
+</sect1>
+
+</appendix>
diff --git a/docs/progGuideDB/limitations.xml b/docs/progGuideDB/limitations.xml
deleted file mode 100644 (file)
index 34d1cbd..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-<appendix id="limitations" xreflabel="Implementation Limitations">
-
-  <title>Implementation Limitations</title>
-
-  <para> 
-    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.
-  </para>
-
-  <para>
-    According to the AspectJ language semantics, the declaration
-  </para>
-
-<programlisting><![CDATA[
-  before(): get(int Point.x) { System.out.println("got x"); }
-]]></programlisting>
-
-  <para>
-    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.
-  </para>
-
-  <para>   
-    But AspectJ implementations are permitted to deviate from this in
-    a well-defined way -- they are permitted to advise only accesses
-    in <emphasis>code the implementation controls</emphasis>.  Each
-    implementation is free within certain bounds to provide its own
-    definition of what it means to control code.
-  </para>
-
-  <para>
-    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 <literal>new
-    Point().x</literal> (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.
-  </para>
-
-  <para>
-    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.
-  </para>
-
-  <para>
-    Aspects that are defined <literal>perthis</literal> or
-    <literal>pertarget</literal> 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 <literal>perthis</literal> of that join point will
-    not be associated.  So aspects defined
-    <literal>perthis(Object)</literal> will not create aspect
-    instances for every object unless <literal>Object</literal>is part
-    of the compile.  Similar restrictions apply to
-    <literal>pertarget</literal> aspects.
-  </para>
-
-  <para>
-    Inter-type declarations such as <literal>declare parents</literal>
-    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, <literal>declare parents : String implements
-    MyInterface</literal> will not work for
-    <literal>java.lang.String</literal> unless
-    <literal>java.lang.String</literal> is part of the compile.
-  </para>
-  
-  <para>
-    Other AspectJ implementations, indeed, future versions of ajc, may
-    define <emphasis>code the implementation controls</emphasis> more
-    liberally or restrictively.
-  </para>
-
-  <para>
-    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.
-  </para>
-
-</appendix>
index 1ad7b382bee9927634e8df7c16ff1575a2da07d8..5484fe5b3c1f29acddceabbb387d7fed6e377011 100644 (file)
@@ -24,7 +24,7 @@
 
     It includes appendices that give a reference to the syntax of AspectJ,
     a more formal description of AspectJ's semantics, and a description of
-    limitations allowed by AspectJ implementations.
+    notes about the AspectJ implementation.
   </para>
 
   <para>
@@ -60,7 +60,7 @@
     linkend="quick">quick reference</xref> to the language's syntax, a more
     in depth coverage of its <xref linkend="semantics">semantics</xref>,
     and a description of the latitude enjoyed by its <xref
-    linkend="limitations">implementations</xref>.
+    linkend="implementation">implementations</xref>.
   </para>
 
 </preface>
index f23ca03b358113c3de33e15cb6f85cbd868b9cca..433d71585a9b7da2f0af5a6f9c540fbc7695b829 100644 (file)
@@ -11,7 +11,7 @@
 <!ENTITY pitfalls       SYSTEM "pitfalls.xml">
 <!ENTITY quickreference SYSTEM "quickreference.xml">
 <!ENTITY semantics      SYSTEM "semantics.xml">
-<!ENTITY limitations    SYSTEM "limitations.xml">
+<!ENTITY implementation SYSTEM "implementation.xml">
 ]>
 
 <book>
@@ -58,6 +58,6 @@
   &pitfalls;
   &quickreference;
   &semantics;
-  &limitations;
+  &implementation;
 
 </book>
index 7b065f136d5d0f1f0e1600ddeec6847e27bc7947..2fe8f7444e872a99169ff9cbeab97c31c576fdd0 100644 (file)
 
         <para> Both <literal>perthis</literal> and <literal>pertarget</literal>
         aspects may be affected by code the AspectJ compiler controls, as
-        discussed in the <xref linkend="limitations"/> appendix.  </para>
+        discussed in the <xref linkend="implementation"/> appendix.  </para>
       </sect3>
 
       <sect3>