From 71eef386e49b7f610d71791a4ddd9cb5625424e4 Mon Sep 17 00:00:00 2001 From: hfhbd Date: Mon, 3 Jul 2023 15:44:23 +0200 Subject: [PATCH 1/2] Move system tables to baseContributorFiles --- .../sql/psi/core/SqlCoreEnvironment.kt | 4 --- .../alecstrong/sql/psi/core/SqlFileBase.kt | 20 ++---------- .../sql/psi/core/TablesExposedTest.kt | 28 ++++++----------- .../sql/psi/test/fixtures/CompileFile.kt | 5 ++- .../sql/psi/test/fixtures/FixturesTest.kt | 11 ++----- .../psi/test/fixtures/TestHeadlessParser.kt | 29 ++++++++++++++--- .../fixtures/predefined/Dual.predefined | 3 -- .../resources/fixtures/predefined/Select.s | 2 -- .../sql/psi/sample/core/SampleFile.kt | 2 +- .../fixtures/PassingPredefinedTablesTest.kt | 31 +++++++++++++++++++ 10 files changed, 72 insertions(+), 63 deletions(-) delete mode 100644 core/src/testFixtures/resources/fixtures/predefined/Dual.predefined delete mode 100644 core/src/testFixtures/resources/fixtures/predefined/Select.s create mode 100644 test-fixtures/src/test/kotlin/com/alecstrong/sql/psi/test/fixtures/PassingPredefinedTablesTest.kt diff --git a/core/src/main/kotlin/com/alecstrong/sql/psi/core/SqlCoreEnvironment.kt b/core/src/main/kotlin/com/alecstrong/sql/psi/core/SqlCoreEnvironment.kt index 334222d6..d78f9265 100644 --- a/core/src/main/kotlin/com/alecstrong/sql/psi/core/SqlCoreEnvironment.kt +++ b/core/src/main/kotlin/com/alecstrong/sql/psi/core/SqlCoreEnvironment.kt @@ -56,10 +56,6 @@ private class ApplicationEnvironment { } } -data class PredefinedTable(val packageName: String, val simpleFileName: String, val content: String) { - val fileName = "$packageName.$simpleFileName" -} - open class SqlCoreEnvironment( sourceFolders: List, dependencies: List, diff --git a/core/src/main/kotlin/com/alecstrong/sql/psi/core/SqlFileBase.kt b/core/src/main/kotlin/com/alecstrong/sql/psi/core/SqlFileBase.kt index 8e923ad5..ec9f3d35 100644 --- a/core/src/main/kotlin/com/alecstrong/sql/psi/core/SqlFileBase.kt +++ b/core/src/main/kotlin/com/alecstrong/sql/psi/core/SqlFileBase.kt @@ -13,7 +13,6 @@ import com.intellij.extapi.psi.PsiFileBase import com.intellij.lang.Language import com.intellij.psi.FileViewProvider import com.intellij.psi.PsiElement -import com.intellij.psi.PsiFileFactory import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.util.PsiTreeUtil import kotlin.reflect.KClass @@ -21,7 +20,6 @@ import kotlin.reflect.KClass abstract class SqlFileBase( viewProvider: FileViewProvider, language: Language, - predefinedTables: Collection = emptyList(), ) : PsiFileBase(viewProvider, language) { abstract val order: Long? @@ -39,26 +37,12 @@ abstract class SqlFileBase( return schema(T::class, sqlStmtElement, includeAll) } - private val systemTables: List by lazy { - val psiFactory = PsiFileFactory.getInstance(project) - predefinedTables.flatMap { predefinedTable -> - val sqlFile = psiFactory.createFileFromText(predefinedTable.fileName, language, predefinedTable.content) as SqlFileBase - val stmts = sqlFile.sqlStmtList!! - stmts.stmtList.mapNotNull { - it.firstChild as? SchemaContributor - } - } - } - fun schema( type: KClass, sqlStmtElement: PsiElement? = null, includeAll: Boolean = true, ): Collection { val schema = Schema() - for (systemTable in systemTables) { - systemTable.modifySchema(schema) - } iteratePreviousStatements(type, sqlStmtElement, includeAll) { statement -> if (sqlStmtElement != null && PsiTreeUtil.isAncestor(sqlStmtElement, statement, false)) { if (order == null && (statement is TableElement && statement !is SqlCreateTableStmt)) { @@ -130,8 +114,8 @@ abstract class SqlFileBase( val baseContributorFiles = baseContributorFiles() for ((baseContributorIndex, baseContributor) in baseContributorFiles.withIndex()) { - // Put the last file to index 0, and the previous files to previous index. - val orderedIndex = -baseContributorFiles.lastIndex + baseContributorIndex.toLong() + // Put the last file to index -1, and the previous files to previous index. + val orderedIndex = -1 - baseContributorFiles.lastIndex + baseContributorIndex.toLong() baseContributor.contributors()?.let { contributors -> orderedContributors[orderedIndex] = linkedSetOf(elements = contributors.toTypedArray()) } diff --git a/core/src/test/kotlin/com/alecstrong/sql/psi/core/TablesExposedTest.kt b/core/src/test/kotlin/com/alecstrong/sql/psi/core/TablesExposedTest.kt index e5564a47..e18cf676 100644 --- a/core/src/test/kotlin/com/alecstrong/sql/psi/core/TablesExposedTest.kt +++ b/core/src/test/kotlin/com/alecstrong/sql/psi/core/TablesExposedTest.kt @@ -30,15 +30,11 @@ class TablesExposedTest { |ALTER TABLE test3 RENAME TO test5; """.trimMargin(), predefined = listOf( - PredefinedTable( - "predefined", - "1.predefined", - """ - |CREATE TABLE predefined ( - | id TEXT NOT NULL - |); - """.trimMargin(), - ), + """ + |CREATE TABLE predefined ( + | id TEXT NOT NULL + |); + """.trimMargin(), ), ) { (_, file) -> @@ -77,15 +73,11 @@ class TablesExposedTest { |ALTER TABLE test3 RENAME TO test5; """.trimMargin(), predefined = listOf( - PredefinedTable( - "predefined", - "1.predefined", - """ - |CREATE TABLE predefined ( - | id TEXT NOT NULL - |); - """.trimMargin(), - ), + """ + |CREATE TABLE predefined ( + | id TEXT NOT NULL + |); + """.trimMargin(), ), ) { (_, file) -> diff --git a/core/src/testFixtures/kotlin/com/alecstrong/sql/psi/test/fixtures/CompileFile.kt b/core/src/testFixtures/kotlin/com/alecstrong/sql/psi/test/fixtures/CompileFile.kt index be3be01a..67ff4a2d 100644 --- a/core/src/testFixtures/kotlin/com/alecstrong/sql/psi/test/fixtures/CompileFile.kt +++ b/core/src/testFixtures/kotlin/com/alecstrong/sql/psi/test/fixtures/CompileFile.kt @@ -1,6 +1,5 @@ package com.alecstrong.sql.psi.test.fixtures -import com.alecstrong.sql.psi.core.PredefinedTable import com.alecstrong.sql.psi.core.SqlFileBase import com.intellij.core.CoreApplicationEnvironment import java.io.File @@ -10,7 +9,7 @@ fun compileFile( // language=sql text: String, customInit: CoreApplicationEnvironment.() -> Unit = { }, - predefined: List = emptyList(), + predefined: List = emptyList(), action: (SqlFileBase) -> Unit, ) { compileFiles(text, predefined = predefined, customInit = customInit) { @@ -21,7 +20,7 @@ fun compileFile( fun compileFiles( vararg files: String, customInit: CoreApplicationEnvironment.() -> Unit = { }, - predefined: List = emptyList(), + predefined: List = emptyList(), action: (List) -> Unit, ) { val directory = Files.createTempDirectory("sql-psi").toFile() diff --git a/core/src/testFixtures/kotlin/com/alecstrong/sql/psi/test/fixtures/FixturesTest.kt b/core/src/testFixtures/kotlin/com/alecstrong/sql/psi/test/fixtures/FixturesTest.kt index 8303623f..90291655 100644 --- a/core/src/testFixtures/kotlin/com/alecstrong/sql/psi/test/fixtures/FixturesTest.kt +++ b/core/src/testFixtures/kotlin/com/alecstrong/sql/psi/test/fixtures/FixturesTest.kt @@ -1,6 +1,5 @@ package com.alecstrong.sql.psi.test.fixtures -import com.alecstrong.sql.psi.core.PredefinedTable import com.alecstrong.sql.psi.core.SqlFileBase import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiElement @@ -13,7 +12,7 @@ import java.util.jar.JarFile abstract class FixturesTest( val name: String, val fixtureRoot: File, - val predefinedTables: List = emptyList(), + val predefinedTables: List = emptyList(), ) { protected open val replaceRules: Array> = emptyArray() @@ -41,13 +40,7 @@ abstract class FixturesTest( val offsetInLine = element.textOffset - document.getLineStartOffset(lineNum) errors.add("$name line ${lineNum + 1}:$offsetInLine - $s") }, - predefinedTables = ( - newRoot.listFiles { _, name -> - name.endsWith(".predefined") - }?.map { - PredefinedTable("", it.nameWithoutExtension, it.readText()) - } ?: emptyList() - ) + predefinedTables, + predefinedTables = predefinedTables, ) val sourceFiles = StringBuilder() diff --git a/core/src/testFixtures/kotlin/com/alecstrong/sql/psi/test/fixtures/TestHeadlessParser.kt b/core/src/testFixtures/kotlin/com/alecstrong/sql/psi/test/fixtures/TestHeadlessParser.kt index ca533660..28649513 100644 --- a/core/src/testFixtures/kotlin/com/alecstrong/sql/psi/test/fixtures/TestHeadlessParser.kt +++ b/core/src/testFixtures/kotlin/com/alecstrong/sql/psi/test/fixtures/TestHeadlessParser.kt @@ -1,6 +1,5 @@ package com.alecstrong.sql.psi.test.fixtures -import com.alecstrong.sql.psi.core.PredefinedTable import com.alecstrong.sql.psi.core.SqlAnnotationHolder import com.alecstrong.sql.psi.core.SqlCoreEnvironment import com.alecstrong.sql.psi.core.SqlFileBase @@ -9,7 +8,9 @@ import com.intellij.core.CoreApplicationEnvironment import com.intellij.icons.AllIcons import com.intellij.lang.Language import com.intellij.openapi.fileTypes.LanguageFileType +import com.intellij.openapi.util.Key import com.intellij.psi.FileViewProvider +import com.intellij.psi.PsiFileFactory import com.intellij.psi.tree.IFileElementType import java.io.File @@ -17,7 +18,7 @@ object TestHeadlessParser { fun build( root: String, annotator: SqlAnnotationHolder, - predefinedTables: List = emptyList(), + predefinedTables: List = emptyList(), customInit: CoreApplicationEnvironment.() -> Unit = { }, ): SqlCoreEnvironment { return build(listOf(File(root)), annotator, predefinedTables, customInit) @@ -26,7 +27,7 @@ object TestHeadlessParser { fun build( sourceFolders: List, annotator: SqlAnnotationHolder, - predefinedTables: List = emptyList(), + predefinedTables: List = emptyList(), customInit: CoreApplicationEnvironment.() -> Unit = { }, ): SqlCoreEnvironment { val parserDefinition = TestParserDefinition(predefinedTables) @@ -39,6 +40,7 @@ object TestHeadlessParser { initializeApplication { registerFileType(TestFileType, TestFileType.defaultExtension) registerParserDefinition(parserDefinition) + customInit() } } @@ -56,7 +58,7 @@ private object TestFileType : LanguageFileType(TestLanguage) { override fun getDescription() = "Test SQLite Language File" } -private class TestParserDefinition(private val predefinedTables: List) : SqlParserDefinition() { +private class TestParserDefinition(private val predefinedTables: List) : SqlParserDefinition() { override fun createFile(viewProvider: FileViewProvider) = TestFile(viewProvider, predefinedTables) override fun getFileNodeType() = FILE override fun getLanguage() = TestLanguage @@ -66,7 +68,7 @@ private class TestParserDefinition(private val predefinedTables: List) : SqlFileBase(viewProvider, TestLanguage, predefinedTables) { +private class TestFile(viewProvider: FileViewProvider, private val predefinedTables: List) : SqlFileBase(viewProvider, TestLanguage) { override fun getFileType() = TestFileType override val order = name.substringBefore(".${fileType.defaultExtension}").let { name -> if (name.all { it in '0'..'9' }) { @@ -75,4 +77,21 @@ private class TestFile(viewProvider: FileViewProvider, predefinedTables: List { + val base = super.baseContributorFiles() + if (getUserData(isPredefined) == Unit) { + return base + } + val factory = PsiFileFactory.getInstance(project) + return base + predefinedTables.map { + val file = factory.createFileFromText(TestLanguage, it) as SqlFileBase + file.putUserData(isPredefined, Unit) + file + } + } + + companion object { + val isPredefined = Key.create("isPredefined") + } } diff --git a/core/src/testFixtures/resources/fixtures/predefined/Dual.predefined b/core/src/testFixtures/resources/fixtures/predefined/Dual.predefined deleted file mode 100644 index 20b52938..00000000 --- a/core/src/testFixtures/resources/fixtures/predefined/Dual.predefined +++ /dev/null @@ -1,3 +0,0 @@ -CREATE TABLE dual ( - DUMMY TEXT NOT NULL -); diff --git a/core/src/testFixtures/resources/fixtures/predefined/Select.s b/core/src/testFixtures/resources/fixtures/predefined/Select.s deleted file mode 100644 index 78f6daba..00000000 --- a/core/src/testFixtures/resources/fixtures/predefined/Select.s +++ /dev/null @@ -1,2 +0,0 @@ -SELECT * -FROM dual; diff --git a/sample-core/src/main/kotlin/com/alecstrong/sql/psi/sample/core/SampleFile.kt b/sample-core/src/main/kotlin/com/alecstrong/sql/psi/sample/core/SampleFile.kt index c1c2e3b5..7e7ea621 100644 --- a/sample-core/src/main/kotlin/com/alecstrong/sql/psi/sample/core/SampleFile.kt +++ b/sample-core/src/main/kotlin/com/alecstrong/sql/psi/sample/core/SampleFile.kt @@ -3,7 +3,7 @@ package com.alecstrong.sql.psi.sample.core import com.alecstrong.sql.psi.core.SqlFileBase import com.intellij.psi.FileViewProvider -class SampleFile(viewProvider: FileViewProvider) : SqlFileBase(viewProvider, SampleLanguage, predefinedTables = emptyList()) { +class SampleFile(viewProvider: FileViewProvider) : SqlFileBase(viewProvider, SampleLanguage) { override val order = name.substringBefore(".${fileType.defaultExtension}").let { name -> if (name.all { it in '0'..'9' }) { name.toLong() diff --git a/test-fixtures/src/test/kotlin/com/alecstrong/sql/psi/test/fixtures/PassingPredefinedTablesTest.kt b/test-fixtures/src/test/kotlin/com/alecstrong/sql/psi/test/fixtures/PassingPredefinedTablesTest.kt new file mode 100644 index 00000000..c7f1ccb9 --- /dev/null +++ b/test-fixtures/src/test/kotlin/com/alecstrong/sql/psi/test/fixtures/PassingPredefinedTablesTest.kt @@ -0,0 +1,31 @@ +package com.alecstrong.sql.psi.test.fixtures + +import org.junit.Assert.fail +import org.junit.Test +import java.io.File +import java.nio.file.Files + +class PassingPredefinedTablesTest { + @Test + fun mirrorSqlDelight() { + val temp = Files.createTempDirectory("predefinedTest").toFile() + File(temp, "Test.s").writeText( + """ + SELECT * FROM dual; + SELECT name FROM dual; + """.trimIndent(), + ) + val env = TestHeadlessParser.build( + sourceFolders = listOf(temp), + annotator = { _, message -> + fail(message) + }, + predefinedTables = listOf( + """ + CREATE TABLE dual ( name TEXT ); + """.trimIndent(), + ), + ) + env.close() + } +} From 1eaa07ad6218b44040041828cf67f1574647a470 Mon Sep 17 00:00:00 2001 From: hfhbd Date: Wed, 18 Oct 2023 17:50:55 +0200 Subject: [PATCH 2/2] Lazy create the schema files once --- .../psi/test/fixtures/TestHeadlessParser.kt | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/core/src/testFixtures/kotlin/com/alecstrong/sql/psi/test/fixtures/TestHeadlessParser.kt b/core/src/testFixtures/kotlin/com/alecstrong/sql/psi/test/fixtures/TestHeadlessParser.kt index 28649513..bb93b830 100644 --- a/core/src/testFixtures/kotlin/com/alecstrong/sql/psi/test/fixtures/TestHeadlessParser.kt +++ b/core/src/testFixtures/kotlin/com/alecstrong/sql/psi/test/fixtures/TestHeadlessParser.kt @@ -8,7 +8,6 @@ import com.intellij.core.CoreApplicationEnvironment import com.intellij.icons.AllIcons import com.intellij.lang.Language import com.intellij.openapi.fileTypes.LanguageFileType -import com.intellij.openapi.util.Key import com.intellij.psi.FileViewProvider import com.intellij.psi.PsiFileFactory import com.intellij.psi.tree.IFileElementType @@ -30,8 +29,6 @@ object TestHeadlessParser { predefinedTables: List = emptyList(), customInit: CoreApplicationEnvironment.() -> Unit = { }, ): SqlCoreEnvironment { - val parserDefinition = TestParserDefinition(predefinedTables) - val environment = object : SqlCoreEnvironment( sourceFolders = sourceFolders, dependencies = emptyList(), @@ -39,6 +36,14 @@ object TestHeadlessParser { init { initializeApplication { registerFileType(TestFileType, TestFileType.defaultExtension) + val parserDefinition = TestParserDefinition( + lazy { + val factory = PsiFileFactory.getInstance(projectEnvironment.project) + predefinedTables.map { + factory.createFileFromText(TestLanguage, it) as SqlFileBase + } + }, + ) registerParserDefinition(parserDefinition) customInit() @@ -58,7 +63,7 @@ private object TestFileType : LanguageFileType(TestLanguage) { override fun getDescription() = "Test SQLite Language File" } -private class TestParserDefinition(private val predefinedTables: List) : SqlParserDefinition() { +private class TestParserDefinition(private val predefinedTables: Lazy>) : SqlParserDefinition() { override fun createFile(viewProvider: FileViewProvider) = TestFile(viewProvider, predefinedTables) override fun getFileNodeType() = FILE override fun getLanguage() = TestLanguage @@ -68,7 +73,7 @@ private class TestParserDefinition(private val predefinedTables: List) : } } -private class TestFile(viewProvider: FileViewProvider, private val predefinedTables: List) : SqlFileBase(viewProvider, TestLanguage) { +private class TestFile(viewProvider: FileViewProvider, private val predefinedTables: Lazy>) : SqlFileBase(viewProvider, TestLanguage) { override fun getFileType() = TestFileType override val order = name.substringBefore(".${fileType.defaultExtension}").let { name -> if (name.all { it in '0'..'9' }) { @@ -80,18 +85,6 @@ private class TestFile(viewProvider: FileViewProvider, private val predefinedTab override fun baseContributorFiles(): List { val base = super.baseContributorFiles() - if (getUserData(isPredefined) == Unit) { - return base - } - val factory = PsiFileFactory.getInstance(project) - return base + predefinedTables.map { - val file = factory.createFileFromText(TestLanguage, it) as SqlFileBase - file.putUserData(isPredefined, Unit) - file - } - } - - companion object { - val isPredefined = Key.create("isPredefined") + return base + predefinedTables.value } }