Changelog update - v0.3.0-beta.5 - #214
Open
github-actions[bot] wants to merge 19 commits into
Open
Conversation
…ity (Issue #42) Grammar (FeatureModel.bnf): - Add COMPONENT, LOGIC, OR_BLOCK, XOR_BLOCK, SUB_LOGIC grammar rules - feature children are now COMPONENT* (feature | LOGIC) enabling proper group scoping - Add QUESTIONMARK for optional feature syntax (?) - Restore getFullLPQText() in methods[] (required by FeatureModelUtil) Lexer (FeatureModel.flex): - Add OR/XOR/QUESTIONMARK token support via character-by-character state machine - Fix token definitions: OR="or", XOR="xor", QUESTIONMARK="?" - New lexer states: or1/or2, xor1/xor2/xor3, returnOr/returnXor etc. Generated PSI (src/main/gen): - New types: FeatureModelComponent, FeatureModelLogic, FeatureModelOrBlock, FeatureModelXorBlock, FeatureModelSubLogic (+ Impl classes) - Updated FeatureModelTypes: adds OR, XOR, QUESTIONMARK tokens + new element types - Updated FeatureModelFeature: replaces getFeatureList() with getComponentList(), restores getFullLPQText() Syntax highlighting: - FeatureModelHighlightingLexer.flex: adds OR/XOR/QUESTIONMARK token rules - FeatureModelSyntaxHighlighter: adds OR/XOR/QUESTIONMARK attribute keys (keyword style) - FeatureModelAnnotator: removes forced feature coloring so keywords get own color - HAnSDarcula.xml + HAnSDefault.xml: adds color entries for XOR_TOKEN/OR_TOKEN/OPTIONAL Existing functionality preserved: - PsiTreeUtil.collectElementsOfType still finds all FeatureModelFeature nodes - getFullLPQText(), getLPQText(), all metrics/referencing APIs unchanged - Plain feature hierarchy behavior unchanged Note: LPQ resolution for features inside OR/XOR groups is limited (parent-chain traversal in FeatureModelUtil only sees FeatureModelComponent, not FeatureModelFeature); follow-up work needed for full LPQ support in grouped features. Co-authored-by: Simon Osterheider <156541812+SimonOsterheider@users.noreply.github.com> Co-authored-by: Cindy Liang <lmxcin@protonmail.com> Co-authored-by: JoudiAlakkad <joudi.alakkad@outlook.com> Co-authored-by: DSaatz <126864831+DSaatz@users.noreply.github.com> Co-authored-by: ManhalJasem <96029523+ManhalJasem@users.noreply.github.com>
…ammar
The new XOR/OR grammar wraps every child feature in a COMPONENT node:
Old: childFeature.getParent() == parentFeature
New: childFeature.getParent() == FeatureModelComponent
childFeature.getParent().getParent() == parentFeature
This broke LPQ resolution, full LPQ lookup, rename, and add-feature
for ALL nested features (not just XOR/OR groups).
Fixes:
- FeatureModelPsiImplUtil.getParentFeature(): new helper that traverses
past COMPONENT/LOGIC/OR_BLOCK/XOR_BLOCK/SUB_LOGIC wrappers to find
the nearest FeatureModelFeature ancestor (null = file root)
- getFullLPQStack(): skip non-FeatureModelFeature nodes in parent walk
so COMPONENT wrapper nodes do not pollute the LPQ name stack
- findLPQRecursively(): replace feature.peek().getParent().getParent()
with getParentFeature() so disambiguation works for any nesting depth
regardless of intermediate wrapper nodes
- addFeatureToFeatureModel(): replace sibling-based indentation hack
(which NPE'd because feature.getPrevSibling() is null inside COMPONENT)
with column-based computation: feature column + 4, grammar-agnostic
- FeatureModelUtil.processSelectedFeatures(): replace
feature.getParent() instanceof FeatureModelFeature
with FeatureModelPsiImplUtil.getParentFeature(feature)
- Named groups (xor channel / or gateway): lexer already tokenizes these correctly; grammar XOR_BLOCK ::= XOR (SUB_LOGIC) handles inline name as first COMPONENT. No grammar change needed. - GrammarKit Gradle plugin (org.jetbrains.grammarkit 2023.3.2.2) added to build.gradle.kts and libs.versions.toml with generateParser/generateLexer tasks for all four grammars (FeatureModel, CodeAnnotation, FileAnnotation, FolderAnnotation) plus FeatureModelHighlightingLexer. compileJava depends on all generation tasks. - Parser/lexer tests: delete stale ParsingTestData.txt (COMPONENT wrappers now differ); add six new fixture files (PlainHierarchy, OrGroup, XorGroup, OptionalFeature, NamedXorGroup, KeywordPrefixedFeatures). On first run the framework auto-generates the .txt PSI dumps; second run is a passing check. - Highlighting tests: new cases for or/xor keyword coloring, '?' operation sign, keyword-prefix false positives (orange/xorfoo), and named-group shorthand (xor channel). - Qodana fixes (6 warnings): 1. Remove unused PsiTreeUtil import 2. Fix constant-value: prevSibling instanceof PsiFile -> getParent() instanceof PsiFile 3+4. Add instanceof guards before FeatureModelFeature casts in findLPQRecursively 5. Use explicit scope in ReferencesSearch.search() 6. ReferencesSearch with GlobalSearchScope.projectScope instead of implicit scope
- Add org.jetbrains.grammarkit 2023.3.0.3 to libs.versions.toml - Configure GenerateParserTask/GenerateLexerTask for all 4 grammars using new API: sourceFile, targetRootOutputDir, targetOutputDir - Update idea-flex.skeleton: remove zzAtBOL/zzEOFDone declarations (JFlex 1.9.2 generates them internally; duplicate fields caused 'variable already defined' compile errors when skeleton was applied) - Add import com.intellij.lexer.FlexLexer to FeatureModel.flex and FeatureModelHighlightingLexer.flex (IDE GrammarKit added this automatically; CLI task does not) - Declare metric methods in FeatureAnnotationNamedElement interface (getTanglingDegree, setScatteringDegree, etc.) so they are part of the interface contract rather than methods= in BNF - Remove metric methods from BNF methods= (they lack static delegates in FeatureModelPsiImplUtil; GrammarKit 2023.3.0.3 is strict about this) - Fix PsiElement→FeatureModelFeature parameter types in FeatureModelPsiImplUtil for getFullLPQText, getLPQText, getLPQStack, deleteFromFeatureModel, deleteFeature, deleteFeatureWithAnnotations, deleteFeatureWithCode (GrammarKit 2023.3.0.3 requires exact type match) - Generation tasks are NOT wired to compileJava/compileKotlin; run them explicitly when .bnf/.flex files change (CLI parser generator omits method stubs it can't resolve; PSI interface files in src/main/gen/ are authoritative/committed)
…fixtures - Update FeatureModel.bnf: OR_BLOCK/XOR_BLOCK now accept CRLF* between the keyword and SUB_LOGIC, so 'or' and 'xor' on their own line parse correctly (previously the newline caused PsiErrorElement) - Regenerate FeatureModelParser.java: OR_BLOCK_1/XOR_BLOCK_1 helpers consume zero or more CRLF tokens before SUB_LOGIC - Add PSI dump fixtures for all 7 parsing tests: PlainHierarchy, OrGroup, XorGroup, OptionalFeature, NamedXorGroup, KeywordPrefixedFeatures, ParsingTestData (generated by ParsingTestCase on first run; verified correct on second run) - Add .gradle-isolated/ to .gitignore (local workaround for JetBrains Toolbox corrupting Gradle transform cache during builds)
- Add goIntoFeaturenameN(n) helper to FeatureModel.flex — same as
goIntoFeaturename() but pushes back n characters instead of 1;
needed when the full token text spans multiple chars consumed
by intermediate state transitions
- Add rules in <indent> state for 'or{FEATURENAME}+' and
'xor{FEATURENAME}+': JFlex longest-match picks these over the
single-char 'o'/'x' rules, so 'orange' emits FEATURENAME('orange')
rather than the incorrect OR + FEATURENAME('ange')
- Regenerate FeatureModelLexer.java (DFA grows from 62→67→41 states)
- Update KeywordPrefixedFeatures.txt fixture to reflect correct behavior
(orange/xorfoo/ordinal are now full FEATURENAME tokens)
- Restore plugin.xml to main baseline: the original PR commit contained
incorrect implementationClass paths (missing featureAnnotation/
syntaxHighlighting sub-packages) that caused ClassNotFoundException
in the full test suite
PR #201 grammar change wraps feature children in COMPONENT/LOGIC/OR_BLOCK/XOR_BLOCK/SUB_LOGIC nodes. Several callers still assumed direct PSI parent/child relationships, causing: - Feature Model view collapsed to root (shallow getChildrenOfTypeAsList) - Metrics view empty (ClassCastException in getChildFeatures/getParentFeature) - IDE background-task pileup at startup (HansTrafficLightAction queued a GetFeatureFileMappings task on every update; broken casts blocked the cache from initializing, so each task redid the full scan) Add wrapper-safe FeatureModelPsiImplUtil.getChildFeatures(PsiElement) and route FeatureViewElement, ProjectMetricsService, FeatureReferenceUtil, and FeatureModelPsiImplUtil (addFeature, moveFeatureWithChildren) through it or through the existing getParentFeature helper. Add AtomicBoolean dedupe to HansTrafficLightAction so concurrent update() calls don't pile up. Also rewrite ProjectMetricsService.getRootFeatures using findFeatures + isRootFeature filter, removing a latent infinite-loop bug in the prior sibling-walk implementation. Bumps version to 0.3.0-beta.2.
GetFeatureFileMappings (traffic-light) and GetProjectMetrics (metrics tool window) both call FeatureLocationManager.getAllFeatureFileMappings on startup. The double-checked isFullyInitialized guard alone was not enough: both threads entered the guarded branch and ran calculateAllFeatureFileMappings in parallel, each spending minutes inside ReferencesSearch.search under tryRunReadActionInSmartMode. The resulting read-lock pressure starved the EDT write-intent permit and triggered the IDE freeze popup. Add a per-project Object lock and wrap the calculation in synchronized + double-checked isFullyInitialized. First caller computes, subsequent callers block briefly, then see the populated cache and return immediately. Bumps version to 0.3.0-beta.3.
FeatureModelUtil.getFeatureModelFiles used GlobalSearchScope.allScope, which also indexes feature-model fixtures under src/test/resources. When the plugin was loaded into the HAnS project itself the Metrics view and Feature Model view listed features from the parser-test fixtures. Switch to GlobalSearchScopesCore.projectProductionScope so only files under production source roots are picked up. Existing plugin tests use light test fixtures whose copied files land in the production source root of the synthetic test project, so they still find their fixtures. Bumps version to 0.3.0-beta.4.
beta.4 used GlobalSearchScopesCore.projectProductionScope, which only includes production source roots. A .feature-model file at the project root (the most common placement) falls outside any source root and was therefore dropped from the scan — Metrics view, Feature Model view, and reference resolution all came up empty even on a minimal project. Replace the scope with FeatureAnnotationSearchScope and extend its contains() to also exclude test source content. The scope still covers project content roots, so root-level feature models are picked up, while test fixtures under src/test/resources/ stay out. Bumps version to 0.3.0-beta.5.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Current pull request contains patched
CHANGELOG.mdfile for thev0.3.0-beta.5version.