diff --git a/.gitignore b/.gitignore index 1439d28..b9ce341 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ out/ grammars/*.json npm-debug.log* copy.sh +bun.lock diff --git a/grammars/csharp.tmLanguage b/grammars/csharp.tmLanguage index 34c7e14..8d65102 100644 --- a/grammars/csharp.tmLanguage +++ b/grammars/csharp.tmLanguage @@ -9075,7 +9075,7 @@ preprocessor-pragma-warning match - \b(pragma)\b\s*\b(warning)\b\s*\b(?:(disable)|(restore))\b(\s*[0-9]+(?:\s*,\s*[0-9]+)?)? + \b(pragma)\b\s*\b(warning)\b\s*\b(?:(disable)|(restore))\b([A-Za-z0-9\s,]+) captures 1 @@ -9104,7 +9104,7 @@ match - [0-9]+ + [A-Za-z0-9]+ captures 0 diff --git a/grammars/csharp.tmLanguage.cson b/grammars/csharp.tmLanguage.cson index 5047f1f..d1f4062 100644 --- a/grammars/csharp.tmLanguage.cson +++ b/grammars/csharp.tmLanguage.cson @@ -5445,7 +5445,7 @@ repository: } ] "preprocessor-pragma-warning": - match: "\\b(pragma)\\b\\s*\\b(warning)\\b\\s*\\b(?:(disable)|(restore))\\b(\\s*[0-9]+(?:\\s*,\\s*[0-9]+)?)?" + match: "\\b(pragma)\\b\\s*\\b(warning)\\b\\s*\\b(?:(disable)|(restore))\\b([A-Za-z0-9\\s,]+)" captures: "1": name: "keyword.preprocessor.pragma.cs" @@ -5458,7 +5458,7 @@ repository: "5": patterns: [ { - match: "[0-9]+" + match: "[A-Za-z0-9]+" captures: "0": name: "constant.numeric.decimal.cs" diff --git a/src/csharp.tmLanguage.yml b/src/csharp.tmLanguage.yml index 2625cab..5ddafa5 100644 --- a/src/csharp.tmLanguage.yml +++ b/src/csharp.tmLanguage.yml @@ -3559,7 +3559,7 @@ repository: '0': { name: string.quoted.double.cs } preprocessor-pragma-warning: - match: \b(pragma)\b\s*\b(warning)\b\s*\b(?:(disable)|(restore))\b(\s*[0-9]+(?:\s*,\s*[0-9]+)?)? + match: \b(pragma)\b\s*\b(warning)\b\s*\b(?:(disable)|(restore))\b([A-Za-z0-9\s,]+) captures: '1': { name: keyword.preprocessor.pragma.cs } '2': { name: keyword.preprocessor.warning.cs } @@ -3567,7 +3567,7 @@ repository: '4': { name: keyword.preprocessor.restore.cs } '5': patterns: - - match: '[0-9]+' + - match: '[A-Za-z0-9]+' captures: '0': { name: constant.numeric.decimal.cs } - include: '#punctuation-comma' diff --git a/test/preprocessor.tests.ts b/test/preprocessor.tests.ts index 7bec550..da6bf06 100644 --- a/test/preprocessor.tests.ts +++ b/test/preprocessor.tests.ts @@ -745,6 +745,210 @@ void Bar() Token.Punctuation.CloseBrace ]); }); + + it("#pragma warning disable with comment followed by code", async () => { + const input = Input.InClass(` +#pragma warning disable IDE0001 // Comment1 + private int myField; +#pragma warning restore IDE0001 // Comment2`); + const tokens = await tokenize(input); + + tokens.should.deep.equal([ + Token.Punctuation.Hash, + Token.Keyword.Preprocessor.Pragma, + Token.Keyword.Preprocessor.Warning, + Token.Keyword.Preprocessor.Disable, + Token.Literal.Numeric.Decimal("IDE0001"), + Token.Comment.SingleLine.Start, + Token.Comment.SingleLine.Text(" Comment1"), + Token.Keyword.Modifier.Private, + Token.PrimitiveType.Int, + Token.Identifier.FieldName("myField"), + Token.Punctuation.Semicolon, + Token.Punctuation.Hash, + Token.Keyword.Preprocessor.Pragma, + Token.Keyword.Preprocessor.Warning, + Token.Keyword.Preprocessor.Restore, + Token.Literal.Numeric.Decimal("IDE0001"), + Token.Comment.SingleLine.Start, + Token.Comment.SingleLine.Text(" Comment2"), + ]); + }); + + it("#pragma warning disable multiple warnings", async () => { + const input = Input.InClass(` +#pragma warning disable IDE0001, IDE0002 + private int myField; +#pragma warning restore IDE0001, IDE0002 + private int anotherField; +`); + const tokens = await tokenize(input); + + tokens.should.deep.equal([ + Token.Punctuation.Hash, + Token.Keyword.Preprocessor.Pragma, + Token.Keyword.Preprocessor.Warning, + Token.Keyword.Preprocessor.Disable, + Token.Literal.Numeric.Decimal("IDE0001"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("IDE0002"), + Token.Keyword.Modifier.Private, + Token.PrimitiveType.Int, + Token.Identifier.FieldName("myField"), + Token.Punctuation.Semicolon, + Token.Punctuation.Hash, + Token.Keyword.Preprocessor.Pragma, + Token.Keyword.Preprocessor.Warning, + Token.Keyword.Preprocessor.Restore, + Token.Literal.Numeric.Decimal("IDE0001"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("IDE0002"), + Token.Keyword.Modifier.Private, + Token.PrimitiveType.Int, + Token.Identifier.FieldName("anotherField"), + Token.Punctuation.Semicolon, + ]); + }); + + it("#pragma warning disable many warnings", async () => { + const input = Input.InClass(` +#pragma warning disable IDE0001, IDE0002, 1, CS1233, XYZ9999, 404, 505, 606, 707, 808, 909 + private int myField; +#pragma warning restore IDE0001, IDE0002, 1, CS1233, XYZ9999, 404, 505, 606, 707, 808, 909 + private int anotherField; +`); + const tokens = await tokenize(input); + + tokens.should.deep.equal([ + Token.Punctuation.Hash, + Token.Keyword.Preprocessor.Pragma, + Token.Keyword.Preprocessor.Warning, + Token.Keyword.Preprocessor.Disable, + Token.Literal.Numeric.Decimal("IDE0001"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("IDE0002"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("1"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("CS1233"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("XYZ9999"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("404"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("505"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("606"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("707"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("808"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("909"), + Token.Keyword.Modifier.Private, + Token.PrimitiveType.Int, + Token.Identifier.FieldName("myField"), + Token.Punctuation.Semicolon, + Token.Punctuation.Hash, + Token.Keyword.Preprocessor.Pragma, + Token.Keyword.Preprocessor.Warning, + Token.Keyword.Preprocessor.Restore, + Token.Literal.Numeric.Decimal("IDE0001"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("IDE0002"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("1"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("CS1233"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("XYZ9999"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("404"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("505"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("606"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("707"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("808"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("909"), + Token.Keyword.Modifier.Private, + Token.PrimitiveType.Int, + Token.Identifier.FieldName("anotherField"), + Token.Punctuation.Semicolon, + ]); + }); + + it("#pragma warning disable multiple warnings with comment", async () => { + const input = Input.InClass(` +#pragma warning disable IDE0001, IDE0002, CS1234 // Comment1 + private int myField; +#pragma warning restore IDE0001, IDE0002 // Comment2 + private int anotherField; +`); + const tokens = await tokenize(input); + + tokens.should.deep.equal([ + Token.Punctuation.Hash, + Token.Keyword.Preprocessor.Pragma, + Token.Keyword.Preprocessor.Warning, + Token.Keyword.Preprocessor.Disable, + Token.Literal.Numeric.Decimal("IDE0001"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("IDE0002"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("CS1234"), + Token.Comment.SingleLine.Start, + Token.Comment.SingleLine.Text(" Comment1"), + Token.Keyword.Modifier.Private, + Token.PrimitiveType.Int, + Token.Identifier.FieldName("myField"), + Token.Punctuation.Semicolon, + Token.Punctuation.Hash, + Token.Keyword.Preprocessor.Pragma, + Token.Keyword.Preprocessor.Warning, + Token.Keyword.Preprocessor.Restore, + Token.Literal.Numeric.Decimal("IDE0001"), + Token.Punctuation.Comma, + Token.Literal.Numeric.Decimal("IDE0002"), + Token.Comment.SingleLine.Start, + Token.Comment.SingleLine.Text(" Comment2"), + Token.Keyword.Modifier.Private, + Token.PrimitiveType.Int, + Token.Identifier.FieldName("anotherField"), + Token.Punctuation.Semicolon, + ]); + }); + + it("#region and #endregion with comment", async () => { + const input = Input.InClass(` +#region My Region // This is my region + private int myField; +#endregion // End of my region + private int anotherField; +`); + const tokens = await tokenize(input); + + tokens.should.deep.equal([ + Token.Punctuation.Hash, + Token.Keyword.Preprocessor.Region, + Token.PreprocessorMessage("My Region // This is my region"), + Token.Keyword.Modifier.Private, + Token.PrimitiveType.Int, + Token.Identifier.FieldName("myField"), + Token.Punctuation.Semicolon, + Token.Punctuation.Hash, + Token.Keyword.Preprocessor.EndRegion, + Token.Comment.SingleLine.Start, + Token.Comment.SingleLine.Text(" End of my region"), + Token.Keyword.Modifier.Private, + Token.PrimitiveType.Int, + Token.Identifier.FieldName("anotherField"), + Token.Punctuation.Semicolon, + ]); + }); }); describe("AppDirectives", () => {