diff --git a/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md b/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md index 57b35de0133bc..744e788b4c100 100644 --- a/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md +++ b/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md @@ -1,5 +1,16 @@ # This document lists known breaking changes in Roslyn after .NET 6 all the way to .NET 7. +## Required spaces in #line span directives + +***Introduced in .NET SDK 6.0.400, Visual Studio 2022 version 17.3.*** + +When the `#line` span directive was introduced in C# 10, it required no particular spacing. +For example, this would be valid: `#line(1,2)-(3,4)5"file.cs"`. + +In Visual Studio 17.3, the compiler requires spaces before the first parenthesis, the character +offset, and the file name. +So the above example fails to parse unless spaces are added: `#line (1,2)-(3,4) 5 "file.cs"`. + ## Checked operators on System.IntPtr and System.UIntPtr ***Introduced in .NET SDK 7.0.100, Visual Studio 2022 version 17.3.*** diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 36f9795e5f956..f9e666cf5c3b3 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -6670,9 +6670,6 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ inferred delegate type - - line span directive - auto default struct fields @@ -6682,6 +6679,9 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ The #line directive end position must be greater than or equal to the start position + + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + Comparison of function pointers might yield an unexpected result, since pointers to the same function may be distinct. diff --git a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs index d5865961b3996..34d5138dd8559 100644 --- a/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs +++ b/src/Compilers/CSharp/Portable/Errors/ErrorCode.cs @@ -2071,6 +2071,7 @@ internal enum ErrorCode ERR_CannotBeConvertedToUTF8 = 9026, ERR_MisplacedUnchecked = 9027, + ERR_LineSpanDirectiveRequiresSpace = 9028, ERR_RequiredNameDisallowed = 9029, ERR_OverrideMustHaveRequired = 9030, diff --git a/src/Compilers/CSharp/Portable/Errors/MessageID.cs b/src/Compilers/CSharp/Portable/Errors/MessageID.cs index ac133c4752460..c64cb4dc638d5 100644 --- a/src/Compilers/CSharp/Portable/Errors/MessageID.cs +++ b/src/Compilers/CSharp/Portable/Errors/MessageID.cs @@ -230,7 +230,7 @@ internal enum MessageID IDS_FeatureLambdaReturnType = MessageBase + 12804, IDS_AsyncMethodBuilderOverride = MessageBase + 12805, IDS_FeatureImplicitImplementationOfNonPublicMembers = MessageBase + 12806, - IDS_FeatureLineSpanDirective = MessageBase + 12807, + // IDS_FeatureLineSpanDirective = MessageBase + 12807, // feature no longer gated on LangVer IDS_FeatureImprovedInterpolatedStrings = MessageBase + 12808, IDS_FeatureFileScopedNamespace = MessageBase + 12809, IDS_FeatureParameterlessStructConstructors = MessageBase + 12810, @@ -396,7 +396,6 @@ internal static LanguageVersion RequiredVersion(this MessageID feature) case MessageID.IDS_AsyncMethodBuilderOverride: // semantic check case MessageID.IDS_FeatureConstantInterpolatedStrings: // semantic check case MessageID.IDS_FeatureImplicitImplementationOfNonPublicMembers: // semantic check - case MessageID.IDS_FeatureLineSpanDirective: case MessageID.IDS_FeatureFileScopedNamespace: // syntax check case MessageID.IDS_FeatureParameterlessStructConstructors: // semantic check case MessageID.IDS_FeatureStructFieldInitializers: // semantic check diff --git a/src/Compilers/CSharp/Portable/Parser/DirectiveParser.cs b/src/Compilers/CSharp/Portable/Parser/DirectiveParser.cs index 066be0b8d5350..a88f2714788f4 100644 --- a/src/Compilers/CSharp/Portable/Parser/DirectiveParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/DirectiveParser.cs @@ -406,13 +406,12 @@ private LineSpanDirectiveTriviaSyntax ParseLineSpanDirective(SyntaxToken hash, S { Debug.Assert(CurrentToken.Kind == SyntaxKind.OpenParenToken); - if (isActive) - { - lineKeyword = CheckFeatureAvailability(lineKeyword, MessageID.IDS_FeatureLineSpanDirective); - } - bool reportError = isActive; var start = ParseLineDirectivePosition(ref reportError, out int startLine, out int startCharacter); + if (noTriviaBetween(lineKeyword, start.GetFirstToken())) + { + start = this.AddError(start, ErrorCode.ERR_LineSpanDirectiveRequiresSpace); + } var minus = EatToken(SyntaxKind.MinusToken, reportError: reportError); if (minus.IsMissing) reportError = false; @@ -428,11 +427,28 @@ private LineSpanDirectiveTriviaSyntax ParseLineSpanDirective(SyntaxToken hash, S ParseLineDirectiveNumericLiteral(ref reportError, minValue: 1, maxValue: MaxCharacterValue, out _) : null; + if (noTriviaBetween(end.GetLastToken(), characterOffset)) + { + characterOffset = this.AddError(characterOffset, ErrorCode.ERR_LineSpanDirectiveRequiresSpace); + } + var file = EatToken(SyntaxKind.StringLiteralToken, ErrorCode.ERR_MissingPPFile, reportError: reportError); if (file.IsMissing) reportError = false; + if (noTriviaBetween(characterOffset ?? end.GetLastToken(), file)) + { + file = this.AddError(file, ErrorCode.ERR_LineSpanDirectiveRequiresSpace); + } + var endOfDirective = this.ParseEndOfDirective(ignoreErrors: !reportError); return SyntaxFactory.LineSpanDirectiveTrivia(hash, lineKeyword, start, minus, end, characterOffset, file, endOfDirective, isActive); + + static bool noTriviaBetween(SyntaxToken token1, SyntaxToken token2) + { + return token1 is { IsMissing: false } + && token2 is { IsMissing: false } + && LanguageParser.NoTriviaBetween(token1, token2); + } } private LineDirectivePositionSyntax ParseLineDirectivePosition(ref bool reportError, out int line, out int character) diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index e5b791ebe2763..4ec9e9f3f9d65 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -4596,7 +4596,7 @@ private void ParseParameterNullCheck( GetExpectedTokenError(kind, t1.Kind)); } - private static bool NoTriviaBetween(SyntaxToken token1, SyntaxToken token2) + internal static bool NoTriviaBetween(SyntaxToken token1, SyntaxToken token2) => token1.GetTrailingTriviaWidth() == 0 && token2.GetLeadingTriviaWidth() == 0; #nullable disable diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf index 705bb52302be9..c4f813d5d31f4 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.cs.xlf @@ -837,6 +837,11 @@ Hodnota direktivy #line chybí nebo je mimo rozsah. + + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + + List patterns may not be used for a value of type '{0}'. No suitable 'Length' or 'Count' property was found. Vzory seznamů nelze použít pro hodnotu typu {0}. Nenašla se žádná vhodná vlastnost Length nebo Count. @@ -1577,11 +1582,6 @@ návratový typ lambda - - line span directive - direktiva line span - - list pattern vzor seznamu diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf index 738cf7d8191c8..9e9cd0133f541 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.de.xlf @@ -837,6 +837,11 @@ Der Wert der #line-Anweisung fehlt oder liegt außerhalb des gültigen Bereichs. + + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + + List patterns may not be used for a value of type '{0}'. No suitable 'Length' or 'Count' property was found. Listenmuster dürfen nicht für einen Wert vom Typ „{0}“ verwendet werden. Es wurde keine geeignete Längen- oder Anzahl-Eigenschaft gefunden. @@ -1577,11 +1582,6 @@ Lambda-Rückgabetyp - - line span directive - Zeilenabstand-Anweisung - - list pattern Listenmuster diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf index cd26a9aed72bf..c048c769b89c7 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.es.xlf @@ -837,6 +837,11 @@ Falta el valor de directiva #line o está fuera del rango + + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + + List patterns may not be used for a value of type '{0}'. No suitable 'Length' or 'Count' property was found. No se pueden usar patrones de lista para un valor de tipo \"{0}\". No se encontró ninguna propiedad \"Length\" o \"Count\" adecuada. @@ -1577,11 +1582,6 @@ tipo de valor devuelto de lambda - - line span directive - directiva de intervalo de línea - - list pattern patrón de lista diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf index bdc7bd13c0ef4..6af1a3b58650e 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.fr.xlf @@ -837,6 +837,11 @@ La valeur de directive #line est manquante ou hors limites + + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + + List patterns may not be used for a value of type '{0}'. No suitable 'Length' or 'Count' property was found. Les modèles de liste ne peuvent pas être utilisés pour une valeur de type '{0}'. Aucune propriété 'Longueur' ou 'Compte' appropriée n’a été trouvée. @@ -1577,11 +1582,6 @@ type de retour lambda - - line span directive - directive de l’étendue de ligne - - list pattern modèle de liste diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf index c5257dc722735..f6829bac270d4 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.it.xlf @@ -837,6 +837,11 @@ Il valore della direttiva #line manca oppure non è compreso nell'intervallo + + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + + List patterns may not be used for a value of type '{0}'. No suitable 'Length' or 'Count' property was found. I criteri di elenco non possono essere utilizzati per un valore di tipo '{0}'. Non è stata trovata alcuna proprietà 'Length' o 'Count' appropriata. @@ -1577,11 +1582,6 @@ tipo restituito dell'espressione lambda - - line span directive - direttiva per intervallo di riga - - list pattern modello di elenco diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf index c1f8f1aa44805..200b7dbd75fba 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ja.xlf @@ -837,6 +837,11 @@ #line ディレクティブの値が見つからないか、範囲外です + + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + + List patterns may not be used for a value of type '{0}'. No suitable 'Length' or 'Count' property was found. リスト パターンは、型 '{0}' の値には使用できません。適切な 'Length' または 'Count' プロパティが見つかりませんでした。 @@ -1577,11 +1582,6 @@ ラムダ戻り値の型 - - line span directive - line span ディレクティブ - - list pattern リスト パターン diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf index 8b0a5edeecb24..435c2e7a505da 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ko.xlf @@ -837,6 +837,11 @@ #line 지시문 값이 없거나 범위를 벗어났습니다. + + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + + List patterns may not be used for a value of type '{0}'. No suitable 'Length' or 'Count' property was found. 목록 패턴은 '{0}' 형식의 값에 사용할 수 없습니다. 적합한 'Length' 또는 'Count' 속성을 찾을 수 없습니다. @@ -1577,11 +1582,6 @@ 람다 반환 유형 - - line span directive - 라인 범위 지시문 - - list pattern 목록 패턴 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf index 45f669a3e71c6..39361ce42cd44 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pl.xlf @@ -837,6 +837,11 @@ Brak wartości dyrektywy #line lub jest ona poza zakresem + + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + + List patterns may not be used for a value of type '{0}'. No suitable 'Length' or 'Count' property was found. Wzorce listy nie mogą być używane dla wartości typu „{0}”. Nie znaleziono odpowiedniej właściwości „Długość” ani „Liczba”. @@ -1577,11 +1582,6 @@ zwracany typ lambda - - line span directive - dyrektywa zakresu wierszy - - list pattern wzorzec listy diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf index f89d211e56616..628b310615556 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.pt-BR.xlf @@ -837,6 +837,11 @@ O valor da diretiva de #line está ausente ou fora do intervalo + + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + + List patterns may not be used for a value of type '{0}'. No suitable 'Length' or 'Count' property was found. Padrões de lista não podem ser usados para um valor do tipo “{0}”. Nenhuma propriedade “Length” ou “Count” adequada foi encontrada. @@ -1577,11 +1582,6 @@ tipo de retorno de lambda - - line span directive - diretiva de extensão de linha - - list pattern padrão de lista diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf index 30c7985df5171..0210521a8f7ee 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.ru.xlf @@ -837,6 +837,11 @@ Значение директивы #line отсутствует или находится за пределами допустимого диапазона + + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + + List patterns may not be used for a value of type '{0}'. No suitable 'Length' or 'Count' property was found. Шаблоны списка не могут использоваться для значения типа {0}. Подходящее свойство \"Length\" или \"Count\" не найдено. @@ -1577,11 +1582,6 @@ тип возвращаемого значения лямбда - - line span directive - директива line span - - list pattern шаблон списка diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf index 78fe1007cf2b9..edd05a10e1b15 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.tr.xlf @@ -837,6 +837,11 @@ #line yönerge değeri eksik veya aralık dışı + + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + + List patterns may not be used for a value of type '{0}'. No suitable 'Length' or 'Count' property was found. Liste desenleri, '{0}' türündeki bir değer için kullanılamaz. Uygun 'Length' veya 'Count' özelliği bulunamadı. @@ -1577,11 +1582,6 @@ lambda dönüş türü - - line span directive - satır aralığı yönergesi - - list pattern liste deseni diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf index 10822f4c623f3..b67600d9f7ce9 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hans.xlf @@ -837,6 +837,11 @@ #line 指令值缺失或超出范围 + + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + + List patterns may not be used for a value of type '{0}'. No suitable 'Length' or 'Count' property was found. 列表模式不能用于 '{0}' 类型的值。找不到合适的 \"Length\" 或 \"Count\" 属性。 @@ -1577,11 +1582,6 @@ lambda 返回类型 - - line span directive - 行跨度指令 - - list pattern 列表模式 diff --git a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf index fd727d9767934..1f3cf3c9108cd 100644 --- a/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf +++ b/src/Compilers/CSharp/Portable/xlf/CSharpResources.zh-Hant.xlf @@ -837,6 +837,11 @@ #Line 指示詞值遺漏或超出範圍 + + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + + List patterns may not be used for a value of type '{0}'. No suitable 'Length' or 'Count' property was found. 清單模式不能用於型別 '{0}' 的值。找不到適當的 'Length' 或 'Count' 屬性。 @@ -1577,11 +1582,6 @@ lambda 傳回型別 - - line span directive - line span 指示詞 - - list pattern 清單模式 diff --git a/src/Compilers/CSharp/Test/Syntax/Parsing/LineSpanDirectiveParsingTests.cs b/src/Compilers/CSharp/Test/Syntax/Parsing/LineSpanDirectiveParsingTests.cs index c640a6dbd6a91..55f7c83168014 100644 --- a/src/Compilers/CSharp/Test/Syntax/Parsing/LineSpanDirectiveParsingTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Parsing/LineSpanDirectiveParsingTests.cs @@ -5,6 +5,7 @@ using System.Linq; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; using Xunit; using Xunit.Abstractions; @@ -42,10 +43,7 @@ public void IsActive() UsingLineDirective(source, TestOptions.Regular9); verify(); - UsingLineDirective(source, TestOptions.Regular9.WithPreprocessorSymbols("IsActive"), - // (2,2): error CS8773: Feature 'line span directive' is not available in C# 9.0. Please use language version 10.0 or greater. - // #line (1, 2) - (3, 4) "file.cs" - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion9, "line").WithArguments("line span directive", "10.0").WithLocation(2, 2)); + UsingLineDirective(source, TestOptions.Regular9.WithPreprocessorSymbols("IsActive")); verify(); void verify() @@ -83,10 +81,7 @@ public void LineDirective_01() { string source = @"#line (1, 2) - (3, 4) ""file.cs"""; - UsingLineDirective(source, TestOptions.Regular9, - // (1,2): error CS8773: Feature 'line span directive' is not available in C# 9.0. Please use language version 10.0 or greater. - // #line (1, 2) - (3, 4) "file.cs" - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion9, "line").WithArguments("line span directive", "10.0").WithLocation(1, 2)); + UsingLineDirective(source, TestOptions.Regular9); verify(); UsingLineDirective(source, TestOptions.Regular10); @@ -127,10 +122,7 @@ public void LineDirective_02() { string source = @"#line (1, 2) - (3, 4) 5 ""file.cs"""; - UsingLineDirective(source, TestOptions.Regular9, - // (1,2): error CS8773: Feature 'line span directive' is not available in C# 9.0. Please use language version 10.0 or greater. - // #line (1, 2) - (3, 4) "file.cs" - Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion9, "line").WithArguments("line span directive", "10.0").WithLocation(1, 2)); + UsingLineDirective(source, TestOptions.Regular9); verify(); UsingLineDirective(source, TestOptions.Regular10); @@ -241,7 +233,13 @@ public void LineDirective_05() { string source = @"#line(1,2)-(3,4)""file.cs"""; - UsingLineDirective(source, options: null); + UsingLineDirective(source, options: null, + // (1,6): error CS9028: The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + // #line(1,2)-(3,4)"file.cs" + Diagnostic(ErrorCode.ERR_LineSpanDirectiveRequiresSpace, "(1,2)").WithLocation(1, 6), + // (1,17): error CS9028: The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + // #line(1,2)-(3,4)"file.cs" + Diagnostic(ErrorCode.ERR_LineSpanDirectiveRequiresSpace, @"""file.cs""").WithLocation(1, 17)); N(SyntaxKind.LineSpanDirectiveTrivia); { @@ -271,10 +269,89 @@ public void LineDirective_05() } [Fact] + public void LineDirective_05_WithRequiredSpaces() + { + string source = @"#line (1,2)-(3,4) ""file.cs"""; + + UsingLineDirective(source, options: null); + + N(SyntaxKind.LineSpanDirectiveTrivia); + { + N(SyntaxKind.HashToken); + N(SyntaxKind.LineKeyword); + N(SyntaxKind.LineDirectivePosition); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.NumericLiteralToken, "1"); + N(SyntaxKind.CommaToken); + N(SyntaxKind.NumericLiteralToken, "2"); + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.MinusToken); + N(SyntaxKind.LineDirectivePosition); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.NumericLiteralToken, "3"); + N(SyntaxKind.CommaToken); + N(SyntaxKind.NumericLiteralToken, "4"); + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.StringLiteralToken, "\"file.cs\""); + N(SyntaxKind.EndOfDirectiveToken); + } + EOF(); + } + + [Fact, WorkItem(61663, "https://github.com/dotnet/roslyn/issues/61663")] public void LineDirective_06() { string source = @"#line(1,2)-(3,4)5""file.cs"""; + UsingLineDirective(source, options: null, + // (1,6): error CS9028: The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + // #line(1,2)-(3,4)5"file.cs" + Diagnostic(ErrorCode.ERR_LineSpanDirectiveRequiresSpace, "(1,2)").WithLocation(1, 6), + // (1,17): error CS9028: The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + // #line(1,2)-(3,4)5"file.cs" + Diagnostic(ErrorCode.ERR_LineSpanDirectiveRequiresSpace, "5").WithLocation(1, 17), + // (1,18): error CS9028: The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + // #line(1,2)-(3,4)5"file.cs" + Diagnostic(ErrorCode.ERR_LineSpanDirectiveRequiresSpace, @"""file.cs""").WithLocation(1, 18) + ); + + N(SyntaxKind.LineSpanDirectiveTrivia); + { + N(SyntaxKind.HashToken); + N(SyntaxKind.LineKeyword); + N(SyntaxKind.LineDirectivePosition); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.NumericLiteralToken, "1"); + N(SyntaxKind.CommaToken); + N(SyntaxKind.NumericLiteralToken, "2"); + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.MinusToken); + N(SyntaxKind.LineDirectivePosition); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.NumericLiteralToken, "3"); + N(SyntaxKind.CommaToken); + N(SyntaxKind.NumericLiteralToken, "4"); + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.NumericLiteralToken, "5"); + N(SyntaxKind.StringLiteralToken, "\"file.cs\""); + N(SyntaxKind.EndOfDirectiveToken); + } + EOF(); + } + + [Fact] + public void LineDirective_06_WithRequiredSpaces() + { + string source = @"#line (1,2)-(3,4) 5 ""file.cs"""; + UsingLineDirective(source, options: null); N(SyntaxKind.LineSpanDirectiveTrivia); @@ -675,7 +752,7 @@ public void Incomplete_10() EOF(); } - [Fact] + [Fact, WorkItem(61663, "https://github.com/dotnet/roslyn/issues/61663")] public void Incomplete_11() { string source = @"#line (1, 2) - (3, 4)"; @@ -712,7 +789,7 @@ public void Incomplete_11() EOF(); } - [Fact] + [Fact, WorkItem(61663, "https://github.com/dotnet/roslyn/issues/61663")] public void Incomplete_12() { string source = @"#line (1, 2) - (3, 4) 5"; @@ -2266,5 +2343,159 @@ public void NotUTF8StringLiteral_16() } EOF(); } + + [Fact, WorkItem(61663, "https://github.com/dotnet/roslyn/issues/61663")] + public void RequireSpace_BeforeFirstParen() + { + string source = @"#line(1, 2) - (3, 4) ""file.cs"""; + + UsingLineDirective(source, TestOptions.Regular10, + // (1,6): error CS9028: The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + // #line(1, 2) - (3, 4) "file.cs" + Diagnostic(ErrorCode.ERR_LineSpanDirectiveRequiresSpace, "(1, 2)").WithLocation(1, 6) + ); + + N(SyntaxKind.LineSpanDirectiveTrivia); + { + N(SyntaxKind.HashToken); + N(SyntaxKind.LineKeyword); + N(SyntaxKind.LineDirectivePosition); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.NumericLiteralToken, "1"); + N(SyntaxKind.CommaToken); + N(SyntaxKind.NumericLiteralToken, "2"); + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.MinusToken); + N(SyntaxKind.LineDirectivePosition); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.NumericLiteralToken, "3"); + N(SyntaxKind.CommaToken); + N(SyntaxKind.NumericLiteralToken, "4"); + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.StringLiteralToken, "\"file.cs\""); + N(SyntaxKind.EndOfDirectiveToken); + } + EOF(); + } + + [Fact, WorkItem(61663, "https://github.com/dotnet/roslyn/issues/61663")] + public void RequireSpace_BeforeCharacterOffset() + { + string source = @"#line (1, 2) - (3, 4)5 ""file.cs"""; + + UsingLineDirective(source, TestOptions.Regular10, + // (1,22): error CS9028: The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + // #line (1, 2) - (3, 4)5 "file.cs" + Diagnostic(ErrorCode.ERR_LineSpanDirectiveRequiresSpace, "5").WithLocation(1, 22) + ); + + N(SyntaxKind.LineSpanDirectiveTrivia); + { + N(SyntaxKind.HashToken); + N(SyntaxKind.LineKeyword); + N(SyntaxKind.LineDirectivePosition); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.NumericLiteralToken, "1"); + N(SyntaxKind.CommaToken); + N(SyntaxKind.NumericLiteralToken, "2"); + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.MinusToken); + N(SyntaxKind.LineDirectivePosition); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.NumericLiteralToken, "3"); + N(SyntaxKind.CommaToken); + N(SyntaxKind.NumericLiteralToken, "4"); + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.NumericLiteralToken, "5"); + N(SyntaxKind.StringLiteralToken, "\"file.cs\""); + N(SyntaxKind.EndOfDirectiveToken); + } + EOF(); + } + + [Fact, WorkItem(61663, "https://github.com/dotnet/roslyn/issues/61663")] + public void RequireSpace_BeforeFilename() + { + string source = @"#line (1, 2) - (3, 4) 5""file.cs"""; + + UsingLineDirective(source, TestOptions.Regular10, + // (1,24): error CS9028: The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + // #line (1, 2) - (3, 4) 5"file.cs" + Diagnostic(ErrorCode.ERR_LineSpanDirectiveRequiresSpace, @"""file.cs""").WithLocation(1, 24) + ); + + N(SyntaxKind.LineSpanDirectiveTrivia); + { + N(SyntaxKind.HashToken); + N(SyntaxKind.LineKeyword); + N(SyntaxKind.LineDirectivePosition); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.NumericLiteralToken, "1"); + N(SyntaxKind.CommaToken); + N(SyntaxKind.NumericLiteralToken, "2"); + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.MinusToken); + N(SyntaxKind.LineDirectivePosition); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.NumericLiteralToken, "3"); + N(SyntaxKind.CommaToken); + N(SyntaxKind.NumericLiteralToken, "4"); + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.NumericLiteralToken, "5"); + N(SyntaxKind.StringLiteralToken, "\"file.cs\""); + N(SyntaxKind.EndOfDirectiveToken); + } + EOF(); + } + + [Fact, WorkItem(61663, "https://github.com/dotnet/roslyn/issues/61663")] + public void RequireSpace_BeforeFilename_WithoutCharacterOffset() + { + string source = @"#line (1, 2) - (3, 4)""file.cs"""; + + UsingLineDirective(source, TestOptions.Regular10, + // (1,22): error CS9028: The #line span directive requires space before the first parenthesis, before the character offset, and before the file name + // #line (1, 2) - (3, 4)"file.cs" + Diagnostic(ErrorCode.ERR_LineSpanDirectiveRequiresSpace, @"""file.cs""").WithLocation(1, 22) + ); + + N(SyntaxKind.LineSpanDirectiveTrivia); + { + N(SyntaxKind.HashToken); + N(SyntaxKind.LineKeyword); + N(SyntaxKind.LineDirectivePosition); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.NumericLiteralToken, "1"); + N(SyntaxKind.CommaToken); + N(SyntaxKind.NumericLiteralToken, "2"); + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.MinusToken); + N(SyntaxKind.LineDirectivePosition); + { + N(SyntaxKind.OpenParenToken); + N(SyntaxKind.NumericLiteralToken, "3"); + N(SyntaxKind.CommaToken); + N(SyntaxKind.NumericLiteralToken, "4"); + N(SyntaxKind.CloseParenToken); + } + N(SyntaxKind.StringLiteralToken, "\"file.cs\""); + N(SyntaxKind.EndOfDirectiveToken); + } + EOF(); + } } }