implements PLN-0028 studio frontend-owned semantic presentation consumption
This commit is contained in:
parent
de9782c16e
commit
d6ffd9eb62
@ -10,47 +10,47 @@
|
|||||||
-fx-text-fill: #71859a;
|
-fx-text-fill: #71859a;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-workspace-code-area-type-pbs .text.editor-syntax-pbs-keyword {
|
.editor-workspace-code-area-type-pbs .text.editor-semantic-pbs-keyword {
|
||||||
-fx-fill: #8dc7ff;
|
-fx-fill: #8dc7ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-workspace-code-area-type-pbs .text.editor-syntax-pbs-function {
|
.editor-workspace-code-area-type-pbs .text.editor-semantic-pbs-function {
|
||||||
-fx-fill: #f0cb79;
|
-fx-fill: #f0cb79;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-workspace-code-area-type-pbs .text.editor-syntax-pbs-type {
|
.editor-workspace-code-area-type-pbs .text.editor-semantic-pbs-type {
|
||||||
-fx-fill: #9ddba8;
|
-fx-fill: #9ddba8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-workspace-code-area-type-pbs .text.editor-syntax-pbs-binding {
|
.editor-workspace-code-area-type-pbs .text.editor-semantic-pbs-binding {
|
||||||
-fx-fill: #ffb1c8;
|
-fx-fill: #ffb1c8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-workspace-code-area-type-pbs .text.editor-syntax-pbs-string {
|
.editor-workspace-code-area-type-pbs .text.editor-semantic-pbs-string {
|
||||||
-fx-fill: #e2c48c;
|
-fx-fill: #e2c48c;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-workspace-code-area-type-pbs .text.editor-syntax-pbs-number {
|
.editor-workspace-code-area-type-pbs .text.editor-semantic-pbs-number {
|
||||||
-fx-fill: #c4e58a;
|
-fx-fill: #c4e58a;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-workspace-code-area-type-pbs .text.editor-syntax-pbs-comment {
|
.editor-workspace-code-area-type-pbs .text.editor-semantic-pbs-comment {
|
||||||
-fx-fill: #6f8192;
|
-fx-fill: #6f8192;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-workspace-code-area-type-pbs .text.editor-syntax-pbs-literal {
|
.editor-workspace-code-area-type-pbs .text.editor-semantic-pbs-literal {
|
||||||
-fx-fill: #c8a2ff;
|
-fx-fill: #c8a2ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-workspace-code-area-type-pbs .text.editor-syntax-pbs-operator {
|
.editor-workspace-code-area-type-pbs .text.editor-semantic-pbs-operator {
|
||||||
-fx-fill: #dbe6f1;
|
-fx-fill: #dbe6f1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-workspace-code-area-type-pbs .text.editor-syntax-pbs-punctuation {
|
.editor-workspace-code-area-type-pbs .text.editor-semantic-pbs-punctuation {
|
||||||
-fx-fill: #adc1d4;
|
-fx-fill: #adc1d4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-workspace-code-area-type-pbs .text.editor-syntax-pbs-identifier {
|
.editor-workspace-code-area-type-pbs .text.editor-semantic-pbs-identifier {
|
||||||
-fx-fill: #edf4fb;
|
-fx-fill: #edf4fb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,7 @@ final class EditorDocumentHighlightingRouter {
|
|||||||
final LspAnalyzeDocumentResult analysis) {
|
final LspAnalyzeDocumentResult analysis) {
|
||||||
if (fileBuffer.frontendDocument()
|
if (fileBuffer.frontendDocument()
|
||||||
&& analysis != null
|
&& analysis != null
|
||||||
|
&& presentation.supportsSemanticHighlighting()
|
||||||
&& !analysis.semanticHighlights().isEmpty()) {
|
&& !analysis.semanticHighlights().isEmpty()) {
|
||||||
return new EditorDocumentHighlightingResult(
|
return new EditorDocumentHighlightingResult(
|
||||||
EditorDocumentHighlightOwner.LSP,
|
EditorDocumentHighlightOwner.LSP,
|
||||||
|
|||||||
@ -10,15 +10,21 @@ import java.util.Objects;
|
|||||||
record EditorDocumentPresentation(
|
record EditorDocumentPresentation(
|
||||||
String styleKey,
|
String styleKey,
|
||||||
List<String> stylesheetUrls,
|
List<String> stylesheetUrls,
|
||||||
|
List<String> semanticKeys,
|
||||||
EditorDocumentSyntaxHighlighting syntaxHighlighting) {
|
EditorDocumentSyntaxHighlighting syntaxHighlighting) {
|
||||||
|
|
||||||
EditorDocumentPresentation {
|
EditorDocumentPresentation {
|
||||||
styleKey = Objects.requireNonNull(styleKey, "styleKey");
|
styleKey = Objects.requireNonNull(styleKey, "styleKey");
|
||||||
stylesheetUrls = List.copyOf(Objects.requireNonNull(stylesheetUrls, "stylesheetUrls"));
|
stylesheetUrls = List.copyOf(Objects.requireNonNull(stylesheetUrls, "stylesheetUrls"));
|
||||||
|
semanticKeys = List.copyOf(Objects.requireNonNull(semanticKeys, "semanticKeys"));
|
||||||
syntaxHighlighting = Objects.requireNonNull(syntaxHighlighting, "syntaxHighlighting");
|
syntaxHighlighting = Objects.requireNonNull(syntaxHighlighting, "syntaxHighlighting");
|
||||||
}
|
}
|
||||||
|
|
||||||
StyleSpans<Collection<String>> highlight(final String content) {
|
StyleSpans<Collection<String>> highlight(final String content) {
|
||||||
return syntaxHighlighting.highlight(content);
|
return syntaxHighlighting.highlight(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean supportsSemanticHighlighting() {
|
||||||
|
return !semanticKeys.isEmpty() && !stylesheetUrls.isEmpty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,36 +1,47 @@
|
|||||||
package p.studio.workspaces.editor;
|
package p.studio.workspaces.editor;
|
||||||
|
|
||||||
import p.studio.compiler.FrontendRegistryService;
|
import p.studio.compiler.FrontendRegistryService;
|
||||||
|
import p.studio.lsp.dtos.LspSemanticPresentationDTO;
|
||||||
import p.studio.vfs.messages.VfsDocumentTypeIds;
|
import p.studio.vfs.messages.VfsDocumentTypeIds;
|
||||||
import p.studio.workspaces.editor.syntaxhighlight.EditorDocumentSyntaxHighlighting;
|
import p.studio.workspaces.editor.syntaxhighlight.EditorDocumentSyntaxHighlighting;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
final class EditorDocumentPresentationRegistry {
|
final class EditorDocumentPresentationRegistry {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(EditorDocumentPresentationRegistry.class.getName());
|
||||||
private static final EditorDocumentPresentation TEXT_PRESENTATION = new EditorDocumentPresentation(
|
private static final EditorDocumentPresentation TEXT_PRESENTATION = new EditorDocumentPresentation(
|
||||||
"text",
|
"text",
|
||||||
java.util.List.of(),
|
java.util.List.of(),
|
||||||
|
java.util.List.of(),
|
||||||
EditorDocumentSyntaxHighlighting.plainText());
|
EditorDocumentSyntaxHighlighting.plainText());
|
||||||
private static final EditorDocumentPresentation JSON_PRESENTATION = new EditorDocumentPresentation(
|
private static final EditorDocumentPresentation JSON_PRESENTATION = new EditorDocumentPresentation(
|
||||||
"json",
|
"json",
|
||||||
java.util.List.of(stylesheet("presentations/json.css")),
|
java.util.List.of(stylesheet("presentations/json.css")),
|
||||||
|
java.util.List.of(),
|
||||||
EditorDocumentSyntaxHighlighting.json());
|
EditorDocumentSyntaxHighlighting.json());
|
||||||
private static final EditorDocumentPresentation BASH_PRESENTATION = new EditorDocumentPresentation(
|
private static final EditorDocumentPresentation BASH_PRESENTATION = new EditorDocumentPresentation(
|
||||||
"bash",
|
"bash",
|
||||||
java.util.List.of(stylesheet("presentations/bash.css")),
|
java.util.List.of(stylesheet("presentations/bash.css")),
|
||||||
|
java.util.List.of(),
|
||||||
EditorDocumentSyntaxHighlighting.bash());
|
EditorDocumentSyntaxHighlighting.bash());
|
||||||
private static final EditorDocumentPresentation FRONTEND_PRESENTATION = new EditorDocumentPresentation(
|
|
||||||
"fe",
|
|
||||||
java.util.List.of(stylesheet("presentations/fe.css")),
|
|
||||||
EditorDocumentSyntaxHighlighting.plainText());
|
|
||||||
|
|
||||||
EditorDocumentPresentation resolve(final String typeId) {
|
EditorDocumentPresentation resolve(final String typeId) {
|
||||||
|
return resolve(typeId, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorDocumentPresentation resolve(
|
||||||
|
final String typeId,
|
||||||
|
final LspSemanticPresentationDTO semanticPresentation) {
|
||||||
final String normalizedTypeId = normalize(typeId);
|
final String normalizedTypeId = normalize(typeId);
|
||||||
if (normalizedTypeId.isBlank()) {
|
if (normalizedTypeId.isBlank()) {
|
||||||
return TEXT_PRESENTATION;
|
return TEXT_PRESENTATION;
|
||||||
}
|
}
|
||||||
if (FrontendRegistryService.getFrontendSpec(normalizedTypeId).isPresent()) {
|
if (FrontendRegistryService.getFrontendSpec(normalizedTypeId).isPresent()) {
|
||||||
return FRONTEND_PRESENTATION;
|
return frontendPresentation(normalizedTypeId, semanticPresentation);
|
||||||
}
|
}
|
||||||
if (VfsDocumentTypeIds.JSON.equals(normalizedTypeId)) {
|
if (VfsDocumentTypeIds.JSON.equals(normalizedTypeId)) {
|
||||||
return JSON_PRESENTATION;
|
return JSON_PRESENTATION;
|
||||||
@ -41,6 +52,26 @@ final class EditorDocumentPresentationRegistry {
|
|||||||
return TEXT_PRESENTATION;
|
return TEXT_PRESENTATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private EditorDocumentPresentation frontendPresentation(
|
||||||
|
final String normalizedTypeId,
|
||||||
|
final LspSemanticPresentationDTO semanticPresentation) {
|
||||||
|
if (semanticPresentation == null) {
|
||||||
|
return new EditorDocumentPresentation(
|
||||||
|
normalizedTypeId,
|
||||||
|
java.util.List.of(),
|
||||||
|
java.util.List.of(),
|
||||||
|
EditorDocumentSyntaxHighlighting.plainText());
|
||||||
|
}
|
||||||
|
return new EditorDocumentPresentation(
|
||||||
|
normalizedTypeId,
|
||||||
|
semanticPresentation.resources().stream()
|
||||||
|
.map(EditorDocumentPresentationRegistry::resourceStylesheet)
|
||||||
|
.flatMap(Optional::stream)
|
||||||
|
.toList(),
|
||||||
|
semanticPresentation.semanticKeys(),
|
||||||
|
EditorDocumentSyntaxHighlighting.plainText());
|
||||||
|
}
|
||||||
|
|
||||||
private String normalize(final String typeId) {
|
private String normalize(final String typeId) {
|
||||||
return typeId == null ? "" : typeId.trim().toLowerCase(Locale.ROOT);
|
return typeId == null ? "" : typeId.trim().toLowerCase(Locale.ROOT);
|
||||||
}
|
}
|
||||||
@ -51,4 +82,22 @@ final class EditorDocumentPresentationRegistry {
|
|||||||
"missing editor presentation stylesheet: " + relativePath)
|
"missing editor presentation stylesheet: " + relativePath)
|
||||||
.toExternalForm();
|
.toExternalForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Optional<String> resourceStylesheet(final String resourcePath) {
|
||||||
|
final String normalizedPath = normalizeResourcePath(resourcePath);
|
||||||
|
final URL resource = EditorDocumentPresentationRegistry.class.getResource(normalizedPath);
|
||||||
|
if (resource == null) {
|
||||||
|
LOGGER.fine("missing frontend semantic presentation resource: " + resourcePath);
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
return Optional.of(resource.toExternalForm());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String normalizeResourcePath(final String resourcePath) {
|
||||||
|
final String normalized = Objects.requireNonNull(resourcePath, "resourcePath").trim();
|
||||||
|
if (normalized.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("resourcePath cannot be blank");
|
||||||
|
}
|
||||||
|
return normalized.startsWith("/") ? normalized : "/" + normalized;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -124,10 +124,12 @@ public final class EditorWorkspace extends Workspace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final var fileBuffer = activeFile.orElseThrow();
|
final var fileBuffer = activeFile.orElseThrow();
|
||||||
final EditorDocumentPresentation presentation = presentationRegistry.resolve(fileBuffer.typeId());
|
|
||||||
final LspAnalyzeDocumentResult analysis = fileBuffer.frontendDocument()
|
final LspAnalyzeDocumentResult analysis = fileBuffer.frontendDocument()
|
||||||
? prometeuLspService.analyzeDocument(new LspAnalyzeDocumentRequest(fileBuffer.path()))
|
? prometeuLspService.analyzeDocument(new LspAnalyzeDocumentRequest(fileBuffer.path()))
|
||||||
: null;
|
: null;
|
||||||
|
final EditorDocumentPresentation presentation = presentationRegistry.resolve(
|
||||||
|
fileBuffer.typeId(),
|
||||||
|
analysis == null ? null : analysis.semanticPresentation());
|
||||||
final EditorDocumentHighlightingResult highlighting = EditorDocumentHighlightingRouter.route(
|
final EditorDocumentHighlightingResult highlighting = EditorDocumentHighlightingRouter.route(
|
||||||
fileBuffer,
|
fileBuffer,
|
||||||
presentation,
|
presentation,
|
||||||
|
|||||||
@ -28,7 +28,7 @@ public final class EditorDocumentSemanticHighlighting {
|
|||||||
builder.add(Collections.emptyList(), start - cursor);
|
builder.add(Collections.emptyList(), start - cursor);
|
||||||
}
|
}
|
||||||
if (end > start) {
|
if (end > start) {
|
||||||
builder.add(List.of("editor-syntax-" + highlight.semanticKey()), end - start);
|
builder.add(List.of("editor-semantic-" + highlight.semanticKey()), end - start);
|
||||||
cursor = end;
|
cursor = end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -708,10 +708,6 @@
|
|||||||
-fx-fill: #eef3f8;
|
-fx-fill: #eef3f8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-workspace-code-area-type-fe .text {
|
|
||||||
-fx-fill: #f2f6fb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-workspace-command-bar {
|
.editor-workspace-command-bar {
|
||||||
-fx-padding: 10 12 0 12;
|
-fx-padding: 10 12 0 12;
|
||||||
-fx-alignment: center-left;
|
-fx-alignment: center-left;
|
||||||
@ -880,12 +876,6 @@
|
|||||||
-fx-text-fill: #c5d2de;
|
-fx-text-fill: #c5d2de;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-workspace-status-chip-type-fe {
|
|
||||||
-fx-background-color: #271a35;
|
|
||||||
-fx-border-color: #8d67c7;
|
|
||||||
-fx-text-fill: #f3ecff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-workspace-status-chip-position {
|
.editor-workspace-status-chip-position {
|
||||||
-fx-min-width: 44;
|
-fx-min-width: 44;
|
||||||
-fx-pref-width: 44;
|
-fx-pref-width: 44;
|
||||||
|
|||||||
@ -1,61 +0,0 @@
|
|||||||
.editor-workspace-code-area-type-fe {
|
|
||||||
-fx-highlight-fill: #1b3244;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-workspace-code-area-type-fe .text {
|
|
||||||
-fx-fill: #edf4fb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-workspace-code-area-type-fe .lineno {
|
|
||||||
-fx-text-fill: #71859a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-workspace-code-area-type-fe .text.editor-syntax-fe-keyword {
|
|
||||||
-fx-fill: #8dc7ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-workspace-code-area-type-fe .text.editor-syntax-fe-callable {
|
|
||||||
-fx-fill: #f0cb79;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-workspace-code-area-type-fe .text.editor-syntax-fe-type {
|
|
||||||
-fx-fill: #9ddba8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-workspace-code-area-type-fe .text.editor-syntax-fe-binding {
|
|
||||||
-fx-fill: #ffb1c8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-workspace-code-area-type-fe .text.editor-syntax-fe-string {
|
|
||||||
-fx-fill: #e2c48c;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-workspace-code-area-type-fe .text.editor-syntax-fe-number {
|
|
||||||
-fx-fill: #c4e58a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-workspace-code-area-type-fe .text.editor-syntax-fe-comment {
|
|
||||||
-fx-fill: #6f8192;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-workspace-code-area-type-fe .text.editor-syntax-fe-literal {
|
|
||||||
-fx-fill: #c8a2ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-workspace-code-area-type-fe .text.editor-syntax-fe-operator {
|
|
||||||
-fx-fill: #dbe6f1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-workspace-code-area-type-fe .text.editor-syntax-fe-punctuation {
|
|
||||||
-fx-fill: #adc1d4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-workspace-code-area-type-fe .text.editor-syntax-fe-identifier {
|
|
||||||
-fx-fill: #edf4fb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-workspace-status-chip-type-fe {
|
|
||||||
-fx-background-color: #152432;
|
|
||||||
-fx-border-color: #4d8db9;
|
|
||||||
-fx-text-fill: #e8f5ff;
|
|
||||||
}
|
|
||||||
@ -12,6 +12,7 @@ import java.nio.file.Path;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
final class EditorDocumentHighlightingRouterTest {
|
final class EditorDocumentHighlightingRouterTest {
|
||||||
@Test
|
@Test
|
||||||
@ -29,18 +30,21 @@ final class EditorDocumentHighlightingRouterTest {
|
|||||||
|
|
||||||
final LspAnalyzeDocumentResult analysis = new LspAnalyzeDocumentResult(
|
final LspAnalyzeDocumentResult analysis = new LspAnalyzeDocumentResult(
|
||||||
new LspSessionStateDTO(true, List.of("highlight")),
|
new LspSessionStateDTO(true, List.of("highlight")),
|
||||||
new LspSemanticPresentationDTO(List.of(), List.of()),
|
new LspSemanticPresentationDTO(
|
||||||
|
List.of("pbs-keyword"),
|
||||||
|
List.of("/themes/pbs/semantic-highlighting.css")),
|
||||||
List.of(),
|
List.of(),
|
||||||
List.of(new LspHighlightSpanDTO(new LspRangeDTO(0, 2), "fe-keyword")),
|
List.of(new LspHighlightSpanDTO(new LspRangeDTO(0, 2), "pbs-keyword")),
|
||||||
List.of(),
|
List.of(),
|
||||||
List.of());
|
List.of());
|
||||||
|
|
||||||
final EditorDocumentHighlightingResult result = EditorDocumentHighlightingRouter.route(
|
final EditorDocumentHighlightingResult result = EditorDocumentHighlightingRouter.route(
|
||||||
fileBuffer,
|
fileBuffer,
|
||||||
registry.resolve("pbs"),
|
registry.resolve("pbs", analysis.semanticPresentation()),
|
||||||
analysis);
|
analysis);
|
||||||
|
|
||||||
assertEquals(EditorDocumentHighlightOwner.LSP, result.owner());
|
assertEquals(EditorDocumentHighlightOwner.LSP, result.owner());
|
||||||
|
assertEquals(List.of("editor-semantic-pbs-keyword"), List.copyOf(result.styleSpans().getStyleSpan(0).getStyle()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -71,4 +75,36 @@ final class EditorDocumentHighlightingRouterTest {
|
|||||||
|
|
||||||
assertEquals(EditorDocumentHighlightOwner.LOCAL, result.owner());
|
assertEquals(EditorDocumentHighlightOwner.LOCAL, result.owner());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void frontendDocumentsDegradeToLocalWhenSemanticPresentationResourcesAreUnavailable() {
|
||||||
|
final EditorDocumentPresentationRegistry registry = new EditorDocumentPresentationRegistry();
|
||||||
|
final EditorOpenFileBuffer fileBuffer = new EditorOpenFileBuffer(
|
||||||
|
Path.of("/tmp/example/src/main.pbs"),
|
||||||
|
"main.pbs",
|
||||||
|
"pbs",
|
||||||
|
"fn main() -> void {}",
|
||||||
|
"LF",
|
||||||
|
true,
|
||||||
|
VfsDocumentAccessMode.READ_ONLY,
|
||||||
|
false);
|
||||||
|
|
||||||
|
final LspAnalyzeDocumentResult analysis = new LspAnalyzeDocumentResult(
|
||||||
|
new LspSessionStateDTO(true, List.of("highlight")),
|
||||||
|
new LspSemanticPresentationDTO(
|
||||||
|
List.of("pbs-keyword"),
|
||||||
|
List.of("/themes/pbs/missing.css")),
|
||||||
|
List.of(),
|
||||||
|
List.of(new LspHighlightSpanDTO(new LspRangeDTO(0, 2), "pbs-keyword")),
|
||||||
|
List.of(),
|
||||||
|
List.of());
|
||||||
|
|
||||||
|
final EditorDocumentHighlightingResult result = EditorDocumentHighlightingRouter.route(
|
||||||
|
fileBuffer,
|
||||||
|
registry.resolve("pbs", analysis.semanticPresentation()),
|
||||||
|
analysis);
|
||||||
|
|
||||||
|
assertEquals(EditorDocumentHighlightOwner.LOCAL, result.owner());
|
||||||
|
assertTrue(result.styleSpans().getStyleSpan(0).getStyle().isEmpty());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,39 @@
|
|||||||
package p.studio.workspaces.editor;
|
package p.studio.workspaces.editor;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import p.studio.lsp.dtos.LspSemanticPresentationDTO;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
final class EditorDocumentPresentationRegistryTest {
|
final class EditorDocumentPresentationRegistryTest {
|
||||||
private final EditorDocumentPresentationRegistry registry = new EditorDocumentPresentationRegistry();
|
private final EditorDocumentPresentationRegistry registry = new EditorDocumentPresentationRegistry();
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void resolvesFrontendTypeIdsToFrontendPresentation() {
|
void resolvesFrontendTypeIdsToFrontendPresentation() {
|
||||||
assertEquals("fe", registry.resolve("pbs").styleKey());
|
final EditorDocumentPresentation presentation = registry.resolve(
|
||||||
|
"pbs",
|
||||||
|
new LspSemanticPresentationDTO(
|
||||||
|
java.util.List.of("pbs-keyword"),
|
||||||
|
java.util.List.of("/themes/pbs/semantic-highlighting.css")));
|
||||||
|
|
||||||
|
assertEquals("pbs", presentation.styleKey());
|
||||||
|
assertEquals(java.util.List.of("pbs-keyword"), presentation.semanticKeys());
|
||||||
|
assertEquals(1, presentation.stylesheetUrls().size());
|
||||||
|
assertTrue(presentation.stylesheetUrls().getFirst().endsWith("/themes/pbs/semantic-highlighting.css"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void missingFrontendResourcesDegradeToPlainFrontendPresentation() {
|
||||||
|
final EditorDocumentPresentation presentation = registry.resolve(
|
||||||
|
"pbs",
|
||||||
|
new LspSemanticPresentationDTO(
|
||||||
|
java.util.List.of("pbs-keyword"),
|
||||||
|
java.util.List.of("/themes/pbs/missing.css")));
|
||||||
|
|
||||||
|
assertEquals("pbs", presentation.styleKey());
|
||||||
|
assertEquals(java.util.List.of("pbs-keyword"), presentation.semanticKeys());
|
||||||
|
assertTrue(presentation.stylesheetUrls().isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user