提交 b49f841b 编写于 作者: D dustincampbell

IDE Support for C# using static (changeset 1383492)

上级 3164ac98
......@@ -2,11 +2,9 @@
using System.Linq;
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;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Extensions.ContextQuery
......@@ -20,6 +18,36 @@ public static bool IsUsingOrExternKeyword(this SyntaxToken token)
token.CSharpKind() == SyntaxKind.ExternKeyword;
}
public static bool IsUsingKeywordInUsingDirective(this SyntaxToken token)
{
if (token.IsKind(SyntaxKind.UsingKeyword))
{
var usingDirective = token.GetAncestor<UsingDirectiveSyntax>();
if (usingDirective != null &&
usingDirective.UsingKeyword == token)
{
return true;
}
}
return false;
}
public static bool IsStaticKeywordInUsingDirective(this SyntaxToken token)
{
if (token.IsKind(SyntaxKind.StaticKeyword))
{
var usingDirective = token.GetAncestor<UsingDirectiveSyntax>();
if (usingDirective != null &&
usingDirective.StaticKeyword == token)
{
return true;
}
}
return false;
}
public static bool IsBeginningOfStatementContext(this SyntaxToken token)
{
// cases:
......
......@@ -506,6 +506,12 @@ public static bool IsAttributeNameContext(this SyntaxTree syntaxTree, int positi
return true;
}
// using static | is never a type declaration context
if (token.IsStaticKeywordInUsingDirective())
{
return false;
}
var modifierTokens = contextOpt != null
? contextOpt.PrecedingModifiers
: syntaxTree.GetPrecedingModifiers(position, leftToken, cancellationToken);
......@@ -577,6 +583,12 @@ public static bool IsAttributeNameContext(this SyntaxTree syntaxTree, int positi
}
}
// using static |
if (token.IsStaticKeywordInUsingDirective())
{
return true;
}
// if it is not using directive location, most of places where
// type can appear, namespace can appear as well
return syntaxTree.IsTypeContext(position, cancellationToken, semanticModelOpt);
......@@ -625,6 +637,7 @@ public static bool IsDefinitelyNotTypeContext(this SyntaxTree syntaxTree, int po
syntaxTree.IsStatementContext(position, tokenOnLeftOfPosition, cancellationToken) ||
syntaxTree.IsTypeParameterConstraintContext(position, tokenOnLeftOfPosition, cancellationToken) ||
syntaxTree.IsUsingAliasContext(position, cancellationToken) ||
syntaxTree.IsUsingStaticContext(position, cancellationToken) ||
syntaxTree.IsGlobalMemberDeclarationContext(position, SyntaxKindSet.AllGlobalMemberModifiers, cancellationToken) ||
syntaxTree.IsMemberDeclarationContext(
position,
......@@ -671,6 +684,16 @@ public static bool IsUsingAliasContext(this SyntaxTree syntaxTree, int position,
return false;
}
public static bool IsUsingStaticContext(this SyntaxTree syntaxTree, int position, CancellationToken cancellationToken)
{
// using static |
var token = syntaxTree.FindTokenOnLeftOfPosition(position, cancellationToken);
token = token.GetPreviousTokenIfTouchingWord(position);
return token.IsStaticKeywordInUsingDirective();
}
public static bool IsTypeArgumentOfConstraintClause(
this SyntaxTree syntaxTree, int position, CancellationToken cancellationToken)
{
......
......@@ -220,6 +220,16 @@ internal class CSharpRecommendationService : AbstractRecommendationService
{
var symbols = context.SemanticModel.LookupNamespacesAndTypes(context.LeftToken.SpanStart);
if (context.TargetToken.IsUsingKeywordInUsingDirective())
{
return symbols.Where(s => s.IsNamespace());
}
if (context.TargetToken.IsStaticKeywordInUsingDirective())
{
return symbols.Where(s => !s.IsDelegateType() && !s.IsInterfaceType());
}
return symbols;
}
......@@ -248,6 +258,9 @@ internal class CSharpRecommendationService : AbstractRecommendationService
? context.SemanticModel.LookupStaticMembers(context.LeftToken.SpanStart)
: context.SemanticModel.LookupSymbols(context.LeftToken.SpanStart);
// Filter out any extension methods that might be imported by a using static directive.
symbols = symbols.Where(symbol => !symbol.IsExtensionMethod());
// The symbols may include local variables that are declared later in the method and
// should not be included in the completion list, so remove those. Filter them away,
// unless we're in the debugger, where we show all locals in scope.
......@@ -301,15 +314,16 @@ internal class CSharpRecommendationService : AbstractRecommendationService
// Filter the types when in a using directive, but not an alias.
//
// Cases:
// using | -- Show namespaces (and static types in C# v6)
// using | -- Show namespaces
// using A.| -- Show namespaces
// using static | -- Show namespace and types
// using A = B.| -- Show namespace and types
var usingDirective = name.GetAncestorOrThis<UsingDirectiveSyntax>();
if (usingDirective != null && usingDirective.Alias == null)
{
// Do we also have inclusion of static types?
if (((CSharpParseOptions)context.SyntaxTree.Options).LanguageVersion >= LanguageVersion.CSharp6)
if (usingDirective.StaticKeyword.IsKind(SyntaxKind.StaticKeyword))
{
symbols = symbols.Where(s => s.IsNamespace() || s.IsStaticType()).ToList();
return symbols.Where(s => !s.IsDelegateType() && !s.IsInterfaceType());
}
else
{
......
// Copyright (c) Microsoft Open Technologies, Inc. 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.Globalization;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Microsoft.CodeAnalysis.CSharp.Extensions;
namespace Microsoft.CodeAnalysis.CSharp.Utilities
{
......@@ -32,8 +28,8 @@ private static bool IsSystem(string s)
public int Compare(SyntaxToken x, SyntaxToken y)
{
if (specialCaseSystem &&
x.GetPreviousToken(includeSkipped: true).CSharpKind() == SyntaxKind.UsingKeyword &&
y.GetPreviousToken(includeSkipped: true).CSharpKind() == SyntaxKind.UsingKeyword)
x.GetPreviousToken(includeSkipped: true).IsKind(SyntaxKind.UsingKeyword, SyntaxKind.StaticKeyword) &&
y.GetPreviousToken(includeSkipped: true).IsKind(SyntaxKind.UsingKeyword, SyntaxKind.StaticKeyword))
{
var token1IsSystem = IsSystem(x.ValueText);
var token2IsSystem = IsSystem(y.ValueText);
......
// Copyright (c) Microsoft Open Technologies, Inc. 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 Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Utilities
......@@ -48,13 +44,21 @@ public int Compare(SyntaxNode directive1, SyntaxNode directive2)
var directive1IsExtern = extern1 != null;
var directive2IsExtern = extern2 != null;
var directive1IsNamespace = using1 != null && using1.Alias == null;
var directive2IsNamespace = using2 != null && using2.Alias == null;
var directive1IsNamespace = using1 != null && using1.Alias == null && !using1.StaticKeyword.IsKind(SyntaxKind.StaticKeyword);
var directive2IsNamespace = using2 != null && using2.Alias == null && !using2.StaticKeyword.IsKind(SyntaxKind.StaticKeyword);
var directive1IsUsingStatic = using1 != null && using1.StaticKeyword.IsKind(SyntaxKind.StaticKeyword);
var directive2IsUsingStatic = using2 != null && using2.StaticKeyword.IsKind(SyntaxKind.StaticKeyword);
var directive1IsAlias = using1 != null && using1.Alias != null;
var directive2IsAlias = using2 != null && using2.Alias != null;
// different types of usings get broken up into groups.
// * externs
// * usings
// * using statics
// * aliases
if (directive1IsExtern && !directive2IsExtern)
{
return -1;
......@@ -71,6 +75,14 @@ public int Compare(SyntaxNode directive1, SyntaxNode directive2)
{
return 1;
}
else if (directive1IsUsingStatic && !directive2IsUsingStatic)
{
return -1;
}
else if (directive2IsUsingStatic && !directive1IsUsingStatic)
{
return 1;
}
else if (directive1IsAlias && !directive2IsAlias)
{
return -1;
......
......@@ -162,6 +162,13 @@ public static bool IsModuleType(this ISymbol symbol)
((ITypeSymbol)symbol).TypeKind == TypeKind.Module;
}
public static bool IsInterfaceType(this ISymbol symbol)
{
return
symbol is ITypeSymbol &&
((ITypeSymbol)symbol).TypeKind == TypeKind.Interface;
}
public static bool IsArrayType(this ISymbol symbol)
{
return
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册