- Dart:Scalable Application Development
- Davy Mitchell Sergey Akopkokhyants Ivo Balbaert
- 1280字
- 2021-07-09 18:56:16
The command-line app for source code statistics
Our customers like the software development angle of the text editor and has asked for some source code statistics such as SLOC (source lines of code) to be made accessible. This feature may be of use outside the web page, such as in a continuous integration environment, so we will construct our first command-line application.
We will create the project in WebStorm from scratch, but a completed version is also supplied in the sample code in a folder called dart_stats
.
The command-line project structure
Open WebStorm, click on Create New Project, and select Console application from the Project Templates list. Choose a location for your project and call it dart_stats
.
The structure of the application has a bin
folder with main.dart
, which is the entry point for the application. This is where the main
function is located. The project template contains several other items. For this tool, the focus will be on the main function.
Add the source code file sourcescan.dart
to the project. This contains the code for scanning the text and tallying up line counts for classes, code, comments, imports, and whitespace.
The SourceCodeScanner
class contains five integer fields to store the counts and a single method to perform the analysis:
void scan: (List<String> lines) { totalLines = lines.length; lines.forEach((line) { line = line.trim(); if (line.startsWith("class")) classes++; else if (line.startsWith("import")) imports++; else if (line.startsWith("http://")) comments++; else if (line.length == 0) whitespace++; }); }
The list of lines is iterated over and the trim
method is used to remove extra whitespace from the lines to aid in matching the keywords that trigger and increment the count. The startsWith
method makes sure that the keyword is not appearing mid-line in another context.
The application will be passed a single command-line argument, which is the full file path to a Dart source code file. The command-line arguments can be read from the parameter passed to the main function in main.dart
.
One aspect that we will not have to deal with in the browser is loading the source code from a text file. A package that is not available to Dart in the web browser, due to security, is the IO
package, which contains direct file handling functionality:
import 'sourcescan.dart'; import 'dart:io'; main(List<String> arguments) { print(arguments[0]); SourceCodeScanner codeScan = new SourceCodeScanner(); File myFile = new File(arguments[0]); myFile.readAsLines().then((List<String> Lines) { codeScan.scan(Lines); print("${codeScan.totalLines}"); print("${codeScan.classes}"); print("${codeScan.comments}"); print("${codeScan.imports}"); print("${codeScan.whitespace}"); }); }
Once the text file is in a string, it can be processed in the same manner as in the web text editor.
The program can be run from the command-line, as shown here on Linux:
$ dart bin/main.dart lib/dartstats.dart lib/dartstats.dart 9 0 3 0 2
The program can examine its own source code!
Tip
For more advanced handling of command-line arguments, see the very powerful args
package on pub
at https://pub.dartlang.org/packages/args.
readAsLines
is an asynchronous function that immediately returns a Future
object. A function is passed into the future object's then
method. The timing of the execution of this function is unknown to the developer. The flow of the program continues straight away. When the file read operation is run and has completed, the function passed to the then
method is executed when the Dart VM schedules it.
To see this in action, move the print statements outside of the then
function, as shown, and run the program again:
... myFile.readAsLines().then((List<String> Lines) { codeScan.scan(Lines); }); print("${codeScan.totalLines}"); print("${codeScan.classes}"); print("${codeScan.comments}"); print("${codeScan.imports}"); print("${codeScan.whitespace}"); ...
The probable output is all zeros as the code lines have not been scanned yet; this is because the print
functions are being called first.
It is also possible that the program will run just as before. The key point is that the overall program execution keeps moving forward even when the code is asked to perform a potentially long-running task, allowing other tasks to continue and keeping the application responsive.
If you launch the program as it is in WebStorm by using Run
, then it will open up the debugger with a RangeError
exception. This is because the program is assuming that a command-line argument has been passed and the program has been run without any input.
In WebStorm, launches of programs into debugging can be configured, including a feature to set command-line arguments. In this case, a full file path to a Dart source file should be put in the Program arguments field. Note that, by default, no command-line arguments are passed. It is also possible to set multiple launches with different sets of command-line options:

To configure launches, select the Edit Configurations option from the Run menu. Select main.dart
from the list and enter the full file path of any Dart source code file, such as one for the sample code for this book or from the Dart SDK.
Once the program is run, the results are printed to standard output using the print
function.
The class SourceStats
can be added to the text editor project by adding the sourcescan.dart
file to the bin
folder and referencing it as a straightforward import. The scan is to be performed on the contents of the editor in the scanCode
method of the CodeStatDialog,
and the data is to be extracted for drawing on the pie chart.
HTML5 and the canvas
Given that the Canvas
HTML element has been around for approximately 10 years since Apple introduced it into their version of Webkit, it seems odd that it is still considered a new feature! Widespread support has been seen in the major and minor browsers for several years now.
The canvas element provides a high-performance 2D raster-based graphics bitmap that can be scripted dynamically. In contrast to SVG, there are no scene graphs or selectable objects, just a graphic image. It provides an easy-to-use and powerful way to display dynamic images on the client side for applications such as graphs, animations, and games:

The four pieces of data collected are to be represented as segments in a pie chart. In the CodeStatsDialog
constructor, the canvas
HTML element is selected in the same manner as any other page element. A 2D context is requested, which returns an object we can call methods on to draw on the Canvas
:
CanvasElement graphs = new CanvasElement(); graphs.width = 500; graphs.height = 270; c2d = graphs.getContext("2d"); contentDiv..append(new BRElement())..append(graphs);
The stroke is the pen to be used and the fill is analogous to the paint. Each pie segment is drawn in a black outline (stroke
) and painted in with the fill
:
for (int i = 0; i < 4; i++) { c2d ..fillStyle = colors[i] ..strokeStyle = "black" ..beginPath() ..moveTo(radius, radius) ..arc(radius, radius, radius, lastpos, (lastpos + (PI * 2.0 * (data[i] / totalLines))), false) ..lineTo(radius, radius) ..fill() ..stroke() ..closePath(); lastpos += PI * 2.0 * (data[i] / totalLines); print(lastpos);
The arc
method uses radians, so the constant PI
is used in the calculations:
c2d ..beginPath() ..strokeStyle = "black" ..fillStyle = colors[i] ..fillRect(380, 90 + 20 * i, 8, 8) ..strokeRect(380, 90 + 20 * i, 8, 8) ..strokeText(labels[i], 400, 100 + 20 * i) ..stroke() ..closePath();
The labels are drawn for each of the four counts by using a square Rect
to show the color, and the text is drawn alongside it.
- 編程卓越之道(卷3):軟件工程化
- Mastering ServiceNow(Second Edition)
- Learning Apache Mahout Classification
- Python算法從菜鳥到達(dá)人
- Python Data Analysis Cookbook
- Spring核心技術(shù)和案例實(shí)戰(zhàn)
- PHP+Ajax+jQuery網(wǎng)站開發(fā)項(xiàng)目式教程
- Go語(yǔ)言底層原理剖析
- C++程序設(shè)計(jì)教程(第2版)
- Python Deep Learning
- Hacking Android
- 超好玩的Scratch 3.5少兒編程
- Java高手是怎樣煉成的:原理、方法與實(shí)踐
- Xamarin Cross-Platform Development Cookbook
- 量子計(jì)算機(jī)編程:從入門到實(shí)踐