-
-
Notifications
You must be signed in to change notification settings - Fork 15
Annotation Processing Flow
type: flow title: Annotation Processing Flow created: 2026-05-25 updated: 2026-05-25 tags:
- domain/annotation
- domain/flow status: mature related:
- "Annotation Syntax"
- "Feature Model Language"
- "Extension Points"
- "Code Annotation Module"
- "Feature Location Module" sources:
- .raw/plugin.xml
- .raw/CodeAnnotationInjector.java
- .raw/FeatureLocationManager.java
- .raw/GetProjectMetrics.java
- .raw/GetFeatureMetricsForFeature.java
How HAnS processes &begin/&end/&line annotations in arbitrary source files.
- Developer writes
// &begin[Feature]in any source file (Java, Kotlin, XML, etc.). -
CodeAnnotationInjector(MultiHostInjector) is invoked for everyPsiComment. - Filter: skip
PsiDocCommentBase; skip if text does not match.*(&begin|&line|&end).*. - Injector strips comment delimiters (e.g. removes
//) to produce a cleanTextRange. -
registrar.startInjecting(CodeAnnotationLanguage.INSTANCE)— registers the injection. - IntelliJ PSI now contains a
CodeAnnotationslanguage fragment at that location. -
FeatureReferenceContributorresolves the feature name to the.feature-modeldefinition, enabling navigation, find usages, rename, and completion.
[!key-insight] Metrics are NOT triggered by a
DocumentListenerorPsiTreeChangeListenerdirectly on the source file. Instead, background tasks are explicitly enqueued by callers (e.g. UI actions, tool window open).ProjectMetricsService.getProjectMetricsBackground(callback)wrapsGetProjectMetrics(...).queue().
The background task lifecycle:
-
GetProjectMetrics.run(indicator)callsFeatureLocationManager.getAllFeatureFileMappings(project). -
FeatureLocationManagerusesReferencesSearch.search()— scoped toFeatureAnnotationSearchScope— to find all PSI references to eachFeatureModelFeature. - Search runs inside
DumbService.tryRunReadActionInSmartMode()to avoidIndexNotReadyExceptionduring indexing. - References are classified by containing file type:
CodeAnnotationFile,FileAnnotationFile,FolderAnnotationFile.
- Caller enqueues
GetProjectMetrics(orGetFeatureMetricsForFeaturefor single-feature) viaProjectMetricsService. - Task calls
FeatureLocationManager.getAllFeatureFileMappings()→ buildsMap<String, FeatureFileMapping>. -
FeatureTangling.getTanglingMap()→Map<FeatureModelFeature, HashSet<FeatureModelFeature>>. -
NestingDepths.getNestingDepthMap()→Map<String, List<Pair<String, Integer>>>. - Per-feature:
FeatureScattering.getScatteringDegree(), line count fromFeatureFileMapping, nesting stats. - Results written to mutable fields on each
FeatureModelFeaturePSI element. -
ProjectMetricssnapshot constructed. -
onSuccess()→callback.onComplete(ProjectMetrics).
Within FeatureLocationManager.calculateFeatureFileMapping():
- Inject-host detection: if
InjectedLanguageManager.getInjectionHost(element)returns aPsiComment, use it; otherwise walk up withPsiTreeUtil.getContextOfType(element, PsiComment.class). - Marker type resolved from PSI parent:
element.getParent().getParent()→ checked againstCodeAnnotationBeginmarker/CodeAnnotationEndmarker/CodeAnnotationLinemarker. - Line numbers via
PsiDocumentManager.getDocument(file).getLineNumber(element.getTextRange().getStartOffset()).
FeatureAnnotationScopeEnlarger ensures find-usages searches include annotation files outside the default project source roots (e.g. .feature-to-file, .feature-to-folder files).
- Code Annotation Module — injection details
-
Feature Location Module —
FeatureLocationManager,FeatureFileMapping - Metrics Module — calculators
-
Plugin Extensions Module —
ProjectMetricsService, background tasks - Extension Points
- Feature Metrics View
Modules
Components
- Annotation Syntax
- Feature Model Language
- Feature Model View
- Feature Metrics View
- Traffic Light
- Extension Points
- Syntax Highlighting
- Live Templates
Decisions
Dependencies
Flows