-
Notifications
You must be signed in to change notification settings - Fork 108
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
Injected grammars don't always properly relinquish control once completed. #125
Comments
Last time I investigated something similar, microsoft/vscode#87496, I spent 1 hour and in the end there was no change needed to Thank you! ❤️ |
Sure, I was able to simplify the Razor + C# grammars (put them into a single grammar) to only include the pieces for this repro: Simplified Repro Grammar (Razor + C#){
"name": "ASP.NET Razor",
"scopeName": "text.aspnetcorerazor",
"patterns": [
{
"include": "#code-directive"
}
],
"repository": {
"code-directive": {
"begin": "(@)(code)\\s*",
"beginCaptures": {
"1": {
"name": "keyword.control.cshtml.transition"
},
"2": {
"name": "keyword.control.razor.directive.code"
}
},
"patterns": [
{
"include": "#directive-codeblock"
}
],
"end": "(?<=})|\\s"
},
"directive-codeblock": {
"begin": "(\\{)",
"beginCaptures": {
"1": {
"name": "keyword.control.razor.directive.codeblock.open"
}
},
"name": "meta.structure.razor.directive.codeblock",
"patterns": [
{
"include": "#source-cs-light"
}
],
"end": "(\\})",
"endCaptures": {
"1": {
"name": "keyword.control.razor.directive.codeblock.close"
}
}
},
"source-cs-light": {
"patterns": [
{
"include": "#storage-modifier"
},
{
"include": "#interface-declaration"
},
{
"include": "#class-declaration"
}
]
},
"interface-declaration": {
"begin": "(?=\\binterface\\b)",
"end": "(?<=\\})",
"patterns": [
{
"begin": "(?x)\n(interface)\\b\\s+\n(@?[_[:alpha:]][_[:alnum:]]*)",
"beginCaptures": {
"1": {
"name": "keyword.other.interface.cs"
},
"2": {
"name": "entity.name.type.interface.cs"
}
},
"end": "(?=\\{)"
},
{
"begin": "\\{",
"beginCaptures": {
"0": {
"name": "punctuation.curlybrace.open.cs"
}
},
"end": "\\}",
"endCaptures": {
"0": {
"name": "punctuation.curlybrace.close.cs"
}
}
}
]
},
"class-declaration": {
"begin": "(?=\\bclass\\b)",
"end": "(?<=\\})",
"patterns": [
{
"begin": "(?x)\n\\b(class)\\b\\s+\n(@?[_[:alpha:]][_[:alnum:]]*)\\s*",
"beginCaptures": {
"1": {
"name": "keyword.other.class.cs"
},
"2": {
"name": "entity.name.type.class.cs"
}
},
"end": "(?=\\{)"
},
{
"begin": "\\{",
"beginCaptures": {
"0": {
"name": "punctuation.curlybrace.open.cs"
}
},
"end": "\\}",
"endCaptures": {
"0": {
"name": "punctuation.curlybrace.close.cs"
}
}
}
]
},
"storage-modifier": {
"name": "storage.modifier.cs",
"match": "(?<!\\.)\\b(new|public|protected|internal|private|abstract|virtual|override|sealed|static|partial|readonly|volatile|const|extern|async|unsafe|ref)\\b"
}
}
}
Is there an easy way to test TextMate/SublimeText/Atom? I'm unfamiliar with getting TextMate pieces to run in those editors sadly. Also, to note I was developing the grammar for VSCode first and found this issue as part of that. I just happened to try it in VS and saw that it worked after the fact. Oh and commenting out the injection makes everything work perfectly 😄 . |
Thank you for the reduced repro. But when I try the reduced grammar you have provided,
I have executed
|
@alexdima my apologies. It was a total fat finger mistake on my part. It looks like I pasted the grammar with the injection already deleted. I just added back the injection here and it repros: Simplified Repro Grammar (Razor + C#){
"name": "ASP.NET Razor",
"scopeName": "text.aspnetcorerazor",
"patterns": [
{
"include": "#code-directive"
}
],
"injections": {
"L:meta.structure.razor.codeblock - (meta.statement | string.quoted | comment), L:meta.structure.razor.directive.codeblock - (meta.statement | string.quoted | comment)": {
"patterns": [
{
"begin": "(\\{)",
"beginCaptures": {
"1": {
"name": "punctuation.curlybrace.open.cs"
}
},
"patterns": [
{
"include": "#source-cs-light"
}
],
"end": "(\\})",
"endCaptures": {
"1": {
"name": "punctuation.curlybrace.close.cs"
}
}
}
]
}
},
"repository": {
"code-directive": {
"begin": "(@)(code)\\s*",
"beginCaptures": {
"1": {
"name": "keyword.control.cshtml.transition"
},
"2": {
"name": "keyword.control.razor.directive.code"
}
},
"patterns": [
{
"include": "#directive-codeblock"
}
],
"end": "(?<=})|\\s"
},
"directive-codeblock": {
"begin": "(\\{)",
"beginCaptures": {
"1": {
"name": "keyword.control.razor.directive.codeblock.open"
}
},
"name": "meta.structure.razor.directive.codeblock",
"patterns": [
{
"include": "#source-cs-light"
}
],
"end": "(\\})",
"endCaptures": {
"1": {
"name": "keyword.control.razor.directive.codeblock.close"
}
}
},
"source-cs-light": {
"patterns": [
{
"include": "#storage-modifier"
},
{
"include": "#interface-declaration"
},
{
"include": "#class-declaration"
}
]
},
"interface-declaration": {
"begin": "(?=\\binterface\\b)",
"end": "(?<=\\})",
"patterns": [
{
"begin": "(?x)\n(interface)\\b\\s+\n(@?[_[:alpha:]][_[:alnum:]]*)",
"beginCaptures": {
"1": {
"name": "keyword.other.interface.cs"
},
"2": {
"name": "entity.name.type.interface.cs"
}
},
"end": "(?=\\{)"
},
{
"begin": "\\{",
"beginCaptures": {
"0": {
"name": "punctuation.curlybrace.open.cs"
}
},
"end": "\\}",
"endCaptures": {
"0": {
"name": "punctuation.curlybrace.close.cs"
}
}
}
]
},
"class-declaration": {
"begin": "(?=\\bclass\\b)",
"end": "(?<=\\})",
"patterns": [
{
"begin": "(?x)\n\\b(class)\\b\\s+\n(@?[_[:alpha:]][_[:alnum:]]*)\\s*",
"beginCaptures": {
"1": {
"name": "keyword.other.class.cs"
},
"2": {
"name": "entity.name.type.class.cs"
}
},
"end": "(?=\\{)"
},
{
"begin": "\\{",
"beginCaptures": {
"0": {
"name": "punctuation.curlybrace.open.cs"
}
},
"end": "\\}",
"endCaptures": {
"0": {
"name": "punctuation.curlybrace.close.cs"
}
}
}
]
},
"storage-modifier": {
"name": "storage.modifier.cs",
"match": "(?<!\\.)\\b(new|public|protected|internal|private|abstract|virtual|override|sealed|static|partial|readonly|volatile|const|extern|async|unsafe|ref)\\b"
}
}
}
Here's the output from running the npm inspect as you suggested (note the npm inspect output
|
Ok, I have now debugged through it. The rule The problem is that at offset 18 in the line
Both of them match at the same offset. In this case, the tie is broken via the injection priority. In the way you wrote the injection selector:
This means that the injection is placed to the "left" (
See e.g. https://stackoverflow.com/a/47517414 , http://textmate.1073791.n5.nabble.com/Grammar-injection-Main-grammar-taking-priority-td29990.html I can only imagine that VS perhaps does not implement |
Hmm, i'm intentionally trying to have the injection take priority here so we can hijack the curly brace scope and add additional features. I was under the assumption that's Is it wrong to think that |
@NTaylorMullen I have transformed your grammar to one accepted by TextMate and tried out your sample in TextMate:
When changing the injection to use I therefore believe we are working in the same way as TextMate, which is the goal of this project. Because we pursue grammar compatibility with the TextMate grammars, we will not make any change to diverge from the TextMate interpreter. |
So looks like VS is the one acting funky then 😄. @alexdima thanks for all your help here. |
We've been developing ASP.NET Core Razor's TextMate grammar and have recently ran into an issue that seems to be a root issue with the VSCode TextMate parser (doesn't repro in Visual Studio's TextMate parser). It seems to be that injections don't always properly relinquish control to the previous grammar once completed.
Repro:
myfile.razor
myfile.razor
:class Baz
miscolored:In other textmate parsers this works as expected, Visual Studio's:
![image](https://user-images.githubusercontent.com/2008729/74305948-0d8a2d00-4d16-11ea-9725-83740b8acd20.png)
My preliminary investigation
This is being classified through Razor's TextMate grammar (json, yml) and removing this injection ends up resolving the problem. From what I've found it looks like after the
interface Bar { }
the injection does not relinquish control to the parent rule that was running.The text was updated successfully, but these errors were encountered: