From 97f7618bf697443883bbee23fcb14672e1da21be Mon Sep 17 00:00:00 2001 From: John Maxwell Date: Fri, 23 Aug 2024 09:48:47 -0700 Subject: [PATCH] Add DeletePhonology, fix LT-21870 (Import phonology crash) --- .../DomainServices/M3ModelExportServices.cs | 16 +- .../DomainServices/PhonologyServices.cs | 54 +++---- .../TestData/HomographDrops/Test.bak | 151 ++++++++++++++++++ .../DomainServices/PhonologyServicesTest.cs | 36 +++++ 4 files changed, 217 insertions(+), 40 deletions(-) create mode 100644 tests/SIL.LCModel.FixData.Tests/TestData/HomographDrops/Test.bak diff --git a/src/SIL.LCModel/DomainServices/M3ModelExportServices.cs b/src/SIL.LCModel/DomainServices/M3ModelExportServices.cs index 0ce09b8c..67f43d02 100644 --- a/src/SIL.LCModel/DomainServices/M3ModelExportServices.cs +++ b/src/SIL.LCModel/DomainServices/M3ModelExportServices.cs @@ -591,12 +591,16 @@ select ExportItemAsReference(constraint, constraints.IndexOf(constraint), "Featu new XAttribute("Id", rhs.Hvo), new XElement("StrucChange", from structChange in rhs.StrucChangeOS select ExportContext(structChange)), - new XElement("InputPOSes", from pos in rhs.InputPOSesRC - select ExportItemAsReference(pos, "RequiredPOS")), - new XElement("ReqRuleFeats", from rrf in rhs.ReqRuleFeatsRC - select ExportItemAsReference(rrf, "RuleFeat")), - new XElement("ExclRuleFeats", from erf in rhs.ExclRuleFeatsRC - select ExportItemAsReference(erf, "RuleFeat")), + // RuleFeats and POS are not part of the phonology. + phonology ? null + : new XElement("InputPOSes", from pos in rhs.InputPOSesRC + select ExportItemAsReference(pos, "RequiredPOS")), + phonology ? null + : new XElement("ReqRuleFeats", from rrf in rhs.ReqRuleFeatsRC + select ExportItemAsReference(rrf, "RuleFeat")), + phonology ? null + : new XElement("ExclRuleFeats", from erf in rhs.ExclRuleFeatsRC + select ExportItemAsReference(erf, "RuleFeat")), new XElement("LeftContext", ExportContext(rhs.LeftContextOA)), new XElement("RightContext", ExportContext(rhs.RightContextOA))))); break; diff --git a/src/SIL.LCModel/DomainServices/PhonologyServices.cs b/src/SIL.LCModel/DomainServices/PhonologyServices.cs index 6449cafa..a2a7a52b 100644 --- a/src/SIL.LCModel/DomainServices/PhonologyServices.cs +++ b/src/SIL.LCModel/DomainServices/PhonologyServices.cs @@ -11,6 +11,7 @@ using SIL.LCModel.Core.Text; using SIL.LCModel.Infrastructure.Impl; using static Icu.Normalization.Normalizer2; +using SIL.LCModel.Core.KernelInterfaces; namespace SIL.LCModel.DomainServices { @@ -74,42 +75,27 @@ public void ImportPhonologyFromXml(TextReader rdr) // () => AssignVernacularWritingSystemToDefaultPhPhonemes(Cache)); } - private void AssignVernacularWritingSystemToDefaultPhPhonemes(LcmCache cache) + /// + /// Clear PhonologicalData and Phonological Features. + /// Don't clear boundary markers. + /// + public void DeletePhonology() { - // For all PhCodes in the default phoneme set, change the writing system from "en" to icuLocale - if (cache.LanguageProject.PhonologicalDataOA.PhonemeSetsOS.Count == 0) - return; - var phSet = cache.LanguageProject.PhonologicalDataOA.PhonemeSetsOS[0]; - int wsVern = m_wsVernId == null - ? cache.DefaultVernWs - : cache.ServiceLocator.WritingSystemManager.Get(m_wsVernId).Handle; - foreach (var phone in phSet.PhonemesOC) - { - foreach (var code in phone.CodesOS) - { - - if (code.Representation.VernacularDefaultWritingSystem.Length == 0) - code.Representation.VernacularDefaultWritingSystem = - TsStringUtils.MakeString(code.Representation.UserDefaultWritingSystem.Text, wsVern); - } - if (phone.Name.VernacularDefaultWritingSystem.Length == 0) - phone.Name.VernacularDefaultWritingSystem = - TsStringUtils.MakeString(phone.Name.UserDefaultWritingSystem.Text, wsVern); - } - foreach (var mrkr in phSet.BoundaryMarkersOC) + NonUndoableUnitOfWorkHelper.Do(Cache.ServiceLocator.GetInstance(), () => { - foreach (var code in mrkr.CodesOS) - { - if (code.Representation.VernacularDefaultWritingSystem.Length == 0) - code.Representation.VernacularDefaultWritingSystem = - TsStringUtils.MakeString(code.Representation.UserDefaultWritingSystem.Text, wsVern); - } - if (mrkr.Name.VernacularDefaultWritingSystem.Length == 0) - mrkr.Name.VernacularDefaultWritingSystem = - TsStringUtils.MakeString(mrkr.Name.UserDefaultWritingSystem.Text, wsVern); - } + IPhPhonData phonData = Cache.LangProject.PhonologicalDataOA; + // Delete what is covered by ImportPhonology. + phonData.ContextsOS.Clear(); + phonData.EnvironmentsOS.Clear(); + phonData.FeatConstraintsOS.Clear(); + phonData.NaturalClassesOS.Clear(); + phonData.GetPhonemeSet().PhonemesOC.Clear(); + // Don't clear phonData.GetPhonemeSet().BoundaryMarkersOC! + // They have GUIDs known to the code. + phonData.PhonRulesOS.Clear(); + Cache.LanguageProject.PhFeatureSystemOA.TypesOC.Clear(); + Cache.LanguageProject.PhFeatureSystemOA.FeaturesOC.Clear(); + }); } - - } } diff --git a/tests/SIL.LCModel.FixData.Tests/TestData/HomographDrops/Test.bak b/tests/SIL.LCModel.FixData.Tests/TestData/HomographDrops/Test.bak new file mode 100644 index 00000000..8fb1c582 --- /dev/null +++ b/tests/SIL.LCModel.FixData.Tests/TestData/HomographDrops/Test.bak @@ -0,0 +1,151 @@ + + + + ++ + + + + + + + + + + + +
+riɔ +
+ + + + +
+ + +sfx + + + + + + +A suffix is an affix that is attached to the end of a root or stem. + + + + + + +suffix + + +- + + + + + + + + + + + + + + + + + +
+riɔ +
+ + + + +
+ + + + + + + + + + + +
+riɔ +
+ + + + +
+ + +MjeTyp + + + + + + + + + + + +Morpheme Types + + + + + + + + + + + + + + + + + + + +Dictionary + + + + +en ru enh-x-source en-x-ref en-x-geo enh + + +en ru enh-x-source en-x-ref en-x-geo enh + + +enh + + +enh enh-x-source + + + + +enh + + + + + +enh enh-x-source + + +
\ No newline at end of file diff --git a/tests/SIL.LCModel.Tests/DomainServices/PhonologyServicesTest.cs b/tests/SIL.LCModel.Tests/DomainServices/PhonologyServicesTest.cs index 21fad3f7..65d82b38 100644 --- a/tests/SIL.LCModel.Tests/DomainServices/PhonologyServicesTest.cs +++ b/tests/SIL.LCModel.Tests/DomainServices/PhonologyServicesTest.cs @@ -90,6 +90,24 @@ private void SetDefaultVernacularWritingSystem(LcmCache cache, CoreWritingSystem m_cache.ServiceLocator.WritingSystems.DefaultVernacularWritingSystem = vernWritingSystem); } + /// + /// Test all projects in a directory. + /// + /// + private void TestProjects(string directory) + { + foreach (string subDirectory in Directory.GetDirectories(directory, "*")) + { + foreach (string project in Directory.GetFiles(subDirectory, "*.fwdata")) + { + Console.WriteLine("Testing " + project); + CreateTestCache(); + TestProject(subDirectory, project); + DestroyTestCache(); + } + } + } + private void TestProject(string projectsDirectory, string dbFileName) { var projectId = new TestProjectId(BackendProviderType.kXML, dbFileName); @@ -98,6 +116,15 @@ private void TestProject(string projectsDirectory, string dbFileName) using (var cache = LcmCache.CreateCacheFromExistingData(projectId, "en", m_ui, m_lcmDirectories, new LcmSettings(), new DummyProgressDlg())) { + // Create PhonemeSet if necessary. + NonUndoableUnitOfWorkHelper.Do(m_cache.ActionHandlerAccessor, () => + { + if (m_cache.LangProject.PhonologicalDataOA.PhonemeSetsOS.Count == 0) + { + var phonemeset = m_cache.ServiceLocator.GetInstance().Create(); + m_cache.LangProject.PhonologicalDataOA.PhonemeSetsOS.Add(phonemeset); + } + }); // Export project as XML. var services = new PhonologyServices(cache); XDocument xdoc = services.ExportPhonologyAsXml(); @@ -109,6 +136,7 @@ private void TestProject(string projectsDirectory, string dbFileName) var vernWs = cache.ServiceLocator.WritingSystemManager.Get(cache.DefaultVernWs); SetDefaultVernacularWritingSystem(m_cache, vernWs); var services2 = new PhonologyServices(m_cache, vernWs.Id); + services2.DeletePhonology(); services2.ImportPhonologyFromXml(rdr); xdoc2 = services2.ExportPhonologyAsXml(); } @@ -134,6 +162,7 @@ private void TestXml(string xml, string vernWs) ILcmOwningSequence phonemeList = m_cache.LangProject.PhonologicalDataOA.PhonemeSetsOS; IPhPhonemeSet phonemeSet = m_cache.LangProject.PhonologicalDataOA.GetPhonemeSet(); var services = new PhonologyServices(m_cache); + services.DeletePhonology(); using (var rdr = new StringReader(xml)) { services.ImportPhonologyFromXml(rdr); @@ -156,6 +185,7 @@ private void TestXml(string xml, string vernWs) } Assert.IsTrue(hasMorphBdry); Assert.IsTrue(hasWordBdry); + Assert.IsTrue(m_cache.LangProject.PhonologicalDataOA.GetPhonemeSet().BoundaryMarkersOC.Count == 2); } private void TestXml(XDocument xdoc, XDocument xdoc2) @@ -1211,5 +1241,11 @@ public void TestPhonologicalFeatures() TestXml(xdoc, xdoc2); } } + + // [Test] + public void TestPCProjects() + { + TestProjects("C:\\Users\\PC\\source\\repos\\FieldWorks\\DistFiles\\Projects"); + } } }