提交 01338f6d 编写于 作者: M Manish Vasani

Move SyntaxFacts service down to CompilerExtensions shared project

Split ISyntaxFactsService into two parts:

1. `ISyntaxFacts`: Pure data interface to query about syntactic facts. This is moved to CompilerExtensions shared project and can be used by analyzers.

2. `ISyntaxFactsService`: Derives from ISyntaxFacts and ILanguageService and is present in the WorkspaceExtensions shared project. This enables Code fixes and Workspaces layer to access the same functionality via a language service, i.e. `GetLanguageService<ISyntaxFactsService>`.

Note that we cannot use a partial declaration for `ISyntaxFactsService` instead of `ISyntaxFacts`. This causes `ISyntaxFacts` to be defined in both the CodeStyle analyzer and CodeStyle fixer assembly (former imports CompilerExtensions and latter imports WorkspaceExtensions), which leads to type conflicts. We also cannot follow the approach taken for `ISyntaxKindsSevice` as it defines the second partial declaration `ISyntaxKindsSevice` which sub-types `ILanguageService` in Workspaces project, leading to the language service not being defined in CodeStyle fixer assembly, which will cause any code fix requesting `GetLanguageService<ISyntaxKindsService>` to fail. The only feasible approach for us to have the functionality available in shared analyzer layer is to split out the pure data query part of the service to a separate type, as done in this PR. I will send a follow-up PR to also split `ISyntaxKindsService` similarly. Hoepfully, these two are the only language services that are commonly used by our analyzers, and we will not require any more such splits.
上级 916b15db
......@@ -8,7 +8,7 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Completion.Providers;
using Microsoft.CodeAnalysis.CSharp.Extensions.ContextQuery;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.Editor.Completion.CompletionProviders;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Shared.Extensions;
......
......@@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Extensions.ContextQuery;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Test.Utilities;
using Xunit;
......
......@@ -7,7 +7,6 @@
using System.Composition;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.ConflictMarkerResolution;
using Microsoft.CodeAnalysis.CSharp.LanguageServices;
namespace Microsoft.CodeAnalysis.CSharp.ConflictMarkerResolution
{
......
......@@ -5,7 +5,6 @@
#nullable enable
using Microsoft.CodeAnalysis.ConvertAnonymousTypeToTuple;
using Microsoft.CodeAnalysis.CSharp.LanguageServices;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
......
......@@ -5,7 +5,6 @@
Imports System.Composition
Imports Microsoft.CodeAnalysis.CodeFixes
Imports Microsoft.CodeAnalysis.ConflictMarkerResolution
Imports Microsoft.CodeAnalysis.VisualBasic.LanguageServices
Namespace Microsoft.CodeAnalysis.VisualBasic.ConflictMarkerResolution
<ExportCodeFixProvider(LanguageNames.VisualBasic), [Shared]>
......
......@@ -5,7 +5,6 @@
Imports Microsoft.CodeAnalysis.ConvertAnonymousTypeToTuple
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Microsoft.CodeAnalysis.VisualBasic.LanguageServices
Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertAnonymousTypeToTuple
<DiagnosticAnalyzer(LanguageNames.VisualBasic)>
......
......@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Shared.Extensions;
......
......@@ -3,10 +3,8 @@
// See the LICENSE file in the project root for more information.
using System.Composition;
using Microsoft.CodeAnalysis.CSharp.LanguageServices;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.LanguageServices;
namespace Microsoft.CodeAnalysis.CSharp
{
......
......@@ -6,7 +6,7 @@
using Microsoft.CodeAnalysis.Host;
namespace Microsoft.CodeAnalysis.LanguageServices
namespace Microsoft.CodeAnalysis
{
/// <summary>
/// Provides a uniform view of SyntaxKinds over C# and VB for constructs they have
......
......@@ -14,8 +14,16 @@
<Compile Include="$(MSBuildThisFileDirectory)CodeStyle\PreferBracesPreference.cs" />
<Compile Include="$(MSBuildThisFileDirectory)CodeStyle\TypeStyle\TypeStyleHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)CodeStyle\TypeStyle\UseVarPreference.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ArgumentSyntaxExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\AssignmentExpressionSyntaxExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\DirectiveSyntaxExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\DirectiveSyntaxExtensions.DirectiveInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\DirectiveSyntaxExtensions.DirectiveSyntaxEqualityComparer.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\DirectiveSyntaxExtensions.DirectiveWalker.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ExpressionSyntaxExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\MemberDeclarationSyntaxExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\MemberDeclarationSyntaxExtensions.DeclarationFinder.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\MemberDeclarationSyntaxExtensions.LocalDeclarationMap.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\MemberDeclarationSyntaxExtensions_GetAttributes.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\OperatorPrecedence.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SimpleNameSyntaxExtensions.cs" />
......@@ -24,7 +32,9 @@
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxKindExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxListExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxNodeExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxNodeExtensions.SingleLineRewriter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxTokenExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxTreeExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxTriviaExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxTriviaListExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\TypeSyntaxExtensions.cs" />
......@@ -61,6 +71,8 @@
<Compile Include="$(MSBuildThisFileDirectory)Formatting\Rules\TokenBasedFormattingRule.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Formatting\Rules\WrappingFormattingRule.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\RemoveUnnecessaryImports\CSharpUnnecessaryImportsProvider.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Services\SyntaxFacts\CSharpDocumentationCommentService.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Services\SyntaxFacts\CSharpSyntaxFacts.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Services\SyntaxFacts\CSharpSyntaxKindsService.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\FormattingRangeHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\TypeStyle\CSharpTypeStyleHelper.cs" />
......
......@@ -136,4 +136,7 @@
<value>'using' directive preferences</value>
<comment>{Locked="using"} "using" is a C# keyword and should not be localized.</comment>
</data>
<data name="Expected_string_or_char_literal" xml:space="preserve">
<value>Expected string or char literal</value>
</data>
</root>
\ No newline at end of file
......@@ -5,11 +5,9 @@
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CSharp.Extensions
{
......
......@@ -4,10 +4,7 @@
using System;
using System.Collections.Generic;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CSharp.Extensions
{
......
......@@ -3,10 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CSharp.Extensions
{
......
......@@ -6,10 +6,7 @@
using System.Diagnostics;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Extensions
......
......@@ -6,10 +6,7 @@
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CSharp.Extensions
{
......
......@@ -4,10 +4,6 @@
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CSharp.Extensions
{
......
......@@ -2,7 +2,14 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Extensions
{
......@@ -94,5 +101,231 @@ public static bool CouldBeKeyword(this SyntaxToken token)
return false;
}
public static bool IsLiteral(this SyntaxToken token)
{
switch (token.Kind())
{
case SyntaxKind.CharacterLiteralToken:
case SyntaxKind.FalseKeyword:
case SyntaxKind.NumericLiteralToken:
case SyntaxKind.StringLiteralToken:
case SyntaxKind.TrueKeyword:
return true;
default:
return false;
}
}
public static bool IntersectsWith(this SyntaxToken token, int position)
{
return token.Span.IntersectsWith(position);
}
public static SyntaxToken GetPreviousTokenIfTouchingWord(this SyntaxToken token, int position)
{
return token.IntersectsWith(position) && IsWord(token)
? token.GetPreviousToken(includeSkipped: true)
: token;
}
private static bool IsWord(SyntaxToken token)
{
return CSharpSyntaxFacts.Instance.IsWord(token);
}
public static SyntaxToken GetNextNonZeroWidthTokenOrEndOfFile(this SyntaxToken token)
{
return token.GetNextTokenOrEndOfFile();
}
/// <summary>
/// Determines whether the given SyntaxToken is the first token on a line in the specified SourceText.
/// </summary>
public static bool IsFirstTokenOnLine(this SyntaxToken token, SourceText text)
{
var previousToken = token.GetPreviousToken(includeSkipped: true, includeDirectives: true, includeDocumentationComments: true);
if (previousToken.Kind() == SyntaxKind.None)
{
return true;
}
var tokenLine = text.Lines.IndexOf(token.SpanStart);
var previousTokenLine = text.Lines.IndexOf(previousToken.SpanStart);
return tokenLine > previousTokenLine;
}
public static bool SpansPreprocessorDirective(this IEnumerable<SyntaxToken> tokens)
=> CSharpSyntaxFacts.Instance.SpansPreprocessorDirective(tokens);
/// <summary>
/// Retrieves all trivia after this token, including it's trailing trivia and
/// the leading trivia of the next token.
/// </summary>
public static IEnumerable<SyntaxTrivia> GetAllTrailingTrivia(this SyntaxToken token)
{
foreach (var trivia in token.TrailingTrivia)
{
yield return trivia;
}
var nextToken = token.GetNextTokenOrEndOfFile(includeZeroWidth: true, includeSkipped: true, includeDirectives: true, includeDocumentationComments: true);
foreach (var trivia in nextToken.LeadingTrivia)
{
yield return trivia;
}
}
public static bool TryParseGenericName(this SyntaxToken genericIdentifier, CancellationToken cancellationToken, out GenericNameSyntax genericName)
{
if (genericIdentifier.GetNextToken(includeSkipped: true).Kind() == SyntaxKind.LessThanToken)
{
var lastToken = genericIdentifier.FindLastTokenOfPartialGenericName();
var syntaxTree = genericIdentifier.SyntaxTree;
var name = SyntaxFactory.ParseName(syntaxTree.GetText(cancellationToken).ToString(TextSpan.FromBounds(genericIdentifier.SpanStart, lastToken.Span.End)));
genericName = name as GenericNameSyntax;
return genericName != null;
}
genericName = null;
return false;
}
/// <summary>
/// Lexically, find the last token that looks like it's part of this generic name.
/// </summary>
/// <param name="genericIdentifier">The "name" of the generic identifier, last token before
/// the "&amp;"</param>
/// <returns>The last token in the name</returns>
/// <remarks>This is related to the code in <see cref="SyntaxTreeExtensions.IsInPartiallyWrittenGeneric(SyntaxTree, int, CancellationToken)"/></remarks>
public static SyntaxToken FindLastTokenOfPartialGenericName(this SyntaxToken genericIdentifier)
{
Contract.ThrowIfFalse(genericIdentifier.Kind() == SyntaxKind.IdentifierToken);
// advance to the "<" token
var token = genericIdentifier.GetNextToken(includeSkipped: true);
Contract.ThrowIfFalse(token.Kind() == SyntaxKind.LessThanToken);
var stack = 0;
do
{
// look forward one token
{
var next = token.GetNextToken(includeSkipped: true);
if (next.Kind() == SyntaxKind.None)
{
return token;
}
token = next;
}
if (token.Kind() == SyntaxKind.GreaterThanToken)
{
if (stack == 0)
{
return token;
}
else
{
stack--;
continue;
}
}
switch (token.Kind())
{
case SyntaxKind.LessThanLessThanToken:
stack++;
goto case SyntaxKind.LessThanToken;
// fall through
case SyntaxKind.LessThanToken:
stack++;
break;
case SyntaxKind.AsteriskToken: // for int*
case SyntaxKind.QuestionToken: // for int?
case SyntaxKind.ColonToken: // for global:: (so we don't dismiss help as you type the first :)
case SyntaxKind.ColonColonToken: // for global::
case SyntaxKind.CloseBracketToken:
case SyntaxKind.OpenBracketToken:
case SyntaxKind.DotToken:
case SyntaxKind.IdentifierToken:
case SyntaxKind.CommaToken:
break;
// If we see a member declaration keyword, we know we've gone too far
case SyntaxKind.ClassKeyword:
case SyntaxKind.StructKeyword:
case SyntaxKind.InterfaceKeyword:
case SyntaxKind.DelegateKeyword:
case SyntaxKind.EnumKeyword:
case SyntaxKind.PrivateKeyword:
case SyntaxKind.PublicKeyword:
case SyntaxKind.InternalKeyword:
case SyntaxKind.ProtectedKeyword:
case SyntaxKind.VoidKeyword:
return token.GetPreviousToken(includeSkipped: true);
default:
// user might have typed "in" on the way to typing "int"
// don't want to disregard this genericname because of that
if (SyntaxFacts.IsKeywordKind(token.Kind()))
{
break;
}
// anything else and we're sunk. Go back to the token before.
return token.GetPreviousToken(includeSkipped: true);
}
}
while (true);
}
public static bool IsRegularStringLiteral(this SyntaxToken token)
{
return token.Kind() == SyntaxKind.StringLiteralToken && !token.IsVerbatimStringLiteral();
}
public static bool IsValidAttributeTarget(this SyntaxToken token)
{
switch (token.Kind())
{
case SyntaxKind.AssemblyKeyword:
case SyntaxKind.ModuleKeyword:
case SyntaxKind.FieldKeyword:
case SyntaxKind.EventKeyword:
case SyntaxKind.MethodKeyword:
case SyntaxKind.ParamKeyword:
case SyntaxKind.PropertyKeyword:
case SyntaxKind.ReturnKeyword:
case SyntaxKind.TypeKeyword:
return true;
default:
return false;
}
}
public static SyntaxToken WithCommentsFrom(
this SyntaxToken token,
IEnumerable<SyntaxTrivia> leadingTrivia,
IEnumerable<SyntaxTrivia> trailingTrivia,
params SyntaxNodeOrToken[] trailingNodesOrTokens)
=> token
.WithPrependedLeadingTrivia(leadingTrivia)
.WithTrailingTrivia((
token.TrailingTrivia.Concat(SyntaxNodeOrTokenExtensions.GetTrivia(trailingNodesOrTokens).Concat(trailingTrivia))).FilterComments(addElasticMarker: false));
public static SyntaxToken KeepCommentsAndAddElasticMarkers(this SyntaxToken token)
=> token
.WithTrailingTrivia(token.TrailingTrivia.FilterComments(addElasticMarker: true))
.WithLeadingTrivia(token.LeadingTrivia.FilterComments(addElasticMarker: true));
}
}
......@@ -7,8 +7,6 @@
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Extensions.ContextQuery;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Shared.Extensions;
......@@ -166,6 +164,43 @@ public static bool IsPrimaryFunctionExpressionContext(this SyntaxTree syntaxTree
syntaxTree.IsSizeOfExpressionContext(position, tokenOnLeftOfPosition);
}
public static bool IsTypeOfExpressionContext(this SyntaxTree syntaxTree, int position, SyntaxToken tokenOnLeftOfPosition)
{
var token = tokenOnLeftOfPosition.GetPreviousTokenIfTouchingWord(position);
if (token.IsKind(SyntaxKind.OpenParenToken) && token.Parent.IsKind(SyntaxKind.TypeOfExpression))
{
return true;
}
return false;
}
public static bool IsDefaultExpressionContext(this SyntaxTree syntaxTree, int position, SyntaxToken tokenOnLeftOfPosition)
{
var token = tokenOnLeftOfPosition.GetPreviousTokenIfTouchingWord(position);
if (token.IsKind(SyntaxKind.OpenParenToken) && token.Parent.IsKind(SyntaxKind.DefaultExpression))
{
return true;
}
return false;
}
public static bool IsSizeOfExpressionContext(
this SyntaxTree syntaxTree, int position, SyntaxToken tokenOnLeftOfPosition)
{
var token = tokenOnLeftOfPosition.GetPreviousTokenIfTouchingWord(position);
if (token.IsKind(SyntaxKind.OpenParenToken) && token.Parent.IsKind(SyntaxKind.SizeOfExpression))
{
return true;
}
return false;
}
public static bool IsAfterKeyword(this SyntaxTree syntaxTree, int position, SyntaxKind kind, CancellationToken cancellationToken)
{
var token = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken);
......@@ -375,7 +410,7 @@ private static bool AtEndOfIncompleteStringOrCharLiteral(SyntaxToken token, int
{
if (!token.IsKind(SyntaxKind.StringLiteralToken, SyntaxKind.CharacterLiteralToken))
{
throw new ArgumentException(CSharpWorkspaceExtensionsResources.Expected_string_or_char_literal, nameof(token));
throw new ArgumentException(CSharpCompilerExtensionsResources.Expected_string_or_char_literal, nameof(token));
}
var startLength = 1;
......@@ -736,5 +771,154 @@ private static bool IsFullyWrittenGeneric(SyntaxToken token, SyntaxToken lessTha
return token.Parent is GenericNameSyntax genericName && genericName.TypeArgumentList != null &&
genericName.TypeArgumentList.LessThanToken == lessThanToken && !genericName.TypeArgumentList.GreaterThanToken.IsMissing;
}
public static bool IsPreProcessorDirectiveContext(this SyntaxTree syntaxTree, int position, SyntaxToken preProcessorTokenOnLeftOfPosition, CancellationToken cancellationToken)
{
var token = preProcessorTokenOnLeftOfPosition;
var directive = token.GetAncestor<DirectiveTriviaSyntax>();
// Directives contain the EOL, so if the position is within the full span of the
// directive, then it is on that line, the only exception is if the directive is on the
// last line, the position at the end if technically not contained by the directive but
// its also not on a new line, so it should be considered part of the preprocessor
// context.
if (directive == null)
{
return false;
}
return
directive.FullSpan.Contains(position) ||
directive.FullSpan.End == syntaxTree.GetRoot(cancellationToken).FullSpan.End;
}
public static bool IsPreProcessorDirectiveContext(this SyntaxTree syntaxTree, int position, CancellationToken cancellationToken)
{
var leftToken = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken, includeDirectives: true);
return syntaxTree.IsPreProcessorDirectiveContext(position, leftToken, cancellationToken);
}
public static bool IsPreProcessorKeywordContext(this SyntaxTree syntaxTree, int position, CancellationToken cancellationToken)
{
return IsPreProcessorKeywordContext(
syntaxTree, position,
syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken, includeDirectives: true));
}
public static bool IsPreProcessorKeywordContext(this SyntaxTree syntaxTree, int position, SyntaxToken preProcessorTokenOnLeftOfPosition)
{
// cases:
// #|
// #d|
// # |
// # d|
// note: comments are not allowed between the # and item.
var token = preProcessorTokenOnLeftOfPosition;
token = token.GetPreviousTokenIfTouchingWord(position);
if (token.IsKind(SyntaxKind.HashToken))
{
return true;
}
return false;
}
/// <summary>
/// Are you possibly typing a tuple type or expression?
/// This is used to suppress colon as a completion trigger (so that you can type element names).
/// This is also used to recommend some keywords (like var).
/// </summary>
public static bool IsPossibleTupleContext(this SyntaxTree syntaxTree, SyntaxToken leftToken, int position)
{
leftToken = leftToken.GetPreviousTokenIfTouchingWord(position);
// ($$
// (a, $$
if (IsPossibleTupleOpenParenOrComma(leftToken))
{
return true;
}
// ((a, b) $$
// (..., (a, b) $$
if (leftToken.IsKind(SyntaxKind.CloseParenToken))
{
if (leftToken.Parent.IsKind(
SyntaxKind.ParenthesizedExpression,
SyntaxKind.TupleExpression,
SyntaxKind.TupleType))
{
var possibleCommaOrParen = FindTokenOnLeftOfNode(leftToken.Parent);
if (IsPossibleTupleOpenParenOrComma(possibleCommaOrParen))
{
return true;
}
}
}
// (a $$
// (..., b $$
if (leftToken.IsKind(SyntaxKind.IdentifierToken))
{
var possibleCommaOrParen = FindTokenOnLeftOfNode(leftToken.Parent);
if (IsPossibleTupleOpenParenOrComma(possibleCommaOrParen))
{
return true;
}
}
// (a.b $$
// (..., a.b $$
if (leftToken.IsKind(SyntaxKind.IdentifierToken) &&
leftToken.Parent.IsKind(SyntaxKind.IdentifierName) &&
leftToken.Parent.IsParentKind(SyntaxKind.QualifiedName, SyntaxKind.SimpleMemberAccessExpression))
{
var possibleCommaOrParen = FindTokenOnLeftOfNode(leftToken.Parent.Parent);
if (IsPossibleTupleOpenParenOrComma(possibleCommaOrParen))
{
return true;
}
}
return false;
}
public static bool IsPossibleTupleOpenParenOrComma(this SyntaxToken possibleCommaOrParen)
{
if (!possibleCommaOrParen.IsKind(SyntaxKind.OpenParenToken, SyntaxKind.CommaToken))
{
return false;
}
if (possibleCommaOrParen.Parent.IsKind(
SyntaxKind.ParenthesizedExpression,
SyntaxKind.TupleExpression,
SyntaxKind.TupleType,
SyntaxKind.CastExpression))
{
return true;
}
// in script
if (possibleCommaOrParen.Parent.IsKind(SyntaxKind.ParameterList) &&
possibleCommaOrParen.Parent.IsParentKind(SyntaxKind.ParenthesizedLambdaExpression))
{
var parenthesizedLambda = (ParenthesizedLambdaExpressionSyntax)possibleCommaOrParen.Parent.Parent;
if (parenthesizedLambda.ArrowToken.IsMissing)
{
return true;
}
}
return false;
}
private static SyntaxToken FindTokenOnLeftOfNode(SyntaxNode node)
{
return node.FindTokenOnLeftOfPosition(node.SpanStart);
}
}
}
......@@ -20,7 +20,7 @@ internal class CSharpDocumentationCommentService : AbstractDocumentationCommentS
XmlTextAttributeSyntax>
{
private CSharpDocumentationCommentService()
: base(CSharpSyntaxFactsService.Instance)
: base(CSharpSyntaxFacts.Instance)
{
}
......
......@@ -4,9 +4,7 @@
#nullable enable
using Microsoft.CodeAnalysis.LanguageServices;
namespace Microsoft.CodeAnalysis.CSharp.LanguageServices
namespace Microsoft.CodeAnalysis.CSharp
{
internal sealed class CSharpSyntaxKindsService : ISyntaxKindsService
{
......
......@@ -7,6 +7,11 @@
<target state="new">Code-block preferences</target>
<note />
</trans-unit>
<trans-unit id="Expected_string_or_char_literal">
<source>Expected string or char literal</source>
<target state="new">Expected string or char literal</target>
<note />
</trans-unit>
<trans-unit id="Expression_bodied_members">
<source>Expression-bodied members</source>
<target state="new">Expression-bodied members</target>
......
......@@ -7,6 +7,11 @@
<target state="new">Code-block preferences</target>
<note />
</trans-unit>
<trans-unit id="Expected_string_or_char_literal">
<source>Expected string or char literal</source>
<target state="new">Expected string or char literal</target>
<note />
</trans-unit>
<trans-unit id="Expression_bodied_members">
<source>Expression-bodied members</source>
<target state="new">Expression-bodied members</target>
......
......@@ -7,6 +7,11 @@
<target state="new">Code-block preferences</target>
<note />
</trans-unit>
<trans-unit id="Expected_string_or_char_literal">
<source>Expected string or char literal</source>
<target state="new">Expected string or char literal</target>
<note />
</trans-unit>
<trans-unit id="Expression_bodied_members">
<source>Expression-bodied members</source>
<target state="new">Expression-bodied members</target>
......
......@@ -7,6 +7,11 @@
<target state="new">Code-block preferences</target>
<note />
</trans-unit>
<trans-unit id="Expected_string_or_char_literal">
<source>Expected string or char literal</source>
<target state="new">Expected string or char literal</target>
<note />
</trans-unit>
<trans-unit id="Expression_bodied_members">
<source>Expression-bodied members</source>
<target state="new">Expression-bodied members</target>
......
......@@ -7,6 +7,11 @@
<target state="new">Code-block preferences</target>
<note />
</trans-unit>
<trans-unit id="Expected_string_or_char_literal">
<source>Expected string or char literal</source>
<target state="new">Expected string or char literal</target>
<note />
</trans-unit>
<trans-unit id="Expression_bodied_members">
<source>Expression-bodied members</source>
<target state="new">Expression-bodied members</target>
......
......@@ -7,6 +7,11 @@
<target state="new">Code-block preferences</target>
<note />
</trans-unit>
<trans-unit id="Expected_string_or_char_literal">
<source>Expected string or char literal</source>
<target state="new">Expected string or char literal</target>
<note />
</trans-unit>
<trans-unit id="Expression_bodied_members">
<source>Expression-bodied members</source>
<target state="new">Expression-bodied members</target>
......
......@@ -7,6 +7,11 @@
<target state="new">Code-block preferences</target>
<note />
</trans-unit>
<trans-unit id="Expected_string_or_char_literal">
<source>Expected string or char literal</source>
<target state="new">Expected string or char literal</target>
<note />
</trans-unit>
<trans-unit id="Expression_bodied_members">
<source>Expression-bodied members</source>
<target state="new">Expression-bodied members</target>
......
......@@ -7,6 +7,11 @@
<target state="new">Code-block preferences</target>
<note />
</trans-unit>
<trans-unit id="Expected_string_or_char_literal">
<source>Expected string or char literal</source>
<target state="new">Expected string or char literal</target>
<note />
</trans-unit>
<trans-unit id="Expression_bodied_members">
<source>Expression-bodied members</source>
<target state="new">Expression-bodied members</target>
......
......@@ -7,6 +7,11 @@
<target state="new">Code-block preferences</target>
<note />
</trans-unit>
<trans-unit id="Expected_string_or_char_literal">
<source>Expected string or char literal</source>
<target state="new">Expected string or char literal</target>
<note />
</trans-unit>
<trans-unit id="Expression_bodied_members">
<source>Expression-bodied members</source>
<target state="new">Expression-bodied members</target>
......
......@@ -7,6 +7,11 @@
<target state="new">Code-block preferences</target>
<note />
</trans-unit>
<trans-unit id="Expected_string_or_char_literal">
<source>Expected string or char literal</source>
<target state="new">Expected string or char literal</target>
<note />
</trans-unit>
<trans-unit id="Expression_bodied_members">
<source>Expression-bodied members</source>
<target state="new">Expression-bodied members</target>
......
......@@ -7,6 +7,11 @@
<target state="new">Code-block preferences</target>
<note />
</trans-unit>
<trans-unit id="Expected_string_or_char_literal">
<source>Expected string or char literal</source>
<target state="new">Expected string or char literal</target>
<note />
</trans-unit>
<trans-unit id="Expression_bodied_members">
<source>Expression-bodied members</source>
<target state="new">Expression-bodied members</target>
......
......@@ -7,6 +7,11 @@
<target state="new">Code-block preferences</target>
<note />
</trans-unit>
<trans-unit id="Expected_string_or_char_literal">
<source>Expected string or char literal</source>
<target state="new">Expected string or char literal</target>
<note />
</trans-unit>
<trans-unit id="Expression_bodied_members">
<source>Expression-bodied members</source>
<target state="new">Expression-bodied members</target>
......
......@@ -7,6 +7,11 @@
<target state="new">Code-block preferences</target>
<note />
</trans-unit>
<trans-unit id="Expected_string_or_char_literal">
<source>Expected string or char literal</source>
<target state="new">Expected string or char literal</target>
<note />
</trans-unit>
<trans-unit id="Expression_bodied_members">
<source>Expression-bodied members</source>
<target state="new">Expression-bodied members</target>
......
......@@ -270,6 +270,12 @@
<Compile Include="$(MSBuildThisFileDirectory)Log\Logger.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Log\Logger.LogBlock.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Log\LogMessage.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Services\SyntaxFacts\AbstractDocumentationCommentService.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Services\SyntaxFacts\AbstractSyntaxFacts.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Services\SyntaxFacts\ExternalSourceInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Services\SyntaxFacts\IDocumentationCommentService.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Services\SyntaxFacts\ISyntaxFacts.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Services\SyntaxFacts\ISyntaxFactsExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Services\SyntaxFacts\ISyntaxKindsService.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Simplification\AliasAnnotation.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Simplification\DoNotAddImportsAnnotation.cs" />
......@@ -301,6 +307,12 @@
<Compile Include="$(MSBuildThisFileDirectory)Utilities\IReadOnlyListExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\IReferenceCountedDisposable.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\LazyInitialization.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\Matcher.ChoiceMatcher.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\Matcher.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\Matcher.RepeatMatcher.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\Matcher.SequenceMatcher.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\Matcher.SingleMatcher.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\Matcher`1.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\NonReentrantLock.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\PooledBuilderExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\PredefinedOperator.cs" />
......@@ -316,7 +328,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxNodeOrTokenExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxTokenExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxTokenListExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxTreeExtensions_SharedWithCodeStyle.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxTreeExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxTriviaExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxTriviaListExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\TextLineExtensions.cs" />
......
......@@ -152,7 +152,7 @@ public static bool IsChildNode<TParent>(this SyntaxNode node, Func<TParent, Synt
/// <summary>
/// Returns true if this node is found underneath the specified child in the given parent.
/// </summary>
public static bool IsFoundUnder<TParent>(this SyntaxNode node, Func<TParent, SyntaxNode> childGetter)
public static bool IsFoundUnder<TParent>(this SyntaxNode node, Func<TParent, SyntaxNode?> childGetter)
where TParent : SyntaxNode
{
var ancestor = node.GetAncestor<TParent>();
......
......@@ -5,9 +5,9 @@
#nullable enable
using System;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
......@@ -15,6 +15,24 @@ namespace Microsoft.CodeAnalysis.Shared.Extensions
{
internal static partial class SyntaxTreeExtensions
{
public static bool OverlapsHiddenPosition([NotNullWhen(returnValue: true)] this SyntaxTree? tree, TextSpan span, CancellationToken cancellationToken)
{
if (tree == null)
{
return false;
}
var text = tree.GetText(cancellationToken);
return text.OverlapsHiddenPosition(span, (position, cancellationToken2) =>
{
// implements the ASP.NET IsHidden rule
var lineVisibility = tree.GetLineVisibility(position, cancellationToken2);
return lineVisibility == LineVisibility.Hidden || lineVisibility == LineVisibility.BeforeFirstLineDirective;
},
cancellationToken);
}
public static bool IsScript(this SyntaxTree syntaxTree)
{
return syntaxTree.Options.Kind != SourceCodeKind.Regular;
......@@ -27,7 +45,7 @@ public static bool IsScript(this SyntaxTree syntaxTree)
public static Task<SyntaxToken> GetTouchingWordAsync(
this SyntaxTree syntaxTree,
int position,
ISyntaxFactsService syntaxFacts,
ISyntaxFacts syntaxFacts,
CancellationToken cancellationToken,
bool findInsideTrivia = false)
{
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Threading;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.Shared.Extensions
{
internal static partial class SyntaxTreeExtensions
{
public static bool OverlapsHiddenPosition(this SyntaxTree tree, TextSpan span, CancellationToken cancellationToken)
{
if (tree == null)
{
return false;
}
var text = tree.GetText(cancellationToken);
return text.OverlapsHiddenPosition(span, (position, cancellationToken2) =>
{
// implements the ASP.NET IsHidden rule
var lineVisibility = tree.GetLineVisibility(position, cancellationToken2);
return lineVisibility == LineVisibility.Hidden || lineVisibility == LineVisibility.BeforeFirstLineDirective;
},
cancellationToken);
}
}
}
......@@ -34,9 +34,9 @@ internal abstract class AbstractDocumentationCommentService<
{
public const string Ellipsis = "...";
private readonly ISyntaxFactsService _syntaxFacts;
private readonly ISyntaxFacts _syntaxFacts;
protected AbstractDocumentationCommentService(ISyntaxFactsService syntaxFacts)
protected AbstractDocumentationCommentService(ISyntaxFacts syntaxFacts)
{
_syntaxFacts = syntaxFacts;
}
......
......@@ -17,7 +17,7 @@
namespace Microsoft.CodeAnalysis.LanguageServices
{
internal abstract class AbstractSyntaxFactsService
internal abstract class AbstractSyntaxFacts
{
private readonly static ObjectPool<Stack<(SyntaxNodeOrToken nodeOrToken, bool leading, bool trailing)>> s_stackPool
= SharedPools.Default<Stack<(SyntaxNodeOrToken nodeOrToken, bool leading, bool trailing)>>();
......@@ -39,7 +39,7 @@ internal abstract class AbstractSyntaxFactsService
// <start-of-file> (whitespace* (single-comment|multi-comment) whitespace* newline)+ blankLine*
private readonly Matcher<SyntaxTrivia> _fileBannerMatcher;
protected AbstractSyntaxFactsService()
protected AbstractSyntaxFacts()
{
var whitespace = Matcher.Repeat(
Matcher.Single<SyntaxTrivia>(IsWhitespaceTrivia, "\\b"));
......
......@@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.
namespace Microsoft.CodeAnalysis.LanguageServices
namespace Microsoft.CodeAnalysis
{
internal struct ExternalSourceInfo
{
......
......@@ -4,7 +4,7 @@
#nullable enable
namespace Microsoft.CodeAnalysis.LanguageServices
namespace Microsoft.CodeAnalysis
{
/// <summary>
/// Provides a uniform view of SyntaxKinds over C# and VB for constructs they have
......
......@@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CodeAnalysis.LanguageServices
namespace Microsoft.CodeAnalysis
{
internal enum PredefinedOperator
{
......
......@@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Microsoft.CodeAnalysis.LanguageServices
namespace Microsoft.CodeAnalysis
{
internal enum PredefinedType
{
......
' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.
Imports System.Runtime.CompilerServices
Imports System.Threading
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions
Partial Friend Module ExpressionSyntaxExtensions
<Extension()>
Public Function WalkUpParentheses(expression As ExpressionSyntax) As ExpressionSyntax
While expression.IsParentKind(SyntaxKind.ParenthesizedExpression)
expression = DirectCast(expression.Parent, ExpressionSyntax)
End While
Return expression
End Function
<Extension()>
Public Function WalkDownParentheses(expression As ExpressionSyntax) As ExpressionSyntax
While expression.IsKind(SyntaxKind.ParenthesizedExpression)
expression = DirectCast(expression, ParenthesizedExpressionSyntax).Expression
End While
Return expression
End Function
<Extension()>
Public Function IsLeftSideOfDot(expression As ExpressionSyntax) As Boolean
If expression Is Nothing Then
Return False
End If
Return _
(expression.IsParentKind(SyntaxKind.QualifiedName) AndAlso DirectCast(expression.Parent, QualifiedNameSyntax).Left Is expression) OrElse
(expression.IsParentKind(SyntaxKind.SimpleMemberAccessExpression) AndAlso DirectCast(expression.Parent, MemberAccessExpressionSyntax).Expression Is expression)
End Function
<Extension()>
Public Function IsNewOnRightSideOfDotOrBang(expression As ExpressionSyntax) As Boolean
Dim identifierName = TryCast(expression, IdentifierNameSyntax)
If identifierName Is Nothing Then
Return False
End If
If String.Compare(identifierName.Identifier.ToString(), "New", StringComparison.OrdinalIgnoreCase) <> 0 Then
Return False
End If
Return identifierName.IsRightSideOfDotOrBang()
End Function
<Extension()>
Public Function IsMemberAccessExpressionName(expression As ExpressionSyntax) As Boolean
Return expression.IsParentKind(SyntaxKind.SimpleMemberAccessExpression) AndAlso
DirectCast(expression.Parent, MemberAccessExpressionSyntax).Name Is expression
End Function
<Extension()>
Public Function IsAnyMemberAccessExpressionName(expression As ExpressionSyntax) As Boolean
Return expression IsNot Nothing AndAlso
TypeOf expression.Parent Is MemberAccessExpressionSyntax AndAlso
DirectCast(expression.Parent, MemberAccessExpressionSyntax).Name Is expression
End Function
<Extension()>
Public Function IsRightSideOfDotOrBang(expression As ExpressionSyntax) As Boolean
Return expression.IsAnyMemberAccessExpressionName() OrElse expression.IsRightSideOfQualifiedName()
End Function
<Extension()>
Public Function IsRightSideOfDot(expression As ExpressionSyntax) As Boolean
Return expression.IsMemberAccessExpressionName() OrElse expression.IsRightSideOfQualifiedName()
End Function
<Extension()>
Public Function IsRightSideOfQualifiedName(expression As ExpressionSyntax) As Boolean
Return expression.IsParentKind(SyntaxKind.QualifiedName) AndAlso
DirectCast(expression.Parent, QualifiedNameSyntax).Right Is expression
End Function
<Extension()>
Public Function IsLeftSideOfQualifiedName(expression As ExpressionSyntax) As Boolean
Return expression.IsParentKind(SyntaxKind.QualifiedName) AndAlso
DirectCast(expression.Parent, QualifiedNameSyntax).Left Is expression
End Function
<Extension()>
Public Function IsAnyLiteralExpression(expression As ExpressionSyntax) As Boolean
Return expression.IsKind(SyntaxKind.CharacterLiteralExpression) OrElse
expression.IsKind(SyntaxKind.DateLiteralExpression) OrElse
expression.IsKind(SyntaxKind.FalseLiteralExpression) OrElse
expression.IsKind(SyntaxKind.NothingLiteralExpression) OrElse
expression.IsKind(SyntaxKind.NumericLiteralExpression) OrElse
expression.IsKind(SyntaxKind.StringLiteralExpression) OrElse
expression.IsKind(SyntaxKind.TrueLiteralExpression)
End Function
<Extension()>
Public Function DetermineType(expression As ExpressionSyntax,
semanticModel As SemanticModel,
cancellationToken As CancellationToken) As ITypeSymbol
' If a parameter appears to have a void return type, then just use 'object' instead.
If expression IsNot Nothing Then
Dim typeInfo = semanticModel.GetTypeInfo(expression, cancellationToken)
Dim symbolInfo = semanticModel.GetSymbolInfo(expression, cancellationToken)
If typeInfo.Type IsNot Nothing AndAlso typeInfo.Type.SpecialType = SpecialType.System_Void Then
Return semanticModel.Compilation.ObjectType
End If
Dim symbol = If(typeInfo.Type, symbolInfo.GetAnySymbol())
If symbol IsNot Nothing Then
Return symbol.ConvertToType(semanticModel.Compilation)
End If
If TypeOf expression Is CollectionInitializerSyntax Then
Dim collectionInitializer = DirectCast(expression, CollectionInitializerSyntax)
Return DetermineType(collectionInitializer, semanticModel, cancellationToken)
End If
End If
Return semanticModel.Compilation.ObjectType
End Function
<Extension()>
Private Function DetermineType(collectionInitializer As CollectionInitializerSyntax,
semanticModel As SemanticModel,
cancellationToken As CancellationToken) As ITypeSymbol
Dim rank = 1
While collectionInitializer.Initializers.Count > 0 AndAlso
collectionInitializer.Initializers(0).Kind = SyntaxKind.CollectionInitializer
rank += 1
collectionInitializer = DirectCast(collectionInitializer.Initializers(0), CollectionInitializerSyntax)
End While
Dim type = collectionInitializer.Initializers.FirstOrDefault().DetermineType(semanticModel, cancellationToken)
Return semanticModel.Compilation.CreateArrayTypeSymbol(type, rank)
End Function
End Module
End Namespace
' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.
Imports System.Runtime.CompilerServices
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions
Partial Friend Module MemberAccessExpressionSyntaxExtensions
<Extension()>
Public Function IsConstructorInitializer(memberAccess As MemberAccessExpressionSyntax) As Boolean
Return memberAccess.IsThisConstructorInitializer() OrElse memberAccess.IsBaseConstructorInitializer()
End Function
<Extension()>
Public Function IsThisConstructorInitializer(memberAccess As MemberAccessExpressionSyntax) As Boolean
If memberAccess IsNot Nothing Then
If IsFirstStatementInConstructor(memberAccess) Then
If memberAccess.Expression.IsKind(SyntaxKind.MeExpression) OrElse
memberAccess.Expression.IsKind(SyntaxKind.MyClassExpression) Then
If memberAccess.Name.IsKind(SyntaxKind.IdentifierName) Then
Return memberAccess.Name.Identifier.HasMatchingText(SyntaxKind.NewKeyword)
End If
End If
End If
End If
Return False
End Function
<Extension()>
Public Function IsBaseConstructorInitializer(memberAccess As MemberAccessExpressionSyntax) As Boolean
If memberAccess IsNot Nothing Then
If IsFirstStatementInConstructor(memberAccess) Then
If memberAccess.Expression.IsKind(SyntaxKind.MyBaseExpression) Then
If memberAccess.Name.IsKind(SyntaxKind.IdentifierName) Then
Return memberAccess.Name.Identifier.HasMatchingText(SyntaxKind.NewKeyword)
End If
End If
End If
End If
Return False
End Function
Private Function IsFirstStatementInConstructor(memberAccess As MemberAccessExpressionSyntax) As Boolean
Dim isCall As Boolean
Dim statement As SyntaxNode
If TypeOf memberAccess.Parent Is InvocationExpressionSyntax Then
statement = memberAccess.Parent.Parent
isCall = statement IsNot Nothing AndAlso (statement.Kind = SyntaxKind.CallStatement OrElse statement.Kind = SyntaxKind.ExpressionStatement)
Else
statement = memberAccess.Parent
isCall = statement.IsKind(SyntaxKind.CallStatement)
End If
If isCall Then
Return statement.IsParentKind(SyntaxKind.ConstructorBlock) AndAlso
DirectCast(statement.Parent, ConstructorBlockSyntax).Statements.First() Is statement
End If
Return False
End Function
<Extension>
Public Function GetExpressionOfMemberAccessExpression(
memberAccessExpression As MemberAccessExpressionSyntax,
Optional allowImplicitTarget As Boolean = False) As ExpressionSyntax
If memberAccessExpression Is Nothing Then
Return Nothing
End If
If memberAccessExpression.Expression IsNot Nothing Then
Return memberAccessExpression.Expression
End If
' we have a member access expression with a null expression, this may be one of the
' following forms:
'
' 1) new With { .a = 1, .b = .a <-- .a refers to the anonymous type
' 2) With obj : .m <-- .m refers to the obj type
' 3) new T() With { .a = 1, .b = .a <-- 'a refers to the T type
If allowImplicitTarget Then
Dim conditional = memberAccessExpression.GetCorrespondingConditionalAccessExpression()
If conditional IsNot Nothing Then
If conditional.Expression Is Nothing Then
' No expression, maybe we're in a with block
Dim withBlock = conditional.GetAncestor(Of WithBlockSyntax)()
If withBlock IsNot Nothing Then
Return withBlock.WithStatement.Expression
End If
End If
Return conditional.Expression
End If
Dim current As SyntaxNode = memberAccessExpression
While current IsNot Nothing
If TypeOf current Is AnonymousObjectCreationExpressionSyntax Then
Return DirectCast(current, ExpressionSyntax)
ElseIf TypeOf current Is WithBlockSyntax Then
Dim withBlock = DirectCast(current, WithBlockSyntax)
If memberAccessExpression IsNot withBlock.WithStatement.Expression Then
Return withBlock.WithStatement.Expression
End If
ElseIf TypeOf current Is ObjectMemberInitializerSyntax AndAlso
TypeOf current.Parent Is ObjectCreationExpressionSyntax Then
Return DirectCast(current.Parent, ExpressionSyntax)
End If
current = current.Parent
End While
End If
Return Nothing
End Function
End Module
End Namespace
......@@ -237,7 +237,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions
<Extension()>
Public Function SpansPreprocessorDirective(Of TSyntaxNode As SyntaxNode)(list As IEnumerable(Of TSyntaxNode)) As Boolean
Return VisualBasicSyntaxFactsService.Instance.SpansPreprocessorDirective(list)
Return VisualBasicSyntaxFacts.Instance.SpansPreprocessorDirective(list)
End Function
<Extension()>
......@@ -356,7 +356,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions
''' </summary>
<Extension()>
Public Function ContainsInterleavedDirective(node As SyntaxNode, cancellationToken As CancellationToken) As Boolean
Return VisualBasicSyntaxFactsService.Instance.ContainsInterleavedDirective(node, cancellationToken)
Return VisualBasicSyntaxFacts.Instance.ContainsInterleavedDirective(node, cancellationToken)
End Function
<Extension>
......@@ -421,32 +421,32 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions
<Extension()>
Public Function GetLeadingBlankLines(Of TSyntaxNode As SyntaxNode)(node As TSyntaxNode) As ImmutableArray(Of SyntaxTrivia)
Return VisualBasicSyntaxFactsService.Instance.GetLeadingBlankLines(node)
Return VisualBasicSyntaxFacts.Instance.GetLeadingBlankLines(node)
End Function
<Extension()>
Public Function GetNodeWithoutLeadingBlankLines(Of TSyntaxNode As SyntaxNode)(node As TSyntaxNode) As TSyntaxNode
Return VisualBasicSyntaxFactsService.Instance.GetNodeWithoutLeadingBlankLines(node)
Return VisualBasicSyntaxFacts.Instance.GetNodeWithoutLeadingBlankLines(node)
End Function
<Extension()>
Public Function GetNodeWithoutLeadingBlankLines(Of TSyntaxNode As SyntaxNode)(node As TSyntaxNode, ByRef strippedTrivia As ImmutableArray(Of SyntaxTrivia)) As TSyntaxNode
Return VisualBasicSyntaxFactsService.Instance.GetNodeWithoutLeadingBlankLines(node, strippedTrivia)
Return VisualBasicSyntaxFacts.Instance.GetNodeWithoutLeadingBlankLines(node, strippedTrivia)
End Function
<Extension()>
Public Function GetLeadingBannerAndPreprocessorDirectives(Of TSyntaxNode As SyntaxNode)(node As TSyntaxNode) As ImmutableArray(Of SyntaxTrivia)
Return VisualBasicSyntaxFactsService.Instance.GetLeadingBannerAndPreprocessorDirectives(node)
Return VisualBasicSyntaxFacts.Instance.GetLeadingBannerAndPreprocessorDirectives(node)
End Function
<Extension()>
Public Function GetNodeWithoutLeadingBannerAndPreprocessorDirectives(Of TSyntaxNode As SyntaxNode)(node As TSyntaxNode) As TSyntaxNode
Return VisualBasicSyntaxFactsService.Instance.GetNodeWithoutLeadingBannerAndPreprocessorDirectives(node)
Return VisualBasicSyntaxFacts.Instance.GetNodeWithoutLeadingBannerAndPreprocessorDirectives(node)
End Function
<Extension()>
Public Function GetNodeWithoutLeadingBannerAndPreprocessorDirectives(Of TSyntaxNode As SyntaxNode)(node As TSyntaxNode, ByRef strippedTrivia As ImmutableArray(Of SyntaxTrivia)) As TSyntaxNode
Return VisualBasicSyntaxFactsService.Instance.GetNodeWithoutLeadingBannerAndPreprocessorDirectives(node, strippedTrivia)
Return VisualBasicSyntaxFacts.Instance.GetNodeWithoutLeadingBannerAndPreprocessorDirectives(node, strippedTrivia)
End Function
''' <summary>
......
......@@ -4,12 +4,21 @@
Imports System.Runtime.CompilerServices
Imports System.Threading
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.LanguageServices
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions
Partial Friend Module SyntaxTokenExtensions
<Extension()>
Public Function IsKind(token As SyntaxToken, kind1 As SyntaxKind, kind2 As SyntaxKind) As Boolean
Return token.Kind = kind1 OrElse
token.Kind = kind2
End Function
<Extension()>
Public Function IsKind(token As SyntaxToken, ParamArray kinds As SyntaxKind()) As Boolean
Return kinds.Contains(token.Kind)
End Function
<Extension()>
Public Function IsKindOrHasMatchingText(token As SyntaxToken, kind As SyntaxKind) As Boolean
Return token.Kind = kind OrElse
......@@ -197,7 +206,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions
<Extension()>
Public Function SpansPreprocessorDirective(tokens As IEnumerable(Of SyntaxToken)) As Boolean
Return VisualBasicSyntaxFactsService.Instance.SpansPreprocessorDirective(tokens)
Return VisualBasicSyntaxFacts.Instance.SpansPreprocessorDirective(tokens)
End Function
<Extension()>
......@@ -209,7 +218,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions
<Extension>
Public Function IsWord(token As SyntaxToken) As Boolean
Return VisualBasicSyntaxFactsService.Instance.IsWord(token)
Return VisualBasicSyntaxFacts.Instance.IsWord(token)
End Function
<Extension()>
......
' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.
Imports System.Runtime.CompilerServices
Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions
Partial Friend Module SyntaxTokenExtensions
<Extension()>
Public Function IsKind(token As SyntaxToken, kind1 As SyntaxKind, kind2 As SyntaxKind) As Boolean
Return token.Kind = kind1 OrElse
token.Kind = kind2
End Function
<Extension()>
Public Function IsKind(token As SyntaxToken, ParamArray kinds As SyntaxKind()) As Boolean
Return kinds.Contains(token.Kind)
End Function
End Module
End Namespace
......@@ -5,13 +5,111 @@
Imports System.Collections.Immutable
Imports System.Runtime.CompilerServices
Imports System.Threading
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.PooledObjects
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Roslyn.Utilities
Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions
Partial Friend Module SyntaxTreeExtensions
''' <summary>
''' check whether given token is the last token of a statement that ends with end of line trivia or an elastic trivia
''' </summary>
<Extension()>
Public Function IsLastTokenOfStatementWithEndOfLine(token As SyntaxToken) As Boolean
If Not token.HasTrailingTrivia Then
Return False
End If
' easy case
Dim trailing = token.TrailingTrivia
If trailing.Count = 1 Then
Dim trivia = trailing.First()
If trivia.Kind = SyntaxKind.EndOfLineTrivia Then
Return token.IsLastTokenOfStatement()
End If
Return False
End If
' little bit more expansive case
For Each trivia In trailing
If trivia.Kind = SyntaxKind.EndOfLineTrivia Then
Return token.IsLastTokenOfStatement()
End If
Next
Return False
End Function
''' <summary>
''' check whether given token is the last token of a statement by walking up the spine
''' </summary>
<Extension()>
Public Function IsLastTokenOfStatement(token As SyntaxToken, Optional checkColonTrivia As Boolean = False) As Boolean
Dim current = token.Parent
While current IsNot Nothing
If current.FullSpan.End <> token.FullSpan.End Then
Return False
End If
If TypeOf current Is StatementSyntax Then
Dim colonTrivia = GetTrailingColonTrivia(DirectCast(current, StatementSyntax))
If Not PartOfSingleLineLambda(current) AndAlso Not PartOfMultilineLambdaFooter(current) Then
If checkColonTrivia Then
If colonTrivia Is Nothing Then
Return current.GetLastToken(includeZeroWidth:=True) = token
End If
Else
Return current.GetLastToken(includeZeroWidth:=True) = token
End If
End If
End If
current = current.Parent
End While
Return False
End Function
<PerformanceSensitive("https://github.com/dotnet/roslyn/issues/30819", AllowImplicitBoxing:=False)>
Private Function GetTrailingColonTrivia(statement As StatementSyntax) As SyntaxTrivia?
If Not statement.HasTrailingTrivia Then
Return Nothing
End If
Return statement _
.GetTrailingTrivia() _
.FirstOrNull(Function(t) t.Kind = SyntaxKind.ColonTrivia)
End Function
Private Function PartOfSingleLineLambda(node As SyntaxNode) As Boolean
While node IsNot Nothing
If TypeOf node Is MultiLineLambdaExpressionSyntax Then Return False
If TypeOf node Is SingleLineLambdaExpressionSyntax Then Return True
node = node.Parent
End While
Return False
End Function
<PerformanceSensitive("https://github.com/dotnet/roslyn/issues/30819", AllowCaptures:=False)>
Private Function PartOfMultilineLambdaFooter(node As SyntaxNode) As Boolean
For Each n In node.AncestorsAndSelf
Dim multiLine = TryCast(n, MultiLineLambdaExpressionSyntax)
If multiLine Is Nothing Then
Continue For
End If
If (multiLine.EndSubOrFunctionStatement Is node) Then
Return True
End If
Next
Return False
End Function
''' <summary>
''' Finds the token being touched by this position. Unlike the normal FindTrivia helper, this helper will prefer
''' trivia to the left rather than the right if the position is on the border.
......@@ -339,5 +437,23 @@ recurse:
Public Function GetFirstEnclosingStatement(node As SyntaxNode) As StatementSyntax
Return node.AncestorsAndSelf().Where(Function(n) TypeOf n Is StatementSyntax).OfType(Of StatementSyntax).FirstOrDefault()
End Function
' Tuple literals aren't recognized by the parser until there is a comma
' So a parenthesized expression is a possible tuple context too
<Extension>
Friend Function IsPossibleTupleContext(syntaxTree As SyntaxTree,
tokenOnLeftOfPosition As SyntaxToken,
position As Integer) As Boolean
tokenOnLeftOfPosition = tokenOnLeftOfPosition.GetPreviousTokenIfTouchingWord(position)
If tokenOnLeftOfPosition.IsKind(SyntaxKind.OpenParenToken) Then
Return tokenOnLeftOfPosition.Parent.IsKind(SyntaxKind.ParenthesizedExpression,
SyntaxKind.TupleExpression, SyntaxKind.TupleType)
End If
Return tokenOnLeftOfPosition.IsKind(SyntaxKind.CommaToken) AndAlso
tokenOnLeftOfPosition.Parent.IsKind(SyntaxKind.TupleExpression, SyntaxKind.TupleType)
End Function
End Module
End Namespace
' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.
Imports System.Runtime.CompilerServices
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Roslyn.Utilities
Namespace Microsoft.CodeAnalysis.VisualBasic.Extensions
Partial Friend Module SyntaxTreeExtensions
''' <summary>
''' check whether given token is the last token of a statement that ends with end of line trivia or an elastic trivia
''' </summary>
<Extension()>
Public Function IsLastTokenOfStatementWithEndOfLine(token As SyntaxToken) As Boolean
If Not token.HasTrailingTrivia Then
Return False
End If
' easy case
Dim trailing = token.TrailingTrivia
If trailing.Count = 1 Then
Dim trivia = trailing.First()
If trivia.Kind = SyntaxKind.EndOfLineTrivia Then
Return token.IsLastTokenOfStatement()
End If
Return False
End If
' little bit more expansive case
For Each trivia In trailing
If trivia.Kind = SyntaxKind.EndOfLineTrivia Then
Return token.IsLastTokenOfStatement()
End If
Next
Return False
End Function
''' <summary>
''' check whether given token is the last token of a statement by walking up the spine
''' </summary>
<Extension()>
Public Function IsLastTokenOfStatement(token As SyntaxToken, Optional checkColonTrivia As Boolean = False) As Boolean
Dim current = token.Parent
While current IsNot Nothing
If current.FullSpan.End <> token.FullSpan.End Then
Return False
End If
If TypeOf current Is StatementSyntax Then
Dim colonTrivia = GetTrailingColonTrivia(DirectCast(current, StatementSyntax))
If Not PartOfSingleLineLambda(current) AndAlso Not PartOfMultilineLambdaFooter(current) Then
If checkColonTrivia Then
If colonTrivia Is Nothing Then
Return current.GetLastToken(includeZeroWidth:=True) = token
End If
Else
Return current.GetLastToken(includeZeroWidth:=True) = token
End If
End If
End If
current = current.Parent
End While
Return False
End Function
<PerformanceSensitive("https://github.com/dotnet/roslyn/issues/30819", AllowImplicitBoxing:=False)>
Private Function GetTrailingColonTrivia(statement As StatementSyntax) As SyntaxTrivia?
If Not statement.HasTrailingTrivia Then
Return Nothing
End If
Return statement _
.GetTrailingTrivia() _
.FirstOrNull(Function(t) t.Kind = SyntaxKind.ColonTrivia)
End Function
Private Function PartOfSingleLineLambda(node As SyntaxNode) As Boolean
While node IsNot Nothing
If TypeOf node Is MultiLineLambdaExpressionSyntax Then Return False
If TypeOf node Is SingleLineLambdaExpressionSyntax Then Return True
node = node.Parent
End While
Return False
End Function
<PerformanceSensitive("https://github.com/dotnet/roslyn/issues/30819", AllowCaptures:=False)>
Private Function PartOfMultilineLambdaFooter(node As SyntaxNode) As Boolean
For Each n In node.AncestorsAndSelf
Dim multiLine = TryCast(n, MultiLineLambdaExpressionSyntax)
If multiLine Is Nothing Then
Continue For
End If
If (multiLine.EndSubOrFunctionStatement Is node) Then
Return True
End If
Next
Return False
End Function
End Module
End Namespace
......@@ -22,7 +22,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Public Shared ReadOnly Instance As New VisualBasicDocumentationCommentService()
Private Sub New()
MyBase.New(VisualBasicSyntaxFactsService.Instance)
MyBase.New(VisualBasicSyntaxFacts.Instance)
End Sub
Protected Overrides Function GetIdentifier(xmlName As XmlNameAttributeSyntax) As SyntaxToken
......
......@@ -2,9 +2,7 @@
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.
Imports Microsoft.CodeAnalysis.LanguageServices
Namespace Microsoft.CodeAnalysis.VisualBasic.LanguageServices
Namespace Microsoft.CodeAnalysis.VisualBasic
Friend NotInheritable Class VisualBasicSyntaxKindsService
Implements ISyntaxKindsService
......
......@@ -9,11 +9,22 @@
<Import_RootNamespace>Microsoft.CodeAnalysis.VisualBasic.Shared</Import_RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxTokenExtensions_SharedWithCodeStyle.vb" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxTreeExtensions_SharedWithCodeStyle.vb" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ArgumentSyntaxExtensions.vb" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\DirectiveSyntaxExtensions.vb" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ExpressionSyntaxExtensions.vb" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\MemberAccessExpressionSyntaxExtensions.vb" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SingleLineRewriter.vb" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\StatementSyntaxExtensions.vb" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxNodeExtensions.vb" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxTokenExtensions.vb" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxTreeExtensions.vb" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxTriviaExtensions.vb" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\RemoveUnnecessaryImports\VisualBasicUnnecessaryImportsProvider.vb" />
<Compile Include="$(MSBuildThisFileDirectory)Services\SyntaxFacts\VisualBasicDocumentationCommentService.vb" />
<Compile Include="$(MSBuildThisFileDirectory)Services\SyntaxFacts\VisualBasicSyntaxFacts.vb" />
<Compile Include="$(MSBuildThisFileDirectory)Services\SyntaxFacts\VisualBasicSyntaxKindsService.vb" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\DirectiveSyntaxEqualityComparer.vb" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\DirectiveWalker.vb" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)VisualBasicCompilerExtensionsResources.resx" GenerateSource="true" Link="VisualBasicCompilerExtensionsResources.resx" />
......
......@@ -9,7 +9,6 @@
<Import_RootNamespace>Microsoft.CodeAnalysis.CSharp.Shared</Import_RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ArgumentSyntaxExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ArrowExpressionClauseSyntaxExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\AttributeArgumentSyntaxExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\BaseArgumentListSyntaxExtensions.cs" />
......@@ -22,10 +21,6 @@
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ContextQuery\SyntaxTokenExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ContextQuery\SyntaxTreeExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ConversionExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\DirectiveSyntaxExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\DirectiveSyntaxExtensions.DirectiveInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\DirectiveSyntaxExtensions.DirectiveSyntaxEqualityComparer.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\DirectiveSyntaxExtensions.DirectiveWalker.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\DocumentationCommentExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ExpressionSyntaxExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ForEachStatementSyntaxExtensions.cs" />
......@@ -34,9 +29,6 @@
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ITypeSymbolExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ITypeSymbolExtensions.ExpressionSyntaxGeneratorVisitor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ITypeSymbolExtensions.TypeSyntaxGeneratorVisitor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\MemberDeclarationSyntaxExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\MemberDeclarationSyntaxExtensions.DeclarationFinder.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\MemberDeclarationSyntaxExtensions.LocalDeclarationMap.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\NamespaceDeclarationSyntaxExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\NameSyntaxExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ParenthesizedExpressionSyntaxExtensions.cs" />
......@@ -45,17 +37,13 @@
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SeparatedSyntaxListExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\StringExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxNodeExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxNodeExtensions.SingleLineRewriter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxTokenExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxTokenListExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxTreeExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\TypeDeclarationSyntaxExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\TypeSyntaxExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\UsingDirectiveSyntaxExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\VariableDeclaratorExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)LanguageServices\CSharpAddImportsService.cs" />
<Compile Include="$(MSBuildThisFileDirectory)LanguageServices\CSharpCommandLineParserService.cs" />
<Compile Include="$(MSBuildThisFileDirectory)LanguageServices\CSharpDocumentationCommentService.cs" />
<Compile Include="$(MSBuildThisFileDirectory)LanguageServices\CSharpPrecedenceService.cs" />
<Compile Include="$(MSBuildThisFileDirectory)LanguageServices\CSharpSemanticFactsServiceFactory.cs" />
<Compile Include="$(MSBuildThisFileDirectory)LanguageServices\CSharpSymbolDeclarationService.cs" />
......
......@@ -117,7 +117,8 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Expected_string_or_char_literal" xml:space="preserve">
<value>Expected string or char literal</value>
<data name="EmptyResource" xml:space="preserve">
<value>Remove this value when another is added.</value>
<comment>https://github.com/Microsoft/msbuild/issues/1661</comment>
</data>
</root>
\ No newline at end of file
......@@ -3,11 +3,8 @@
// See the LICENSE file in the project root for more information.
using System;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Simplification;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.CSharp.Extensions
{
......
......@@ -2,10 +2,10 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="cs" original="../CSharpWorkspaceExtensionsResources.resx">
<body>
<trans-unit id="Expected_string_or_char_literal">
<source>Expected string or char literal</source>
<target state="new">Expected string or char literal</target>
<note />
<trans-unit id="EmptyResource">
<source>Remove this value when another is added.</source>
<target state="new">Remove this value when another is added.</target>
<note>https://github.com/Microsoft/msbuild/issues/1661</note>
</trans-unit>
</body>
</file>
......
......@@ -2,10 +2,10 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="de" original="../CSharpWorkspaceExtensionsResources.resx">
<body>
<trans-unit id="Expected_string_or_char_literal">
<source>Expected string or char literal</source>
<target state="new">Expected string or char literal</target>
<note />
<trans-unit id="EmptyResource">
<source>Remove this value when another is added.</source>
<target state="new">Remove this value when another is added.</target>
<note>https://github.com/Microsoft/msbuild/issues/1661</note>
</trans-unit>
</body>
</file>
......
......@@ -2,10 +2,10 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="es" original="../CSharpWorkspaceExtensionsResources.resx">
<body>
<trans-unit id="Expected_string_or_char_literal">
<source>Expected string or char literal</source>
<target state="new">Expected string or char literal</target>
<note />
<trans-unit id="EmptyResource">
<source>Remove this value when another is added.</source>
<target state="new">Remove this value when another is added.</target>
<note>https://github.com/Microsoft/msbuild/issues/1661</note>
</trans-unit>
</body>
</file>
......
......@@ -2,10 +2,10 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="fr" original="../CSharpWorkspaceExtensionsResources.resx">
<body>
<trans-unit id="Expected_string_or_char_literal">
<source>Expected string or char literal</source>
<target state="new">Expected string or char literal</target>
<note />
<trans-unit id="EmptyResource">
<source>Remove this value when another is added.</source>
<target state="new">Remove this value when another is added.</target>
<note>https://github.com/Microsoft/msbuild/issues/1661</note>
</trans-unit>
</body>
</file>
......
......@@ -2,10 +2,10 @@
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
<file datatype="xml" source-language="en" target-language="it" original="../CSharpWorkspaceExtensionsResources.resx">
<body>
<trans-unit id="Expected_string_or_char_literal">
<source>Expected string or char literal</source>
<target state="new">Expected string or char literal</target>
<note />
<trans-unit id="EmptyResource">
<source>Remove this value when another is added.</source>
<target state="new">Remove this value when another is added.</target>
<note>https://github.com/Microsoft/msbuild/issues/1661</note>
</trans-unit>
</body>
</file>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册