예제 #1
0
        private static void BuildName(NameSyntax nameSyntax, StringBuilder builder, bool includeAlias)
        {
            if (nameSyntax.IsKind(SyntaxKind.IdentifierName))
            {
                var identifierNameSyntax = (IdentifierNameSyntax)nameSyntax;
                builder.Append(identifierNameSyntax.Identifier.ValueText);
            }
            else if (nameSyntax.IsKind(SyntaxKind.QualifiedName))
            {
                var qualifiedNameSyntax = (QualifiedNameSyntax)nameSyntax;
                BuildName(qualifiedNameSyntax.Left, builder, includeAlias);
                builder.Append(DotChar);
                BuildName(qualifiedNameSyntax.Right, builder, includeAlias);
            }
            else if (nameSyntax.IsKind(SyntaxKind.GenericName))
            {
                var genericNameSyntax = (GenericNameSyntax)nameSyntax;
                builder.AppendFormat("{0}{1}", genericNameSyntax.Identifier.ValueText, genericNameSyntax.TypeArgumentList.ToString());
            }
            else if (nameSyntax.IsKind(SyntaxKind.AliasQualifiedName))
            {
                var aliasQualifiedNameSyntax = (AliasQualifiedNameSyntax)nameSyntax;
                if (includeAlias)
                {
                    builder.Append(aliasQualifiedNameSyntax.Alias.Identifier.ValueText);
                    builder.Append("::");
                }

                builder.Append(aliasQualifiedNameSyntax.Name.Identifier.ValueText);
            }
        }
            private static void AppendName(StringBuilder builder, NameSyntax name)
            {
                if (name.Kind() == SyntaxKind.QualifiedName)
                {
                    AppendName(builder, ((QualifiedNameSyntax)name).Left);
                }

                switch (name.Kind())
                {
                    case SyntaxKind.IdentifierName:
                        AppendDotIfNeeded(builder);
                        builder.Append(((IdentifierNameSyntax)name).Identifier.ValueText);
                        break;

                    case SyntaxKind.GenericName:
                        var genericName = (GenericNameSyntax)name;
                        AppendDotIfNeeded(builder);
                        builder.Append(genericName.Identifier.ValueText);
                        AppendArity(builder, genericName.Arity);
                        break;

                    case SyntaxKind.AliasQualifiedName:
                        var aliasQualifiedName = (AliasQualifiedNameSyntax)name;
                        AppendName(builder, aliasQualifiedName.Alias);
                        builder.Append("::");
                        AppendName(builder, aliasQualifiedName.Name);
                        break;

                    case SyntaxKind.QualifiedName:
                        AppendName(builder, ((QualifiedNameSyntax)name).Right);
                        break;
                }
            }
        private async Task<IEnumerable<CompletionItem>> GetCompletionsOffOfExplicitInterfaceAsync(
            Document document, SemanticModel semanticModel, int position, NameSyntax name, CancellationToken cancellationToken)
        {
            // Bind the interface name which is to the left of the dot
            var syntaxTree = semanticModel.SyntaxTree;
            var nameBinding = semanticModel.GetSymbolInfo(name, cancellationToken);
            var context = CSharpSyntaxContext.CreateContext(document.Project.Solution.Workspace, semanticModel, position, cancellationToken);

            var symbol = nameBinding.Symbol as ITypeSymbol;
            if (symbol == null || symbol.TypeKind != TypeKind.Interface)
            {
                return SpecializedCollections.EmptyEnumerable<CompletionItem>();
            }

            var members = semanticModel.LookupSymbols(
                position: name.SpanStart,
                container: symbol)
                    .Where(s => !s.IsStatic)
                    .FilterToVisibleAndBrowsableSymbols(document.ShouldHideAdvancedMembers(), semanticModel.Compilation);

            // We're going to create a entry for each one, including the signature
            var completions = new List<CompletionItem>();

            var signatureDisplayFormat =
                new SymbolDisplayFormat(
                    genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
                    memberOptions:
                        SymbolDisplayMemberOptions.IncludeParameters,
                    parameterOptions:
                        SymbolDisplayParameterOptions.IncludeName |
                        SymbolDisplayParameterOptions.IncludeType |
                        SymbolDisplayParameterOptions.IncludeParamsRefOut,
                    miscellaneousOptions:
                        SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers |
                        SymbolDisplayMiscellaneousOptions.UseSpecialTypes);

            var namePosition = name.SpanStart;

            var text = await context.SyntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false);
            var textChangeSpan = CompletionUtilities.GetTextChangeSpan(text, context.Position);

            foreach (var member in members)
            {
                var displayString = member.ToMinimalDisplayString(semanticModel, namePosition, signatureDisplayFormat);
                var memberCopied = member;
                var insertionText = displayString;

                completions.Add(new SymbolCompletionItem(
                    this,
                    displayString,
                    insertionText: insertionText,
                    filterSpan: textChangeSpan,
                    position: position,
                    symbols: new List<ISymbol> { member },
                    context: context,
                    rules: ItemRules.Instance));
            }

            return completions;
        }
