private async Task<Document> InsertAsyncCall(Document document, MemberAccessExpressionSyntax memberAccess, CancellationToken cancellationToken)
        {
            var name = memberAccess.Name.Identifier.ValueText;
            ExpressionSyntax oldNode, newNode, newMemberAccess;
            switch (name)
            {
                case "WaitAny":
                    newMemberAccess = memberAccess.WithName((SimpleNameSyntax)SyntaxFactory.ParseName("WhenAny"));
                    break;
                case "WaitAll":
                    newMemberAccess = memberAccess.WithName((SimpleNameSyntax)SyntaxFactory.ParseName("WhenAny"));
                    break;
                case "Wait":
                    newMemberAccess = memberAccess.Expression;
                    break;
                case "Result":
                    newMemberAccess = memberAccess.Expression;
                    break;
                case "Sleep":
                    newMemberAccess = SyntaxFactory.ParseExpression("Task.Delay");
                    break;
                default:
                    newMemberAccess = memberAccess.WithName((SimpleNameSyntax)SyntaxFactory.ParseName(memberAccess.Name.Identifier.ValueText + "Async"));
                    break;
            }

            var invoc = memberAccess.Parent as InvocationExpressionSyntax;
            // WaitAny, WaitAll, Wait, Sleep, XyzAsync etc.
            if (invoc != null)
            {
                oldNode = invoc;
                newNode = name == "Wait" ? newMemberAccess : invoc.WithExpression(newMemberAccess);
            }
            // t.Result
            else
            {
                oldNode = memberAccess;
                newNode = newMemberAccess;
            }

            newNode = SyntaxFactory.AwaitExpression(newNode)
                .WithAdditionalAnnotations(Formatter.Annotation)
                .WithLeadingTrivia(memberAccess.GetLeadingTrivia())
                .WithTrailingTrivia(memberAccess.GetTrailingTrivia());

            if (oldNode.Parent.Kind() == SyntaxKind.SimpleMemberAccessExpression)
            {
                newNode = SyntaxFactory.ParenthesizedExpression(newNode);
            }

            var root = await document.GetSyntaxRootAsync().ConfigureAwait(false);
            var newRoot = root.ReplaceNode(oldNode, newNode);
            return document.WithSyntaxRoot(newRoot);
        }
        public override SyntaxNode VisitMemberAccessExpression(MemberAccessExpressionSyntax node)
        {
            node = (MemberAccessExpressionSyntax)base.VisitMemberAccessExpression(node);

            var type = _context.GetNodeContainingClassType(node);

            if (type == _type && node.Name.ToString() == _memberName)
            {
                node = node
                       .WithName(SyntaxFactory.IdentifierName(_newName))
                       .WithLeadingTrivia(node.GetLeadingTrivia())
                       .WithTrailingTrivia(node.GetTrailingTrivia());

                node = node.CopyAnnotationsTo(node);
            }

            return(node);
        }
        public override SyntaxNode VisitMemberAccessExpression(MemberAccessExpressionSyntax node)
        {
            SimpleNameSyntax name = node.Name;

            if (name != null && _nodes.Contains(name))
            {
                var expression = (ExpressionSyntax)base.Visit(node.Expression);

                node = node
                       .WithExpression(expression)
                       .WithName(IdentifierName(_methodName).WithTriviaFrom(name));

                return(InvocationExpression(
                           node.WithoutTrailingTrivia(),
                           ArgumentList().WithTrailingTrivia(node.GetTrailingTrivia())));
            }

            return(base.VisitMemberAccessExpression(node));
        }
