From 0788afe92c294ef321a545e223d6b0c061ec23eb Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Wed, 11 Apr 2018 10:45:29 +0300 Subject: [PATCH] Avoid computing AST for IdentifierChecker Basically, it's unnecessary to check anything when analysing stubs, but it's complicated now to avoid that, so we just postpone computing AST until reporting happens --- .../checkers/JvmSimpleNameBacktickChecker.kt | 25 +++++++++++-------- .../kotlin/resolve/IdentifierChecker.kt | 6 ++--- .../kotlin/resolve/LazyTopDownAnalyzer.kt | 2 +- .../diagnostics/JsIdentifierChecker.kt | 9 ++++--- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmSimpleNameBacktickChecker.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmSimpleNameBacktickChecker.kt index cba0a368ee1..e1c26e0d41d 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmSimpleNameBacktickChecker.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/JvmSimpleNameBacktickChecker.kt @@ -26,10 +26,8 @@ object JvmSimpleNameBacktickChecker : IdentifierChecker { // See The Java Virtual Machine Specification, section 4.7.9.1 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.9.1 private val CHARS = setOf('.', ';', '[', ']', '/', '<', '>', ':', '\\') - override fun checkIdentifier(identifier: PsiElement?, diagnosticHolder: DiagnosticSink) { - if (identifier == null) return - - reportIfNeeded(identifier.text, identifier, diagnosticHolder) + override fun checkIdentifier(simpleNameExpression: KtSimpleNameExpression, diagnosticHolder: DiagnosticSink) { + reportIfNeeded(simpleNameExpression.getReferencedName(), { simpleNameExpression.getIdentifier() }, diagnosticHolder) } override fun checkDeclaration(declaration: KtDeclaration, diagnosticHolder: DiagnosticSink) { @@ -50,17 +48,22 @@ object JvmSimpleNameBacktickChecker : IdentifierChecker { private fun checkNamed(declaration: KtNamedDeclaration, diagnosticHolder: DiagnosticSink) { val name = declaration.name ?: return - val element = declaration.nameIdentifier ?: declaration - reportIfNeeded(name, element, diagnosticHolder) + reportIfNeeded(name, { declaration.nameIdentifier ?: declaration }, diagnosticHolder) } - private fun reportIfNeeded(name: String, element: PsiElement, diagnosticHolder: DiagnosticSink) { + private fun reportIfNeeded(name: String, reportOn: () -> PsiElement?, diagnosticHolder: DiagnosticSink) { val text = KtPsiUtil.unquoteIdentifier(name) if (text.isEmpty()) { - diagnosticHolder.report(Errors.INVALID_CHARACTERS.on(element, "should not be empty")) - } - else if (text.any { it in CHARS }) { - diagnosticHolder.report(Errors.INVALID_CHARACTERS.on(element, "contains illegal characters: ${CHARS.intersect(text.toSet()).joinToString("")}")) + diagnosticHolder.report(Errors.INVALID_CHARACTERS.on(reportOn() ?: return, "should not be empty")) + } else if (text.any { it in CHARS }) { + diagnosticHolder.report( + Errors.INVALID_CHARACTERS.on( + reportOn() ?: return, + "contains illegal characters: ${CHARS.intersect(text.toSet()).joinToString( + "" + )}" + ) + ) } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/IdentifierChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/IdentifierChecker.kt index a6e0318a26d..92a91c0139b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/IdentifierChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/IdentifierChecker.kt @@ -16,16 +16,16 @@ package org.jetbrains.kotlin.resolve -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtSimpleNameExpression interface IdentifierChecker { - fun checkIdentifier(identifier: PsiElement?, diagnosticHolder: DiagnosticSink) + fun checkIdentifier(simpleNameExpression: KtSimpleNameExpression, diagnosticHolder: DiagnosticSink) fun checkDeclaration(declaration: KtDeclaration, diagnosticHolder: DiagnosticSink) object Default : IdentifierChecker { - override fun checkIdentifier(identifier: PsiElement?, diagnosticHolder: DiagnosticSink) {} + override fun checkIdentifier(simpleNameExpression: KtSimpleNameExpression, diagnosticHolder: DiagnosticSink) {} override fun checkDeclaration(declaration: KtDeclaration, diagnosticHolder: DiagnosticSink) {} } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt index ff518b28d0e..b5dab79fffc 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/LazyTopDownAnalyzer.kt @@ -102,7 +102,7 @@ class LazyTopDownAnalyzer( } override fun visitPackageDirective(directive: KtPackageDirective) { - directive.packageNames.forEach { identifierChecker.checkIdentifier(it.getIdentifier(), trace) } + directive.packageNames.forEach { identifierChecker.checkIdentifier(it, trace) } qualifiedExpressionResolver.resolvePackageHeader(directive, moduleDescriptor, trace) } diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsIdentifierChecker.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsIdentifierChecker.kt index e6539eacadc..ab57618a4af 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsIdentifierChecker.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsIdentifierChecker.kt @@ -16,19 +16,20 @@ package org.jetbrains.kotlin.js.resolve.diagnostics -import com.intellij.psi.PsiElement import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.js.naming.NameSuggestion import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtSimpleNameExpression import org.jetbrains.kotlin.resolve.IdentifierChecker object JsIdentifierChecker : IdentifierChecker { - override fun checkIdentifier(identifier: PsiElement?, diagnosticHolder: DiagnosticSink) { - if (identifier == null) return + override fun checkIdentifier(simpleNameExpression: KtSimpleNameExpression, diagnosticHolder: DiagnosticSink) { + val simpleName = simpleNameExpression.getReferencedName() - val hasIllegalChars = identifier.text.split('.').any { NameSuggestion.sanitizeName(it) != it } + val hasIllegalChars = simpleName.split('.').any { NameSuggestion.sanitizeName(it) != it } if (hasIllegalChars) { + val identifier = simpleNameExpression.getIdentifier() ?: return diagnosticHolder.report(Errors.INVALID_CHARACTERS.on(identifier, "contains illegal characters")) } }