Skip to content

Incorrect matching of operator identifiers #43

Closed
@trepidacious

Description

@trepidacious

This is slightly complicated, and I'm still working through the scala spec. etc. to work out what should happen, but probably an example is the best place to start:

In grammars/scala.cson there is:

'match': '(==?|!=|<=|>=|<>|<|>)'
'name': 'keyword.operator.comparison.scala'

This matches === as == then =, which is incorrect - the whole === is a function name, defined by say scalaz as an improved comparison.

In fact == itself isn't really a keyword, it's also a method, with an "operator identifier" consisting of symbols.

Since methods aren't assigned a style, it would seem to be the correct behaviour to just get rid of these matches, and leave ==, ===, >= etc. unstyled?

To work properly the following would also need fixing:

'match': '(<-|←|->|→|=>|⇒|\\?|\\:+|@|\\|)+'
'name': 'keyword.operator.scala'

Since this will catch stuff like >=>, which I think is a valid function or variable name, not a => keyword. I've had a quick look at what could be done to avoid catching this, and it might look something like:

   'captures':
     '2':
       'name': 'keyword.operator.scala'
   'match': '([^!#%&*+\-/:<=>?@\\^|~])(<-|←|->|→|=>|⇒|\\?|\\:+|@|\\|)+([^!#%&*+\-/:<=>?@\\^|~])'

This requires that there is a non-operator character both before and after the keyword. Since operator identifiers need to contain only operator OR alphanumeric characters I think this should work reasonably well. However it's definitely not completely correct since there are more operator characters - unicode mathematical symbols etc., and there's something to do with using an underscore between operator characters and alphanumerics. There's more here: http://stackoverflow.com/questions/7656937/valid-identifier-characters-in-scala

On a side-note, the keyword.operator.comparison.scala match above also catches =, which is a keyword but not comparison?

I ran into this while using fira code to get nice ligatures for stuff like <- and => - when you type === it gets broken up into two spans for styling, so you don't get the "triple equals" ligature, but a "double equals" ligature then a normal equals sign. The same thing affects other ligatures like '<=<'.

I've submitted a pull request for this, it may not be usable directly but should show approximately what I mean...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions