Skip to content

Commit

Permalink
Use AttributeUses instead of Attributes to get all available attribut…
Browse files Browse the repository at this point in the history
…es from base types

Generate suggestions for boolean attributes
  • Loading branch information
MarkMpn committed Jul 31, 2021
1 parent 6f90213 commit f2679ec
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 33 deletions.
45 changes: 17 additions & 28 deletions MarkMpn.XmlSchemaAutoComplete/Autocomplete.cs
Original file line number Diff line number Diff line change
Expand Up @@ -306,22 +306,14 @@ public AutocompleteSuggestion[] GetSuggestions(string text)
if (elements.TryPeek(out var currentElement) &&
currentElement.Type is XmlSchemaComplexType complex)
{
suggestions.AddRange(complex.Attributes
suggestions.AddRange(complex.AttributeUses
.Values
.Cast<XmlSchemaAttribute>()
.Select(a => new AutocompleteAttributeSuggestion { Name = a.Name })
);

// Recurse through base types adding their attributes too
var baseType = complex.BaseXmlSchemaType;
while (baseType is XmlSchemaComplexType baseComplex)
{
suggestions.AddRange(baseComplex.Attributes.Cast<XmlSchemaAttribute>().Select(a => new AutocompleteAttributeSuggestion { Name = a.Name }));
baseType = baseType.BaseXmlSchemaType;
}

// Sort all the attributes by name
suggestions.Sort((x, y) => x.Name.CompareTo(y.Name));

}

// Special cases for xsi:type
Expand Down Expand Up @@ -355,27 +347,25 @@ public AutocompleteSuggestion[] GetSuggestions(string text)
if (elements.TryPeek(out var currentElement) &&
currentElement.Type is XmlSchemaComplexType complex)
{
var attribute = complex.Attributes
var attribute = complex.AttributeUses
.Values
.Cast<XmlSchemaAttribute>()
.SingleOrDefault(a => a.Name == element.CurrentAttribute);

// Recurse through base types adding their attributes too
var baseType = complex.BaseXmlSchemaType;
while (attribute == null && baseType is XmlSchemaComplexType baseComplex)
{
attribute = baseComplex.Attributes
.Cast<XmlSchemaAttribute>()
.SingleOrDefault(a => a.Name == element.CurrentAttribute);

baseType = baseType.BaseXmlSchemaType;
}

if (attribute != null && attribute.AttributeSchemaType.Content is XmlSchemaSimpleTypeRestriction attrValues)
if (attribute != null)
{
suggestions.AddRange(attrValues.Facets
.OfType<XmlSchemaEnumerationFacet>()
.Select(value => new AutocompleteAttributeValueSuggestion { Value = value.Value })
);
if (attribute.AttributeSchemaType.TypeCode == XmlTypeCode.Boolean)
{
suggestions.Add(new AutocompleteAttributeValueSuggestion { Value = "false" });
suggestions.Add(new AutocompleteAttributeValueSuggestion { Value = "true" });
}
else if (attribute.AttributeSchemaType.Content is XmlSchemaSimpleTypeRestriction attrValues)
{
suggestions.AddRange(attrValues.Facets
.OfType<XmlSchemaEnumerationFacet>()
.Select(value => new AutocompleteAttributeValueSuggestion { Value = value.Value })
);
}
}

// Use the event callback to gather suggestions
Expand All @@ -391,7 +381,6 @@ public AutocompleteSuggestion[] GetSuggestions(string text)
}

AutocompleteAttributeValue(this, new AutocompleteAttributeValueEventArgs(suggestions, currentElement.Element, schemaTypes, schemaElements, attribute));
return suggestions.ToArray<AutocompleteSuggestion>();
}
}

Expand Down
3 changes: 3 additions & 0 deletions MarkMpn.XmlSchemaAutocomplete.Tests/Model/Person.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,8 @@ public class Person

[XmlAttribute("gender")]
public Gender GenderAttribute { get; set; }

[XmlAttribute("manager")]
public bool IsManager { get; set; }
}
}
11 changes: 6 additions & 5 deletions MarkMpn.XmlSchemaAutocomplete.Tests/Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ public void SuggestsArrayMembers(string input, params string[] elements)

[Theory]
[InlineData("<MyDoc ", "xmlns:xsi", "xsi:nil")]
[InlineData("<MyDoc><Members><p ", "xsi:nil", "xsi:type", "gender", "surname")]
[InlineData("<MyDoc><Members><c ", "xsi:nil", "gender", "surname")]
[InlineData("<MyDoc><Staff ", "xsi:type", "gender", "surname")]
[InlineData("<MyDoc><Members><p ", "xsi:nil", "xsi:type", "gender", "manager", "surname")]
[InlineData("<MyDoc><Members><c ", "xsi:nil", "gender", "manager", "surname")]
[InlineData("<MyDoc><Staff ", "xsi:type", "gender", "manager", "surname")]
[InlineData("<MyDoc><Staff s", "surname")]
[InlineData("<MyDoc><Staff gender='Male' ", "xsi:type", "surname")]
[InlineData("<MyDoc><Staff gender='Male' ", "xsi:type", "manager", "surname")]
[InlineData("<MyDoc><Staff f")]
public void SuggestsAttributes(string input, params string[] attributes)
{
Expand All @@ -66,6 +66,7 @@ public void SuggestsAttributes(string input, params string[] attributes)
[InlineData("<MyDoc xmlns:xsi=\"", "http://www.w3.org/2001/XMLSchema-instance")]
[InlineData("<MyDoc><Staff gender=", "Male", "Female")]
[InlineData("<MyDoc><Staff gender=\"M", "Male")]
[InlineData("<MyDoc><Staff manager=\"", "false", "true")]
public void SuggestsAttributeValues(string input, params string[] values)
{
var autocomplete = new Autocomplete<Root>();
Expand Down Expand Up @@ -147,7 +148,7 @@ public void CallbacksToCompleteValues(string input, string path)
var suggestions = autocomplete.GetSuggestions(input);
var expected = new AutocompleteSuggestion[]
{
input.EndsWith("=") ? (AutocompleteSuggestion) new AutocompleteAttributeValueSuggestion { Value = path } : new AutocompleteValueSuggestion { Value = path },
input.EndsWith("=") ? (AutocompleteSuggestion) new AutocompleteAttributeValueSuggestion { Value = path, IncludeQuotes = true } : new AutocompleteValueSuggestion { Value = path },
};
Assert.Equal(expected, suggestions, new PropertyComparer());
}
Expand Down

0 comments on commit f2679ec

Please sign in to comment.