or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

compiler-entry-points.mdconfiguration-system.mdhigh-level-api.mdincremental-compilation.mdindex.mdmessage-collection.mdplugin-system.md

message-collection.mddocs/

0

# Message Collection and Diagnostics

1

2

Comprehensive diagnostic collection system for compilation errors, warnings, and informational messages with customizable output formatting. The message collection system provides structured reporting of compilation diagnostics with precise source location information.

3

4

## Capabilities

5

6

### MessageCollector Interface

7

8

Core interface for collecting compilation diagnostics with severity levels and source location information.

9

10

```kotlin { .api }

11

/**

12

* Core interface for collecting compilation diagnostic messages

13

* Implementations handle display, storage, or processing of compiler messages

14

*/

15

interface MessageCollector {

16

/** Report a diagnostic message with severity and optional location */

17

fun report(

18

severity: CompilerMessageSeverity,

19

message: String,

20

location: CompilerMessageSourceLocation? = null

21

): Unit

22

23

/** Check if any error messages have been reported */

24

fun hasErrors(): Boolean

25

26

/** Clear all collected messages */

27

fun clear(): Unit

28

}

29

```

30

31

**Usage Examples:**

32

33

```kotlin

34

// Custom message collector implementation

35

class CustomMessageCollector : MessageCollector {

36

private val messages = mutableListOf<CompilerMessage>()

37

private var hasErrorsFlag = false

38

39

override fun report(

40

severity: CompilerMessageSeverity,

41

message: String,

42

location: CompilerMessageSourceLocation?

43

) {

44

messages.add(CompilerMessage(severity, message, location))

45

if (severity == CompilerMessageSeverity.ERROR) {

46

hasErrorsFlag = true

47

}

48

49

// Custom handling

50

when (severity) {

51

CompilerMessageSeverity.ERROR -> logger.error(message)

52

CompilerMessageSeverity.WARNING -> logger.warn(message)

53

else -> logger.info(message)

54

}

55

}

56

57

override fun hasErrors(): Boolean = hasErrorsFlag

58

override fun clear() {

59

messages.clear()

60

hasErrorsFlag = false

61

}

62

}

63

64

// Using with compiler

65

val messageCollector = CustomMessageCollector()

66

val compiler = K2JVMCompiler()

67

val exitCode = compiler.exec(messageCollector, Services.EMPTY, arguments)

68

69

if (messageCollector.hasErrors()) {

70

println("Compilation failed with errors")

71

}

72

```

73

74

### CompilerMessageSeverity

75

76

Enumeration of message severity levels for categorizing diagnostic messages.

77

78

```kotlin { .api }

79

/**

80

* Message severity levels for compilation diagnostics

81

* Ordered from most severe (ERROR) to least severe (OUTPUT)

82

*/

83

enum class CompilerMessageSeverity {

84

/** Fatal compilation error - prevents successful compilation */

85

ERROR,

86

87

/** Strong warning - significant issue but compilation can continue */

88

STRONG_WARNING,

89

90

/** Standard warning - potential issue worth noting */

91

WARNING,

92

93

/** Informational message */

94

INFO,

95

96

/** Verbose logging information */

97

LOGGING,

98

99

/** Compiler output information */

100

OUTPUT;

101

102

companion object {

103

/** Verbose logging level for detailed output */

104

val VERBOSE: CompilerMessageSeverity = LOGGING

105

}

106

}

107

```

108

109

### CompilerMessageSourceLocation

110

111

Source location information for precise error reporting and IDE integration.

112

113

```kotlin { .api }

114

/**

115

* Source location information for diagnostic messages

116

* Provides precise file, line, and column information

117

*/

118

data class CompilerMessageSourceLocation(

119

/** File path where the diagnostic occurred */

120

val path: String,

121

122

/** Line number (1-based) */

123

val line: Int,

124

125

/** Column number (1-based) */

126

val column: Int,

127

128

/** Source line content for context (optional) */

129

val lineContent: String? = null

130

) {

131

/** Create location with line content for better error reporting */

132

constructor(

133

path: String,

134

line: Int,

135

column: Int,

136

lineContent: String

137

) : this(path, line, column, lineContent)

138

139

override fun toString(): String = "$path:$line:$column"

140

}

141

```

142

143

### Built-in Message Collectors

144

145

Pre-built message collector implementations for common use cases.

146

147

```kotlin { .api }

148

/**

149

* Message collector that prints messages to a PrintStream

150

* Supports different output formats and verbosity levels

151

*/

152

class PrintingMessageCollector(

153

/** Stream to write messages to */

154

val stream: PrintStream,

155

156

/** Message renderer for formatting output */

157

val messageRenderer: MessageRenderer,

158

159

/** Whether to print verbose messages */

160

val verbose: Boolean

161

) : MessageCollector {

162

163

override fun report(

164

severity: CompilerMessageSeverity,

165

message: String,

166

location: CompilerMessageSourceLocation?

167

): Unit

168

169

override fun hasErrors(): Boolean

170

override fun clear(): Unit

171

}

172

173

/**

174

* Message collector that groups messages by severity

175

* Useful for batch processing of diagnostics

176

*/

177

class GroupingMessageCollector(

178

/** Delegate message collector */

179

private val delegate: MessageCollector,

180

181

/** Treat warnings as errors */

182

private val treatWarningsAsErrors: Boolean,

183

184

/** Report all warnings */

185

private val reportAllWarnings: Boolean

186

) : MessageCollector {

187

188

/** Get all messages grouped by severity */

189

fun getGroupedMessages(): Map<CompilerMessageSeverity, List<String>>

190

191

override fun report(

192

severity: CompilerMessageSeverity,

193

message: String,

194

location: CompilerMessageSourceLocation?

195

): Unit

196

197

override fun hasErrors(): Boolean

198

override fun clear(): Unit

199

}

200

201

/**

202

* Message collector that filters messages based on severity

203

* Useful for controlling output verbosity

204

*/

205

class FilteringMessageCollector(

206

/** Delegate message collector */

207

private val delegate: MessageCollector,

208

209

/** Minimum severity to report */

210

private val minSeverity: CompilerMessageSeverity

211

) : MessageCollector {

212

213

override fun report(

214

severity: CompilerMessageSeverity,

215

message: String,

216

location: CompilerMessageSourceLocation?

217

): Unit

218

219

override fun hasErrors(): Boolean

220

override fun clear(): Unit

221

}

222

```

223

224

### Message Rendering

225

226

Different output formats for diagnostic messages.

227

228

```kotlin { .api }

229

/**

230

* Message rendering formats for different output contexts

231

*/

232

enum class MessageRenderer {

233

/** Plain text format suitable for console output */

234

PLAIN,

235

236

/** Plain text with full file paths */

237

PLAIN_FULL_PATHS,

238

239

/** XML format suitable for IDE integration */

240

XML,

241

242

/** JSON format for structured processing */

243

JSON;

244

245

/** Render a diagnostic message with the specified format */

246

fun render(

247

severity: CompilerMessageSeverity,

248

message: String,

249

location: CompilerMessageSourceLocation?

250

): String

251

}

252

```

253

254

**Advanced Usage Examples:**

255

256

```kotlin

257

// Hierarchical message collection with filtering

258

val baseCollector = PrintingMessageCollector(

259

System.err,

260

MessageRenderer.PLAIN_FULL_PATHS,

261

verbose = false

262

)

263

264

val groupingCollector = GroupingMessageCollector(

265

baseCollector,

266

treatWarningsAsErrors = false,

267

reportAllWarnings = true

268

)

269

270

val filteringCollector = FilteringMessageCollector(

271

groupingCollector,

272

minSeverity = CompilerMessageSeverity.WARNING

273

)

274

275

// Use with compilation

276

val compiler = K2JVMCompiler()

277

val exitCode = compiler.exec(filteringCollector, Services.EMPTY, arguments)

278

279

// Analyze results

280

val groupedMessages = groupingCollector.getGroupedMessages()

281

val errors = groupedMessages[CompilerMessageSeverity.ERROR] ?: emptyList()

282

val warnings = groupedMessages[CompilerMessageSeverity.WARNING] ?: emptyList()

283

284

println("Compilation completed with ${errors.size} errors, ${warnings.size} warnings")

285

286

// XML output for IDE integration

287

val xmlCollector = PrintingMessageCollector(

288

System.out,

289

MessageRenderer.XML,

290

verbose = true

291

)

292

293

// JSON output for tooling

294

val jsonCollector = PrintingMessageCollector(

295

FileOutputStream("compilation-results.json"),

296

MessageRenderer.JSON,

297

verbose = true

298

)

299

```

