Frontend Visual Theme Spec and Retirement of Host-Consumed Semantic CSS
This commit is contained in:
parent
fb13e166f1
commit
10fd7f6111
@ -12,34 +12,34 @@ public class PBSFrontendThemes {
|
||||
"PBS Default",
|
||||
new FrontendEditorPaletteSpec(
|
||||
"#d9e2ec",
|
||||
"#2d4f6b",
|
||||
"#2d4f6b",
|
||||
"#6f8193",
|
||||
"#2c2140",
|
||||
"#a47dff",
|
||||
"#efe6ff"),
|
||||
"#2f3f5b",
|
||||
"#23314a",
|
||||
"#6b7f99",
|
||||
"#241f38",
|
||||
"#b392f0",
|
||||
"#f5efff"),
|
||||
List.of(
|
||||
new FrontendTokenStyleSpec("pbs-comment", "#c090b0", true, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-string", "#00c088", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-number", "#ff90b0", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-literal", "#4fc1ff", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-lifecycle", "#ef50c0", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-keyword", "#569cd6", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-operator", "#d4d4d4", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-punctuation", "#d4d4d4", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-function", "#f2c14e", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-method", "#f2c14e", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-constructor", "#ecdcaa", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-struct", "#4ec9b0", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-contract", "#78dce8", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-host", "#b7a2fa", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-builtin-type", "#8be9fd", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-service", "#b7a2fa", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-error", "#ff5b5b", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-enum", "#56cfe1", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-callback", "#b7a2fa", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-global", "#f790fc", true, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-const", "#f78c6c", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-implements", "#a1c181", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-comment", "#8b949e", true, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-string", "#7ee787", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-number", "#ffa657", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-literal", "#79c0ff", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-lifecycle", "#ff7b72", false, true, false),
|
||||
new FrontendTokenStyleSpec("pbs-keyword", "#d2a8ff", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-operator", "#c9d1d9", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-punctuation", "#8b949e", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-function", "#ffa657", false, true, false),
|
||||
new FrontendTokenStyleSpec("pbs-method", "#ffd580", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-constructor", "#e3b341", false, true, false),
|
||||
new FrontendTokenStyleSpec("pbs-struct", "#56d4dd", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-contract", "#79c0ff", false, false, true),
|
||||
new FrontendTokenStyleSpec("pbs-host", "#c297ff", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-builtin-type", "#7ee787", true, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-service", "#c297ff", false, true, false),
|
||||
new FrontendTokenStyleSpec("pbs-error", "#ff7b72", false, false, true),
|
||||
new FrontendTokenStyleSpec("pbs-enum", "#56d4dd", false, true, false),
|
||||
new FrontendTokenStyleSpec("pbs-callback", "#ffb3e6", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-global", "#f778ba", true, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-const", "#ffab70", false, true, false),
|
||||
new FrontendTokenStyleSpec("pbs-implements", "#a5d6ff", false, false, false),
|
||||
new FrontendTokenStyleSpec("pbs-identifier", "#d4d4d4", false, false, false)));
|
||||
}
|
||||
|
||||
@ -51,12 +51,13 @@ public enum PbsSemanticKind {
|
||||
case COMMENT -> COMMENT;
|
||||
case STRING_LITERAL -> STRING;
|
||||
case INT_LITERAL, FLOAT_LITERAL, BOUNDED_LITERAL -> NUMBER;
|
||||
case TRUE, FALSE, NONE -> LITERAL;
|
||||
case TRUE, FALSE, NONE, SOME, OK, ERR -> LITERAL;
|
||||
case VOID, OPTIONAL, RESULT -> BUILTIN_TYPE;
|
||||
case IMPORT, FROM, AS, SERVICE, HOST, FN, APPLY, BIND, NEW, IMPLEMENTS, USING, CTOR,
|
||||
DECLARE, LET, CONST, GLOBAL, STRUCT, CONTRACT, ERROR, ENUM, CALLBACK, BUILTIN,
|
||||
SELF, THIS, PUB, MUT, MOD, TYPE, IF, ELSE, SWITCH, DEFAULT, FOR, UNTIL, STEP,
|
||||
WHILE, BREAK, CONTINUE, RETURN, VOID, OPTIONAL, RESULT, SOME, OK, ERR, HANDLE,
|
||||
AND, OR, NOT, SPAWN, YIELD, SLEEP, MATCH -> KEYWORD;
|
||||
WHILE, BREAK, CONTINUE, RETURN, HANDLE, AND, OR, NOT, SPAWN, YIELD, SLEEP,
|
||||
MATCH -> KEYWORD;
|
||||
case PLUS, MINUS, STAR, SLASH, PERCENT, BANG, PLUS_EQUAL, MINUS_EQUAL, STAR_EQUAL,
|
||||
SLASH_EQUAL, PERCENT_EQUAL, BANG_EQUAL, EQUAL, EQUAL_EQUAL, LESS, LESS_EQUAL,
|
||||
GREATER, GREATER_EQUAL, AND_AND, OR_OR, ARROW, QUESTION -> OPERATOR;
|
||||
|
||||
@ -20,7 +20,8 @@ final class PbsSemanticPresentationContractTest {
|
||||
assertEquals(1, presentation.themes().size());
|
||||
assertEquals("PBS Default", presentation.defaultTheme().displayName());
|
||||
assertEquals("#d9e2ec", presentation.defaultTheme().editorPalette().baseForeground());
|
||||
assertEquals("#569cd6", presentation.defaultTheme().requireTokenStyle("pbs-keyword").foreground());
|
||||
assertEquals("#d2a8ff", presentation.defaultTheme().requireTokenStyle("pbs-keyword").foreground());
|
||||
assertTrue(presentation.defaultTheme().requireTokenStyle("pbs-builtin-type").italic());
|
||||
assertTrue(presentation.defaultTheme().requireTokenStyle("pbs-comment").italic());
|
||||
assertEquals(PBSFrontendHostProjections.VSCODE_HOST_ID, presentation.requireHostProjection("vscode").hostId());
|
||||
}
|
||||
|
||||
@ -8,12 +8,6 @@ public record FrontendSemanticPresentationSpec(
|
||||
String defaultThemeId,
|
||||
List<FrontendHostProjectionSpec> hostProjections) {
|
||||
|
||||
public FrontendSemanticPresentationSpec(
|
||||
final List<FrontendVisualThemeSpec> themes,
|
||||
final String defaultThemeId) {
|
||||
this(themes, defaultThemeId, List.of());
|
||||
}
|
||||
|
||||
public FrontendSemanticPresentationSpec {
|
||||
themes = List.copyOf(Objects.requireNonNull(themes, "themes"));
|
||||
defaultThemeId = Objects.requireNonNull(defaultThemeId, "defaultThemeId").trim();
|
||||
|
||||
@ -14,6 +14,7 @@ import p.studio.compiler.models.FrontendVisualThemeSpec;
|
||||
import p.studio.compiler.pbs.PbsSemanticKind;
|
||||
import p.studio.compiler.pbs.lexer.PbsLexer;
|
||||
import p.studio.compiler.pbs.lexer.PbsToken;
|
||||
import p.studio.compiler.pbs.lexer.PbsTokenKind;
|
||||
import p.studio.compiler.source.identifiers.FileId;
|
||||
import p.studio.compiler.source.diagnostics.DiagnosticSink;
|
||||
import p.studio.compiler.utilities.SourceProviderFactory;
|
||||
@ -29,8 +30,11 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public record CompilerLanguageServiceBridge() implements LanguageServiceBridge {
|
||||
private static final Set<String> BUILTIN_TYPE_NAMES = Set.of("int", "float", "bool", "string", "i32", "i64", "f32", "f64");
|
||||
|
||||
|
||||
@Override
|
||||
public BaselineServerDescription describeServer(final LspProjectContext context) {
|
||||
@ -182,7 +186,97 @@ public record CompilerLanguageServiceBridge() implements LanguageServiceBridge {
|
||||
if (isLifecycleToken(tokens, index, token)) {
|
||||
return PbsSemanticKind.LIFECYCLE;
|
||||
}
|
||||
return PbsSemanticKind.IDENTIFIER;
|
||||
return classifyIdentifierToken(tokens, index, token);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private PbsSemanticKind classifyIdentifierToken(
|
||||
final ReadOnlyList<PbsToken> tokens,
|
||||
final int index,
|
||||
final PbsToken token) {
|
||||
final PbsTokenKind previousKind = previousSignificantKind(tokens, index);
|
||||
final PbsTokenKind nextKind = nextSignificantKind(tokens, index);
|
||||
|
||||
if (previousKind == PbsTokenKind.STRUCT) {
|
||||
return PbsSemanticKind.STRUCT;
|
||||
}
|
||||
if (previousKind == PbsTokenKind.CONTRACT) {
|
||||
return PbsSemanticKind.CONTRACT;
|
||||
}
|
||||
if (previousKind == PbsTokenKind.HOST) {
|
||||
return PbsSemanticKind.HOST;
|
||||
}
|
||||
if (previousKind == PbsTokenKind.SERVICE) {
|
||||
return PbsSemanticKind.SERVICE;
|
||||
}
|
||||
if (previousKind == PbsTokenKind.ENUM || previousKind == PbsTokenKind.ERROR) {
|
||||
return PbsSemanticKind.ENUM;
|
||||
}
|
||||
if (previousKind == PbsTokenKind.CALLBACK) {
|
||||
return PbsSemanticKind.CALLBACK;
|
||||
}
|
||||
if (previousKind == PbsTokenKind.GLOBAL) {
|
||||
return PbsSemanticKind.GLOBAL;
|
||||
}
|
||||
if (previousKind == PbsTokenKind.CONST) {
|
||||
return PbsSemanticKind.CONST;
|
||||
}
|
||||
if (previousKind == PbsTokenKind.CTOR || previousKind == PbsTokenKind.NEW) {
|
||||
return PbsSemanticKind.CONSTRUCTOR;
|
||||
}
|
||||
if (previousKind == PbsTokenKind.BUILTIN) {
|
||||
return PbsSemanticKind.BUILTIN_TYPE;
|
||||
}
|
||||
if (previousKind == PbsTokenKind.DOT && nextKind == PbsTokenKind.LEFT_PAREN) {
|
||||
return PbsSemanticKind.METHOD;
|
||||
}
|
||||
if (nextKind == PbsTokenKind.LEFT_PAREN) {
|
||||
return PbsSemanticKind.FUNCTION;
|
||||
}
|
||||
if (isTypeReferenceContext(previousKind, token.lexeme())) {
|
||||
return PbsSemanticKind.BUILTIN_TYPE;
|
||||
}
|
||||
return PbsSemanticKind.IDENTIFIER;
|
||||
}
|
||||
|
||||
private boolean isTypeReferenceContext(
|
||||
final PbsTokenKind previousKind,
|
||||
final String lexeme) {
|
||||
if (previousKind == null) {
|
||||
return false;
|
||||
}
|
||||
if (previousKind != PbsTokenKind.COLON
|
||||
&& previousKind != PbsTokenKind.ARROW
|
||||
&& previousKind != PbsTokenKind.AS
|
||||
&& previousKind != PbsTokenKind.IMPLEMENTS) {
|
||||
return false;
|
||||
}
|
||||
return BUILTIN_TYPE_NAMES.contains(lexeme);
|
||||
}
|
||||
|
||||
private PbsTokenKind previousSignificantKind(
|
||||
final ReadOnlyList<PbsToken> tokens,
|
||||
final int index) {
|
||||
for (int cursor = index - 1; cursor >= 0; cursor -= 1) {
|
||||
final PbsTokenKind kind = tokens.get(cursor).kind();
|
||||
if (kind == PbsTokenKind.COMMENT || kind == PbsTokenKind.EOF) {
|
||||
continue;
|
||||
}
|
||||
return kind;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private PbsTokenKind nextSignificantKind(
|
||||
final ReadOnlyList<PbsToken> tokens,
|
||||
final int index) {
|
||||
for (int cursor = index + 1; cursor < tokens.size(); cursor += 1) {
|
||||
final PbsTokenKind kind = tokens.get(cursor).kind();
|
||||
if (kind == PbsTokenKind.COMMENT || kind == PbsTokenKind.EOF) {
|
||||
continue;
|
||||
}
|
||||
return kind;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -46,14 +46,28 @@ class CompilerLanguageServiceBridgeTest {
|
||||
new LspProjectContext("main", "pbs", Path.of(".")),
|
||||
Path.of("demo.pbs").toUri().toString(),
|
||||
"""
|
||||
struct Vec2 {
|
||||
fn length() -> int {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> void {
|
||||
const answer = 42;
|
||||
const answer: int = 42;
|
||||
let value = new Vec2();
|
||||
value.length();
|
||||
}
|
||||
""");
|
||||
|
||||
assertTrue(semanticTokens.legend().contains("pbs-keyword"));
|
||||
assertTrue(semanticTokens.tokens().stream().anyMatch(token -> token.semanticKey().equals("pbs-keyword")));
|
||||
assertTrue(semanticTokens.tokens().stream().anyMatch(token -> token.semanticKey().equals("pbs-number")));
|
||||
assertTrue(semanticTokens.tokens().stream().anyMatch(token -> token.semanticKey().equals("pbs-struct")));
|
||||
assertTrue(semanticTokens.tokens().stream().anyMatch(token -> token.semanticKey().equals("pbs-function")));
|
||||
assertTrue(semanticTokens.tokens().stream().anyMatch(token -> token.semanticKey().equals("pbs-method")));
|
||||
assertTrue(semanticTokens.tokens().stream().anyMatch(token -> token.semanticKey().equals("pbs-const")));
|
||||
assertTrue(semanticTokens.tokens().stream().anyMatch(token -> token.semanticKey().equals("pbs-builtin-type")));
|
||||
assertTrue(semanticTokens.tokens().stream().anyMatch(token -> token.semanticKey().equals("pbs-constructor")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -74,7 +88,7 @@ class CompilerLanguageServiceBridgeTest {
|
||||
assertEquals("#d9e2ec", description.visualThemes().getFirst().editorPalette().baseForeground());
|
||||
assertTrue(description.visualThemes().getFirst().tokenStyles().stream()
|
||||
.anyMatch(tokenStyle -> tokenStyle.semanticKey().equals("pbs-keyword")
|
||||
&& tokenStyle.foreground().equals("#569cd6")));
|
||||
&& tokenStyle.foreground().equals("#d2a8ff")));
|
||||
}
|
||||
|
||||
private Path findRepoRoot(final Path start) {
|
||||
|
||||
141
test-projects/main/.vscode/settings.json
vendored
141
test-projects/main/.vscode/settings.json
vendored
@ -3,66 +3,117 @@
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"pbs-comment:pbs": {
|
||||
"foreground": "#c090b0",
|
||||
"foreground": "#8b949e",
|
||||
"italic": true
|
||||
},
|
||||
"pbs-string:pbs": "#00c088",
|
||||
"pbs-number:pbs": "#ff90b0",
|
||||
"pbs-literal:pbs": "#4fc1ff",
|
||||
"pbs-lifecycle:pbs": "#ef50c0",
|
||||
"pbs-keyword:pbs": "#569cd6",
|
||||
"pbs-operator:pbs": "#d4d4d4",
|
||||
"pbs-punctuation:pbs": "#d4d4d4",
|
||||
"pbs-function:pbs": "#f2c14e",
|
||||
"pbs-method:pbs": "#f2c14e",
|
||||
"pbs-constructor:pbs": "#ecdcaa",
|
||||
"pbs-struct:pbs": "#4ec9b0",
|
||||
"pbs-contract:pbs": "#78dce8",
|
||||
"pbs-host:pbs": "#b7a2fa",
|
||||
"pbs-builtin-type:pbs": "#8be9fd",
|
||||
"pbs-service:pbs": "#b7a2fa",
|
||||
"pbs-error:pbs": "#ff5b5b",
|
||||
"pbs-enum:pbs": "#56cfe1",
|
||||
"pbs-callback:pbs": "#b7a2fa",
|
||||
"pbs-string:pbs": "#7ee787",
|
||||
"pbs-number:pbs": "#ffa657",
|
||||
"pbs-literal:pbs": "#79c0ff",
|
||||
"pbs-lifecycle:pbs": {
|
||||
"foreground": "#ff7b72",
|
||||
"bold": true
|
||||
},
|
||||
"pbs-keyword:pbs": "#d2a8ff",
|
||||
"pbs-operator:pbs": "#c9d1d9",
|
||||
"pbs-punctuation:pbs": "#8b949e",
|
||||
"pbs-function:pbs": {
|
||||
"foreground": "#ffa657",
|
||||
"bold": true
|
||||
},
|
||||
"pbs-method:pbs": "#ffd580",
|
||||
"pbs-constructor:pbs": {
|
||||
"foreground": "#e3b341",
|
||||
"bold": true
|
||||
},
|
||||
"pbs-struct:pbs": "#56d4dd",
|
||||
"pbs-contract:pbs": {
|
||||
"foreground": "#79c0ff",
|
||||
"underline": true
|
||||
},
|
||||
"pbs-host:pbs": "#c297ff",
|
||||
"pbs-builtin-type:pbs": {
|
||||
"foreground": "#7ee787",
|
||||
"italic": true
|
||||
},
|
||||
"pbs-service:pbs": {
|
||||
"foreground": "#c297ff",
|
||||
"bold": true
|
||||
},
|
||||
"pbs-error:pbs": {
|
||||
"foreground": "#ff7b72",
|
||||
"underline": true
|
||||
},
|
||||
"pbs-enum:pbs": {
|
||||
"foreground": "#56d4dd",
|
||||
"bold": true
|
||||
},
|
||||
"pbs-callback:pbs": "#ffb3e6",
|
||||
"pbs-global:pbs": {
|
||||
"foreground": "#f790fc",
|
||||
"foreground": "#f778ba",
|
||||
"italic": true
|
||||
},
|
||||
"pbs-const:pbs": "#f78c6c",
|
||||
"pbs-implements:pbs": "#a1c181",
|
||||
"pbs-const:pbs": {
|
||||
"foreground": "#ffab70",
|
||||
"bold": true
|
||||
},
|
||||
"pbs-implements:pbs": "#a5d6ff",
|
||||
"pbs-identifier:pbs": "#d4d4d4",
|
||||
"comment:pbs": {
|
||||
"foreground": "#c090b0",
|
||||
"foreground": "#8b949e",
|
||||
"italic": true
|
||||
},
|
||||
"string:pbs": "#00c088",
|
||||
"number:pbs": "#ff90b0",
|
||||
"enumMember:pbs": "#4fc1ff",
|
||||
"variable:pbs": "#4fc1ff",
|
||||
"function.async:pbs": "#ef50c0",
|
||||
"variable.async:pbs": "#ef50c0",
|
||||
"keyword:pbs": "#569cd6",
|
||||
"operator:pbs": "#d4d4d4",
|
||||
"function:pbs": "#f2c14e",
|
||||
"method:pbs": "#f2c14e",
|
||||
"class.declaration:pbs": "#ecdcaa",
|
||||
"type.declaration:pbs": "#ecdcaa",
|
||||
"struct:pbs": "#4ec9b0",
|
||||
"type:pbs": "#4ec9b0",
|
||||
"interface:pbs": "#78dce8",
|
||||
"class.defaultLibrary:pbs": "#b7a2fa",
|
||||
"type.defaultLibrary:pbs": "#b7a2fa",
|
||||
"variable.defaultLibrary:pbs": "#8be9fd",
|
||||
"enum:pbs": "#ff5b5b",
|
||||
"string:pbs": "#7ee787",
|
||||
"number:pbs": "#ffa657",
|
||||
"enumMember:pbs": "#79c0ff",
|
||||
"variable:pbs": "#79c0ff",
|
||||
"function.async:pbs": {
|
||||
"foreground": "#ff7b72",
|
||||
"bold": true
|
||||
},
|
||||
"variable.async:pbs": {
|
||||
"foreground": "#ff7b72",
|
||||
"bold": true
|
||||
},
|
||||
"keyword:pbs": "#d2a8ff",
|
||||
"operator:pbs": "#c9d1d9",
|
||||
"function:pbs": {
|
||||
"foreground": "#ffa657",
|
||||
"bold": true
|
||||
},
|
||||
"method:pbs": "#ffd580",
|
||||
"class.declaration:pbs": {
|
||||
"foreground": "#e3b341",
|
||||
"bold": true
|
||||
},
|
||||
"type.declaration:pbs": {
|
||||
"foreground": "#e3b341",
|
||||
"bold": true
|
||||
},
|
||||
"struct:pbs": "#56d4dd",
|
||||
"type:pbs": "#56d4dd",
|
||||
"interface:pbs": {
|
||||
"foreground": "#79c0ff",
|
||||
"underline": true
|
||||
},
|
||||
"class.defaultLibrary:pbs": "#c297ff",
|
||||
"type.defaultLibrary:pbs": "#c297ff",
|
||||
"variable.defaultLibrary:pbs": {
|
||||
"foreground": "#7ee787",
|
||||
"italic": true
|
||||
},
|
||||
"enum:pbs": {
|
||||
"foreground": "#ff7b72",
|
||||
"underline": true
|
||||
},
|
||||
"variable.readonly:pbs": {
|
||||
"foreground": "#f790fc",
|
||||
"foreground": "#f778ba",
|
||||
"italic": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"workbench.colorCustomizations": {
|
||||
"editor.foreground": "#d9e2ec",
|
||||
"editor.selectionBackground": "#2d4f6b",
|
||||
"editorLineNumber.foreground": "#6f8193"
|
||||
"editor.selectionBackground": "#2f3f5b",
|
||||
"editorLineNumber.foreground": "#6b7f99"
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user