1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
|
<!DOCTYPE html>
<html>
<head>
<title>Checker Framework developer manual</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="../manual/favicon-checkerframework.png" type="image/png"/>
</head>
<body>
<h1 id="Checker_Framework_developer_manual">Checker Framework developer manual</h1>
<p>
If you wish to use the Checker Framework, see its user manual
(<a href="https://checkerframework.org/manual/">HTML</a>,
<a href="https://checkerframework.org/manual/checker-framework-manual.pdf">PDF</a>).
</p>
<p>
This document contains information for Checker Framework developers,
including people who wish to edit its source code or make pull requests.
</p>
<p>Contents:</p>
<!-- start toc. do not edit; run html-update-toc instead -->
<ul>
<li><a href="#Directory_structure">Directory structure</a></li>
<li><a href="#Build_tasks">Build tasks</a></li>
<li><a href="#tests">Testing the Checker Framework</a></li>
<li><a href="#Code_style">Code style</a></li>
<li><a href="#IDE_configuration">IDE configuration</a>
<ul>
<li><a href="#Configure_Eclipse_to_edit_the_Checker_Framework">Configure Eclipse to edit the Checker Framework</a></li>
</ul></li>
<li><a href="#pull-requests">Pull requests</a>
<ul>
<li><a href="#pull-requests-maintainers">Pull request and commit notes for maintainers</a></li>
</ul></li>
<li><a href="#ci">Continuous Integration</a>
<ul>
<li><a href="#ci-failure">What to do if a Continuous Integration build fails</a></li>
</ul></li>
<li><a href="#testing-optimizations">Testing optimizations</a></li>
<li><a href="#Documenting_refactoring_ideas">Documenting refactoring ideas</a></li>
<li><a href="#annotated-library-version-numbers">Version numbers for annotated libraries</a></li>
<li><a href="#Making_a_Checker_Framework_release">Making a Checker Framework release</a></li>
</ul>
<!-- end toc -->
<h2 id="Directory_structure">Directory structure</h2>
<p>
The <a href="https://github.com/typetools/checker-framework">checker-framework
repository</a> contains several related projects:
</p>
<dl>
<dt><code>framework</code></dt>
<dd>the framework that enables building pluggable type checkers</dd>
<dt><code>checker</code></dt>
<dd>the type checkers provided with the Checker Framework</dd>
<dt><code>javacutil</code></dt>
<dd>utilities for integrating with javac</dd>
<dt><code>dataflow</code></dt>
<dd>a dataflow framework that is used by the Checker Framework, <a href="https://errorprone.info">Error Prone</a>, <a href="https://github.com/uber/NullAway">NullAway</a>, and other tools</dd>
</dl>
<p>
The repository also contains the following directories:
</p>
<dl>
<dt><code>docs</code></dt>
<dd>documentation: manual, tutorial, examples, developer docs</dd>
<dt><code>maven-artifacts</code></dt>
<dd>artifacts to be uploaded to Maven Central</dd>
</dl>
<h2 id="Build_tasks">Build tasks</h2>
<p>
Full instructions for building the Checker Framework from sources appear in
the <a href="https://checkerframework.org/manual/#build-source">Checker
Framework manual</a>. This section describes the build system (the Gradle build tasks).
</p>
<p>
Don't run the <code>gradle</code> command, which would use whatever version
of Gradle is installed on your computer. Instead, use
the <code>gradlew</code> script in the <code>checker-framework</code>
directory, also known as
the <a href="https://docs.gradle.org/current/userguide/gradle_wrapper.html">Gradle
wrapper</a>.
</p>
<p>
Frequently-used tasks:
</p>
<ul>
<li> <code>assemble</code>: builds all jars except <code>jdk8.jar</code>, including javadoc jars and fat jars that contain all dependencies.
<li> <code>build</code>: <code>assemble</code>, plus runs all JUnit tests.
<li> <code>buildJdk</code>: builds <code>jdk8.jar</code>.
<li> <code>allTests</code>: runs all tests.
<li> <code>reformat</code>: reformats Java files.
<li> <code>NameOfJUnitTest</code>: runs the JUnit test with that name; for example, <code>NullnessFbcTest</code>.
<li> <code>task</code>: lists tasks; use <code>--all</code> to see all tasks.
</ul>
<p>
If you run a task from the main directory, then it will run that task in all
subprojects with a task by that name. So, if you run <code>./gradlew
allTests</code> that runs all tests everywhere. But <code>(cd
framework && ../gradlew allTests)</code> only runs tests in
the <code>framework</code> project.
Alternatively, running <code>:framework:allTests</code> from the
main directory or any subproject runs the <code>allTests</code> task only in the <code>framework</code> project.
</p>
<h2 id="tests">Testing the Checker Framework</h2>
<p>
For writing new test cases, see file
[`checker/tests/README`](https://raw.githubusercontent.com/typetools/checker-framework/master/checker/tests/README).
</p>
<h2 id="Code_style">Code style</h2>
<p>
Code in this project follows the
<a href="https://google.github.io/styleguide/javaguide.html">Google Java Style
Guide</a> (except 4 spaces are used for indentation),
<a href="https://homes.cs.washington.edu/~mernst/advice/coding-style.html">Michael
Ernst's coding style guidelines</a>, and <a href="http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-136091.html#248">Oracle's
Java code conventions</a>.
</p>
<p>
From the command line, you can format your code by running <code>./gradlew reformat</code>.
You
can <a href="https://github.com/google/google-java-format#using-the-formatter">configure
your IDE</a> (Eclipse or IntelliJ) to use the formatting (don't forget the
non-standard <code>-a</code> flag).
</p>
<p>
We don't use <code>@author</code> Javadoc tags in code files.
Doing so clutters the code, and is misleading once that individual
is no longer maintaining the code.
Authorship (and who has made changes recently) can be obtained from the
version control system, such as by running <code>git annotate <em>filename</em></code>.
</p>
<p>
Every class, method, and field (even private ones) must have a
descriptive Javadoc comment.
</p>
<h2 id="IDE_configuration">IDE configuration</h2>
<h3 id="Configure_Eclipse_to_edit_the_Checker_Framework">Configure Eclipse to edit the Checker Framework</h3>
<p>
These instructions are relevant if you use Eclipse as your IDE.
</p>
<ol>
<li> <a href="../manual/manual.html">Clone and build all projects from their sources.</a>
</li>
<li> Download Eclipse from
the <a href="https://www.eclipse.org/downloads/">official Eclipse website</a>
and install it.
</li>
<li> Run Eclipse.
</li>
<li> Enter the main Eclipse working screen and in the “File” menu,
select “Import” ⇒ “General” ⇒ “Existing
Projects into Workspace”.
</li>
<li> After the “Import Projects” window appears, select “Select
Root Directory”, and select the parent of the <code>$CHECKERFRAMEWORK</code> directory.
</li>
<li> Ensure “Search for nested projects” is selected in the Options panel.
</li>
<li> Select all the projects in the folder except for “personalblog-demo”,
then select “Finish” to import the projects.
</li>
</ol>
<p>
Eclipse should successfully build all the imported projects.
If Eclipse reports any errors, ensure you followed the instructions for
<a href="../manual/manual.html">cloning and building all projects.</a>
</p>
<h2 id="pull-requests">Pull requests</h2>
<p>
Each pull request should address a single concern, rather than (say)
addressing multiple concerns such as fixing a bug, adding a feature, <em>and</em>
changing formatting. Focusing each pull request on a single concern makes
the commit easier to understand and review. It also makes the commit
history (after the pull request is merged) easier to understand and (if
necessary) revert.
</p>
<p>
The pull request title should clearly explain the change. It will be used
as the commit message for your change. If the pull request fixes an issue
in the issue tracker, its title should end with "; fixes #NNN" where NNN is
the fixed issue.
</p>
<p>
Your pull request (whether it is a bug fix or a new feature) should
include tests that fail before your change and pass afterward.
</p>
<p>
If you make a user-visible change, update the manual (or add a new section)
and add a brief description at the top of the changelog
(file <code>changelog.txt</code>).
</p>
<p>
To reduce iterations of code review, please follow
the <a href="#code-style">coding conventions</a>.
Also enable <a href="#ci">continuous integration</a> on your fork of the Checker
Framework and ensure that it passes before you open a pull request.
</p>
<p>
It is good style to create a branch (in your fork of the Checker
Framework GitHub repository) for each independent change. Do not make
changes to your <code>master</code> branch.
</p>
<p>
If you make related changes in the <code>checker-framework</code>
and <code>checker-framework-inference</code> repositories, use the <em>same
branch name</em> for each. The continuous integration framework will find
and use that branch when running tests.
</p>
<p>
Also
see <a href="https://homes.cs.washington.edu/~mernst/advice/github-pull-request.html">Michael
Ernst's advice about creating GitHub pull requests</a>.
</p>
<h3 id="pull-requests-maintainers">Pull request and commit notes for maintainers</h3>
<p>
It is acceptable to commit small, noncontroversial changes directly to
master. (This policy differs from some projects, which require an issue
tracker issue and a pull request for every change, however minor.)
As with pull requests, each commit should address a single concern.
For any change where you want feedback, or where others might have
useful comments or might disagree, please submit a pull request. Be
conservative in your judgment; others might consider something
controversial that you do not.
</p>
<p>
Try to review pull requests promptly, to avoid stalling others while
waiting for your feedback. If you have been waiting for more than a week
after the pull request was assigned with no feedback, then ping the
assignee, wait at least another business day, and then go ahead and push
your changes. It's great if reviewers can give feedback, but if they are
too busy to do so, you should recognize that and move on.
</p>
<h2 id="ci">Continuous Integration</h2>
<p>
The Checker Framework has continuous integration jobs that run in Azure
Pipelines, CircleCI, and/or Travis CI on each push to GitHub.
</p>
<p>
To enable Travis CI continuous integration for your fork:
</p>
<ul>
<li>Browse to <a href="https://travis-ci.com/">travis-ci.com</a></li>
<li>Click the downarrow for the dropdown, near your face in the upper right corner</li>
<li>Click settings</li>
<li>Find "checker-framework" in the list, and click the slider to enable it.</li>
</ul>
<p>
To enable Azure Pipelines continuous integration for your fork:
</p>
<ul>
<li>Go to dev.azure.com.
(You might need to create a (free) account.)</li>
<li>Click "Create a project to get started"</li>
<li>Click "public".</li>
<li>Click "create project"</li>
<li>At the left, click the blue rocket labeled "pipelines"</li>
<li>Click "new pipeline"</li>
<li>Click "GitHub"
(You might need to authorize the app on GitHub.)</li>
<li>Click "Select a repository"</li>
<li>Choose <em>MYUSERID</em>/checker-framework</li>
<li>Choose the default radio button, "only selected repositories". <b>Do not</b> choose "all repositories".</li>
<li>Approve and install.</li>
<li>Click "run".</li>
</ul>
<h3 id="ci-failure">What to do if a Continuous Integration build fails</h3>
<p>
Sometimes, CI tests for your pull request may fail even though your local build passed.
This is usually because the CI service performed more tests than you ran locally.
</p>
<p>
First, examine the CI service's logs, which contain diagnostic output from the
failing command. You can determine which command was run from the logs, or
from the CI configuration file (such as <code>azure-pipelines.yml</code>).
</p>
<h2 id="testing-optimizations">Testing optimizations</h2>
<p>
To test an optimization that should speed up type-checking, see
the <code>test-daikon.sh</code> stage of the <code>daikon_jdk8</code> job
of the Azure Pipelines CI job. Compare the run time of this stage (or of
the entire <code>daikon_jdk8</code> job) between the master branch and a
branch with your improvements.
</p>
<p>
You can also compare run times of the Checker Framework test suite.
</p>
<h2 id="Documenting_refactoring_ideas">Documenting refactoring ideas</h2>
<p>
If you have an idea for a code improvement (such as a refactoring), please
document it. If it can be described concisely and is low priority, a TODO
comment in the code is more appropriate than an enhancement request in the
issue tracker. The code comment is more likely to be noticed by someone
working with the code, and it is equally easy to search for. Furthermore,
it doesn't clutter the issue tracker. Clutter in the issue tracker reduces
morale, makes it harder to search, and makes the project appear
lower-quality than it actually is.
</p>
<h2 id="annotated-library-version-numbers">Version numbers for annotated libraries</h2>
<p>
We maintain annotated versions of some third-party libraries. The source
code appears in a fork in
the <a href="https://github.com/typetools">GitHub <code>typetools</code>
organization</a>. Binaries are hosted
at <a href="https://search.maven.org/search?q=annotatedlib">Maven Central
in the <code>org.checkerframework.annotatedlib</code> group</a>.
</p>
<p>
Annotated libraries should be based on a released version of the upstream
library, not an arbitrary commit in the upstream library's version control
system. The library's version number is the same as the upstream version
number.
</p>
<p>
When making a new version of an annotated library, between upstream
releases, add ".0.1" to the end of the version number. For example, if we
already uploaded version 6.2 to Maven Central, the next version we upload
would be 6.2.0.1. This accommodates the possibility that the upstream
maintainers release 6.2.1. Our further releases increment the last number,
for example to 6.2.0.2.
</p>
<h2 id="Making_a_Checker_Framework_release">Making a Checker Framework release</h2>
<p>
See a separate document about the
<a href="release/README-release-process.html">Checker Framework release process</a>.
</p>
</body>
</html>
<!-- LocalWords: TODO javacutil gradle javadoc reformats subprojects pre NullAway CircleCI travis ci downarrow dropdown MYUSERID
-->
<!-- LocalWords: subproject personalblog changelog
-->
|