Exemple #4
0
        public override SyntaxNode VisitMemberAccessExpression(MemberAccessExpressionSyntax node)
        {
            var symbol = semanticModel.GetSymbolInfo(node.Expression).Symbol;

            var parent = node.Parent;

            while (parent != null && !(parent is TypeDeclarationSyntax))
            {
                parent = parent.Parent;
            }

            ITypeSymbol thisType = null;

            if (parent is TypeDeclarationSyntax)
            {
                thisType = this.semanticModel.GetDeclaredSymbol(parent) as ITypeSymbol;
            }

            node = (MemberAccessExpressionSyntax)base.VisitMemberAccessExpression(node);

            if (node.Expression is IdentifierNameSyntax && symbol != null && symbol.IsStatic && symbol.ContainingType != null && thisType != null && !thisType.InheritsFromOrEquals(symbol.ContainingType) && (symbol is IMethodSymbol || symbol is IPropertySymbol || symbol is IFieldSymbol || symbol is IEventSymbol))
            {
                return(SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.IdentifierName(SyntaxFactory.Identifier(node.GetLeadingTrivia(), symbol.FullyQualifiedName(), node.GetTrailingTrivia())), node.OperatorToken, node.Name));
            }

            return(node);
        }
        private static bool TryReduceMemberAccessExpression(
            MemberAccessExpressionSyntax memberAccess,
            SemanticModel semanticModel,
            out TypeSyntax replacementNode,
            out TextSpan issueSpan,
            OptionSet optionSet,
            CancellationToken cancellationToken)
        {
            replacementNode = null;
            issueSpan = default;

            if (memberAccess.Name == null || memberAccess.Expression == null)
                return false;

            // if this node is annotated as being a SpecialType, let's use this information.
            if (memberAccess.HasAnnotations(SpecialTypeAnnotation.Kind))
            {
                replacementNode = SyntaxFactory.PredefinedType(
                    SyntaxFactory.Token(
                        memberAccess.GetLeadingTrivia(),
                        GetPredefinedKeywordKind(SpecialTypeAnnotation.GetSpecialType(memberAccess.GetAnnotations(SpecialTypeAnnotation.Kind).First())),
                        memberAccess.GetTrailingTrivia()));

                issueSpan = memberAccess.Span;
                return true;
            }

            // See https://github.com/dotnet/roslyn/issues/40974
            //
            // To be very safe, we only support simplifying code that bound to a symbol without any
            // sort of problems.  We could potentially relax this in the future.  However, we would
            // need to be very careful about the implications of us offering to fixup 'broken' code 
            // in a manner that might end up making things worse or confusing the user.
            var symbol = SimplificationHelpers.GetOriginalSymbolInfo(semanticModel, memberAccess);
            if (symbol == null)
                return false;

            if (memberAccess.Expression.IsKind(SyntaxKind.ThisExpression) &&
                !SimplificationHelpers.ShouldSimplifyThisOrMeMemberAccessExpression(semanticModel, optionSet, symbol))
            {
                return false;
            }

            // if this node is on the left side, we could simplify to aliases
            if (!memberAccess.IsRightSideOfDot())
            {
                // Check if we need to replace this syntax with an alias identifier
                if (TryReplaceExpressionWithAlias(
                        memberAccess, semanticModel, symbol,
                        cancellationToken, out var aliasReplacement))
                {
                    // get the token text as it appears in source code to preserve e.g. unicode character escaping
                    var text = aliasReplacement.Name;
                    var syntaxRef = aliasReplacement.DeclaringSyntaxReferences.FirstOrDefault();

                    if (syntaxRef != null)
                    {
                        var declIdentifier = ((UsingDirectiveSyntax)syntaxRef.GetSyntax(cancellationToken)).Alias.Name.Identifier;
                        text = declIdentifier.IsVerbatimIdentifier() ? declIdentifier.ToString().Substring(1) : declIdentifier.ToString();
                    }

                    replacementNode = SyntaxFactory.IdentifierName(
                                        memberAccess.Name.Identifier.CopyAnnotationsTo(SyntaxFactory.Identifier(
                                            memberAccess.GetLeadingTrivia(),
                                            SyntaxKind.IdentifierToken,
                                            text,
                                            aliasReplacement.Name,
                                            memberAccess.GetTrailingTrivia())));

                    replacementNode = memberAccess.CopyAnnotationsTo(replacementNode);
                    replacementNode = memberAccess.Name.CopyAnnotationsTo(replacementNode);

                    issueSpan = memberAccess.Span;

                    // In case the alias name is the same as the last name of the alias target, we only include 
                    // the left part of the name in the unnecessary span to Not confuse uses.
                    if (memberAccess.Name.Identifier.ValueText == ((IdentifierNameSyntax)replacementNode).Identifier.ValueText)
                    {
                        issueSpan = memberAccess.Expression.Span;
                    }

                    return true;
                }

                // Check if the Expression can be replaced by Predefined Type keyword
                if (PreferPredefinedTypeKeywordInMemberAccess(memberAccess, optionSet, semanticModel))
                {
                    if (symbol != null && symbol.IsKind(SymbolKind.NamedType))
                    {
                        var keywordKind = GetPredefinedKeywordKind(((INamedTypeSymbol)symbol).SpecialType);
                        if (keywordKind != SyntaxKind.None)
                        {
                            replacementNode = CreatePredefinedTypeSyntax(memberAccess, keywordKind);

                            replacementNode = replacementNode
                                .WithAdditionalAnnotations<TypeSyntax>(new SyntaxAnnotation(
                                    nameof(CodeStyleOptions2.PreferIntrinsicPredefinedTypeKeywordInMemberAccess)));

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

                            return true;
                        }
                    }
                }
            }

            // Try to eliminate cases without actually calling CanReplaceWithReducedName. For expressions of the form
            // 'this.Name' or 'base.Name', no additional check here is required.
            if (!memberAccess.Expression.IsKind(SyntaxKind.ThisExpression, SyntaxKind.BaseExpression))
            {
                GetReplacementCandidates(
                    semanticModel,
                    memberAccess,
                    symbol,
                    out var speculativeSymbols,
                    out var speculativeNamespacesAndTypes);

                if (!IsReplacementCandidate(symbol, speculativeSymbols, speculativeNamespacesAndTypes))
                {
                    return false;
                }
            }

            replacementNode = memberAccess.GetNameWithTriviaMoved();
            issueSpan = memberAccess.Expression.Span;

            return CanReplaceWithReducedName(
                memberAccess, replacementNode, semanticModel, symbol, cancellationToken);
        }
 public static SimpleNameSyntax GetNameWithTriviaMoved(this MemberAccessExpressionSyntax memberAccess)
 => memberAccess.Name
 .WithLeadingTrivia(GetLeadingTriviaForSimplifiedMemberAccess(memberAccess))
 .WithTrailingTrivia(memberAccess.GetTrailingTrivia());
        public override SyntaxNode VisitMemberAccessExpression(MemberAccessExpressionSyntax node)
        {
            var symbol = semanticModel.GetSymbolInfo(node.Expression).Symbol;

            node = (MemberAccessExpressionSyntax)base.VisitMemberAccessExpression(node);

            if (node.Expression is IdentifierNameSyntax && symbol != null && symbol.IsStatic && symbol.ContainingType != null && (symbol is IMethodSymbol || symbol is IPropertySymbol || symbol is IFieldSymbol || symbol is IEventSymbol))
            {
                return(SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.IdentifierName(SyntaxFactory.Identifier(node.GetLeadingTrivia(), symbol.FullyQualifiedName(), node.GetTrailingTrivia())), node.OperatorToken, node.Name));
            }

            return(node);
        }
