@produtype/core 0.69.0 → 0.70.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The lines of a C-family file that sit inside a block comment.
3
+ *
4
+ * The comment rule reads one line at a time and looks for a marker at its start:
5
+ * a double slash, a slash-star, a lone star. A block comment written without a
6
+ * leading star on every line has no marker to find, and neither does code that
7
+ * somebody commented out by wrapping the whole thing. In AsteroidsJS a wrapped
8
+ * `localStorage.setItem('highScores', ...)` was cited as evidence that the game
9
+ * saves progress; the function it belongs to is switched off.
10
+ *
11
+ * It is the same defect the Python docstrings had, in the languages where the marker
12
+ * usually is there and sometimes is not.
13
+ *
14
+ * Counting the delimiters is not enough, and measuring that was the point. A first
15
+ * pass said 135 citations across the corpus, and the second example it offered was
16
+ * live code: a glob like star-star-slash-star-dot-ts, and a slash-star inside a
17
+ * shader string, both look like an opening. So this walks the file properly —
18
+ * through single quotes, double quotes, template literals and line comments — and
19
+ * only then decides.
20
+ */
21
+ export declare function blockCommentLines(file: string, text: string): Set<number>;
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ /**
3
+ * The lines of a C-family file that sit inside a block comment.
4
+ *
5
+ * The comment rule reads one line at a time and looks for a marker at its start:
6
+ * a double slash, a slash-star, a lone star. A block comment written without a
7
+ * leading star on every line has no marker to find, and neither does code that
8
+ * somebody commented out by wrapping the whole thing. In AsteroidsJS a wrapped
9
+ * `localStorage.setItem('highScores', ...)` was cited as evidence that the game
10
+ * saves progress; the function it belongs to is switched off.
11
+ *
12
+ * It is the same defect the Python docstrings had, in the languages where the marker
13
+ * usually is there and sometimes is not.
14
+ *
15
+ * Counting the delimiters is not enough, and measuring that was the point. A first
16
+ * pass said 135 citations across the corpus, and the second example it offered was
17
+ * live code: a glob like star-star-slash-star-dot-ts, and a slash-star inside a
18
+ * shader string, both look like an opening. So this walks the file properly —
19
+ * through single quotes, double quotes, template literals and line comments — and
20
+ * only then decides.
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.blockCommentLines = blockCommentLines;
24
+ const C_FAMILY = /\.(ts|tsx|js|jsx|mjs|cjs|go|java|cs|rs|php|scala|kt|swift|c|cc|cpp|h)$/i;
25
+ function blockCommentLines(file, text) {
26
+ const inside = new Set();
27
+ if (!C_FAMILY.test(file))
28
+ return inside;
29
+ if (!text.includes('/*'))
30
+ return inside;
31
+ let line = 1;
32
+ let state = 'code';
33
+ let escaped = false;
34
+ for (let i = 0; i < text.length; i++) {
35
+ const character = text[i];
36
+ const next = text[i + 1];
37
+ if (character === '\n') {
38
+ line++;
39
+ if (state === 'line-comment')
40
+ state = 'code';
41
+ if (state === 'single' || state === 'double')
42
+ state = 'code';
43
+ if (state === 'block-comment')
44
+ inside.add(line);
45
+ escaped = false;
46
+ continue;
47
+ }
48
+ if (escaped) {
49
+ escaped = false;
50
+ continue;
51
+ }
52
+ switch (state) {
53
+ case 'code':
54
+ if (character === '/' && next === '/') {
55
+ state = 'line-comment';
56
+ i++;
57
+ }
58
+ else if (character === '/' && next === '*') {
59
+ state = 'block-comment';
60
+ i++;
61
+ }
62
+ else if (character === "'")
63
+ state = 'single';
64
+ else if (character === '"')
65
+ state = 'double';
66
+ else if (character === '`')
67
+ state = 'template';
68
+ break;
69
+ case 'block-comment':
70
+ if (character === '*' && next === '/') {
71
+ state = 'code';
72
+ i++;
73
+ }
74
+ break;
75
+ case 'single':
76
+ case 'double':
77
+ case 'template':
78
+ if (character === '\\')
79
+ escaped = true;
80
+ else if ((state === 'single' && character === "'")
81
+ || (state === 'double' && character === '"')
82
+ || (state === 'template' && character === '`')) {
83
+ state = 'code';
84
+ }
85
+ break;
86
+ default:
87
+ break;
88
+ }
89
+ }
90
+ return inside;
91
+ }
@@ -7,6 +7,7 @@ exports.anyIncludes = anyIncludes;
7
7
  const readTextFileSafe_1 = require("./readTextFileSafe");
8
8
  const developmentOnly_1 = require("../analyzer/developmentOnly");
9
9
  const proseLines_1 = require("../analyzer/proseLines");
10
+ const blockComments_1 = require("../analyzer/blockComments");
10
11
  /**
11
12
  * A line that declares a pattern rather than doing anything.
12
13
  *
@@ -106,9 +107,11 @@ function matchLines(text, needles, file = '') {
106
107
  const testOnly = (0, developmentOnly_1.testOnlyLines)(file, text);
107
108
  /** A Python docstring is prose with no line marker to recognise it by. */
108
109
  const prose = (0, proseLines_1.proseLines)(file, text);
110
+ /** Code somebody switched off by wrapping it, which has no marker on its lines. */
111
+ const commented = (0, blockComments_1.blockCommentLines)(file, text);
109
112
  for (let i = 0; i < lines.length; i++) {
110
113
  const line = lines[i];
111
- if (testOnly.has(i + 1) || prose.has(i + 1))
114
+ if (testOnly.has(i + 1) || prose.has(i + 1) || commented.has(i + 1))
112
115
  continue;
113
116
  if (line.length > MAX_CITABLE_LINE)
114
117
  continue;
@@ -139,9 +142,10 @@ async function searchInFiles(root, files, needles, limit = 25) {
139
142
  const lines = text.split(/\r?\n/);
140
143
  const testOnly = (0, developmentOnly_1.testOnlyLines)(file, text);
141
144
  const prose = (0, proseLines_1.proseLines)(file, text);
145
+ const commented = (0, blockComments_1.blockCommentLines)(file, text);
142
146
  for (let i = 0; i < lines.length; i++) {
143
147
  const line = lines[i];
144
- if (testOnly.has(i + 1) || prose.has(i + 1))
148
+ if (testOnly.has(i + 1) || prose.has(i + 1) || commented.has(i + 1))
145
149
  continue;
146
150
  if (line.length > MAX_CITABLE_LINE)
147
151
  continue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@produtype/core",
3
- "version": "0.69.0",
3
+ "version": "0.70.0",
4
4
  "description": "Deterministic CLI and library that analyzes a web application repository and reports how far it is from production-ready for the kind of product it is meant to be.",
5
5
  "license": "MIT",
6
6
  "bin": {