예제 #4
0
        private bool TryClassifySymbol(
            NameSyntax name,
            SymbolInfo symbolInfo,
            SemanticModel semanticModel,
            CancellationToken cancellationToken,
            out IEnumerable<ClassifiedSpan> result)
        {
            if (symbolInfo.CandidateReason == CandidateReason.Ambiguous)
            {
                return TryClassifyAmbiguousSymbol(name, symbolInfo, semanticModel, cancellationToken, out result);
            }

            // Only classify if we get one good symbol back, or if it bound to a constructor symbol with
            // overload resolution/accessibility errors, or bound to type/constructor and type wasn't creatable.
            var symbol = TryGetSymbol(name, symbolInfo, semanticModel);

            ClassifiedSpan classifiedSpan;
            if (TryClassifySymbol(name, symbol, semanticModel, cancellationToken, out classifiedSpan))
            {
                result = SpecializedCollections.SingletonEnumerable(classifiedSpan);
                return true;
            }

            result = null;
            return false;
        }
예제 #5
0
        private static bool IsNamespaceName(NameSyntax name)
        {
            while (name.Parent is NameSyntax)
            {
                name = (NameSyntax)name.Parent;
            }

            return name.IsParentKind(SyntaxKind.NamespaceDeclaration);
        }
 public DeltaGen(CodeGen generator)
     : base(generator)
 {
     var recursiveType = this.applyTo.RecursiveTypeFromFamily;
     if (!recursiveType.IsDefault)
     {
         this.changedPropertiesEnumTypeName = SyntaxFactory.IdentifierName(recursiveType.TypeSymbol.Name + "ChangedProperties");
         this.diffGramTypeSyntax = SyntaxFactory.QualifiedName(recursiveType.TypeSyntax, DiffGramTypeName);
         this.recursiveDiffingType = SyntaxFactory.QualifiedName(
             SyntaxFactory.IdentifierName(nameof(ImmutableObjectGraph)),
             SyntaxFactory.GenericName(nameof(ImmutableObjectGraph.IRecursiveDiffingType<uint, uint>))
                 .AddTypeArgumentListArguments(
                     this.changedPropertiesEnumTypeName,
                     this.diffGramTypeSyntax));
     }
 }
        private Document IntroduceQueryLocalForSingleOccurrence(
            SemanticDocument document,
            ExpressionSyntax expression,
            NameSyntax newLocalName,
            LetClauseSyntax letClause,
            bool allOccurrences,
            CancellationToken cancellationToken)
        {
            var oldClause = expression.GetAncestors<SyntaxNode>().First(IsAnyQueryClause);
            var newClause = Rewrite(
                document, expression, newLocalName, document, oldClause, allOccurrences, cancellationToken);

            var oldQuery = (QueryBodySyntax)oldClause.Parent;
            var newQuery = GetNewQuery(oldQuery, oldClause, newClause, letClause);

            var newRoot = document.Root.ReplaceNode(oldQuery, newQuery);
            return document.Document.WithSyntaxRoot(newRoot);
        }
