Узнайте класс methodinvocation в Процессоре Аннотации для Java

Вместо создания копии я предлагаю использовать средство доступа в NSObject, чтобы получить доступ к NSMutableOrderedSet отношений.

- (void)addSubitemsObject:(SubItem *)value {
      NSMutableOrderedSet* tempSet = [self mutableOrderedSetValueForKey:@"subitems"];
      [tempSet addObject:value];
 }

Например, Примечания к выпуску Core Data для iOS v5.0 ссылаются на это.

В коротком тесте это сработало в моем приложении.

6
задан runT1ME 30 June 2009 в 23:13
поделиться

1 ответ

Здесь есть пара проблем. Вы можете быть заинтересованы в зная Java-тип приемника вызова метода или просто зная, что вызывается класс метода. Информация о Java больше информативен, поскольку он также дает вам общие типы, например List в то время как Elements предоставит вам только класс, например List .

Получение элемента

Чтобы получить элемент класса, для которого вызывается метод, вы можете сделать следующее:


  MethodInvocationTree node = ...;
  Element method =
        TreeInfo.symbol((JCTree)node.getMethodSelect());
  TypeElement invokedClass = (TypeElement)method.getEnclosingElement();

Угловые корпуса:

1. invokedClass может быть суперклассом типа получателя. Так работает фрагмент new ArrayList .equals (null) вернет AbstractList вместо ArrayList , поскольку реализовано equals () в AbstractList , а не в ArrayList .

2. При обработке вызовов массива, например new int []. Clone () , вы должны get TypeElement класса Array .

Получение фактического типа

Чтобы получить тип, нет прямого способа определить, что Тип ресивера есть. Есть некоторая сложность в обработке вызовов методов внутри внутренних классов, где получатель не указан явно (например, в отличие от OuterClass.this.toString () ). Вот пример реализации:


  MethodInvocationTree node = ...;
  TypeMirror receiver;
  if (methodSel.getKind() == Tree.Kind.MEMBER_SELECT) {
    ExpressionTree receiver = ((MemberSelectTree)methodSel).getExpression();
    receiverType = ((JCTree)receiver).type;
  } else if (methodSel.getKind() == Tree.Kind.IDENTIFIER) {
    // need to resolve implicit this, which is described in
    //  JLS3 15.12.1 and 15.9.2

    // A bit too much work that I don't want to work on now
    // Look at source code of
    //   Attr.visitApply(JCMethodInvocation)
    //   resolveImplicitThis(DiagnosticPosition, Env, Type)
  } else
    throw new AssertionError("Unexpected type: " + methodSel.getKind());

Примечание:

Тип получателя должен быть TypeMirror , а не DeclaredType К сожалению. При вызове new int [5] .clone () , получатель будет ArrayType из int [] , который более информативен, чем предыдущий метод.

Запуск его

Оба предыдущих метода требуют, чтобы компилятор определил тип информация для классов. В обычных обстоятельствах компилятор разрешать только типы для объявлений методов, но не тела. Следовательно, методы, описанные ранее, вместо этого вернут null .

Чтобы компилятор разрешил информацию о типе, вы можете выполнить одно из следующими способами:

1. Используйте класс AbstractTypeProcessor , который только что был добавлен в репозиторий компилятора для JDK 7. Ознакомьтесь с работой над JSR 308 и их компилятор. Хотя работа в основном ведется над аннотированными типами, это может быть полезно для. Компилятор позволяет использовать предоставленный класс в обратном совместим с Java 5.

Этот подход позволяет вам писать процессоры, которые вызываются просто как ваши нынешние процессоры.

2. Используйте вместо него JavacTask и вызовите JavacTask.analyze () . смотреть на основной метод этого теста javac , чтобы увидеть, как чтобы вызвать посетителя на классы.

Этот подход делает ваш процессор больше похожим на инструмент анализа а не плагин к компилятору, так как вам нужно будет вызвать его напрямую, а не как обычный процесс.

10
ответ дан 10 December 2019 в 00:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: