Skip to content

Commit 7efbd88

Browse files
authored
Merge pull request github#13526 from igfoo/igfoo/diagwriter
Kotlin: Define DiagnosticTrapWriter, for type safety
2 parents 9ab7a83 + bfd0a19 commit 7efbd88

File tree

5 files changed

+82
-47
lines changed

5 files changed

+82
-47
lines changed

java/kotlin-extractor/src/main/kotlin/ExternalDeclExtractor.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import java.util.ArrayList
1414
import java.util.HashSet
1515
import java.util.zip.GZIPOutputStream
1616

17-
class ExternalDeclExtractor(val logger: FileLogger, val invocationTrapFile: String, val sourceFilePath: String, val primitiveTypeMapping: PrimitiveTypeMapping, val pluginContext: IrPluginContext, val globalExtensionState: KotlinExtractorGlobalState, val diagnosticTrapWriter: TrapWriter) {
17+
class ExternalDeclExtractor(val logger: FileLogger, val invocationTrapFile: String, val sourceFilePath: String, val primitiveTypeMapping: PrimitiveTypeMapping, val pluginContext: IrPluginContext, val globalExtensionState: KotlinExtractorGlobalState, val diagnosticTrapWriter: DiagnosticTrapWriter) {
1818

1919
val declBinaryNames = HashMap<IrDeclaration, String>()
2020
val externalDeclsDone = HashSet<Pair<String, String>>()
@@ -95,8 +95,8 @@ class ExternalDeclExtractor(val logger: FileLogger, val invocationTrapFile: Stri
9595
val binaryPath = getIrClassBinaryPath(containingClass)
9696

9797
// We want our comments to be the first thing in the file,
98-
// so start off with a mere TrapWriter
99-
val tw = TrapWriter(logger.loggerBase, TrapLabelManager(), trapFileBW, diagnosticTrapWriter)
98+
// so start off with a PlainTrapWriter
99+
val tw = PlainTrapWriter(logger.loggerBase, TrapLabelManager(), trapFileBW, diagnosticTrapWriter)
100100
tw.writeComment("Generated by the CodeQL Kotlin extractor for external dependencies")
101101
tw.writeComment("Part of invocation $invocationTrapFile")
102102
if (signature != possiblyLongSignature) {

java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ class KotlinExtractorExtension(
127127
val lm = TrapLabelManager()
128128
val logCounter = LogCounter()
129129
val loggerBase = LoggerBase(logCounter)
130-
val tw = TrapWriter(loggerBase, lm, invocationTrapFileBW, null)
130+
val tw = DiagnosticTrapWriter(loggerBase, lm, invocationTrapFileBW)
131131
// The interceptor has already defined #compilation = *
132132
val compilation: Label<DbCompilation> = StringLabel("compilation")
133133
tw.writeCompilation_started(compilation)
@@ -324,13 +324,13 @@ private fun doFile(
324324
trapFileWriter.getTempWriter().use { trapFileBW ->
325325
// We want our comments to be the first thing in the file,
326326
// so start off with a mere TrapWriter
327-
val tw = TrapWriter(loggerBase, TrapLabelManager(), trapFileBW, fileTrapWriter)
327+
val tw = PlainTrapWriter(loggerBase, TrapLabelManager(), trapFileBW, fileTrapWriter.getDiagnosticTrapWriter())
328328
tw.writeComment("Generated by the CodeQL Kotlin extractor for kotlin source code")
329329
tw.writeComment("Part of invocation $invocationTrapFile")
330330
// Now elevate to a SourceFileTrapWriter, and populate the
331331
// file information
332332
val sftw = tw.makeSourceFileTrapWriter(srcFile, true)
333-
val externalDeclExtractor = ExternalDeclExtractor(logger, invocationTrapFile, srcFilePath, primitiveTypeMapping, pluginContext, globalExtensionState, fileTrapWriter)
333+
val externalDeclExtractor = ExternalDeclExtractor(logger, invocationTrapFile, srcFilePath, primitiveTypeMapping, pluginContext, globalExtensionState, fileTrapWriter.getDiagnosticTrapWriter())
334334
val linesOfCode = LinesOfCode(logger, sftw, srcFile)
335335
val fileExtractor = KotlinFileExtractor(logger, sftw, linesOfCode, srcFilePath, null, externalDeclExtractor, primitiveTypeMapping, pluginContext, KotlinFileExtractor.DeclarationStack(), globalExtensionState)
336336

java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,13 @@ open class KotlinUsesExtractor(
139139
if (clsFile == null || isExternalDeclaration(cls)) {
140140
val filePath = getIrClassBinaryPath(cls)
141141
val newTrapWriter = tw.makeFileTrapWriter(filePath, true)
142-
val newLoggerTrapWriter = logger.tw.makeFileTrapWriter(filePath, false)
142+
val newLoggerTrapWriter = logger.dtw.makeFileTrapWriter(filePath, false)
143143
val newLogger = FileLogger(logger.loggerBase, newLoggerTrapWriter)
144144
return KotlinFileExtractor(newLogger, newTrapWriter, null, filePath, dependencyCollector, externalClassExtractor, primitiveTypeMapping, pluginContext, newDeclarationStack, globalExtensionState)
145145
}
146146

147147
val newTrapWriter = tw.makeSourceFileTrapWriter(clsFile, true)
148-
val newLoggerTrapWriter = logger.tw.makeSourceFileTrapWriter(clsFile, false)
148+
val newLoggerTrapWriter = logger.dtw.makeSourceFileTrapWriter(clsFile, false)
149149
val newLogger = FileLogger(logger.loggerBase, newLoggerTrapWriter)
150150
return KotlinFileExtractor(newLogger, newTrapWriter, null, clsFile.path, dependencyCollector, externalClassExtractor, primitiveTypeMapping, pluginContext, newDeclarationStack, globalExtensionState)
151151
}

java/kotlin-extractor/src/main/kotlin/TrapWriter.kt

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ class TrapLabelManager {
5757
* share the same `TrapLabelManager` and `BufferedWriter`.
5858
*/
5959
// TODO lm was `protected` before anonymousTypeMapping and locallyVisibleFunctionLabelMapping moved into it. Should we re-protect it and provide accessors?
60-
open class TrapWriter (protected val loggerBase: LoggerBase, val lm: TrapLabelManager, private val bw: BufferedWriter, val diagnosticTrapWriter: TrapWriter?) {
60+
abstract class TrapWriter (protected val loggerBase: LoggerBase, val lm: TrapLabelManager, private val bw: BufferedWriter) {
61+
abstract fun getDiagnosticTrapWriter(): DiagnosticTrapWriter
62+
6163
/**
6264
* Returns the label that is defined to be the given key, if such
6365
* a label exists, and `null` otherwise. Most users will want to use
@@ -223,7 +225,7 @@ open class TrapWriter (protected val loggerBase: LoggerBase, val lm: TrapLabelMa
223225
val len = str.length
224226
val newLen = UTF8Util.encodablePrefixLength(str, MAX_STRLEN)
225227
if (newLen < len) {
226-
loggerBase.warn(diagnosticTrapWriter ?: this,
228+
loggerBase.warn(this.getDiagnosticTrapWriter(),
227229
"Truncated string of length $len",
228230
"Truncated string of length $len, starting '${str.take(100)}', ending '${str.takeLast(100)}'")
229231
return str.take(newLen)
@@ -237,14 +239,43 @@ open class TrapWriter (protected val loggerBase: LoggerBase, val lm: TrapLabelMa
237239
* writer etc), but using the given `filePath` for locations.
238240
*/
239241
fun makeFileTrapWriter(filePath: String, populateFileTables: Boolean) =
240-
FileTrapWriter(loggerBase, lm, bw, diagnosticTrapWriter, filePath, populateFileTables)
242+
FileTrapWriter(loggerBase, lm, bw, this.getDiagnosticTrapWriter(), filePath, populateFileTables)
241243

242244
/**
243245
* Gets a FileTrapWriter like this one (using the same label manager,
244246
* writer etc), but using the given `IrFile` for locations.
245247
*/
246248
fun makeSourceFileTrapWriter(file: IrFile, populateFileTables: Boolean) =
247-
SourceFileTrapWriter(loggerBase, lm, bw, diagnosticTrapWriter, file, populateFileTables)
249+
SourceFileTrapWriter(loggerBase, lm, bw, this.getDiagnosticTrapWriter(), file, populateFileTables)
250+
}
251+
252+
/**
253+
* A `PlainTrapWriter` has no additional context of its own.
254+
*/
255+
class PlainTrapWriter (
256+
loggerBase: LoggerBase,
257+
lm: TrapLabelManager,
258+
bw: BufferedWriter,
259+
val dtw: DiagnosticTrapWriter
260+
): TrapWriter (loggerBase, lm, bw) {
261+
override fun getDiagnosticTrapWriter(): DiagnosticTrapWriter {
262+
return dtw
263+
}
264+
}
265+
266+
/**
267+
* A `DiagnosticTrapWriter` is a TrapWriter that diagnostics can be
268+
* written to; i.e. it has the #compilation label defined. In practice,
269+
* this means that it is a TrapWriter for the invocation TRAP file.
270+
*/
271+
class DiagnosticTrapWriter (
272+
loggerBase: LoggerBase,
273+
lm: TrapLabelManager,
274+
bw: BufferedWriter
275+
): TrapWriter (loggerBase, lm, bw) {
276+
override fun getDiagnosticTrapWriter(): DiagnosticTrapWriter {
277+
return this
278+
}
248279
}
249280

250281
/**
@@ -259,16 +290,20 @@ open class FileTrapWriter (
259290
loggerBase: LoggerBase,
260291
lm: TrapLabelManager,
261292
bw: BufferedWriter,
262-
diagnosticTrapWriter: TrapWriter?,
293+
val dtw: DiagnosticTrapWriter,
263294
val filePath: String,
264295
populateFileTables: Boolean
265-
): TrapWriter (loggerBase, lm, bw, diagnosticTrapWriter) {
296+
): TrapWriter (loggerBase, lm, bw) {
266297

267298
/**
268299
* The ID for the file that we are extracting from.
269300
*/
270301
val fileId = mkFileId(filePath, populateFileTables)
271302

303+
override fun getDiagnosticTrapWriter(): DiagnosticTrapWriter {
304+
return dtw
305+
}
306+
272307
private fun offsetMinOf(default: Int, vararg options: Int?): Int {
273308
if (default == UNDEFINED_OFFSET || default == SYNTHETIC_OFFSET) {
274309
return default
@@ -349,10 +384,10 @@ class SourceFileTrapWriter (
349384
loggerBase: LoggerBase,
350385
lm: TrapLabelManager,
351386
bw: BufferedWriter,
352-
diagnosticTrapWriter: TrapWriter?,
387+
dtw: DiagnosticTrapWriter,
353388
val irFile: IrFile,
354389
populateFileTables: Boolean) :
355-
FileTrapWriter(loggerBase, lm, bw, diagnosticTrapWriter, irFile.path, populateFileTables) {
390+
FileTrapWriter(loggerBase, lm, bw, dtw, irFile.path, populateFileTables) {
356391

357392
/**
358393
* The file entry for the file that we are extracting from.
@@ -363,14 +398,14 @@ class SourceFileTrapWriter (
363398
override fun getLocation(startOffset: Int, endOffset: Int): Label<DbLocation> {
364399
if (startOffset == UNDEFINED_OFFSET || endOffset == UNDEFINED_OFFSET) {
365400
if (startOffset != endOffset) {
366-
loggerBase.warn(this, "Location with inconsistent offsets (start $startOffset, end $endOffset)", null)
401+
loggerBase.warn(dtw, "Location with inconsistent offsets (start $startOffset, end $endOffset)", null)
367402
}
368403
return getWholeFileLocation()
369404
}
370405

371406
if (startOffset == SYNTHETIC_OFFSET || endOffset == SYNTHETIC_OFFSET) {
372407
if (startOffset != endOffset) {
373-
loggerBase.warn(this, "Location with inconsistent offsets (start $startOffset, end $endOffset)", null)
408+
loggerBase.warn(dtw, "Location with inconsistent offsets (start $startOffset, end $endOffset)", null)
374409
}
375410
return getWholeFileLocation()
376411
}
@@ -390,14 +425,14 @@ class SourceFileTrapWriter (
390425
override fun getLocationString(e: IrElement): String {
391426
if (e.startOffset == UNDEFINED_OFFSET || e.endOffset == UNDEFINED_OFFSET) {
392427
if (e.startOffset != e.endOffset) {
393-
loggerBase.warn(this, "Location with inconsistent offsets (start ${e.startOffset}, end ${e.endOffset})", null)
428+
loggerBase.warn(dtw, "Location with inconsistent offsets (start ${e.startOffset}, end ${e.endOffset})", null)
394429
}
395430
return "<unknown location while processing $filePath>"
396431
}
397432

398433
if (e.startOffset == SYNTHETIC_OFFSET || e.endOffset == SYNTHETIC_OFFSET) {
399434
if (e.startOffset != e.endOffset) {
400-
loggerBase.warn(this, "Location with inconsistent offsets (start ${e.startOffset}, end ${e.endOffset})", null)
435+
loggerBase.warn(dtw, "Location with inconsistent offsets (start ${e.startOffset}, end ${e.endOffset})", null)
401436
}
402437
return "<synthetic location while processing $filePath>"
403438
}

java/kotlin-extractor/src/main/kotlin/utils/Logger.kt

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ open class LoggerBase(val logCounter: LogCounter) {
107107
file_number_diagnostic_number = 0
108108
}
109109

110-
fun diagnostic(tw: TrapWriter, severity: Severity, msg: String, extraInfo: String?, locationString: String? = null, mkLocationId: () -> Label<DbLocation> = { tw.unknownLocation }) {
110+
fun diagnostic(dtw: DiagnosticTrapWriter, severity: Severity, msg: String, extraInfo: String?, locationString: String? = null, mkLocationId: () -> Label<DbLocation> = { dtw.unknownLocation }) {
111111
val diagnosticLoc = getDiagnosticLocation()
112112
val diagnosticLocStr = if(diagnosticLoc == null) "<unknown location>" else diagnosticLoc
113113
val suffix =
@@ -121,7 +121,7 @@ open class LoggerBase(val logCounter: LogCounter) {
121121
// counting machinery
122122
if (verbosity >= 1) {
123123
val message = "Severity mismatch ($severity vs ${oldInfo.first}) at $diagnosticLoc"
124-
emitDiagnostic(tw, Severity.Error, "Inconsistency", message, message)
124+
emitDiagnostic(dtw, Severity.Error, "Inconsistency", message, message)
125125
}
126126
}
127127
val newCount = oldInfo.second + 1
@@ -149,18 +149,18 @@ open class LoggerBase(val logCounter: LogCounter) {
149149
fullMsgBuilder.append(suffix)
150150

151151
val fullMsg = fullMsgBuilder.toString()
152-
emitDiagnostic(tw, severity, diagnosticLocStr, msg, fullMsg, locationString, mkLocationId)
152+
emitDiagnostic(dtw, severity, diagnosticLocStr, msg, fullMsg, locationString, mkLocationId)
153153
}
154154

155-
private fun emitDiagnostic(tw: TrapWriter, severity: Severity, diagnosticLocStr: String, msg: String, fullMsg: String, locationString: String? = null, mkLocationId: () -> Label<DbLocation> = { tw.unknownLocation }) {
155+
private fun emitDiagnostic(dtw: DiagnosticTrapWriter, severity: Severity, diagnosticLocStr: String, msg: String, fullMsg: String, locationString: String? = null, mkLocationId: () -> Label<DbLocation> = { dtw.unknownLocation }) {
156156
val locStr = if (locationString == null) "" else "At " + locationString + ": "
157157
val kind = if (severity <= Severity.WarnHigh) "WARN" else "ERROR"
158158
val logMessage = LogMessage(kind, "Diagnostic($diagnosticLocStr): $locStr$fullMsg")
159159
// We don't actually make the location until after the `return` above
160160
val locationId = mkLocationId()
161-
val diagLabel = tw.getFreshIdLabel<DbDiagnostic>()
162-
tw.writeDiagnostics(diagLabel, "CodeQL Kotlin extractor", severity.sev, "", msg, "${logMessage.timestamp} $fullMsg", locationId)
163-
tw.writeDiagnostic_for(diagLabel, StringLabel("compilation"), file_number, file_number_diagnostic_number++)
161+
val diagLabel = dtw.getFreshIdLabel<DbDiagnostic>()
162+
dtw.writeDiagnostics(diagLabel, "CodeQL Kotlin extractor", severity.sev, "", msg, "${logMessage.timestamp} $fullMsg", locationId)
163+
dtw.writeDiagnostic_for(diagLabel, StringLabel("compilation"), file_number, file_number_diagnostic_number++)
164164
logStream.write(logMessage.toJsonLine())
165165
}
166166

@@ -188,18 +188,18 @@ open class LoggerBase(val logCounter: LogCounter) {
188188
}
189189
}
190190

191-
fun warn(tw: TrapWriter, msg: String, extraInfo: String?) {
191+
fun warn(dtw: DiagnosticTrapWriter, msg: String, extraInfo: String?) {
192192
if (verbosity >= 2) {
193-
diagnostic(tw, Severity.Warn, msg, extraInfo)
193+
diagnostic(dtw, Severity.Warn, msg, extraInfo)
194194
}
195195
}
196-
fun error(tw: TrapWriter, msg: String, extraInfo: String?) {
196+
fun error(dtw: DiagnosticTrapWriter, msg: String, extraInfo: String?) {
197197
if (verbosity >= 1) {
198-
diagnostic(tw, Severity.Error, msg, extraInfo)
198+
diagnostic(dtw, Severity.Error, msg, extraInfo)
199199
}
200200
}
201201

202-
fun printLimitedDiagnosticCounts(tw: TrapWriter) {
202+
fun printLimitedDiagnosticCounts(dtw: DiagnosticTrapWriter) {
203203
for((caller, info) in logCounter.diagnosticInfo) {
204204
val severity = info.first
205205
val count = info.second
@@ -209,7 +209,7 @@ open class LoggerBase(val logCounter: LogCounter) {
209209
// to be an error regardless.
210210
val message = "Total of $count diagnostics (reached limit of ${logCounter.diagnosticLimit}) from $caller."
211211
if (verbosity >= 1) {
212-
emitDiagnostic(tw, severity, "Limit", message, message)
212+
emitDiagnostic(dtw, severity, "Limit", message, message)
213213
}
214214
}
215215
}
@@ -224,28 +224,28 @@ open class LoggerBase(val logCounter: LogCounter) {
224224
}
225225
}
226226

227-
open class Logger(val loggerBase: LoggerBase, open val tw: TrapWriter) {
227+
open class Logger(val loggerBase: LoggerBase, open val dtw: DiagnosticTrapWriter) {
228228
fun flush() {
229-
tw.flush()
229+
dtw.flush()
230230
loggerBase.flush()
231231
}
232232

233233
fun trace(msg: String) {
234-
loggerBase.trace(tw, msg)
234+
loggerBase.trace(dtw, msg)
235235
}
236236
fun trace(msg: String, exn: Throwable) {
237237
trace(msg + "\n" + exn.stackTraceToString())
238238
}
239239
fun debug(msg: String) {
240-
loggerBase.debug(tw, msg)
240+
loggerBase.debug(dtw, msg)
241241
}
242242

243243
fun info(msg: String) {
244-
loggerBase.info(tw, msg)
244+
loggerBase.info(dtw, msg)
245245
}
246246

247247
private fun warn(msg: String, extraInfo: String?) {
248-
loggerBase.warn(tw, msg, extraInfo)
248+
loggerBase.warn(dtw, msg, extraInfo)
249249
}
250250
fun warn(msg: String, exn: Throwable) {
251251
warn(msg, exn.stackTraceToString())
@@ -255,7 +255,7 @@ open class Logger(val loggerBase: LoggerBase, open val tw: TrapWriter) {
255255
}
256256

257257
private fun error(msg: String, extraInfo: String?) {
258-
loggerBase.error(tw, msg, extraInfo)
258+
loggerBase.error(dtw, msg, extraInfo)
259259
}
260260
fun error(msg: String) {
261261
error(msg, null)
@@ -265,16 +265,16 @@ open class Logger(val loggerBase: LoggerBase, open val tw: TrapWriter) {
265265
}
266266
}
267267

268-
class FileLogger(loggerBase: LoggerBase, override val tw: FileTrapWriter): Logger(loggerBase, tw) {
268+
class FileLogger(loggerBase: LoggerBase, val ftw: FileTrapWriter): Logger(loggerBase, ftw.getDiagnosticTrapWriter()) {
269269
fun warnElement(msg: String, element: IrElement, exn: Throwable? = null) {
270-
val locationString = tw.getLocationString(element)
271-
val mkLocationId = { tw.getLocation(element) }
272-
loggerBase.diagnostic(tw, Severity.Warn, msg, exn?.stackTraceToString(), locationString, mkLocationId)
270+
val locationString = ftw.getLocationString(element)
271+
val mkLocationId = { ftw.getLocation(element) }
272+
loggerBase.diagnostic(ftw.getDiagnosticTrapWriter(), Severity.Warn, msg, exn?.stackTraceToString(), locationString, mkLocationId)
273273
}
274274

275275
fun errorElement(msg: String, element: IrElement, exn: Throwable? = null) {
276-
val locationString = tw.getLocationString(element)
277-
val mkLocationId = { tw.getLocation(element) }
278-
loggerBase.diagnostic(tw, Severity.Error, msg, exn?.stackTraceToString(), locationString, mkLocationId)
276+
val locationString = ftw.getLocationString(element)
277+
val mkLocationId = { ftw.getLocation(element) }
278+
loggerBase.diagnostic(ftw.getDiagnosticTrapWriter(), Severity.Error, msg, exn?.stackTraceToString(), locationString, mkLocationId)
279279
}
280280
}

0 commit comments

Comments
 (0)