Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
26 changes: 26 additions & 0 deletions server/src/cache/cache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export class Cache<TKey, TValue> {
private readonly data: Map<TKey, TValue>

public constructor() {
this.data = new Map()
}

public cached(key: TKey, cb: () => TValue): TValue {
const cached = this.data.get(key)
if (cached !== undefined) {
return cached
}

const value = cb()
this.data.set(key, value)
return value
}

public clear(): void {
this.data.clear()
}

public get size(): number {
return this.data.size
}
}
8 changes: 8 additions & 0 deletions server/src/completion/CompletionItemAdditionalInformation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {File} from "@server/psi/File"

export interface CompletionItemAdditionalInformation {
readonly name: string | undefined
readonly file: File | undefined
readonly elementFile: File | undefined
readonly language: "tolk" | "func" | undefined
}
15 changes: 15 additions & 0 deletions server/src/completion/CompletionProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// SPDX-License-Identifier: MIT
// Copyright © 2025 TON Studio
import {CompletionResult} from "@server/completion/WeightedCompletionItem"

export interface CompletionProvider<Ctx> {
isAvailable(ctx: Ctx): boolean

addCompletion(ctx: Ctx, result: CompletionResult): void
}

export interface AsyncCompletionProvider<Ctx> {
isAvailable(ctx: Ctx): boolean

addCompletion(ctx: Ctx, result: CompletionResult): Promise<void>
}
3 changes: 0 additions & 3 deletions server/src/files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,6 @@ export const isTlbFile = (
event?: lsp.TextDocumentChangeEvent<TextDocument>,
): boolean => event?.document.languageId === "tlb" || uri.endsWith(".tlb")

