/* The CheckLineLenght Method which is called from
         * MainWindowControl.xaml.cs when the assigned button is pressed
         */
        public void CheckLineLength(List <Document> documents, int numChars)
        {
            foreach (var document in documents)
            {
                if (document != null)
                {
                    /* convert the document to a text
                     * so every line can be accesed
                     */
                    Task <SourceText> t       = document.GetTextAsync();
                    SourceText        doctext = t.Result;

                    if (doctext != null)
                    {
                        foreach (var line in doctext.Lines)
                        {
                            if (line.ToString().Length > numChars)
                            {
                                ErrorReporter.AddWarning(
                                    "Line " + (line.LineNumber + 1) +
                                    " in Document " + document.Name +
                                    " is too long!",
                                    document.FilePath, line.LineNumber
                                    );
                            }
                        }
                    }
                }
            }
        }
        /* this method checks if the namingconventions for namespaces
         * set by the user are met for all documents in the project
         */
        public void Namespacenaming(
            List <NamespaceDeclarationSyntax> list,
            String projekt, List <string> folders,
            Document document)
        {
            String desiredNamespace = projekt;

            if (list.Count > 1)
            {
            }
            list.ForEach(delegate(NamespaceDeclarationSyntax nds)
            {
                folders.ForEach(delegate(string folder)
                {
                    desiredNamespace += "." + folder;
                });

                if (!nds.Name.Equals(desiredNamespace))
                {
                    int line = nds.GetLocation().GetMappedLineSpan().
                               StartLinePosition.Line;
                    ErrorReporter.AddWarning(
                        "Wrong namespace : " + nds.Name +
                        "! Should be : " + desiredNamespace + "!",
                        document.FilePath,
                        line);
                }
            });
        }
        /* this method checks if the namingconventions for classes
         * set by the user are met for all documents in the project
         */
        public void Classnaming(
            List <ClassDeclarationSyntax> list,
            Document document)
        {
            list.ForEach(delegate(ClassDeclarationSyntax cds)
            {
                string currentClassName = cds.Identifier.ToString();

                /* determine whether the class name only contains
                 * letters of the abc and if the first letter is in uppercase
                 */
                if (char.IsUpper(currentClassName[0]) &&
                    Regex.Matches(currentClassName, @"[a-zA-Z ]").
                    Count == currentClassName.Length)
                {
                }
                else
                {
                    int line = cds.GetLocation().GetMappedLineSpan().
                               StartLinePosition.Line;
                    ErrorReporter.AddWarning(
                        "Flawed class name : " + cds.Identifier,
                        document.FilePath,
                        line);
                }
            });
        }
Beispiel #4
0
        /* this method checks whether the view knows the model or
         * the other way around.
         * This will be the case if an object of the other
         * is instantiated anywhere within it.
         */
        public void ModelknowsViews(
            List <ClassDeclarationSyntax> classModellist,
            List <ClassDeclarationSyntax> classViewlist,
            List <Tuple <ObjectCreationExpressionSyntax, Document> > idModellist,
            List <Tuple <ObjectCreationExpressionSyntax, Document> > idViewlist)
        {
            classModellist.ForEach(delegate(ClassDeclarationSyntax cdsm)
            {
                string modelClassname = cdsm.Identifier.ToString();
                idViewlist.ForEach(
                    delegate(
                        Tuple <ObjectCreationExpressionSyntax, Document> tuple)
                {
                    string createdObject = tuple.Item1.ToString();
                    if (createdObject.Contains(modelClassname))
                    {
                        int line = tuple.Item1.GetLocation().
                                   GetMappedLineSpan().
                                   StartLinePosition.Line;

                        ErrorReporter.AddWarning(
                            "View accessing model!",
                            tuple.Item2.FilePath, line);
                    }
                });
            });

            classViewlist.ForEach(delegate(ClassDeclarationSyntax cdsv)
            {
                string viewClassname = cdsv.Identifier.ToString();
                idModellist.ForEach(
                    delegate(
                        Tuple <ObjectCreationExpressionSyntax, Document> tuple)
                {
                    string createdObject = tuple.Item1.ToString();
                    if (createdObject.Contains(viewClassname))
                    {
                        int line = tuple.Item1.GetLocation().
                                   GetMappedLineSpan().
                                   StartLinePosition.Line;
                        ErrorReporter.AddWarning(
                            "Model accessing view!",
                            tuple.Item2.FilePath, line);
                    }
                });
            });
        }
