Add legacy dependencies of C# lowering
This commit is contained in:
parent
03549bb542
commit
9cefcdd450
|
|
@ -0,0 +1,536 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
{
|
||||
internal class CSharpCodeWriter : CodeWriter
|
||||
{
|
||||
private const string InstanceMethodFormat = "{0}.{1}";
|
||||
|
||||
private static readonly char[] CStyleStringLiteralEscapeChars = {
|
||||
'\r',
|
||||
'\t',
|
||||
'\"',
|
||||
'\'',
|
||||
'\\',
|
||||
'\0',
|
||||
'\n',
|
||||
'\u2028',
|
||||
'\u2029',
|
||||
};
|
||||
|
||||
public CSharpCodeWriter()
|
||||
{
|
||||
LineMappingManager = new LineMappingManager();
|
||||
}
|
||||
|
||||
public LineMappingManager LineMappingManager { get; private set; }
|
||||
|
||||
public new CSharpCodeWriter Write(string data)
|
||||
{
|
||||
return (CSharpCodeWriter)base.Write(data);
|
||||
}
|
||||
|
||||
public new CSharpCodeWriter Indent(int size)
|
||||
{
|
||||
return (CSharpCodeWriter)base.Indent(size);
|
||||
}
|
||||
|
||||
public new CSharpCodeWriter ResetIndent()
|
||||
{
|
||||
return (CSharpCodeWriter)base.ResetIndent();
|
||||
}
|
||||
|
||||
public new CSharpCodeWriter SetIndent(int size)
|
||||
{
|
||||
return (CSharpCodeWriter)base.SetIndent(size);
|
||||
}
|
||||
|
||||
public new CSharpCodeWriter IncreaseIndent(int size)
|
||||
{
|
||||
return (CSharpCodeWriter)base.IncreaseIndent(size);
|
||||
}
|
||||
|
||||
public new CSharpCodeWriter DecreaseIndent(int size)
|
||||
{
|
||||
return (CSharpCodeWriter)base.DecreaseIndent(size);
|
||||
}
|
||||
|
||||
public new CSharpCodeWriter WriteLine(string data)
|
||||
{
|
||||
return (CSharpCodeWriter)base.WriteLine(data);
|
||||
}
|
||||
|
||||
public new CSharpCodeWriter WriteLine()
|
||||
{
|
||||
return (CSharpCodeWriter)base.WriteLine();
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteVariableDeclaration(string type, string name, string value)
|
||||
{
|
||||
Write(type).Write(" ").Write(name);
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
Write(" = ").Write(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Write(" = null");
|
||||
}
|
||||
|
||||
WriteLine(";");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteComment(string comment)
|
||||
{
|
||||
return Write("// ").WriteLine(comment);
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteBooleanLiteral(bool value)
|
||||
{
|
||||
return Write(value.ToString().ToLowerInvariant());
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteStartAssignment(string name)
|
||||
{
|
||||
return Write(name).Write(" = ");
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteParameterSeparator()
|
||||
{
|
||||
return Write(", ");
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteStartNewObject(string typeName)
|
||||
{
|
||||
return Write("new ").Write(typeName).Write("(");
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteLocationTaggedString(LocationTagged<string> value)
|
||||
{
|
||||
WriteStringLiteral(value.Value);
|
||||
WriteParameterSeparator();
|
||||
Write(value.Location.AbsoluteIndex.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteStringLiteral(string literal)
|
||||
{
|
||||
if (literal.Length >= 256 && literal.Length <= 1500 && literal.IndexOf('\0') == -1)
|
||||
{
|
||||
WriteVerbatimStringLiteral(literal);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteCStyleStringLiteral(literal);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteLineHiddenDirective()
|
||||
{
|
||||
return WriteLine("#line hidden");
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WritePragma(string value)
|
||||
{
|
||||
return Write("#pragma ").WriteLine(value);
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteUsing(string name)
|
||||
{
|
||||
return WriteUsing(name, endLine: true);
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteUsing(string name, bool endLine)
|
||||
{
|
||||
Write("using ");
|
||||
Write(name);
|
||||
|
||||
if (endLine)
|
||||
{
|
||||
WriteLine(";");
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteLineDefaultDirective()
|
||||
{
|
||||
return WriteLine("#line default");
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteStartReturn()
|
||||
{
|
||||
return Write("return ");
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteReturn(string value)
|
||||
{
|
||||
return WriteReturn(value, endLine: true);
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteReturn(string value, bool endLine)
|
||||
{
|
||||
Write("return ").Write(value);
|
||||
|
||||
if (endLine)
|
||||
{
|
||||
Write(";");
|
||||
}
|
||||
|
||||
return WriteLine();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a <c>#line</c> pragma directive for the line number at the specified <paramref name="location"/>.
|
||||
/// </summary>
|
||||
/// <param name="location">The location to generate the line pragma for.</param>
|
||||
/// <param name="file">The file to generate the line pragma for.</param>
|
||||
/// <returns>The current instance of <see cref="CSharpCodeWriter"/>.</returns>
|
||||
public CSharpCodeWriter WriteLineNumberDirective(SourceLocation location, string file)
|
||||
{
|
||||
if (location.FilePath != null)
|
||||
{
|
||||
file = location.FilePath;
|
||||
}
|
||||
|
||||
if (Builder.Length >= NewLine.Length && !IsAfterNewLine)
|
||||
{
|
||||
WriteLine();
|
||||
}
|
||||
|
||||
var lineNumberAsString = (location.LineIndex + 1).ToString(CultureInfo.InvariantCulture);
|
||||
return Write("#line ").Write(lineNumberAsString).Write(" \"").Write(file).WriteLine("\"");
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteStartMethodInvocation(string methodName)
|
||||
{
|
||||
return WriteStartMethodInvocation(methodName, new string[0]);
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteStartMethodInvocation(string methodName, params string[] genericArguments)
|
||||
{
|
||||
Write(methodName);
|
||||
|
||||
if (genericArguments.Length > 0)
|
||||
{
|
||||
Write("<").Write(string.Join(", ", genericArguments)).Write(">");
|
||||
}
|
||||
|
||||
return Write("(");
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteEndMethodInvocation()
|
||||
{
|
||||
return WriteEndMethodInvocation(endLine: true);
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteEndMethodInvocation(bool endLine)
|
||||
{
|
||||
Write(")");
|
||||
if (endLine)
|
||||
{
|
||||
WriteLine(";");
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// Writes a method invocation for the given instance name.
|
||||
public CSharpCodeWriter WriteInstanceMethodInvocation(string instanceName,
|
||||
string methodName,
|
||||
params string[] parameters)
|
||||
{
|
||||
if (instanceName == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(instanceName));
|
||||
}
|
||||
|
||||
if (methodName == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(methodName));
|
||||
}
|
||||
|
||||
return WriteInstanceMethodInvocation(instanceName, methodName, endLine: true, parameters: parameters);
|
||||
}
|
||||
|
||||
// Writes a method invocation for the given instance name.
|
||||
public CSharpCodeWriter WriteInstanceMethodInvocation(string instanceName,
|
||||
string methodName,
|
||||
bool endLine,
|
||||
params string[] parameters)
|
||||
{
|
||||
if (instanceName == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(instanceName));
|
||||
}
|
||||
|
||||
if (methodName == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(methodName));
|
||||
}
|
||||
|
||||
return WriteMethodInvocation(
|
||||
string.Format(CultureInfo.InvariantCulture, InstanceMethodFormat, instanceName, methodName),
|
||||
endLine,
|
||||
parameters);
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteStartInstanceMethodInvocation(string instanceName,
|
||||
string methodName)
|
||||
{
|
||||
if (instanceName == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(instanceName));
|
||||
}
|
||||
|
||||
if (methodName == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(methodName));
|
||||
}
|
||||
|
||||
return WriteStartMethodInvocation(
|
||||
string.Format(CultureInfo.InvariantCulture, InstanceMethodFormat, instanceName, methodName));
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteMethodInvocation(string methodName, params string[] parameters)
|
||||
{
|
||||
return WriteMethodInvocation(methodName, endLine: true, parameters: parameters);
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteMethodInvocation(string methodName, bool endLine, params string[] parameters)
|
||||
{
|
||||
return WriteStartMethodInvocation(methodName)
|
||||
.Write(string.Join(", ", parameters))
|
||||
.WriteEndMethodInvocation(endLine);
|
||||
}
|
||||
|
||||
public CSharpCodeWriter WriteAutoPropertyDeclaration(string accessibility, string typeName, string name)
|
||||
{
|
||||
return Write(accessibility)
|
||||
.Write(" ")
|
||||
.Write(typeName)
|
||||
.Write(" ")
|
||||
.Write(name)
|
||||
.Write(" { get; set; }")
|
||||
.WriteLine();
|
||||
}
|
||||
|
||||
public CSharpDisableWarningScope BuildDisableWarningScope(int warning)
|
||||
{
|
||||
return new CSharpDisableWarningScope(this, warning);
|
||||
}
|
||||
|
||||
public CSharpCodeWritingScope BuildScope()
|
||||
{
|
||||
return new CSharpCodeWritingScope(this);
|
||||
}
|
||||
|
||||
public CSharpCodeWritingScope BuildLambda(bool endLine, params string[] parameterNames)
|
||||
{
|
||||
return BuildLambda(endLine, async: false, parameterNames: parameterNames);
|
||||
}
|
||||
|
||||
public CSharpCodeWritingScope BuildAsyncLambda(bool endLine, params string[] parameterNames)
|
||||
{
|
||||
return BuildLambda(endLine, async: true, parameterNames: parameterNames);
|
||||
}
|
||||
|
||||
private CSharpCodeWritingScope BuildLambda(bool endLine, bool async, string[] parameterNames)
|
||||
{
|
||||
if (async)
|
||||
{
|
||||
Write("async");
|
||||
}
|
||||
|
||||
Write("(").Write(string.Join(", ", parameterNames)).Write(") => ");
|
||||
|
||||
var scope = new CSharpCodeWritingScope(this);
|
||||
|
||||
if (endLine)
|
||||
{
|
||||
// End the lambda with a semicolon
|
||||
scope.OnClose += () =>
|
||||
{
|
||||
WriteLine(";");
|
||||
};
|
||||
}
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
public CSharpCodeWritingScope BuildNamespace(string name)
|
||||
{
|
||||
Write("namespace ").WriteLine(name);
|
||||
|
||||
return new CSharpCodeWritingScope(this);
|
||||
}
|
||||
|
||||
public CSharpCodeWritingScope BuildClassDeclaration(string accessibility, string name)
|
||||
{
|
||||
return BuildClassDeclaration(accessibility, name, Enumerable.Empty<string>());
|
||||
}
|
||||
|
||||
public CSharpCodeWritingScope BuildClassDeclaration(string accessibility, string name, string baseType)
|
||||
{
|
||||
return BuildClassDeclaration(accessibility, name, new string[] { baseType });
|
||||
}
|
||||
|
||||
public CSharpCodeWritingScope BuildClassDeclaration(
|
||||
string accessibility,
|
||||
string name,
|
||||
IEnumerable<string> baseTypes)
|
||||
{
|
||||
Write(accessibility).Write(" class ").Write(name);
|
||||
|
||||
if (baseTypes.Count() > 0)
|
||||
{
|
||||
Write(" : ");
|
||||
Write(string.Join(", ", baseTypes));
|
||||
}
|
||||
|
||||
WriteLine();
|
||||
|
||||
return new CSharpCodeWritingScope(this);
|
||||
}
|
||||
|
||||
public CSharpCodeWritingScope BuildConstructor(string name)
|
||||
{
|
||||
return BuildConstructor("public", name);
|
||||
}
|
||||
|
||||
public CSharpCodeWritingScope BuildConstructor(string accessibility, string name)
|
||||
{
|
||||
return BuildConstructor(accessibility, name, Enumerable.Empty<KeyValuePair<string, string>>());
|
||||
}
|
||||
|
||||
public CSharpCodeWritingScope BuildConstructor(
|
||||
string accessibility,
|
||||
string name,
|
||||
IEnumerable<KeyValuePair<string, string>> parameters)
|
||||
{
|
||||
Write(accessibility)
|
||||
.Write(" ")
|
||||
.Write(name)
|
||||
.Write("(")
|
||||
.Write(string.Join(", ", parameters.Select(p => p.Key + " " + p.Value)))
|
||||
.WriteLine(")");
|
||||
|
||||
return new CSharpCodeWritingScope(this);
|
||||
}
|
||||
|
||||
public CSharpCodeWritingScope BuildMethodDeclaration(string accessibility, string returnType, string name)
|
||||
{
|
||||
return BuildMethodDeclaration(accessibility, returnType, name, Enumerable.Empty<KeyValuePair<string, string>>());
|
||||
}
|
||||
|
||||
public CSharpCodeWritingScope BuildMethodDeclaration(
|
||||
string accessibility,
|
||||
string returnType,
|
||||
string name,
|
||||
IEnumerable<KeyValuePair<string, string>> parameters)
|
||||
{
|
||||
Write(accessibility)
|
||||
.Write(" ")
|
||||
.Write(returnType)
|
||||
.Write(" ")
|
||||
.Write(name)
|
||||
.Write("(")
|
||||
.Write(string.Join(", ", parameters.Select(p => p.Key + " " + p.Value)))
|
||||
.WriteLine(")");
|
||||
|
||||
return new CSharpCodeWritingScope(this);
|
||||
}
|
||||
|
||||
private void WriteVerbatimStringLiteral(string literal)
|
||||
{
|
||||
Write("@\"");
|
||||
|
||||
// We need to find the index of each '"' (double-quote) to escape it.
|
||||
var start = 0;
|
||||
int end;
|
||||
while ((end = literal.IndexOf('\"', start)) > -1)
|
||||
{
|
||||
Write(literal, start, end - start);
|
||||
|
||||
Write("\"\"");
|
||||
|
||||
start = end + 1;
|
||||
}
|
||||
|
||||
Debug.Assert(end == -1); // We've hit all of the double-quotes.
|
||||
|
||||
// Write the remainder after the last double-quote.
|
||||
Write(literal, start, literal.Length - start);
|
||||
|
||||
Write("\"");
|
||||
}
|
||||
|
||||
private void WriteCStyleStringLiteral(string literal)
|
||||
{
|
||||
// From CSharpCodeGenerator.QuoteSnippetStringCStyle in CodeDOM
|
||||
Write("\"");
|
||||
|
||||
// We need to find the index of each escapable character to escape it.
|
||||
var start = 0;
|
||||
int end;
|
||||
while ((end = literal.IndexOfAny(CStyleStringLiteralEscapeChars, start)) > -1)
|
||||
{
|
||||
Write(literal, start, end - start);
|
||||
|
||||
switch (literal[end])
|
||||
{
|
||||
case '\r':
|
||||
Write("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
Write("\\t");
|
||||
break;
|
||||
case '\"':
|
||||
Write("\\\"");
|
||||
break;
|
||||
case '\'':
|
||||
Write("\\\'");
|
||||
break;
|
||||
case '\\':
|
||||
Write("\\\\");
|
||||
break;
|
||||
case '\0':
|
||||
Write("\\\0");
|
||||
break;
|
||||
case '\n':
|
||||
Write("\\n");
|
||||
break;
|
||||
case '\u2028':
|
||||
case '\u2029':
|
||||
Write("\\u");
|
||||
Write(((int)literal[end]).ToString("X4", CultureInfo.InvariantCulture));
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, "Unknown escape character.");
|
||||
break;
|
||||
}
|
||||
|
||||
start = end + 1;
|
||||
}
|
||||
|
||||
Debug.Assert(end == -1); // We've hit all of chars that need escaping.
|
||||
|
||||
// Write the remainder after the last escaped char.
|
||||
Write(literal, start, literal.Length - start);
|
||||
|
||||
Write("\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
{
|
||||
internal struct CSharpCodeWritingScope : IDisposable
|
||||
{
|
||||
private CodeWriter _writer;
|
||||
private bool _autoSpace;
|
||||
private int _tabSize;
|
||||
private int _startIndent;
|
||||
|
||||
public CSharpCodeWritingScope(CodeWriter writer) : this(writer, true) { }
|
||||
public CSharpCodeWritingScope(CodeWriter writer, int tabSize) : this(writer, tabSize, true) { }
|
||||
// TODO: Make indents (tabs) environment specific
|
||||
public CSharpCodeWritingScope(CodeWriter writer, bool autoSpace) : this(writer, 4, autoSpace) { }
|
||||
public CSharpCodeWritingScope(CodeWriter writer, int tabSize, bool autoSpace)
|
||||
{
|
||||
_writer = writer;
|
||||
_autoSpace = true;
|
||||
_tabSize = tabSize;
|
||||
_startIndent = -1; // Set in WriteStartScope
|
||||
|
||||
OnClose = () => { };
|
||||
|
||||
WriteStartScope();
|
||||
}
|
||||
|
||||
public Action OnClose;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
WriteEndScope();
|
||||
OnClose();
|
||||
}
|
||||
|
||||
private void WriteStartScope()
|
||||
{
|
||||
TryAutoSpace(" ");
|
||||
|
||||
_writer.WriteLine("{").IncreaseIndent(_tabSize);
|
||||
_startIndent = _writer.CurrentIndent;
|
||||
}
|
||||
|
||||
private void WriteEndScope()
|
||||
{
|
||||
TryAutoSpace(_writer.NewLine);
|
||||
|
||||
// Ensure the scope hasn't been modified
|
||||
if (_writer.CurrentIndent == _startIndent)
|
||||
{
|
||||
_writer.DecreaseIndent(_tabSize);
|
||||
}
|
||||
|
||||
_writer.WriteLine("}");
|
||||
}
|
||||
|
||||
private void TryAutoSpace(string spaceCharacter)
|
||||
{
|
||||
if (_autoSpace &&
|
||||
_writer.Builder.Length > 0 &&
|
||||
!char.IsWhiteSpace(_writer.Builder[_writer.Builder.Length - 1]))
|
||||
{
|
||||
_writer.Write(spaceCharacter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
{
|
||||
internal struct CSharpDisableWarningScope : IDisposable
|
||||
{
|
||||
private CSharpCodeWriter _writer;
|
||||
int _warningNumber;
|
||||
|
||||
public CSharpDisableWarningScope(CSharpCodeWriter writer) : this(writer, 219)
|
||||
{ }
|
||||
|
||||
public CSharpDisableWarningScope(CSharpCodeWriter writer, int warningNumber)
|
||||
{
|
||||
_writer = writer;
|
||||
_warningNumber = warningNumber;
|
||||
|
||||
_writer.WritePragma("warning disable " + _warningNumber);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_writer.WritePragma("warning restore " + _warningNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,203 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
{
|
||||
internal class CodeWriter : IDisposable
|
||||
{
|
||||
private static readonly char[] NewLineCharacters = { '\r', '\n' };
|
||||
|
||||
private string _cache = string.Empty;
|
||||
private bool _dirty;
|
||||
|
||||
private int _absoluteIndex;
|
||||
private int _currentLineIndex;
|
||||
private int _currentLineCharacterIndex;
|
||||
|
||||
public StringBuilder Builder { get; } = new StringBuilder();
|
||||
|
||||
public int CurrentIndent { get; private set; }
|
||||
|
||||
public bool IsAfterNewLine { get; private set; }
|
||||
|
||||
public string NewLine { get; set; } = Environment.NewLine;
|
||||
|
||||
public CodeWriter ResetIndent()
|
||||
{
|
||||
return SetIndent(0);
|
||||
}
|
||||
|
||||
public CodeWriter IncreaseIndent(int size)
|
||||
{
|
||||
CurrentIndent += size;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public CodeWriter DecreaseIndent(int size)
|
||||
{
|
||||
CurrentIndent -= size;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public CodeWriter SetIndent(int size)
|
||||
{
|
||||
CurrentIndent = size;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public CodeWriter Indent(int size)
|
||||
{
|
||||
if (IsAfterNewLine)
|
||||
{
|
||||
Builder.Append(' ', size);
|
||||
|
||||
_currentLineCharacterIndex += size;
|
||||
_absoluteIndex += size;
|
||||
|
||||
_dirty = true;
|
||||
IsAfterNewLine = false;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public CodeWriter Write(string data)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
return Write(data, 0, data.Length);
|
||||
}
|
||||
|
||||
public CodeWriter Write(string data, int index, int count)
|
||||
{
|
||||
if (data == null || count == 0)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
Indent(CurrentIndent);
|
||||
|
||||
Builder.Append(data, index, count);
|
||||
|
||||
_dirty = true;
|
||||
IsAfterNewLine = false;
|
||||
|
||||
_absoluteIndex += count;
|
||||
|
||||
// The data string might contain a partial newline where the previously
|
||||
// written string has part of the newline.
|
||||
var i = index;
|
||||
int? trailingPartStart = null;
|
||||
|
||||
if (
|
||||
// Check the last character of the previous write operation.
|
||||
Builder.Length - count - 1 >= 0 &&
|
||||
Builder[Builder.Length - count - 1] == '\r' &&
|
||||
|
||||
// Check the first character of the current write operation.
|
||||
Builder[Builder.Length - count] == '\n')
|
||||
{
|
||||
// This is newline that's spread across two writes. Skip the first character of the
|
||||
// current write operation.
|
||||
//
|
||||
// We don't need to increment our newline counter because we already did that when we
|
||||
// saw the \r.
|
||||
i += 1;
|
||||
trailingPartStart = 1;
|
||||
}
|
||||
|
||||
// Iterate the string, stopping at each occurrence of a newline character. This lets us count the
|
||||
// newline occurrences and keep the index of the last one.
|
||||
while ((i = data.IndexOfAny(NewLineCharacters, i)) >= 0)
|
||||
{
|
||||
// Newline found.
|
||||
_currentLineIndex++;
|
||||
_currentLineCharacterIndex = 0;
|
||||
|
||||
i++;
|
||||
|
||||
// We might have stopped at a \r, so check if it's followed by \n and then advance the index to
|
||||
// start the next search after it.
|
||||
if (count > i &&
|
||||
data[i - 1] == '\r' &&
|
||||
data[i] == '\n')
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
// The 'suffix' of the current line starts after this newline token.
|
||||
trailingPartStart = i;
|
||||
}
|
||||
|
||||
if (trailingPartStart == null)
|
||||
{
|
||||
// No newlines, just add the length of the data buffer
|
||||
_currentLineCharacterIndex += count;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Newlines found, add the trailing part of 'data'
|
||||
_currentLineCharacterIndex += (count - trailingPartStart.Value);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public CodeWriter WriteLine()
|
||||
{
|
||||
Builder.Append(NewLine);
|
||||
|
||||
_currentLineIndex++;
|
||||
_currentLineCharacterIndex = 0;
|
||||
_absoluteIndex += NewLine.Length;
|
||||
|
||||
_dirty = true;
|
||||
IsAfterNewLine = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public CodeWriter WriteLine(string data)
|
||||
{
|
||||
return Write(data).WriteLine();
|
||||
}
|
||||
|
||||
public string GenerateCode()
|
||||
{
|
||||
if (_dirty)
|
||||
{
|
||||
_cache = Builder.ToString();
|
||||
_dirty = false;
|
||||
}
|
||||
|
||||
return _cache;
|
||||
}
|
||||
|
||||
public SourceLocation GetCurrentSourceLocation()
|
||||
{
|
||||
return new SourceLocation(_absoluteIndex, _currentLineIndex, _currentLineCharacterIndex);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
Builder.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Globalization;
|
||||
using Microsoft.Extensions.Internal;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
{
|
||||
internal class LineMapping
|
||||
{
|
||||
public LineMapping(MappingLocation documentLocation, MappingLocation generatedLocation)
|
||||
{
|
||||
DocumentLocation = documentLocation;
|
||||
GeneratedLocation = generatedLocation;
|
||||
}
|
||||
|
||||
public MappingLocation DocumentLocation { get; }
|
||||
|
||||
public MappingLocation GeneratedLocation { get; }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var other = obj as LineMapping;
|
||||
if (ReferenceEquals(other, null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return DocumentLocation.Equals(other.DocumentLocation) &&
|
||||
GeneratedLocation.Equals(other.GeneratedLocation);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var hashCodeCombiner = HashCodeCombiner.Start();
|
||||
hashCodeCombiner.Add(DocumentLocation);
|
||||
hashCodeCombiner.Add(GeneratedLocation);
|
||||
|
||||
return hashCodeCombiner;
|
||||
}
|
||||
|
||||
public static bool operator ==(LineMapping left, LineMapping right)
|
||||
{
|
||||
if (ReferenceEquals(left, right))
|
||||
{
|
||||
// Exact equality e.g. both objects are null.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(left, null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(LineMapping left, LineMapping right)
|
||||
{
|
||||
if (ReferenceEquals(left, right))
|
||||
{
|
||||
// Exact equality e.g. both objects are null.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(left, null))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, "{0} -> {1}", DocumentLocation, GeneratedLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
{
|
||||
internal class LineMappingManager
|
||||
{
|
||||
public LineMappingManager()
|
||||
{
|
||||
Mappings = new List<LineMapping>();
|
||||
}
|
||||
|
||||
public List<LineMapping> Mappings { get; }
|
||||
|
||||
public void AddMapping(MappingLocation documentLocation, MappingLocation generatedLocation)
|
||||
{
|
||||
Mappings.Add(new LineMapping(documentLocation, generatedLocation));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Microsoft.Extensions.Internal;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
{
|
||||
internal class MappingLocation
|
||||
{
|
||||
public MappingLocation()
|
||||
{
|
||||
}
|
||||
|
||||
public MappingLocation(SourceLocation location, int contentLength)
|
||||
{
|
||||
ContentLength = contentLength;
|
||||
AbsoluteIndex = location.AbsoluteIndex;
|
||||
LineIndex = location.LineIndex;
|
||||
CharacterIndex = location.CharacterIndex;
|
||||
FilePath = location.FilePath;
|
||||
}
|
||||
|
||||
public int ContentLength { get; }
|
||||
|
||||
public int AbsoluteIndex { get; }
|
||||
|
||||
public int LineIndex { get; }
|
||||
|
||||
public int CharacterIndex { get; }
|
||||
|
||||
public string FilePath { get; }
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var other = obj as MappingLocation;
|
||||
if (ReferenceEquals(other, null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return string.Equals(FilePath, other.FilePath, StringComparison.Ordinal) &&
|
||||
AbsoluteIndex == other.AbsoluteIndex &&
|
||||
ContentLength == other.ContentLength &&
|
||||
LineIndex == other.LineIndex &&
|
||||
CharacterIndex == other.CharacterIndex;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var hashCodeCombiner = HashCodeCombiner.Start();
|
||||
hashCodeCombiner.Add(FilePath, StringComparer.Ordinal);
|
||||
hashCodeCombiner.Add(AbsoluteIndex);
|
||||
hashCodeCombiner.Add(ContentLength);
|
||||
hashCodeCombiner.Add(LineIndex);
|
||||
hashCodeCombiner.Add(CharacterIndex);
|
||||
|
||||
return hashCodeCombiner;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(
|
||||
CultureInfo.CurrentCulture, "({0}:{1},{2} [{3}] {4})",
|
||||
AbsoluteIndex,
|
||||
LineIndex,
|
||||
CharacterIndex,
|
||||
ContentLength,
|
||||
FilePath);
|
||||
}
|
||||
|
||||
public static bool operator ==(MappingLocation left, MappingLocation right)
|
||||
{
|
||||
if (ReferenceEquals(left, right))
|
||||
{
|
||||
// Exact equality e.g. both objects are null.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(left, null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(MappingLocation left, MappingLocation right)
|
||||
{
|
||||
if (ReferenceEquals(left, right))
|
||||
{
|
||||
// Exact equality e.g. both objects are null.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(left, null))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return !left.Equals(right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
{
|
||||
public class CSharpCodeWriterTest
|
||||
{
|
||||
[Fact]
|
||||
public void WriteLineNumberDirective_UsesFilePath_WhenFileInSourceLocationIsNull()
|
||||
{
|
||||
// Arrange
|
||||
var filePath = "some-path";
|
||||
var writer = new CSharpCodeWriter();
|
||||
var expected = $"#line 5 \"{filePath}\"" + writer.NewLine;
|
||||
var sourceLocation = new SourceLocation(10, 4, 3);
|
||||
|
||||
// Act
|
||||
writer.WriteLineNumberDirective(sourceLocation, filePath);
|
||||
var code = writer.GenerateCode();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, code);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("")]
|
||||
[InlineData("source-location-file-path")]
|
||||
public void WriteLineNumberDirective_UsesSourceLocationFilePath_IfAvailable(
|
||||
string sourceLocationFilePath)
|
||||
{
|
||||
// Arrange
|
||||
var filePath = "some-path";
|
||||
var writer = new CSharpCodeWriter();
|
||||
var expected = $"#line 5 \"{sourceLocationFilePath}\"" + writer.NewLine;
|
||||
var sourceLocation = new SourceLocation(sourceLocationFilePath, 10, 4, 3);
|
||||
|
||||
// Act
|
||||
writer.WriteLineNumberDirective(sourceLocation, filePath);
|
||||
var code = writer.GenerateCode();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,265 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
{
|
||||
public class CodeWriterTest
|
||||
{
|
||||
// The length of the newline string written by writer.WriteLine.
|
||||
private static readonly int WriterNewLineLength = Environment.NewLine.Length;
|
||||
|
||||
public static IEnumerable<object[]> NewLines
|
||||
{
|
||||
get
|
||||
{
|
||||
return new object[][]
|
||||
{
|
||||
new object[] { "\r" },
|
||||
new object[] { "\n" },
|
||||
new object[] { "\r\n" },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CodeWriter_TracksPosition_WithWrite()
|
||||
{
|
||||
// Arrange
|
||||
var writer = new CodeWriter();
|
||||
|
||||
// Act
|
||||
writer.Write("1234");
|
||||
|
||||
// Assert
|
||||
var location = writer.GetCurrentSourceLocation();
|
||||
var expected = new SourceLocation(absoluteIndex: 4, lineIndex: 0, characterIndex: 4);
|
||||
|
||||
Assert.Equal(expected, location);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CodeWriter_TracksPosition_WithIndent()
|
||||
{
|
||||
// Arrange
|
||||
var writer = new CodeWriter();
|
||||
|
||||
// Act
|
||||
writer.WriteLine();
|
||||
writer.Indent(size: 3);
|
||||
|
||||
// Assert
|
||||
var location = writer.GetCurrentSourceLocation();
|
||||
var expected = new SourceLocation(absoluteIndex: 3 + WriterNewLineLength, lineIndex: 1, characterIndex: 3);
|
||||
|
||||
Assert.Equal(expected, location);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CodeWriter_TracksPosition_WithWriteLine()
|
||||
{
|
||||
// Arrange
|
||||
var writer = new CodeWriter();
|
||||
|
||||
// Act
|
||||
writer.WriteLine("1234");
|
||||
|
||||
// Assert
|
||||
var location = writer.GetCurrentSourceLocation();
|
||||
|
||||
var expected = new SourceLocation(absoluteIndex: 4 + WriterNewLineLength, lineIndex: 1, characterIndex: 0);
|
||||
|
||||
Assert.Equal(expected, location);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData("NewLines")]
|
||||
public void CodeWriter_TracksPosition_WithWriteLine_WithNewLineInContent(string newLine)
|
||||
{
|
||||
// Arrange
|
||||
var writer = new CodeWriter();
|
||||
|
||||
// Act
|
||||
writer.WriteLine("1234" + newLine + "12");
|
||||
|
||||
// Assert
|
||||
var location = writer.GetCurrentSourceLocation();
|
||||
|
||||
var expected = new SourceLocation(
|
||||
absoluteIndex: 6 + newLine.Length + WriterNewLineLength,
|
||||
lineIndex: 2,
|
||||
characterIndex: 0);
|
||||
|
||||
Assert.Equal(expected, location);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData("NewLines")]
|
||||
public void CodeWriter_TracksPosition_WithWrite_WithNewlineInContent(string newLine)
|
||||
{
|
||||
// Arrange
|
||||
var writer = new CodeWriter();
|
||||
|
||||
// Act
|
||||
writer.Write("1234" + newLine + "123" + newLine + "12");
|
||||
|
||||
// Assert
|
||||
var location = writer.GetCurrentSourceLocation();
|
||||
|
||||
var expected = new SourceLocation(
|
||||
absoluteIndex: 9 + newLine.Length + newLine.Length,
|
||||
lineIndex: 2,
|
||||
characterIndex: 2);
|
||||
|
||||
Assert.Equal(expected, location);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CodeWriter_TracksPosition_WithWrite_WithNewlineInContent_RepeatedN()
|
||||
{
|
||||
// Arrange
|
||||
var writer = new CodeWriter();
|
||||
|
||||
// Act
|
||||
writer.Write("1234\n\n123");
|
||||
|
||||
// Assert
|
||||
var location = writer.GetCurrentSourceLocation();
|
||||
|
||||
var expected = new SourceLocation(
|
||||
absoluteIndex: 9,
|
||||
lineIndex: 2,
|
||||
characterIndex: 3);
|
||||
|
||||
Assert.Equal(expected, location);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CodeWriter_TracksPosition_WithWrite_WithMixedNewlineInContent()
|
||||
{
|
||||
// Arrange
|
||||
var writer = new CodeWriter();
|
||||
|
||||
// Act
|
||||
writer.Write("1234\r123\r\n12\n1");
|
||||
|
||||
// Assert
|
||||
var location = writer.GetCurrentSourceLocation();
|
||||
|
||||
var expected = new SourceLocation(
|
||||
absoluteIndex: 14,
|
||||
lineIndex: 3,
|
||||
characterIndex: 1);
|
||||
|
||||
Assert.Equal(expected, location);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CodeWriter_TracksPosition_WithNewline_SplitAcrossWrites()
|
||||
{
|
||||
// Arrange
|
||||
var writer = new CodeWriter();
|
||||
|
||||
// Act
|
||||
writer.Write("1234\r");
|
||||
var location1 = writer.GetCurrentSourceLocation();
|
||||
|
||||
writer.Write("\n");
|
||||
var location2 = writer.GetCurrentSourceLocation();
|
||||
|
||||
// Assert
|
||||
var expected1 = new SourceLocation(absoluteIndex: 5, lineIndex: 1, characterIndex: 0);
|
||||
Assert.Equal(expected1, location1);
|
||||
|
||||
var expected2 = new SourceLocation(absoluteIndex: 6, lineIndex: 1, characterIndex: 0);
|
||||
Assert.Equal(expected2, location2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CodeWriter_TracksPosition_WithTwoNewline_SplitAcrossWrites_R()
|
||||
{
|
||||
// Arrange
|
||||
var writer = new CodeWriter();
|
||||
|
||||
// Act
|
||||
writer.Write("1234\r");
|
||||
var location1 = writer.GetCurrentSourceLocation();
|
||||
|
||||
writer.Write("\r");
|
||||
var location2 = writer.GetCurrentSourceLocation();
|
||||
|
||||
// Assert
|
||||
var expected1 = new SourceLocation(absoluteIndex: 5, lineIndex: 1, characterIndex: 0);
|
||||
Assert.Equal(expected1, location1);
|
||||
|
||||
var expected2 = new SourceLocation(absoluteIndex: 6, lineIndex: 2, characterIndex: 0);
|
||||
Assert.Equal(expected2, location2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CodeWriter_TracksPosition_WithTwoNewline_SplitAcrossWrites_N()
|
||||
{
|
||||
// Arrange
|
||||
var writer = new CodeWriter();
|
||||
|
||||
// Act
|
||||
writer.Write("1234\n");
|
||||
var location1 = writer.GetCurrentSourceLocation();
|
||||
|
||||
writer.Write("\n");
|
||||
var location2 = writer.GetCurrentSourceLocation();
|
||||
|
||||
// Assert
|
||||
var expected1 = new SourceLocation(absoluteIndex: 5, lineIndex: 1, characterIndex: 0);
|
||||
Assert.Equal(expected1, location1);
|
||||
|
||||
var expected2 = new SourceLocation(absoluteIndex: 6, lineIndex: 2, characterIndex: 0);
|
||||
Assert.Equal(expected2, location2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CodeWriter_TracksPosition_WithTwoNewline_SplitAcrossWrites_Reversed()
|
||||
{
|
||||
// Arrange
|
||||
var writer = new CodeWriter();
|
||||
|
||||
// Act
|
||||
writer.Write("1234\n");
|
||||
var location1 = writer.GetCurrentSourceLocation();
|
||||
|
||||
writer.Write("\r");
|
||||
var location2 = writer.GetCurrentSourceLocation();
|
||||
|
||||
// Assert
|
||||
var expected1 = new SourceLocation(absoluteIndex: 5, lineIndex: 1, characterIndex: 0);
|
||||
Assert.Equal(expected1, location1);
|
||||
|
||||
var expected2 = new SourceLocation(absoluteIndex: 6, lineIndex: 2, characterIndex: 0);
|
||||
Assert.Equal(expected2, location2);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CodeWriter_TracksPosition_WithNewline_SplitAcrossWrites_AtBeginning()
|
||||
{
|
||||
// Arrange
|
||||
var writer = new CodeWriter();
|
||||
|
||||
// Act
|
||||
writer.Write("\r");
|
||||
var location1 = writer.GetCurrentSourceLocation();
|
||||
|
||||
writer.Write("\n");
|
||||
var location2 = writer.GetCurrentSourceLocation();
|
||||
|
||||
// Assert
|
||||
var expected1 = new SourceLocation(absoluteIndex: 1, lineIndex: 1, characterIndex: 0);
|
||||
Assert.Equal(expected1, location1);
|
||||
|
||||
var expected2 = new SourceLocation(absoluteIndex: 2, lineIndex: 1, characterIndex: 0);
|
||||
Assert.Equal(expected2, location2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
|
||||
{
|
||||
public class LineMappingTest
|
||||
{
|
||||
[Fact]
|
||||
public void GeneratedCodeMappingsAreEqualIfDataIsEqual()
|
||||
{
|
||||
// Arrange
|
||||
var left = new LineMapping(
|
||||
new MappingLocation(new SourceLocation(1, 2, 3), 4),
|
||||
new MappingLocation(new SourceLocation(5, 6, 7), 8)
|
||||
);
|
||||
var right = new LineMapping(
|
||||
new MappingLocation(new SourceLocation(1, 2, 3), 4),
|
||||
new MappingLocation(new SourceLocation(5, 6, 7), 8)
|
||||
);
|
||||
|
||||
// Assert
|
||||
Assert.True(left == right);
|
||||
Assert.True(left.Equals(right));
|
||||
Assert.True(right.Equals(left));
|
||||
Assert.True(Equals(left, right));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GeneratedCodeMappingsAreNotEqualIfCodeLengthIsNotEqual()
|
||||
{
|
||||
// Arrange
|
||||
var left = new LineMapping(
|
||||
new MappingLocation(new SourceLocation(1, 2, 3), 4),
|
||||
new MappingLocation(new SourceLocation(5, 6, 7), 8)
|
||||
);
|
||||
var right = new LineMapping(
|
||||
new MappingLocation(new SourceLocation(1, 2, 3), 5),
|
||||
new MappingLocation(new SourceLocation(5, 6, 7), 9)
|
||||
);
|
||||
|
||||
// Assert
|
||||
AssertNotEqual(left, right);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GeneratedCodeMappingsAreNotEqualIfStartGeneratedColumnIsNotEqual()
|
||||
{
|
||||
// Arrange
|
||||
var left = new LineMapping(
|
||||
new MappingLocation(new SourceLocation(1, 2, 3), 4),
|
||||
new MappingLocation(new SourceLocation(5, 6, 7), 8)
|
||||
);
|
||||
var right = new LineMapping(
|
||||
new MappingLocation(new SourceLocation(1, 2, 3), 4),
|
||||
new MappingLocation(new SourceLocation(5, 6, 8), 8)
|
||||
);
|
||||
|
||||
// Assert
|
||||
AssertNotEqual(left, right);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GeneratedCodeMappingsAreNotEqualIfStartColumnIsNotEqual()
|
||||
{
|
||||
// Arrange
|
||||
var left = new LineMapping(
|
||||
new MappingLocation(new SourceLocation(1, 2, 3), 4),
|
||||
new MappingLocation(new SourceLocation(5, 6, 8), 8)
|
||||
);
|
||||
var right = new LineMapping(
|
||||
new MappingLocation(new SourceLocation(1, 2, 3), 4),
|
||||
new MappingLocation(new SourceLocation(5, 6, 7), 8)
|
||||
);
|
||||
|
||||
// Assert
|
||||
AssertNotEqual(left, right);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GeneratedCodeMappingsAreNotEqualIfStartLineIsNotEqual()
|
||||
{
|
||||
// Arrange
|
||||
var left = new LineMapping(
|
||||
new MappingLocation(new SourceLocation(1, 2, 3), 4),
|
||||
new MappingLocation(new SourceLocation(5, 5, 7), 8)
|
||||
);
|
||||
var right = new LineMapping(
|
||||
new MappingLocation(new SourceLocation(1, 1, 3), 4),
|
||||
new MappingLocation(new SourceLocation(5, 6, 7), 8)
|
||||
);
|
||||
|
||||
// Assert
|
||||
AssertNotEqual(left, right);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GeneratedCodeMappingsAreNotEqualIfAbsoluteIndexIsNotEqual()
|
||||
{
|
||||
// Arrange
|
||||
var left = new LineMapping(
|
||||
new MappingLocation(new SourceLocation(1, 2, 3), 4),
|
||||
new MappingLocation(new SourceLocation(4, 6, 7), 8)
|
||||
);
|
||||
var right = new LineMapping(
|
||||
new MappingLocation(new SourceLocation(1, 2, 3), 4),
|
||||
new MappingLocation(new SourceLocation(5, 6, 7), 9)
|
||||
);
|
||||
|
||||
// Assert
|
||||
AssertNotEqual(left, right);
|
||||
}
|
||||
|
||||
private void AssertNotEqual(LineMapping left, LineMapping right)
|
||||
{
|
||||
Assert.False(left == right);
|
||||
Assert.False(left.Equals(right));
|
||||
Assert.False(right.Equals(left));
|
||||
Assert.False(Equals(left, right));
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue