diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateMethodTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateMethodTests.cs index 5cd0940a8192a819d511da9e2dcfa1d849252182..a888fc6a9ac7b101461b23739c356a89d97a3f55 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateMethodTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateMethodTests.cs @@ -7307,5 +7307,61 @@ public void M1() }", parseOptions: TestOptions.Regular); } + + [WorkItem(15315, "https://github.com/dotnet/roslyn/issues/15315")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)] + public async Task TestInferBooleanTypeBasedOnName1() + { + await TestAsync( +@"class Class +{ + void Method(int i) + { + var v = [|IsPrime|](i); + } +}", +@"using System; + +class Class +{ + void Method(int i) + { + var v = IsPrime(i); + } + + private bool IsPrime(int i) + { + throw new NotImplementedException(); + } +}"); + } + + [WorkItem(15315, "https://github.com/dotnet/roslyn/issues/15315")] + [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)] + public async Task TestInferBooleanTypeBasedOnName2() + { + await TestAsync( +@"class Class +{ + void Method(int i) + { + var v = [|Issue|](i); + } +}", +@"using System; + +class Class +{ + void Method(int i) + { + var v = Issue(i); + } + + private object Issue(int i) + { + throw new NotImplementedException(); + } +}"); + } } } \ No newline at end of file diff --git a/src/Features/CSharp/Portable/CodeFixes/Async/CSharpAddAwaitCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/Async/CSharpAddAwaitCodeFixProvider.cs index 82e2076a1c31dd3fed8a3a6aa39f01c17d1f01ff..70c0576aedc2f9178f32e4a6bcab805042a051fd 100644 --- a/src/Features/CSharp/Portable/CodeFixes/Async/CSharpAddAwaitCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/Async/CSharpAddAwaitCodeFixProvider.cs @@ -1,7 +1,5 @@ // Copyright (c) Microsoft. 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.Collections.Immutable; using System.Composition; using System.Linq; @@ -13,6 +11,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.LanguageServices; +using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.Simplification; using Roslyn.Utilities; @@ -175,4 +174,4 @@ private static SyntaxNode ConvertToAwaitExpression(ExpressionSyntax expression) .WithAdditionalAnnotations(Simplifier.Annotation, Formatter.Annotation); } } -} +} \ No newline at end of file diff --git a/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateParameterizedMemberService.cs b/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateParameterizedMemberService.cs index 861e49b66cbd38c6afbae7e8181b9a4fa675aa1f..aaf2c1578a9e841b7b1401ea694e5ca1fe239cca 100644 --- a/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateParameterizedMemberService.cs +++ b/src/Features/CSharp/Portable/GenerateMember/GenerateParameterizedMember/CSharpGenerateParameterizedMemberService.cs @@ -41,8 +41,9 @@ protected override ITypeSymbol DetermineReturnTypeWorker(CancellationToken cance // Defer to the type inferrer to figure out what the return type of this new method // should be. var typeInference = this.Document.Project.LanguageServices.GetService(); - var inferredType = typeInference.InferType(this.Document.SemanticModel, - _invocationExpression, objectAsDefault: true, cancellationToken: cancellationToken); + var inferredType = typeInference.InferType( + this.Document.SemanticModel, _invocationExpression, objectAsDefault: true, + nameOpt: this.State.IdentifierToken.ValueText, cancellationToken: cancellationToken); return inferredType; } diff --git a/src/Features/CSharp/Portable/SignatureHelp/TupleConstructionSignatureHelpProvider.cs b/src/Features/CSharp/Portable/SignatureHelp/TupleConstructionSignatureHelpProvider.cs index b77d7eeb87bd1e1a84c44bff68386d3430097846..7c8413afdb197006c88535344800bcc44a48c9e6 100644 --- a/src/Features/CSharp/Portable/SignatureHelp/TupleConstructionSignatureHelpProvider.cs +++ b/src/Features/CSharp/Portable/SignatureHelp/TupleConstructionSignatureHelpProvider.cs @@ -12,6 +12,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax; using Roslyn.Utilities; using System.Collections.Immutable; +using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.CSharp.SignatureHelp { diff --git a/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.State.cs b/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.State.cs index 97e22a361cce0fd49fe629af60c93d4856d88d7e..1e00a81ae1f2c035d23dafd21ccc94b2a3b5d448 100644 --- a/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.State.cs +++ b/src/Features/Core/Portable/GenerateMember/GenerateVariable/AbstractGenerateVariableService.State.cs @@ -269,9 +269,9 @@ internal bool CanGenerateLocal() { var typeInference = document.Project.LanguageServices.GetService(); var inferredType = typeInference.InferType( - document.SemanticModel, this.SimpleNameOrMemberAccessExpressionOpt, - objectAsDefault: true, - cancellationToken: cancellationToken); + document.SemanticModel, this.SimpleNameOrMemberAccessExpressionOpt, objectAsDefault: true, + nameOpt: this.IdentifierToken.ValueText, cancellationToken: cancellationToken); + var compilation = document.SemanticModel.Compilation; inferredType = inferredType.SpecialType == SpecialType.System_Void ? compilation.ObjectType diff --git a/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateParameterizedMemberService.vb b/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateParameterizedMemberService.vb index ee4934061778b64c2a9269ae33424b0df1d0e63b..b6958b17f2161c909d77a182be440c50d24b3814 100644 --- a/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateParameterizedMemberService.vb +++ b/src/Features/VisualBasic/Portable/GenerateMember/GenerateParameterizedMember/VisualBasicGenerateParameterizedMemberService.vb @@ -47,8 +47,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.GenerateMember.GenerateMethod End Select Dim typeInference = Document.Project.LanguageServices.GetService(Of ITypeInferenceService)() - Dim inferredType = typeInference.InferType(Document.SemanticModel, Me.InvocationExpression, - objectAsDefault:=True, cancellationToken:=cancellationToken) + Dim inferredType = typeInference.InferType( + Document.SemanticModel, Me.InvocationExpression, objectAsDefault:=True, + nameOpt:=Me.State.IdentifierToken.ValueText, cancellationToken:=cancellationToken) Return inferredType End Function diff --git a/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs b/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs index 6cfc5b292a39832662ab2ea857e508e9e999ad25..e7fd219530a15d979ff50da1e8d74bd466e7543b 100644 --- a/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs +++ b/src/Workspaces/CSharp/Portable/LanguageServices/CSharpTypeInferenceService.TypeInferrer.cs @@ -751,8 +751,8 @@ private IEnumerable InferTypeInArrayType(ArrayTypeSyntax arra var currentTypes = InferTypes(arrayType); for (var i = 0; i < arrayType.RankSpecifiers.Count; i++) { - currentTypes = currentTypes.Where(c => c.InferredType is IArrayTypeSymbol) - .Select(c => new TypeInferenceInfo(((IArrayTypeSymbol)c.InferredType).ElementType)); + currentTypes = currentTypes.WhereAsArray(c => c.InferredType is IArrayTypeSymbol) + .SelectAsArray(c => new TypeInferenceInfo(((IArrayTypeSymbol)c.InferredType).ElementType)); } return currentTypes; } diff --git a/src/Workspaces/Core/Portable/LanguageServices/TypeInferenceService/AbstractTypeInferenceService.AbstractTypeInferrer.cs b/src/Workspaces/Core/Portable/LanguageServices/TypeInferenceService/AbstractTypeInferenceService.AbstractTypeInferrer.cs new file mode 100644 index 0000000000000000000000000000000000000000..b24fbfe4b511577e0a3795851fd4aedcea44dd30 --- /dev/null +++ b/src/Workspaces/Core/Portable/LanguageServices/TypeInferenceService/AbstractTypeInferenceService.AbstractTypeInferrer.cs @@ -0,0 +1,95 @@ +// Copyright (c) Microsoft. 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.Collections.Immutable; +using System.Linq; +using System.Threading; +using Roslyn.Utilities; + +namespace Microsoft.CodeAnalysis.LanguageServices.TypeInferenceService +{ + internal partial class AbstractTypeInferenceService : ITypeInferenceService + where TExpressionSyntax : SyntaxNode + { + protected abstract class AbstractTypeInferrer + { + protected readonly CancellationToken CancellationToken; + protected readonly SemanticModel SemanticModel; + protected readonly Func IsUsableTypeFunc; + + private readonly HashSet _seenExpressionInferType = new HashSet(); + private readonly HashSet _seenExpressionGetType = new HashSet(); + + private static readonly Func s_isNotNull = t => t.InferredType != null; + + protected AbstractTypeInferrer(SemanticModel semanticModel, CancellationToken cancellationToken) + { + this.SemanticModel = semanticModel; + this.CancellationToken = cancellationToken; + this.IsUsableTypeFunc = t => t.InferredType != null && !IsUnusableType(t.InferredType); + } + + protected abstract IEnumerable InferTypesWorker_DoNotCallDirectly(int position); + protected abstract IEnumerable InferTypesWorker_DoNotCallDirectly(TExpressionSyntax expression); + protected abstract IEnumerable GetTypes_DoNotCallDirectly(TExpressionSyntax expression, bool objectAsDefault); + protected abstract bool IsUnusableType(ITypeSymbol arg); + + protected Compilation Compilation => SemanticModel.Compilation; + + public ImmutableArray InferTypes(int position) + { + var types = InferTypesWorker_DoNotCallDirectly(position); + return Filter(types); + } + + public ImmutableArray InferTypes(TExpressionSyntax expression, bool filterUnusable = true) + { + if (expression != null) + { + if (_seenExpressionInferType.Add(expression)) + { + var types = InferTypesWorker_DoNotCallDirectly(expression); + return Filter(types, filterUnusable); + } + } + + return ImmutableArray.Empty; + } + + protected IEnumerable GetTypes(TExpressionSyntax expression, bool objectAsDefault = false) + { + if (_seenExpressionGetType.Add(expression)) + { + return GetTypes_DoNotCallDirectly(expression, objectAsDefault); + } + + return SpecializedCollections.EmptyEnumerable(); + } + + private ImmutableArray Filter(IEnumerable types, bool filterUnusable = true) + { + return types.Where(filterUnusable ? IsUsableTypeFunc : s_isNotNull) + .Distinct() + .ToImmutableArray(); + } + + protected IEnumerable ExpandParamsParameter(IParameterSymbol parameterSymbol) + { + var result = new List(); + result.Add(parameterSymbol.Type); + + if (parameterSymbol.IsParams) + { + var arrayTypeSymbol = parameterSymbol.Type as IArrayTypeSymbol; + if (arrayTypeSymbol != null) + { + result.Add(arrayTypeSymbol.ElementType); + } + } + + return result; + } + } + } +} diff --git a/src/Workspaces/Core/Portable/LanguageServices/TypeInferenceService/AbstractTypeInferenceService.cs b/src/Workspaces/Core/Portable/LanguageServices/TypeInferenceService/AbstractTypeInferenceService.cs index e8d06ede7ea78c9c477f0ebd47de5bae346f39ab..b469754a4d7973b53c64219698f3d52934d6f927 100644 --- a/src/Workspaces/Core/Portable/LanguageServices/TypeInferenceService/AbstractTypeInferenceService.cs +++ b/src/Workspaces/Core/Portable/LanguageServices/TypeInferenceService/AbstractTypeInferenceService.cs @@ -2,123 +2,120 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.Linq; using System.Threading; -using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.LanguageServices.TypeInferenceService { - internal abstract class AbstractTypeInferenceService : ITypeInferenceService + internal abstract partial class AbstractTypeInferenceService : ITypeInferenceService where TExpressionSyntax : SyntaxNode { - protected abstract class AbstractTypeInferrer - { - - protected readonly CancellationToken CancellationToken; - protected readonly SemanticModel SemanticModel; - protected readonly Func IsUsableTypeFunc; - - private readonly HashSet _seenExpressionInferType = new HashSet(); - private readonly HashSet _seenExpressionGetType = new HashSet(); - - private static readonly Func s_isNotNull = t => t.InferredType != null; + protected abstract AbstractTypeInferrer CreateTypeInferrer(SemanticModel semanticModel, CancellationToken cancellationToken); - protected AbstractTypeInferrer(SemanticModel semanticModel, CancellationToken cancellationToken) + private ImmutableArray InferTypeBasedOnNameIfEmpty( + SemanticModel semanticModel, ImmutableArray result, string nameOpt) + { + if (result.IsEmpty && nameOpt != null) { - this.SemanticModel = semanticModel; - this.CancellationToken = cancellationToken; - this.IsUsableTypeFunc = t => t.InferredType != null && !IsUnusableType(t.InferredType); + return InferTypeBasedOnName(semanticModel, nameOpt); } - protected abstract IEnumerable InferTypesWorker_DoNotCallDirectly(int position); - protected abstract IEnumerable InferTypesWorker_DoNotCallDirectly(TExpressionSyntax expression); - protected abstract IEnumerable GetTypes_DoNotCallDirectly(TExpressionSyntax expression, bool objectAsDefault); - protected abstract bool IsUnusableType(ITypeSymbol arg); - - protected Compilation Compilation => SemanticModel.Compilation; + return result; + } - public IEnumerable InferTypes(int position) + private ImmutableArray InferTypeBasedOnNameIfEmpty( + SemanticModel semanticModel, ImmutableArray result, string nameOpt) + { + if (result.IsEmpty && nameOpt != null) { - var types = InferTypesWorker_DoNotCallDirectly(position); - return Filter(types); + var types = InferTypeBasedOnName(semanticModel, nameOpt); + return types.SelectAsArray(t => new TypeInferenceInfo(t)); } - public IEnumerable InferTypes(TExpressionSyntax expression, bool filterUnusable = true) - { - if (expression != null) - { - if (_seenExpressionInferType.Add(expression)) - { - var types = InferTypesWorker_DoNotCallDirectly(expression); - return Filter(types, filterUnusable); - } - } + return result; + } - return SpecializedCollections.EmptyEnumerable(); - } + private static readonly ImmutableArray s_booleanPrefixes = + ImmutableArray.Create("Is", "Has", "Contains", "Supports"); + + private ImmutableArray InferTypeBasedOnName( + SemanticModel semanticModel, string name) + { + var matchesBoolean = MatchesBoolean(name); + return matchesBoolean + ? ImmutableArray.Create(semanticModel.Compilation.GetSpecialType(SpecialType.System_Boolean)) + : ImmutableArray.Empty; + } - protected IEnumerable GetTypes(TExpressionSyntax expression, bool objectAsDefault = false) + private static bool MatchesBoolean(string name) + { + foreach (var prefix in s_booleanPrefixes) { - if (_seenExpressionGetType.Add(expression)) + if (Matches(name, prefix)) { - return GetTypes_DoNotCallDirectly(expression, objectAsDefault); + return true; } - - return SpecializedCollections.EmptyEnumerable(); } - private IEnumerable Filter(IEnumerable types, bool filterUnusable = true) - { - return types.Where(filterUnusable ? IsUsableTypeFunc : s_isNotNull) - .Distinct() - .ToImmutableReadOnlyListOrEmpty(); - } + return false; + } - protected IEnumerable ExpandParamsParameter(IParameterSymbol parameterSymbol) + private static bool Matches(string name, string prefix) + { + if (name.StartsWith(prefix)) { - var result = new List(); - result.Add(parameterSymbol.Type); - - if (parameterSymbol.IsParams) + if (name.Length == prefix.Length) { - var arrayTypeSymbol = parameterSymbol.Type as IArrayTypeSymbol; - if (arrayTypeSymbol != null) - { - result.Add(arrayTypeSymbol.ElementType); - } + return true; } - return result; + var nextChar = name[prefix.Length]; + return !char.IsLower(nextChar); } - } - protected abstract AbstractTypeInferrer CreateTypeInferrer(SemanticModel semanticModel, CancellationToken cancellationToken); + return false; + } - public IEnumerable InferTypes(SemanticModel semanticModel, int position, CancellationToken cancellationToken) + public ImmutableArray InferTypes( + SemanticModel semanticModel, int position, + string nameOpt, CancellationToken cancellationToken) { - return CreateTypeInferrer(semanticModel, cancellationToken).InferTypes(position).Select(t => t.InferredType); + var result = CreateTypeInferrer(semanticModel, cancellationToken) + .InferTypes(position) + .Select(t => t.InferredType) + .ToImmutableArray(); + + return InferTypeBasedOnNameIfEmpty(semanticModel, result, nameOpt); } - public IEnumerable InferTypes(SemanticModel semanticModel, SyntaxNode expression, CancellationToken cancellationToken) + + public ImmutableArray InferTypes( + SemanticModel semanticModel, SyntaxNode expression, + string nameOpt, CancellationToken cancellationToken) { - var result = new List(); - var typeInferenceInfo = CreateTypeInferrer(semanticModel, cancellationToken).InferTypes(expression as TExpressionSyntax); - foreach (var info in typeInferenceInfo) - { - result.Add(info.InferredType); - } + var result = CreateTypeInferrer(semanticModel, cancellationToken) + .InferTypes(expression as TExpressionSyntax) + .Select(info => info.InferredType) + .ToImmutableArray(); - return result; + return InferTypeBasedOnNameIfEmpty(semanticModel, result, nameOpt); } - public IEnumerable GetTypeInferenceInfo(SemanticModel semanticModel, int position, CancellationToken cancellationToken) + public ImmutableArray GetTypeInferenceInfo( + SemanticModel semanticModel, int position, + string nameOpt, CancellationToken cancellationToken) { - return CreateTypeInferrer(semanticModel, cancellationToken).InferTypes(position); + var result = CreateTypeInferrer(semanticModel, cancellationToken).InferTypes(position); + return InferTypeBasedOnNameIfEmpty(semanticModel, result, nameOpt); } - public IEnumerable GetTypeInferenceInfo(SemanticModel semanticModel, SyntaxNode expression, CancellationToken cancellationToken) + public ImmutableArray GetTypeInferenceInfo( + SemanticModel semanticModel, SyntaxNode expression, + string nameOpt, CancellationToken cancellationToken) { - return CreateTypeInferrer(semanticModel, cancellationToken).InferTypes(expression as TExpressionSyntax); + var result = CreateTypeInferrer(semanticModel, cancellationToken).InferTypes(expression as TExpressionSyntax); + return InferTypeBasedOnNameIfEmpty(semanticModel, result, nameOpt); } } } diff --git a/src/Workspaces/Core/Portable/LanguageServices/TypeInferenceService/ITypeInferenceService.cs b/src/Workspaces/Core/Portable/LanguageServices/TypeInferenceService/ITypeInferenceService.cs index 44563d155fbeb17f76df75117573446aff6c7822..caca31b14f7c3e18f3ff29db74a1fc07e2ef9ac7 100644 --- a/src/Workspaces/Core/Portable/LanguageServices/TypeInferenceService/ITypeInferenceService.cs +++ b/src/Workspaces/Core/Portable/LanguageServices/TypeInferenceService/ITypeInferenceService.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft. 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; +using System.Collections.Immutable; using System.Threading; using Microsoft.CodeAnalysis.Host; @@ -22,12 +23,11 @@ namespace Microsoft.CodeAnalysis.LanguageServices /// internal interface ITypeInferenceService : ILanguageService { - IEnumerable InferTypes(SemanticModel semanticModel, SyntaxNode expression, CancellationToken cancellationToken); - IEnumerable InferTypes(SemanticModel semanticModel, int position, CancellationToken cancellationToken); + ImmutableArray InferTypes(SemanticModel semanticModel, SyntaxNode expression, string nameOpt, CancellationToken cancellationToken); + ImmutableArray InferTypes(SemanticModel semanticModel, int position, string nameOpt, CancellationToken cancellationToken); - IEnumerable GetTypeInferenceInfo(SemanticModel semanticModel, int position, CancellationToken cancellationToken); - - IEnumerable GetTypeInferenceInfo(SemanticModel semanticModel, SyntaxNode expression, CancellationToken cancellationToken); + ImmutableArray GetTypeInferenceInfo(SemanticModel semanticModel, int position, string nameOpt, CancellationToken cancellationToken); + ImmutableArray GetTypeInferenceInfo(SemanticModel semanticModel, SyntaxNode expression, string nameOpt, CancellationToken cancellationToken); } internal struct TypeInferenceInfo diff --git a/src/Workspaces/Core/Portable/Shared/Extensions/ITypeInferenceServiceExtensions.cs b/src/Workspaces/Core/Portable/Shared/Extensions/ITypeInferenceServiceExtensions.cs index 57cfa5835e49c23f3c8bcbcabf9c486f386c1267..3e7a241c113fd1a5b8efb092a7a8cb6fe93b41ec 100644 --- a/src/Workspaces/Core/Portable/Shared/Extensions/ITypeInferenceServiceExtensions.cs +++ b/src/Workspaces/Core/Portable/Shared/Extensions/ITypeInferenceServiceExtensions.cs @@ -1,5 +1,6 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Collections.Immutable; using System.Linq; using System.Threading; using Microsoft.CodeAnalysis.LanguageServices; @@ -9,6 +10,18 @@ namespace Microsoft.CodeAnalysis.Shared.Extensions { internal static class ITypeInferenceServiceExtensions { + public static ImmutableArray InferTypes(this ITypeInferenceService service, SemanticModel semanticModel, SyntaxNode expression, CancellationToken cancellationToken) + => service.InferTypes(semanticModel, expression, nameOpt: null, cancellationToken: cancellationToken); + + public static ImmutableArray InferTypes(this ITypeInferenceService service, SemanticModel semanticModel, int position, CancellationToken cancellationToken) + => service.InferTypes(semanticModel, position, nameOpt: null, cancellationToken: cancellationToken); + + public static ImmutableArray GetTypeInferenceInfo(this ITypeInferenceService service, SemanticModel semanticModel, int position, CancellationToken cancellationToken) + => service.GetTypeInferenceInfo(semanticModel, position, nameOpt: null, cancellationToken: cancellationToken); + + public static ImmutableArray GetTypeInferenceInfo(this ITypeInferenceService service, SemanticModel semanticModel, SyntaxNode expression, CancellationToken cancellationToken) + => service.GetTypeInferenceInfo(semanticModel, expression, nameOpt: null, cancellationToken: cancellationToken); + public static INamedTypeSymbol InferDelegateType( this ITypeInferenceService typeInferenceService, SemanticModel semanticModel, @@ -20,16 +33,29 @@ internal static class ITypeInferenceServiceExtensions return delegateTypes.WhereNotNull().FirstOrDefault(); } - public static ITypeSymbol InferType(this ITypeInferenceService typeInferenceService, + public static ITypeSymbol InferType( + this ITypeInferenceService typeInferenceService, + SemanticModel semanticModel, + SyntaxNode expression, + bool objectAsDefault, + CancellationToken cancellationToken) + { + return InferType( + typeInferenceService, semanticModel, expression, objectAsDefault, + nameOpt: null, cancellationToken: cancellationToken); + } + + public static ITypeSymbol InferType( + this ITypeInferenceService typeInferenceService, SemanticModel semanticModel, SyntaxNode expression, bool objectAsDefault, + string nameOpt, CancellationToken cancellationToken) { - var types = typeInferenceService.InferTypes(semanticModel, expression, cancellationToken) - .WhereNotNull(); + var types = typeInferenceService.InferTypes(semanticModel, expression, nameOpt, cancellationToken); - if (!types.Any()) + if (types.Length == 0) { return objectAsDefault ? semanticModel.Compilation.ObjectType : null; } @@ -37,16 +63,29 @@ internal static class ITypeInferenceServiceExtensions return types.FirstOrDefault(); } - public static ITypeSymbol InferType(this ITypeInferenceService typeInferenceService, + public static ITypeSymbol InferType( + this ITypeInferenceService typeInferenceService, + SemanticModel semanticModel, + int position, + bool objectAsDefault, + CancellationToken cancellationToken) + { + return InferType( + typeInferenceService, semanticModel, position, objectAsDefault, + nameOpt: null, cancellationToken: cancellationToken); + } + + public static ITypeSymbol InferType( + this ITypeInferenceService typeInferenceService, SemanticModel semanticModel, int position, bool objectAsDefault, + string nameOpt, CancellationToken cancellationToken) { - var types = typeInferenceService.InferTypes(semanticModel, position, cancellationToken) - .WhereNotNull(); + var types = typeInferenceService.InferTypes(semanticModel, position, nameOpt, cancellationToken); - if (!types.Any()) + if (types.Length == 0) { return objectAsDefault ? semanticModel.Compilation.ObjectType : null; } @@ -54,4 +93,4 @@ internal static class ITypeInferenceServiceExtensions return types.FirstOrDefault(); } } -} +} \ No newline at end of file diff --git a/src/Workspaces/Core/Portable/Workspaces.csproj b/src/Workspaces/Core/Portable/Workspaces.csproj index aea3f2d67a13743d51cc2a5ed3c3a41832f06be0..858c0b8eb6fec7465629a779f2e4fe5aa6987e3c 100644 --- a/src/Workspaces/Core/Portable/Workspaces.csproj +++ b/src/Workspaces/Core/Portable/Workspaces.csproj @@ -360,6 +360,7 @@ + diff --git a/src/Workspaces/VisualBasic/Portable/LanguageServices/VisualBasicTypeInferenceService.TypeInferrer.vb b/src/Workspaces/VisualBasic/Portable/LanguageServices/VisualBasicTypeInferenceService.TypeInferrer.vb index 05b5ecb3bfe5b6371fc3af042edc4a684c00e35b..17db38f322e26c33420262e70c963d67fe94fdd2 100644 --- a/src/Workspaces/VisualBasic/Portable/LanguageServices/VisualBasicTypeInferenceService.TypeInferrer.vb +++ b/src/Workspaces/VisualBasic/Portable/LanguageServices/VisualBasicTypeInferenceService.TypeInferrer.vb @@ -352,8 +352,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Dim currentTypes = InferTypes(arrayType) Dim i = 0 While i < arrayType.RankSpecifiers.Count - currentTypes = currentTypes.Where(Function(c) TypeOf c.InferredType Is IArrayTypeSymbol) _ - .Select(Function(c) New TypeInferenceInfo(DirectCast(c.InferredType, IArrayTypeSymbol).ElementType)) + currentTypes = currentTypes.WhereAsArray(Function(c) TypeOf c.InferredType Is IArrayTypeSymbol). + SelectAsArray(Function(c) New TypeInferenceInfo(DirectCast(c.InferredType, IArrayTypeSymbol).ElementType)) i = i + 1 End While