Highlight color adjustments
This commit is contained in:
parent
dfad621d05
commit
905d92afe7
@ -39,6 +39,7 @@ public final class PBSFrontendHostProjections {
|
|||||||
case HOST -> projection(HOST.semanticKey(), "class", "type", "defaultLibrary");
|
case HOST -> projection(HOST.semanticKey(), "class", "type", "defaultLibrary");
|
||||||
case BUILTIN_TYPE -> projection(BUILTIN_TYPE.semanticKey(), "type", "variable", "defaultLibrary");
|
case BUILTIN_TYPE -> projection(BUILTIN_TYPE.semanticKey(), "type", "variable", "defaultLibrary");
|
||||||
case SERVICE -> projection(SERVICE.semanticKey(), "class", "type", "defaultLibrary");
|
case SERVICE -> projection(SERVICE.semanticKey(), "class", "type", "defaultLibrary");
|
||||||
|
case ASSET -> projection(ASSET.semanticKey(), "variable", "string", "readonly");
|
||||||
case ERROR -> projection(ERROR.semanticKey(), "enum", "type");
|
case ERROR -> projection(ERROR.semanticKey(), "enum", "type");
|
||||||
case ENUM -> projection(ENUM.semanticKey(), "enum", "type");
|
case ENUM -> projection(ENUM.semanticKey(), "enum", "type");
|
||||||
case CALLBACK -> projection(CALLBACK.semanticKey(), "interface", "type");
|
case CALLBACK -> projection(CALLBACK.semanticKey(), "interface", "type");
|
||||||
|
|||||||
@ -20,21 +20,22 @@ public class PBSFrontendThemes {
|
|||||||
"#f5efff"),
|
"#f5efff"),
|
||||||
List.of(
|
List.of(
|
||||||
new FrontendTokenStyleSpec("pbs-comment", "#8b949e", true, false, false),
|
new FrontendTokenStyleSpec("pbs-comment", "#8b949e", true, false, false),
|
||||||
new FrontendTokenStyleSpec("pbs-string", "#7ee787", false, false, false),
|
new FrontendTokenStyleSpec("pbs-string", "#d8b86a", false, false, false),
|
||||||
new FrontendTokenStyleSpec("pbs-number", "#ffa657", false, false, false),
|
new FrontendTokenStyleSpec("pbs-number", "#ff8cc6", false, false, false),
|
||||||
new FrontendTokenStyleSpec("pbs-literal", "#79c0ff", false, false, false),
|
new FrontendTokenStyleSpec("pbs-literal", "#7fb8ff", false, false, false),
|
||||||
new FrontendTokenStyleSpec("pbs-lifecycle", "#ff7b72", false, true, false),
|
new FrontendTokenStyleSpec("pbs-lifecycle", "#ff7b72", false, true, false),
|
||||||
new FrontendTokenStyleSpec("pbs-keyword", "#d2a8ff", false, false, false),
|
new FrontendTokenStyleSpec("pbs-keyword", "#7fb8ff", false, false, false),
|
||||||
new FrontendTokenStyleSpec("pbs-operator", "#c9d1d9", false, false, false),
|
new FrontendTokenStyleSpec("pbs-operator", "#c9d1d9", false, false, false),
|
||||||
new FrontendTokenStyleSpec("pbs-punctuation", "#8b949e", false, false, false),
|
new FrontendTokenStyleSpec("pbs-punctuation", "#8b949e", false, false, false),
|
||||||
new FrontendTokenStyleSpec("pbs-function", "#ffa657", false, true, false),
|
new FrontendTokenStyleSpec("pbs-function", "#7ee787", false, true, false),
|
||||||
new FrontendTokenStyleSpec("pbs-method", "#ffd580", false, false, false),
|
new FrontendTokenStyleSpec("pbs-method", "#7ee787", false, false, false),
|
||||||
new FrontendTokenStyleSpec("pbs-constructor", "#e3b341", false, true, false),
|
new FrontendTokenStyleSpec("pbs-constructor", "#7ee787", false, true, false),
|
||||||
new FrontendTokenStyleSpec("pbs-struct", "#56d4dd", false, false, false),
|
new FrontendTokenStyleSpec("pbs-struct", "#56d4dd", true, false, false),
|
||||||
new FrontendTokenStyleSpec("pbs-contract", "#79c0ff", false, false, true),
|
new FrontendTokenStyleSpec("pbs-contract", "#79c0ff", false, false, true),
|
||||||
new FrontendTokenStyleSpec("pbs-host", "#c297ff", false, false, false),
|
new FrontendTokenStyleSpec("pbs-host", "#c297ff", false, false, false),
|
||||||
new FrontendTokenStyleSpec("pbs-builtin-type", "#7ee787", true, false, false),
|
new FrontendTokenStyleSpec("pbs-builtin-type", "#56d4dd", false, false, false),
|
||||||
new FrontendTokenStyleSpec("pbs-service", "#ff8e7a", false, true, false),
|
new FrontendTokenStyleSpec("pbs-service", "#ff8e7a", false, true, false),
|
||||||
|
new FrontendTokenStyleSpec("pbs-asset", "#c297ff", false, false, false),
|
||||||
new FrontendTokenStyleSpec("pbs-error", "#ff7b72", false, false, true),
|
new FrontendTokenStyleSpec("pbs-error", "#ff7b72", false, false, true),
|
||||||
new FrontendTokenStyleSpec("pbs-enum", "#56d4dd", false, true, false),
|
new FrontendTokenStyleSpec("pbs-enum", "#56d4dd", false, true, false),
|
||||||
new FrontendTokenStyleSpec("pbs-callback", "#ffb3e6", false, false, false),
|
new FrontendTokenStyleSpec("pbs-callback", "#ffb3e6", false, false, false),
|
||||||
|
|||||||
@ -2,33 +2,44 @@ package p.studio.compiler;
|
|||||||
|
|
||||||
import p.studio.compiler.models.FrontendSemanticToken;
|
import p.studio.compiler.models.FrontendSemanticToken;
|
||||||
import p.studio.compiler.models.FrontendSemanticTokenProvider;
|
import p.studio.compiler.models.FrontendSemanticTokenProvider;
|
||||||
|
import p.studio.compiler.pbs.ast.PbsAst;
|
||||||
import p.studio.compiler.pbs.PbsSemanticKind;
|
import p.studio.compiler.pbs.PbsSemanticKind;
|
||||||
import p.studio.compiler.pbs.lexer.PbsLexer;
|
import p.studio.compiler.pbs.lexer.PbsLexer;
|
||||||
import p.studio.compiler.pbs.lexer.PbsToken;
|
import p.studio.compiler.pbs.lexer.PbsToken;
|
||||||
import p.studio.compiler.pbs.lexer.PbsTokenKind;
|
import p.studio.compiler.pbs.lexer.PbsTokenKind;
|
||||||
|
import p.studio.compiler.pbs.parser.PbsBarrelParser;
|
||||||
|
import p.studio.compiler.pbs.parser.PbsParser;
|
||||||
|
import p.studio.compiler.pbs.stdlib.ResourceStdlibEnvironmentResolver;
|
||||||
|
import p.studio.compiler.pbs.stdlib.StdlibModuleSource;
|
||||||
import p.studio.compiler.source.diagnostics.DiagnosticSink;
|
import p.studio.compiler.source.diagnostics.DiagnosticSink;
|
||||||
import p.studio.compiler.source.identifiers.FileId;
|
import p.studio.compiler.source.identifiers.FileId;
|
||||||
import p.studio.utilities.structures.ReadOnlyList;
|
import p.studio.utilities.structures.ReadOnlyList;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.EnumMap;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public final class PBSSemanticTokenProvider implements FrontendSemanticTokenProvider {
|
public final class PBSSemanticTokenProvider implements FrontendSemanticTokenProvider {
|
||||||
private static final Set<String> BUILTIN_TYPE_NAMES = Set.of("int", "float", "bool", "string", "i32", "i64", "f32", "f64");
|
private static final Set<String> BUILTIN_TYPE_NAMES = Set.of("int", "float", "bool", "string", "i32", "i64", "f32", "f64");
|
||||||
|
private static final int DEFAULT_STDLIB_VERSION = 1;
|
||||||
|
private static final ResourceStdlibEnvironmentResolver STDLIB_RESOLVER = new ResourceStdlibEnvironmentResolver();
|
||||||
|
private static final Map<PbsTokenKind, PbsSemanticKind> DECLARATION_KINDS = declarationKinds();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<FrontendSemanticToken> tokenize(final String documentText) {
|
public List<FrontendSemanticToken> tokenize(final String documentText) {
|
||||||
final String effectiveText = documentText == null ? "" : documentText;
|
final String effectiveText = documentText == null ? "" : documentText;
|
||||||
final ReadOnlyList<PbsToken> tokens = PbsLexer.lex(effectiveText, FileId.none(), DiagnosticSink.empty());
|
final ReadOnlyList<PbsToken> tokens = PbsLexer.lex(effectiveText, FileId.none(), DiagnosticSink.empty());
|
||||||
final Map<String, PbsSemanticKind> declaredKindsByName = collectDeclaredKinds(tokens);
|
final Map<String, PbsSemanticKind> declaredKindsByName = collectDeclaredKinds(tokens);
|
||||||
|
final Set<Integer> assetReferenceTokenIndexes = collectAssetReferenceTokenIndexes(tokens);
|
||||||
final ArrayList<FrontendSemanticToken> semanticTokens = new ArrayList<>();
|
final ArrayList<FrontendSemanticToken> semanticTokens = new ArrayList<>();
|
||||||
|
|
||||||
for (int index = 0; index < tokens.size(); index += 1) {
|
for (int index = 0; index < tokens.size(); index += 1) {
|
||||||
final PbsToken token = tokens.get(index);
|
final PbsToken token = tokens.get(index);
|
||||||
final PbsSemanticKind semanticKind = classifyToken(tokens, index, declaredKindsByName);
|
final PbsSemanticKind semanticKind = classifyToken(tokens, index, declaredKindsByName, assetReferenceTokenIndexes);
|
||||||
if (semanticKind == null) {
|
if (semanticKind == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -41,13 +52,17 @@ public final class PBSSemanticTokenProvider implements FrontendSemanticTokenProv
|
|||||||
private PbsSemanticKind classifyToken(
|
private PbsSemanticKind classifyToken(
|
||||||
final ReadOnlyList<PbsToken> tokens,
|
final ReadOnlyList<PbsToken> tokens,
|
||||||
final int index,
|
final int index,
|
||||||
final Map<String, PbsSemanticKind> declaredKindsByName) {
|
final Map<String, PbsSemanticKind> declaredKindsByName,
|
||||||
|
final Set<Integer> assetReferenceTokenIndexes) {
|
||||||
final PbsToken token = tokens.get(index);
|
final PbsToken token = tokens.get(index);
|
||||||
final PbsSemanticKind lexicalKind = PbsSemanticKind.forToken(token);
|
final PbsSemanticKind lexicalKind = PbsSemanticKind.forToken(token);
|
||||||
if (lexicalKind != null) {
|
if (lexicalKind != null) {
|
||||||
return lexicalKind;
|
return lexicalKind;
|
||||||
}
|
}
|
||||||
if (token.kind() == PbsTokenKind.IDENTIFIER) {
|
if (token.kind() == PbsTokenKind.IDENTIFIER) {
|
||||||
|
if (assetReferenceTokenIndexes.contains(index)) {
|
||||||
|
return PbsSemanticKind.ASSET;
|
||||||
|
}
|
||||||
if (isLifecycleToken(tokens, index, token)) {
|
if (isLifecycleToken(tokens, index, token)) {
|
||||||
return PbsSemanticKind.LIFECYCLE;
|
return PbsSemanticKind.LIFECYCLE;
|
||||||
}
|
}
|
||||||
@ -63,6 +78,7 @@ public final class PBSSemanticTokenProvider implements FrontendSemanticTokenProv
|
|||||||
final Map<String, PbsSemanticKind> declaredKindsByName) {
|
final Map<String, PbsSemanticKind> declaredKindsByName) {
|
||||||
final PbsTokenKind previousKind = previousSignificantKind(tokens, index);
|
final PbsTokenKind previousKind = previousSignificantKind(tokens, index);
|
||||||
final PbsTokenKind nextKind = nextSignificantKind(tokens, index);
|
final PbsTokenKind nextKind = nextSignificantKind(tokens, index);
|
||||||
|
final boolean typeReferenceContext = isTypeReferenceContext(previousKind);
|
||||||
|
|
||||||
if (previousKind == PbsTokenKind.STRUCT) {
|
if (previousKind == PbsTokenKind.STRUCT) {
|
||||||
return PbsSemanticKind.STRUCT;
|
return PbsSemanticKind.STRUCT;
|
||||||
@ -101,7 +117,7 @@ public final class PBSSemanticTokenProvider implements FrontendSemanticTokenProv
|
|||||||
}
|
}
|
||||||
if (nextKind == PbsTokenKind.DOT
|
if (nextKind == PbsTokenKind.DOT
|
||||||
|| previousKind == PbsTokenKind.NEW
|
|| previousKind == PbsTokenKind.NEW
|
||||||
|| isTypeReferenceContext(previousKind, token.lexeme())) {
|
|| typeReferenceContext) {
|
||||||
return declaredKind;
|
return declaredKind;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,7 +127,7 @@ public final class PBSSemanticTokenProvider implements FrontendSemanticTokenProv
|
|||||||
if (nextKind == PbsTokenKind.LEFT_PAREN) {
|
if (nextKind == PbsTokenKind.LEFT_PAREN) {
|
||||||
return PbsSemanticKind.FUNCTION;
|
return PbsSemanticKind.FUNCTION;
|
||||||
}
|
}
|
||||||
if (isTypeReferenceContext(previousKind, token.lexeme())) {
|
if (typeReferenceContext && BUILTIN_TYPE_NAMES.contains(token.lexeme())) {
|
||||||
return PbsSemanticKind.BUILTIN_TYPE;
|
return PbsSemanticKind.BUILTIN_TYPE;
|
||||||
}
|
}
|
||||||
return PbsSemanticKind.IDENTIFIER;
|
return PbsSemanticKind.IDENTIFIER;
|
||||||
@ -131,28 +147,163 @@ public final class PBSSemanticTokenProvider implements FrontendSemanticTokenProv
|
|||||||
}
|
}
|
||||||
declaredKindsByName.put(nextToken.lexeme(), declarationKind);
|
declaredKindsByName.put(nextToken.lexeme(), declarationKind);
|
||||||
}
|
}
|
||||||
|
declaredKindsByName.putAll(collectStdlibImportedKinds(tokens));
|
||||||
return Map.copyOf(declaredKindsByName);
|
return Map.copyOf(declaredKindsByName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Set<Integer> collectAssetReferenceTokenIndexes(final ReadOnlyList<PbsToken> tokens) {
|
||||||
|
final Set<Integer> indexes = new HashSet<>();
|
||||||
|
for (int index = 0; index < tokens.size(); index += 1) {
|
||||||
|
final PbsToken token = tokens.get(index);
|
||||||
|
if (token.kind() != PbsTokenKind.IDENTIFIER || !"assets".equals(token.lexeme())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final Integer firstDotIndex = nextSignificantIndex(tokens, index);
|
||||||
|
if (firstDotIndex == null || tokens.get(firstDotIndex).kind() != PbsTokenKind.DOT) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
indexes.add(index);
|
||||||
|
Integer cursor = firstDotIndex;
|
||||||
|
while (cursor != null && tokens.get(cursor).kind() == PbsTokenKind.DOT) {
|
||||||
|
final Integer memberIndex = nextSignificantIndex(tokens, cursor);
|
||||||
|
if (memberIndex == null || tokens.get(memberIndex).kind() != PbsTokenKind.IDENTIFIER) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
indexes.add(memberIndex);
|
||||||
|
cursor = nextSignificantIndex(tokens, memberIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Set.copyOf(indexes);
|
||||||
|
}
|
||||||
|
|
||||||
private PbsSemanticKind declarationKind(final PbsTokenKind kind) {
|
private PbsSemanticKind declarationKind(final PbsTokenKind kind) {
|
||||||
return switch (kind) {
|
return DECLARATION_KINDS.get(kind);
|
||||||
case STRUCT -> PbsSemanticKind.STRUCT;
|
}
|
||||||
case CONTRACT -> PbsSemanticKind.CONTRACT;
|
|
||||||
case HOST -> PbsSemanticKind.HOST;
|
private Map<String, PbsSemanticKind> collectStdlibImportedKinds(final ReadOnlyList<PbsToken> tokens) {
|
||||||
case SERVICE -> PbsSemanticKind.SERVICE;
|
final DiagnosticSink diagnostics = DiagnosticSink.empty();
|
||||||
case ENUM, ERROR -> PbsSemanticKind.ENUM;
|
final PbsAst.File file = PbsParser.parse(tokens, FileId.none(), diagnostics);
|
||||||
case CALLBACK -> PbsSemanticKind.CALLBACK;
|
final Map<String, PbsSemanticKind> importedKindsByLocalName = new HashMap<>();
|
||||||
case GLOBAL -> PbsSemanticKind.GLOBAL;
|
for (final PbsAst.ImportDecl importDecl : file.imports()) {
|
||||||
case CONST -> PbsSemanticKind.CONST;
|
if (importDecl.items().isEmpty()) {
|
||||||
case CTOR -> PbsSemanticKind.CONSTRUCTOR;
|
continue;
|
||||||
case BUILTIN -> PbsSemanticKind.BUILTIN_TYPE;
|
}
|
||||||
default -> null;
|
final Map<String, PbsSemanticKind> exportedKinds = resolveStdlibExportKinds(importDecl.moduleRef());
|
||||||
|
if (exportedKinds.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (final Map.Entry<String, PbsSemanticKind> entry : exportedKinds.entrySet()) {
|
||||||
|
if (entry.getValue() == PbsSemanticKind.BUILTIN_TYPE) {
|
||||||
|
importedKindsByLocalName.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (final PbsAst.ImportItem item : importDecl.items()) {
|
||||||
|
final PbsSemanticKind semanticKind = exportedKinds.get(item.name());
|
||||||
|
if (semanticKind == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
importedKindsByLocalName.put(item.alias() == null ? item.name() : item.alias(), semanticKind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return importedKindsByLocalName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, PbsSemanticKind> resolveStdlibExportKinds(final PbsAst.ModuleRef moduleRef) {
|
||||||
|
final var stdlibEnvironment = STDLIB_RESOLVER.resolve(DEFAULT_STDLIB_VERSION);
|
||||||
|
return stdlibEnvironment.resolveModule(moduleRef.project(), moduleRef.pathSegments())
|
||||||
|
.map(this::parseStdlibVisibleKinds)
|
||||||
|
.orElseGet(Map::of);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, PbsSemanticKind> parseStdlibVisibleKinds(final StdlibModuleSource moduleSource) {
|
||||||
|
final Map<String, PbsSemanticKind> visibleKinds = new HashMap<>(parseBarrelExportKinds(moduleSource.barrelSource()));
|
||||||
|
for (final StdlibModuleSource.SourceFile sourceFile : moduleSource.sourceFiles()) {
|
||||||
|
visibleKinds.putAll(parseBuiltinTypeKinds(sourceFile.source()));
|
||||||
|
}
|
||||||
|
return visibleKinds;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, PbsSemanticKind> parseBarrelExportKinds(final String barrelSource) {
|
||||||
|
final ReadOnlyList<PbsToken> barrelTokens = PbsLexer.lex(barrelSource, FileId.none(), DiagnosticSink.empty());
|
||||||
|
final PbsAst.BarrelFile barrelFile = PbsBarrelParser.parse(barrelTokens, FileId.none(), DiagnosticSink.empty());
|
||||||
|
final Map<String, PbsSemanticKind> exportedKinds = new HashMap<>();
|
||||||
|
for (final PbsAst.BarrelItem item : barrelFile.items()) {
|
||||||
|
final PbsSemanticKind semanticKind = semanticKindForBarrelItem(item);
|
||||||
|
if (semanticKind == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (item instanceof PbsAst.BarrelStructItem structItem && structItem.visibility() == PbsAst.Visibility.PUB) {
|
||||||
|
exportedKinds.put(structItem.name(), semanticKind);
|
||||||
|
} else if (item instanceof PbsAst.BarrelContractItem contractItem && contractItem.visibility() == PbsAst.Visibility.PUB) {
|
||||||
|
exportedKinds.put(contractItem.name(), semanticKind);
|
||||||
|
} else if (item instanceof PbsAst.BarrelHostItem hostItem && hostItem.visibility() == PbsAst.Visibility.PUB) {
|
||||||
|
exportedKinds.put(hostItem.name(), semanticKind);
|
||||||
|
} else if (item instanceof PbsAst.BarrelErrorItem errorItem && errorItem.visibility() == PbsAst.Visibility.PUB) {
|
||||||
|
exportedKinds.put(errorItem.name(), semanticKind);
|
||||||
|
} else if (item instanceof PbsAst.BarrelEnumItem enumItem && enumItem.visibility() == PbsAst.Visibility.PUB) {
|
||||||
|
exportedKinds.put(enumItem.name(), semanticKind);
|
||||||
|
} else if (item instanceof PbsAst.BarrelServiceItem serviceItem && serviceItem.visibility() == PbsAst.Visibility.PUB) {
|
||||||
|
exportedKinds.put(serviceItem.name(), semanticKind);
|
||||||
|
} else if (item instanceof PbsAst.BarrelGlobalItem globalItem && globalItem.visibility() == PbsAst.Visibility.PUB) {
|
||||||
|
exportedKinds.put(globalItem.name(), semanticKind);
|
||||||
|
} else if (item instanceof PbsAst.BarrelConstItem constItem && constItem.visibility() == PbsAst.Visibility.PUB) {
|
||||||
|
exportedKinds.put(constItem.name(), semanticKind);
|
||||||
|
} else if (item instanceof PbsAst.BarrelCallbackItem callbackItem && callbackItem.visibility() == PbsAst.Visibility.PUB) {
|
||||||
|
exportedKinds.put(callbackItem.name(), semanticKind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return exportedKinds;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, PbsSemanticKind> parseBuiltinTypeKinds(final String source) {
|
||||||
|
final ReadOnlyList<PbsToken> sourceTokens = PbsLexer.lex(source, FileId.none(), DiagnosticSink.empty());
|
||||||
|
final PbsAst.File file = PbsParser.parse(
|
||||||
|
sourceTokens,
|
||||||
|
FileId.none(),
|
||||||
|
DiagnosticSink.empty(),
|
||||||
|
PbsParser.ParseMode.INTERFACE_MODULE);
|
||||||
|
final Map<String, PbsSemanticKind> builtinKinds = new HashMap<>();
|
||||||
|
for (final PbsAst.TopDecl topDecl : file.topDecls()) {
|
||||||
|
if (topDecl instanceof PbsAst.BuiltinTypeDecl builtinTypeDecl) {
|
||||||
|
builtinKinds.put(builtinTypeDecl.name(), PbsSemanticKind.BUILTIN_TYPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builtinKinds;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PbsSemanticKind semanticKindForBarrelItem(final PbsAst.BarrelItem item) {
|
||||||
|
return switch (item) {
|
||||||
|
case PbsAst.BarrelStructItem ignored -> PbsSemanticKind.STRUCT;
|
||||||
|
case PbsAst.BarrelContractItem ignored -> PbsSemanticKind.CONTRACT;
|
||||||
|
case PbsAst.BarrelHostItem ignored -> PbsSemanticKind.HOST;
|
||||||
|
case PbsAst.BarrelErrorItem ignored -> PbsSemanticKind.ENUM;
|
||||||
|
case PbsAst.BarrelEnumItem ignored -> PbsSemanticKind.ENUM;
|
||||||
|
case PbsAst.BarrelServiceItem ignored -> PbsSemanticKind.SERVICE;
|
||||||
|
case PbsAst.BarrelGlobalItem ignored -> PbsSemanticKind.GLOBAL;
|
||||||
|
case PbsAst.BarrelConstItem ignored -> PbsSemanticKind.CONST;
|
||||||
|
case PbsAst.BarrelCallbackItem ignored -> PbsSemanticKind.CALLBACK;
|
||||||
|
case PbsAst.BarrelFunctionItem ignored -> null;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isTypeReferenceContext(
|
private static Map<PbsTokenKind, PbsSemanticKind> declarationKinds() {
|
||||||
final PbsTokenKind previousKind,
|
final Map<PbsTokenKind, PbsSemanticKind> kinds = new EnumMap<>(PbsTokenKind.class);
|
||||||
final String lexeme) {
|
kinds.put(PbsTokenKind.STRUCT, PbsSemanticKind.STRUCT);
|
||||||
|
kinds.put(PbsTokenKind.CONTRACT, PbsSemanticKind.CONTRACT);
|
||||||
|
kinds.put(PbsTokenKind.HOST, PbsSemanticKind.HOST);
|
||||||
|
kinds.put(PbsTokenKind.SERVICE, PbsSemanticKind.SERVICE);
|
||||||
|
kinds.put(PbsTokenKind.ENUM, PbsSemanticKind.ENUM);
|
||||||
|
kinds.put(PbsTokenKind.ERROR, PbsSemanticKind.ENUM);
|
||||||
|
kinds.put(PbsTokenKind.CALLBACK, PbsSemanticKind.CALLBACK);
|
||||||
|
kinds.put(PbsTokenKind.GLOBAL, PbsSemanticKind.GLOBAL);
|
||||||
|
kinds.put(PbsTokenKind.CONST, PbsSemanticKind.CONST);
|
||||||
|
kinds.put(PbsTokenKind.CTOR, PbsSemanticKind.CONSTRUCTOR);
|
||||||
|
kinds.put(PbsTokenKind.BUILTIN, PbsSemanticKind.BUILTIN_TYPE);
|
||||||
|
return Map.copyOf(kinds);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isTypeReferenceContext(final PbsTokenKind previousKind) {
|
||||||
if (previousKind == null) {
|
if (previousKind == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -162,7 +313,7 @@ public final class PBSSemanticTokenProvider implements FrontendSemanticTokenProv
|
|||||||
&& previousKind != PbsTokenKind.IMPLEMENTS) {
|
&& previousKind != PbsTokenKind.IMPLEMENTS) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return BUILTIN_TYPE_NAMES.contains(lexeme);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PbsTokenKind previousSignificantKind(
|
private PbsTokenKind previousSignificantKind(
|
||||||
@ -181,12 +332,19 @@ public final class PBSSemanticTokenProvider implements FrontendSemanticTokenProv
|
|||||||
private PbsTokenKind nextSignificantKind(
|
private PbsTokenKind nextSignificantKind(
|
||||||
final ReadOnlyList<PbsToken> tokens,
|
final ReadOnlyList<PbsToken> tokens,
|
||||||
final int index) {
|
final int index) {
|
||||||
|
final Integer cursor = nextSignificantIndex(tokens, index);
|
||||||
|
return cursor == null ? null : tokens.get(cursor).kind();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer nextSignificantIndex(
|
||||||
|
final ReadOnlyList<PbsToken> tokens,
|
||||||
|
final int index) {
|
||||||
for (int cursor = index + 1; cursor < tokens.size(); cursor += 1) {
|
for (int cursor = index + 1; cursor < tokens.size(); cursor += 1) {
|
||||||
final PbsTokenKind kind = tokens.get(cursor).kind();
|
final PbsTokenKind kind = tokens.get(cursor).kind();
|
||||||
if (kind == PbsTokenKind.COMMENT || kind == PbsTokenKind.EOF) {
|
if (kind == PbsTokenKind.COMMENT || kind == PbsTokenKind.EOF) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
return kind;
|
return cursor;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@ public enum PbsSemanticKind {
|
|||||||
HOST("pbs-host"),
|
HOST("pbs-host"),
|
||||||
BUILTIN_TYPE("pbs-builtin-type"),
|
BUILTIN_TYPE("pbs-builtin-type"),
|
||||||
SERVICE("pbs-service"),
|
SERVICE("pbs-service"),
|
||||||
|
ASSET("pbs-asset"),
|
||||||
ERROR("pbs-error"),
|
ERROR("pbs-error"),
|
||||||
ENUM("pbs-enum"),
|
ENUM("pbs-enum"),
|
||||||
CALLBACK("pbs-callback"),
|
CALLBACK("pbs-callback"),
|
||||||
|
|||||||
@ -23,9 +23,19 @@ final class PbsSemanticPresentationContractTest {
|
|||||||
assertEquals(1, presentation.themes().size());
|
assertEquals(1, presentation.themes().size());
|
||||||
assertEquals("PBS Default", presentation.defaultTheme().displayName());
|
assertEquals("PBS Default", presentation.defaultTheme().displayName());
|
||||||
assertEquals("#d9e2ec", presentation.defaultTheme().editorPalette().baseForeground());
|
assertEquals("#d9e2ec", presentation.defaultTheme().editorPalette().baseForeground());
|
||||||
assertEquals("#d2a8ff", presentation.defaultTheme().requireTokenStyle("pbs-keyword").foreground());
|
assertEquals("#7fb8ff", presentation.defaultTheme().requireTokenStyle("pbs-keyword").foreground());
|
||||||
|
assertEquals("#d8b86a", presentation.defaultTheme().requireTokenStyle("pbs-string").foreground());
|
||||||
|
assertEquals("#ff8cc6", presentation.defaultTheme().requireTokenStyle("pbs-number").foreground());
|
||||||
|
assertEquals("#7fb8ff", presentation.defaultTheme().requireTokenStyle("pbs-literal").foreground());
|
||||||
|
assertEquals("#7ee787", presentation.defaultTheme().requireTokenStyle("pbs-function").foreground());
|
||||||
|
assertEquals("#7ee787", presentation.defaultTheme().requireTokenStyle("pbs-method").foreground());
|
||||||
|
assertEquals("#7ee787", presentation.defaultTheme().requireTokenStyle("pbs-constructor").foreground());
|
||||||
|
assertEquals("#56d4dd", presentation.defaultTheme().requireTokenStyle("pbs-struct").foreground());
|
||||||
|
assertTrue(presentation.defaultTheme().requireTokenStyle("pbs-struct").italic());
|
||||||
|
assertEquals("#56d4dd", presentation.defaultTheme().requireTokenStyle("pbs-builtin-type").foreground());
|
||||||
|
assertFalse(presentation.defaultTheme().requireTokenStyle("pbs-builtin-type").italic());
|
||||||
assertEquals("#ff8e7a", presentation.defaultTheme().requireTokenStyle("pbs-service").foreground());
|
assertEquals("#ff8e7a", presentation.defaultTheme().requireTokenStyle("pbs-service").foreground());
|
||||||
assertTrue(presentation.defaultTheme().requireTokenStyle("pbs-builtin-type").italic());
|
assertEquals("#c297ff", presentation.defaultTheme().requireTokenStyle("pbs-asset").foreground());
|
||||||
assertTrue(presentation.defaultTheme().requireTokenStyle("pbs-comment").italic());
|
assertTrue(presentation.defaultTheme().requireTokenStyle("pbs-comment").italic());
|
||||||
assertEquals(PBSFrontendHostProjections.VSCODE_HOST_ID, presentation.requireHostProjection("vscode").hostId());
|
assertEquals(PBSFrontendHostProjections.VSCODE_HOST_ID, presentation.requireHostProjection("vscode").hostId());
|
||||||
}
|
}
|
||||||
@ -50,6 +60,7 @@ final class PbsSemanticPresentationContractTest {
|
|||||||
vscodeProjection.tokenProjections().stream().map(tokenProjection -> tokenProjection.semanticKey()).toList());
|
vscodeProjection.tokenProjections().stream().map(tokenProjection -> tokenProjection.semanticKey()).toList());
|
||||||
assertEquals("keyword", vscodeProjection.requireProjection(PbsSemanticKind.KEYWORD.semanticKey()).hostTokenType());
|
assertEquals("keyword", vscodeProjection.requireProjection(PbsSemanticKind.KEYWORD.semanticKey()).hostTokenType());
|
||||||
assertEquals("type", vscodeProjection.requireProjection(PbsSemanticKind.STRUCT.semanticKey()).fallbackTokenType());
|
assertEquals("type", vscodeProjection.requireProjection(PbsSemanticKind.STRUCT.semanticKey()).fallbackTokenType());
|
||||||
|
assertEquals("variable", vscodeProjection.requireProjection(PbsSemanticKind.ASSET.semanticKey()).hostTokenType());
|
||||||
assertEquals(
|
assertEquals(
|
||||||
java.util.List.of("readonly"),
|
java.util.List.of("readonly"),
|
||||||
vscodeProjection.requireProjection(PbsSemanticKind.GLOBAL.semanticKey()).hostTokenModifiers());
|
vscodeProjection.requireProjection(PbsSemanticKind.GLOBAL.semanticKey()).hostTokenModifiers());
|
||||||
@ -73,7 +84,7 @@ final class PbsSemanticPresentationContractTest {
|
|||||||
}
|
}
|
||||||
""");
|
""");
|
||||||
|
|
||||||
assertTrue(semanticTokens.stream().anyMatch(token -> token.semanticKey().equals(PbsSemanticKind.STRUCT.semanticKey())));
|
assertTrue(semanticTokens.stream().anyMatch(token -> token.semanticKey().equals(PbsSemanticKind.BUILTIN_TYPE.semanticKey())));
|
||||||
assertTrue(semanticTokens.stream().anyMatch(token -> token.semanticKey().equals(PbsSemanticKind.FUNCTION.semanticKey())));
|
assertTrue(semanticTokens.stream().anyMatch(token -> token.semanticKey().equals(PbsSemanticKind.FUNCTION.semanticKey())));
|
||||||
assertTrue(semanticTokens.stream().anyMatch(token -> token.semanticKey().equals(PbsSemanticKind.CONST.semanticKey())));
|
assertTrue(semanticTokens.stream().anyMatch(token -> token.semanticKey().equals(PbsSemanticKind.CONST.semanticKey())));
|
||||||
assertTrue(semanticTokens.stream().anyMatch(token -> token.semanticKey().equals(PbsSemanticKind.BUILTIN_TYPE.semanticKey())));
|
assertTrue(semanticTokens.stream().anyMatch(token -> token.semanticKey().equals(PbsSemanticKind.BUILTIN_TYPE.semanticKey())));
|
||||||
@ -83,4 +94,53 @@ final class PbsSemanticPresentationContractTest {
|
|||||||
assertTrue(semanticTokens.stream().anyMatch(token -> token.semanticKey().equals(PbsSemanticKind.HOST.semanticKey())));
|
assertTrue(semanticTokens.stream().anyMatch(token -> token.semanticKey().equals(PbsSemanticKind.HOST.semanticKey())));
|
||||||
assertTrue(semanticTokens.stream().anyMatch(token -> token.semanticKey().equals(PbsSemanticKind.ENUM.semanticKey())));
|
assertTrue(semanticTokens.stream().anyMatch(token -> token.semanticKey().equals(PbsSemanticKind.ENUM.semanticKey())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldClassifyStdlibImportsUsingTheirPublishedBarrelKinds() {
|
||||||
|
final List<FrontendSemanticToken> semanticTokens = PBSDefinitions.PBS.getSemanticTokenProvider().tokenize("""
|
||||||
|
import { Log } from @sdk:log;
|
||||||
|
import { Composer } from @sdk:composer;
|
||||||
|
import { Color as Paint } from @core:color;
|
||||||
|
|
||||||
|
fn main() -> void {
|
||||||
|
Log.info("hello");
|
||||||
|
Composer.emit_sprite(0, 0, 0, 0, 0, 0, false, false, 0);
|
||||||
|
let paint: Paint;
|
||||||
|
}
|
||||||
|
""");
|
||||||
|
|
||||||
|
assertTrue(semanticTokens.stream().anyMatch(token -> token.semanticKey().equals(PbsSemanticKind.SERVICE.semanticKey())));
|
||||||
|
assertTrue(semanticTokens.stream().anyMatch(token -> token.semanticKey().equals(PbsSemanticKind.BUILTIN_TYPE.semanticKey())));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldClassifyAssetRootedAliasesUsingDedicatedSemanticKind() {
|
||||||
|
final List<FrontendSemanticToken> semanticTokens = PBSDefinitions.PBS.getSemanticTokenProvider().tokenize("""
|
||||||
|
import { Assets } from @sdk:asset;
|
||||||
|
|
||||||
|
fn main() -> void {
|
||||||
|
Assets.load(assets.ui.atlas2, 3);
|
||||||
|
}
|
||||||
|
""");
|
||||||
|
|
||||||
|
final long assetTokenCount = semanticTokens.stream()
|
||||||
|
.filter(token -> token.semanticKey().equals(PbsSemanticKind.ASSET.semanticKey()))
|
||||||
|
.count();
|
||||||
|
|
||||||
|
assertEquals(3, assetTokenCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldClassifyBuiltinTypesExposedByImportedStdlibModules() {
|
||||||
|
final List<FrontendSemanticToken> semanticTokens = PBSDefinitions.PBS.getSemanticTokenProvider().tokenize("""
|
||||||
|
import { Input } from @sdk:input;
|
||||||
|
|
||||||
|
fn main() -> void {
|
||||||
|
let touch : InputTouch = Input.touch();
|
||||||
|
let pad : InputPad = Input.pad();
|
||||||
|
}
|
||||||
|
""");
|
||||||
|
|
||||||
|
assertTrue(semanticTokens.stream().filter(token -> token.semanticKey().equals(PbsSemanticKind.BUILTIN_TYPE.semanticKey())).count() >= 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -80,6 +80,24 @@ class CompilerLanguageServiceBridgeTest {
|
|||||||
assertTrue(semanticTokens.tokens().stream().anyMatch(token -> token.semanticKey().equals("pbs-enum")));
|
assertTrue(semanticTokens.tokens().stream().anyMatch(token -> token.semanticKey().equals("pbs-enum")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void semanticTokensClassifyBuiltinTypesExposedByImportedStdlibModules() {
|
||||||
|
final CompilerLanguageServiceBridge bridge = new CompilerLanguageServiceBridge();
|
||||||
|
|
||||||
|
final var semanticTokens = bridge.semanticTokens(
|
||||||
|
new LspProjectContext("main", "pbs", Path.of(".")),
|
||||||
|
Path.of("demo.pbs").toUri().toString(),
|
||||||
|
"""
|
||||||
|
import { Input } from @sdk:input;
|
||||||
|
|
||||||
|
fn main() -> void {
|
||||||
|
let touch : InputTouch = Input.touch();
|
||||||
|
}
|
||||||
|
""");
|
||||||
|
|
||||||
|
assertTrue(semanticTokens.tokens().stream().anyMatch(token -> token.semanticKey().equals("pbs-builtin-type")));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void describeServerPublishesFrontendVisualThemes() {
|
void describeServerPublishesFrontendVisualThemes() {
|
||||||
final CompilerLanguageServiceBridge bridge = new CompilerLanguageServiceBridge();
|
final CompilerLanguageServiceBridge bridge = new CompilerLanguageServiceBridge();
|
||||||
@ -98,7 +116,7 @@ class CompilerLanguageServiceBridgeTest {
|
|||||||
assertEquals("#d9e2ec", description.visualThemes().getFirst().editorPalette().baseForeground());
|
assertEquals("#d9e2ec", description.visualThemes().getFirst().editorPalette().baseForeground());
|
||||||
assertTrue(description.visualThemes().getFirst().tokenStyles().stream()
|
assertTrue(description.visualThemes().getFirst().tokenStyles().stream()
|
||||||
.anyMatch(tokenStyle -> tokenStyle.semanticKey().equals("pbs-keyword")
|
.anyMatch(tokenStyle -> tokenStyle.semanticKey().equals("pbs-keyword")
|
||||||
&& tokenStyle.foreground().equals("#d2a8ff")));
|
&& tokenStyle.foreground().equals("#7fb8ff")));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Path findRepoRoot(final Path start) {
|
private Path findRepoRoot(final Path start) {
|
||||||
|
|||||||
64
test-projects/main/.vscode/settings.json
vendored
64
test-projects/main/.vscode/settings.json
vendored
@ -6,35 +6,35 @@
|
|||||||
"foreground": "#8b949e",
|
"foreground": "#8b949e",
|
||||||
"italic": true
|
"italic": true
|
||||||
},
|
},
|
||||||
"pbs-string:pbs": "#7ee787",
|
"pbs-string:pbs": "#d8b86a",
|
||||||
"pbs-number:pbs": "#ffa657",
|
"pbs-number:pbs": "#ff8cc6",
|
||||||
"pbs-literal:pbs": "#79c0ff",
|
"pbs-literal:pbs": "#7fb8ff",
|
||||||
"pbs-lifecycle:pbs": {
|
"pbs-lifecycle:pbs": {
|
||||||
"foreground": "#ff7b72",
|
"foreground": "#ff7b72",
|
||||||
"bold": true
|
"bold": true
|
||||||
},
|
},
|
||||||
"pbs-keyword:pbs": "#d2a8ff",
|
"pbs-keyword:pbs": "#7fb8ff",
|
||||||
"pbs-operator:pbs": "#c9d1d9",
|
"pbs-operator:pbs": "#c9d1d9",
|
||||||
"pbs-punctuation:pbs": "#8b949e",
|
"pbs-punctuation:pbs": "#8b949e",
|
||||||
"pbs-function:pbs": {
|
"pbs-function:pbs": {
|
||||||
"foreground": "#ffa657",
|
"foreground": "#7ee787",
|
||||||
"bold": true
|
"bold": true
|
||||||
},
|
},
|
||||||
"pbs-method:pbs": "#ffd580",
|
"pbs-method:pbs": "#7ee787",
|
||||||
"pbs-constructor:pbs": {
|
"pbs-constructor:pbs": {
|
||||||
"foreground": "#e3b341",
|
"foreground": "#7ee787",
|
||||||
"bold": true
|
"bold": true
|
||||||
},
|
},
|
||||||
"pbs-struct:pbs": "#56d4dd",
|
"pbs-struct:pbs": {
|
||||||
|
"foreground": "#56d4dd",
|
||||||
|
"italic": true
|
||||||
|
},
|
||||||
"pbs-contract:pbs": {
|
"pbs-contract:pbs": {
|
||||||
"foreground": "#79c0ff",
|
"foreground": "#79c0ff",
|
||||||
"underline": true
|
"underline": true
|
||||||
},
|
},
|
||||||
"pbs-host:pbs": "#c297ff",
|
"pbs-host:pbs": "#c297ff",
|
||||||
"pbs-builtin-type:pbs": {
|
"pbs-builtin-type:pbs": "#56d4dd",
|
||||||
"foreground": "#7ee787",
|
|
||||||
"italic": true
|
|
||||||
},
|
|
||||||
"pbs-service:pbs": {
|
"pbs-service:pbs": {
|
||||||
"foreground": "#ff8e7a",
|
"foreground": "#ff8e7a",
|
||||||
"bold": true
|
"bold": true
|
||||||
@ -62,10 +62,10 @@
|
|||||||
"foreground": "#8b949e",
|
"foreground": "#8b949e",
|
||||||
"italic": true
|
"italic": true
|
||||||
},
|
},
|
||||||
"string:pbs": "#7ee787",
|
"string:pbs": "#d8b86a",
|
||||||
"number:pbs": "#ffa657",
|
"number:pbs": "#ff8cc6",
|
||||||
"enumMember:pbs": "#79c0ff",
|
"enumMember:pbs": "#7fb8ff",
|
||||||
"variable:pbs": "#79c0ff",
|
"variable:pbs": "#7fb8ff",
|
||||||
"function.async:pbs": {
|
"function.async:pbs": {
|
||||||
"foreground": "#ff7b72",
|
"foreground": "#ff7b72",
|
||||||
"bold": true
|
"bold": true
|
||||||
@ -74,41 +74,43 @@
|
|||||||
"foreground": "#ff7b72",
|
"foreground": "#ff7b72",
|
||||||
"bold": true
|
"bold": true
|
||||||
},
|
},
|
||||||
"keyword:pbs": "#d2a8ff",
|
"keyword:pbs": "#7fb8ff",
|
||||||
"operator:pbs": "#c9d1d9",
|
"operator:pbs": "#c9d1d9",
|
||||||
"function:pbs": {
|
"function:pbs": {
|
||||||
"foreground": "#ffa657",
|
"foreground": "#7ee787",
|
||||||
"bold": true
|
"bold": true
|
||||||
},
|
},
|
||||||
"method:pbs": "#ffd580",
|
"method:pbs": "#7ee787",
|
||||||
"class.declaration:pbs": {
|
"class.declaration:pbs": {
|
||||||
"foreground": "#e3b341",
|
"foreground": "#7ee787",
|
||||||
"bold": true
|
"bold": true
|
||||||
},
|
},
|
||||||
"type.declaration:pbs": {
|
"type.declaration:pbs": {
|
||||||
"foreground": "#e3b341",
|
"foreground": "#7ee787",
|
||||||
"bold": true
|
"bold": true
|
||||||
},
|
},
|
||||||
"struct:pbs": "#56d4dd",
|
"struct:pbs": {
|
||||||
"type:pbs": "#56d4dd",
|
"foreground": "#56d4dd",
|
||||||
|
"italic": true
|
||||||
|
},
|
||||||
|
"type:pbs": {
|
||||||
|
"foreground": "#56d4dd",
|
||||||
|
"italic": true
|
||||||
|
},
|
||||||
"interface:pbs": {
|
"interface:pbs": {
|
||||||
"foreground": "#79c0ff",
|
"foreground": "#79c0ff",
|
||||||
"underline": true
|
"underline": true
|
||||||
},
|
},
|
||||||
"class.defaultLibrary:pbs": "#c297ff",
|
"class.defaultLibrary:pbs": "#c297ff",
|
||||||
"type.defaultLibrary:pbs": "#c297ff",
|
"type.defaultLibrary:pbs": "#c297ff",
|
||||||
"variable.defaultLibrary:pbs": {
|
"variable.defaultLibrary:pbs": "#56d4dd",
|
||||||
"foreground": "#7ee787",
|
|
||||||
"italic": true
|
|
||||||
},
|
|
||||||
"enum:pbs": {
|
"enum:pbs": {
|
||||||
"foreground": "#ff7b72",
|
"foreground": "#ff7b72",
|
||||||
"underline": true
|
"underline": true
|
||||||
},
|
},
|
||||||
"variable.readonly:pbs": {
|
"variable.readonly:pbs": "#c297ff",
|
||||||
"foreground": "#f778ba",
|
"pbs-asset:pbs": "#c297ff",
|
||||||
"italic": true
|
"string.readonly:pbs": "#c297ff"
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"workbench.colorCustomizations": {
|
"workbench.colorCustomizations": {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -15,6 +15,8 @@ declare global camera_mult: int = 1;
|
|||||||
declare const MAX_FRAMES: int = 4;
|
declare const MAX_FRAMES: int = 4;
|
||||||
declare const CAMERA_SPEED: int = 1;
|
declare const CAMERA_SPEED: int = 1;
|
||||||
|
|
||||||
|
declare struct Bla (a: int) {}
|
||||||
|
|
||||||
[Init]
|
[Init]
|
||||||
fn init() -> void
|
fn init() -> void
|
||||||
{
|
{
|
||||||
@ -25,6 +27,7 @@ fn init() -> void
|
|||||||
camera_x = 0;
|
camera_x = 0;
|
||||||
camera_mult = 1;
|
camera_mult = 1;
|
||||||
Composer.bind_scene(0);
|
Composer.bind_scene(0);
|
||||||
|
let bla: Bla = new Bla(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Frame]
|
[Frame]
|
||||||
@ -55,9 +58,8 @@ fn frame() -> void
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let touch : InputTouch = Input.touch();
|
let touch : InputTouch = Input.touch();
|
||||||
|
let pad : InputPad = Input.pad();
|
||||||
|
|
||||||
if (touch.button().released())
|
if (touch.button().released())
|
||||||
{
|
{
|
||||||
@ -93,15 +95,15 @@ fn frame() -> void
|
|||||||
let b : int = 15;
|
let b : int = 15;
|
||||||
let total : int = a + b;
|
let total : int = a + b;
|
||||||
|
|
||||||
if (Input.pad().a().pressed())
|
if (pad.a().pressed())
|
||||||
{
|
{
|
||||||
total += 25;
|
total += 25;
|
||||||
}
|
}
|
||||||
else if (Input.pad().b().pressed())
|
else if (pad.b().pressed())
|
||||||
{
|
{
|
||||||
total += 5;
|
total += 5;
|
||||||
}
|
}
|
||||||
else if (Input.pad().x().pressed())
|
else if (pad.x().pressed())
|
||||||
{
|
{
|
||||||
total -= 10;
|
total -= 10;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user