Skip to content
Draft
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
799d51c
CPG language TS: prepare specs for svelte language support
andreineamtu May 2, 2025
dea3d0b
CPG Language TS: init svelte language stub of files
andreineamtu May 2, 2025
5ad32e1
cpg-language-ts: prepare svelte parser with deno and add task in grad…
andreineamtu May 2, 2025
49a3fa2
CPG langeuage TS: update gradle config for svelte-porser folder
andreineamtu May 2, 2025
8a809dd
cpg-language-typescript: change the current svelte language support s…
andreineamtu May 5, 2025
a5ecf67
TSScriptLanguageFrontend: add --language flag and prepare to use the …
andreineamtu May 5, 2025
9470db5
cpg-language-ts module: change current ts parser and config to use th…
andreineamtu May 5, 2025
175fd26
cpg-lang-ts: TypeScriptLanguageFrontend: Unified Deno parser exec in …
andreineamtu May 6, 2025
e8401a9
cpg-lang-ts: SvelteLanguageFrontend: run Deno parser directly
andreineamtu May 6, 2025
c85868f
cpg-lang-ts: TS and Svelte Fronteneds: remove CpgTranslationException…
andreineamtu May 6, 2025
02659c3
cpg-lang-ts: add test for a simple svelte component
andreineamtu May 6, 2025
1c3ae67
cpg-lang-ts: parser: update README file
andreineamtu May 6, 2025
3ab434c
cpg-lang-ts: svelteLanguageFrontendTest: fix register svelte language
andreineamtu May 6, 2025
636766f
SvelteLanguageFrontend: add handlers for different tags and attribute…
andreineamtu May 6, 2025
1416d21
cpg-lang-ts: gradle build config: Add kotlin-reflect for Jackson Kotl…
andreineamtu May 6, 2025
435825c
cpg-lang-ts: add README file with the description
andreineamtu May 7, 2025
25d2d8c
cpg-language-ts: add Svelte language frontend handler, SvelteLanguage…
andreineamtu May 7, 2025
e00d8ce
Actually using CPG API
oxisto May 8, 2025
306e562
README: add guide for development
andreineamtu May 9, 2025
c376473
cpg-lang-ts: Advance Svelte frontend implementation and resolve API u…
andreineamtu May 9, 2025
f7b9b42
cpg-language-typescript: fix typeOf method params
andreineamtu May 12, 2025
8e84ad6
cpg-lang-ts: SvelteLanguageFrontend: track and log added declarations…
andreineamtu May 12, 2025
01c4fa1
cpg-lang-ts: parser.ts: import typescript to test if svelte files use ts
andreineamtu May 12, 2025
34cdafa
cpg-lang-ts: README: add notes about testing the parser directly with…
andreineamtu May 12, 2025
f331583
cpg-lang-ts: parser: update svelte compiler to v5
andreineamtu May 12, 2025
f4b7701
cpg-lang-ts: Readme: add note about running build command
andreineamtu May 12, 2025
5cc2c96
cps-lang-ts: SvelteAST: Refactor for Svelte 5 and Jackson deserializa…
andreineamtu May 13, 2025
98cdfae
cps-lang-ts: common-conventions.gradle.kts: Add SLF4J API to common f…
andreineamtu May 13, 2025
7ad7dc0
cps-lang-ts: SvelteLanuageFrontend: fix compilation errors
andreineamtu May 13, 2025
dd638b9
cpg-lang-ts: SvelteLanguageFrontend: import kotlin.jvm.Throws and fix…
andreineamtu May 13, 2025
6659f99
cpg-lang-ts: docs: add environment-setup doc
andreineamtu May 13, 2025
c521ac4
cps-lan-ts: Gradle build config: add stdlib, libs.jackson, slf4j and …
andreineamtu May 13, 2025
c2a0cee
cpg-lang-ts: SvelteLanguageFrontend: Add debug logging to Svelte fron…
andreineamtu May 14, 2025
ef08e8b
cpg-lang-ts: specs: add notes about the implementation using svelte.p…
andreineamtu May 15, 2025
fbf77fc
cpg-lang-ts: docs: update env-setup to optimize memory usage. disable…
andreineamtu May 16, 2025
38f08da
cpg-lang-ts: vscode settings: add minimal settings for java
andreineamtu May 16, 2025
f6d6422
cpg-lang-ts: SvelteAST: Refactor classes to use GenericAstNode base i…
andreineamtu May 19, 2025
ac8f5e2
cpg-lang-ts: Specs: describe new GenericAstNode approach
andreineamtu May 19, 2025
9c2e96d
cpg-lang-ts: Refactored SvelteLanguageFrontend to use GenericAstNode …
andreineamtu May 21, 2025
eaff9e4
cpg-lang-typescript: finish Basic Svelte language support with workin…
andreineamtu May 30, 2025
3682117
cpg-lang-ts: svelte test: enhance test to successfully generate JSON …
andreineamtu May 30, 2025
6d68df7
cpg-lang-ts: Svelte Language Frontend and test: Complete parsing of …
andreineamtu May 30, 2025
c9b4274
cpg-lang-ts: Svelte Language Frontend and test: HTML Template Parsin…
andreineamtu May 30, 2025
e30c102
Complete CSS block parsing for Svelte language support
andreineamtu Jun 2, 2025
ffa420b
cpg-languge-typescritpt: Register SvelteLanguage in cpg-neo4j Applica…
andreineamtu Jun 2, 2025
4e1f5c4
cpg-language-typescript: update guide to use the existing SimpleCompo…
andreineamtu Jun 2, 2025
714abd6
cpg-language-typescript: Add TemplateLiteral support for Svelte compo…
andreineamtu Jun 2, 2025
d232151
cpg-language-typescript: Add support for complex AST node types in Sv…
andreineamtu Jun 3, 2025
25e8afa
cpg-language-typecript: Add comprehensive AST node support for Svelte…
andreineamtu Jun 3, 2025
e7c1a1b
cpg-lang-ts: Add ImportDeclaration support for Svelte script imports …
andreineamtu Jun 3, 2025
0204ea8
cpg-lang-ts: feat: Add ImportSpecifier support for named imports (13t…
andreineamtu Jun 3, 2025
0f25301
cpg-lang-ts: add simple svelte and react components in test forlde
andreineamtu Jun 4, 2025
42f0d59
cpg-lang-ts: implement general Svelte parsing test with comprehensive…
andreineamtu Jun 4, 2025
131ce68
cpg-lang-ts: implement comprehensive Svelte AST node support (28+ types)
andreineamtu Jun 4, 2025
cc209ca
cpg-lang-ts: implement graceful degradation and comprehensive Svelte …
andreineamtu Jun 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions cpg-language-typescript/__specs/svelte-language-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Svelte Language Support Integration Plan

This document tracks the progress of integrating Svelte language support into the `cpg-language-typescript` module.

## Plan (Systematic Approach)

1. **Revert & Branch:** Revert `cpg-language-typescript` to baseline (main branch state). Create new branch `feature/svelte-support`. (DONE)
2. **Verify Baseline:** Confirm the original module builds correctly (ignoring test setup issues like Kover). (DONE - `./gradlew :cpg-language-typescript:clean :cpg-language-typescript:assemble` succeeded).
3. **Add Svelte Kotlin Stubs:** Create minimal `SvelteLanguage.kt`, `SvelteAST.kt`, `SvelteLanguageFrontend.kt`. (DONE)
4. **Build Step 1:** Run `compileKotlin` to ensure stubs are syntactically correct. Commit. (Current Step)
* Purpose: Quickly check basic Kotlin syntax, class structure, inheritance, and imports for the new stub files before adding complex logic. Confirms the stubs themselves don't break compilation.
5. **Add Svelte Parser Script & Build Logic:** Decide between Deno or Node.js for the `svelte.parse` script. Add parser script and necessary build tasks (`build.gradle.kts`). Run `assemble`. Commit.
6. **Integrate Parser Execution:** Add logic to `SvelteLanguageFrontend.kt` to run the parser and read JSON output.
7. **Build Step 2:** Run `compileKotlin`. Fix process/IO/JSON errors. Commit.
8. **Integrate Basic CPG Nodes:** Add code to create `TranslationUnitDeclaration` and placeholder `RecordDeclaration` from AST.
9. **Build Step 3:** Run `compileKotlin`. Analyze and fix core CPG integration errors carefully. Commit.
10. **Add Dispatch Logic:** Re-introduce Svelte dispatch logic in `TypeScriptLanguageFrontend.kt`.
11. **Build Step 4:** Run `compileKotlin`. Fix. Commit.
12. **Add Tests & Refine:** Implement tests and detailed CPG node handling.

## Progress Notes

* **Strategy Shift:** Decided to integrate Svelte support directly into `cpg-language-typescript` instead of a separate module, based on maintainer feedback.
* **Kotlin Stubs:** Created initial Kotlin classes within `cpg-language-typescript`:
* `SvelteLanguage.kt`: Defines the language properties.
* `SvelteAST.kt`: Placeholder interface for AST nodes.
* `SvelteLanguageFrontend.kt`: Stub implementation for the frontend, including basic `parse` method structure.
* **Parser Setup:**
* Modified the existing Deno-based parser script (`src/main/typescript/parser.ts`) to include `svelte.parse()` for handling `.svelte` files.
* The build process in `cpg-language-typescript/build.gradle.kts` will need to be adjusted to handle Deno execution for the combined parser (specific tasks to be defined).
* **Frontend Integration:** Modified `TypeScriptLanguageFrontend.kt`'s `parse` method to detect `.svelte` files and delegate to `SvelteLanguageFrontend` (when instantiated).
* **Build Status (Current):** Successfully added Kotlin stubs. Next step is to resolve Kotlin compilation errors in the new Svelte files and attempt a build (`./gradlew :cpg-language-typescript:build`).
2 changes: 2 additions & 0 deletions cpg-language-typescript/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/*
* cpg-language-typescript module gradle build config
*
* Copyright (c) 2022, Fraunhofer AISEC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2025, Fraunhofer AISEC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $$$$$$\ $$$$$$$\ $$$$$$\
* $$ __$$\ $$ __$$\ $$ __$$\
* $$ / \__|$$ | $$ |$$ / \__|
* $$ | $$$$$$$ |$$ |$$$$\
* $$ | $$ ____/ $$ |\_$$ |
* $$ | $$\ $$ | $$ | $$ |
* \$$$$$ |$$ | \$$$$$ |
* \______/ \__| \______/
*
*/
package de.fraunhofer.aisec.cpg.frontends.typescript

/**
* Base interface for Svelte AST nodes parsed from the svelte parser. We will define concrete data
* classes inheriting from this later.
*/
interface SvelteNode {
// Common properties expected from the svelte parser output
// For now, let's assume they will be added later.
// val type: String
// val start: Int
// val end: Int
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (c) 2025, Fraunhofer AISEC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $$$$$$\ $$$$$$$\ $$$$$$\
* $$ __$$\ $$ __$$\ $$ __$$\
* $$ / \__|$$ | $$ |$$ / \__|
* $$ | $$$$$$$ |$$ |$$$$\
* $$ | $$ ____/ $$ |\_$$ |
* $$ | $$\ $$ | $$ | $$ |
* \$$$$$ |$$ | \$$$$$ |
* \______/ \__| \______/
*
*/
package de.fraunhofer.aisec.cpg.frontends.typescript

import de.fraunhofer.aisec.cpg.frontends.Language
import de.fraunhofer.aisec.cpg.graph.types.*
import kotlin.reflect.KClass
import org.neo4j.ogm.annotation.Transient

/** The Svelte language. */
class SvelteLanguage : Language<SvelteLanguageFrontend>() {

override val fileExtensions = listOf("svelte")
override val namespaceDelimiter = "." // Using JS/TS convention for now

@Transient
override val frontend: KClass<out SvelteLanguageFrontend> = SvelteLanguageFrontend::class

// TODO: Define built-in types relevant for Svelte if any, beyond JS/TS
@Transient override val builtInTypes: Map<String, Type> = mapOf()

// TODO: Define compound assignment operators if Svelte has specific ones
@Transient override val compoundAssignmentOperators = setOf<String>() // Inherit from JS/TS?
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/*
* Copyright (c) 2025, Fraunhofer AISEC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $$$$$$\ $$$$$$$\ $$$$$$\
* $$ __$$\ $$ __$$\ $$ __$$\
* $$ / \__|$$ | $$ |$$ / \__|
* $$ | $$$$$$$ |$$ |$$$$\
* $$ | $$ ____/ $$ |\_$$ |
* $$ | $$\ $$ | $$ | $$ |
* \$$$$$ |$$ | \$$$$$ |
* \______/ \__| \______/
*
*/
package de.fraunhofer.aisec.cpg.frontends.typescript

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import de.fraunhofer.aisec.cpg.TranslationContext
import de.fraunhofer.aisec.cpg.frontends.LanguageFrontend
import de.fraunhofer.aisec.cpg.frontends.TranslationException as CpgTranslationException
import de.fraunhofer.aisec.cpg.graph.Node
import de.fraunhofer.aisec.cpg.graph.declarations.TranslationUnitDeclaration
import de.fraunhofer.aisec.cpg.graph.newTranslationUnitDeclaration
import de.fraunhofer.aisec.cpg.graph.types.Type
import de.fraunhofer.aisec.cpg.graph.unknownType
import de.fraunhofer.aisec.cpg.sarif.PhysicalLocation
import java.io.File
import java.io.InputStreamReader

/**
* Language Frontend for analyzing Svelte files.
*
* Responsible for converting a Svelte AST (obtained by running the Deno parser script) into CPG
* nodes.
*/
class SvelteLanguageFrontend(ctx: TranslationContext, language: SvelteLanguage = SvelteLanguage()) :
LanguageFrontend<SvelteNode, SvelteNode>(ctx, language) {

private val mapper = jacksonObjectMapper()
private var currentFileContent: String? = null

// Companion object to manage the parser binary extraction (similar to TS frontend)
companion object {
// Use the *same* parser binary as TypeScriptLanguageFrontend
private val parserFile: File = TypeScriptLanguageFrontend.parserFile
}

@Throws(CpgTranslationException::class)
override fun parse(file: File): TranslationUnitDeclaration {
currentFileContent = file.readText() // Store content for code/location mapping

if (!parserFile.exists()) {
// If the TS frontend didn't extract it, something is wrong
throw CpgTranslationException(
"Unified parser binary not found at ${parserFile.absolutePath} (expected TS frontend to extract)"
)
}

// This frontend *only* handles Svelte
val languageFlag = "--language=svelte"

log.info(
"Executing unified parser for Svelte file {} with flag: {}",
file.absolutePath,
languageFlag,
)
val process =
try {
Runtime.getRuntime()
.exec(arrayOf(parserFile.absolutePath, languageFlag, file.absolutePath))
} catch (e: Exception) {
throw CpgTranslationException(
"Error executing unified parser for Svelte: ${e.message}",
e,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the extra parameter

)
}

val stdInput = InputStreamReader(process.inputStream)
val stdError = InputStreamReader(process.errorStream)
val jsonResult = stdInput.readText()
val errors = stdError.readText()
stdInput.close()
stdError.close()

val exitCode = process.waitFor()

if (exitCode != 0) {
log.error("Unified parser (Svelte) exited with code {}: {}", exitCode, errors)
throw CpgTranslationException("Unified parser (Svelte) failed: $errors")
}
if (errors.isNotEmpty()) {
log.warn("Unified parser (Svelte) reported errors/warnings: {}", errors)
}

// --- Start AST Deserialization and CPG Creation ---
log.info("Handling Svelte AST JSON for {}", file.name)

// TODO: Define SvelteNode data classes in SvelteAST.kt matching svelte.parse output
// For now, we deserialize into a generic map or a placeholder root node
// data class SvelteProgramNode(val type: String?, val children: List<Any>?) : SvelteNode //
// Placeholder - move to SvelteAST.kt
// val svelteAstRoot: SvelteProgramNode = try { ... } catch ...

// Placeholder implementation:
log.debug("Svelte parser JSON output: {}", jsonResult)
// val svelteAstRoot: Map<String, Any> = mapper.readValue(jsonString) // Example
// deserialization

// Create the TranslationUnitDeclaration using the builder function
val tud = newTranslationUnitDeclaration(file.name, currentFileContent ?: "")

// TODO: Implement the actual CPG node creation logic here.
// Iterate through svelteAstRoot (html, css, instance, module sections)
// and create corresponding CPG nodes (RecordDeclaration, FunctionDeclaration, etc.)

// TODO: Implement comment handling if needed and possible from Svelte AST

log.info("Svelte CPG construction finished for {}", file.name)
return tud
}

override fun typeOf(typeNode: SvelteNode): Type {
// TODO: Implement type mapping based on Svelte AST node types
return unknownType()
}

override fun codeOf(astNode: SvelteNode): String? {
// TODO: Extract code snippet corresponding to the SvelteNode
// Requires SvelteNode to have start/end properties from parser
// Use currentFileContent?.substring(astNode.start, astNode.end)
return null // Placeholder
}

override fun locationOf(astNode: SvelteNode): PhysicalLocation? {
// TODO: Create PhysicalLocation based on SvelteNode start/end properties
// Requires SvelteNode to have start/end and file info
// Use FrontendUtils.parseLocation or similar
return null // Placeholder
}

override fun setComment(node: Node, astNode: SvelteNode) {
// TODO: Implement comment association if Svelte AST provides comment info
}
}
Loading
Loading