Skip to content

Commit

Permalink
Fix some bugs introduced when adding EOF support
Browse files Browse the repository at this point in the history
  • Loading branch information
mhutch committed Jul 11, 2023
1 parent 0482592 commit feee974
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 6 deletions.
4 changes: 4 additions & 0 deletions Core/Parser/XmlAttributeState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ public XmlAttributeState (
var att = (XAttribute)context.Nodes.Pop ();
att.End (context.PositionBeforeCurrentChar);

if (!att.IsNamed) {
return Parent;
}

var element = (IAttributedXObject)context.Nodes.Peek ();

if (logDuplicate && context.Diagnostics is not null && element.Attributes.Get (att.Name, false) is not null) {
Expand Down
2 changes: 1 addition & 1 deletion Core/Parser/XmlParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ public void Push (char c)
if (Context.Nodes.Count != 1 || Context.Nodes.Pop () is not XDocument doc) {
throw new InvalidParserStateException ("Malformed state stack when ending all nodes");
}
doc.End (Context.Position);
doc.End (Context.PositionBeforeCurrentChar);

for (int i = nodes.Length - 1; i >= 0; i--) {
var node = nodes[i];
Expand Down
6 changes: 4 additions & 2 deletions Core/Parser/XmlParserContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,10 @@ public XmlParserContext (XmlParserState? previousState, XmlParserState currentSt

internal bool IsAtEndOfFile { get; set; }

internal int PositionBeforeCurrentChar => Position;
internal int PositionAfterCurrentChar => IsAtEndOfFile ? Position : Position + 1;
// during EOF, the position is after the last char, so these helpers ensure we don't end up with an invalid span
internal int PositionBeforeCurrentChar => IsAtEndOfFile? Position - 1 : Position;
internal int PositionAfterCurrentChar => IsAtEndOfFile ? Position - 1 : Position + 1;

internal TextSpan CurrentStateSpanIncludingCurrentChar => TextSpan.FromBounds(Position - CurrentStateLength, PositionAfterCurrentChar);
internal TextSpan CurrentStateSpanExcludingCurrentChar => TextSpan.FromBounds(Position - CurrentStateLength, PositionBeforeCurrentChar);

Expand Down
12 changes: 9 additions & 3 deletions Core/Parser/XmlTagState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ public XmlTagState (XmlAttributeState attributeState, XmlNameState nameState)

// if the current node on the stack is ended or not an element, then it's the parent
// and we need to create the new element
if ((element is null || (element.IsEnded && !isEndOfFile))) {
if (isEndOfFile) {
if (element is null) {
throw new InvalidParserStateException ("When entering tag state during EOF, there must be an XElement on the stack");
}
} else if (element is null || element.IsEnded) {
var parent = peekedNode;
element = new XElement (context.Position - STARTOFFSET) { Parent = parent };
context.Nodes.Push (element);
Expand All @@ -78,14 +82,16 @@ public XmlTagState (XmlAttributeState attributeState, XmlNameState nameState)
}

if (isEndOfFile || c == '<') {
element.End (context.PositionBeforeCurrentChar);
if (!element.IsEnded) {
element.End (context.PositionBeforeCurrentChar);
}
if (isEndOfFile) {
context.Diagnostics?.Add (XmlCoreDiagnostics.IncompleteTagEof, context.PositionBeforeCurrentChar);
}
else if (element.Name.IsValid) {
context.Diagnostics?.Add (XmlCoreDiagnostics.MalformedNamedTag, context.PositionBeforeCurrentChar, element.Name.FullName, '<');
} else {
context.Diagnostics?.Add (XmlCoreDiagnostics.UnnamedTag, context.Position);
context.Diagnostics?.Add (XmlCoreDiagnostics.UnnamedTag, context.PositionBeforeCurrentChar);
}

if (isEndOfFile) {
Expand Down

0 comments on commit feee974

Please sign in to comment.