This fixes #2415 by checking for exact equality of the type before shortcutting an unnessary projection.
54 lines
1.8 KiB
Plaintext
54 lines
1.8 KiB
Plaintext
[[api:Default]]
|
|
[role=group,includesConstraints="api:*"]
|
|
|
|
=== General considerations
|
|
|
|
We use https://github.com/apiguardian-team/apiguardian[@API Guardian] to keep track of what we expose as public or internal API.
|
|
To keep things both clear and concise, we restrict the usage of those annotations to interfaces, classes (incl. constructors)
|
|
and annotations.
|
|
|
|
[[api:api-guardian-usage]]
|
|
[source,cypher,role="constraint"]
|
|
.@API Guardian annotations must not be used on fields
|
|
----
|
|
MATCH (c:Java)-[:ANNOTATED_BY]->(a)-[:OF_TYPE]->(t:Type {fqn: 'org.apiguardian.api.API'}),
|
|
(p)-[:DECLARES]->(c)
|
|
WHERE c:Member AND NOT (c:Constructor OR c:Method)
|
|
RETURN p.fqn, c.name
|
|
----
|
|
|
|
Public interfaces, classes or annotations are either part of internal or public API and have a status.
|
|
|
|
[[api:api-guardian-api-concept]]
|
|
[source,cypher,role="concept",verify=rowCount,rowCountMin=0]
|
|
.Define which Java artifacts are part of internal or public API
|
|
----
|
|
MATCH (c:Java)-[:ANNOTATED_BY]->(a)-[:OF_TYPE]->(t:Type {fqn: 'org.apiguardian.api.API'}),
|
|
(a)-[:HAS]->({name: 'status'})-[:IS]->(s)
|
|
WHERE ANY (label IN labels(c) WHERE label in ['Interface', 'Class', 'Annotation'])
|
|
WITH c, trim(split(s.signature, ' ')[1]) AS status
|
|
WITH c, status,
|
|
CASE status
|
|
WHEN 'INTERNAL' THEN 'Internal'
|
|
ELSE 'Public'
|
|
END AS type
|
|
MERGE (a:Api {type: type, status: status})
|
|
MERGE (c)-[:IS_PART_OF]->(a)
|
|
RETURN c,a
|
|
----
|
|
|
|
=== Internal API
|
|
|
|
See ADR-003.
|
|
|
|
[[api:internal]]
|
|
[source,cypher,role="constraint",requiresConcepts="api:api-guardian-api-concept"]
|
|
.Non abstract, public classes that are only part of internal API must be final
|
|
----
|
|
MATCH (c:Class)-[:IS_PART_OF]->(:Api {type: 'Internal'})
|
|
WHERE c.visibility = 'public'
|
|
AND coalesce(c.abstract, false) = false
|
|
AND NOT exists(c.final)
|
|
RETURN c.name
|
|
----
|