or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-api.mdindex.mdmodels.mdprogrammatic-api.mdreporters.mdutilities.md

reporters.mddocs/

0

# Analysis Reporters

1

2

Specialized analysis modules for different code quality metrics and linting integration. Reporters provide the core analysis functionality for complexity calculation, JSHint integration, and ESLint integration.

3

4

## Capabilities

5

6

### Complexity Reporter

7

8

Analyzes JavaScript source code to calculate complexity metrics including cyclomatic complexity, Halstead metrics, and maintainability indices.

9

10

```javascript { .api }

11

/**

12

* Analyze JavaScript source code complexity metrics

13

* @param {String} source - JavaScript source code to analyze

14

* @param {Object} options - Analysis options and configuration

15

* @param {Object} reportInfo - File information object for context

16

* @returns {Object} Complexity analysis report with detailed metrics

17

*/

18

function process(source, options, reportInfo);

19

```

20

21

**Parameters:**

22

23

- `source` (String): JavaScript source code to analyze

24

- `options` (Object): Analysis options and configuration

25

- `reportInfo` (Object): File information object containing file metadata

26

27

**Returns:** Object - Comprehensive complexity analysis report

28

29

**Report Structure:**

30

31

```javascript { .api }

32

interface ComplexityReport {

33

/** Cyclomatic complexity score */

34

cyclomatic: number;

35

36

/** Source lines of code metrics */

37

sloc: {

38

/** Physical lines of code (including comments and whitespace) */

39

physical: number;

40

/** Logical lines of code (executable statements) */

41

logical: number;

42

};

43

44

/** Halstead complexity metrics */

45

halstead: {

46

/** Operator analysis */

47

operators: {

48

distinct: number; // Number of unique operators

49

total: number; // Total operator count

50

identifiers: string[]; // List of operators found

51

};

52

/** Operand analysis */

53

operands: {

54

distinct: number; // Number of unique operands

55

total: number; // Total operand count

56

identifiers: string[]; // List of operands found

57

};

58

length: number; // Program length (N = N1 + N2)

59

vocabulary: number; // Program vocabulary (n = n1 + n2)

60

difficulty: number; // Programming difficulty

61

volume: number; // Program volume

62

effort: number; // Programming effort

63

bugs: number; // Estimated bugs

64

time: number; // Estimated programming time (seconds)

65

};

66

67

/** Maintainability index (0-100, higher is better) */

68

maintainability: number;

69

70

/** Function parameter count analysis */

71

params: number;

72

73

/** Additional complexity metrics */

74

// ... other complexity measurements

75

}

76

```

77

78

**Usage Examples:**

79

80

```javascript

81

const complexityReporter = require('plato/lib/reporters/complexity');

82

83

// Analyze source code

84

const sourceCode = `

85

function calculateSum(a, b, c) {

86

if (a > 0) {

87

return a + b + c;

88

} else {

89

return b + c;

90

}

91

}

92

`;

93

94

const reportInfo = {

95

file: 'calculator.js',

96

fileShort: 'calculator.js'

97

};

98

99

const complexityReport = complexityReporter.process(sourceCode, {}, reportInfo);

100

101

console.log('Cyclomatic Complexity:', complexityReport.cyclomatic);

102

console.log('Maintainability Index:', complexityReport.maintainability);

103

console.log('Physical SLOC:', complexityReport.sloc.physical);

104

console.log('Logical SLOC:', complexityReport.sloc.logical);

105

console.log('Halstead Volume:', complexityReport.halstead.volume);

106

```

107

108

### JSHint Reporter

109

110

Integrates JSHint linting analysis to identify potential issues and coding standard violations in JavaScript code.

111

112

```javascript { .api }

113

/**

114

* Run JSHint analysis on JavaScript source code

115

* @param {String} source - JavaScript source code to analyze

116

* @param {Object} options - JSHint configuration options

117

* @returns {Object} JSHint analysis report with messages and metadata

118

*/

119

function process(source, options);

120

```

121

122

**Parameters:**

123

124

- `source` (String): JavaScript source code to analyze

125

- `options` (Object): JSHint configuration options and rules

126

127

**Returns:** Object - JSHint analysis report

128

129

**Report Structure:**

130

131

