Syntax highlighting breaks when opening bracket of a method is placed in a new line
From @zeroskyx on May 17, 2017 18:46
The following code placed in a class breaks syntax highlighting:
public void Routine
(
IInterface Interface0,
IInterface Interface1,
IInterface Interface2
)
{
string One = "";
string Two = "";
string Three = "";
}
interface IInterface
{
}
Beginning with the second instance of IInterface and after the method body, everything is white -- in more complex projects, somewhere it works again later in the file.
Screenshot:
Removing the newline after public void Routine does not cause the issue:
I am aware that this appears to be a "strange" coding style; it makes reading constructors with loads of dependency injections much cleaner though (issue happens with both methods and constructors).
Copied from original issue: OmniSharp/omnisharp-vscode#1489
There's not much we can do about the first example as colorization is handled by running regular expressions in a line-by-line fashion. When the open and close parens are both placed on separate lines, it's pretty much impossible to detect.
I'm marking this as a bug for now. However, there may not be much we can do about the issue. VS Code colorization is handled by scanning a document line-by-line using regular expressions. This provides colorization that is generally "good enough", but won't every be perfect. If there's not enough information on a single line to identify a particular construct, it's unlikely that it will be colorized precisely.
Note that this is related to #61.
It's been over 3 years, any updates?
Although this is related to #61 and #62 that it's linebreaks that makes it impossible to distinguish tokens, there's something that could be fixed here.
Method 1.
public void Routine // <- Routine here can never be correctly detected by textmate -
// it could be field/property/method.
// This should be left to be handled by the semantic highlighter.
( // <- But at least we can at least detect for undetected dangling "tuple",
// which could be a tuple return type or a method parameter definition.
IInterface Interface0,
IInterface Interface1,
IInterface Interface2
)
{ // <- And at the very least we can catch dangling blocks and assume it's a body for something.
string One = "";
string Two = "";
string Three = "";
}
Above logic works if the public void Routine part does not greedily consume the line in a begin block and try look for some end block.
Method 2.
Another method is to set the begin detection as minimum as possible - specifically only the beginning of the required token - the return type:
begin: (type detection)
end: (?<=})|(?=;|}) # lookahead closing brace to end search within current class
Storage modifiers, attributes and others should be detected separately by themselves. And then we detect what could be inside this pattern - field, property, event, method, constructor, etc. - basically a type member.
Method 1 is a more conservative way, as it's more similar to the current patterns. I find it much harder to maintain/extend. Method 2 is what I prefer however, as it allows better detection overall with possibly less errors and more lenient. Would need to rewrite quite a lot of stuff though.
Additionally: method 2 can also handle #97 since (<, >) pair can be detected separately within the member detection.