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
90 changes: 86 additions & 4 deletions src/SIL.LCModel/DomainImpl/OverridesCellar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2247,8 +2247,9 @@ public ITsString GetFeatureValueString(bool fLongForm)
var tisb = TsStringUtils.MakeIncStrBldr();
tisb.SetIntPropValues((int)FwTextPropType.ktptWs, (int)FwTextPropVar.ktpvDefault, Cache.DefaultUserWs);

var sFeature = GetFeatureString(fLongForm);
var sValue = GetValueString(fLongForm);
// ValueRA == null is an empty value that is filled in by FillInBlanks.
var sFeature = GetFeatureString(fLongForm || ValueRA == null);
var sValue = ValueRA == null ? "*" : GetValueString(fLongForm);
if ((!fLongForm) &&
(FeatureRA != null) &&
(FeatureRA.DisplayToRightOfValues))
Expand Down Expand Up @@ -3871,8 +3872,8 @@ from myitem in FeatureSpecsOC
else
{
if (myFeatureValues.First() is IFsComplexValue complex &&
spec is IFsComplexValue newComplexValue &&
complex.ValueOA is IFsFeatStruc fs)
spec is IFsComplexValue newComplexValue &&
complex.ValueOA is IFsFeatStruc fs)
{
fs.PriorityUnion(newComplexValue.ValueOA as IFsFeatStruc);
}
Expand All @@ -3885,6 +3886,87 @@ spec is IFsComplexValue newComplexValue &&
}

}

/// <summary>
/// Fill in the blanks.
/// Remove unfilled blanks and empty feature structures.
/// </summary>
/// <param name="fsValue">the values to fill with</param>
public IFsFeatStruc FillInBlanks(IFsFeatStruc fsValue)
{
foreach (IFsFeatureSpecification spec in FeatureSpecsOC.ToList())
{
// Find matching specification.
IFsFeatureSpecification spec2 = null;
if (fsValue != null)
{
foreach (var spec3 in fsValue.FeatureSpecsOC)
{
if (spec3.FeatureRA.Name == spec.FeatureRA.Name)
{
spec2 = spec3;
}
}
}
// Fill in blanks in spec.
if (spec is IFsClosedValue closed && closed != null && closed.ValueRA == null)
{
if (spec2 is IFsClosedValue closed2 && closed2 != null)
{
// Fill in blank.
closed.ValueRA = closed2.ValueRA;

}
if (closed.ValueRA == null)
{
// Remove unfilled blank.
FeatureSpecsOC.Remove(spec);
}
}
if (spec is IFsComplexValue complex && complex != null)
{
// Recursively fill in blanks.
if (complex.ValueOA is IFsFeatStruc fs)
{
IFsComplexValue complex2 = spec2 as IFsComplexValue;
if (fs.FillInBlanks(complex2?.ValueOA as IFsFeatStruc) == null)
{
// Remove empty feature structure.
FeatureSpecsOC.Remove(complex);
}
}
}
}
// See if removing blanks emptied the feature structure.
if (FeatureSpecsOC.Count == 0)
{
return null;
}
return this;
}

public bool ContainsBlank()
{
foreach (IFsFeatureSpecification spec in FeatureSpecsOC.ToList())
{
if (spec is IFsClosedValue closed && closed != null && closed.ValueRA == null)
{
return true;
}
if (spec is IFsComplexValue complex && complex != null)
{
if (complex.ValueOA is IFsFeatStruc fs)
{
if (fs.ContainsBlank())
{
return true;
}
}
}
}
return false;
}

protected override void RemoveObjectSideEffectsInternal(RemoveObjectEventArgs e)
{
switch (e.Flid)
Expand Down
13 changes: 13 additions & 0 deletions src/SIL.LCModel/InterfaceAdditions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2323,6 +2323,19 @@ ITsString LongNameSortedTSS
/// </summary>
/// <param name="fsNew">the new feature structure</param>
void PriorityUnion(IFsFeatStruc fsNew);

/// <summary>
/// Fill in the blanks of this feature structure
/// using the given values.
/// Eliminates blanks with no values and returns null if there is nothing left.
/// </summary>
/// <param name="fsValues">feature structure with given values</param>
IFsFeatStruc FillInBlanks(IFsFeatStruc fsValues);

/// <summary>
/// Determine if this feature structure contains a blank.
/// </summary>
public bool ContainsBlank();
}

