Как получить полную переадресацию возвращаемого типа в активных аннотациях Xtend?

Я пробую активные аннотации Xtend, написав простую аннотацию «Logged» для отслеживания, когда были вызваны методы. В основном я хочу написать это в Xtend:

@Logged
override onCreate()
{
   sampleFuncCall()
}

и получить что-то вроде этого в Java:

@Override void onCreate()
{
   Log.d("TAG", "onCreate started");
   sampleFuncCall();
   Log.d("TAG", "onCreate ended");
}

Вот моя первая попытка:

@Active(LoggedAnnotationProcessor)
@Target(ElementType.METHOD)
annotation Logged {
}

class LoggedAnnotationProcessor extends AbstractMethodProcessor
{
    override doTransform(MutableMethodDeclaration method, extension TransformationContext context) 
    {
        val prefix = "wrapped_"
        method.declaringType.addMethod(prefix + method.simpleName) [ m |
            m.static = method.static
            m.visibility = Visibility.PRIVATE
            m.docComment = method.docComment            
            m.exceptions = method.exceptions
            method.parameters.forEach[ p | m.addParameter(p.simpleName, p.type) ]
            m.body = method.body
            m.primarySourceElement = method
            m.returnType = method.returnType
        ]
        val voidMethod = method.returnType === null || method.returnType.void
        method.body = [ ''' 
                try {
                    android.util.Log.d("TAG", "«method.simpleName» start");
                    «IF (!voidMethod) method.returnType» ret = «ENDIF»
                    «prefix + method.simpleName»(«method.parameters.map[simpleName].join(", ")»);
                    android.util.Log.d("TAG", "«method.simpleName» end");
                    «IF (!voidMethod)»return ret;«ENDIF»
                }
                catch(RuntimeException e) {
                    android.util.Log.d("TAG", "«method.simpleName» ended with exception " 
                        + e.getClass().getSimpleName() + "\n" + e.getMessage());
                    throw e;                
                }
            ''']
    }
}

(Обратите внимание, что я не смог найти способ изменить method.body и должен создать новый закрытый метод с префиксом «wrapped_». Я думаю, это плохо для производительности, поэтому, если вы знаете, как изменить тело метода напрямую, Поделись, пожалуйста).

Здесь у меня возникают проблемы при работе с методами, возвращающими void. Если тип возвращаемого значения метода не был объявлен явно, я получаю следующую ошибку:

Невозможно вызвать метод isVoid для ссылки на предполагаемый тип до этапа компиляции. Проверяйте isInferred() перед вызовом любых методов.

Хорошо, я могу добавить проверку метода. возвращаемое значение.

Подскажите, пожалуйста, как правильно написать такую ​​аннотацию, спасибо!


person Alex Jenter    schedule 21.06.2015    source источник
comment
Та же проблема возникает во встроенном org.eclipse.xtend.lib.annotations.AccessorsAnnotation. Таким образом, я думаю, что лучше всего подать запрос об ошибке/улучшении в eclipse.   -  person Christian Dietrich    schedule 21.06.2015


Ответы (1)


возможно, вам следует отложить расчет. к закрытию

method.body = [
    val voidMethod = method.returnType === null || method.returnType.void

         ''' 
            try {
                android.util.Log.d("TAG", "«method.simpleName» start");
                «IF (!voidMethod)»«method.returnType» ret = «ENDIF»
                «prefix + method.simpleName»(«method.parameters.map[simpleName].join(", ")»);
                android.util.Log.d("TAG", "«method.simpleName» end");
                «IF (!voidMethod)»return ret;«ENDIF»
            }
            catch(RuntimeException e) {
                android.util.Log.d("TAG", "«method.simpleName» ended with exception " 
                    + e.getClass().getSimpleName() + "\n" + e.getMessage());
                throw e;                
            }
        ''']
person Christian Dietrich    schedule 21.06.2015
comment
Это сработало, спасибо! Однако я все еще не могу использовать аннотацию из-за другой ошибки: если метод объявляет и использует анонимный класс, объявление этого класса не копируется. Это известная проблема, и она уже обсуждалась здесь: groups.google. com/forum/#!topic/xtend-lang/mvt1YS12_ik Увы, пока от этой идеи придется отказаться. Но все равно спасибо за помощь! - person Alex Jenter; 22.06.2015