private static bool CheckIfConstructorAlreadyExists(SemanticModel model, BaseMethodDeclarationSyntax methodDeclaration,
                                                            TypeDeclarationSyntax typeDeclaration, CancellationToken cancellationToken)
        {
            var constructors = typeDeclaration.DescendantNodes().OfType <ConstructorDeclarationSyntax>().Where(ctor => ctor != methodDeclaration).ToList();

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

            foreach (var constructor in constructors)
            {
                if (constructor.ParameterList.Parameters.Count == methodDeclaration.ParameterList.Parameters.Count)
                {
                    for (int i = 0; i < constructor.ParameterList.Parameters.Count; i++)
                    {
                        var constructorParameter = model.GetDeclaredSymbol(constructor.ParameterList.Parameters[i], cancellationToken) as IParameterSymbol;
                        var methodParameter      = model.GetDeclaredSymbol(methodDeclaration.ParameterList.Parameters[i], cancellationToken) as IParameterSymbol;
                        if (constructorParameter.Type != methodParameter.Type)
                        {
                            return(false);
                        }
                    }

                    return(true);
                }
            }

            return(false);
        }
        private static ConstructorDeclarationSyntax InitializeStructFields(FieldDeclarationSyntax fieldDeclaration, TypeDeclarationSyntax typeDeclaration, ConstructorDeclarationSyntax newConstructor)
        {
            if (typeDeclaration is StructDeclarationSyntax)
            {
                var assignments = new List <ExpressionStatementSyntax>();
                var otherFields = typeDeclaration.DescendantNodes().OfType <FieldDeclarationSyntax>()
                                  .Where(field => field != fieldDeclaration).ToList();
                foreach (var field in otherFields)
                {
                    var variableDeclaration = field.DescendantNodes().OfType <VariableDeclarationSyntax>().FirstOrDefault();
                    var variableDeclarator  = variableDeclaration?.DescendantNodes().OfType <VariableDeclaratorSyntax>().FirstOrDefault();
                    if (variableDeclarator != null)
                    {
                        assignments.Add(
                            CreateDefaultAssignmentStatement(variableDeclarator.Identifier.ValueText, variableDeclaration.Type));
                    }
                }

                if (assignments.Any())
                {
                    newConstructor = newConstructor.WithBody(newConstructor.Body.AddStatements(assignments.ToArray()));
                }
            }

            return(newConstructor);
        }
        private static bool CheckIfConstructorWithSingleParameterExists(SemanticModel model, VariableDeclaratorSyntax variableDeclarator,
                                                                        TypeDeclarationSyntax typeDeclaration, CancellationToken cancellationToken)
        {
            var constructors = typeDeclaration.DescendantNodes().OfType <ConstructorDeclarationSyntax>()
                               .Where(constructor => constructor.ParameterList.Parameters.Count == 1).ToList();

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

            var fieldSymbol = model.GetDeclaredSymbol(variableDeclarator, cancellationToken) as IFieldSymbol;

            foreach (var constructor in constructors)
            {
                var parameterSymbol = model.GetDeclaredSymbol(constructor.ParameterList.Parameters[0], cancellationToken) as IParameterSymbol;
                if (fieldSymbol != null && parameterSymbol != null &&
                    fieldSymbol.Type == parameterSymbol.Type)
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #4
0
        private static TypeDeclarationSyntax AddGeneratedItems <T>(ClassModel classModel, TypeDeclarationSyntax declaration, ItemGenerationStrategyFactory <T> factory, Func <ClassModel, IEnumerable <T> > selector, bool withRegeneration)
        {
            foreach (var property in selector(classModel))
            {
                foreach (var method in factory.CreateFor(property, classModel))
                {
                    var methodName     = method.Identifier.Text;
                    var existingMethod = declaration.DescendantNodes().OfType <MethodDeclarationSyntax>().FirstOrDefault(x => string.Equals(x.Identifier.Text, methodName, StringComparison.OrdinalIgnoreCase));

                    if (existingMethod != null)
                    {
                        if (!withRegeneration)
                        {
                            throw new InvalidOperationException("One or more of the generated methods ('" + methodName + "') already exists in the test class. In order to over-write existing tests, hold left shift while right-clicking and select the 'Regenerate' option.");
                        }

                        declaration = declaration.ReplaceNode(existingMethod, method);
                    }
                    else
                    {
                        declaration = declaration.AddMembers(method);
                    }
                }
            }

            return(declaration);
        }
        static async Task <Solution> MakeImmutableAsync(Document document, TypeDeclarationSyntax typeDecl, CancellationToken cancellationToken)
        {
            var fieldDeclarations         = typeDecl.DescendantNodes().OfType <FieldDeclarationSyntax>();
            var readonlyFieldDeclarations = fieldDeclarations
                                            .Where(field => field.Modifiers.Any(modifier => modifier.Kind() == ReadOnlyKeyword)).ToArray();

            var @class = new Class(typeDecl.Identifier.ValueText);

            var fields = readonlyFieldDeclarations.SelectMany(field =>
                                                              field.Declaration.Variables.Select(variable =>
                                                                                                 new Field(field.Declaration.Type, variable.Identifier.ValueText))).ToArray();

            var documentEditor = await DocumentEditor.CreateAsync(document, cancellationToken);

            var properties  = GetProperties(fields).ToArray();
            var constructor = GetConstructor(@class, fields);
            var method      = GetWith(@class, fields);
            var optional    = GetOptional();

            var all = List <MemberDeclarationSyntax>(properties).Add(constructor).Add(method).Add(optional).ToArray();
            var surroundedByRegion = SurroundWithRegion(all);

            documentEditor.InsertAfter(readonlyFieldDeclarations.Last(), surroundedByRegion);

            return(document.Project.Solution.WithDocumentText(
                       document.Id,
                       await documentEditor.GetChangedDocument().GetTextAsync(cancellationToken)));
        }
예제 #6
0
        private bool HasPublicProperties(TypeDeclarationSyntax declaration)
        {
            var properties = declaration.DescendantNodes().OfType <PropertyDeclarationSyntax>();

            return(properties.Where(property => property.DescendantTokens().Any(t => t.RawKind == PublicToken))
                   .Any(property => property.AccessorList.Accessors.Count == 2));
        }
예제 #7
0
 public IEnumerable <MethodDeclarationSyntax> GetPossibleStaticMethods(TypeDeclarationSyntax type)
 {
     return(type.DescendantNodes()
            .OfType <MethodDeclarationSyntax>()
            .Where(x => !x.Modifiers.Any(SyntaxKind.StaticKeyword))
            .Where(CanBeMadeStatic)
            .AsArray());
 }
예제 #8
0
        private static IEnumerable <FieldDeclarationSyntax> GetTypeFieldNodes(
            TypeDeclarationSyntax root,
            Func <FieldDeclarationSyntax, bool> predicate)
        {
            var fields = from fieldDeclaration in root.DescendantNodes().OfType <FieldDeclarationSyntax>()
                         where predicate(fieldDeclaration)
                         select fieldDeclaration;

            return(fields);
        }
예제 #9
0
        public static IEnumerable <string> GetNamespacesReferencedByType(this SemanticModel model, TypeDeclarationSyntax typeDeclarationNode)
        {
            // We use a set here because there's no need to maintain
            // duplicates of the referenced namespace declarations
            var namespaces = new HashSet <string>();

            var descendantNodes = typeDeclarationNode.DescendantNodes();

            // Get references required for any inheritance
            var classTypeSymbol = model.GetDeclaredSymbol(typeDeclarationNode);

            if (classTypeSymbol.BaseType != null)
            {
                namespaces.Add(classTypeSymbol.BaseType.ContainingNamespace?.ToDisplayString());
            }
            namespaces.UnionWith(classTypeSymbol.Interfaces.Select(interfaceTypeSymbol => interfaceTypeSymbol.ContainingNamespace?.ToDisplayString()));

            // Get references required for any declarations that occur
            var variableDeclarationNodes = descendantNodes.OfType <VariableDeclarationSyntax>();

            namespaces.UnionWith(variableDeclarationNodes
                                 // Note that we pass node.Type to GetSymbolInfo, this is because
                                 // VariableDeclarationSyntax can refer to multiple declarations of
                                 // the same type, but we are only interested in the type itself
                                 .SelectMany(node => GetAllPotentialSymbols(model.GetSymbolInfo(node.Type))
                                             .Select(symbol => symbol.ContainingNamespace?.ToDisplayString())));

            // Get references required for any object creation that occurs,
            // this is distinct from the declaration references as the namespace
            // of the initialized type may be different from the declared type
            // of the variable it is assigned to
            var objectCreationNodes = descendantNodes.OfType <ObjectCreationExpressionSyntax>();

            namespaces.UnionWith(objectCreationNodes
                                 .SelectMany(node => GetAllPotentialSymbols(model.GetSymbolInfo(node))
                                             .Select(symbol => symbol.ContainingNamespace?.ToDisplayString())));

            // Get references required for any invocations that occur
            var invocationNodes = descendantNodes.OfType <InvocationExpressionSyntax>();

            namespaces.UnionWith(invocationNodes
                                 .SelectMany(node => GetAllPotentialSymbols(model.GetSymbolInfo(node)))
                                 .Select(symbol => symbol.ContainingNamespace?.ToDisplayString()));

            // We don't need to include the namespace that the given class belongs
            // to as references within the same namespace are already accessible
            namespaces.Remove(classTypeSymbol.ContainingNamespace?.ToDisplayString());

            // TODO: Find out why null namespaces occur and maybe replace with Codelyzer usage
            // We need to remove occurrences of the global namespace, it sometimes gets added
            // when a required namespace was not found
            return(namespaces.Where(@namespace => @namespace != null && [email protected](Constants.GlobalNamespace)));
        }
예제 #10
0
        protected string TypeModifiersToCecil(TypeDeclarationSyntax node)
        {
            var hasStaticCtor  = node.DescendantNodes().OfType <ConstructorDeclarationSyntax>().Any(d => d.Modifiers.Any(m => m.IsKind(SyntaxKind.StaticKeyword)));
            var typeAttributes = DefaultTypeAttributeFor(node, hasStaticCtor);

            if (IsNestedTypeDeclaration(node))
            {
                return(typeAttributes.AppendModifier(ModifiersToCecil(node.Modifiers, m => "TypeAttributes.Nested" + m.ValueText.CamelCase())));
            }

            var convertedModifiers = ModifiersToCecil("TypeAttributes", node.Modifiers, "NotPublic", ExcludeHasNoCILRepresentationInTypes);

            return(typeAttributes.AppendModifier(convertedModifiers));
        }
        private static TypeDeclarationSyntax WithBackingFields(this TypeDeclarationSyntax node, IEnumerable <ExpandablePropertyInfo> properties, Workspace workspace)
        {
            // generate backing field for auto-props
            foreach (ExpandablePropertyInfo p in properties)
            {
                MemberDeclarationSyntax fieldDecl = GenerateBackingField(p, workspace);

                // put field just before property
                PropertyDeclarationSyntax currentProp = node.DescendantNodes().OfType <PropertyDeclarationSyntax>().First(d => d.Identifier.Text == p.PropertyDeclaration.Identifier.Text);
                node = node.InsertNodesBefore(currentProp, new[] { fieldDecl });
            }

            return(node);
        }
예제 #12
0
        private bool HasNotOnlyConstOrReadonlyFields(TypeDeclarationSyntax declaration)
        {
            var fields = declaration.DescendantNodes().OfType <FieldDeclarationSyntax>();

            foreach (var field in fields)
            {
                if (field.ChildTokens().Any(t => t.RawKind == PublicToken))
                {
                    if (!field.ChildTokens().Any(t => t.RawKind == ConstToken || t.RawKind == ReadOnlyToken))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
예제 #13
0
        protected IEnumerable <TypeInfo> FindAssociatedModel
            (SemanticModel semanticModel, TypeDeclarationSyntax controller)
        {
            var returnValue = new List <TypeInfo>();
            var attributes  = controller.DescendantNodes().OfType <AttributeSyntax>()
                              .Where(a => a.Name.ToString() == "ResponseType");
            var parameters = attributes.Select(a => a.ArgumentList.Arguments.FirstOrDefault());
            var types      = parameters.Select(p => p.Expression).OfType <TypeOfExpressionSyntax>();

            foreach (var t in types)
            {
                var symbol = semanticModel.GetTypeInfo(t.Type);
                if (symbol.Type.SpecialType == SpecialType.System_Void)
                {
                    continue;
                }
                returnValue.Add(symbol);
            }
            return(returnValue.Distinct());
        }
 private ConstructorDeclarationSyntax FindStaticCtor(TypeDeclarationSyntax declaration) =>
 declaration
 .DescendantNodes()
 .OfType <ConstructorDeclarationSyntax>()
 .FirstOrDefault(c => c.Modifiers.Any(SyntaxKind.StaticKeyword));
예제 #15
0
        private bool HasMethods(TypeDeclarationSyntax declaration)
        {
            var methods = declaration.DescendantNodes().OfType <MethodDeclarationSyntax>();

            return(methods.Any());
        }
예제 #16
0
 public static HashSet <TypeDeclarationSyntax> GetSubtypeDeclarations(this TypeDeclarationSyntax typeDeclaration)
 {
     return(new HashSet <TypeDeclarationSyntax>(typeDeclaration.DescendantNodes()
                                                .Where(x => x is TypeDeclarationSyntax)
                                                .Cast <TypeDeclarationSyntax>()));
 }
예제 #17
0
 public static IEnumerable <MethodDeclarationSyntax> GetMethodDeclarations(TypeDeclarationSyntax interfaceNode)
 {
     return(interfaceNode.DescendantNodes().OfType <MethodDeclarationSyntax>());
 }
예제 #18
0
        private bool HasPublicFields(TypeDeclarationSyntax declaration)
        {
            var fields = declaration.DescendantNodes().OfType <FieldDeclarationSyntax>();

            return(fields.Any(field => field.DescendantTokens().Any(t => t.RawKind == PublicToken)));
        }