```javascript { .api }

132

interface JSHintReport {

133

/** Array of JSHint messages */

134

messages: Array<{

135

/** Message severity level */

136

severity: 'error' | 'warning' | 'info';

137

/** Line number where issue occurs */

138

line: number;

139

/** Column number where issue occurs */

140

column: number;

141

/** Human-readable message describing the issue */

142

message: string;

143

/** Source code evidence showing the problematic line */

144

evidence: string;

145

/** JSHint rule identifier */

146

reason?: string;

147

/** Character position in source */

148

character?: number;

149

}>;

150

}

151

```

152

153

**Usage Examples:**

154

155

```javascript

156

const jshintReporter = require('plato/lib/reporters/jshint');

157

158

// Analyze with JSHint

159

const sourceCode = `

160

function badCode() {

161

var unused = 1;

162

undeclaredVar = 2;

163

return "missing semicolon"

164

}

165

`;

166

167

const jshintOptions = {

168

undef: true, // Require variable declarations

169

unused: true, // Warn about unused variables

170

asi: false // Require semicolons

171

};

172

173

const jshintReport = jshintReporter.process(sourceCode, jshintOptions);

174

175

jshintReport.messages.forEach(msg => {

176

console.log(`${msg.severity} at line ${msg.line}: ${msg.message}`);

177

console.log(`Evidence: ${msg.evidence}`);

178

});

179

180

// Example output:

181

// error at line 3: 'unused' is defined but never used.

182

// error at line 4: 'undeclaredVar' is not defined.

183

// error at line 5: Missing semicolon.

184

```

185

186

### ESLint Reporter

187

188

Integrates ESLint analysis for modern JavaScript linting with configurable rules and comprehensive error reporting.

189

190

```javascript { .api }

191

/**

192

* Run ESLint analysis on JavaScript source code

193

* @param {String} source - JavaScript source code to analyze

194

* @param {Object} options - ESLint configuration options and rules

195

* @returns {Object} ESLint analysis report with messages and metadata

196

*/

197

function process(source, options);

198

```

199

200

**Parameters:**

201

202

- `source` (String): JavaScript source code to analyze

203

- `options` (Object): ESLint configuration options, rules, and environment settings

204

205

**Returns:** Object - ESLint analysis report

206

207

**Report Structure:**

208

209

```javascript { .api }

210

interface ESLintReport {

211

/** Array of ESLint messages */

212

messages: Array<{

213

/** Message severity level */

214

severity: 'error' | 'warning';

215

/** Line number where issue occurs */

216

line: number;

217

/** Column number where issue occurs */

218

column: number;

219

/** Human-readable message describing the issue */

220

message: string;

221

/** ESLint rule identifier that triggered the message */

222

ruleId: string;

223

/** End line number for multi-line issues */

224

endLine?: number;

225

/** End column number for multi-line issues */

226

endColumn?: number;

227

/** Node type that triggered the rule */

228

nodeType?: string;

229

/** Source code excerpt */

230

source?: string;

231

}>;

232

}

233

```

234

235

**Usage Examples:**

236

237

```javascript

238

const eslintReporter = require('plato/lib/reporters/eslint');

239

240

// Analyze with ESLint

241

const sourceCode = `

242

const unusedVar = 1;

243

244

function inconsistentQuotes() {

245

console.log("double quotes");

246

console.log('single quotes');

247

return `template literal`;

248

}

249

250

if(true){

251

console.log("no spacing");

252

}

253

`;

254

255

const eslintOptions = {

256

env: {

257

es6: true,

258

node: true

259

},

260

rules: {

261

'no-unused-vars': 'error',

262

'quotes': ['error', 'single'],

263

'space-before-blocks': 'error',

264

'keyword-spacing': 'error'

265

}

266

};

267

268

const eslintReport = eslintReporter.process(sourceCode, eslintOptions);

269

270

eslintReport.messages.forEach(msg => {

271

console.log(`${msg.severity}: ${msg.message} (${msg.ruleId})`);

272

console.log(` at line ${msg.line}, column ${msg.column}`);

273

});

274

275

// Example output:

276

// error: 'unusedVar' is defined but never used. (no-unused-vars)

277

// at line 2, column 7

278

// error: Strings must use single quote. (quotes)

279

// at line 5, column 15

280

```

281

282

## Integration with Main Analysis

283

284

The reporters integrate seamlessly with Plato's main analysis workflow:

285

286

### Reporter Configuration

287

288

