Skip to content

LT-22822: Don't display autogenerated Natural Classes - #1198

Open
aror92 wants to merge 5 commits into
mainfrom
LT-22822-dont-display-autogen-NCs
Open

aror92 wants to merge 5 commits into
mainfrom
LT-22822-dont-display-autogen-NCs

Conversation

@aror92

@aror92 aror92 commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor
  • Fix IsFeatureBasedNCUserDefined logic

    • Update logic to consider NCs with no name user-defined
      instead of auto-generated. Auto-generated feature-based
      natural classes are always assigned a non-empty name.
  • Exclude auto-generated feature-based NCs from the NCs record list.

    • Create a RecordList subclass ("NaturalClassRecordList")
      which excludes auto-generated NCs, and use it to dynamically
      load the NC list in areaConfiguration.xml.
  • Hide auto-generated feature-based NCs from the phonological rule NC
    choosers, so they can't be assigned to other APRs or phonological rules.

    • Update AffixRuleFormulaControl.SetMappingNaturalClass and the
      NaturalClass case of RuleFormulaControl.m_insertionControl_Insert
      to show only NCs that are not auto-generated.

Note: auto-generated feature-based NCs still appear in environments.
After we have made a model change to add a flag to NCs to identify
auto-generated vs user-defined, we will be able to hide auto-generated
NCs in environment choosers as well.


This change is Reviewable

aror92 and others added 4 commits October 14, 2026 13:59
Feature-based natural classes with no name are user-defined,
since auto-generated natural classes are always assigned
a non-empty name.
* Hide auto-generated feature-based NCs from displaying in NCs list.
  * Create a RecordFilter subclass ("ExcludeAutoGeneratedNaturalClassFilter")
  to filter out auto-gen NCs, and use it to filter the NC list in
  areaConfiguration.xml.

* Hide auto-generated feature-based NCs from the phonological rule NC
choosers, so they can't be assigned to other APRs or phonological rules.
  * Update AffixRuleFormulaControl.SetMappingNaturalClass and the
  NaturalClass case of RuleFormulaControl.m_insertionControl_Insert
  to show only NCs that are not auto-generated.
Cover ExcludeAutoGeneratedNaturalClassFilter: it rejects auto-generated
classes, passes named, unnamed and segment-based classes, and still
works when it receives its cache only through the Cache setter, as a
filter restored from persisted settings does.

Move the name matching out of IsFeatureBasedNCUserDefined into an
internal IsAutoGeneratedName(ncName, format) helper, so it can be
tested against format strings other than the English one. The
behavior of IsFeatureBasedNCUserDefined is unchanged.

Add tests that a null class is not auto-generated, that a format
starting with the rule name recognizes generated names without
matching ordinary ones, and that a format with no rule name
placeholder recognizes nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Comment hygiene (advisory)

No comment-style violations in the lines this branch adds since origin/main.

@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

NUnit Tests

    1 files  ± 0      1 suites  ±0   11m 23s ⏱️ - 1m 50s
6 823 tests +71  6 738 ✅ +71  85 💤 ±0  0 ❌ ±0 
6 832 runs  +71  6 747 ✅ +71  85 💤 ±0  0 ❌ ±0 

Results for commit cf36e63. ± Comparison against base commit 30e4078.

This pull request removes 24 and adds 95 tests. Note that renamed tests count towards both.
LexTextDllTests.AiAnalysisExportListenerTests ‑ Export_UnloadableGrammar_ThrowsAndWritesNothing
LexTextDllTests.AiAnalysisExportListenerTests ‑ Export_WritesTheGrammarAndMarksTheRequestHandled
LexTextDllTests.GrammarExportLoadLoggerTests ‑ InvalidPhoneme_AddsAMessage_DoesNotThrow
LexTextDllTests.GrammarExportLoadLoggerTests ‑ InvalidStrata_AddsTheReasonToTheMessage
SIL.FieldWorks.Common.FwUtils.AiAnalysisExportRequestTests ‑ Constructor_SetsTextsFolderAndGrammarPath_LeavesHandledFalseAndMessagesEmpty
SIL.FieldWorks.Common.FwUtils.AiAnalysisExportRequestTests ‑ Messages_CanBeAppendedByASubscriber
SIL.FieldWorks.IText.FlexTextExporterTests ‑ ExportTexts_OnAThreadPoolThread_WritesTheFileWithoutThrowing
SIL.FieldWorks.IText.FlexTextExporterTests ‑ ExportTexts_OneText_WritesOneFlexTextFile
SIL.FieldWorks.IText.FlexTextExporterTests ‑ ExportTexts_TextNamedLikeTheGrammarFile_DoesNotOverwriteIt
SIL.FieldWorks.XWorks.ExportDialogAiGateTests ‑ IsAiExportTemplate_FalseForEveryOtherTemplate("<somethingElse />")
…
LexEdDllTests.MotifApplyConfigurationTests ‑ MainDefinesTheGlobalToolsCommandAndItsListener
LexEdDllTests.MotifApplyConfigurationTests ‑ OnlyTheMotifListenerHandlesTheMotifCommand
LexEdDllTests.MotifApplyWorkflowTests ‑ ExecuteCommitsEditsAndUnlocksBeforeOneMotifInvocation
LexEdDllTests.MotifApplyWorkflowTests ‑ ExecuteSelectsMessageForEachOutcome(Ambiguous,8,"",True,9,True,True)
LexEdDllTests.MotifApplyWorkflowTests ‑ ExecuteSelectsMessageForEachOutcome(Applied,0,"{\"ok\":true,\"applied\":true}",True,1,True,True)
LexEdDllTests.MotifApplyWorkflowTests ‑ ExecuteSelectsMessageForEachOutcome(Busy,3,"",False,5,True,True)
LexEdDllTests.MotifApplyWorkflowTests ‑ ExecuteSelectsMessageForEachOutcome(CouldNotStart,-1,"",False,8,False,True)
LexEdDllTests.MotifApplyWorkflowTests ‑ ExecuteSelectsMessageForEachOutcome(NoChanges,0,"{\"ok\":true,\"applied\":false}",False,3,True,True)
LexEdDllTests.MotifApplyWorkflowTests ‑ ExecuteSelectsMessageForEachOutcome(NotInstalled,0,"",False,7,True,False)
LexEdDllTests.MotifApplyWorkflowTests ‑ ExecuteSelectsMessageForEachOutcome(ReconciliationRequired,4,"",True,9,True,True)
…

