Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 120 additions & 0 deletions src/SIL.LCModel/DomainImpl/OverridesLing_MoClasses.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4066,6 +4066,126 @@ public override void PostClone(Dictionary<int, ICmObject> copyMap)
clonedProcess.OutputOS.RemoveAt(0);
}
}
/// <summary>
/// Gets all of the feature constraints in this rule.
/// </summary>
/// <value>The feature constraints.</value>
[VirtualProperty(CellarPropertyType.ReferenceCollection, "PhFeatureConstraint")]
public IEnumerable<IPhFeatureConstraint> FeatureConstraints
{
get
{
return GetFeatureConstraints();
}
}

/// <summary>
/// Gets all of the feature constraints in this rule.
/// </summary>
/// <returns>The feature constraints.</returns>
public List<IPhFeatureConstraint> GetFeatureConstraints()
{
var featureConstrs = new List<IPhFeatureConstraint>();
CollectVars(InputOS, featureConstrs);
var contents = new List<IPhContextOrVar>();
foreach (var ruleMapping in OutputOS)
{
switch (ruleMapping.ClassID)
{
case MoCopyFromInputTags.kClassId:
var copyInput = ruleMapping as IMoCopyFromInput;
if (copyInput != null && copyInput.ContentRA != null)
{
contents.Add(copyInput.ContentRA);
}
break;
case MoModifyFromInputTags.kClassId:
var modInput = ruleMapping as IMoModifyFromInput;
if (modInput != null && modInput.ContentRA != null)
{
contents.Add(modInput.ContentRA);
}
break;
}
}
CollectVars(contents, featureConstrs);
return featureConstrs;
}

/// <summary>
/// Collects all of the alpha variables in the specified sequence of contexts.
/// </summary>
/// <param name="seq">The sequence.</param>
/// <param name="featureConstrs">The feature constraints.</param>
void CollectVars(IEnumerable<IPhContextOrVar> seq, List<IPhFeatureConstraint> featureConstrs)
{
foreach (var ctxt in seq)
{
if (ctxt.ClassID == PhSequenceContextTags.kClassId)
{
IPhSequenceContext psc = ctxt as IPhSequenceContext;
if (psc == null)
continue;
foreach (var memb in psc.MembersRS)
{
if (memb.ClassID == PhSimpleContextNCTags.kClassId)
{
var ncMemb = memb as IPhSimpleContextNC;
CollectVars(ncMemb, featureConstrs);
}
}
}
else if (ctxt.ClassID == PhSimpleContextNCTags.kClassId)
{
var ncCtxt = ctxt as IPhSimpleContextNC;
CollectVars(ncCtxt, featureConstrs);
}
}
}
/// <summary>
/// Collects all of the alpha variables in the specified sequence of contexts.
/// </summary>
/// <param name="ctxt">The context.</param>
/// <param name="featureConstrs">The feature indices.</param>
void CollectVars(IPhPhonContext ctxt, List<IPhFeatureConstraint> featureConstrs)
{
if (ctxt == null)
return;

switch (ctxt.ClassID)
{
case PhSequenceContextTags.kClassId:
var seqCtxt = (IPhSequenceContext)ctxt;
foreach (var cur in seqCtxt.MembersRS)
CollectVars(cur as IPhSimpleContextNC, featureConstrs);
break;

case PhIterationContextTags.kClassId:
var iterCtxt = (IPhIterationContext)ctxt;
CollectVars(iterCtxt.MemberRA, featureConstrs);
break;

case PhSimpleContextNCTags.kClassId:
var ncCtxt = (IPhSimpleContextNC)ctxt;
CollectVars(ncCtxt.PlusConstrRS, featureConstrs);
CollectVars(ncCtxt.MinusConstrRS, featureConstrs);
break;
}
}

