public static ImmutableList<EventDeclarationModel> getEventDeclarations(PsiClass psiClass) {
final PsiAnnotation layoutSpecAnnotation =
AnnotationUtil.findAnnotation(psiClass, LayoutSpec.class.getName());
if (layoutSpecAnnotation == null) {
throw new RuntimeException("LayoutSpec annotation not found on class");
}
PsiAnnotationMemberValue psiAnnotationMemberValue =
layoutSpecAnnotation.findAttributeValue("events");
ArrayList<EventDeclarationModel> eventDeclarationModels = new ArrayList<>();
if (psiAnnotationMemberValue instanceof PsiArrayInitializerMemberValue) {
PsiArrayInitializerMemberValue value =
(PsiArrayInitializerMemberValue) psiAnnotationMemberValue;
for (PsiAnnotationMemberValue annotationMemberValue : value.getInitializers()) {
PsiClassObjectAccessExpression accessExpression =
(PsiClassObjectAccessExpression) annotationMemberValue;
eventDeclarationModels.add(getEventDeclarationModel(accessExpression));
}
} else if (psiAnnotationMemberValue instanceof PsiClassObjectAccessExpression) {
eventDeclarationModels.add(
getEventDeclarationModel((PsiClassObjectAccessExpression) psiAnnotationMemberValue));
}
return ImmutableList.copyOf(eventDeclarationModels);
}
public static boolean isLayoutSpec(@Nullable PsiClass psiClass) {
return psiClass != null && hasAnnotation(psiClass, equals(LayoutSpec.class.getName()));
}
/**
* @return a new {@link LayoutSpecModel} or null if provided class isn't a {@link LayoutSpec}
* class. Access is allowed from event dispatch thread or inside read-action only.
*/
@Nullable
public LayoutSpecModel createWithPsi(
Project project,
PsiClass psiClass,
@Nullable DependencyInjectionHelper dependencyInjectionHelper) {
LayoutSpec layoutSpecAnnotation =
PsiAnnotationProxyUtils.findAnnotationInHierarchy(psiClass, LayoutSpec.class);
if (layoutSpecAnnotation == null) {
return null;
}
// #5 trigger methods
ImmutableList<SpecMethodModel<EventMethod, EventDeclarationModel>> triggerMethods =
PsiTriggerMethodExtractor.getOnTriggerMethods(psiClass, INTER_STAGE_INPUT_ANNOTATIONS);
// #12 classJavadoc
String classJavadoc = "classJavadoc";
// #13 JavadocExtractor.getPropJavadocs()
ImmutableList<PropJavadocModel> propJavadocs = ImmutableList.of();
return new LayoutSpecModel(
psiClass.getQualifiedName(),
layoutSpecAnnotation.value(),
PsiDelegateMethodExtractor.getDelegateMethods(
psiClass,
mLayoutSpecDelegateMethodAnnotations,
INTER_STAGE_INPUT_ANNOTATIONS,
ImmutableList.<Class<? extends Annotation>>of(ShouldUpdate.class)),
PsiEventMethodExtractor.getOnEventMethods(psiClass, INTER_STAGE_INPUT_ANNOTATIONS),
triggerMethods,
PsiWorkingRangesMethodExtractor.getRegisterMethod(psiClass, INTER_STAGE_INPUT_ANNOTATIONS),
PsiWorkingRangesMethodExtractor.getRangesMethods(psiClass, INTER_STAGE_INPUT_ANNOTATIONS),
PsiUpdateStateMethodExtractor.getOnUpdateStateMethods(
psiClass, INTER_STAGE_INPUT_ANNOTATIONS, false),
PsiUpdateStateMethodExtractor.getOnUpdateStateMethods(
psiClass, INTER_STAGE_INPUT_ANNOTATIONS, true),
ImmutableList.<String>of(),
PsiPropDefaultsExtractor.getPropDefaults(psiClass),
PsiEventDeclarationsExtractor.getEventDeclarations(psiClass),
PsiAnnotationExtractor.extractValidAnnotations(project, psiClass),
null,
classJavadoc,
propJavadocs,
layoutSpecAnnotation.isPublic(),
dependencyInjectionHelper,
layoutSpecAnnotation.isPureRender(),
SpecElementType.JAVA_CLASS,
psiClass,
mLayoutSpecGenerator,
PsiTypeVariablesExtractor.getTypeVariables(psiClass),
PsiFieldsExtractor.extractFields(psiClass),
null);
}
@Override
public Set<Element> extract(RoundEnvironment roundEnvironment) {
return (Set<Element>) roundEnvironment.getElementsAnnotatedWith(LayoutSpec.class);
}
/**
* Create a {@link LayoutSpecModel} from the given {@link TypeElement} and an optional {@link
* DependencyInjectionHelper}.
*/
@Override
public LayoutSpecModel create(
Elements elements,
Types types,
TypeElement element,
Messager messager,
EnumSet<RunMode> runMode,
@Nullable DependencyInjectionHelper dependencyInjectionHelper,
@Nullable InterStageStore interStageStore) {
return new LayoutSpecModel(
element.getQualifiedName().toString(),
element.getAnnotation(LayoutSpec.class).value(),
DelegateMethodExtractor.getDelegateMethods(
element,
mLayoutSpecDelegateMethodAnnotations,
INTER_STAGE_INPUT_ANNOTATIONS,
ImmutableList.<Class<? extends Annotation>>of(ShouldUpdate.class),
messager),
EventMethodExtractor.getOnEventMethods(
elements, element, INTER_STAGE_INPUT_ANNOTATIONS, messager, runMode),
TriggerMethodExtractor.getOnTriggerMethods(
elements, element, INTER_STAGE_INPUT_ANNOTATIONS, messager, runMode),
WorkingRangesMethodExtractor.getRegisterMethod(
element, INTER_STAGE_INPUT_ANNOTATIONS, messager),
WorkingRangesMethodExtractor.getRangesMethods(
elements, element, INTER_STAGE_INPUT_ANNOTATIONS, messager),
UpdateStateMethodExtractor.getOnUpdateStateMethods(
element, INTER_STAGE_INPUT_ANNOTATIONS, messager),
UpdateStateMethodExtractor.getOnUpdateStateWithTransitionMethods(
element, INTER_STAGE_INPUT_ANNOTATIONS, messager),
interStageStore == null
? ImmutableList.of()
: CachedPropNameExtractor.getCachedPropNames(
interStageStore, element.getQualifiedName()),
ImmutableList.copyOf(PropDefaultsExtractor.getPropDefaults(element)),
EventDeclarationsExtractor.getEventDeclarations(
elements, element, LayoutSpec.class, runMode),
AnnotationExtractor.extractValidAnnotations(element),
TagExtractor.extractTagsFromSpecClass(types, element, runMode),
JavadocExtractor.getClassJavadoc(elements, element),
JavadocExtractor.getPropJavadocs(elements, element),
element.getAnnotation(LayoutSpec.class).isPublic(),
dependencyInjectionHelper,
element.getAnnotation(LayoutSpec.class).isPureRender(),
SpecElementTypeDeterminator.determine(element),
element,
mLayoutSpecGenerator,
ImmutableList.copyOf(TypeVariablesExtractor.getTypeVariables(element)),
FieldsExtractor.extractFields(element),
element.getAnnotation(LayoutSpec.class).simpleNameDelegate());
}