Exemple #8
0
        private async Task <Document> InsertAsyncCall(Document document, MemberAccessExpressionSyntax memberAccess, CancellationToken cancellationToken)
        {
            var name = memberAccess.Name.Identifier.ValueText;
            ExpressionSyntax oldNode, newNode, newMemberAccess;

            switch (name)
            {
            case "WaitAny":
                newMemberAccess = memberAccess.WithName((SimpleNameSyntax)SyntaxFactory.ParseName("WhenAny"));
                break;

            case "WaitAll":
                newMemberAccess = memberAccess.WithName((SimpleNameSyntax)SyntaxFactory.ParseName("WhenAny"));
                break;

            case "Wait":
                newMemberAccess = memberAccess.Expression;
                break;

            case "Result":
                newMemberAccess = memberAccess.Expression;
                break;

            case "Sleep":
                newMemberAccess = SyntaxFactory.ParseExpression("Task.Delay");
                break;

            default:
                newMemberAccess = memberAccess.WithName((SimpleNameSyntax)SyntaxFactory.ParseName(memberAccess.Name.Identifier.ValueText + "Async"));
                break;
            }

            var invoc = memberAccess.Parent as InvocationExpressionSyntax;

            // WaitAny, WaitAll, Wait, Sleep, XyzAsync etc.
            if (invoc != null)
            {
                oldNode = invoc;
                newNode = name == "Wait" ? newMemberAccess : invoc.WithExpression(newMemberAccess);
            }
            // t.Result
            else
            {
                oldNode = memberAccess;
                newNode = newMemberAccess;
            }

            newNode = SyntaxFactory.AwaitExpression(newNode)
                      .WithAdditionalAnnotations(Formatter.Annotation)
                      .WithLeadingTrivia(memberAccess.GetLeadingTrivia())
                      .WithTrailingTrivia(memberAccess.GetTrailingTrivia());

            if (oldNode.Parent.Kind() == SyntaxKind.SimpleMemberAccessExpression)
            {
                newNode = SyntaxFactory.ParenthesizedExpression(newNode);
            }

            var root = await document.GetSyntaxRootAsync().ConfigureAwait(false);

            var newRoot = root.ReplaceNode(oldNode, newNode);

            return(document.WithSyntaxRoot(newRoot));
        }
        public override SyntaxNode VisitMemberAccessExpression(MemberAccessExpressionSyntax node)
        {
            var esym = m_Model.GetSymbolInfo(node).Symbol as IEventSymbol;
            var psym = m_Model.GetSymbolInfo(node).Symbol as IPropertySymbol;
            var fsym = m_Model.GetSymbolInfo(node).Symbol as IFieldSymbol;
            var msym = m_Model.GetSymbolInfo(node).Symbol as IMethodSymbol;
            var oper = m_Model.GetOperation(node);

            SyntaxNode newNode = null;
            var        name    = node.Expression as IdentifierNameSyntax;

            if (null != name)
            {
                var text = name.Identifier.Text;
                foreach (var ns in SymbolTable.Instance.Namespaces)
                {
                    if (ns == text || ns.Contains("." + text + ".") || ns.EndsWith("." + text))
                    {
                        newNode = SyntaxFactory.IdentifierName(node.Name.ToString()).WithLeadingTrivia(node.GetLeadingTrivia()).WithTrailingTrivia(node.GetTrailingTrivia());
                    }
                }
            }
            if (null == newNode)
            {
                newNode = base.VisitMemberAccessExpression(node);
            }
            bool             isExtern  = false;
            INamedTypeSymbol classType = null;

            if (null != esym && SymbolTable.Instance.IsExternSymbol(esym))
            {
                isExtern  = true;
                classType = esym.ContainingType;
                newNode   = ReportAndAttachError(newNode, string.Format("[Cs2LuaRewriter] Unsupported extern event !"));
            }
            if (null != psym && SymbolTable.Instance.IsExternSymbol(psym))
            {
                isExtern  = true;
                classType = psym.ContainingType;
                if (SymbolTable.Instance.IsIllegalProperty(psym))
                {
                    newNode = ReportAndAttachError(newNode, string.Format("[Cs2LuaRewriter] Unsupported extern property !"));
                }
            }
            if (null != fsym && SymbolTable.Instance.IsExternSymbol(fsym))
            {
                isExtern  = true;
                classType = fsym.ContainingType;
                if (SymbolTable.Instance.IsIllegalField(fsym))
                {
                    newNode = ReportAndAttachError(newNode, string.Format("[Cs2LuaRewriter] Unsupported extern field !"));
                }
            }
            if (null != msym && !(node.Parent is InvocationExpressionSyntax) && SymbolTable.Instance.IsExternSymbol(msym.ContainingType))
            {
                if (SymbolTable.Instance.IsIllegalMethod(msym))
                {
                    newNode = ReportAndAttachError(newNode, "[Cs2LuaRewriter] Unsupported extern method !");
                }
            }
            if (isExtern && null != oper)
            {
                bool legal = true;
                SymbolTable.TryRemoveNullable(ref classType);
                if (null != classType && (classType.TypeKind == TypeKind.Delegate || classType.IsGenericType && SymbolTable.Instance.IsLegalGenericType(classType, true)))
                {
                    //如果是标记为合法的泛型类或委托类型的成员,则不用再进行类型检查
                }
                else
                {
                    var type = oper.Type as INamedTypeSymbol;
                    SymbolTable.TryRemoveNullable(ref type);
                    if (null != type && SymbolTable.Instance.IsExternSymbol(type) && type.TypeKind != TypeKind.Delegate)
                    {
                        if (type.IsGenericType)
                        {
                            if (!SymbolTable.Instance.IsLegalParameterGenericType(type))
                            {
                                legal = false;
                            }
                        }
                        else
                        {
                            if (SymbolTable.Instance.IsIllegalType(type))
                            {
                                legal = false;
                            }
                        }
                    }
                }
                if (!legal)
                {
                    newNode = ReportAndAttachError(newNode, string.Format("[Cs2LuaRewriter] Unsupported extern type from member access !"));
                }
            }
            return(newNode);
        }