《底层到底做了什么》--- SonarLint for IntelliJ IDEA底层原理

前一篇 《底层到底做了什么》--- sonar-maven-plugin底层原理 里,sonar-maven-plugin项目依赖关系比较复杂,向底层递归了4、5个层包都没有找到sonar-maven-plugin项目sonar-java项目实际执行代码分析的联系。相对而言IDEA的Sonar插件以来关系要简单的多。sonarlint-intellij项目直接依赖sonar-java项目

上源码


import com.intellij.ide.AppLifecycleListener

class InitializeSonarLintOnStartup : AppLifecycleListener {
    override fun appFrameCreated(commandLineArgs: MutableList) {
        SonarLintUtils.getService(BackendService::class.java).startOnce()
        SonarLintUtils.getService(SonarLintHttpServer::class.java).startOnce()
    }
}

插件的入口类继承了intelij-idea的接口AppLifecycleListener。

类启动了两个服务,其中SonarLintHttpServer会使用Netty启动一个http服务。


class RequestProcessor(

    fun processRequest(request: Request): Response {
        if (request.path == STATUS_ENDPOINT && request.method == HttpMethod.GET) {
            return getStatusData(request.isTrustedOrigin)
        }
        if (request.path == SHOW_HOTSPOT_ENDPOINT && request.method == HttpMethod.GET) {
            return processOpenInIdeRequest(request)
        }
        if (request.path == TOKEN_ENDPOINT && request.method == HttpMethod.POST) {
            return processUserToken(request)
        }
        return BadRequest("Invalid path or method.")
    }

这个http服务处理器只会处理三种基础请求,没有业务功能。


class BackendService @NonInjectable constructor(private val backend: SonarLintBackend) : Disposable {
    constructor() : this(SonarLintBackendImpl(SonarLintIntelliJClient()))

    private var initialized = false

    fun startOnce() {
        if (initialized) return

        initialized = true
        initialize()
    }

    private fun initialize() {
        migrateStoragePath()
        val serverConnections = getGlobalSettings().serverConnections
        val sonarCloudConnections =
            serverConnections.filter { it.isSonarCloud }.map { toSonarCloudBackendConnection(it) }
        val sonarQubeConnections =
            serverConnections.filter { !it.isSonarCloud }.map { toSonarQubeBackendConnection(it) }
        backend.initialize(
            InitializeParams(
                HostInfoDto("FIXME"),
                TelemetryManagerProvider.TELEMETRY_PRODUCT_KEY,
                getLocalStoragePath(),
                EmbeddedPlugins.findEmbeddedPlugins(),
                EmbeddedPlugins.getExtraPluginsForConnectedMode(),
                EmbeddedPlugins.getEmbeddedPluginsForConnectedMode(),
                EmbeddedPlugins.enabledLanguagesInStandaloneMode,
                EmbeddedPlugins.enabledLanguagesInConnectedMode,
                false,
                sonarQubeConnections,
                sonarCloudConnections,
                null,
                false
            )
        )
        ApplicationManager.getApplication().messageBus.connect()
            .subscribe(GlobalConfigurationListener.TOPIC, object : GlobalConfigurationListener.Adapter() {
                override fun applied(previousSettings: SonarLintGlobalSettings, newSettings: SonarLintGlobalSettings) {
                    connectionsUpdated(newSettings.serverConnections)
                }

                override fun changed(serverList: MutableList) {
                    connectionsUpdated(serverList)
                }
            })
        ApplicationManager.getApplication().messageBus.connect()
            .subscribe(ProjectManager.TOPIC, object : ProjectManagerListener {
                override fun projectOpened(project: Project) {
                    [email protected](project)
                }

                override fun projectClosing(project: Project) {
                    [email protected](project)
                }
            })
    }

BackendService启动过程,包括 启动SonarLintBackend、向IDEA manager注册监听修改配置事件、注册监听项目事件。

SonarLintBackend是sonarlint.core项目中类,通过sonar-java项目间接引入。

SonarLintBackend的执行流程,待补充

你可能感兴趣的:(《底层到底做了什么》--- SonarLint for IntelliJ IDEA底层原理)