예제 #8
0
        private static ISymbol TryGetSymbol(NameSyntax name, SymbolInfo symbolInfo, SemanticModel semanticModel)
        {
            if (symbolInfo.Symbol == null && symbolInfo.CandidateSymbols.Length > 0)
            {
                var firstSymbol = symbolInfo.CandidateSymbols[0];

                switch (symbolInfo.CandidateReason)
                {
                    case CandidateReason.NotAValue:
                        return firstSymbol;

                    case CandidateReason.NotCreatable:
                        // We want to color types even if they can't be constructed.
                        if (firstSymbol.IsConstructor() || firstSymbol is ITypeSymbol)
                        {
                            return firstSymbol;
                        }

                        break;

                    case CandidateReason.OverloadResolutionFailure:
                        // If we couldn't bind to a constructor, still classify the type.
                        if (firstSymbol.IsConstructor())
                        {
                            return firstSymbol;
                        }

                        break;

                    case CandidateReason.Inaccessible:
                        // If a constructor wasn't accessible, still classify the type if it's accessible.
                        if (firstSymbol.IsConstructor() && semanticModel.IsAccessible(name.SpanStart, firstSymbol.ContainingType))
                        {
                            return firstSymbol;
                        }

                        break;
                }
            }

            return symbolInfo.Symbol;
        }