Beispiel #5
0
        /*this method checks if the code behind file is left empty.
         * Every code behind file has a .xaml as its parent
         * which is treatet like its folder.
         */
        public void CheckCodeBehind(Project project)
        {
            foreach (var document in project.Documents)
            {
                if (document != null)
                {
                    Task <SyntaxTree> t    = document.GetSyntaxTreeAsync();
                    SyntaxTree        tree = t.Result;

                    /* get every method/variable and
                     * propertydeclaration of the current document
                     */
                    List <MethodDeclarationSyntax> methodDeclarations =
                        tree.GetRoot().DescendantNodesAndSelf().
                        OfType <MethodDeclarationSyntax>().ToList();

                    List <VariableDeclarationSyntax> variableDeclarations =
                        tree.GetRoot().DescendantNodesAndSelf().
                        OfType <VariableDeclarationSyntax>().ToList();

                    List <PropertyDeclarationSyntax> propertyDeclarations =
                        tree.GetRoot().DescendantNodesAndSelf().
                        OfType <PropertyDeclarationSyntax>().ToList();

                    List <string> folders = document.Folders.ToList();
                    folders.ForEach(delegate(string folder)
                    {
                        //check if any declarations are in the code behind file
                        if (folder.Contains(".xaml") &&
                            (methodDeclarations.Any() ||
                             variableDeclarations.Any() ||
                             propertyDeclarations.Any()))
                        {
                            ErrorReporter.AddWarning(
                                "Codebehind is not empty!",
                                document.FilePath);
                        }
                    });
                }
            }
        }
Beispiel #6
0
        /* The CheckImports Method which is called from
         * MainWindowControl.xaml.cs when the assigned button is pressed
         */
        public void CheckImports(List <Document> documents)
        {
            foreach (var document in documents)
            {
                if (document != null)
                {
                    Compilation        compilation;
                    Task <Compilation> taskc = document.Project.
                                               GetCompilationAsync();

                    compilation = taskc.Result;
                    SyntaxTree        tree;
                    Task <SyntaxTree> taskst = document.GetSyntaxTreeAsync();
                    tree = taskst.Result;
                    var root = tree.GetRoot();

                    /* part of this snippet is taken from a solution provided
                     * by Jon Skeet in his Stackoverflow post
                     * https://stackoverflow.com/questions/44058243/how-can-i-detect-unused-imports-in-a-script-rather-than-a-document-with-roslyn
                     */
                    var unusedImportNodes = compilation.GetDiagnostics()
                                            .Where(d => d.Id == "CS8019")
                                            .Where(d => d.Location?.SourceTree == tree)
                                            .Select(d => root.FindNode(d.Location.SourceSpan))
                                            .ToList();
                    unusedImportNodes.ForEach(delegate(SyntaxNode nd)
                    {
                        int line = nd.GetLocation().GetMappedLineSpan().
                                   StartLinePosition.Line;

                        ErrorReporter.AddWarning("Unused import : " +
                                                 nd.ToString(),
                                                 document.FilePath, line);
                    });
                }
            }
        }
