-
Notifications
You must be signed in to change notification settings - Fork 37
Consistent highlight on derives' qualIds #240
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@Meowcolm024 What do you think about this? you can check it by
|
fix: scala#239 vscode-scala-syntax couldn't provide consistent highlights for `C` and `D` in `derives C, D`. Consider we have the following code ```scala enum A extends B derives C, D ``` Previously, `B` and `C` have the following TextMate Scopes ``` entity.other.inherited-class.scala source.scala ``` while `D` has ``` entity.name.class source.scala ``` because it had accepted only one qualId after `derived` https://github.com/scala/vscode-scala-syntax/blob/0b2b1e8829254f0d190e723d3a49874cb7d135c0/src/typescript/Scala.tmLanguage.ts#L1156 even though Scala3 syntax allows us to put multiple qualIds. Therefore, the first one will have `entity.other.inherited-class.scala`, but the following qualIds won't be named as `entity.other.inherited-class.scala`. Instead, falllback to `entity.name.class` based on it's name (upper camel). This commit makes it provide consistent highlight for each qualId after `derives` keyword. Now, both `C` and `D` will have `entity.name.class` instead of `entity.other.inherited-class.scala`. It would be ideal to put `entity.other.inherited-class.scala` to both `C` and `D`, but it looks like impossible with TextMate grammer. Because, according to the [syntax](https://dotty.epfl.ch/docs/reference/contextual/derivation.html#syntax) (see the syntax spec for Scala3 here https://docs.scala-lang.org/scala3/reference/syntax.html) we can't tell where's the end of `derives` clause. In the complete program, we can tell `{` or `:` is the end of `derives` clause, but it messes up if the program is incomplete like ```scala enum A extends B derives C, D ``` where there's no `:` or `{`. Just give up providing `entity.other.inherited-class.scala` and put `entity.name.class` based on their name (upper camel).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for looking into this! 🎉
tests/snap/scala_spec.test.scala
Outdated
case B, c, D | ||
|
||
enum A extends B derives X, Y, Z |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
enum A extends B derives X, Y, Z | |
enum A extends B, C derives X, Y, Z |
wouldn't we have the same problem with extends?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, right!
src/typescript/Scala.tmLanguage.ts
Outdated
@@ -1153,7 +1156,7 @@ export const scalaTmLanguage: TmLanguage = { | |||
inheritance: { | |||
patterns: [ | |||
{ | |||
match: `\\b(extends|with|derives)\\b\\s*(${idUpper}|${backQuotedId}|(?=\\([^\\)]+=>)|(?=${plainid})|(?="))?`, | |||
match: `\\b(extends|with)\\b\\s*(${idUpper}|${backQuotedId}|(?=\\([^\\)]+=>)|(?=${plainid})|(?="))?`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
match: `\\b(extends|with)\\b\\s*(${idUpper}|${backQuotedId}|(?=\\([^\\)]+=>)|(?=${plainid})|(?="))?`, | |
match: `\\b(extends|with|derives|,)\\b\\s*(${idUpper}|${backQuotedId}|(?=\\([^\\)]+=>)|(?=${plainid})|(?="))?`, |
something like this wouldn't work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so because it's too generic, that rule accepts any identifiers separated by ,
as entity.other.inherited-class.scala
. For example A , B
, B
will be entity.other.inherited-class.scala
though it's not.
It would be great if we can apply such rules only in extends
and derives
clause by
patterns: [
{
start: `\\b(extends|derives)`,
end: ???,
patterns: [
// patterns that matches `qualId`s and assign name as `entity.other.inherited-class.scala`
]
}
]
However, the problem is we can't tell what is the end
of extends
or derives
.
(At first, I thought maybe we can end with :
or {
or <newline>
but it doesn't work if derives clause contains new line)
class A derives B,
C
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With new line that should be ok since we ended with ,
we still expect something to be after it, no?
@@ -1165,6 +1168,18 @@ export const scalaTmLanguage: TmLanguage = { | |||
} | |||
] | |||
}, | |||
derives: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Derives is a soft keyword, wouldn't it be an issue when someone uses it as an identifier?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it would be a problem.
derives, if it appears after an extension clause or after the name and possibly parameters of a class, trait, object, or enum definition.
https://docs.scala-lang.org/scala3/reference/soft-modifier.html
However, I don't think there's a way for regex to check the previous clause is "extension clause or after the name and possibly parameters of a class, trait, object, or enum definition."
(for using
, we could determine it's after (
by positive-lookahead though).
Closing for #242 |
fix: #239
vscode-scala-syntax couldn't provide consistent highlights for
C
andD
inderives C, D
.Problem
Consider we have the following code
Previously,
B
andC
have the following TextMate Scopeswhile
D
hasbecause it had accepted only one qualId after
derived
vscode-scala-syntax/src/typescript/Scala.tmLanguage.ts
Line 1156 in 0b2b1e8
even though Scala3 syntax allows us to put multiple qualIds.
Therefore, the first one will have
entity.other.inherited-class.scala
, but the following qualIds won't be named asentity.other.inherited-class.scala
. Instead, falllback toentity.name.class
based on it's name (upper camel).fix
This commit makes it provides consistent highlight for each qualId after
derives
keyword.Now, both
C
andD
will haveentity.name.class
instead ofentity.other.inherited-class.scala
.alternative solution
It would be ideal to put
entity.other.inherited-class.scala
to bothC
andD
,but it looks like impossible with TextMate grammar.
Because according to the syntax
(see the syntax spec for Scala3 here https://docs.scala-lang.org/scala3/reference/syntax.html)
we can't tell where's the end of
derives
clause.In the complete program, we can tell
{
or:
is the end ofderives
clause, but it messes up if the program is incomplete like
where there's no
:
or{
.So, just give up providing
entity.other.inherited-class.scala
and putentity.name.class
based on their name (upper camel).