/// <summary>
/// Collects all of the alpha variables in the specified sequence.
/// </summary>
/// <param name="vars">The sequence of variables.</param>
/// <param name="featureConstrs">The feature constraints.</param>
void CollectVars(IEnumerable<IPhFeatureConstraint> vars, List<IPhFeatureConstraint> featureConstrs)
{
foreach (var var in vars)
{
if (!featureConstrs.Contains(var))
featureConstrs.Add(var);
}
}
}

internal partial class MoMorphData
Expand Down
18 changes: 18 additions & 0 deletions src/SIL.LCModel/InterfaceAdditions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2107,6 +2107,24 @@ public partial interface IMoInflAffixSlot : ICloneableCmObject
IEnumerable<ILexEntry> OtherInflectionalAffixLexEntries { get; }
}

public partial interface IMoAffixProcess
{
/// <summary>
/// Gets all of the feature constraints in this rule.
/// </summary>
/// <value>The feature constraints.</value>
IEnumerable<IPhFeatureConstraint> FeatureConstraints
{
get;
}

/// <summary>
/// Gets all of the feature constraints in this rule.
/// </summary>
/// <returns>The feature constraints.</returns>
public List<IPhFeatureConstraint> GetFeatureConstraints();
}

public partial interface IFsFeatureSystem
{
/// <summary>
Expand Down
40 changes: 40 additions & 0 deletions tests/SIL.LCModel.Tests/DomainImpl/LingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,46 @@ public void NewMoAffixProcessHasInputAndOutput()
Assert.That(affixProcess.OutputOS[0], Is.TypeOf(typeof(MoCopyFromInput)));
}

/// <summary>
/// Verify that a new MoAffixProcess is properly initialized. This is needed at least for the Affix Process slice
/// to work properly. See FWR-1619.
/// </summary>
[Test]
public void MoAffixProcessFeatureConstraints()
{
var phData = Cache.LangProject.PhonologicalDataOA;
var entry = Cache.ServiceLocator.GetInstance<ILexEntryFactory>().Create();
var affixProcess = Cache.ServiceLocator.GetInstance<IMoAffixProcessFactory>().Create();
entry.LexemeFormOA = affixProcess;

var ctxtInput = Cache.ServiceLocator.GetInstance<IPhSimpleContextNCFactory>().Create();
affixProcess.InputOS.Add(ctxtInput);
var featConstrInput = Cache.ServiceLocator.GetInstance<IPhFeatureConstraintFactory>().Create();
phData.FeatConstraintsOS.Add(featConstrInput);
ctxtInput.PlusConstrRS.Add(featConstrInput);

var cfi = Cache.ServiceLocator.GetInstance<IMoCopyFromInputFactory>().Create();
affixProcess.OutputOS.Add(cfi);
var ctxtCfi = Cache.ServiceLocator.GetInstance<IPhSimpleContextNCFactory>().Create();
phData.ContextsOS.Add(ctxtCfi);
cfi.ContentRA = ctxtCfi;
var featConstrCfi = Cache.ServiceLocator.GetInstance<IPhFeatureConstraintFactory>().Create();
phData.FeatConstraintsOS.Add(featConstrCfi);
ctxtCfi.MinusConstrRS.Add(featConstrCfi);

var mfi = Cache.ServiceLocator.GetInstance<IMoModifyFromInputFactory>().Create();
affixProcess.OutputOS.Add(mfi);
var ctxtMfi = Cache.ServiceLocator.GetInstance<IPhSimpleContextNCFactory>().Create();
phData.ContextsOS.Add(ctxtMfi);
mfi.ContentRA = ctxtMfi;
var featConstrMfi = Cache.ServiceLocator.GetInstance<IPhFeatureConstraintFactory>().Create();
phData.FeatConstraintsOS.Add(featConstrMfi);
ctxtMfi.PlusConstrRS.Add(featConstrMfi);

var featureConstrs = affixProcess.FeatureConstraints;
Assert.That(featureConstrs, Has.Count.EqualTo(3));
}

/// <summary>
/// Trivial test that a newly created InflAffixTemplate has the Final property set to true.
/// </summary>
Expand Down
Loading