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
This commit is contained in:
Denis Zharkov
2018-04-11 10:45:29 +03:00
parent 6e8247f7cf
commit 0788afe92c
4 changed files with 23 additions and 19 deletions
@@ -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 // 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('.', ';', '[', ']', '/', '<', '>', ':', '\\') private val CHARS = setOf('.', ';', '[', ']', '/', '<', '>', ':', '\\')
override fun checkIdentifier(identifier: PsiElement?, diagnosticHolder: DiagnosticSink) { override fun checkIdentifier(simpleNameExpression: KtSimpleNameExpression, diagnosticHolder: DiagnosticSink) {
if (identifier == null) return reportIfNeeded(simpleNameExpression.getReferencedName(), { simpleNameExpression.getIdentifier() }, diagnosticHolder)
reportIfNeeded(identifier.text, identifier, diagnosticHolder)
} }
override fun checkDeclaration(declaration: KtDeclaration, diagnosticHolder: DiagnosticSink) { override fun checkDeclaration(declaration: KtDeclaration, diagnosticHolder: DiagnosticSink) {
@@ -50,17 +48,22 @@ object JvmSimpleNameBacktickChecker : IdentifierChecker {
private fun checkNamed(declaration: KtNamedDeclaration, diagnosticHolder: DiagnosticSink) { private fun checkNamed(declaration: KtNamedDeclaration, diagnosticHolder: DiagnosticSink) {
val name = declaration.name ?: return val name = declaration.name ?: return
val element = declaration.nameIdentifier ?: declaration reportIfNeeded(name, { declaration.nameIdentifier ?: declaration }, diagnosticHolder)
reportIfNeeded(name, element, diagnosticHolder)
} }
private fun reportIfNeeded(name: String, element: PsiElement, diagnosticHolder: DiagnosticSink) { private fun reportIfNeeded(name: String, reportOn: () -> PsiElement?, diagnosticHolder: DiagnosticSink) {
val text = KtPsiUtil.unquoteIdentifier(name) val text = KtPsiUtil.unquoteIdentifier(name)
if (text.isEmpty()) { if (text.isEmpty()) {
diagnosticHolder.report(Errors.INVALID_CHARACTERS.on(element, "should not be empty")) diagnosticHolder.report(Errors.INVALID_CHARACTERS.on(reportOn() ?: return, "should not be empty"))
} } else if (text.any { it in CHARS }) {
else if (text.any { it in CHARS }) { diagnosticHolder.report(
diagnosticHolder.report(Errors.INVALID_CHARACTERS.on(element, "contains illegal characters: ${CHARS.intersect(text.toSet()).joinToString("")}")) Errors.INVALID_CHARACTERS.on(
reportOn() ?: return,
"contains illegal characters: ${CHARS.intersect(text.toSet()).joinToString(
""
)}"
)
)
} }
} }
} }
@@ -16,16 +16,16 @@
package org.jetbrains.kotlin.resolve package org.jetbrains.kotlin.resolve
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
interface IdentifierChecker { interface IdentifierChecker {
fun checkIdentifier(identifier: PsiElement?, diagnosticHolder: DiagnosticSink) fun checkIdentifier(simpleNameExpression: KtSimpleNameExpression, diagnosticHolder: DiagnosticSink)
fun checkDeclaration(declaration: KtDeclaration, diagnosticHolder: DiagnosticSink) fun checkDeclaration(declaration: KtDeclaration, diagnosticHolder: DiagnosticSink)
object Default : IdentifierChecker { object Default : IdentifierChecker {
override fun checkIdentifier(identifier: PsiElement?, diagnosticHolder: DiagnosticSink) {} override fun checkIdentifier(simpleNameExpression: KtSimpleNameExpression, diagnosticHolder: DiagnosticSink) {}
override fun checkDeclaration(declaration: KtDeclaration, diagnosticHolder: DiagnosticSink) {} override fun checkDeclaration(declaration: KtDeclaration, diagnosticHolder: DiagnosticSink) {}
} }
} }
@@ -102,7 +102,7 @@ class LazyTopDownAnalyzer(
} }
override fun visitPackageDirective(directive: KtPackageDirective) { 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) qualifiedExpressionResolver.resolvePackageHeader(directive, moduleDescriptor, trace)
} }
@@ -16,19 +16,20 @@
package org.jetbrains.kotlin.js.resolve.diagnostics package org.jetbrains.kotlin.js.resolve.diagnostics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.js.naming.NameSuggestion import org.jetbrains.kotlin.js.naming.NameSuggestion
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import org.jetbrains.kotlin.resolve.IdentifierChecker import org.jetbrains.kotlin.resolve.IdentifierChecker
object JsIdentifierChecker : IdentifierChecker { object JsIdentifierChecker : IdentifierChecker {
override fun checkIdentifier(identifier: PsiElement?, diagnosticHolder: DiagnosticSink) { override fun checkIdentifier(simpleNameExpression: KtSimpleNameExpression, diagnosticHolder: DiagnosticSink) {
if (identifier == null) return 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) { if (hasIllegalChars) {
val identifier = simpleNameExpression.getIdentifier() ?: return
diagnosticHolder.report(Errors.INVALID_CHARACTERS.on(identifier, "contains illegal characters")) diagnosticHolder.report(Errors.INVALID_CHARACTERS.on(identifier, "contains illegal characters"))
} }
} }