♻️ This comment has been updated with latest results.

@codecov-commenter

codecov-commenter commented Oct 21, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 64.70588% with 12 lines in your changes missing coverage. Please review.
✅ Project coverage is 39.88%. Comparing base (30e4078) to head (cf36e63).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
Src/LexText/Morphology/NaturalClassRecordList.cs 62.50% 3 Missing ⚠️
Src/LexText/Morphology/RuleFormulaControl.cs 82.35% 2 Missing and 1 partial ⚠️
Src/LexText/Morphology/RuleFormulaSlice.cs 0.00% 2 Missing and 1 partial ⚠️
Src/LexText/Morphology/AffixRuleFormulaSlice.cs 0.00% 1 Missing and 1 partial ⚠️
Src/LexText/Morphology/AffixRuleFormulaControl.cs 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1198      +/-   ##
==========================================
+ Coverage   39.82%   39.88%   +0.06%     
==========================================
  Files        1544     1543       -1     
  Lines      355187   355384     +197     
  Branches    41277    41325      +48     
==========================================
+ Hits       141451   141752     +301     
+ Misses     184386   184274     -112     
- Partials    29350    29358       +8     
Files with missing lines Coverage Δ
Src/LexText/Morphology/RuleFormulaVcBase.cs 60.51% <100.00%> (ø)
Src/LexText/Morphology/AffixRuleFormulaControl.cs 0.00% <0.00%> (ø)
Src/LexText/Morphology/AffixRuleFormulaSlice.cs 0.00% <0.00%> (ø)
Src/LexText/Morphology/NaturalClassRecordList.cs 62.50% <62.50%> (ø)
Src/LexText/Morphology/RuleFormulaControl.cs 2.95% <82.35%> (+1.60%) ⬆️
Src/LexText/Morphology/RuleFormulaSlice.cs 0.00% <0.00%> (ø)

... and 22 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@aror92

aror92 commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor Author

Unaddressed bugs mentioned by Devin:

  1. Language changes reveal generated classes
    After a UI language change, IsFeatureBasedNCUserDefined compares stored generated names against the new translation. Previously generated classes become selectable and lose their feature-editing action.

This is a known possible but rare edge-case issue that can't currently be handled. After we make a model change to add a flag to NCs to track whether they were generated and do away with the naming-based detection method, this issue will go away.

  1. Unnamed classes lose formula feature editing
    For an unnamed feature class, IsFeatureBasedNCUserDefined now returns true. OnDisplayContextSetFeatures hides its feature-editing command, which was previously available.

This is intentional and is actually fixing what was a bug in the code. An unnamed feature class is user defined, not auto-generated, so its feature-editing command should not be visible.

@aror92
aror92 marked this pull request as ready for review October 21, 2026 14:08
@aror92
aror92 marked this pull request as draft October 21, 2026 14:24
If we use a default hidden filter to hide auto-generated NCs, there are a
couple of code paths that will circumvent the filter and cause autogen NCs
to re-display in the NCs list. Instead, we remove them at the source--using
a dynamic loader for the NC record list.

Update tests to match new behavior.

For clarity, rename test helper method from AddRuleNamedFeatureNaturalClass
to AddAutoGeneratedFeatureNaturalClass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@aror92
aror92 marked this pull request as ready for review October 21, 2026 17:31
{
protected override IEnumerable<int> GetObjectSet()
{
return ExcludeAutoGenerated(base.GetObjectSet(), m_cache);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once a rule stops using one of its auto-generated classes, I can't find a way for the user to delete it now. Nothing deletes the class when the context is removed from the rule, when the rule itself is deleted, or when Set Mapping Features clears an affix mapping back to a copy (AffixRuleFormulaControl.SetMappingFeatures removes the mapping and leaves its class in NaturalClassesOS). Until now the user could find these leftovers in Grammar > Natural Classes and delete them; this list now hides them. They still show in the environment natural-class chooser, so the user will see "Created automatically for rule …" entries there that they can't remove.

Should a class be deleted when its rule stops using it? Or should the list still show the leftovers?

/// True for feature-based natural classes generated automatically for a rule.
/// Phoneme-based classes are never auto-generated.
/// </summary>
public static bool IsAutoGeneratedNaturalClass(IPhNaturalClass nc)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This decides from the name alone, so an auto-generated class the user has taken over is hidden too. Two cases already have tests:

  • the user gave it an abbreviation (RuleNamedClass_AbbreviatedC_DrawsFeature), so environments can use it as [C];
  • the user added text in front of the generated name (ClassNamedForARuleBehindAPrefix_IsNotUserDefined).

In both cases the class now drops out of the Natural Classes list and the rule choosers, while environments and other rules may still use it. The user can no longer find it to edit it. Is that intended?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants