-
Notifications
You must be signed in to change notification settings - Fork 222
Add line mappings to project TagHelper attribute values. #244
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -166,6 +166,8 @@ private static KeyValuePair<string, SyntaxTreeNode> ParseSpan( | |
Kind = span.Kind | ||
}; | ||
var htmlSymbols = span.Symbols.OfType<HtmlSymbol>().ToArray(); | ||
var capturedAttributeValueStart = false; | ||
var attributeValueStartLocation = span.Start; | ||
var symbolOffset = 1; | ||
string name = null; | ||
|
||
|
@@ -175,13 +177,24 @@ private static KeyValuePair<string, SyntaxTreeNode> ParseSpan( | |
{ | ||
var symbol = htmlSymbols[i]; | ||
|
||
if (name == null && symbol.Type == HtmlSymbolType.Text) | ||
if (afterEquals) | ||
{ | ||
name = symbol.Content; | ||
// When symbols are accepted into SpanBuilders, their locations get altered to be offset by the | ||
// parent which is why we need to mark our start location prior to adding the symbol. | ||
// This is needed to know the location of the attribute value start within the document. | ||
if (!capturedAttributeValueStart) | ||
{ | ||
capturedAttributeValueStart = true; | ||
|
||
attributeValueStartLocation = span.Start + symbol.Start; | ||
} | ||
|
||
builder.Accept(symbol); | ||
} | ||
else if (afterEquals) | ||
else if (name == null && symbol.Type == HtmlSymbolType.Text) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. curious: is there a case where this condition and There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the code block is |
||
{ | ||
builder.Accept(symbol); | ||
name = symbol.Content; | ||
attributeValueStartLocation = SourceLocation.Advance(span.Start, name); | ||
} | ||
else if (symbol.Type == HtmlSymbolType.Equals) | ||
{ | ||
|
@@ -193,22 +206,36 @@ private static KeyValuePair<string, SyntaxTreeNode> ParseSpan( | |
// TODO: Handle malformed tags, if there's an '=' then there MUST be a value. | ||
// https://github.com/aspnet/Razor/issues/104 | ||
|
||
SourceLocation symbolStartLocation; | ||
|
||
// Check for attribute start values, aka single or double quote | ||
if (IsQuote(htmlSymbols[i + 1])) | ||
{ | ||
// Move past the attribute start so we can accept the true value. | ||
i++; | ||
symbolStartLocation = htmlSymbols[i + 1].Start; | ||
} | ||
else | ||
{ | ||
symbolStartLocation = symbol.Start; | ||
|
||
// Set the symbol offset to 0 so we don't attempt to skip an end quote that doesn't exist. | ||
symbolOffset = 0; | ||
} | ||
|
||
attributeValueStartLocation = symbolStartLocation + | ||
span.Start + | ||
new SourceLocation(absoluteIndex: 1, | ||
lineIndex: 0, | ||
characterIndex: 1); | ||
afterEquals = true; | ||
} | ||
} | ||
|
||
// After all symbols have been added we need to set the builders start position so we do not indirectly | ||
// modify each symbol's Start location. | ||
builder.Start = attributeValueStartLocation; | ||
|
||
return CreateMarkupAttribute(name, builder, attributeValueTypes); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -174,7 +174,14 @@ public static TheoryData DesignTimeTagHelperTestData | |
generatedAbsoluteIndex: 475, | ||
generatedLineIndex: 15, | ||
characterOffsetIndex: 14, | ||
contentLength: 11) | ||
contentLength: 11), | ||
BuildLineMapping(documentAbsoluteIndex: 57, | ||
documentLineIndex: 2, | ||
documentCharacterOffsetIndex: 28, | ||
generatedAbsoluteIndex: 927, | ||
generatedLineIndex: 33, | ||
generatedCharacterOffsetIndex: 31, | ||
contentLength: 4) | ||
} | ||
}, | ||
{ | ||
|
@@ -188,7 +195,14 @@ public static TheoryData DesignTimeTagHelperTestData | |
generatedAbsoluteIndex: 475, | ||
generatedLineIndex: 15, | ||
characterOffsetIndex: 14, | ||
contentLength: 11) | ||
contentLength: 11), | ||
BuildLineMapping(documentAbsoluteIndex: 189, | ||
documentLineIndex: 6, | ||
documentCharacterOffsetIndex: 40, | ||
generatedAbsoluteIndex: 1599, | ||
generatedLineIndex: 44, | ||
generatedCharacterOffsetIndex: 40, | ||
contentLength: 4) | ||
} | ||
}, | ||
{ | ||
|
@@ -218,6 +232,7 @@ public static TheoryData DesignTimeTagHelperTestData | |
BuildLineMapping(218, 9, 13, 1356, 56, 12, 27), | ||
BuildLineMapping(346, 12, 1754, 68, 0, 48), | ||
BuildLineMapping(440, 15, 46, 2004, 78, 6, 8), | ||
BuildLineMapping(457, 15, 63, 2267, 85, 40, 4), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. looks relatively skimpy. how about one or two tests of the specific line mapping generation? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What would those tests do? We're already validating the raw attribute value use-case (only one with custom projections) 3x over and the other attribute values in pretty much every test. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup, we cover both of these and more in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👌 |
||
BuildLineMapping(501, 16, 31, 2384, 88, 6, 30), | ||
BuildLineMapping(568, 17, 30, 2733, 97, 0, 10), | ||
BuildLineMapping(601, 17, 63, 2815, 103, 0, 8), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where exactly will this point when
capturedAttributeValueStart == false
and when that'strue
?I suspect it'll point to the start of the attribute name in the
false
case and the@
in thetrue
case. I hope that's not correct...There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You were correct, addressed this.