예제 #9
0
        private IEnumerable<ClassifiedSpan> ClassifyTypeSyntax(
            NameSyntax name,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            if (!IsNamespaceName(name))
            {
                var symbolInfo = semanticModel.GetSymbolInfo(name, cancellationToken);

                IEnumerable<ClassifiedSpan> result;
                if (TryClassifySymbol(name, symbolInfo, semanticModel, cancellationToken, out result) ||
                    TryClassifyFromIdentifier(name, symbolInfo, out result) ||
                    TryClassifyValueIdentifier(name, symbolInfo, out result))
                {
                    return result;
                }
            }

            return null;
        }
 public FastSpineGen(CodeGen generator)
     : base(generator)
 {
     if (this.applyTo.IsRecursive || this.applyTo.IsRecursiveParentOrDerivative)
     {
         var keyValuePairType = SyntaxFactory.ParseTypeName(
             string.Format(
                 CultureInfo.InvariantCulture,
                 "System.Collections.Generic.KeyValuePair<{1}, {0}>",
                 IdentityFieldTypeSyntax,
                 this.applyTo.RecursiveTypeFromFamily.TypeSyntax));
         this.lookupTableType = SyntaxFactory.ParseTypeName(
             string.Format(
                 CultureInfo.InvariantCulture,
                 "System.Collections.Immutable.ImmutableDictionary<{0}, {1}>",
                 IdentityFieldTypeSyntax,
                 keyValuePairType));
         this.IRecursiveParentWithChildReplacementType = SyntaxFactory.QualifiedName(
             SyntaxFactory.IdentifierName(nameof(ImmutableObjectGraph)),
             SyntaxFactory.GenericName(nameof(IRecursiveParentWithChildReplacement<IRecursiveType>))
                 .AddTypeArgumentListArguments(this.applyTo.RecursiveType.TypeSyntax));
     }
 }
        private static void CheckNameSyntax(SyntaxNodeAnalysisContext context, NameSyntax nameSyntax)
        {
            if (nameSyntax == null || nameSyntax.IsMissing)
            {
                return;
            }

            QualifiedNameSyntax qualifiedNameSyntax = nameSyntax as QualifiedNameSyntax;
            if (qualifiedNameSyntax != null)
            {
                CheckNameSyntax(context, qualifiedNameSyntax.Left);
                CheckNameSyntax(context, qualifiedNameSyntax.Right);
                return;
            }

            SimpleNameSyntax simpleNameSyntax = nameSyntax as SimpleNameSyntax;
            if (simpleNameSyntax != null)
            {
                CheckElementNameToken(context, simpleNameSyntax.Identifier);
                return;
            }

            // TODO: any other cases?
        }
        private static ImmutableArray<ISymbol> GetSymbolsOffOfName(
            CSharpSyntaxContext context,
            NameSyntax name,
            CancellationToken cancellationToken)
        {
            // Check if we're in an interesting situation like this:
            //
            //     int i = 5;
            //     i.          // <-- here
            //     List<string> ml = new List<string>();

            // The problem is that "i.List<string>" gets parsed as a type.  In this case we need to
            // try binding again as if "i" is an expression and not a type.  In order to do that, we
            // need to speculate as to what 'i' meant if it wasn't part of a local declaration's
            // type.

            if (name.IsFoundUnder<LocalDeclarationStatementSyntax>(d => d.Declaration.Type))
            {
                var speculativeBinding = context.SemanticModel.GetSpeculativeSymbolInfo(name.SpanStart, name, SpeculativeBindingOption.BindAsExpression);
                var container = context.SemanticModel.GetSpeculativeTypeInfo(name.SpanStart, name, SpeculativeBindingOption.BindAsExpression).Type;
                return GetSymbolsOffOfBoundExpression(context, name, name, speculativeBinding, container, cancellationToken);
            }

            // We're in a name-only context, since if we were an expression we'd be a
            // MemberAccessExpressionSyntax. Thus, let's do other namespaces and types.
            var nameBinding = context.SemanticModel.GetSymbolInfo(name, cancellationToken);

            var symbol = nameBinding.Symbol as INamespaceOrTypeSymbol;
            if (symbol != null)
            {
                if (context.IsNameOfContext)
                {
                    return context.SemanticModel.LookupSymbols(position: name.SpanStart, container: symbol);
                }

                var symbols = context.SemanticModel.LookupNamespacesAndTypes(
                    position: name.SpanStart,
                    container: symbol);

                if (context.IsNamespaceDeclarationNameContext)
                {
                    var declarationSyntax = name.GetAncestorOrThis<NamespaceDeclarationSyntax>();
                    return symbols.WhereAsArray(s => IsNonIntersectingNamespace(s, declarationSyntax));
                }

                // Filter the types when in a using directive, but not an alias.
                // 
                // Cases:
                //    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)
                {
                    if (usingDirective.StaticKeyword.IsKind(SyntaxKind.StaticKeyword))
                    {
                        return symbols.WhereAsArray(s => !s.IsDelegateType() && !s.IsInterfaceType());
                    }
                    else
                    {
                        symbols = symbols.WhereAsArray(s => s.IsNamespace());
                    }
                }

                if (symbols.Any())
                {
                    return symbols;
                }
            }

            return ImmutableArray<ISymbol>.Empty;
        }
예제 #13
0
        private Symbol GetDeclaredMember(NamespaceOrTypeSymbol container, TextSpan declarationSpan, NameSyntax name)
        {
            switch (name.Kind())
            {
                case SyntaxKind.GenericName:
                case SyntaxKind.IdentifierName:
                    return GetDeclaredMember(container, declarationSpan, ((SimpleNameSyntax)name).Identifier.ValueText);

                case SyntaxKind.QualifiedName:
                    var qn = (QualifiedNameSyntax)name;
                    var left = GetDeclaredMember(container, declarationSpan, qn.Left) as NamespaceOrTypeSymbol;
                    Debug.Assert((object)left != null);
                    return GetDeclaredMember(left, declarationSpan, qn.Right);

                case SyntaxKind.AliasQualifiedName:
                    // this is not supposed to happen, but we allow for errors don't we!
                    var an = (AliasQualifiedNameSyntax)name;
                    return GetDeclaredMember(container, declarationSpan, an.Name);

                default:
                    throw ExceptionUtilities.UnexpectedValue(name.Kind());
            }
        }
