diff --git a/wp/pictures/class.PNG b/wp/pictures/class.PNG new file mode 100644 index 0000000000..f21aef475c Binary files /dev/null and b/wp/pictures/class.PNG differ diff --git a/wp/pictures/data_flow.PNG b/wp/pictures/data_flow.PNG new file mode 100644 index 0000000000..9a2677797a Binary files /dev/null and b/wp/pictures/data_flow.PNG differ diff --git a/wp/pictures/detekt.png b/wp/pictures/detekt.png new file mode 100644 index 0000000000..88852441ef Binary files /dev/null and b/wp/pictures/detekt.png differ diff --git a/wp/pictures/diktat.png b/wp/pictures/diktat.png new file mode 100644 index 0000000000..7dcc31afe8 Binary files /dev/null and b/wp/pictures/diktat.png differ diff --git a/wp/pictures/kotlinRating.png b/wp/pictures/kotlinRating.png new file mode 100644 index 0000000000..82297cbd26 Binary files /dev/null and b/wp/pictures/kotlinRating.png differ diff --git a/wp/pictures/ktfmt.png b/wp/pictures/ktfmt.png new file mode 100644 index 0000000000..68d948f02a Binary files /dev/null and b/wp/pictures/ktfmt.png differ diff --git a/wp/pictures/ktlint.png b/wp/pictures/ktlint.png new file mode 100644 index 0000000000..1044e0f0f5 Binary files /dev/null and b/wp/pictures/ktlint.png differ diff --git a/wp/logo.png b/wp/pictures/logo.png similarity index 100% rename from wp/logo.png rename to wp/pictures/logo.png diff --git a/wp/pictures/sequence.jpg b/wp/pictures/sequence.jpg new file mode 100644 index 0000000000..b461c73cb3 Binary files /dev/null and b/wp/pictures/sequence.jpg differ diff --git a/wp/pictures/web-example.png b/wp/pictures/web-example.png new file mode 100644 index 0000000000..1353ca41e9 Binary files /dev/null and b/wp/pictures/web-example.png differ diff --git a/wp/references.bib b/wp/references.bib new file mode 100644 index 0000000000..2debfb190b --- /dev/null +++ b/wp/references.bib @@ -0,0 +1,85 @@ + +%% This BibTeX bibliography file was created using BibDesk. +%% http://bibdesk.sourceforge.net/ + +%% Created for Daniel Lawson at 2016-03-27 19:31:34 +0100 + + +%% Saved with string encoding Unicode (UTF-8) + +@article{ref:kremenek, + Author = {Kremenek, Ted}, + url = "https://llvm.org/devmtg/2008-08/Kremenek_StaticAnalyzer.pdf", + Title = {Finding Software Bugs With the Clang Static Analyzer}, + Year = {2008}} + +@article{ref:spa, + Author = {Yegor Bugaenko}, + Title = {New Object Calculus to Improve Static Program Analysis}, + Year = {September 30, 2020} +} + +@article{ref:effective, + Author = {Wu Jingyue}, + Title = {Effective Dynamic Detection of Alias Analysis Errors}, + Year = {2013}, + pages = "279-289", + journal = "Proceedings of the 9th Joint Meeting on Foundations of Software, Engineering" +} + +@article{ref:simple, + Author = {Wand Mitchell}, + Title = {A Simple Algorithm and Proof for Type Inference}, + Year = {1987}, + journal = "Fundamenta Informaticae 10.2", + pages = "115–121" +} + +@article{ref:dis, + Author = {Jiri Slaby}, + Title = {Automatic Bug-finding Techniques for Large Software Projects}, + Year = {2013} +} + +@book{ref:ast, +title={Abstract Syntax Tree}, +author={Miller, F.P. and Vandome, A.F. and John, M.B.}, +isbn={9786133773127}, +url={https://books.google.ru/books?id=5ns7YgEACAAJ}, +year={2010}, +publisher={VDM Publishing} +} + +@book{ref:cleancode, +title={Clean Code: A Handbook of Agile Software Craftsmanship}, +author={Martin, R.C.}, +isbn={9780132350884}, +lccn={20080240}, +series={Robert C. Martin series}, +url={https://books.google.ru/books?id=dwSfGQAACAAJ}, +year={2009}, +publisher={Prentice Hall} +} + +@book{ref:sca, + title={Static Code Analysis: Lint, Static Code Analysis, Data-Flow Analysis, Parasoft, Clang, List of Tools for Static Code Analysis}, + author={LLC Books}, + isbn={9781155282619}, + url={https://books.google.ru/books?id=rYurSQAACAAJ}, + year={2010}, + publisher={General Books LLC} +} + +@book{ref:kotlinInAction, +title={Kotlin in Action}, +author={Dmitry Jemerov, Svetlana Isakova}, +pages = {88-91}, +year={2017}, +publisher={ Manning Publications} +} +@article{ref:offKotlin, + Author = {Jetbrains}, + Title = {Kotlin official documentation}, + url = "https://kotlinlang.org/docs/reference/", + year = {2020} +} \ No newline at end of file diff --git a/wp/sections/appendix.tex b/wp/sections/appendix.tex new file mode 100644 index 0000000000..73050a904d --- /dev/null +++ b/wp/sections/appendix.tex @@ -0,0 +1,8 @@ +\subsection{Class diagram} + \includegraphics[scale=0.5]{pictures/class.PNG} + +\subsection{Data Flow diagram} + \includegraphics[scale=0.6]{pictures/data_flow.PNG} + +\subsection{Sequence diagram} + \includegraphics[scale=0.33]{pictures/sequence.jpg} \ No newline at end of file diff --git a/wp/sections/chapter 4/cli.tex b/wp/sections/chapter 4/cli.tex deleted file mode 100644 index 39dbc6a3c5..0000000000 --- a/wp/sections/chapter 4/cli.tex +++ /dev/null @@ -1,24 +0,0 @@ -You can run diKTat as CLI-application. In order to do that you need to: -\begin{enumerate} - \item Install KTlint manually at \url{https://github.com/pinterest/ktlint/releases} - \par - \textbf{OR} use curl: - \par - \verb|curl -sSLO https://github.com/pinterest/ktlint/releases/download/0.39.0/| - \par - \verb|ktlint && chmod a+x ktlint| - \par - \textbf{OR} use brew: - \par - \verb|brew install ktlint| - \item Load diKTat manually at \url{no.url} - \par - \textbf{OR} use curl: - \par - \verb|curl -sSLO https://github.com/cqfn/diKTat/releases/download/v0.1.1/| - \par - \verb|diktat-0.1.1.jar| - \item Finally, run KTlint (with diKTat injected) to check your \verb|*.kt| files in \verb|dir/your/dir|: - \par - \verb|./ktlint -R diktat.jar "dir/your/dir/**/*.kt"| -\end{enumerate} diff --git a/wp/sections/chapter 4/gradle.tex b/wp/sections/chapter 4/gradle.tex deleted file mode 100644 index 29d66dc671..0000000000 --- a/wp/sections/chapter 4/gradle.tex +++ /dev/null @@ -1,44 +0,0 @@ -You can see how it is configured in our project for self-checks: \verb|build.gradle.kts|. Check our github: \url{https://github.com/cqfn/diKTat}. -\par Add the code below to your \verb|build.gradle.kts|: -\par -\begin{verbatim} -val ktlint by configurations.creating - -dependencies { - ktlint("com.pinterest:ktlint:0.39.0") { - // need to exclude standard ruleset to use only diktat rules - exclude("com.pinterest.ktlint", "ktlint-ruleset-standard") - } - - // diktat ruleset - ktlint("org.cqfn.diktat:diktat-rules:0.1.1") -} - -val outputDir = "${project.buildDir}/reports/diktat/" -val inputFiles = project.fileTree(mapOf("dir" to "src", "include" to "**/*.kt")) - -val diktatCheck by tasks.creating(JavaExec::class) { - inputs.files(inputFiles) - outputs.dir(outputDir) - - description = "Check Kotlin code style." - classpath = ktlint - main = "com.pinterest.ktlint.Main" - - // specify proper path to sources that should be checked here - args = listOf("src/main/kotlin/**/*.kt") -} - -val diktatFormat by tasks.creating(JavaExec::class) { - inputs.files(inputFiles) - outputs.dir(outputDir) - - description = "Fix Kotlin code style deviations." - classpath = ktlint - main = "com.pinterest.ktlint.Main" - - // specify proper path to sources that should be checked here - args = listOf("-F", "src/main/kotlin/**/*.kt") -} -\end{verbatim} -\par To run diktat to check/fix code style - run: \verb|gradle diktatCheck|. \ No newline at end of file diff --git a/wp/sections/chapter 4/maven.tex b/wp/sections/chapter 4/maven.tex deleted file mode 100644 index e71ee74085..0000000000 --- a/wp/sections/chapter 4/maven.tex +++ /dev/null @@ -1,37 +0,0 @@ -\textbf{Use maven-antrun-plugin} -\par You can find a code snippet of maven-antrun-plugin on our github page: \url{https://github.com/cqfn/diKTat} -\par In case you want to add autofixer with diKTat ruleset just extend the snippet above with \verb|.| - -\par To run diktat to check/fix code style - run: \verb|mvn antrun:run@diktat.| -\newline -\textbf{Use the new diktat-maven-plugin} -\par You can see how it is configured in our project for self-checks: pom.xml. This plugin should be available since version 0.1.2. It requires less configuration but may contain bugs. If you use it and encounter any problems, feel free to open issues on github: \url{https://github.com/cqfn/diKTat}. - -Add this plugin to your pom.xml: -\begin{verbatim} - - org.cqfn.diktat - diktat-maven-plugin - ${diktat.version} - - - diktat - none - - check - fix - - - - ${project.basedir}/src/main/kotlin - ${project.basedir}/src/test/kotlin - - diktat-analysis.yml - - - - -\end{verbatim} - -\par To run diktat check use command \verb| mvn diktat:check@diktat|. -\par To run diktat in autocorrect mode use command \verb|mvn diktat:fix@diktat|. \ No newline at end of file diff --git a/wp/sections/chapter 4/rulesetConfiguration.tex b/wp/sections/chapter 4/rulesetConfiguration.tex deleted file mode 100644 index ed12cde5f4..0000000000 --- a/wp/sections/chapter 4/rulesetConfiguration.tex +++ /dev/null @@ -1 +0,0 @@ -You change rules configuration in \textbf{diktat-analysis.yml}. Each rule has a description and each rule is configured by default. If rule doesn't have a default configuration than it can't be configurable. \ No newline at end of file diff --git a/wp/sections/compare.tex b/wp/sections/compare.tex new file mode 100644 index 0000000000..015b1f36f3 --- /dev/null +++ b/wp/sections/compare.tex @@ -0,0 +1,79 @@ +\subsection{About ktlint} +\par Ktlint is a popular an anti-bikeshedding Kotlin linter with a built-in formatter created by pinterest. It tries to capture (reflect) official code style from kotlinlang.org and Android Kotlin Style Guide and then automatically apply these rules to your codebase. Ktlint checks and can automatically fix code and it claims to be simple and easy to use. As it is focused more on checking code-style and code-smell related issues, ktlint inspections are working with Abstract Syntax Tree generated by Kotlin parser. Ktlint framework has some basic utilities to make the work with Kotlin AST easier, but anyway all inspections work with original ASTNode. + +Ktlint has been developing since 2016 and from then on it has 3.8k stars, 309 forks and 390 closed PRs (at least on the moment of writing this article). It looks to be the most popular and mature linter in the Kotlin community right now. There have been written ~15k lines of code. + +Ktlint has it’s own set of rules, which divides on standard and experimental rules. But unfortunately the number of fixers\&checkers in the standard ruleset is very few ($\approx$20 rules) and inspections are very trivial. + +Ktlint can be used as a plugin via Maven, Gradle or command line app. To configure rules in Ktlint you should modify .editorconfig file - this is the only configuration that ktlint provides. Actually you even can’t configure specific rules (for example to disable or suppress any of them), instead you can provide some common settings like the number of spaces for indenting. In other words, ktlint has a ”fixed hardcoded” codestyle that is not very configurable. Properties should be specified under $.kt,kts$. + +If you want to implement your own rules you need to create a your own ruleset. Ktlint is very user-friendly for creation of custom rulesets. In this case ktlint will parse the code using a Kotlin parser and will trigger your inspection (as visitor) for each and every node of AST. Ktlint is using java’s ServiceLoader to discover all available ”RuleSets”. ServiceLoader is used to inject your own implementation of rules for the static analysis. In this case ktlint becomes a third-party dependency and a framework. Basically you should provide implementation of RuleSetProviderinterface. + +Ktlint refers to article on medium on how to create a ruleset and a rule. + +\par A lot of projects uses ktlint as their code formatting tool. For example, OmiseGo \footnote{\url{https://github.com/omgnetwork/android-sdk}} (currently rebranding to OMG Network) - a quite popular cryptocurrency. + +\par To summarize: Ktlint is very mature and useful as a framework for creating your own checker\&fixer of Kotlin code and doing AST-analysis. It can be very useful if you need only simple inspections that check (and fix) code-style issues (like indents). +\subsection{About detekt} +\par Detekt is a static code analysis tool. It operates on an abstract syntax tree (AST) and meta-information provided by Kotlin compiler. On then top of that info, it does a complex analysis of the code. However, this project is more focused on checking the code rather than fixing. Similarly, to ktlint, it has it’s own rules and inspections. Detekt uses wrapped ktlint to redefine rules as it’s formatting rules. + +Detekt supports such features as code smell analysis, bugs searching and code-style checking. It has a highly configurable rule sets (can even make suppression of issues from the code). And the number of checkers is quite big: it has more than 100 inspections. Detekt has IntelliJ integration, third-party integrations for Maven, Bazel and Github actions, mechanism for suppression of their warnings with @Suppressannotation and many more. It is being developed since 2016 and today it has 3.2k stars, 411 forks and 1850 closed PRs. It has about 45k lines of code. And it’s codebase is the biggest comparing to other analyzers. +\par Detekt is used in such projects as fountain or Kaspresso. "Fountain is an Android Kotlin library conceived to make your life easier when dealing with paged endpoint services" \footnote{\url{https://github.com/xmartlabs/fountain}} and Kaspresso is a framework for UI testing on Android made by KasperskyLab \footnote{\url{https://github.com/KasperskyLab/Kaspresso}}. + +\par To summarize: Detekt is very useful as a Kotlin static analyser for CI/CD. It tries to find bugs in the code and is focused more on checking of the code. Detekt has 100+ rules that check the code. + +\subsection{About ktfmt} +\par Ktfmt is a program that formats Kotlin code, based on google-java-format. It's development has started in Facebook in the end of 2019. It can be added to your project through a Maven dependency, Gradle dependency, IntelliJ plugin or you can run it through a command line. Ktfmt is not a configurable application, so to change any rule logic you need to download the project and redefine some constants. Ktfmt has 214 stars, 16 forks, 20 closed PRs and around 7500 lines of code. + +\par To summarize: no one knows why Facebook has invested their money in this tool. Nothing new was not introduced. + +\subsection{About diKTat} +Diktat as well as ktlint and detekt is a static code analysis tool. But diktat is not only a tool, but also a coding convention that in details describes all the rules that you should follow when writing a code on Kotlin. It’s development has started in 2020 and at the time of writing this article diKTat has 150 stars and 13 forks. DiKTat operates on AST provided by kotlin compiler. So why diKTat is better? + +First of all, it supports much more rules than ktlint. It’s ruleset includes more than 100 rules, that can both check and fix your code. + +Second, diKTat is configurable. A lot of rules have their own settings, and all of them can be easily understood. For example, you can choose whether you need a copyright, choose a length of line or you can configure your indents. + +Third, diKTat is very easy to configure. You don’t need to spend hours only to understand what each rule is doing. Diktat’s ruleset is a .yml file, where each rule is commented out with the description. Also you can suppress error on the particular lines of code using @Suppress annotation in your code. + +DiKTat can be used as a CI/CD tool in order to avoid merging errors in the code. Overall it can find code smells and code style issues. Also it can find pretty not obvious bugs by complex AST analysis. Diktat works with maven, gradle and as command-line application powered by ktlint. + +\par To summarize: diktat contains a strict coding convention that was not yet introduced by other linters. It works both as a checker and as a fixer. Diktat has much more inspections (100+) and is very configurable (each inspection can be disabled/configured separately), so you can configure it for your particular project. + +\subsection{A few words about Jetbrains} +\par Jetbrains created one of the best IDEs for Java and Kotlin called IntelliJ. This IDE supports a built-in linter. However, it is not a well-configurable tool, you are not able to specify your own coding convention and it is not useful for CI/CD as it is highly coupled with UI. Unfortunately such static analysis is not so effective as it cannot prevent merging of the code with bugs into the repository. As experience shows - many developers simply ignorethose static analysis errors until they are blocked from merging their pull requests. So it is not so suitable for CI/CD, but very good for finding and fixing issues inside your IDE. + +\subsection{Graphics} + +\subsubsection{Detekt Code Frequency} +\hfill\\ + \includegraphics[scale = 0.5]{pictures/detekt.png} +\subsubsection{Ktlint Code Frequency} +\hfill\\ + \includegraphics[scale=0.5]{pictures/ktlint.png} +\subsubsection{Ktfmt Code Frequency} +\hfill\\ + \includegraphics[scale=0.5]{pictures/ktfmt.png} +\subsubsection{DiKTat Code Frequency} +\hfill\\ + \includegraphics[scale=0.5]{pictures/diktat.png} +\subsection{Summary} + +\begin{center} +\begin{tabular}{ |p{3cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}|p{2.5cm}| } +\hline +\multicolumn{5}{|c|}{\textbf{Comparing table}} \\ +\hline +& diKTat& ktlint &detekt & ktfmt \\ +\hline +starting year & 2020 & 2016 & 2016 & 2019 \\ +stars & 130 & 3.2k & 3.8k & 214\\ +forks & 12 & 299 & 411 & 16\\ +closed PRs & 226 & 390 & 1850 & 20 \\ +lines of code & 22k & 15k & 45k & 7,5k\\ +number of rules & $>$100 & $\approx$ 20 & $>$100 & $\approx$ 10 \\ +\hline + +\hline +\end{tabular} +\end{center} \ No newline at end of file diff --git a/wp/sections/conclusion.tex b/wp/sections/conclusion.tex new file mode 100644 index 0000000000..dda3a19a79 --- /dev/null +++ b/wp/sections/conclusion.tex @@ -0,0 +1,2 @@ +\par DiKTat is a static code analyzer that finds and fixes code style inconsistencies. DiKTat is configurable, easy-to-use and it implements CI/CD pipelines, which distinguishes it from analogues. We offer many convenient ways to use diktat in projects, so you can use it as Maven/Gradle plugin, CLI tool, Web or github actions. It supports more than 100 rules, where each of them has clear explanation and can be configured by user. +\par When the development of diKTat will finish, we are going to support rules, update frameworks and track latest kotlin language releases to keep diKTat relevant. \ No newline at end of file diff --git a/wp/sections/definition.tex b/wp/sections/definition.tex new file mode 100644 index 0000000000..a0b2db8257 --- /dev/null +++ b/wp/sections/definition.tex @@ -0,0 +1,7 @@ +Before continue, it is necessary to define some terms so that the reader correctly understands the context of what was written. +The first and basic concept that should be introduced is \textbf{"rule"}. In diKTat, a \textbf{“rule”} is the logic described in a class, which checks a certain paragraph of code style for compliance with the code. + You should also know that \textbf{set} - is a well-defined collection of distinct objects, considered as an object in its own right. + \textbf{Ruleset}, in turn, is a set of such "rules". Suppose $W_i$ is set of checks of i-th rule and $F_i$ is set of fixers of i-th rule. Then $I_i = W_i \cup F_i $ is the set of checks and fixers of the i-th rule. Let R be a ruleset, therefore $R = \sum_{k=1}^n I_k$, where n is number of turned-on rules, $I_k$ is k-th rule. + \textbf{Abstract syntax tree (AST)} is a tree representation of the abstract syntactic structure of source code written in a programming language. Each node of the tree denotes a construct occurring in the source code. + \textbf{CICD} - continuous integration (CI) and continuous delivery (CD) is a methodology that allows application development teams to make changes to code more frequently and reliably. + \textbf{KDoc} - is the language used to document Kotlin code (the equivalent of Java's JavaDoc). \ No newline at end of file diff --git a/wp/sections/diKTat.tex b/wp/sections/diKTat.tex new file mode 100644 index 0000000000..47445425e6 --- /dev/null +++ b/wp/sections/diKTat.tex @@ -0,0 +1,5 @@ +\subsection{What is diKTat?} +DiKTat - is a formal strict code style (\url{https://github.com/cqfn/diKTat}) and a linter with a set of rules that implement this code style for Kotlin language. Basically, it is a collection of Kotlin code style rules implemented as AST visitors on top of KTlint framework (\url{https://github.com/pinterest/ktlint}). Diktat warns and fixes code style errors and code smells based on configuration file. DiKTat is a highly configurable framework, that can be extended further by adding custom rules. It can be run as command line application or with maven or gradle plugins. In this paper, we will explain how DiKTat works, describes advantages and disadvantages and how it differs from other static analyzers. + +\subsection{Why diKTat?} +So why did we decide to create diKTat? We looked at similar projects and realized that they have defects and their functionality does not give you a chance to implement modern configurable code style. That’s why we came to a conclusion that we need to create convenient and easy-to-use tool for developers. Why is it easy-to-use? First of all, diKTat has its own highly configurable ruleset. You just need to fill your own options on rules in ruleset or either use default one. Basically, ruleset is an yml file with a description of each rule. Secondly, there are a lot of developers that use different tools for building projects. Most popular are Maven and Gradle. DiKTat supports these ones and it also has cli. Finally, each developer has their own codestyle and sometimes they don’t want static analyzers to trigger on some lines of code. In diKTat you can easily disable a rule. \ No newline at end of file diff --git a/wp/sections/download.tex b/wp/sections/download.tex new file mode 100644 index 0000000000..be69ad8549 --- /dev/null +++ b/wp/sections/download.tex @@ -0,0 +1,8 @@ +\subsection{CLI-application} +\par You can run diKTat as a CLI-application by installing it first. You can find detailed instructions on how to install and run on different OS on github (\url{https://github.com/cqfn/diKTat/blob/master/README.md#run-as-cli-application}). After the run, errors will be found and displayed. Each error consists of a rule name, a description of the rule so that the user can understands the error, the line and column number where the error was found.\\ +\subsection{Plugins} +\par Alternatively, you can add a diktat maven or gradle plugin directly to the project: detailed instructions for maven can be found here - \url{https://github.com/cqfn/diKTat/blob/master/README.md#run-with-maven}and for gralde - \url{https://github.com/cqfn/diKTat/blob/master/README.md#run-with-gradle-plugin}.\\ +\subsection{Configuratifon file} +As described above, diKTat has a configuration file. Note that you should place the \textsl{diktat-analysis.yml} file containing the diktat configuration in the parent directory of your project when running as a CLI application. Diktat-maven-plugin and diktat-gradle-plugin have a separate option for configuration file path. +\subsection{WEB} +\par Of course, the easiest way to use it without any downloads or installations is the web version of the app. You can try it by following the link \url{https://ktlint-demo.herokuapp.com/demo}. Web app supports both checking and fixing, using either ktlint or diktat ruleset. For diktat you can also upload a custom configuration file. diff --git a/wp/sections/examples.tex b/wp/sections/examples.tex new file mode 100644 index 0000000000..3292ceff48 --- /dev/null +++ b/wp/sections/examples.tex @@ -0,0 +1 @@ +Describe how does diKtat work on real projects \ No newline at end of file diff --git a/wp/sections/feature.tex b/wp/sections/feature.tex new file mode 100644 index 0000000000..308601ea11 --- /dev/null +++ b/wp/sections/feature.tex @@ -0,0 +1,137 @@ +\par As described above, diKTat is very configurable and user-friendly. But these are not all of its advantages and features. Below will be presented and described unusual and important killer-features of diKTat. + +\subsection{Configuration file} +\par +It's worth starting with the configuration file. This is a file in which the user can manually turn rules on and off or configure the rules settings. Below is one of the rules in the configuration file. + + +\begin{center} +\begin{tabular}{@{}l@{}} + name: FILE\underline{ }IS\underline{ }TOO\underline{ }LONG\\ + \hspace{1cm}enabled: true\\ + \hspace{1cm}configuration:\\ + \hspace{2 cm}maxSize: '2000'\\ + \hspace{2 cm}ignoreFolders: ' '\\ +\end{tabular} +\end{center} + +Each rule in this file has 3 fields: name - the name of the rule, enabled - whether the rule is enabled or disabled (all rules are enabled by default), configuration - parameters for the rule. With the first two, everything is obvious. The third parameter is less obvious. The configuration is a set of "properties" to configure this rule. For example, for a rule "FILE\underline{ }IS\underline{ }TOO\underline{ }LONG", that checks the number of lines in a Kotlin file, the user can configure the maximum number of lines allowed in the file - by changing the "maxSize" in the configuration, or the user can specify paths to folders that do not need to be checked - by writing the path in "ignoreFolders". \\ + +\subsection{Create ASTNode} +\par +Another feature is a method that allows you to construct an abstract syntax node from text. This algorithm can parse the code even partially, when you do not need to save the hierarchy of the file (with imports/packages/classes). +For example it can parse and provide you a sub-tree for these lines of code: + +\begin{lstlisting}[caption={Example of creating node.}, label={lst:example1}, language=Kotlin] + val nodeFromText: ASTNode = KotlinParser().createNode("val age: Int = 21") +\end{lstlisting} + +\tikzstyle{every node}=[draw=black,thick,anchor=west, scale = 0.5] + +\begin{tikzpicture}[% + grow via three points={one child at (0.3,-0.8) and + two children at (0.3,-0.8) and (0.3,-1.5)}, + scale=0.5, + edge from parent path={(\tikzparentnode.south) |- (\tikzchildnode.west)}] + + \node {PROPERTY} + child { node {val}} + child {node {WHITE\underline{ }SPACE}} + child {node {IDENTIFIER}} + child {node {COLON}} + child {node {WHITE\underline{ }SPACE}} + child {node {TYPE\underline{ }REFERENCE} + child {node {USER\underline{ }TYPE} + child {node {REFERENCE\underline{ }EXPRESSION} + child {node {IDENTIFIER}} + } + } + } + child [missing] {} + child [missing] {} + child [missing] {} + child {node {WHITE\underline{ }SPACE}} + child {node {EQ}} + child {node {WHITE\underline{ }SPACE}} + child {node {INTEGER\underline{ }CONSTANT} + child {node {INTEGER\underline{ }LIRETAL}} + }; +\end{tikzpicture} + +As you can see in the examples, we pass to the method the text of the source code that we want to transform and the flag, which is set to false by default. The flag should be set to true in order to immediately build a tree with a root node of the FILE type. What's going on inside this method? First of all, the system properties are set (for example: set "idea.io.use.nio2" to true). Further in the method, the text is checked. If the text of the code contains such keywords as import or package, then the method builds a tree with a root node of the FILE type, otherwise it tries with a different root type. In both cases, at the end, if the tree contains an ERROR\underline{ }ELEMENT type of node, it means that an error was made in the code and the method was unable to build the tree and, therefore, throws an exception.\\ +This helps us to implement such complex inspections like the detection of commented code, helps easily fix the code without manually building sub-trees in visitors\\ + +\subsection{"SUPPRESS annotation"} +\par +What if the user wants one of the diKTat rules not to check a piece of code? The \textsl{SUPPRESS} annotation will help with this. This annotation can be supplied to ignore a certain rule. For instance, if run this code: + +\begin{lstlisting}[caption={Function with incorrect name.}, label={lst:example1}, language=Kotlin] + /** +* This is example +*/ + +package org.cqfn.diktat + +/** +* Simple class +*/ +class User(private val name: String, private val age: Int) { + /** + * Function with incorrect name + * + * @return is username longer than age + */ + fun IsInCoRrEcTnAMe() = name.length > age +} + +\end{lstlisting} + +There will be warning: +$$ +\texttt{ \small{ $\big[$FUNCTION\underline{ }NAME\underline{ }INCORRECT\underline{ }CASE$\big]$ function/method name should be in lowerCamelCase}} +$$ + +But if there is a \textsl{@SUPPRESS} before this method, then there will be no errors at run. +\begin{lstlisting}[caption={Function with incorrect name, but with suppress.}, label={lst:example1}, language=Kotlin] + /** +* This is example +*/ + +package org.cqfn.diktat + +/** +* Simple class +*/ +@Suppress("FUNCTION_NAME_INCORRECT_CASE") +class User(private val name: String, private val age: Int) { + /** + * Function with incorrect name + * + * @return is username longer than age + */ + fun IsInCoRrEcTnAMe() = name.length > age +} + +\end{lstlisting} + +The example shows that the method has SUPPRESS annotation. Therefore, the \\ FUNCTION\underline{ }NAME\underline{ }INCORRECT\underline{ }CASE rule will be ignored on this method and there will be no error. The search method for a given annotation goes up recursively to the root element of type FILE, looking for the annotation. This means that Suppress can be placed not only in front of knowingly incorrect code, but also at the upper levels of the abstract tree. In our example, the annotation is not in front of the method, but in front of the class and still works. Also, you can put several annotations: +\begin{lstlisting}[caption={Function with incorrect name, but with suppress.}, label={lst:example1}, language=Kotlin] +@set:[Suppress("WRONG_DECLARATION_ORDER") Suppress("IDENTIFIER_LENGTH")] +\end{lstlisting} + +\subsection{WEB} +\par +Also worth mentioning is the existence of a web version of diKTat.. This is a very handy tool that can be used quickly, and most importantly, it is very simple. The link can be found in or you can find it in "\nameref{sec:download}" chapter or in ktlint project as reference.\footnote{\url{https://github.com/pinterest/ktlint\#online-demo}} +\begin{figure}[H] + \centering + \includegraphics[scale=0.3]{pictures/web-example.png} + \caption{Example of web application} +\end{figure} + +\subsection{Validation rules} +\par +As it has been mention earlier, diktat has a highly customizable configuration file, but manually editing it is error-prone, for example, name of the rule can be incorrect due to a typo. Diktat will validate configuration file on startup and suggest the closest name based on \textsl{Levenshtein} method. + +\subsection{CI-CD} +\par +One of the most important parts of open source project is CI/CD pipeline as it brings considerable benefits to the entire software development process. It improves code quality, customer satisfaction and reduces costs, including time, of making new features. \ No newline at end of file diff --git a/wp/sections/introduction.tex b/wp/sections/introduction.tex index 1e118db080..af000f4b51 100644 --- a/wp/sections/introduction.tex +++ b/wp/sections/introduction.tex @@ -1,26 +1,7 @@ -It is necessary to conform to a specific style of code during software development, otherwise it will reduce the ability to better understand programmers’ intent and -find more functional defects. Analyzers, in turn, have methods for finding and correcting style errors. +It is necessary to conform to a specific style of code during software development, otherwise it will reduce the ability to better understand programmers’ intent and find more functional defects. Analyzers, in turn, have methods for finding and correcting style errors. -There are two types of code analysis: static and dynamic. The first is the process of identifying errors in the source code of the program, the second is the method - of analyzing the code directly during its execution. +Static code analysis is useful not only for optimization and increasing effectiveness but also for automatic error detection. -Static analysis can be thought of as an automated code review process. Of the tasks solved by static code analysis programs, two main ones can be -distinguished: identifying errors in programs and recommending code formatting. That is, the analyzer allows you to check whether the source code complies with the -accepted coding standard. Also, a static analyzer can be used to determine the maintainability of a code, which is how easy it is to analyze, modify and adapt a given -software. Static analysis tools allow you to identify a large number of errors in the design phase, which significantly reduces the development cost of the entire project. -Static analysis covers the entire code - it checks even those code fragments that are difficult to test. It does not depend on the compiler used and the environment -in which the compiled program will be executed.There are both open source\footnote{KtLint: \url{https://github.com/pinterest/ktlint}, -Detekt: \url{https://github.com/detekt/detekt}}, and commercial \footnote{IBM Security AppScan: \url{https://www.hcltechsw.com/wps/portal/products/appscan}, -PVS-Studio: \url{https://www.viva64.com/en/pvs-studio/}}. +There are many methods and techniques used by existing analyzers to find bugs (path-sensitive data flow analysis \cite{ref:kremenek}, alias analysis \cite{ref:effective}, type analysis \cite{ref:simple}, symbolic execution \cite{ref:dis}, abstract interpretation \cite{ref:dis}. -DiKTat - is a formal strict code style (\url{https://github.com/cqfn/diKTat}) and a linter with a set of rules that implement this code style. Basically, it is a collection -of Kotlin code style rules implemented as AST visitors on top of KTlint framework (\url{https://github.com/pinterest/ktlint}). Diktat warns and fixes code style errors and -code smells based on configuration file. DiKTat is a highly configurable framework, that can be extended further by adding custom rules. It can be run as command line -application or with maven or gradle plugins. In this paper, we will explain how DiKTat works, describes advantages and disadvantages and how it differs from other static -analyzers. - -So why did we decide to create diKTat? We looked at similar projects and realized that they have defects. That’s why we came to a conclusion that we need to create -convenient and easy-to-use tool for developers. Why is it easy-to-use? First of all, diKTat has its own highly configurable ruleset. You just need to fill your own options -on rules in ruleset or either use default one. Basically, ruleset is an yml file with a description of each rule. Secondly, there are a lot of developers that use different -tools for building projects. Most popular are Maven and Gradle. DiKTat supports these ones and it also has cli. Finally, each developer has their own codestyle and sometimes -they don’t want static analyzers to trigger on some lines of code. In diKTat you can easily disable a rule. +Static analysis can be thought of as an automated code review process. Of the tasks solved by static code analysis programs, two main ones can be distinguished: identifying errors in programs and recommending code formatting. That is, the analyzer allows you to check whether the source code complies with the accepted coding standard. Also, a static analyzer can be used to determine the maintainability of a code, which is how easy it is to analyze, modify and adapt a given software. Static analysis tools allow you to identify a large number of errors in the design phase, which significantly reduces the development cost of the entire project. Static analysis covers the entire code - it checks even those code fragments that are difficult to test. It does not depend on the compiler used and the environment in which the compiled program will be executed. \ No newline at end of file diff --git a/wp/sections/kotlin.tex b/wp/sections/kotlin.tex new file mode 100644 index 0000000000..c79347c6e0 --- /dev/null +++ b/wp/sections/kotlin.tex @@ -0,0 +1,34 @@ +\par Kotlin is a cross-platform, statically typed, general-purpose programming language with type inference. Kotlin is designed to interoperate fully with Java, and the JVM version of Kotlin's standard library depends on the Java Class Library, but type inference allows its syntax to be more concise. Kotlin mainly targets the JVM, but also compiles to JavaScript (e.g. for frontend web applications using React) or native code (via LLVM), e.g. for native iOS apps sharing business logic with Android apps. % wikipedia + +\par Kotlin has quickly skyrocketed in popularity. It's used by companies like Google, Square, Pinterest, Pivotal, Netflix and Atlassian. It's the fastest-growing programming language, according to GitHub, growing over 2,5 times in the past year. It was voted one of the five most loved languages, according to Stack Overflow. There are even meetups focused on Kotlin. \footnote{\url{https://www.businessinsider.com/kotlin-programming-language-explained-popularity-2019-5\#:\~:text=Kotlin\%20has\%20quickly\%20skyrocketed\%20in,times\%20in\%20the\%20past\%20year}} +% https://www.businessinsider.com/kotlin-programming-language-explained-popularity-2019-5#:~:text=Kotlin%20has%20quickly%20skyrocketed%20in,times%20in%20the%20past%20year. +\par Kotlin is used in a lot of ways. For example it can be used for backend development using ktor framework (developed by JetBrains), and spring framework also has first-party support for kotlin (Spring is one of the most popular framework on Java for Web development). Kotlin/JS provides the ability to transpile your Kotlin code to JavaScript, as well as providing JS variant of kotlin standard library and interopability with existing JS dependencies, both for Node.js and browser. There are numerous ways that Kotlin/JS can be used. For instance, you can write frontend web applications using Kotlin/JS, +write server-side and serverless applications using Kotlin/JS, create libraries for use with JavaScript and TypeScript. Support for multiplatform programming is one of Kotlin’s key benefits. It reduces time spent writing and maintaining the same code for different platforms while retaining the flexibility and benefits of native programming. + +\par Asynchronous or non-blocking programming is the new reality. Whether we're creating server-side, desktop or mobile applications, it's important that we provide an experience that is not only fluid from the user's perspective, but scalable when needed. +There are many approaches to this problem, and Kotlin takes a very flexible one by providing Coroutine support as a first-party library kotlinx.coroutines with a kotlin compiler plugin and delegating most of the functionality to libraries, much in line with Kotlin's philosophy. +As a bonus, coroutines not only open the doors to asynchronous programming, but also provide a wealth of other possibilities such as concurrency, actors, etc. + +A coroutine is a concurrency design pattern that you can use on Android to simplify code that executes asynchronously. Coroutines(in a form of kotlinx.coroutines library and kotlin compiler plugin) were added to Kotlin in version 1.3 and are based on established concepts from other languages. + +On Android, coroutines help to manage long-running tasks that might otherwise block the main thread and cause your app to become unresponsive. Over 50\% of professional developers who use coroutines have reported seeing increased productivity. Coroutines enable you to write cleaner and more concise app code. + +The state of Kotlin in 2020 (according to the latest Kotlin Census and statistical data) +\begin{itemize} + \item 4,7 million users + \item 65\% of users use Kotlin in production + \item For 56\% of users, Kotlin is their primary language, which means the main or only + one they use at work + \item 100+ people are on the Kotlin development team at JetBrains + \item 350+ independent contributors develop the language and its ecosystem outside + of JetBrains +\end{itemize} + +% https://techcrunch.com/2019/05/07/kotlin-is-now-googles-preferred-language-for-android-app-development/ +Kotlin is widely used among Android developers, including open source OS, like HarmonyOS, that are compatible with Android. In 2019 Google announced that the Kotlin programming language is now its preferred language for Android app developers. In the same year Stack Overflow stated that Kotlin is fourth most loved language in community. Nowadays there are over 60\% of android developers who use Kotlin as their main language. \footnote{\url{https://techcrunch.com/2019/05/07/kotlin-is-now-googles-preferred-language-for-android-app-development/}} +\par Kotlin's popularity can be explained by the rising number of Android users (last year, 124.4m in the USA) and, thus, Android-based devices. 80\% of Kotlin programmers use the language to build Android apps, 31\% for back-end applications, 30\% for SDK/libraries. +Kotlin is also interoperable with Java, which allows developers to use all existing Android libraries in a Kotlin app. Kotlin is in the top of PYPL rating. +\newline +\includegraphics[scale = 0.5]{pictures/kotlinRating.png} +\newline +\par Overall, Kotlin is a modern language that gain it's popularity incredibly fast. It is mostly used by Android developers, but other "branches of programming" are gaining popularity as well, for example spring framework(the most popular Java framework) is supporting Kotlin. It supports both OO (object-oriented) and FP (function-oriented) programming paradigms. Since release 1.4 Kotlin claims to bring major updated every 6 month. \ No newline at end of file diff --git a/wp/sections/work.tex b/wp/sections/work.tex new file mode 100644 index 0000000000..e6c49eb72a --- /dev/null +++ b/wp/sections/work.tex @@ -0,0 +1,194 @@ +Diktat does AST-analysis. This means that for internal representation (IR) it uses Abstract Syntax Tree that was created from the parsed code by the kotlin-compiler. This chapter describes how diktat works + +\subsection{ktlint} +\par +To quickly and efficiently analyze the program code, you first need to transform it into a convenient data structure. This is exactly what ktlint does - it parses plain text code into an abstract syntax tree. In ktlint, this happens in the \textsl{prepareCodeForLinting}\footnote{\url{https://github.com/pinterest/ktlint/blob/master/ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/KtLint.kt}} method. This method uses kotlin-compiler-embeddable library to create a root node of type FILE. +For example, this simple code: +\begin{lstlisting}[caption={Simple function.}, label={lst:example1}, language=Kotlin] + fun main() { + println("Hello World") + } +\end{lstlisting} +will be converted into this AST:\\ + +\tikzstyle{every node}=[draw=black,thick,anchor=west, scale = 0.5] + +\begin{tikzpicture}[% + grow via three points={one child at (0.3,-0.8) and + two children at (0.3,-0.8) and (0.3,-1.5)}, + scale=0.5, + edge from parent path={(\tikzparentnode.south) |- (\tikzchildnode.west)}] + + \node {FILE} + child { node {PACKAGE\underline{ }DIRECTIVE}} + child { node {IMPORT\underline{ }LIST}} + child { node {FUN} + child {node {fun}} + child {node {WHITE\underline{ }SPACE}} + child {node {IDENTIFIER}} + child {node {VALUE\underline{ }PARAMETER\underline{ }LIST} + child {node {LPAR}} + child {node {RPAR}} + } + child [missing] {} + child [missing] {} + child {node {WHITE\underline{ }SPACE}} + child {node {BLOCK} + child {node {LBRACE}} + child {node {WHITE\underline{ }SPACE}} + child {node {CALL\underline{ }EXPRESSION} + child {node {REFERENCE\underline{ }EXPRESSION} + child {node {IDENTIFIER}} + } + child [missing] {} + child {node {VALUE\underline{ }ARGUMENT\underline{}LIST} + child {node {LPAR}} + child {node {VALUE\underline{ }ARGUMENT} + child {node {STRING\underline{ }TEMPLATE} + child {node {OPEN\underline{ }QUOTE}} + child {node {LITERAL\underline{ }STRING\underline{ }TEMPLATE\underline{ }ENTRY} + child {node {REGULAR\underline{ }STRING\underline{ }PART}} + } + child [missing] {} + child {node {CLOSING\underline{ }QUOTE}} + } + } + child [missing] {} + child [missing] {} + child [missing] {} + child [missing] {} + child [missing] {} + child [missing] {} + child {node {RPAR}} + } + } + child [missing] {} + child [missing] {} + child [missing] {} + child [missing] {} + child [missing] {} + child [missing] {} + child [missing] {} + child [missing] {} + child [missing] {} + child [missing] {} + child [missing] {} + child [missing] {} + child [missing] {} + child {node {WHITE\underline{ }SPACE}} + child {node {RBRACE}} + } + }; +\end{tikzpicture} + +If there are error elements inside the constructed tree, then the corresponding error is displayed. If the code is valid and parsed without errors, for each rule in the ruleset, the \textsl{visit} method is called to which the root node itself and its “children” are sequentially passed. +When you run program, you can pass flags to ktlint - one of them is "-F". This flag means that the rule will not only report an error, but try to fix it. + +\subsection{diKTat} +\par +Another feature of ktlint is that at startup you can provide a JAR file with additional ruleset(s), which will be discovered by the ServiceLoader and then all nodes will be passed to these rules. This is diKTat! DiKTat is a set of easily configurable rules for static code analysis. The set of all rules is described in the \textsl{DiktatRuleSetProvider}\footnote{\url{https://github.com/cqfn/diKTat/blob/v0.1.3/diktat-rules/src/main/kotlin/org/cqfn/diktat/ruleset/rules/DiktatRuleSetProvider.kt}} class. This class overrides the \textsl{get()} method of the \textsl{RuleSetProvider}\footnote{\url{https://github.com/pinterest/ktlint/blob/master/ktlint-core/src/main/kotlin/com/pinterest/ktlint/core/RuleSetProvider.kt}} interface, which returns a set of rules to be "traversed". But before returning this set, the configuration file, in which the user has independently configured all the rules, is read. If there is no configuration file, then a warning will be displayed and the rules will be triggered in according with the default configuration file. +Each rule must implement the \textsl{visit} method of the abstract Rule class, which describes the logic of the rule. + +//TODO: add comments +\begin{lstlisting}[caption={Example of rule.}, label={lst:example1}, language=Kotlin] +class SingleLineStatementsRule(private val configRules: List) : Rule("statement") { + + companion object { + private val semicolonToken = TokenSet.create(SEMICOLON) + } + + private lateinit var emitWarn: ((offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit) + private var isFixMode: Boolean = false + + override fun visit(node: ASTNode, + autoCorrect: Boolean, + emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit) { + emitWarn = emit + isFixMode = autoCorrect + + checkSemicolon(node) + } + + private fun checkSemicolon(node: ASTNode) { + node.getChildren(semicolonToken).forEach { + if (!it.isFollowedByNewline()) { + MORE_THAN_ONE_STATEMENT_PER_LINE.warnAndFix(configRules, emitWarn, isFixMode, it.extractLineOfText(), + it.startOffset, it) { + if (it.treeParent.elementType == ENUM_ENTRY) { + node.treeParent.addChild(PsiWhiteSpaceImpl("\n"), node.treeNext) + } else { + if (!it.isBeginByNewline()) { + val nextNode = it.parent({ parent -> parent.treeNext != null }, strict = false)?.treeNext + node.appendNewlineMergingWhiteSpace(nextNode, it) + } + node.removeChild(it) + } + } + } + } + } +} +\end{lstlisting} + +The example above describes the rule in which you cannot write more than two statements on one line. The list of configurations is passed to the parameter of this rule so that the error is displayed only when the rule is enabled (further it will be described how to enable and disable the rule). The class fields and the \textsl{visit} method are described below. The first parameter in method is ASTNode - the node that we got in the parsing in ktlint. Then a check occurs: if the code contains a line in which more than one statement per line and this rule is enabled, then the rule will be executed and, depending on the mode in which the user started ktlint, the rule will either simply report an error or fix it. In our case, when an error is found, the method is called to report and fix the error - \textsl{warnAndFix()}. Warnings that contain similar logic (e.g. regarding formatting of function KDocs) are checked in the same Rule. This way we can parse similar parts of AST only once. Whether the warning is enabled or disabled is checked at the very last moment, inside \textsl{warn()} or \textsl{warnAndFix()} methods. Same is true for suppressions: right before emitting the warning we check whether any of current node's parents has a Suppress annotation. + +\subsection{Examples of unique inspections} +\par +As already described above, diKTat has more rules than existing analogues, therefore, it will find and fix more errors and shortcomings and, thereby, make the code cleaner and better. To better understand how much more detailed the diKTat finds errors, consider a few examples: + +\begin{enumerate} + \item \textbf{Package} +In diKTat, there are about 6 rules only for package (examples). For comparison: detekt has only one rule, where the package name is simply checked by a pattern, in ktlint there is no. + \item \textbf{KDoc} +KDoc is an important part of good code to make it easier to understand and navigate the program. In diKTat there are 15 rules on KDoc, in detekt there are only 7. Therefore, diKTat will make and correct KDoc in more detail and correctly. Examples of rules that have no analogues: examples + \item \textbf{Header} +Like KDoc, header is an essential part of quality code. DiKTat has as many as 6 rules for this, while detekt and ktlint do not. (Examples) +\end{enumerate} + +There are also many unique rules that no analogues have, here are some of them: + +\begin{enumerate} + \item \textbf{COMMENTED\underline{ }OUT\underline{ }CODE} – This rule performs checks if there is any commented code. + \item \textbf{FILE\underline{ }CONTAINS\underline{ }ONLY\underline{ }COMMENTS} – This rule checks file contains not only comments. + \item \textbf{LOCAL\underline{ }VARIABLE\underline{ }EARLY\underline{ }DECLARATION} – This rule checks that local variables are declared close to the point where they are first used. + \item \textbf{AVOID\underline{ }NESTED\underline{ }FUNCTIONS} - This rule checks for nested functions and warns and fixes if it finds any. An example of changing the tree when this rule is triggered and diKTat is run with fix mode:\\ + \begin{tikzpicture}[% + grow via three points={one child at (0.3,-0.8) and + two children at (0.3,-0.8) and (0.3,-1.5)}, + scale=0.5, + edge from parent path={(\tikzparentnode.south) |- (\tikzchildnode.west)}] + + \node(a) {...} + child { node {FUN} + child {node {...}} + child {node {BLOCK} + child {node {FUN} + child{node{...}} + child{node{BLOCK} + child{node{...}} + } + } + } + }; + + \node(b) [right of=a, xshift=17cm]{...} + child { node {FUN} + child {node {...}} + child {node {BLOCK} + child{node{...}} + } + } + child [missing] {} + child [missing] {} + child { node {FUN} + child {node {...}} + child {node {BLOCK} + child{node{...}} + } + }; + + \draw[-latex,very thick,shorten <=5mm,shorten >=5mm,] ([xshift=5cm,yshift=-3cm]a.north) to ([xshift=-2cm, yshift=-3cm]b.north); + +\end{tikzpicture} + \item \textbf{FLOAT\underline{ }IN\underline{ }ACCURATE\underline{ }CALCULATIONS} - Rule that checks that floating-point numbers are not used for accurate calculations. +\end{enumerate} diff --git a/wp/wp.tex b/wp/wp.tex index 8c8d301661..6dda8c00c6 100644 --- a/wp/wp.tex +++ b/wp/wp.tex @@ -1,16 +1,33 @@ -\documentclass[12pt]{article} +\documentclass[acmlarge, screen, nonacm]{acmart} +\usepackage[utf8]{inputenc} +\usepackage{graphicx} \usepackage{pgf} +\usepackage{multicol} \usepackage{setspace} - \setstretch{1.1} -\usepackage[top=1.3in, left=1.4in, includefoot]{geometry} \usepackage{charter} \usepackage{listings} -\usepackage{authblk} +\usepackage{hyperref} +\usepackage{float} +\usepackage{placeins} +\usepackage{graphicx} +\graphicspath{ {./images/} } +\usepackage{tikz} +\usepackage{verbatim} +\usepackage{cleveref} +\usepackage{datetime} + +\crefname{figure}{Figure}{Figures} +\usetikzlibrary{trees} +\usetikzlibrary{arrows} \definecolor{codegreen}{rgb}{0,0.6,0} \definecolor{codegray}{rgb}{0.5,0.5,0.5} \definecolor{codepurple}{rgb}{0.58,0,0.82} \definecolor{backcolour}{rgb}{0.95,0.95,0.92} +\definecolor{OrangeRed}{rgb}{1,0.27,0} +\definecolor{ForestGreen}{rgb}{0.1334,0.545,0.1334} +\definecolor{NavyBlue}{rgb}{0,0.502,0} +\definecolor{BurntOrange}{rgb}{0.8,0.3334,0.1334} \lstdefinestyle{mystyle}{ backgroundcolor=\color{backcolour}, @@ -31,81 +48,121 @@ tabsize=2 } -\lstset{style=mystyle} - -\title{ - \includegraphics[height=250pt]{logo.png}\\ - \vspace{10pt} - \textsc{DiKTat:}\\ - Static Code Analysis} -\author{Yegor Bugayenko, Andrey Kuleshov, Peter Trifanov, Kumar Denis, Tsay Alexander} -\affil{Huawei Technologies Co., Ltd. \\ System Programming Lab \\ Russian Research Institute (RRI) \\ Moscow, Russia} - -\begin{document} +\lstdefinelanguage{Kotlin}{ + comment=[l]{//}, + commentstyle={\color{gray}\ttfamily}, + emph={delegate, filter, first, firstOrNull, forEach, lazy, map, mapNotNull, println, return@}, + emphstyle={\color{OrangeRed}}, + identifierstyle=\color{black}, + keywords={abstract, actual, as, as?, break, by, class, companion, continue, data, do, dynamic, else, enum, expect, false, final, for, fun, get, if, import, in, interface, internal, is, null, object, override, package, private, public, return, set, super, suspend, this, throw, true, try, typealias, val, var, vararg, when, where, while}, + keywordstyle={\color{NavyBlue}\bfseries}, + morecomment=[s]{/*}{*/}, + morestring=[b]", + morestring=[s]{"""*}{*"""}, + ndkeywords={@Deprecated, @JvmField, @JvmName, @JvmOverloads, @JvmStatic, @JvmSynthetic, Array, Byte, Double, Float, Int, Integer, Iterable, Long, Runnable, Short, String}, + ndkeywordstyle={\color{BurntOrange}\bfseries}, + sensitive=true, + stringstyle={\color{ForestGreen}\ttfamily}, +} -\maketitle +\lstset{style=mystyle} +\settopmatter{printacmref=false} +\setcopyright{none} +\makeatletter +\let\@authorsaddresses\@empty -\pagebreak +\makeatletter +\let\newdate\@date -\begin{abstract} +\settopmatter{printacmref=false} +\setcopyright{none} +\renewcommand\footnotetextcopyrightpermission[1]{} +\pagestyle{plain} -DiKTat is a collection of Kotlin code style rules implemented as AST visitors on top of KTlint. Diktat warns and fixes code style errors based on configuration file. DiKTat can be extended further by adding custom rules. In this paper, we explain how DiKTat works, describe advantages and disadvantages and how it differs from other static analyzers. +\begin{document} -\end{abstract} +\title[]{ + \includegraphics[width = 230pt, height = 200pt]{wp/pictures/logo.png}\\ + DiKTat - Kotlin linter +} -\newpage +\author{Andrey Kuleshov} +\email{andrewkuleshov7@gmail.com} +\affiliation{ +\institution{Lomonosov Moscow State University} +\country{Russia} +} +\author{Petr Trifanov} +\email{peter.trifanov@mail.ru} +\affiliation{ +\institution{Lomonosov Moscow State University} +\country{Russia} +} +\author{Denis Kumar} +\email{qbextted0@gmail.com} +\affiliation{ +\institution{Higher School of Economics} +\country{Russia} +} +\author{Alexander Tsay} +\email{aktsay6@gmail.com} +\affiliation{ +\institution{Higher School of Economics} +\country{Russia} +} -\tableofcontents +\renewcommand{\shortauthors}{} -\newpage +\maketitle \section{Introduction} \label{sec:intro} \input{sections/introduction} -\newpage +\section{Definition} +\label{sec:definition} +\input{sections/definition} -\section{How does diKTat work} -\subsection{The idea} -\subsection{Rules description} -\subsection{How diKTat detects issues} -\subsection{DiKTat implementation} -\subsection{Examples} +\section{Kotlin} +\label{sec:kotlin} +\input{sections/kotlin} -\newpage +\section{diKTat} +\label{sec:diKTat} +\input{sections/diKTat} -\section{Analysis of similar projects} -\subsection{Ktlint} -\subsection{Detekt} -\newpage +\section{Comparative analysis} +\label{sec:compare} +\input{sections/compare} -\section{How to use diKTat} -\subsection{Maven} -\input{sections/chapter 4/maven} -\subsection{Gradle} -\input{sections/chapter 4/gradle} -\subsection{CLI-application} -\input{sections/chapter 4/cli} -\subsection{How to configure ruleset} -\input{sections/chapter 4/rulesetConfigure} -\newpage +\section{How does it work} +\label{sec:work} +\input{sections/work} -\section{DiKTat on big projects} +\section{Killer-Feature} +\label{sec:feature} +\input{sections/feature} -\newpage -\section{Appendix} -\subsection{Main components} -\subsubsection{Data diagram} -\subsubsection{Class diagram} -\subsubsection{Component view} +\section{How to use diKTat} +\label{sec:download} +\input{sections/download} -\subsection{Diagrams of system usage} -\subsubsection{Use-case diagram} -\subsubsection{Activity diagram} -\subsubsection{Data Flow Diagram} +\section{Examples} +\label{sec:examples} +\input{sections/examples} + +\section{Conclusion \& Future Work} +\label{sec:conclusion} +\input{sections/conclusion} \newpage -\section{References} +\nocite{*} +\bibliographystyle{ieeetr} +\bibliography{references.bib} +\newpage +\section{Appendix} +\label{sec:appendix} +\input{sections/appendix} \end{document}