use of io.micronaut.inject.ast.FieldElement in project micronaut-core by micronaut-projects.
the class BeanDefinitionWriter method visitBeanDefinitionConstructorInternal.
private void visitBeanDefinitionConstructorInternal(GeneratorAdapter staticInit, Object constructor, boolean requiresReflection) {
if (constructor instanceof MethodElement) {
MethodElement methodElement = (MethodElement) constructor;
AnnotationMetadata constructorMetadata = methodElement.getAnnotationMetadata();
DefaultAnnotationMetadata.contributeDefaults(this.annotationMetadata, constructorMetadata);
DefaultAnnotationMetadata.contributeRepeatable(this.annotationMetadata, methodElement.getGenericReturnType());
ParameterElement[] parameters = methodElement.getParameters();
List<ParameterElement> parameterList = Arrays.asList(parameters);
applyDefaultNamedToParameters(parameterList);
pushNewMethodReference(staticInit, JavaModelUtils.getTypeReference(methodElement.getDeclaringType()), methodElement, requiresReflection, false, false);
} else if (constructor instanceof FieldElement) {
FieldElement fieldConstructor = (FieldElement) constructor;
pushNewFieldReference(staticInit, JavaModelUtils.getTypeReference(fieldConstructor.getDeclaringType()), fieldConstructor, constructorRequiresReflection);
} else {
throw new IllegalArgumentException("Unexpected constructor: " + constructor);
}
staticInit.putStatic(beanDefinitionType, FIELD_CONSTRUCTOR, Type.getType(AbstractInitializableBeanDefinition.MethodOrFieldReference.class));
GeneratorAdapter publicConstructor = new GeneratorAdapter(classWriter.visitMethod(ACC_PUBLIC, CONSTRUCTOR_NAME, DESCRIPTOR_DEFAULT_CONSTRUCTOR, null, null), ACC_PUBLIC, CONSTRUCTOR_NAME, DESCRIPTOR_DEFAULT_CONSTRUCTOR);
publicConstructor.loadThis();
publicConstructor.push(beanType);
publicConstructor.getStatic(beanDefinitionType, FIELD_CONSTRUCTOR, Type.getType(AbstractInitializableBeanDefinition.MethodOrFieldReference.class));
publicConstructor.invokeConstructor(superBeanDefinition ? superType : beanDefinitionType, PROTECTED_ABSTRACT_BEAN_DEFINITION_CONSTRUCTOR);
publicConstructor.visitInsn(RETURN);
publicConstructor.visitMaxs(5, 1);
publicConstructor.visitEnd();
if (!superBeanDefinition) {
// create protected constructor for subclasses of AbstractBeanDefinition
GeneratorAdapter protectedConstructor = new GeneratorAdapter(classWriter.visitMethod(ACC_PROTECTED, PROTECTED_ABSTRACT_BEAN_DEFINITION_CONSTRUCTOR.getName(), PROTECTED_ABSTRACT_BEAN_DEFINITION_CONSTRUCTOR.getDescriptor(), null, null), ACC_PROTECTED, PROTECTED_ABSTRACT_BEAN_DEFINITION_CONSTRUCTOR.getName(), PROTECTED_ABSTRACT_BEAN_DEFINITION_CONSTRUCTOR.getDescriptor());
AnnotationMetadata annotationMetadata = this.annotationMetadata != null ? this.annotationMetadata : AnnotationMetadata.EMPTY_METADATA;
protectedConstructor.loadThis();
// 1: beanType
protectedConstructor.loadArg(0);
// 2: `AbstractBeanDefinition2.MethodOrFieldReference.class` constructor
protectedConstructor.loadArg(1);
// 3: annotationMetadata
if (this.annotationMetadata == null) {
protectedConstructor.push((String) null);
} else {
protectedConstructor.getStatic(getTypeReferenceForName(getBeanDefinitionReferenceClassName()), AbstractAnnotationMetadataWriter.FIELD_ANNOTATION_METADATA, Type.getType(AnnotationMetadata.class));
}
// 4: `AbstractBeanDefinition2.MethodReference[].class` methodInjection
if (allMethodVisits.isEmpty()) {
protectedConstructor.push((String) null);
} else {
protectedConstructor.getStatic(beanDefinitionType, FIELD_INJECTION_METHODS, Type.getType(AbstractInitializableBeanDefinition.MethodReference[].class));
}
// 5: `AbstractBeanDefinition2.FieldReference[].class` fieldInjection
if (fieldInjectionPoints.isEmpty()) {
protectedConstructor.push((String) null);
} else {
protectedConstructor.getStatic(beanDefinitionType, FIELD_INJECTION_FIELDS, Type.getType(AbstractInitializableBeanDefinition.FieldReference[].class));
}
// 6: `ExecutableMethod[]` executableMethods
if (executableMethodsDefinitionWriter == null) {
protectedConstructor.push((String) null);
} else {
protectedConstructor.newInstance(executableMethodsDefinitionWriter.getClassType());
protectedConstructor.dup();
protectedConstructor.invokeConstructor(executableMethodsDefinitionWriter.getClassType(), METHOD_DEFAULT_CONSTRUCTOR);
}
// 7: `Map<String, Argument<?>[]>` typeArgumentsMap
if (!hasTypeArguments()) {
protectedConstructor.push((String) null);
} else {
protectedConstructor.getStatic(beanDefinitionType, FIELD_TYPE_ARGUMENTS, Type.getType(Map.class));
}
// 8: `Optional` scope
String scope = annotationMetadata.getAnnotationNameByStereotype(AnnotationUtil.SCOPE).orElse(null);
if (scope != null) {
protectedConstructor.push(scope);
protectedConstructor.invokeStatic(TYPE_OPTIONAL, METHOD_OPTIONAL_OF);
} else {
protectedConstructor.invokeStatic(TYPE_OPTIONAL, METHOD_OPTIONAL_EMPTY);
}
// 9: `boolean` isAbstract
protectedConstructor.push(isAbstract);
// 10: `boolean` isProvided
protectedConstructor.push(annotationMetadata.hasDeclaredStereotype(Provided.class));
// 11: `boolean` isIterable
protectedConstructor.push(isIterable(annotationMetadata));
// 12: `boolean` isSingleton
protectedConstructor.push(isSingleton(scope));
// 13: `boolean` isPrimary
protectedConstructor.push(annotationMetadata.hasDeclaredStereotype(Primary.class));
// 14: `boolean` isConfigurationProperties
protectedConstructor.push(isConfigurationProperties);
// 15: isContainerType
protectedConstructor.push(isContainerType());
// 16: requiresMethodProcessing
protectedConstructor.push(preprocessMethods);
protectedConstructor.invokeConstructor(isSuperFactory ? TYPE_ABSTRACT_BEAN_DEFINITION : superType, BEAN_DEFINITION_CLASS_CONSTRUCTOR);
protectedConstructor.visitInsn(RETURN);
protectedConstructor.visitMaxs(20, 1);
protectedConstructor.visitEnd();
}
}
use of io.micronaut.inject.ast.FieldElement in project micronaut-core by micronaut-projects.
the class AbstractBeanDefinitionBuilder method produceBeans.
@Override
public <E extends MemberElement> BeanElementBuilder produceBeans(ElementQuery<E> methodsOrFields, Consumer<BeanElementBuilder> childBeanBuilder) {
methodsOrFields = methodsOrFields.onlyConcrete().onlyInstance().modifiers((modifiers) -> modifiers.contains(ElementModifier.PUBLIC));
final List<E> enclosedElements = this.beanType.getEnclosedElements(methodsOrFields);
for (E enclosedElement : enclosedElements) {
if (enclosedElement instanceof FieldElement) {
FieldElement fe = (FieldElement) enclosedElement;
final ClassElement type = fe.getGenericField().getType();
if (type.isPublic() && !type.isPrimitive()) {
return addChildBean(fe, childBeanBuilder);
}
}
if (enclosedElement instanceof MethodElement && !(enclosedElement instanceof ConstructorElement)) {
MethodElement me = (MethodElement) enclosedElement;
final ClassElement type = me.getGenericReturnType().getType();
if (type.isPublic() && !type.isPrimitive()) {
return addChildBean(me, childBeanBuilder);
}
}
}
return this;
}
use of io.micronaut.inject.ast.FieldElement in project micronaut-core by micronaut-projects.
the class TestBeanFactoryDefiningVisitor method visitClass.
@Override
public void visitClass(ClassElement element, VisitorContext context) {
if (element.hasAnnotation(Prototype.class)) {
context.getClassElement(TestBeanProducer.class).ifPresent((producer) -> {
final BeanElementBuilder beanElementBuilder = element.addAssociatedBean(producer);
final ElementQuery<MethodElement> query = ElementQuery.ALL_METHODS.annotated((am) -> am.hasAnnotation(TestProduces.class));
beanElementBuilder.produceBeans(query);
final ElementQuery<FieldElement> fields = ElementQuery.ALL_FIELDS.annotated((am) -> am.hasAnnotation(TestProduces.class));
beanElementBuilder.produceBeans(fields);
});
}
}
use of io.micronaut.inject.ast.FieldElement in project micronaut-core by micronaut-projects.
the class JavaClassElement method getBeanProperties.
@Override
public List<PropertyElement> getBeanProperties() {
if (this.beanProperties == null) {
Map<String, BeanPropertyData> props = new LinkedHashMap<>();
Map<String, VariableElement> fields = new LinkedHashMap<>();
if (isRecord()) {
classElement.asType().accept(new SuperclassAwareTypeVisitor<Object, Object>(visitorContext) {
@Override
protected boolean isAcceptable(Element element) {
return JavaModelUtils.isRecord(element);
}
@Override
public Object visitDeclared(DeclaredType type, Object o) {
Element element = type.asElement();
if (isAcceptable(element)) {
List<? extends Element> enclosedElements = element.getEnclosedElements();
for (Element enclosedElement : enclosedElements) {
if (JavaModelUtils.isRecordComponent(enclosedElement) || enclosedElement instanceof ExecutableElement) {
if (enclosedElement.getKind() != ElementKind.CONSTRUCTOR) {
accept(type, enclosedElement, o);
}
}
}
}
return o;
}
@Override
protected void accept(DeclaredType type, Element element, Object o) {
String name = element.getSimpleName().toString();
if (element instanceof ExecutableElement) {
BeanPropertyData beanPropertyData = props.get(name);
if (beanPropertyData != null) {
beanPropertyData.getter = (ExecutableElement) element;
}
} else {
props.computeIfAbsent(name, propertyName -> {
BeanPropertyData beanPropertyData = new BeanPropertyData(propertyName);
beanPropertyData.declaringType = JavaClassElement.this;
beanPropertyData.type = mirrorToClassElement(element.asType(), visitorContext, genericTypeInfo, true);
return beanPropertyData;
});
}
}
}, null);
} else {
classElement.asType().accept(new PublicMethodVisitor<Object, Object>(visitorContext) {
final String[] readPrefixes = getValue(AccessorsStyle.class, "readPrefixes", String[].class).orElse(new String[] { AccessorsStyle.DEFAULT_READ_PREFIX });
final String[] writePrefixes = getValue(AccessorsStyle.class, "writePrefixes", String[].class).orElse(new String[] { AccessorsStyle.DEFAULT_WRITE_PREFIX });
@Override
protected boolean isAcceptable(javax.lang.model.element.Element element) {
if (element.getKind() == ElementKind.FIELD) {
return true;
}
if (element.getKind() == ElementKind.METHOD && element instanceof ExecutableElement) {
Set<Modifier> modifiers = element.getModifiers();
if (modifiers.contains(Modifier.PUBLIC) && !modifiers.contains(Modifier.STATIC)) {
ExecutableElement executableElement = (ExecutableElement) element;
String methodName = executableElement.getSimpleName().toString();
if (methodName.contains("$")) {
return false;
}
if (NameUtils.isReaderName(methodName, readPrefixes) && executableElement.getParameters().isEmpty()) {
return true;
} else {
return NameUtils.isWriterName(methodName, writePrefixes) && executableElement.getParameters().size() == 1;
}
}
}
return false;
}
@Override
protected void accept(DeclaredType declaringType, javax.lang.model.element.Element element, Object o) {
if (element instanceof VariableElement) {
fields.put(element.getSimpleName().toString(), (VariableElement) element);
return;
}
ExecutableElement executableElement = (ExecutableElement) element;
String methodName = executableElement.getSimpleName().toString();
final TypeElement declaringTypeElement = (TypeElement) executableElement.getEnclosingElement();
if (NameUtils.isReaderName(methodName, readPrefixes) && executableElement.getParameters().isEmpty()) {
String propertyName = NameUtils.getPropertyNameForGetter(methodName, readPrefixes);
TypeMirror returnType = executableElement.getReturnType();
ClassElement getterReturnType;
if (returnType instanceof TypeVariable) {
TypeVariable tv = (TypeVariable) returnType;
final String tvn = tv.toString();
final ClassElement classElement = getTypeArguments().get(tvn);
if (classElement != null) {
getterReturnType = classElement;
} else {
getterReturnType = mirrorToClassElement(returnType, visitorContext, JavaClassElement.this.genericTypeInfo, true);
}
} else {
getterReturnType = mirrorToClassElement(returnType, visitorContext, JavaClassElement.this.genericTypeInfo, true);
}
BeanPropertyData beanPropertyData = props.computeIfAbsent(propertyName, BeanPropertyData::new);
configureDeclaringType(declaringTypeElement, beanPropertyData);
beanPropertyData.type = getterReturnType;
beanPropertyData.getter = executableElement;
if (beanPropertyData.setter != null) {
TypeMirror typeMirror = beanPropertyData.setter.getParameters().get(0).asType();
ClassElement setterParameterType = mirrorToClassElement(typeMirror, visitorContext, JavaClassElement.this.genericTypeInfo, true);
if (!setterParameterType.isAssignable(getterReturnType)) {
// not a compatible setter
beanPropertyData.setter = null;
}
}
} else if (NameUtils.isWriterName(methodName, writePrefixes) && executableElement.getParameters().size() == 1) {
String propertyName = NameUtils.getPropertyNameForSetter(methodName, writePrefixes);
TypeMirror typeMirror = executableElement.getParameters().get(0).asType();
ClassElement setterParameterType = mirrorToClassElement(typeMirror, visitorContext, JavaClassElement.this.genericTypeInfo, true);
BeanPropertyData beanPropertyData = props.computeIfAbsent(propertyName, BeanPropertyData::new);
configureDeclaringType(declaringTypeElement, beanPropertyData);
ClassElement propertyType = beanPropertyData.type;
if (propertyType != null) {
if (propertyType.getName().equals(setterParameterType.getName())) {
beanPropertyData.setter = executableElement;
}
} else {
beanPropertyData.setter = executableElement;
}
}
}
private void configureDeclaringType(TypeElement declaringTypeElement, BeanPropertyData beanPropertyData) {
if (beanPropertyData.declaringType == null && !classElement.equals(declaringTypeElement)) {
beanPropertyData.declaringType = mirrorToClassElement(declaringTypeElement.asType(), visitorContext, genericTypeInfo, true);
} else if (beanPropertyData.declaringType == null) {
beanPropertyData.declaringType = mirrorToClassElement(declaringTypeElement.asType(), visitorContext, genericTypeInfo, false);
}
}
}, null);
}
if (!props.isEmpty()) {
this.beanProperties = new ArrayList<>(props.size());
for (Map.Entry<String, BeanPropertyData> entry : props.entrySet()) {
String propertyName = entry.getKey();
BeanPropertyData value = entry.getValue();
final VariableElement fieldElement = fields.get(propertyName);
if (value.getter != null) {
final AnnotationMetadata annotationMetadata;
List<Element> parents = new ArrayList<>();
if (fieldElement != null) {
parents.add(fieldElement);
}
if (value.setter != null) {
parents.add(value.setter);
}
if (!parents.isEmpty()) {
annotationMetadata = visitorContext.getAnnotationUtils().getAnnotationMetadata(parents, value.getter);
} else {
annotationMetadata = visitorContext.getAnnotationUtils().newAnnotationBuilder().buildForMethod(value.getter);
}
JavaPropertyElement propertyElement = new JavaPropertyElement(value.declaringType == null ? this : value.declaringType, value.getter, annotationMetadata, propertyName, value.type, value.setter == null, visitorContext) {
@Override
public ClassElement getGenericType() {
TypeMirror propertyType = value.getter.getReturnType();
if (fieldElement != null) {
TypeMirror fieldType = fieldElement.asType();
if (visitorContext.getTypes().isAssignable(fieldType, propertyType)) {
propertyType = fieldType;
}
}
Map<String, Map<String, TypeMirror>> declaredGenericInfo = getGenericTypeInfo();
return parameterizedClassElement(propertyType, visitorContext, declaredGenericInfo);
}
@Override
public Optional<String> getDocumentation() {
Elements elements = visitorContext.getElements();
String docComment = elements.getDocComment(value.getter);
return Optional.ofNullable(docComment);
}
@Override
public Optional<MethodElement> getWriteMethod() {
if (value.setter != null) {
return Optional.of(new JavaMethodElement(JavaClassElement.this, value.setter, visitorContext.getAnnotationUtils().newAnnotationBuilder().buildForMethod(value.setter), visitorContext));
}
return Optional.empty();
}
@Override
public Optional<MethodElement> getReadMethod() {
return Optional.of(new JavaMethodElement(JavaClassElement.this, value.getter, annotationMetadata, visitorContext));
}
};
beanProperties.add(propertyElement);
}
}
this.beanProperties = Collections.unmodifiableList(beanProperties);
} else {
this.beanProperties = Collections.emptyList();
}
}
return Collections.unmodifiableList(beanProperties);
}
use of io.micronaut.inject.ast.FieldElement in project micronaut-core by micronaut-projects.
the class JavaClassElement method getEnclosedElements.
@Override
public <T extends io.micronaut.inject.ast.Element> List<T> getEnclosedElements(@NonNull ElementQuery<T> query) {
Objects.requireNonNull(query, "Query cannot be null");
ElementQuery.Result<T> result = query.result();
ElementKind kind = getElementKind(result.getElementType());
List<T> resultingElements = new ArrayList<>();
List<Element> enclosedElements = new ArrayList<>(getDeclaredEnclosedElements());
boolean onlyDeclared = result.isOnlyDeclared();
boolean onlyAbstract = result.isOnlyAbstract();
boolean onlyConcrete = result.isOnlyConcrete();
boolean onlyInstance = result.isOnlyInstance();
if (!onlyDeclared) {
Elements elements = visitorContext.getElements();
TypeMirror superclass = classElement.getSuperclass();
// traverse the super class true and add elements that are not overridden
while (superclass instanceof DeclaredType) {
DeclaredType dt = (DeclaredType) superclass;
TypeElement element = (TypeElement) dt.asElement();
// reached non-accessible class like Object, Enum, Record etc.
if (element.getQualifiedName().toString().startsWith("java.lang.")) {
break;
}
List<? extends Element> superElements = element.getEnclosedElements();
List<Element> elementsToAdd = new ArrayList<>(superElements.size());
superElements: for (Element superElement : superElements) {
ElementKind superKind = superElement.getKind();
if (superKind == kind) {
for (Element enclosedElement : enclosedElements) {
if (elements.hides(enclosedElement, superElement)) {
continue superElements;
} else if (enclosedElement.getKind() == ElementKind.METHOD && superElement.getKind() == ElementKind.METHOD) {
final ExecutableElement methodCandidate = (ExecutableElement) superElement;
if (elements.overrides((ExecutableElement) enclosedElement, methodCandidate, this.classElement)) {
continue superElements;
}
}
}
// dependency injection method resolution requires extended overrides checks
if (result.isOnlyInjected() && superElement.getKind() == ElementKind.METHOD) {
final ExecutableElement methodCandidate = (ExecutableElement) superElement;
// check for extended override
final String thisClassName = this.classElement.getQualifiedName().toString();
final String declaringClassName = element.getQualifiedName().toString();
boolean isParent = !declaringClassName.equals(thisClassName);
final ModelUtils javaModelUtils = visitorContext.getModelUtils();
final ExecutableElement overridingMethod = javaModelUtils.overridingOrHidingMethod(methodCandidate, this.classElement, false).orElse(methodCandidate);
TypeElement overridingClass = javaModelUtils.classElementFor(overridingMethod);
boolean overridden = isParent && overridingClass != null && !overridingClass.getQualifiedName().toString().equals(declaringClassName);
boolean isPackagePrivate = javaModelUtils.isPackagePrivate(methodCandidate);
boolean isPrivate = methodCandidate.getModifiers().contains(Modifier.PRIVATE);
if (overridden && !(isPrivate || isPackagePrivate)) {
// bail out if the method has been overridden, since it will have already been handled
continue;
}
if (isParent && overridden) {
boolean overriddenInjected = overridden && visitorContext.getAnnotationUtils().getAnnotationMetadata(overridingMethod).hasDeclaredAnnotation(AnnotationUtil.INJECT);
String packageOfOverridingClass = visitorContext.getElements().getPackageOf(overridingMethod).getQualifiedName().toString();
String packageOfDeclaringClass = visitorContext.getElements().getPackageOf(element).getQualifiedName().toString();
boolean isPackagePrivateAndPackagesDiffer = overridden && isPackagePrivate && !packageOfOverridingClass.equals(packageOfDeclaringClass);
if (!overriddenInjected && !isPackagePrivateAndPackagesDiffer && !isPrivate) {
// and is not annotated with @Inject
continue;
}
}
}
if (onlyAbstract && !superElement.getModifiers().contains(Modifier.ABSTRACT)) {
continue;
} else if (onlyConcrete && superElement.getModifiers().contains(Modifier.ABSTRACT)) {
continue;
} else if (onlyInstance && superElement.getModifiers().contains(Modifier.STATIC)) {
continue;
}
elementsToAdd.add(superElement);
}
}
enclosedElements.addAll(elementsToAdd);
superclass = element.getSuperclass();
}
if (kind == ElementKind.METHOD) {
// if the element kind is interfaces then we need to go through interfaces as well
Set<TypeElement> allInterfaces = visitorContext.getModelUtils().getAllInterfaces(this.classElement);
List<Element> elementsToAdd = new ArrayList<>(allInterfaces.size());
for (TypeElement itfe : allInterfaces) {
List<? extends Element> interfaceElements = itfe.getEnclosedElements();
interfaceElements: for (Element interfaceElement : interfaceElements) {
if (interfaceElement.getKind() == ElementKind.METHOD) {
ExecutableElement ee = (ExecutableElement) interfaceElement;
if (onlyAbstract && ee.getModifiers().contains(Modifier.DEFAULT)) {
continue;
} else if (onlyConcrete && !ee.getModifiers().contains(Modifier.DEFAULT)) {
continue;
}
for (Element enclosedElement : enclosedElements) {
if (enclosedElement.getKind() == ElementKind.METHOD) {
if (elements.overrides((ExecutableElement) enclosedElement, ee, this.classElement)) {
continue interfaceElements;
}
}
}
elementsToAdd.add(interfaceElement);
}
}
}
enclosedElements.addAll(elementsToAdd);
elementsToAdd.clear();
}
}
boolean onlyAccessible = result.isOnlyAccessible();
if (kind == ElementKind.METHOD) {
if (onlyAbstract) {
if (isInterface()) {
enclosedElements.removeIf((e) -> e.getModifiers().contains(Modifier.DEFAULT));
} else {
enclosedElements.removeIf((e) -> !e.getModifiers().contains(Modifier.ABSTRACT));
}
} else if (onlyConcrete) {
if (isInterface()) {
enclosedElements.removeIf((e) -> !e.getModifiers().contains(Modifier.DEFAULT));
} else {
enclosedElements.removeIf((e) -> e.getModifiers().contains(Modifier.ABSTRACT));
}
}
}
if (onlyInstance) {
enclosedElements.removeIf((e) -> e.getModifiers().contains(Modifier.STATIC));
}
List<Predicate<Set<ElementModifier>>> modifierPredicates = result.getModifierPredicates();
List<Predicate<String>> namePredicates = result.getNamePredicates();
List<Predicate<AnnotationMetadata>> annotationPredicates = result.getAnnotationPredicates();
final List<Predicate<ClassElement>> typePredicates = result.getTypePredicates();
boolean hasNamePredicates = !namePredicates.isEmpty();
boolean hasModifierPredicates = !modifierPredicates.isEmpty();
boolean hasAnnotationPredicates = !annotationPredicates.isEmpty();
boolean hasTypePredicates = !typePredicates.isEmpty();
final JavaElementFactory elementFactory = visitorContext.getElementFactory();
elementLoop: for (Element enclosedElement : enclosedElements) {
ElementKind enclosedElementKind = enclosedElement.getKind();
if (enclosedElementKind == kind || (enclosedElementKind == ElementKind.ENUM && kind == ElementKind.CLASS)) {
String elementName = enclosedElement.getSimpleName().toString();
if (onlyAccessible) {
// exclude private members
if (enclosedElement.getModifiers().contains(Modifier.PRIVATE)) {
continue;
} else if (elementName.startsWith("$")) {
// exclude synthetic members or bridge methods that start with $
continue;
} else {
Element enclosingElement = enclosedElement.getEnclosingElement();
final ClassElement onlyAccessibleFrom = result.getOnlyAccessibleFromType().orElse(this);
Object accessibleFrom = onlyAccessibleFrom.getNativeType();
// we need to check if it package private and within a different package so it can be excluded
if (enclosingElement != accessibleFrom && visitorContext.getModelUtils().isPackagePrivate(enclosedElement)) {
if (enclosingElement instanceof TypeElement) {
Name qualifiedName = ((TypeElement) enclosingElement).getQualifiedName();
String packageName = NameUtils.getPackageName(qualifiedName.toString());
if (!packageName.equals(onlyAccessibleFrom.getPackageName())) {
continue;
}
}
}
}
}
if (hasModifierPredicates) {
Set<ElementModifier> modifiers = enclosedElement.getModifiers().stream().map(m -> ElementModifier.valueOf(m.name())).collect(Collectors.toSet());
for (Predicate<Set<ElementModifier>> modifierPredicate : modifierPredicates) {
if (!modifierPredicate.test(modifiers)) {
continue elementLoop;
}
}
}
if (hasNamePredicates) {
for (Predicate<String> namePredicate : namePredicates) {
if (!namePredicate.test(elementName)) {
continue elementLoop;
}
}
}
final AnnotationMetadata metadata = visitorContext.getAnnotationUtils().getAnnotationMetadata(enclosedElement);
if (hasAnnotationPredicates) {
for (Predicate<AnnotationMetadata> annotationPredicate : annotationPredicates) {
if (!annotationPredicate.test(metadata)) {
continue elementLoop;
}
}
}
T element;
switch(enclosedElementKind) {
case METHOD:
final ExecutableElement executableElement = (ExecutableElement) enclosedElement;
// noinspection unchecked
element = (T) elementFactory.newMethodElement(this, executableElement, metadata, genericTypeInfo);
break;
case FIELD:
// noinspection unchecked
element = (T) elementFactory.newFieldElement(this, (VariableElement) enclosedElement, metadata);
break;
case CONSTRUCTOR:
// noinspection unchecked
element = (T) elementFactory.newConstructorElement(this, (ExecutableElement) enclosedElement, metadata);
break;
case CLASS:
case ENUM:
// noinspection unchecked
element = (T) elementFactory.newClassElement((TypeElement) enclosedElement, metadata);
break;
default:
element = null;
}
if (element != null) {
if (hasTypePredicates) {
for (Predicate<ClassElement> typePredicate : typePredicates) {
ClassElement classElement;
if (element instanceof ConstructorElement) {
classElement = this;
} else if (element instanceof MethodElement) {
classElement = ((MethodElement) element).getGenericReturnType();
} else if (element instanceof ClassElement) {
classElement = (ClassElement) element;
} else {
classElement = ((FieldElement) element).getGenericField();
}
if (!typePredicate.test(classElement)) {
continue elementLoop;
}
}
}
List<Predicate<T>> elementPredicates = result.getElementPredicates();
if (!elementPredicates.isEmpty()) {
for (Predicate<T> elementPredicate : elementPredicates) {
if (!elementPredicate.test(element)) {
continue elementLoop;
}
}
}
resultingElements.add(element);
}
}
}
return Collections.unmodifiableList(resultingElements);
}
Aggregations