// export function filePathToUri(filePath: string): string {
// return pathToFileURL(filePath).href
// }
export const filePathToUri = (filePath: string): string => {
const url = pathToFileURL(filePath).toString()
return url.replace(/c:/g, "c%3A").replace(/d:/g, "d%3A")
Expand Down
13 changes: 13 additions & 0 deletions server/src/foldings/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type {Point} from "web-tree-sitter"
import type * as lsp from "vscode-languageserver"
import {FoldingRangeKind} from "vscode-languageserver-types"

export function genericFolding(start: Point, end: Point): lsp.FoldingRange {
return {
kind: FoldingRangeKind.Region,
startLine: start.row,
endLine: end.row - 1,
startCharacter: end.column,
endCharacter: end.column,
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
// SPDX-License-Identifier: MIT
// Copyright © 2025 TON Studio
import * as path from "node:path"
import {glob} from "glob"
import {index} from "@server/languages/func/indexes"
import {fileURLToPath} from "node:url"
import {filePathToUri, findFuncFile} from "@server/files"
import {glob} from "glob"
import * as path from "node:path"
import {filePathToUri} from "@server/files"

export enum FuncIndexingRootKind {
export enum IndexingRootKind {
Stdlib = "stdlib",
Workspace = "workspace",
}

export class FuncIndexingRoot {
public constructor(
export abstract class IndexingRoot {
protected constructor(
public root: string,
public kind: FuncIndexingRootKind,
public extensions: string[],
public kind: IndexingRootKind,
) {}

public async index(): Promise<void> {
const ignore =
this.kind === FuncIndexingRootKind.Stdlib
this.kind === IndexingRootKind.Stdlib
? []
: [
".git/**",
Expand All @@ -30,7 +28,11 @@ export class FuncIndexingRoot {
]

const rootDir = fileURLToPath(this.root)
const files = await glob("**/*.{fc,func}", {

const globPattern =
this.extensions.length === 1 ? this.extensions[0] : `{${this.extensions.join(",")}}`

const files = await glob(`**/*.${globPattern}`, {
cwd: rootDir,
ignore: ignore,
})
Expand All @@ -41,8 +43,9 @@ export class FuncIndexingRoot {
console.info("Indexing:", filePath)
const absPath = path.join(rootDir, filePath)
const uri = filePathToUri(absPath)
const file = await findFuncFile(uri)
index.addFile(uri, file, false)
await this.onFile(uri)
}
}

protected abstract onFile(uri: string): Promise<void>
}
15 changes: 2 additions & 13 deletions server/src/languages/fift/foldings/collect.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,13 @@
// SPDX-License-Identifier: MIT
// Copyright © 2025 TON Studio
import {FoldingRange, FoldingRangeKind} from "vscode-languageserver-types"
import {FoldingRange} from "vscode-languageserver-types"
import {RecursiveVisitor} from "@server/visitor/visitor"
import type {Point} from "web-tree-sitter"
import type * as lsp from "vscode-languageserver"
import {FiftFile} from "@server/languages/fift/psi/FiftFile"
import {genericFolding} from "@server/foldings"

export function provideFiftFoldingRanges(file: FiftFile): FoldingRange[] {
const result: FoldingRange[] = []

const genericFolding = (start: Point, end: Point): lsp.FoldingRange => {
return {
kind: FoldingRangeKind.Region,
startLine: start.row,
endLine: end.row - 1,
startCharacter: end.column,
endCharacter: end.column,
}
}

RecursiveVisitor.visit(file.rootNode, (n): boolean => {
if (
n.type === "program" ||
Expand Down
29 changes: 9 additions & 20 deletions server/src/languages/fift/semantic-tokens/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,20 @@
// Copyright © 2025 TON Studio
import type {SemanticTokens} from "vscode-languageserver"
import {RecursiveVisitor} from "@server/visitor/visitor"
import {SemanticTokensBuilder} from "vscode-languageserver/lib/common/semanticTokens"
import {SemanticTokenTypes} from "vscode-languageserver-protocol"
import type {Node as SyntaxNode} from "web-tree-sitter"
import * as lsp from "vscode-languageserver"
import {FiftReference} from "@server/languages/fift/psi/FiftReference"
import {FiftFile} from "@server/languages/fift/psi/FiftFile"
import {Tokens} from "@server/semantic/tokens"

export function provideFiftSemanticTokens(
file: FiftFile,
settings: {
enabled: boolean
},
): SemanticTokens | null {
if (!settings.enabled) {
return null
}

const builder = new SemanticTokensBuilder()
if (!settings.enabled) return null

function pushToken(n: SyntaxNode, tokenType: lsp.SemanticTokenTypes): void {
builder.push(
n.startPosition.row,
n.startPosition.column,
n.endPosition.column - n.startPosition.column,
Object.keys(lsp.SemanticTokenTypes).indexOf(tokenType.toString()),
0,
)
}
const tokens = new Tokens()

RecursiveVisitor.visit(file.rootNode, (node): boolean => {
if (
Expand All @@ -41,7 +27,7 @@ export function provideFiftSemanticTokens(
) {
const nameNode = node.childForFieldName("name")
if (nameNode) {
pushToken(nameNode, SemanticTokenTypes.function)
tokens.node(nameNode, SemanticTokenTypes.function)
}
}

Expand All @@ -52,12 +38,15 @@ export function provideFiftSemanticTokens(
) {
const def = FiftReference.resolve(node, file)
if (def) {
pushToken(node, SemanticTokenTypes.function)
tokens.node(node, SemanticTokenTypes.function)
}
}

return true
})

return builder.build()
return {
resultId: Date.now().toString(),
data: tokens.result(),
}
}
38 changes: 4 additions & 34 deletions server/src/languages/func/cache.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,15 @@
// SPDX-License-Identifier: MIT
// Copyright © 2025 TON Core
import type {NamedNode} from "@server/languages/func/psi/FuncNode"
import {Cache} from "@server/cache/cache"

export class Cache<TKey, TValue> {
private readonly data: Map<TKey, TValue>

public constructor() {
this.data = new Map()
}

public cached(key: TKey, cb: () => TValue): TValue {
const cached = this.data.get(key)
if (cached !== undefined) {
return cached
}

const value = cb()
this.data.set(key, value)
return value
}

public clear(): void {
this.data.clear()
}

public get size(): number {
return this.data.size
}
}

export class CacheManager {
public readonly resolveCache: Cache<number, NamedNode | null>

public constructor() {
this.resolveCache = new Cache()
}
export class FuncCache {
public readonly resolveCache: Cache<number, NamedNode | null> = new Cache()

public clear(): void {
console.info(`Clearing caches (resolve: ${this.resolveCache.size})`)
this.resolveCache.clear()
}
}

export const FUNC_CACHE = new CacheManager()
export const FUNC_CACHE = new FuncCache()
14 changes: 0 additions & 14 deletions server/src/languages/func/completion/CompletionProvider.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,9 @@ import {
TypeParameter,
} from "@server/languages/func/psi/Decls"
import {CompletionContext} from "./CompletionContext"
import {
CompletionWeight,
WeightedCompletionItem,
} from "@server/languages/func/completion/WeightedCompletionItem"
import {FuncFile} from "@server/languages/func/psi/FuncFile"
import {CompletionWeight, WeightedCompletionItem} from "@server/completion/WeightedCompletionItem"
import {ResolveState} from "@server/psi/ResolveState"

export interface CompletionItemAdditionalInformation {
readonly name: string | undefined
readonly file: FuncFile | undefined
readonly elementFile: FuncFile | undefined
readonly language: "tolk" | "func" | undefined
}
import {CompletionItemAdditionalInformation} from "@server/completion/CompletionItemAdditionalInformation"

export class ReferenceCompletionProcessor implements ScopeProcessor {
public constructor(private readonly ctx: CompletionContext) {}
Expand Down
57 changes: 0 additions & 57 deletions server/src/languages/func/completion/WeightedCompletionItem.ts

This file was deleted.

Loading
Loading