Beispiel #7
0
        public void CheckSingleton(
            Project project,
            ObservableCollection <Document> documents,
            bool checkThreadSafety)
        {
            foreach (Document d in documents)
            {
                // Get SyntaxTree for Document
                Task <SyntaxTree> t    = d.GetSyntaxTreeAsync();
                SyntaxTree        tree = t.Result;

                // Get List of class declarations from SyntaxTree
                List <ClassDeclarationSyntax> classDeclarations =
                    tree.GetRoot().DescendantNodes().
                    OfType <ClassDeclarationSyntax>().ToList();

                foreach (ClassDeclarationSyntax classDec in classDeclarations)
                {
                    // Get List of constructor declarations in class
                    List <ConstructorDeclarationSyntax>
                    constructorDeclarations =
                        classDec.DescendantNodes().
                        OfType <ConstructorDeclarationSyntax>().ToList();

                    string className   = classDec.Identifier.Text;
                    bool   isSingleton = true;

                    /* Check all class constructors for
                     * whether or not they are private
                     */
                    if (!constructorDeclarations.Any())
                    {
                        isSingleton = false;
                    }
                    else
                    {
                        foreach (
                            ConstructorDeclarationSyntax constDec in
                            constructorDeclarations)
                        {
                            List <SyntaxToken> tokens =
                                constDec.ChildTokens().ToList();

                            bool isPrivate = false;
                            foreach (SyntaxToken token in tokens)
                            {
                                if (token.IsKind(SyntaxKind.PrivateKeyword))
                                {
                                    isPrivate = true;
                                }
                            }
                            if (!isPrivate)
                            {
                                isSingleton = false;
                            }
                        }
                    }

                    if (!isSingleton)
                    {
                        int line = classDec.GetLocation().GetMappedLineSpan().
                                   StartLinePosition.Line;
                        ErrorReporter.AddWarning(
                            "Class " + className +
                            " contained in document " + d.Name +
                            " is not singleton but it should be!",
                            d.FilePath,
                            line);
                    }

                    /* Consider the class Singleton
                     * as long as all constructors are private
                     */
                    if (isSingleton && checkThreadSafety)
                    {
                        /* With information from
                         * http://csharpindepth.com/Articles/General/Singleton.aspx
                         */

                        /* Check whether Singleton is thread safe
                         * by way of double check locking
                         */
                        if (IsDoubleCheckLocked(classDec))
                        {
                        }

                        /* If it is not, check if it is thread safe
                         * through use of .NET's Lazy<T>-class
                         */
                        else if (IsLazy(classDec))
                        {
                        }

                        /* If singleton is neither double check locked
                         * nor Lazy-instantiated, add warning
                         * */
                        else
                        {
                            int line = classDec.GetLocation().
                                       GetMappedLineSpan().StartLinePosition.Line;

                            ErrorReporter.AddWarning(
                                "Class " + className +
                                " contained in document " + d.Name +
                                " is neither double check locked nor lazy! \n" +
                                "Consider adding either one for thread safety."
                                , d.FilePath,
                                line);
                        }
                    }
                    else
                    {
                    }
                }
            }
        }
        /* this method checks if the namingconventions for methods
         * set by the user are met for all documents in the project
         */
        public void Methodnaming(
            List <MethodDeclarationSyntax> list,
            List <string> permittedMethods,
            Document document,
            MainWindowControl.NameCase nameCaseMethod)
        {
            list.ForEach(delegate(MethodDeclarationSyntax mds)
            {
                string currentMethodName = mds.Identifier.ToString();
                string regexmatchstring  = currentMethodName;

                /* permitted special signs get treated like
                 * they are not part of the methodname
                 */
                if (permittedMethods.Equals(""))
                {
                    permittedMethods.ForEach(delegate(string permitted)
                    {
                        regexmatchstring =
                            regexmatchstring.Replace(
                                permitted,
                                "");
                    });
                }

                /* determin whether the method name
                 * only contains letters of the abc
                 */
                if (Regex.Matches(regexmatchstring, @"[a-zA-Z ]").
                    Count == regexmatchstring.Length)
                {
                    //check if camelCase constraint is violated
                    if (char.IsUpper(regexmatchstring[0]) && nameCaseMethod.
                        Equals(MainWindowControl.NameCase.camelCase))
                    {
                        int line = mds.GetLocation().GetMappedLineSpan().
                                   StartLinePosition.Line;
                        ErrorReporter.AddWarning(
                            "Method name should be camelCase : "
                            + mds.Identifier,
                            document.FilePath,
                            line);
                    }
                    //check if PascalCase constraint is violated
                    if (char.IsLower(regexmatchstring[0]) && nameCaseMethod.
                        Equals(MainWindowControl.NameCase.PascalCase))
                    {
                        int line = mds.GetLocation().GetMappedLineSpan().
                                   StartLinePosition.Line;
                        ErrorReporter.AddWarning(
                            "Method name should be PascalCase : "
                            + mds.Identifier,
                            document.FilePath,
                            line);
                    }
                }
                else
                {
                    int line = mds.GetLocation().GetMappedLineSpan().
                               StartLinePosition.Line;
                    ErrorReporter.AddWarning(
                        "Illegal character in method name : "
                        + mds.Identifier,
                        document.FilePath,
                        line);
                }
            });
        }