예제 #14
0
 bool IsRewritableMethod(NameSyntax methodNameSyntax)
 {
     var symbol = model.GetSymbolInfo(methodNameSyntax).Symbol as IMethodSymbol;
     return symbol != null && symbol.HasAttribute<MetaRewriteTypeArgsAttribute>(model.Compilation);
 }
 private static bool PreferPredefinedTypeKeywordInDeclarations(NameSyntax name, OptionSet optionSet, SemanticModel semanticModel)
 {
     return !IsInMemberAccessContext(name) &&
            !InsideCrefReference(name) &&
            !InsideNameOfExpression(name, semanticModel) &&
            SimplificationHelpers.PreferPredefinedTypeKeywordInDeclarations(optionSet, semanticModel.Language);
 }
        private static bool IsInScriptClass(SemanticModel model, NameSyntax name)
        {
            var symbol = model.GetSymbolInfo(name).Symbol as INamedTypeSymbol;
            while (symbol != null)
            {
                if (symbol.IsScriptClass)
                {
                    return true;
                }

                symbol = symbol.ContainingType;
            }

            return false;
        }
        private static bool IsQualifiedNameInUsingDirective(SemanticModel model, NameSyntax name, TypeSyntax reducedName)
        {
            while (name.IsLeftSideOfQualifiedName())
            {
                name = (NameSyntax)name.Parent;
            }

            if (name.IsParentKind(SyntaxKind.UsingDirective) &&
                ((UsingDirectiveSyntax)name.Parent).Alias == null)
            {
                // We're a qualified name in a using.  We don't want to reduce this name as people like
                // fully qualified names in usings so they can properly tell what the name is resolving
                // to.
                // However, if this name is actually referencing the special Script class, then we do
                // want to allow that to be reduced.

                return !IsInScriptClass(model, name);
            }

            return false;
        }
예제 #18
0
        private bool TryClassifyFromIdentifier(
            NameSyntax name,
            SymbolInfo symbolInfo,
            out IEnumerable<ClassifiedSpan> result)
        {
            // Okay - it wasn't a type. If the syntax matches "var q = from" or "q = from", and from
            // doesn't bind to anything then optimistically color from as a keyword.
            var identifierName = name as IdentifierNameSyntax;
            if (identifierName != null &&
                identifierName.Identifier.HasMatchingText(SyntaxKind.FromKeyword) &&
                symbolInfo.Symbol == null)
            {
                var token = identifierName.Identifier;
                if (identifierName.IsRightSideOfAnyAssignExpression() || identifierName.IsVariableDeclaratorValue())
                {
                    result = SpecializedCollections.SingletonEnumerable(
                        new ClassifiedSpan(token.Span, ClassificationTypeNames.Keyword));
                    return true;
                }
            }

            result = null;
            return false;
        }
 private static bool PreferPredefinedTypeKeywordInDeclarations(NameSyntax name, OptionSet optionSet, SemanticModel semanticModel)
 {
     return (name.Parent != null) && !(name.Parent is MemberAccessExpressionSyntax) &&
            !InsideCrefReference(name) && !InsideNameOfExpression(name, semanticModel) &&
            optionSet.GetOption(SimplificationOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration, LanguageNames.CSharp);
 }
