Skip to content

Commit

Permalink
Josh/self (FuelLabs#4325)
Browse files Browse the repository at this point in the history
## Description
Fixes incorrect semantic token definitions for `Self` and `self` tokens
so they match how `rust-anaylzer` treats these tokens. Also adds simple
docs for the variants in `SymbolKind`.

closes FuelLabs#4058 
closes FuelLabs#4062
  • Loading branch information
JoshuaBatty authored Mar 22, 2023
1 parent 9ea1695 commit b49c2a3
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 28 deletions.
4 changes: 3 additions & 1 deletion sway-lsp/src/capabilities/document_symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ pub(crate) fn symbol_kind(symbol_kind: &SymbolKind) -> lsp_types::SymbolKind {
SymbolKind::ValueParam
| SymbolKind::ByteLiteral
| SymbolKind::Variable
| SymbolKind::Type
| SymbolKind::TypeAlias
| SymbolKind::Keyword
| SymbolKind::SelfKeyword
| SymbolKind::SelfTypeKeyword
| SymbolKind::Unknown => lsp_types::SymbolKind::VARIABLE,
}
}
Expand Down
8 changes: 6 additions & 2 deletions sway-lsp/src/capabilities/semantic_tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ pub(crate) const SUPPORTED_TYPES: &[SemanticTokenType] = &[
SemanticTokenType::STRING,
SemanticTokenType::NUMBER,
SemanticTokenType::NAMESPACE,
SemanticTokenType::TYPE,
SemanticTokenType::STRUCT,
SemanticTokenType::CLASS,
SemanticTokenType::INTERFACE,
Expand All @@ -129,6 +128,9 @@ pub(crate) const SUPPORTED_TYPES: &[SemanticTokenType] = &[
SemanticTokenType::new("keyword"),
SemanticTokenType::new("builtinType"),
SemanticTokenType::new("deriveHelper"),
SemanticTokenType::new("selfKeyword"),
SemanticTokenType::new("selfTypeKeyword"),
SemanticTokenType::new("typeAlias"),
];

pub(crate) const SUPPORTED_MODIFIERS: &[SemanticTokenModifier] = &[
Expand Down Expand Up @@ -162,11 +164,13 @@ fn semantic_token_type(kind: &SymbolKind) -> SemanticTokenType {
SymbolKind::StringLiteral => SemanticTokenType::STRING,
SymbolKind::ByteLiteral | SymbolKind::NumericLiteral => SemanticTokenType::NUMBER,
SymbolKind::BoolLiteral => SemanticTokenType::new("boolean"),
SymbolKind::Type => SemanticTokenType::TYPE,
SymbolKind::TypeAlias => SemanticTokenType::new("typeAlias"),
SymbolKind::Keyword => SemanticTokenType::new("keyword"),
SymbolKind::Unknown => SemanticTokenType::new("generic"),
SymbolKind::BuiltinType => SemanticTokenType::new("builtinType"),
SymbolKind::DeriveHelper => SemanticTokenType::new("deriveHelper"),
SymbolKind::SelfKeyword => SemanticTokenType::new("selfKeyword"),
SymbolKind::SelfTypeKeyword => SemanticTokenType::new("selfTypeKeyword"),
}
}

Expand Down
74 changes: 57 additions & 17 deletions sway-lsp/src/core/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,27 +84,52 @@ pub enum TypedAstToken {
/// These variants are used to represent the semantic type of the [Token].
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SymbolKind {
Field,
ValueParam,
Function,
Const,
Struct,
Trait,
Storage,
Enum,
Variant,
/// Emitted for the boolean literals `true` and `false`.
BoolLiteral,
ByteLiteral,
StringLiteral,
NumericLiteral,
Variable,
/// Emitted for builtin types like `u32`, and `str`.
BuiltinType,
/// Emitted for byte literals.
ByteLiteral,
/// Emitted for constants.
Const,
/// Emitted for derive helper attributes.
DeriveHelper,
/// Emitted for enums.
Enum,
/// Emitted for struct fields.
Field,
/// Emitted for free-standing & associated functions.
Function,
/// Emitted for keywords.
Keyword,
/// Emitted for modules.
Module,
/// Emitted for numeric literals.
NumericLiteral,
/// Emitted for the self function parameter and self path-specifier.
SelfKeyword,
/// Emitted for the Self type parameter.
SelfTypeKeyword,
/// Emitted for storage.
Storage,
/// Emitted for string literals.
StringLiteral,
/// Emitted for structs.
Struct,
/// Emitted for traits.
Trait,
/// Emitted for type aliases.
TypeAlias,
/// Emitted for type parameters.
TypeParameter,
Keyword,
Type,
/// Emitted for generic tokens that have no mapping.
Unknown,
/// Emitted for non-self function parameters.
ValueParam,
/// Emitted for enum variants.
Variant,
/// Emitted for locals.
Variable,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -200,7 +225,21 @@ pub fn ident_of_type_id(

/// Intended to be used during traversal of the [sway_core::language::parsed::ParseProgram] AST.
/// We can then use the [TypeInfo] to infer the semantic type of the token before type-checking.
pub fn type_info_to_symbol_kind(type_engine: &TypeEngine, type_info: &TypeInfo) -> SymbolKind {
pub fn type_info_to_symbol_kind(
type_engine: &TypeEngine,
type_info: &TypeInfo,
type_span: Option<&Span>,
) -> SymbolKind {
// This is necessary because the type engine resolves `Self` & `self` to the type it refers to.
// We want to keep the semantics of these keywords.
if let Some(type_span) = type_span {
if type_span.as_str() == "Self" {
return SymbolKind::SelfTypeKeyword;
} else if type_span.as_str() == "self" {
return SymbolKind::SelfKeyword;
}
}

match type_info {
TypeInfo::UnsignedInteger(..) | TypeInfo::Boolean | TypeInfo::B256 => {
SymbolKind::BuiltinType
Expand All @@ -212,8 +251,9 @@ pub fn type_info_to_symbol_kind(type_engine: &TypeEngine, type_info: &TypeInfo)
TypeInfo::Enum { .. } => SymbolKind::Enum,
TypeInfo::Array(elem_ty, ..) => {
let type_info = type_engine.get(elem_ty.type_id);
type_info_to_symbol_kind(type_engine, &type_info)
type_info_to_symbol_kind(type_engine, &type_info, Some(&elem_ty.span()))
}
TypeInfo::SelfType => SymbolKind::SelfTypeKeyword,
_ => SymbolKind::Unknown,
}
}
Expand Down
16 changes: 9 additions & 7 deletions sway-lsp/src/traverse/parsed_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ impl Parse for Expression {
{
let symbol_kind = if name.as_str().contains(DESTRUCTURE_PREFIX) {
SymbolKind::Struct
} else if name.as_str() == "self" {
SymbolKind::SelfKeyword
} else {
SymbolKind::Variable
};
Expand Down Expand Up @@ -456,7 +458,7 @@ impl Parse for MethodApplicationExpression {
} = &self.method_name_binding.inner
{
let (type_info, ident) = &call_path_binding.inner.suffix;
collect_type_info_token(ctx, type_info, Some(ident.span()));
collect_type_info_token(ctx, type_info, Some(&ident.span()));
}
self.method_name_binding
.type_arguments
Expand Down Expand Up @@ -884,7 +886,7 @@ impl Parse for TraitFn {
self.parameters.iter().for_each(|param| {
param.parse(ctx);
});
collect_type_info_token(ctx, &self.return_type, Some(self.return_type_span.clone()));
collect_type_info_token(ctx, &self.return_type, Some(&self.return_type_span));
self.attributes.parse(ctx);
}
}
Expand Down Expand Up @@ -975,7 +977,7 @@ impl Parse for TypeArgument {
}
}
_ => {
let symbol_kind = type_info_to_symbol_kind(ctx.engines.te(), &type_info);
let symbol_kind = type_info_to_symbol_kind(ctx.engines.te(), &type_info, None);
if let Some(tree) = &self.call_path_tree {
let token =
Token::from_parsed(AstToken::TypeArgument(self.clone()), symbol_kind);
Expand All @@ -992,16 +994,16 @@ impl Parse for TypeAliasDeclaration {
to_ident_key(&self.name),
Token::from_parsed(
AstToken::Declaration(Declaration::TypeAliasDeclaration(self.clone())),
SymbolKind::Type,
SymbolKind::TypeAlias,
),
);
self.ty.parse(ctx);
self.attributes.parse(ctx);
}
}

fn collect_type_info_token(ctx: &ParseContext, type_info: &TypeInfo, type_span: Option<Span>) {
let symbol_kind = type_info_to_symbol_kind(ctx.engines.te(), type_info);
fn collect_type_info_token(ctx: &ParseContext, type_info: &TypeInfo, type_span: Option<&Span>) {
let symbol_kind = type_info_to_symbol_kind(ctx.engines.te(), type_info, type_span);
match type_info {
TypeInfo::Str(length) => {
let ident = Ident::new(length.span());
Expand Down Expand Up @@ -1039,7 +1041,7 @@ fn collect_type_info_token(ctx: &ParseContext, type_info: &TypeInfo, type_span:
}
_ => {
if let Some(type_span) = type_span {
let ident = Ident::new(type_span);
let ident = Ident::new(type_span.clone());
ctx.tokens.insert(
to_ident_key(&ident),
Token::from_parsed(AstToken::Ident(ident.clone()), symbol_kind),
Expand Down
2 changes: 1 addition & 1 deletion sway-lsp/src/traverse/typed_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1231,7 +1231,7 @@ impl<'a> TypedTree<'a> {
let type_engine = self.ctx.engines.te();
let decl_engine = self.ctx.engines.de();
let type_info = type_engine.get(type_id);
let symbol_kind = type_info_to_symbol_kind(type_engine, &type_info);
let symbol_kind = type_info_to_symbol_kind(type_engine, &type_info, Some(&type_span));
match &type_info {
TypeInfo::Array(type_arg, ..) => {
self.collect_type_argument(type_arg);
Expand Down

0 comments on commit b49c2a3

Please sign in to comment.