private void DetermineFieldType(
                SemanticDocument document,
                CancellationToken cancellationToken)
            {
                var typeInference = document.Project.LanguageServices.GetService <ITypeInferenceService>();
                var inferredType  = typeInference.InferType(
                    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
                    : inferredType;

                if (this.IsInConditionalAccessExpression)
                {
                    inferredType = inferredType.RemoveNullableIfPresent();
                }

                if (inferredType.IsDelegateType() && !inferredType.CanBeReferencedByName)
                {
                    var namedDelegateType = inferredType.GetDelegateType(compilation)?.DelegateInvokeMethod?.ConvertToType(compilation);
                    if (namedDelegateType != null)
                    {
                        inferredType = namedDelegateType;
                    }
                }

                // Substitute 'object' for all captured method type parameters.  Note: we may need to
                // do this for things like anonymous types, as well as captured type parameters that
                // aren't in scope in the destination type.
                var capturedMethodTypeParameters = inferredType.GetReferencedMethodTypeParameters();
                var mapping = capturedMethodTypeParameters.ToDictionary(tp => tp,
                                                                        tp => compilation.ObjectType);

                this.TypeMemberType = inferredType.SubstituteTypes(mapping, compilation);
                var availableTypeParameters = this.TypeToGenerateIn.GetAllTypeParameters();

                this.TypeMemberType = TypeMemberType.RemoveUnavailableTypeParameters(
                    compilation, availableTypeParameters);

                var enclosingMethodSymbol = document.SemanticModel.GetEnclosingSymbol <IMethodSymbol>(this.SimpleNameOrMemberAccessExpressionOpt.SpanStart, cancellationToken);

                if (enclosingMethodSymbol != null && enclosingMethodSymbol.TypeParameters != null && enclosingMethodSymbol.TypeParameters.Length != 0)
                {
                    var combinedTypeParameters = new List <ITypeParameterSymbol>();
                    combinedTypeParameters.AddRange(availableTypeParameters);
                    combinedTypeParameters.AddRange(enclosingMethodSymbol.TypeParameters);
                    this.LocalType = inferredType.RemoveUnavailableTypeParameters(
                        compilation, combinedTypeParameters);
                }
                else
                {
                    this.LocalType = this.TypeMemberType;
                }
            }
Example #2
0
            private void DetermineFieldType(
                SemanticDocument document,
                CancellationToken cancellationToken)
            {
                var inferredType = TypeGuessing.typeInferenceService.InferType(
                    document.SemanticModel, this.SimpleNameOrMemberAccessExpressionOpt,
                    objectAsDefault: true,
                    cancellationToken: cancellationToken);

                inferredType = inferredType.SpecialType == SpecialType.System_Void
                                        ? document.SemanticModel.Compilation.ObjectType
                                        : inferredType;

                if (this.IsInConditionalAccessExpression)
                {
                    inferredType = inferredType.RemoveNullableIfPresent();
                }

                // Substitute 'object' for all captured method type parameters.  Note: we may need to
                // do this for things like anonymous types, as well as captured type parameters that
                // aren't in scope in the destination type.
                var capturedMethodTypeParameters = inferredType.GetReferencedMethodTypeParameters();
                var mapping = capturedMethodTypeParameters.ToDictionary(tp => tp,
                                                                        tp => document.SemanticModel.Compilation.ObjectType);

                this.TypeMemberType = inferredType.SubstituteTypes(mapping, document.SemanticModel.Compilation);
                var availableTypeParameters = this.TypeToGenerateIn.GetAllTypeParameters();

                this.TypeMemberType = TypeMemberType.RemoveUnavailableTypeParameters(
                    document.SemanticModel.Compilation, availableTypeParameters);

                var enclosingMethodSymbol = document.SemanticModel.GetEnclosingSymbol <IMethodSymbol>(this.SimpleNameOrMemberAccessExpressionOpt.SpanStart, cancellationToken);

                if (enclosingMethodSymbol != null && enclosingMethodSymbol.TypeParameters != null && enclosingMethodSymbol.TypeParameters.Count() != 0)
                {
                    var combinedTypeParameters = new List <ITypeParameterSymbol>();
                    combinedTypeParameters.AddRange(availableTypeParameters);
                    combinedTypeParameters.AddRange(enclosingMethodSymbol.TypeParameters);
                    this.LocalType = inferredType.RemoveUnavailableTypeParameters(
                        document.SemanticModel.Compilation, combinedTypeParameters);
                }
                else
                {
                    this.LocalType = this.TypeMemberType;
                }
            }