// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// We don't process any strings that contain diagnostics in it. That means that we can
// trust that all the string's contents (most importantly, the escape sequences) are well
// formed.
if(token.ContainsDiagnostics)
{
returndefault;
}
varresult=TryConvertToVirtualCharsWorker(token);
#if DEBUG
// Do some invariant checking to make sure we processed the string token the same
// way the C# and VB compilers did.
if(!result.IsDefault)
{
// Ensure that we properly broke up the token into a sequence of characters that
// matches what the compiler did.
varexpectedValueText=token.ValueText;
varactualValueText=result.CreateString();
Debug.Assert(expectedValueText==actualValueText);
if(result.Length>0)
{
varcurrentVC=result[0];
Debug.Assert(currentVC.Span.Start>token.SpanStart,"First span has to start after the start of the string token (including its delimeter)");
Debug.Assert(currentVC.Span.Start==token.SpanStart+1||currentVC.Span.Start==token.SpanStart+2,"First span should start on the second or third char of the string.");
for(vari=1;i<result.Length;i++)
{
varnextVC=result[i];
Debug.Assert(currentVC.Span.End==nextVC.Span.Start,"Virtual character spans have to be touching.");
currentVC=nextVC;
}
varlastVC=result.Last();
Debug.Assert(lastVC.Span.End==token.Span.End-1,"Last span has to end right before the end of the string token (including its trailing delimeter).");
}
}
#endif
returnresult;
}
/// <summary>
/// Helper to convert simple string literals that escape quotes by doubling them. This is
/// how normal VB literals and c# verbatim string literals work.
/// </summary>
/// <param name="startDelimiter">The start characters string. " in VB and @" in C#</param>
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
usingSystem.Collections.Immutable;
usingMicrosoft.CodeAnalysis.Host;
usingMicrosoft.CodeAnalysis.Text;
namespaceMicrosoft.CodeAnalysis.VirtualChars
{
/// <summary>
/// Helper service that takes the raw text of a string token and produces the individual
/// characters that raw string token represents (i.e. with escapes collapsed). The difference
/// between this and the result from token.ValueText is that for each collapsed character
/// returned the original span of text in the original token can be found. i.e. if you had the
/// following in C#:
///
/// "G\u006fo"
///
/// Then you'd get back:
///
/// 'G' -> [0, 1) 'o' -> [1, 7) 'o' -> [7, 1)
///
/// This allows for embedded language processing that can refer back to the users' original code
/// instead of the escaped value we're processing.
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
usingSystem;
usingMicrosoft.CodeAnalysis.Text;
namespaceMicrosoft.CodeAnalysis.VirtualChars
{
/// <summary>
/// The Regex and Json parsers wants to work over an array of characters, however this array of
/// characters is not the same as the array of characters a user types into a string in C# or
/// VB. For example In C# someone may write: @"\z". This should appear to the user the same as
/// if they wrote "\\z" and the same as "\\\u007a". However, as these all have wildly different
/// presentations for the user, there needs to be a way to map back the characters it sees ( '\'
/// and 'z' ) back to the ranges of characters the user wrote.
///
/// VirtualChar serves this purpose. It contains the interpreted value of any language
/// character/character-escape-sequence, as well as the original SourceText span where that
/// interpreted character was created from. This allows the regex and json parsers to both
/// process input from any language uniformly, but then also produce trees and diagnostics that
/// map back properly to the original source text locations that make sense to the user.
/// </summary>
internalstructVirtualChar:IEquatable<VirtualChar>
{
publicreadonlycharChar;
publicreadonlyTextSpanSpan;
publicVirtualChar(char@char,TextSpanspan)
{
if(span.IsEmpty)
{
thrownewArgumentException("Span should not be empty.",nameof(span));
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.