예제 #20
0
        private bool TryClassifySymbol(
            NameSyntax name,
            ISymbol symbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken,
            out ClassifiedSpan classifiedSpan)
        {
            if (symbol != null)
            {
                // see through using aliases
                if (symbol.Kind == SymbolKind.Alias)
                {
                    symbol = (symbol as IAliasSymbol).Target;
                }
                else if (symbol.IsConstructor() && name.IsParentKind(SyntaxKind.Attribute))
                {
                    symbol = symbol.ContainingType;
                }
            }

            if (name.IsVar &&
                IsInVarContext(name))
            {
                var alias = semanticModel.GetAliasInfo(name, cancellationToken);
                if (alias == null || alias.Name != "var")
                {
                    if (!IsSymbolCalledVar(symbol))
                    {
                        // We bound to a symbol.  If we bound to a symbol called "var" then we want to
                        // classify this appropriately as a type.  Otherwise, we want to classify this as
                        // a keyword.
                        classifiedSpan = new ClassifiedSpan(name.Span, ClassificationTypeNames.Keyword);
                        return true;
                    }
                }
            }

            if (symbol != null)
            {
                // Use .Equals since we can't rely on object identity for constructed types.
                if (symbol is ITypeSymbol)
                {
                    var classification = GetClassificationForType((ITypeSymbol)symbol);
                    if (classification != null)
                    {
                        var token = name.GetNameToken();
                        classifiedSpan = new ClassifiedSpan(token.Span, classification);
                        return true;
                    }
                }
            }

            classifiedSpan = default(ClassifiedSpan);
            return false;
        }
        private static bool TryReduceAttributeSuffix(
            NameSyntax name,
            SyntaxToken identifierToken,
            SemanticModel semanticModel,
            out TypeSyntax replacementNode,
            out TextSpan issueSpan,
            CancellationToken cancellationToken)
        {
            issueSpan = default(TextSpan);
            replacementNode = default(TypeSyntax);

            // we can try to remove the Attribute suffix if this is the attribute name
            if (SyntaxFacts.IsAttributeName(name))
            {
                if (name.Parent.Kind() == SyntaxKind.Attribute || name.IsRightSideOfDotOrColonColon())
                {
                    const string AttributeName = "Attribute";

                    // an attribute that should keep it (unnecessary "Attribute" suffix should be annotated with a DontSimplifyAnnotation
                    if (identifierToken.ValueText != AttributeName && identifierToken.ValueText.EndsWith(AttributeName, StringComparison.Ordinal) && !identifierToken.HasAnnotation(SimplificationHelpers.DontSimplifyAnnotation))
                    {
                        // weird. the semantic model is able to bind attribute syntax like "[as()]" although it's not valid code.
                        // so we need another check for keywords manually.
                        var newAttributeName = identifierToken.ValueText.Substring(0, identifierToken.ValueText.Length - 9);
                        if (SyntaxFacts.GetKeywordKind(newAttributeName) != SyntaxKind.None)
                        {
                            return false;
                        }

                        // if this attribute name in source contained unicode escaping, we will loose it now
                        // because there is no easy way to determine the substring from identifier->ToString() 
                        // which would be needed to pass to SyntaxFactory.Identifier
                        // The result is an unescaped unicode character in source.

                        // once we remove the Attribute suffix, we can't use an escaped identifier
                        var newIdentifierToken = identifierToken.CopyAnnotationsTo(
                            SyntaxFactory.Identifier(
                                identifierToken.LeadingTrivia,
                                newAttributeName,
                                identifierToken.TrailingTrivia));

                        replacementNode = SyntaxFactory.IdentifierName(newIdentifierToken)
                            .WithLeadingTrivia(name.GetLeadingTrivia());
                        issueSpan = new TextSpan(identifierToken.Span.End - 9, 9);

                        return true;
                    }
                }
            }

            return false;
        }
예제 #22
0
        private bool TryClassifyNameOfIdentifier(NameSyntax name, SymbolInfo symbolInfo, out IEnumerable<ClassifiedSpan> result)
        {
            var identifierName = name as IdentifierNameSyntax;
            if (identifierName != null &&
                identifierName.Identifier.IsKindOrHasMatchingText(SyntaxKind.NameOfKeyword) &&
                symbolInfo.Symbol == null &&
                !symbolInfo.CandidateSymbols.Any())
            {
                result = SpecializedCollections.SingletonEnumerable(new ClassifiedSpan(identifierName.Identifier.Span, ClassificationTypeNames.Keyword));
                return true;
            }

            result = null;
            return false;
        }
