@@ -869,6 +869,9 @@ internal static partial class Patterns
869869{
870870 [ GeneratedRegex ( """\s+""" ) ]
871871 public static partial Regex Whitespace { get ; }
872+
873+ [ GeneratedRegex ( """[\s@=/]""" ) ]
874+ public static partial Regex DisallowedNameCharacters { get ; }
872875}
873876
874877/// <summary>
@@ -907,25 +910,29 @@ private CSharpDirective() { }
907910 }
908911 }
909912
910- private static ( string , string ? ) ? ParseOptionalTwoParts ( ImmutableArray < SimpleDiagnostic > . Builder ? errors , SourceFile sourceFile , TextSpan span , string directiveKind , string directiveText , SearchValues < char > ? separators = null )
913+ private static ( string , string ? ) ? ParseOptionalTwoParts ( ImmutableArray < SimpleDiagnostic > . Builder ? errors , SourceFile sourceFile , TextSpan span , string directiveKind , string directiveText , char separator )
911914 {
912- var i = separators != null
913- ? directiveText . AsSpan ( ) . IndexOfAny ( separators )
914- : directiveText . IndexOf ( ' ' , StringComparison . Ordinal ) ;
915- var firstPart = i < 0 ? directiveText : directiveText [ ..i ] ;
915+ var i = directiveText . IndexOf ( separator , StringComparison . Ordinal ) ;
916+ var firstPart = ( i < 0 ? directiveText : directiveText . AsSpan ( ..i ) ) . Trim ( ) ;
916917
917- if ( string . IsNullOrWhiteSpace ( firstPart ) )
918+ if ( firstPart . IsWhiteSpace ( ) )
918919 {
919920 return ReportError < ( string , string ? ) ? > ( errors , sourceFile , span , string . Format ( CliCommandStrings . MissingDirectiveName , directiveKind , sourceFile . GetLocationString ( span ) ) ) ;
920921 }
921922
923+ // If the name contains characters that resemble separators, report an error to avoid any confusion.
924+ if ( Patterns . DisallowedNameCharacters . IsMatch ( firstPart ) )
925+ {
926+ return ReportError < ( string , string ? ) ? > ( errors , sourceFile , span , string . Format ( CliCommandStrings . InvalidDirectiveName , directiveKind , separator , sourceFile . GetLocationString ( span ) ) ) ;
927+ }
928+
922929 var secondPart = i < 0 ? [ ] : directiveText . AsSpan ( ( i + 1 ) ..) . TrimStart ( ) ;
923930 if ( i < 0 || secondPart . IsWhiteSpace ( ) )
924931 {
925- return ( firstPart , null ) ;
932+ return ( firstPart . ToString ( ) , null ) ;
926933 }
927934
928- return ( firstPart , secondPart . ToString ( ) ) ;
935+ return ( firstPart . ToString ( ) , secondPart . ToString ( ) ) ;
929936 }
930937
931938 /// <summary>
@@ -945,7 +952,7 @@ private Sdk() { }
945952
946953 public static new Sdk ? Parse ( ImmutableArray < SimpleDiagnostic > . Builder ? errors , SourceFile sourceFile , TextSpan span , string directiveKind , string directiveText )
947954 {
948- if ( ParseOptionalTwoParts ( errors , sourceFile , span , directiveKind , directiveText ) is not var ( sdkName , sdkVersion ) )
955+ if ( ParseOptionalTwoParts ( errors , sourceFile , span , directiveKind , directiveText , separator : '@' ) is not var ( sdkName , sdkVersion ) )
949956 {
950957 return null ;
951958 }
@@ -976,7 +983,7 @@ private Property() { }
976983
977984 public static new Property ? Parse ( ImmutableArray < SimpleDiagnostic > . Builder ? errors , SourceFile sourceFile , TextSpan span , string directiveKind , string directiveText )
978985 {
979- if ( ParseOptionalTwoParts ( errors , sourceFile , span , directiveKind , directiveText ) is not var ( propertyName , propertyValue ) )
986+ if ( ParseOptionalTwoParts ( errors , sourceFile , span , directiveKind , directiveText , separator : '=' ) is not var ( propertyName , propertyValue ) )
980987 {
981988 return null ;
982989 }
@@ -1009,16 +1016,14 @@ private Property() { }
10091016 /// </summary>
10101017 public sealed class Package : CSharpDirective
10111018 {
1012- private static readonly SearchValues < char > s_separators = SearchValues . Create ( ' ' , '@' ) ;
1013-
10141019 private Package ( ) { }
10151020
10161021 public required string Name { get ; init ; }
10171022 public string ? Version { get ; init ; }
10181023
10191024 public static new Package ? Parse ( ImmutableArray < SimpleDiagnostic > . Builder ? errors , SourceFile sourceFile , TextSpan span , string directiveKind , string directiveText )
10201025 {
1021- if ( ParseOptionalTwoParts ( errors , sourceFile , span , directiveKind , directiveText , s_separators ) is not var ( packageName , packageVersion ) )
1026+ if ( ParseOptionalTwoParts ( errors , sourceFile , span , directiveKind , directiveText , separator : '@' ) is not var ( packageName , packageVersion ) )
10221027 {
10231028 return null ;
10241029 }
0 commit comments