/// <summary>
Expand Down
41 changes: 41 additions & 0 deletions tests/SIL.LCModel.Tests/DomainImpl/CellarTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,22 @@ public void AddClosedFeaturesToFeatureSystemAndThenToAFeatureStructure()
Assert.AreEqual("Gen", cv.FeatureRA.Abbreviation.AnalysisDefaultWritingSystem.Text, "Expect to have Gen feature name");
Assert.AreEqual("Neut", cv.ValueRA.Abbreviation.AnalysisDefaultWritingSystem.Text, "Expect to have Neut feature value");
}

// Test FillInBlanks.
IFsClosedValue closedValue = featStruct.FeatureSpecsOC.First() as IFsClosedValue;
closedValue.ValueRA = null;
Assert.AreEqual("Gen:*", featStruct.ShortName);
Assert.IsTrue(featStruct.ContainsBlank());
Assert.IsFalse(featStrucGenNeut.ContainsBlank());
featStruct = featStruct.FillInBlanks(featStrucGenNeut);
Assert.IsFalse(featStruct.ContainsBlank());
Assert.AreEqual("Agr", featStruct.TypeRA.Abbreviation.AnalysisDefaultWritingSystem.Text, "Expect type Agr");
Assert.AreEqual(1, featStruct.FeatureSpecsOC.Count, "should have one feature spec");
foreach (IFsClosedValue cv in featStruct.FeatureSpecsOC)
{
Assert.AreEqual("Gen", cv.FeatureRA.Abbreviation.AnalysisDefaultWritingSystem.Text, "Expect to have Gen feature name");
Assert.AreEqual("Neut", cv.ValueRA.Abbreviation.AnalysisDefaultWritingSystem.Text, "Expect to have Neut feature value");
}
}

/// ------------------------------------------------------------------------------------
Expand Down Expand Up @@ -667,6 +683,31 @@ public void AddComplexFeaturesToFeatureSystemAndThenToAFeatureStructure()
// Check for correct LongName
Assert.AreEqual("[asp:aor sbj:[gen:n num:sg pers:1]]", featStruct.LongName, "Incorrect LongName for merged feature struture");
Assert.AreEqual("[asp:aor sbj:[gen:n num:sg pers:1]]", featStruct.LongNameSorted, "Incorrect LongNameSorted for merged feature struture");

// Test FillInBlanks.
pos.DefaultFeaturesOA = null;
pos.DefaultFeaturesOA = Cache.ServiceLocator.GetInstance<IFsFeatStrucFactory>().Create();
featStruct = pos.DefaultFeaturesOA;
featStruct.AddFeatureFromXml(itemFem, msfs);
IFsComplexValue complexValue = featStruct.FeatureSpecsOC.First() as IFsComplexValue;
IFsFeatStruc fsValue = complexValue.ValueOA as IFsFeatStruc;
IFsClosedValue closedValue = fsValue.FeatureSpecsOC.First() as IFsClosedValue;
closedValue.ValueRA = null;
Assert.AreEqual("gen:*", featStruct.ShortName);
Assert.IsTrue(featStruct.ContainsBlank());
Assert.IsFalse(featStruct2.ContainsBlank());
featStruct = featStruct.FillInBlanks(featStruct2);
Assert.IsFalse(featStruct2.ContainsBlank());
Assert.AreEqual("[sbj:[gen:n]]", featStruct.LongName, "Incorrect LongName for merged feature struture");

// Test removing FillInBlanks.
closedValue.ValueRA = null;
featStruct2.FeatureSpecsOC.Remove(featStruct2.FeatureSpecsOC.First());
Assert.AreEqual("gen:*", featStruct.ShortName);
Assert.IsTrue(featStruct.ContainsBlank());
Assert.IsFalse(featStruct2.ContainsBlank());
featStruct = featStruct.FillInBlanks(featStruct2);
Assert.AreEqual(null, featStruct, "FillInBlanks didn't remove unfilled blanks");
}


Expand Down
Loading