Skip to content

Commit

Permalink
Add DeletePhonology, fix LT-21870 (Import phonology crash)
Browse files Browse the repository at this point in the history
  • Loading branch information
jtmaxwell3 committed Aug 23, 2024
1 parent e5c4839 commit 97f7618
Show file tree
Hide file tree
Showing 4 changed files with 217 additions and 40 deletions.
16 changes: 10 additions & 6 deletions src/SIL.LCModel/DomainServices/M3ModelExportServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
54 changes: 20 additions & 34 deletions src/SIL.LCModel/DomainServices/PhonologyServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -74,42 +75,27 @@ public void ImportPhonologyFromXml(TextReader rdr)
// () => AssignVernacularWritingSystemToDefaultPhPhonemes(Cache));
}

private void AssignVernacularWritingSystemToDefaultPhPhonemes(LcmCache cache)
/// <summary>
/// Clear PhonologicalData and Phonological Features.
/// Don't clear boundary markers.
/// </summary>
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<IActionHandler>(), () =>
{
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();
});
}


}
}
151 changes: 151 additions & 0 deletions tests/SIL.LCModel.FixData.Tests/TestData/HomographDrops/Test.bak
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<?xml version="1.0" encoding="utf-8"?>
<languageproject version="7000051">
<rt class="LexEntry" guid="5c7a2684-97dc-4cac-8b31-4e0db5855b27">
<CitationForm>
<AUni ws="enh-x-source">+</AUni>
</CitationForm>
<DateCreated val="2024-02-12 12:57:59.009" />
<DateModified val="2024-03-14 15:59:21.262" />
<DoNotUseForParsing val="False" />
<HomographNumber val="3" />
<LexemeForm>
<objsur guid="76510343-5ba9-4455-bf15-4edd6bcf8fdc" t="o" />
</LexemeForm>
<MorphoSyntaxAnalyses />
</rt>
<rt class="MoAffixAllomorph" guid="76510343-5ba9-4455-bf15-4edd6bcf8fdc" ownerguid="5c7a2684-97dc-4cac-8b31-4e0db5855b27">
<Form>
<AUni ws="enh">riɔ</AUni>
</Form>
<IsAbstract val="False" />
<MorphType>
<objsur guid="d7f713dd-e8cf-11d3-9764-00c04f186933" t="r" />
</MorphType>
</rt>
<rt class="MoMorphType" guid="d7f713dd-e8cf-11d3-9764-00c04f186933" ownerguid="d7f713d8-e8cf-11d3-9764-00c04f186933">
<Abbreviation>
<AUni ws="en">sfx</AUni>
</Abbreviation>
<BackColor val="0" />
<DateCreated val="2021-03-16 21:26:31.760" />
<DateModified val="2021-03-16 21:26:31.760" />
<Description>
<AStr ws="en">
<Run ws="en">A suffix is an affix that is attached to the end of a root or stem.</Run>
</AStr>
</Description>
<ForeColor val="0" />
<Hidden val="False" />
<IsProtected val="True" />
<Name>
<AUni ws="en">suffix</AUni>
</Name>
<Prefix>
<Uni>-</Uni>
</Prefix>
<SecondaryOrder val="70" />
<SortSpec val="0" />
<UnderColor val="0" />
<UnderStyle val="0" />
</rt>
<rt class="LexEntry" guid="74ce3bd5-455b-48ca-986f-e325f8cf96d5">
<DateCreated val="2124-03-12 16:20:00.000" />
<DateModified val="2024-03-13 17:15:53.695" />
<DoNotUseForParsing val="False" />
<HomographNumber val="2" />
<LexemeForm>
<objsur guid="ead4f61a-2bb8-4413-8102-bc936f916988" t="o" />
</LexemeForm>
<MorphoSyntaxAnalyses />
</rt>
<rt class="MoAffixAllomorph" guid="ead4f61a-2bb8-4413-8102-bc936f916988" ownerguid="74ce3bd5-455b-48ca-986f-e325f8cf96d5">
<Form>
<AUni ws="enh">riɔ</AUni>
</Form>
<IsAbstract val="False" />
<MorphType>
<objsur guid="d7f713dd-e8cf-11d3-9764-00c04f186933" t="r" />
</MorphType>
</rt>
<rt class="LexEntry" guid="7dcf9363-29e6-47fb-aa1e-eb8dd1f7afe5">
<DateCreated val="2124-03-12 16:20:00.000" />
<DateModified val="2024-03-13 17:15:53.695" />
<DoNotUseForParsing val="False" />
<HomographNumber val="1" />
<LexemeForm>
<objsur guid="64dcc662-315f-49ef-a339-64a0ef7c8c42" t="o" />
</LexemeForm>
<MorphoSyntaxAnalyses />
</rt>
<rt class="MoAffixAllomorph" guid="64dcc662-315f-49ef-a339-64a0ef7c8c42" ownerguid="7dcf9363-29e6-47fb-aa1e-eb8dd1f7afe5">
<Form>
<AUni ws="enh">riɔ</AUni>
</Form>
<IsAbstract val="False" />
<MorphType>
<objsur guid="d7f713dd-e8cf-11d3-9764-00c04f186933" t="r" />
</MorphType>
</rt>
<rt class="CmPossibilityList" guid="d7f713d8-e8cf-11d3-9764-00c04f186933" ownerguid="af26d792-ea5e-11de-8f7e-0013722f8dec">
<Abbreviation>
<AUni ws="en">MjeTyp</AUni>
</Abbreviation>
<DateCreated val="2018-08-02 16:32:06.267" />
<DateModified val="2018-08-02 16:32:06.267" />
<Depth val="1" />
<DisplayOption val="0" />
<IsClosed val="True" />
<IsSorted val="True" />
<IsVernacular val="False" />
<ItemClsid val="5042" />
<ListVersion val="00000000-0000-0000-0000-000000000000" />
<Name>
<AUni ws="en">Morpheme Types</AUni>
</Name>
<Possibilities>
<objsur guid="d7f713dd-e8cf-11d3-9764-00c04f186933" t="o" />
</Possibilities>
<PreventChoiceAboveLevel val="0" />
<PreventDuplicates val="False" />
<PreventNodeChoices val="False" />
<UseExtendedFields val="False" />
<WsSelector val="-3" />
</rt>
<rt class="LexDb" guid="af26d792-ea5e-11de-8f7e-0013722f8dec" ownerguid="5c937611-0e49-491b-ad5e-b61dd01a45d4">
<DateCreated val="2021-03-16 21:26:29.875" />
<DateModified val="2021-03-16 21:26:29.875" />
<IsBodyInSeparateSubentry val="False" />
<IsHeadwordCitationForm val="False" />
<MorphTypes>
<objsur guid="d7f713d8-e8cf-11d3-9764-00c04f186933" t="o" />
</MorphTypes>
<Name>
<AUni ws="en">Dictionary</AUni>
</Name>
</rt>
<rt class="LangProject" guid="5c937611-0e49-491b-ad5e-b61dd01a45d4">
<AnalysisWss>
<Uni>en ru enh-x-source en-x-ref en-x-geo enh</Uni>
</AnalysisWss>
<CurAnalysisWss>
<Uni>en ru enh-x-source en-x-ref en-x-geo enh</Uni>
</CurAnalysisWss>
<CurPronunWss>
<Uni>enh</Uni>
</CurPronunWss>
<CurVernWss>
<Uni>enh enh-x-source</Uni>
</CurVernWss>
<DateCreated val="2021-03-16 21:26:31.627" />
<DateModified val="2024-03-14 17:37:44.271" />
<HomographWs>
<Uni>enh</Uni>
</HomographWs>
<LexDb>
<objsur guid="af26d792-ea5e-11de-8f7e-0013722f8dec" t="o" />
</LexDb>
<VernWss>
<Uni>enh enh-x-source</Uni>
</VernWss>
</rt>
</languageproject>
36 changes: 36 additions & 0 deletions tests/SIL.LCModel.Tests/DomainServices/PhonologyServicesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,24 @@ private void SetDefaultVernacularWritingSystem(LcmCache cache, CoreWritingSystem
m_cache.ServiceLocator.WritingSystems.DefaultVernacularWritingSystem = vernWritingSystem);
}

/// <summary>
/// Test all projects in a directory.
/// </summary>
/// <param name="directory"></param>
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);
Expand All @@ -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<IPhPhonemeSetFactory>().Create();
m_cache.LangProject.PhonologicalDataOA.PhonemeSetsOS.Add(phonemeset);
}
});
// Export project as XML.
var services = new PhonologyServices(cache);
XDocument xdoc = services.ExportPhonologyAsXml();
Expand All @@ -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();
}
Expand All @@ -134,6 +162,7 @@ private void TestXml(string xml, string vernWs)
ILcmOwningSequence<IPhPhonemeSet> 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);
Expand All @@ -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)
Expand Down Expand Up @@ -1211,5 +1241,11 @@ public void TestPhonologicalFeatures()
TestXml(xdoc, xdoc2);
}
}

// [Test]
public void TestPCProjects()
{
TestProjects("C:\\Users\\PC\\source\\repos\\FieldWorks\\DistFiles\\Projects");
}
}
}

0 comments on commit 97f7618

Please sign in to comment.