-
Notifications
You must be signed in to change notification settings - Fork 300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dependencies should consider annotations #136
Comments
Hi @codecholeric, have you started working on this issue? If not I can take it. |
Hi @slq, first of all thanks a lot for the offer!! I've blocked this issue for someone who offered to contribute as well, so I assume it is in progress. Maybe you could look into #115 if you feel like it. I haven't marked it as "good start for contributing", but I think it would be the next best thing 😉 |
… annotation member dependencies Issue: TNG#136
The differences between JavaClass and JavaMemeber made me duplicate parts of the code in order to make proper Dependency descriptions. I think they might be solved by introducing / upgrading some new concepts. Firstly, it seems to me that there might be a need for a HasDescription implementation on JavaClass. String originType = origin.isInterface() ? "Interface" : "Class";
String originDescription = originType + " " + bracketFormat(origin.getName()); might as well make it explicit, if there's not a better reason not to? Secondly, the last part of the description has to do with the location that's derived differently: Should a JavaClass also implement HasOwner and return itself or is there a need for a new concept? |
Yeah, |
…d JavaClass Issue: TNG#136
I've managed to implement most dependencies from and that way seems to be pretty straight-forward. I've tried to fetch dependencies to class through |
The
I don't know if this really holds for the simple building of annotations. You could compare an import of 50K classes though with and without the change of The |
I've tried testing the performance with and without the supplier on a set of 27441 classes and the duration of both tests seem to converge to around 30s. ArchRule rule = classes().should().resideInAPackage("..");
JavaClasses classes = new ClassFileImporter().importPackages("java", "javax", "org", "com", "net", "junit", "sun", "jdk");
rule.check(classes); So, if my testing and reasoning is correct, the supplier can be omitted in the case of annotations? |
Yeah, I've checked it on the full JDK as well, and didn't notice any difference. Maybe originally I did something more complex there, but for now I think it's save to replace the |
While analyzing some failed tests I think I've figure out why annotations were supplied in a JavaClass and not instantiated eagerly in The test results in a I'm trying to find a third way of providing annotation dependencies to class that is not coupled with the Other tests fail mostly due to the new features added. For example, |
Ay, now that you mention it, I do remember 😉 I think that might have been one of those places where a comment would have been a good idea. |
Only the info that is registered into the context. Since JavaAnnotations are instantiated via a It looks like annotations need to be registered after I've managed to do this in my latest commit, which fixed the issue, but there are still a couple of tests that are bugging me. |
Ah I see! As far as I remember I wanted to avoid a second run over the classes there (since you could iterate all classes again and complete the annotations after the run to complete all members). So there are two things coming to my mind a) check if that really costs so much performance (compare 50K classes or sth. like that again 😉) If not you can iterate twice and still throw out the supplier As soon as I find some time I'll look more closely at your commits! Thanks a lot for your hard work!! |
Okay, so it seems there is another issue with my current implementation of registering annotation dependencies to self. This time with annotations on fields and methods. I've tried to register annotations on members during registering fields, methods and constructors in void registerFields(Set<JavaField> fields) {
for (JavaField field : fields) {
fieldTypeDependencies.put(field.getRawType(), field);
registerMemberWithAnnotations(field);
}
} which is also faulty because I am accessing the supplier of annotations (eagerly) before all methods have been registered. Thus, the following tests are broken
for the same reason It seems that I also need to access all JavaMembers with annotations, but only after each classes members have been completed. |
Issue: #136 Signed-off-by: Alen Kosanović <alen.kosanovic@svgroup.hr>
…d JavaClass Issue: #136 Signed-off-by: Alen Kosanović <alen.kosanovic@svgroup.hr>
Issue: #136 Signed-off-by: Alen Kosanović <alen.kosanovic@svgroup.hr>
Issue: #136 Signed-off-by: Alen Kosanović <alen.kosanovic@svgroup.hr>
Issue: #136 Signed-off-by: Alen Kosanović <alen.kosanovic@svgroup.hr>
Issue: #136 Signed-off-by: Alen Kosanović <alen.kosanovic@svgroup.hr>
Issue: #136 Signed-off-by: Alen Kosanović <alen.kosanovic@svgroup.hr>
Issue: #136 Signed-off-by: Alen Kosanović <alen.kosanovic@svgroup.hr>
Issue: #136 Signed-off-by: Alen Kosanović <alen.kosanovic@svgroup.hr>
Issue: #136 Signed-off-by: Alen Kosanović <alen.kosanovic@svgroup.hr>
Issue: #136 Signed-off-by: Alen Kosanović <alen.kosanovic@svgroup.hr>
Issue: #136 Signed-off-by: Alen Kosanović <alen.kosanovic@svgroup.hr>
…ncies Issue: #136 Signed-off-by: Alen Kosanović <alen.kosanovic@svgroup.hr>
…ndency Issue: #136 Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
…constructor and method to make sure the behavior is the same for each type of member. Issue: #136 Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
Issue: #136 Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
Issue: #136 Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
…f an annotation should be the closest "parent" where the annotation is declared. Like a ThrowsDeclaration on a method having that method as owner, an annotation on a method should as well. Likewise, if an annotation is a parameter of another annotation, it should still have that annotation as "owner". That way it is possible to traverse the declaration tree up and do assertions based on the specific case. Unfortunately for the dependency use case, this is a little less convenient, since we're interested in the origin class of the dependency, which now must be determined by traversal, but still the implementation of HasOwner should not be adjusted to a specific need in one place. Issue: #136 Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
… should be irrelevant (can still be tested via custom condition, etc., but is not part of the Getter) Issue: #136 Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
…endencies of first order. I.e. we do not need to recursively find annotations on annotation parameter types or meta-annotations. This is consistent to all other dependencies, e.g. we do not depend on the super type of a return type of a method, since it is no "direct" dependency, but a transitive one. This also solves the problem of a recursive cycle, because we simply do not need to follow those paths. Issue: #136 Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
…ixed concerns already Issue: #136 Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
…es are possibly queried many times, we should only do the creation once (since JavaClass is immutable after construction) Issue: #136 Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
Since we now have a consistent approach to finding annotation dependencies, where we handle as well class as member owners, we do not need to distinguish anymore before. Issue: #136 Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
It is good to have an example illustrating dependencies by nested annotation parameters, and also good to have an integration test covering this complex scenario. Issue: #136 Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
Issue: #136 Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
By completing the annotations in a later step we can avoid the complexity of the annotations Supplier. Since we have to access this supplier anyway for the import process, there is no value in creating annotations lazily. Issue: #136 Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
Did some quick performance analysis and could not detect any difference between creating the additional Iterable via `Iterables.concat(..)` and executing three loops on Hibernate Core. This way it is quicker to see that all members are handled the same. Issue: #136 Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
Unfortunately we overlooked to include annotation parameters with enum types into dependencies from annotations. Now all cases should be covered though, because dependencies (besides from primitives or String) can only arise from types, enums or nested annotations and arrays of those. We might have to revisit this, if value types are added to Java. Issue: #136 Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
We can actually do a simple `instanceof Object[]` check, in case we have a primitive array, we'll just fall through and not add anything in the second branch (similar as strings and string arrays are ignored, even though we pass the first branch for `String[]`). Issue: #136 Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
For me this still doesn't work: @Override
@RequiresPermission(Permission.VIEW_COLUMN)
public List<FormulaDto> getFormulas() {
....
} with this rules: classes().should(not(new ArchCondition<JavaClass>("access @NoUse stuff") {
@Override
public void check(JavaClass item, ConditionEvents events) {
... item.getAllAccessesFromSelf() ...
}
})); and The other way around also does not work: noMembers().that().areAnnotatedWith(Permission.NoUse.class).should(new ArchCondition<JavaMember>("be accessed") {
@Override
public void check(JavaMember item, ConditionEvents events) {
... item.getAccessesToSelf() ...
}
}); when item is |
At the moment
JavaClass.getDirectDependenciesFromSelf()
andJavaClass.getDirectDependenciesToSelf()
don't consider annotations.Annotations (and their parameters) should be considered dependencies as well.
This includes
JavaClass
or anyJavaMember
of that classJavaClass
parameters of those annotationsJavaClass
parameters of annotations within those annotations (and transitively their annotations and so on)E.g.
Then
OnClass
,InAnnotation
,AnotherDependency
,InNestedAnnotation
,YetAnotherDependency
,OnField
,OnConstructor
andOnMethod
should all be returned as direct dependencies ofSomeClass
.The text was updated successfully, but these errors were encountered: