protected override bool TryInitializeState(
			Document document, SemanticModel model, SyntaxNode node, CancellationToken cancellationToken,
			out INamedTypeSymbol classType, out INamedTypeSymbol abstractClassType)
		{
			var baseClassNode = node as TypeSyntax;
			if (baseClassNode != null && baseClassNode.Parent is BaseTypeSyntax &&
				baseClassNode.Parent.IsParentKind(SyntaxKind.BaseList) &&
				((BaseTypeSyntax)baseClassNode.Parent).Type == baseClassNode)
			{
				if (baseClassNode.Parent.Parent.IsParentKind(SyntaxKind.ClassDeclaration))
				{
					abstractClassType = model.GetTypeInfo(baseClassNode, cancellationToken).Type as INamedTypeSymbol;
					cancellationToken.ThrowIfCancellationRequested();

					if (abstractClassType.IsAbstractClass())
					{
						var classDecl = baseClassNode.Parent.Parent.Parent as ClassDeclarationSyntax;
						classType = model.GetDeclaredSymbol(classDecl, cancellationToken) as INamedTypeSymbol;

						return classType != null && abstractClassType != null;
					}
				}
			}

			classType = null;
			abstractClassType = null;
			return false;
		}
        private static bool IsMainMethodEntryPoint(MethodDeclarationSyntax methodTarget, SemanticModel semanticModel)
        {
            if (!methodTarget.Identifier.Text.Equals("Main", StringComparison.Ordinal)) return false;
            if (!methodTarget.Modifiers.Any(SyntaxKind.StaticKeyword)) return false;

            var returnType = semanticModel.GetTypeInfo(methodTarget.ReturnType).Type;
            if (returnType == null) return false;
            if (!returnType.Name.Equals("Void", StringComparison.OrdinalIgnoreCase) &&
                !returnType.Name.Equals("Int32", StringComparison.OrdinalIgnoreCase))
                return false;

            var parameters = methodTarget.ParameterList.Parameters;
            if (parameters.Count > 1) return false;
            if (parameters.Count == 0) return true;
            var parameterType = semanticModel.GetTypeInfo(parameters.First().Type).Type;
            if (!parameterType.OriginalDefinition.ToString().Equals("String[]", StringComparison.OrdinalIgnoreCase)) return false;
            return true;
        }
 private static void AnalyzeBinaryExpression(BinaryExpressionSyntax node, SemanticModel model, Action<Diagnostic> addDiagnostic)
 {
     var leftType = model.GetTypeInfo(node.Left).Type;
     var rightType = model.GetTypeInfo(node.Right).Type;
     if (leftType != null && rightType != null && leftType.SpecialType == SpecialType.System_String && rightType.SpecialType == SpecialType.System_String)
     {
         addDiagnostic(node.OperatorToken.GetLocation().CreateDiagnostic(Rule));
     }
 }
        private bool IsReportable(VariableDeclarationSyntax variableDeclaration, SemanticModel semanticModel)
        {
            bool result;
            TypeSyntax variableTypeName = variableDeclaration.Type;
            if (variableTypeName.IsVar)
            {
                // Implicitly-typed variables cannot have multiple declarators. Short circuit if it does.
                bool hasMultipleVariables = variableDeclaration.Variables.Skip(1).Any();
                if(hasMultipleVariables == false)
                {
                    // Special case: Ensure that 'var' isn't actually an alias to another type. (e.g. using var = System.String).
                    IAliasSymbol aliasInfo = semanticModel.GetAliasInfo(variableTypeName);
                    if (aliasInfo == null)
                    {
                        // Retrieve the type inferred for var.
                        ITypeSymbol type = semanticModel.GetTypeInfo(variableTypeName).ConvertedType;

                        // Special case: Ensure that 'var' isn't actually a type named 'var'.
                        if (type.Name.Equals("var", StringComparison.Ordinal) == false)
                        {
                            // Special case: Ensure that the type is not an anonymous type.
                            if (type.IsAnonymousType == false)
                            {
                                // Special case: Ensure that it's not a 'new' expression.
                                if (variableDeclaration.Variables.First().Initializer.Value.IsKind(SyntaxKind.ObjectCreationExpression))
                                {
                                    result = false;
                                }
                                else
                                {
                                    result = true;
                                }
                            }
                            else
                            {
                                result = false;
                            }
                        }
                        else
                        {
                            result = false;
                        }
                    }
                    else
                    {
                        result = false;
                    }
                }
                else
                {
                    result = false;
                }
            }
            else
            {
                result = false;
            }

            return result;
        }
        /// <summary>
        /// Determines whether the specified TypeSyntax is actually 'var'.
        /// </summary>
        public static bool IsTypeInferred(this TypeSyntax typeSyntax, SemanticModel semanticModel)
        {
            if (!typeSyntax.IsVar)
            {
                return false;
            }

            if (semanticModel.GetAliasInfo(typeSyntax) != null)
            {
                return false;
            }

            var type = semanticModel.GetTypeInfo(typeSyntax).Type;
            if (type == null)
            {
                return false;
            }

            if (type.Name == "var")
            {
                return false;
            }

            return true;
        }
        static bool IsDeclarationConstFriendly(LocalDeclarationStatementSyntax declaration, SemanticModel semanticModel)
        {
            // all variables could be const?
            foreach (var variable in declaration.Declaration.Variables)
            {
                if (variable.Initializer == null) return false;
                if (variable.Initializer.Value is InterpolatedStringExpressionSyntax) return false;

                // is constant
                var constantValue = semanticModel.GetConstantValue(variable.Initializer.Value);
                var valueIsConstant = constantValue.HasValue;
                if (!valueIsConstant) return false;

                // if reference type, value is null?
                var variableTypeName = declaration.Declaration.Type;
                var variableType = semanticModel.GetTypeInfo(variableTypeName).ConvertedType;
                if (variableType.IsReferenceType && variableType.SpecialType != SpecialType.System_String && constantValue.Value != null) return false;

                // nullable?
                if (variableType.OriginalDefinition?.SpecialType == SpecialType.System_Nullable_T) return false;

                // value can be converted to variable type?
                var conversion = semanticModel.ClassifyConversion(variable.Initializer.Value, variableType);
                if (!conversion.Exists || conversion.IsUserDefined) return false;
            }
            return true;
        }
 static bool CanBeNull(SemanticModel semanticModel, ExpressionSyntax expression, CancellationToken cancellationToken)
 {
     var info = semanticModel.GetTypeInfo(expression, cancellationToken);
     if (info.ConvertedType.IsReferenceType || info.ConvertedType.IsNullableType())
         return true;
     return false;
 }
 internal static bool CheckExceptionType(SemanticModel model, ObjectCreationExpressionSyntax objectCreateExpression, out ExpressionSyntax paramNode)
 {
     paramNode = null;
     var type = model.GetTypeInfo(objectCreateExpression).Type;
     if (type == null)
         return false;
     if (type.Name == typeof(ArgumentException).Name)
     {
         if (objectCreateExpression.ArgumentList.Arguments.Count >= 2)
         {
             paramNode = objectCreateExpression.ArgumentList.Arguments[1].Expression;
         }
         return paramNode != null;
     }
     if (type.Name == typeof(ArgumentNullException).Name ||
         type.Name == typeof(ArgumentOutOfRangeException).Name ||
         type.Name == "DuplicateWaitObjectException")
     {
         if (objectCreateExpression.ArgumentList.Arguments.Count >= 1)
         {
             paramNode = objectCreateExpression.ArgumentList.Arguments[0].Expression;
         }
         return paramNode != null;
     }
     return false;
 }
        //--- Class Methods ---
        public static IEnumerable<ISymbol> GetMissingEnumMembers(SwitchStatementSyntax switchNode, SemanticModel semanticModel, out IdentifierNameSyntax switchVariable)
        {
            // TODO (2016-02-25, steveb): what if the swich calls a function instead?
            switchVariable = switchNode.Expression as IdentifierNameSyntax;
            if(switchVariable == null) {
                return Enumerable.Empty<ISymbol>();
            }
            var switchVariableTypeInfo = semanticModel.GetTypeInfo(switchVariable);

            // check if we are switching over an enum
            if((switchVariableTypeInfo.Type != null) && (switchVariableTypeInfo.Type.TypeKind == TypeKind.Enum)) {

                // get all the enum values
                var enumMembers = switchVariableTypeInfo.Type.GetMembers().Where(x => x.Kind == SymbolKind.Field).ToImmutableArray();

                // get all case statements
                var caseSwitchLabels = switchNode.Sections
                    .SelectMany(section => section.Labels)
                    .Select(label => label.DescendantNodes().OfType<MemberAccessExpressionSyntax>().FirstOrDefault())
                    .Where(memberAccess => memberAccess != null)
                    .Select(memberAccess => semanticModel.GetSymbolInfo(memberAccess).Symbol)
                    .ToImmutableHashSet();

                // make sure we have all cases covered
                return enumMembers.Where(x => !caseSwitchLabels.Contains(x)).ToImmutableArray();
            }
            return Enumerable.Empty<ISymbol>();
        }
 private static bool AnyArgumentIsValueType(ArgumentListSyntax argumentList, SemanticModel semanticModel)
 {
     return argumentList.Arguments.Any(argument =>
     {
         var type = semanticModel.GetTypeInfo(argument.Expression).Type;
         return type != null && type.IsValueType;
     });
 }
 protected void GetDiagnosticsForNode(SyntaxNode node, SemanticModel model, Action<Diagnostic> addDiagnostic)
 {
     var type = model.GetTypeInfo(node).Type;
     if (type != null && TypeHasWeakIdentity(type, model))
     {
         addDiagnostic(node.CreateDiagnostic(Rule, type.ToDisplayString()));
     }
 }
 internal static bool IsCast(SemanticModel model, SyntaxNode n, ITypeSymbol type)
 {
     var expr = n as ExpressionSyntax;
     if (expr == null)
         return false;
     expr = expr.SkipParens();
     var castExpr = expr as CastExpressionSyntax;
     if (castExpr != null)
     {
         return model.GetTypeInfo(castExpr.Type).Type == type;
     }
     var binExpr = expr as BinaryExpressionSyntax;
     if (binExpr != null)
     {
         return binExpr.IsKind(SyntaxKind.AsExpression) && model.GetTypeInfo(binExpr.Right).Type == type;
     }
     return false;
 }
 internal static bool RequireReturnStatement(SemanticModel model, SyntaxNode lambda)
 {
     var typeInfo = model.GetTypeInfo(lambda);
     var type = typeInfo.ConvertedType ?? typeInfo.Type;
     if (type == null || !type.IsDelegateType())
         return false;
     var returnType = type.GetDelegateInvokeMethod().GetReturnType();
     return returnType != null && returnType.SpecialType != SpecialType.System_Void;
 }
 internal static ExpressionSyntax UnpackNullableValueAccess(SemanticModel semanticModel, ExpressionSyntax expression, CancellationToken cancellationToken)
 {
     var expr = expression.SkipParens();
     if (!expr.IsKind(SyntaxKind.SimpleMemberAccessExpression))
         return expression;
     var info = semanticModel.GetTypeInfo(((MemberAccessExpressionSyntax)expr).Expression, cancellationToken);
     if (!info.ConvertedType.IsNullableType())
         return expression;
     return ((MemberAccessExpressionSyntax)expr).Expression;
 }
        internal static bool ShouldReportOnCollectionNode(SemanticModel semanticModel, SyntaxNode argument) {
            const bool returnIfUnknown = false;

            // if the variable is an invocation syntax we can assume that it was returned materialized, if it's not an extension method
            switch(argument.Kind()) {
            case SyntaxKind.InvocationExpression:
                var methodCallInfo = semanticModel.GetSymbolInfo(argument);
                if((methodCallInfo.Symbol != null) && (methodCallInfo.Symbol.Kind == SymbolKind.Method)) {
                    var mSymbol = (IMethodSymbol)methodCallInfo.Symbol;
                    var typeInfo = semanticModel.GetTypeInfo(argument);

                    // If the method is not an extension method, we assume it returned a materialized collection
                    return IsAbstractCollectionType(typeInfo) && mSymbol.IsExtensionMethod && mSymbol.ContainingNamespace.ToDisplayString().Equals("System.Linq");
                }
                break;
            case SyntaxKind.IdentifierName:
                var identifierInfo = semanticModel.GetSymbolInfo(argument);

                // if this identifier came straight from a parameter, assume it is materialized
                if(identifierInfo.Symbol != null && identifierInfo.Symbol.Kind == SymbolKind.Parameter) {

                    //TODO(2016-02-24, yurig): if parameter is modified locally, we should warn
                    return false;
                }

                // if this is a local identifier, look at where it is defined
                if(identifierInfo.Symbol != null && identifierInfo.Symbol.Kind == SymbolKind.Local) {
                    var declaration = identifierInfo.Symbol.DeclaringSyntaxReferences.FirstOrDefault();

                    // if the declaration is an equals expression, dive into it.
                    var equalsExpression = declaration?.GetSyntax()
                        .ChildNodes()
                        .FirstOrDefault(x => x.Kind() == SyntaxKind.EqualsValueClause);
                    var firstChild = equalsExpression?.ChildNodes().FirstOrDefault();
                    if(firstChild != null) {
                        return ShouldReportOnCollectionNode(semanticModel, firstChild);
                    }

                    // if the variable was assigned somewhere else, find it
                    var containingClass = declaration?.GetSyntax().FirstAncestorOrSelf<MethodDeclarationSyntax>();
                    var localAssignment = containingClass?.DescendantNodes().OfType<AssignmentExpressionSyntax>()
                        .Where(x => x.Left.IsKind(SyntaxKind.IdentifierName))
                        .LastOrDefault(x => (x.Left as IdentifierNameSyntax).Identifier.Text.Equals(((IdentifierNameSyntax)argument).Identifier.Text));
                    if(localAssignment != null) {
                        return ShouldReportOnCollectionNode(semanticModel, localAssignment.Right);
                    }
                }
                break;
            case SyntaxKind.SimpleMemberAccessExpression:

                // Assume that member accesses are returned materialized
                return false;
            }
            return returnIfUnknown;
        }
Пример #16
0
        public Statement GetStatement()
        {
            var typeInfo          = semanticModel.GetTypeInfo(literalExpressionSyntax);
            var constantStatement = new ConstantStatement(literalExpressionSyntax.Token.Value);

            if (literalExpressionSyntax.Token.Value != null)
            {
                constantStatement.Type = typeInfo.GetClassType();
            }
            return(constantStatement);
        }
        public ITypeSymbol GetThrownExceptionTypeSymbol(SemanticModel semanticModel, ThrowStatementSyntax throwStatementSyntax)
        {
            SemanticModel = semanticModel;
            ThrowStatementSyntax = throwStatementSyntax;

            SyntaxNode syntaxNodeToGetTypeOf = ThrowStatementSyntax.Expression;

            if (syntaxNodeToGetTypeOf == null)
                syntaxNodeToGetTypeOf = GetCatchClaue();

            if (syntaxNodeToGetTypeOf == null)
                return null; //Not sure this is possible....

            return semanticModel.GetTypeInfo(syntaxNodeToGetTypeOf).Type;
        }
Пример #18
0
        public static IEnumerable<SyntaxNode> CreateFixedYieldReturn(this YieldStatementSyntax yieldStatement, SemanticModel semanticModel)
        {
            var typeInfo = semanticModel.GetTypeInfo(yieldStatement.Expression);
            var type = typeInfo.Type as INamedTypeSymbol;

            var task = SyntaxFactory.IdentifierName(TaskName);
            yield return CreateLocalVariableDeclaration(TaskName, yieldStatement.Expression);
            yield return CreateYieldReturnIfNotCompleted(task);
            yield return CreateThrowIfException(task);

            if (type.TypeArguments.Count() == 1)
            {
                var exp = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, task, SyntaxFactory.IdentifierName("Result"));
                yield return CreateLocalVariableDeclaration("_result", exp);
            }
        }
        private static SyntaxToken GetNewLiteral(LiteralExpressionSyntax literal, SemanticModel semanticModel)
        {
            var type = semanticModel.GetTypeInfo(literal).Type;
            var text = literal.Token.Text;
            var reversedText = text.Reverse();
            var reversedTextEnding = new string(reversedText.TakeWhile(char.IsLetter).ToArray());
            var reversedTextBeginning = new string(reversedText.SkipWhile(char.IsLetter).ToArray());
            var newText = new string((reversedTextEnding.ToUpperInvariant() + reversedTextBeginning).Reverse().ToArray());

            switch (type.SpecialType)
            {
                case SpecialType.System_Int32:
                    return SyntaxFactory.Literal(
                        newText,
                        (int)literal.Token.Value);
                case SpecialType.System_Char:
                    return SyntaxFactory.Literal(
                        newText,
                        (char)literal.Token.Value);
                case SpecialType.System_UInt32:
                    return SyntaxFactory.Literal(
                        newText,
                        (uint)literal.Token.Value);
                case SpecialType.System_Int64:
                    return SyntaxFactory.Literal(
                        newText,
                        (long)literal.Token.Value);
                case SpecialType.System_UInt64:
                    return SyntaxFactory.Literal(
                        newText,
                        (ulong)literal.Token.Value);
                case SpecialType.System_Decimal:
                    return SyntaxFactory.Literal(
                        newText,
                        (decimal)literal.Token.Value);
                case SpecialType.System_Single:
                    return SyntaxFactory.Literal(
                        newText,
                        (float)literal.Token.Value);
                case SpecialType.System_Double:
                    return SyntaxFactory.Literal(
                        newText,
                        (double)literal.Token.Value);
                default:
                    return SyntaxFactory.Token(SyntaxKind.None);
            }
        }
Пример #20
0
        public Statement GetStatement()
        {
            var lamdaStatement = new LamdaStatement();

            var parameters = anonymousMethodExpressionSyntax.ParameterList?.Parameters
                             .Select(x => statementInterpreterHandler.GetStatement(x));

            lamdaStatement.Parameters = parameters?.Cast <Parameter>()?.ToArray() ?? new Parameter[0];

            lamdaStatement.Body = statementInterpreterHandler.GetStatement(anonymousMethodExpressionSyntax.Body);

            var typeInfo = semanticModel.GetTypeInfo(anonymousMethodExpressionSyntax);

            lamdaStatement.Type = typeInfo.ConvertedType.GetClassType();

            return(lamdaStatement);
        }
 private static void CheckParam(InvocationExpressionSyntax invocationExpression, IMethodSymbol methodInfo, SemanticModel semanticModel, Action<Diagnostic> reportDiagnostic, string filePath, CancellationToken cancellationToken)
 {
     var arguments = invocationExpression.ArgumentList.Arguments;
     if (arguments.Count != methodInfo.Parameters.Length)
     {
         reportDiagnostic(Diagnostic.Create(ParamsParameterRule, invocationExpression.GetLocation(), EmptyMessageArgs));
         HeapAllocationAnalyzerEventSource.Logger.ParamsAllocation(filePath);
     }
     else
     {
         var lastIndex = arguments.Count - 1;
         var lastArgumentTypeInfo = semanticModel.GetTypeInfo(arguments[lastIndex].Expression, cancellationToken);
         if (lastArgumentTypeInfo.Type != null && !lastArgumentTypeInfo.Type.Equals(methodInfo.Parameters[lastIndex].Type))
         {
             reportDiagnostic(Diagnostic.Create(ParamsParameterRule, invocationExpression.GetLocation(), EmptyMessageArgs));
             HeapAllocationAnalyzerEventSource.Logger.ParamsAllocation(filePath);
         }
     }
 }
Пример #22
0
        public Statement GetStatement()
        {
            var lamdaStatement = new LamdaStatement();

            var parameters = parenthesizedLambdaExpressionSyntax.ParameterList.Parameters
                             .Select(x => statementInterpreterHandler.GetStatement(x));

            lamdaStatement.Parameters = parameters.Cast <Parameter>().ToArray();

            lamdaStatement.Body = statementInterpreterHandler.GetStatement(parenthesizedLambdaExpressionSyntax.Body);

            var typeInfo = semanticModel.GetTypeInfo(parenthesizedLambdaExpressionSyntax);

            lamdaStatement.Type = typeInfo.ConvertedType.GetClassType();

            lamdaStatement.IsAsync = parenthesizedLambdaExpressionSyntax.AsyncKeyword.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.AsyncKeyword);

            return(lamdaStatement);
        }
        private static bool IsTask(ExpressionSyntax expression, SemanticModel semanticModel)
        {
            var type = semanticModel.GetTypeInfo(expression).Type as INamedTypeSymbol;
            if (type == null)
            {
                return false;
            }

            INamedTypeSymbol taskType;
            if (type.IsGenericType)
            {
                type = type.ConstructedFrom;
                taskType = semanticModel.Compilation.GetTypeByMetadataName(typeof(Task<>).FullName);
            }
            else
            {
                taskType = semanticModel.Compilation.GetTypeByMetadataName(typeof(Task).FullName);
            }

            return type.Equals(taskType);
        }
        public Statement GetStatement()
        {
            var parameterType = semanticModel.GetTypeInfo(forEachStatementSyntax.Type).GetClassType();

            var parameter = new LocalVariableDeclaration
            {
                Type = parameterType,
                Name = forEachStatementSyntax.Identifier.ValueText
            };

            var collection = statementInterpreterHandler.GetStatement(forEachStatementSyntax.Expression);

            var body = statementInterpreterHandler.GetStatement(forEachStatementSyntax.Statement);

            return(new ForEachStatement
            {
                Variable = parameter,
                Collection = collection,
                Body = body
            });
        }
        public AttributeInspector(AttributeSyntax attributeSyntax, SemanticModel semanticModel)
        {
            _attributeName = attributeSyntax.Name.ToString();

            TypeInfo typeInfo = semanticModel.GetTypeInfo(attributeSyntax);
            ITypeSymbol typeSymbol = typeInfo.Type;
            _attributeQualifiedName = typeSymbol.ToString();

            var unamedArguments = new List<string>();
            var namedArguments = new Dictionary<string, string>();
            if (attributeSyntax.ArgumentList != null)
            {
                foreach (AttributeArgumentSyntax attributeArgumentSyntax in attributeSyntax.ArgumentList.Arguments)
                {
                    String argValue = attributeArgumentSyntax.Expression.ToString();
                    if (attributeArgumentSyntax.NameEquals != null)
                    {
                        string argName = attributeArgumentSyntax.NameEquals.Name.Identifier.Text;
                        namedArguments.Add(argName, argValue);
                    }
                    else
                    {
                        // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
                        if (argValue.StartsWith("@"))
                        {
                            argValue = argValue.Remove(0, 1).Replace("\"\"", "\"");
                        }
                        else
                        {
                            argValue = Regex.Unescape(argValue);
                        }
                        argValue = argValue.Trim('"');
                        unamedArguments.Add(argValue);
                    }
                }
            }
            _unamedArguments = unamedArguments.AsReadOnly();
            _namedArguments = new ReadOnlyDictionary<string, string>(namedArguments);
        }
        internal static ExpressionSyntax GetSwitchExpression(SemanticModel context, ExpressionSyntax expr)
        {
            var binaryOp = expr as BinaryExpressionSyntax;
            if (binaryOp == null)
                return null;

            if (binaryOp.OperatorToken.IsKind(SyntaxKind.LogicalOrExpression))
                return GetSwitchExpression(context, binaryOp.Left);

            if (binaryOp.OperatorToken.IsKind(SyntaxKind.EqualsEqualsToken))
            {
                ExpressionSyntax switchExpr = null;
                if (IsConstantExpression(context, binaryOp.Right))
                    switchExpr = binaryOp.Left;
                if (IsConstantExpression(context, binaryOp.Left))
                    switchExpr = binaryOp.Right;
                if (switchExpr != null && IsValidSwitchType(context.GetTypeInfo(switchExpr).Type))
                    return switchExpr;
            }

            return null;
        }
Пример #27
0
        public static bool TryGetAttribute(this SyntaxList<AttributeListSyntax> attributeLists, KnownType attributeKnownType,
            SemanticModel semanticModel, out AttributeSyntax searchedAttribute)
        {
            searchedAttribute = null;

            if (!attributeLists.Any())
            {
                return false;
            }

            foreach (var attribute in attributeLists.SelectMany(attributeList => attributeList.Attributes))
            {
                var attributeType = semanticModel.GetTypeInfo(attribute).Type;

                if (attributeType.Is(attributeKnownType))
                {
                    searchedAttribute = attribute;
                    return true;
                }
            }

            return false;
        }
Пример #28
0
        public Statement GetStatement()
        {
            var catchStatement = new CatchStatement();

            catchStatement.Block  = statementInterpreterHandler.GetStatement(catchClauseSyntax.Block);
            catchStatement.Filter = catchClauseSyntax.Filter == null ?
                                    null : statementInterpreterHandler.GetStatement(catchClauseSyntax.Filter.FilterExpression);

            if (catchClauseSyntax.Declaration != null)
            {
                catchStatement.Type = semanticModel.GetTypeInfo(catchClauseSyntax.Declaration.Type).GetClassType();

                if (!catchClauseSyntax.Declaration.Identifier.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.None))
                {
                    catchStatement.Variable = new LocalVariableDeclaration
                    {
                        Type = catchStatement.Type,
                        Name = catchClauseSyntax.Declaration.Identifier.ValueText
                    };
                }
            }
            return(catchStatement);
        }
        //--- Class Methods ---
        public static IEnumerable<ISymbol> GetMissingEnumMembers(SyntaxNode switchNode, SemanticModel semanticModel, out IdentifierNameSyntax switchVariable)
        {
            switchVariable = switchNode.DescendantNodes().OfType<IdentifierNameSyntax>().First();
            var switchVariableTypeInfo = semanticModel.GetTypeInfo(switchVariable);

            // check if we are switching over an enum
            if(switchVariableTypeInfo.Type.TypeKind == TypeKind.Enum) {

                // get all the enum values
                var enumMembers = switchVariableTypeInfo.Type.GetMembers().Where(x => x.Kind == SymbolKind.Field).ToImmutableArray();

                // get all case statements
                var caseSwitchLabels = switchNode
                    .DescendantNodes().OfType<CaseSwitchLabelSyntax>()
                    .Select(x => x.DescendantNodes().OfType<MemberAccessExpressionSyntax>().FirstOrDefault())
                    .Where(x => x != null)
                    .Select(x => semanticModel.GetSymbolInfo(x).Symbol)
                    .ToImmutableHashSet();

                // make sure we have all cases covered
                return enumMembers.Where(x => !caseSwitchLabels.Contains(x)).ToImmutableArray();
            }
            return Enumerable.Empty<ISymbol>();
        }
 internal static bool CheckExceptionType(SemanticModel model, ObjectCreationExpressionSyntax objectCreateExpression, out ExpressionSyntax paramNode, out ExpressionSyntax altParam, out bool canAddParameterName)
 {
     paramNode = null;
     altParam = null;
     canAddParameterName = false;
     var type = model.GetTypeInfo(objectCreateExpression).Type;
     if (type == null)
         return false;
     if (type.Name == typeof(ArgumentException).Name)
     {
         if (objectCreateExpression.ArgumentList.Arguments.Count >= 2)
         {
             altParam = objectCreateExpression.ArgumentList.Arguments[0].Expression;
             paramNode = objectCreateExpression.ArgumentList.Arguments[1].Expression;
         }
         return paramNode != null;
     }
     if (type.Name == typeof(ArgumentNullException).Name ||
         type.Name == typeof(ArgumentOutOfRangeException).Name ||
         type.Name == "DuplicateWaitObjectException")
     {
         canAddParameterName = objectCreateExpression.ArgumentList.Arguments.Count == 1;
         if (objectCreateExpression.ArgumentList.Arguments.Count >= 1)
         {
             paramNode = objectCreateExpression.ArgumentList.Arguments[0].Expression;
             if (objectCreateExpression.ArgumentList.Arguments.Count == 2)
             {
                 altParam = objectCreateExpression.ArgumentList.Arguments[1].Expression;
                 if (model.GetTypeInfo(altParam).Type?.SpecialType != SpecialType.System_String)
                     paramNode = null;
             }
             if (objectCreateExpression.ArgumentList.Arguments.Count == 3)
                 altParam = objectCreateExpression.ArgumentList.Arguments[2].Expression;
         }
         return paramNode != null;
     }
     return false;
 }
        //		static IEnumerable<ITypeSymbol> GetAllValidTypesFromObjectCreation(SemanticModel resolver, ObjectCreateExpressionSyntax invoke, SyntaxNode parameter)
        //		{
        //			int index = GetArgumentIndex(invoke.Arguments, parameter);
        //			if (index < 0)
        //				yield break;
        //
        //			var targetResult = resolver.Resolve(invoke.Type);
        //			if (targetResult is TypeResolveResult) {
        //				var type = ((TypeResolveResult)targetResult).Type;
        //				if (type.Kind == TypeKind.Delegate && index == 0) {
        //					yield return type;
        //					yield break;
        //				}
        //				foreach (var constructor in type.GetConstructors ()) {
        //					if (index < constructor.Parameters.Count)
        //						yield return constructor.Parameters [index].Type;
        //				}
        //			}
        //		}
        //
        //		public static ITypeSymbol GetElementType(SemanticModel resolver, ITypeSymbol type)
        //		{
        //			// TODO: A better get element type method.
        //			if (type.Kind == TypeKind.Array || type.Kind == TypeKind.Dynamic) {
        //				if (type.Kind == TypeKind.Array)
        //					return ((ArrayType)type).ElementType;
        //				return resolver.Compilation.FindType(KnownTypeCode.Object);
        //			}
        //
        //
        //			foreach (var method in type.GetMethods (m => m.Name == "GetEnumerator")) {
        //				ITypeSymbol returnType = null;
        //				foreach (var prop in method.ReturnType.GetProperties(p => p.Name == "Current")) {
        //					if (returnType != null && prop.ReturnType.IsKnownType (KnownTypeCode.Object))
        //						continue;
        //					returnType = prop.ReturnType;
        //				}
        //				if (returnType != null)
        //					return returnType;
        //			}
        //
        //			return resolver.Compilation.FindType(KnownTypeCode.Object);
        //		}
        //
        //		static IEnumerable<ITypeSymbol> GuessFromConstructorInitializer(SemanticModel resolver, SyntaxNode expr)
        //		{
        //			var init = expr.Parent as ConstructorInitializer;
        //			var rr = resolver.Resolve(expr.Parent);
        //			int index = GetArgumentIndex(init.Arguments, expr);
        //			if (index >= 0) {
        //				foreach (var constructor in rr.Type.GetConstructors()) {
        //					if (index < constructor.Parameters.Count) {
        //						yield return constructor.Parameters[index].Type;
        //					}
        //				}
        //			}
        //		}

        public static IEnumerable<ITypeSymbol> GetValidTypes(SemanticModel model, SyntaxNode expr, CancellationToken cancellationToken = default(CancellationToken))
        {
            //			if (expr.Role == Roles.Condition) {
            //				return new [] { model.Compilation.FindType (KnownTypeCode.Boolean) };
            //			}
            //
            var mref = expr.Parent as MemberAccessExpressionSyntax;
            if (mref != null && mref.Name != expr)
            {
                mref = null;
            }
            if (mref != null)
            {
                // case: guess enum when trying to access not existent enum member
                var rr = model.GetTypeInfo(mref.Expression);
                if (rr.Type != null && rr.Type.TypeKind == TypeKind.Enum)
                    return new[] { rr.Type };
            }

            //			if (expr.Parent is ParenthesizedExpressionSyntax || expr.Parent is NamedArgumentExpressionSyntax) {
            //				return GetValidTypes(model, expr.Parent);
            //			}
            //			if (expr.Parent is DirectionExpressionSyntax) {
            //				var parent = expr.Parent.Parent;
            //				if (parent is InvocationExpressionSyntax) {
            //					var invoke = (InvocationExpressionSyntax)parent;
            //					return GetAllValidTypesFromInvocation(model, invoke, expr.Parent);
            //				}
            //			}
            //
            //			if (expr.Parent is ArrayInitializerExpressionSyntax) {
            //				if (expr is NamedExpressionSyntax)
            //					return new [] { model.Resolve(((NamedExpressionSyntax)expr).ExpressionSyntax).Type };
            //
            //				var aex = expr.Parent as ArrayInitializerExpressionSyntax;
            //				if (aex.IsSingleElement)
            //					aex = aex.Parent as ArrayInitializerExpressionSyntax;
            //				var type = GetElementType(model, model.Resolve(aex.Parent).Type);
            //				if (type.Kind != TypeKind.Unknown)
            //					return new [] { type };
            //			}
            //
            //			if (expr.Parent is ObjectCreateExpressionSyntax) {
            //				var invoke = (ObjectCreateExpressionSyntax)expr.Parent;
            //				return GetAllValidTypesFromObjectCreation(model, invoke, expr);
            //			}
            //
            //			if (expr.Parent is ArrayCreateExpressionSyntax) {
            //				var ace = (ArrayCreateExpressionSyntax)expr.Parent;
            //				if (!ace.Type.IsNull) {
            //					return new [] { model.Resolve(ace.Type).Type };
            //				}
            //			}
            //
            //			if (expr.Parent is VariableInitializer) {
            //				var initializer = (VariableInitializer)expr.Parent;
            //				var field = initializer.GetParent<FieldDeclaration>();
            //				if (field != null) {
            //					var rr = model.Resolve(field.ReturnType);
            //					if (!rr.IsError)
            //						return new [] { rr.Type };
            //				}
            //				var varStmt = initializer.GetParent<VariableDeclarationStatement>();
            //				if (varStmt != null) {
            //					var rr = model.Resolve(varStmt.Type);
            //					if (!rr.IsError)
            //						return new [] { rr.Type };
            //				}
            //				return new [] { model.Resolve(initializer).Type };
            //			}
            //
            //			if (expr.Parent is CastExpressionSyntax) {
            //				var cast = (CastExpressionSyntax)expr.Parent;
            //				return new [] { model.Resolve(cast.Type).Type };
            //			}
            //
            //			if (expr.Parent is AsExpressionSyntax) {
            //				var cast = (AsExpressionSyntax)expr.Parent;
            //				return new [] { model.Resolve(cast.Type).Type };
            //			}

            if (expr.Parent is AssignmentExpressionSyntax || mref != null && mref.Parent is AssignmentExpressionSyntax)
            {
                var assign = expr.Parent as AssignmentExpressionSyntax ?? mref.Parent as AssignmentExpressionSyntax;
                var other = assign.Left == expr || assign.Left == mref ? assign.Right : assign.Left;
                return new[] { model.GetTypeInfo(other).Type };
            }

            //			if (expr.Parent is BinaryOperatorExpressionSyntax) {
            //				var assign = (BinaryOperatorExpressionSyntax)expr.Parent;
            //				var other = assign.Left == expr ? assign.Right : assign.Left;
            //				return new [] { model.Resolve(other).Type };
            //			}
            //
            //			if (expr.Parent is ReturnStatement) {
            //				var parent = expr.Ancestors.FirstOrDefault(n => n is EntityDeclaration || n is AnonymousMethodExpressionSyntax|| n is LambdaExpressionSyntax);
            //				if (parent != null) {
            //					var rr = model.Resolve(parent);
            //					if (!rr.IsError)
            //						return new [] { rr.Type };
            //				}
            //				var e = parent as EntityDeclaration;
            //				if (e != null) {
            //					var rt = model.Resolve(e.ReturnType);
            //					if (!rt.IsError)
            //						return new [] { rt.Type };
            //				}
            //			}
            //
            //			if (expr.Parent is YieldReturnStatement) {
            //				var state = model.GetResolverStateBefore(expr);
            //				if (state != null && (state.CurrentMember.ReturnType is ParameterizedType)) {
            //					var pt = (ParameterizedType)state.CurrentMember.ReturnType;
            //					if (pt.FullName == "System.Collections.Generic.IEnumerable") {
            //						return new [] { pt.TypeArguments.First() };
            //					}
            //				}
            //			}
            //
            //			if (expr.Parent is UnaryOperatorExpressionSyntax) {
            //				var uop = (UnaryOperatorExpressionSyntax)expr.Parent;
            //				switch (uop.Operator) {
            //					case UnaryOperatorType.Not:
            //						return new [] { model.Compilation.FindType(KnownTypeCode.Boolean) };
            //						case UnaryOperatorType.Minus:
            //						case UnaryOperatorType.Plus:
            //						case UnaryOperatorType.Increment:
            //						case UnaryOperatorType.Decrement:
            //						case UnaryOperatorType.PostIncrement:
            //						case UnaryOperatorType.PostDecrement:
            //						return new [] { model.Compilation.FindType(KnownTypeCode.Int32) };
            //				}
            //			}
            //
            //			if (expr.Parent is ConstructorInitializer)
            //				return GuessFromConstructorInitializer(model, expr);
            //
            //			if (expr.Parent is NamedExpressionSyntax) {
            //				var rr = model.Resolve(expr.Parent);
            //				if (!rr.IsError) {
            //					return new [] { rr.Type };
            //				}
            //			}

            if (expr.IsKind(SyntaxKind.Argument))
            {
                var parent = expr.Parent.Parent;
                var invocationParent = parent as InvocationExpressionSyntax;
                if (invocationParent != null)
                {
                    return GetAllValidTypesFromInvocation(model, invocationParent, expr);
                }
            }

            var types = typeInferenceService.InferTypes(model, expr, cancellationToken).ToList();

            return types;
        }
        public override SyntaxNode RemoveImplementedInterface(SyntaxNode node, ITypeSymbol typeSymbol, SemanticModel semanticModel)
        {
            if (!node.IsKind(SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration))
            {
                throw Exceptions.ThrowEFail();
            }

            var typeDeclaration = (TypeDeclarationSyntax)node;
            if (typeDeclaration.BaseList == null ||
                typeDeclaration.BaseList.Types.Count == 0)
            {
                throw Exceptions.ThrowEInvalidArg();
            }

            BaseTypeSyntax baseType = null;
            foreach (var type in typeDeclaration.BaseList.Types)
            {
                var typeInfo = semanticModel.GetTypeInfo(type.Type, CancellationToken.None);
                if (typeInfo.Type != null &&
                    typeInfo.Type.Equals(typeSymbol))
                {
                    baseType = type;
                    break;
                }
            }

            if (baseType == null)
            {
                throw Exceptions.ThrowEInvalidArg();
            }

            var newTypes = typeDeclaration.BaseList.Types.Remove(baseType);
            var newBaseList = typeDeclaration.BaseList.WithTypes(newTypes);
            if (newBaseList.Types.Count == 0)
            {
                newBaseList = null;
            }

            return typeDeclaration.WithBaseList(newBaseList);
        }
 private static bool IsEventHandlerLike(MethodDeclarationSyntax method, SemanticModel semanticModel)
 {
     if (method.ParameterList.Parameters.Count != 2
         || method.ReturnType.ToString() != "void")
         return false;
     var senderType = semanticModel.GetTypeInfo(method.ParameterList.Parameters[0].Type).Type;
     if (senderType.SpecialType != SpecialType.System_Object) return false;
     var eventArgsType = semanticModel.GetTypeInfo(method.ParameterList.Parameters[1].Type).Type as INamedTypeSymbol;
     if (eventArgsType == null) return false;
     return eventArgsType.AllBaseTypesAndSelf().Any(type => type.ToString() == "System.EventArgs");
 }
 private static bool IsSerializationConstructor(ConstructorDeclarationSyntax constructor, SemanticModel semanticModel)
 {
     if (constructor.ParameterList.Parameters.Count != 2) return false;
     var constructorSymbol = semanticModel.GetDeclaredSymbol(constructor);
     var typeSymbol = constructorSymbol?.ContainingType;
     if (!typeSymbol?.AllInterfaces.Any(i => i.ToString() == "System.Runtime.Serialization.ISerializable") ?? true) return false;
     if (!typeSymbol.GetAttributes().Any(a => a.AttributeClass.ToString() == "System.SerializableAttribute")) return false;
     var serializationInfoType = semanticModel.GetTypeInfo(constructor.ParameterList.Parameters[0].Type).Type as INamedTypeSymbol;
     if (serializationInfoType == null) return false;
     if (!serializationInfoType.AllBaseTypesAndSelf().Any(type => type.ToString() == "System.Runtime.Serialization.SerializationInfo"))
         return false;
     var streamingContextType = semanticModel.GetTypeInfo(constructor.ParameterList.Parameters[1].Type).Type as INamedTypeSymbol;
     if (streamingContextType == null) return false;
     return streamingContextType.AllBaseTypesAndSelf().Any(type => type.ToString() == "System.Runtime.Serialization.StreamingContext");
 }
        public override string GetFullName(SyntaxNode node, SemanticModel semanticModel)
        {
            if (node.Kind() == SyntaxKind.UsingDirective)
            {
                throw Exceptions.ThrowEFail();
            }

            var symbol = node is AttributeSyntax
                ? semanticModel.GetTypeInfo(node).Type
                : semanticModel.GetDeclaredSymbol(node);

            return GetExternalSymbolFullName(symbol);
        }