That does look suspicious and it raises a difficult question, re: how to
differentiate field accesses in that case?
I think the situation here is that the methods being extended (prior to your
new @Once annotation) are methods that were introduced new in the class, or
perhaps its transformed parent class.
It may be that we should NOT defer converting field access until the end,
but instead, should require that field access conversions occur early
(before methods are modified). Really, there's a transition point between
the field access conversions, and the EXTENSION of existing methods.
This stuff can get very, very tricky!
Another approach that occurs to me would be to rename the original method
(but not mark it as new) and then create an entirely new method that can
invoke the old method. But that's tricky because you can change the
original semantics of the method too easily.
On 10/15/07, Dan Adams <[EMAIL PROTECTED]> wrote:
>
> So IntertalClassTransformationImpl has this:
>
> public void extendMethod(TransformMethodSignature methodSignature,
> String methodBody)
> {
> failIfFrozen();
>
> CtMethod method = findMethod(methodSignature);
>
> try
> {
> method.insertAfter(methodBody);
> }
> catch (CannotCompileException ex)
> {
> throw new
> MethodCompileException(ServicesMessages.methodCompileError(
> methodSignature,
> methodBody,
> ex), methodBody, ex);
> }
>
> addMethodToDescription("extend", methodSignature, methodBody);
>
> _addedMethods.add(method);
> }
>
> The last line there adds the method to the set of added methods which is
> used later here:
>
> private void replaceFieldAccess()
> {
> // Provide empty maps here, to make the code in the inner class
> a tad
> // easier.
>
> if (_fieldReadTransforms == null) _fieldReadTransforms =
> newMap();
>
> if (_fieldWriteTransforms == null) _fieldWriteTransforms =
> newMap();
>
> ExprEditor editor = new ExprEditor()
> {
> @Override
> public void edit(FieldAccess access) throws
> CannotCompileException
> {
> // Ignore any methods to were added as part of the
> transformation.
> // If we reference the field there, we really mean the
> field.
>
> if (_addedMethods.contains(access.where())) return;
>
> Map<String, String> transformMap = access.isReader() ?
> _fieldReadTransforms
> : _fieldWriteTransforms;
>
> String body = transformMap.get(access.getFieldName());
> if (body == null) return;
>
> access.replace(body);
> }
> };
>
> try
> {
> _ctClass.instrument(editor);
> }
> catch (CannotCompileException ex)
> {
> throw new RuntimeException(ex);
> }
> }
>
> It appears that if you extend a method which already exists with new
> code and the code that was in the method before it was extended
> references a field that is now having it's accesses replaced then the
> accesses to that field won't be replaced. But it appears that this could
> be a bug such as in the case where it referenced an injected field. Am I
> correct or am I missing something?
>
> --
> Dan Adams
> Senior Software Engineer
> Interactive Factory
> 617.235.5857
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>
--
Howard M. Lewis Ship
Partner and Senior Architect at Feature50
Creator Apache Tapestry and Apache HiveMind