public void WriterConstructedWithoutContentLengthAndSourceFile_AddsLinePragmas_OnDispose() { // Arrange var location = new SourceLocation(10, 1, 20); var expected = string.Join(Environment.NewLine, @"#line 2 ""myfile""", "Hello world", "", "#line default", "#line hidden", ""); var expectedMappings = new LineMapping( new MappingLocation(location, 30), new MappingLocation(new SourceLocation(18, 1, 0), 11)); var writer = new CSharpCodeWriter(); // Act using (var mappingWriter = new CSharpLineMappingWriter(writer, location, "myfile")) { writer.Write("Hello world"); } // Assert Assert.Equal(expected, writer.GenerateCode()); Assert.Empty(writer.LineMappingManager.Mappings); }
public void WriterConstructedWithContentLength_AddsLineMappings_OnDispose() { // Arrange var location = new SourceLocation(10, 15, 20); var expected = new LineMapping( new MappingLocation(location, 30), new MappingLocation(new SourceLocation(0, 0, 0), 11)); var writer = new CSharpCodeWriter(); // Act using (var mappingWriter = new CSharpLineMappingWriter(writer, location, 30)) { writer.Write("Hello world"); } // Assert Assert.Equal("Hello world", writer.GenerateCode()); var mapping = Assert.Single(writer.LineMappingManager.Mappings); Assert.Equal(expected, mapping); }
// Render assignment of attribute value to the value accessor. private void RenderNewAttributeValueAssignment( TagHelperAttributeDescriptor attributeDescriptor, bool bufferableAttribute, Chunk attributeValueChunk, string valueAccessor) { // Plain text values are non Razor code (@DateTime.Now) values. If an attribute is bufferable it // may be more than just a plain text value, it may also contain Razor code which is why we attempt // to retrieve a plain text value here. string textValue; var isPlainTextValue = TryGetPlainTextValue(attributeValueChunk, out textValue); if (bufferableAttribute) { if (!isPlainTextValue) { // If we haven't recorded a value and we need to buffer an attribute value and the value is not // plain text then we need to prepare the value prior to setting it below. BuildBufferedWritingScope(attributeValueChunk, htmlEncodeValues: false); } _writer.WriteStartAssignment(valueAccessor); if (isPlainTextValue) { // If the attribute is bufferable but has a plain text value that means the value // is a string which needs to be surrounded in quotes. RenderQuotedAttributeValue(textValue, attributeDescriptor); } else { // The value contains more than plain text e.g. stringAttribute ="Time: @DateTime.Now". RenderBufferedAttributeValue(attributeDescriptor); } _writer.WriteLine(";"); } else { // Write out simple assignment for non-string property value. Try to keep the whole // statement together and the #line pragma correct to make debugging possible. using (var lineMapper = new CSharpLineMappingWriter( _writer, attributeValueChunk.Start, _context.SourceFile)) { // Place the assignment LHS to align RHS with original attribute value's indentation. // Unfortunately originalIndent is incorrect if original line contains tabs. Unable to // use a CSharpPaddingBuilder because the Association has no Previous node; lost the // original Span sequence when the parse tree was rewritten. var originalIndent = attributeValueChunk.Start.CharacterIndex; var generatedLength = valueAccessor.Length + " = ".Length; var newIndent = originalIndent - generatedLength; if (newIndent > 0) { _writer.Indent(newIndent); } _writer.WriteStartAssignment(valueAccessor); lineMapper.MarkLineMappingStart(); // Write out code expression for this attribute value. Property is not a string. // So quoting or buffering are not helpful. RenderCodeAttributeValue(attributeValueChunk, attributeDescriptor, isPlainTextValue); // End the assignment to the attribute. lineMapper.MarkLineMappingEnd(); _writer.WriteLine(";"); } } }