예제 #23
0
        private bool TryClassifyValueIdentifier(
            NameSyntax name,
            SymbolInfo symbolInfo,
            out IEnumerable<ClassifiedSpan> result)
        {
            var identifierName = name as IdentifierNameSyntax;
            if (symbolInfo.Symbol.IsImplicitValueParameter())
            {
                result = SpecializedCollections.SingletonEnumerable(
                    new ClassifiedSpan(identifierName.Identifier.Span, ClassificationTypeNames.Keyword));
                return true;
            }

            result = null;
            return false;
        }
        private static bool CanSimplifyNullable(INamedTypeSymbol type, NameSyntax name, SemanticModel semanticModel)
        {
            if (!type.IsNullable())
            {
                return false;
            }

            if (type.IsUnboundGenericType)
            {
                // Don't simplify unbound generic type "Nullable<>".
                return false;
            }

            if (InsideNameOfExpression(name, semanticModel))
            {
                // Nullable<T> can't be simplified to T? in nameof expressions.
                return false;
            }

            if (!InsideCrefReference(name))
            {
                // Nullable<T> can always be simplified to T? outside crefs.
                return true;
            }

            // Inside crefs, if the T in this Nullable{T} is being declared right here
            // then this Nullable{T} is not a constructed generic type and we should
            // not offer to simplify this to T?.
            //
            // For example, we should not offer the simplification in the following cases where
            // T does not bind to an existing type / type parameter in the user's code.
            // - <see cref="Nullable{T}"/>
            // - <see cref="System.Nullable{T}.Value"/>
            //
            // And we should offer the simplification in the following cases where SomeType and
            // SomeMethod bind to a type and method declared elsewhere in the users code.
            // - <see cref="SomeType.SomeMethod(Nullable{SomeType})"/>

            var argument = type.TypeArguments.SingleOrDefault();
            if (argument == null || argument.IsErrorType())
            {
                return false;
            }

            var argumentDecl = argument.DeclaringSyntaxReferences.FirstOrDefault();
            if (argumentDecl == null)
            {
                // The type argument is a type from metadata - so this is a constructed generic nullable type that can be simplified (e.g. Nullable(Of Integer)).
                return true;
            }

            return !name.Span.Contains(argumentDecl.Span);
        }
        private static bool CanReplaceWithPredefinedTypeKeywordInContext(
            NameSyntax name,
            SemanticModel semanticModel,
            out TypeSyntax replacementNode,
            ref TextSpan issueSpan,
            SyntaxKind keywordKind,
            string codeStyleOptionName,
            CancellationToken cancellationToken)
        {
            replacementNode = CreatePredefinedTypeSyntax(name, keywordKind);

            issueSpan = name.Span; // we want to show the whole name expression as unnecessary

            var canReduce = name.CanReplaceWithReducedNameInContext(replacementNode, semanticModel, cancellationToken);

            if (canReduce)
            {
                replacementNode = replacementNode.WithAdditionalAnnotations(new SyntaxAnnotation(codeStyleOptionName));
            }

            return canReduce;
        }
        private static bool CanReplaceWithPredefinedTypeKeywordInContext(NameSyntax name, SemanticModel semanticModel, out TypeSyntax replacementNode, ref TextSpan issueSpan, SyntaxKind keywordKind, CancellationToken cancellationToken)
        {
            replacementNode = CreatePredefinedTypeSyntax(name, keywordKind);

            issueSpan = name.Span; // we want to show the whole name expression as unnecessary

            return name.CanReplaceWithReducedNameInContext(replacementNode, semanticModel, cancellationToken);
        }
예제 #27
0
 private bool IsInVarContext(NameSyntax name)
 {
     return
         name.CheckParent<VariableDeclarationSyntax>(v => v.Type == name) ||
         name.CheckParent<ForEachStatementSyntax>(f => f.Type == name) ||
         name.CheckParent<TypedVariableComponentSyntax>(f => f.Type == name);
 }
 private static bool ContainsOpenName(NameSyntax name)
 {
     if (name is QualifiedNameSyntax)
     {
         var qualifiedName = (QualifiedNameSyntax)name;
         return ContainsOpenName(qualifiedName.Left) || ContainsOpenName(qualifiedName.Right);
     }
     else if (name is GenericNameSyntax)
     {
         return ((GenericNameSyntax)name).IsUnboundGenericName;
     }
     else
     {
         return false;
     }
 }
