1 /* 2 * Copyright 2020 Google LLC 3 * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package com.google.devtools.ksp.processing.impl 19 20 import com.google.devtools.ksp.processing.KSPLogger 21 import com.google.devtools.ksp.symbol.FileLocation 22 import com.google.devtools.ksp.symbol.KSNode 23 import com.google.devtools.ksp.symbol.NonExistLocation 24 import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity 25 import org.jetbrains.kotlin.cli.common.messages.MessageCollector 26 import java.io.PrintWriter 27 import java.io.StringWriter 28 29 class MessageCollectorBasedKSPLogger( 30 private val messageCollector: MessageCollector, 31 private val wrappedMessageCollector: MessageCollector, 32 private val allWarningsAsErrors: Boolean 33 ) : KSPLogger { 34 35 companion object { 36 const val PREFIX = "[ksp] " 37 } 38 39 data class Event(val severity: CompilerMessageSeverity, val message: String) 40 41 val recordedEvents = mutableListOf<Event>() 42 43 private val reportToCompilerSeverity = setOf(CompilerMessageSeverity.ERROR, CompilerMessageSeverity.EXCEPTION) 44 45 private var reportedToCompiler = false 46 convertMessagenull47 private fun convertMessage(message: String, symbol: KSNode?): String = 48 when (val location = symbol?.location) { 49 is FileLocation -> "$PREFIX${location.filePath}:${location.lineNumber}: $message" 50 is NonExistLocation, null -> "$PREFIX$message" 51 } 52 loggingnull53 override fun logging(message: String, symbol: KSNode?) { 54 recordedEvents.add(Event(CompilerMessageSeverity.LOGGING, convertMessage(message, symbol))) 55 } 56 infonull57 override fun info(message: String, symbol: KSNode?) { 58 recordedEvents.add(Event(CompilerMessageSeverity.INFO, convertMessage(message, symbol))) 59 } 60 warnnull61 override fun warn(message: String, symbol: KSNode?) { 62 val severity = if (allWarningsAsErrors) CompilerMessageSeverity.ERROR else CompilerMessageSeverity.WARNING 63 recordedEvents.add(Event(severity, convertMessage(message, symbol))) 64 } 65 errornull66 override fun error(message: String, symbol: KSNode?) { 67 recordedEvents.add(Event(CompilerMessageSeverity.ERROR, convertMessage(message, symbol))) 68 } 69 exceptionnull70 override fun exception(e: Throwable) { 71 val writer = StringWriter() 72 e.printStackTrace(PrintWriter(writer)) 73 recordedEvents.add(Event(CompilerMessageSeverity.EXCEPTION, writer.toString())) 74 } 75 reportAllnull76 fun reportAll() { 77 for (event in recordedEvents) { 78 if (!reportedToCompiler && event.severity in reportToCompilerSeverity) { 79 reportedToCompiler = true 80 wrappedMessageCollector.report(event.severity, "Error occurred in KSP, check log for detail") 81 } 82 messageCollector.report(event.severity, event.message) 83 } 84 } 85 } 86