csharp-tmLanguage icon indicating copy to clipboard operation
csharp-tmLanguage copied to clipboard

Syntax highlighting breaks when opening bracket of a method is placed in a new line

Open DustinCampbell opened this issue 8 years ago • 5 comments

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: capture

Removing the newline after public void Routine does not cause the issue: capture1

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

DustinCampbell avatar May 17 '17 19:05 DustinCampbell

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.

DustinCampbell avatar May 17 '17 19:05 DustinCampbell

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.

DustinCampbell avatar May 30 '17 16:05 DustinCampbell

Note that this is related to #61.

DustinCampbell avatar May 30 '17 16:05 DustinCampbell

It's been over 3 years, any updates?

Smoovsky avatar Aug 21 '20 16:08 Smoovsky

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.

wise0704 avatar Aug 08 '23 07:08 wise0704