300

301

### Message Utilities

302

303

Utility functions for working with compiler messages.

304

305

```kotlin { .api }

306

/**

307

* Utilities for message processing and formatting

308

*/

309

object MessageUtil {

310

/** Format a location for display */

311

fun formatLocation(location: CompilerMessageSourceLocation): String

312

313

/** Extract file path from location */

314

fun getPath(location: CompilerMessageSourceLocation): String

315

316

/** Create location from PSI element */

317

fun psiElementToMessageLocation(element: PsiElement): CompilerMessageSourceLocation?

318

319

/** Render exception as compiler message */

320

fun renderException(exception: Throwable): String

321

}

322

323

/**

324

* Output message utilities for structured output

325

*/

326

object OutputMessageUtil {

327

/** Format output message for display */

328

fun formatOutputMessage(message: String): String

329

330

/** Format compilation statistics */

331

fun formatCompilationStats(

332

duration: Long,

333

filesCompiled: Int,

334

errorsCount: Int,

335

warningsCount: Int

336

): String

337

}

338

```

339

340

## Integration Examples

341

342

```kotlin

343

// Complete message collection setup for build tools

344

class BuildToolMessageCollector(

345

private val buildLogger: Logger,

346

private val failOnWarnings: Boolean = false

347

) : MessageCollector {

348

349

private var errorCount = 0

350

private var warningCount = 0

351

352

override fun report(

353

severity: CompilerMessageSeverity,

354

message: String,

355

location: CompilerMessageSourceLocation?

356

) {

357

val locationStr = location?.let { " at $it" } ?: ""

358

val fullMessage = "$message$locationStr"

359

360

when (severity) {

361

CompilerMessageSeverity.ERROR -> {

362

errorCount++

363

buildLogger.error(fullMessage)

364

}

365

CompilerMessageSeverity.STRONG_WARNING,

366

CompilerMessageSeverity.WARNING -> {

367

warningCount++

368

if (failOnWarnings) {

369

buildLogger.error("Warning treated as error: $fullMessage")

370

errorCount++

371

} else {

372

buildLogger.warn(fullMessage)

373

}

374

}

375

CompilerMessageSeverity.INFO -> buildLogger.info(fullMessage)

376

CompilerMessageSeverity.LOGGING,

377

CompilerMessageSeverity.OUTPUT -> buildLogger.debug(fullMessage)

378

}

379

}

380

381

override fun hasErrors(): Boolean = errorCount > 0

382

383

fun getErrorCount(): Int = errorCount

384

fun getWarningCount(): Int = warningCount

385

386

override fun clear() {

387

errorCount = 0

388

warningCount = 0

389

}

390

}

391

392

// IDE integration with source navigation

393

class IDEMessageCollector(

394

private val project: Project,

395

private val problemsHolder: ProblemsHolder

396

) : MessageCollector {

397

398

override fun report(

399

severity: CompilerMessageSeverity,

400

message: String,

401

location: CompilerMessageSourceLocation?

402

) {

403

location?.let { loc ->

404

val virtualFile = VirtualFileManager.getInstance()

405

.findFileByUrl("file://${loc.path}")

406

407

if (virtualFile != null) {

408

val psiFile = PsiManager.getInstance(project).findFile(virtualFile)

409

psiFile?.let { file ->

410

val element = file.findElementAt(loc.line, loc.column)

411

element?.let {

412

when (severity) {

413

CompilerMessageSeverity.ERROR ->

414

problemsHolder.registerProblem(it, message, ProblemHighlightType.ERROR)

415

CompilerMessageSeverity.WARNING,

416

CompilerMessageSeverity.STRONG_WARNING ->

417

problemsHolder.registerProblem(it, message, ProblemHighlightType.WARNING)

418

else -> Unit

419

}

420

}

421

}

422

}

423

}

424

}

425

426

override fun hasErrors(): Boolean = problemsHolder.hasErrors()

427

override fun clear(): Unit = problemsHolder.clear()

428

}

429

```