예제 #29
0
        private bool TryClassifyAmbiguousSymbol(
            NameSyntax name,
            SymbolInfo symbolInfo,
            SemanticModel semanticModel,
            CancellationToken cancellationToken,
            out IEnumerable<ClassifiedSpan> result)
        {
            // If everything classifies the same way, then just pick that classification.
            var set = new HashSet<ClassifiedSpan>();
            foreach (var symbol in symbolInfo.CandidateSymbols)
            {
                ClassifiedSpan classifiedSpan;
                if (TryClassifySymbol(name, symbol, semanticModel, cancellationToken, out classifiedSpan))
                {
                    set.Add(classifiedSpan);
                }
            }

            if (set.Count == 1)
            {
                result = SpecializedCollections.SingletonEnumerable(set.First());
                return true;
            }

            result = null;
            return false;
        }
            private bool CompareNames(NameSyntax oldName, NameSyntax newName)
            {
                if (oldName.Kind() != newName.Kind())
                {
                    return false;
                }

                switch (oldName.Kind())
                {
                    case SyntaxKind.IdentifierName:
                        var oldIdentifierName = (IdentifierNameSyntax)oldName;
                        var newIdentifierName = (IdentifierNameSyntax)newName;

                        return StringComparer.Ordinal.Equals(oldIdentifierName.Identifier.ToString(), newIdentifierName.Identifier.ToString());

                    case SyntaxKind.QualifiedName:
                        var oldQualifiedName = (QualifiedNameSyntax)oldName;
                        var newQualifiedName = (QualifiedNameSyntax)newName;

                        return CompareNames(oldQualifiedName.Left, newQualifiedName.Left)
                            && CompareNames(oldQualifiedName.Right, oldQualifiedName.Right);

                    case SyntaxKind.GenericName:
                        var oldGenericName = (GenericNameSyntax)oldName;
                        var newGenericName = (GenericNameSyntax)newName;

                        if (!StringComparer.Ordinal.Equals(oldGenericName.Identifier.ToString(), newGenericName.Identifier.ToString()))
                        {
                            return false;
                        }

                        if (oldGenericName.Arity != newGenericName.Arity)
                        {
                            return false;
                        }

                        for (int i = 0; i < oldGenericName.Arity; i++)
                        {
                            if (!CompareTypes(oldGenericName.TypeArgumentList.Arguments[i], newGenericName.TypeArgumentList.Arguments[i]))
                            {
                                return false;
                            }
                        }

                        return true;

                    case SyntaxKind.AliasQualifiedName:
                        var oldAliasQualifiedName = (AliasQualifiedNameSyntax)oldName;
                        var newAliasQualifiedName = (AliasQualifiedNameSyntax)newName;

                        return CompareNames(oldAliasQualifiedName.Alias, newAliasQualifiedName.Alias)
                            && CompareNames(oldAliasQualifiedName.Name, newAliasQualifiedName.Name);
                }

                Debug.Fail("Unknown kind: " + oldName.Kind());
                return false;
            }
예제 #31
0
 public NamespaceDeclarationSyntax Update(SyntaxToken namespaceKeyword, NameSyntax name, SyntaxToken openBraceToken, SyntaxList <ExternAliasDirectiveSyntax> externs, SyntaxList <UsingDirectiveSyntax> usings, SyntaxList <MemberDeclarationSyntax> members, SyntaxToken closeBraceToken, SyntaxToken semicolonToken)
 => this.Update(this.AttributeLists, this.Modifiers, namespaceKeyword, name, openBraceToken, externs, usings, members, closeBraceToken, semicolonToken);