```javascript

289

const plato = require('plato');

290

291

// Configure analysis with multiple reporters

292

plato.inspect(['src/**/*.js'], 'reports', {

293

// JSHint configuration

294

jshint: {

295

node: true,

296

browser: true,

297

camelcase: true,

298

curly: true,

299

immed: true,

300

indent: 2,

301

latedef: true,

302

newcap: true,

303

nonew: true,

304

quotmark: 'single',

305

undef: true,

306

unused: true,

307

strict: true,

308

maxparams: 4,

309

maxdepth: 3,

310

maxcomplexity: 10

311

},

312

313

// ESLint configuration

314

eslint: {

315

env: {

316

node: true,

317

es6: true

318

},

319

extends: ['eslint:recommended'],

320

rules: {

321

'no-console': 'warn',

322

'no-unused-vars': 'error',

323

'quotes': ['error', 'single'],

324

'semi': ['error', 'always']

325

}

326

}

327

}, function(reports) {

328

reports.forEach(report => {

329

console.log(`\n--- ${report.info.file} ---`);

330

331

// Complexity metrics

332

console.log(`Complexity: ${report.complexity.cyclomatic}`);

333

console.log(`Maintainability: ${report.complexity.maintainability}`);

334

335

// JSHint results

336

if (report.jshint && report.jshint.messages.length > 0) {

337

console.log(`JSHint issues: ${report.jshint.messages.length}`);

338

}

339

340

// ESLint results

341

if (report.eslint && report.eslint.messages.length > 0) {

342

console.log(`ESLint issues: ${report.eslint.messages.length}`);

343

}

344

});

345

});

346

```

347

348

### Custom Reporter Integration

349

350

```javascript

351

// Example of using reporters independently

352

const complexityReporter = require('plato/lib/reporters/complexity');

353

const jshintReporter = require('plato/lib/reporters/jshint');

354

const eslintReporter = require('plato/lib/reporters/eslint');

355

const fs = require('fs');

356

357

function analyzeFile(filePath) {

358

const source = fs.readFileSync(filePath, 'utf8');

359

const reportInfo = { file: filePath };

360

361

// Run all analyses

362

const complexity = complexityReporter.process(source, {}, reportInfo);

363

const jshint = jshintReporter.process(source, { undef: true, unused: true });

364

const eslint = eslintReporter.process(source, {

365

rules: { 'no-unused-vars': 'error' }

366

});

367

368

return {

369

file: filePath,

370

complexity,

371

jshint,

372

eslint

373

};

374

}

375

376

// Analyze specific file

377

const analysis = analyzeFile('src/app.js');

378

console.log('Analysis complete:', analysis);

379

```

380

381

## Reporter Output Integration

382

383

Reporter outputs are combined into the final analysis reports:

384

385

### Combined Report Structure

386

387

```javascript

388

// Final report structure combining all reporters

389

const combinedReport = {

390

info: {

391

file: 'src/app.js',

392

fileShort: 'app.js',

393

// ... other file info

394

},

395

396

// From complexity reporter

397

complexity: {

398

cyclomatic: 8,

399

maintainability: 75.2,

400

sloc: { physical: 120, logical: 95 },

401

halstead: { /* ... */ }

402

},

403

404

// From JSHint reporter (if enabled)

405

jshint: {

406

messages: [

407

{ severity: 'error', line: 15, message: 'Undefined variable' }

408

]

409

},

410

411

// From ESLint reporter (if enabled)

412

eslint: {

413

messages: [

414

{ severity: 'warning', line: 20, ruleId: 'no-console', message: 'Unexpected console statement.' }

415

]

416

}

417

};

418

```

419

420

## Error Handling

421

422

Reporters handle various error scenarios gracefully:

423

424

### Source Code Parsing Errors

425

426

```javascript

427

// Reporters handle malformed JavaScript

428

const malformedCode = `

429

function broken() {

430

if (condition { // Missing closing parenthesis

431

return true;

432

}

433

`;

434

435

try {

436

const report = complexityReporter.process(malformedCode, {}, { file: 'broken.js' });

437

// Report may contain partial analysis or error information

438

} catch (error) {

439

console.error('Analysis failed:', error.message);

440

}

441

```

442

443

### Configuration Errors

444

445

```javascript

446

// Reporters validate configuration options

447

const invalidConfig = {

448

rules: {

449

'nonexistent-rule': 'error'

450

}

451

};

452

453

const report = eslintReporter.process(sourceCode, invalidConfig);

454

// Report will include configuration error messages

455

```

456

457

Each reporter is designed to provide useful information even when encountering errors, ensuring that the overall analysis process can continue and provide valuable insights about code quality.