prometeu-studio/prometeu-lsp/prometeu-lsp-v1/src/main/java/p/studio/lsp/LspSemanticDefinitionService.java

47 lines
2.0 KiB
Java

package p.studio.lsp;
import p.studio.compiler.pbs.lexer.PbsToken;
import p.studio.compiler.pbs.lexer.PbsTokenKind;
import p.studio.lsp.dtos.LspDefinitionTargetDTO;
import p.studio.lsp.dtos.LspSymbolDTO;
import p.studio.lsp.messages.LspDefinitionRequest;
import p.studio.lsp.messages.LspDefinitionResult;
import p.studio.lsp.messages.SemanticSession;
import java.nio.file.Path;
import java.util.List;
import static p.studio.lsp.LspSemanticUtilities.normalize;
import static p.studio.lsp.LspSemanticUtilities.tokenAt;
class LspSemanticDefinitionService {
LspDefinitionResult definition(
final SemanticSession session,
final LspDefinitionRequest request) {
final List<LspDefinitionTargetDTO> targets = resolveDefinitionTargets(session, request);
return new LspDefinitionResult(request.documentPath(), request.offset(), targets);
}
private List<LspDefinitionTargetDTO> resolveDefinitionTargets(
final SemanticSession session,
final LspDefinitionRequest request) {
final Path documentPath = normalize(request.documentPath());
final List<PbsToken> tokens = session.tokensByDocument().getOrDefault(documentPath, List.of());
final PbsToken activeToken = tokenAt(tokens, request.offset());
if (activeToken == null || activeToken.kind() != PbsTokenKind.IDENTIFIER) {
return List.of();
}
final String lexeme = activeToken.lexeme();
final List<LspSymbolDTO> sameDocumentMatches = session.symbolsByName().getOrDefault(lexeme, List.of()).stream()
.filter(symbol -> symbol.documentPath().equals(documentPath))
.toList();
final List<LspSymbolDTO> effectiveMatches = sameDocumentMatches.isEmpty()
? session.symbolsByName().getOrDefault(lexeme, List.of())
: sameDocumentMatches;
return effectiveMatches.stream()
.map(symbol -> new LspDefinitionTargetDTO(symbol.name(), symbol.documentPath(), symbol.range()))
.toList();
}
}