Skip to content
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

No validation for pre-processor symbols in C# Parse Options, and report multiple errors #16920

Closed
wants to merge 3 commits into from
Closed

No validation for pre-processor symbols in C# Parse Options, and report multiple errors #16920

wants to merge 3 commits into from

Conversation

OmarTawfik
Copy link
Contributor

@OmarTawfik OmarTawfik commented Feb 3, 2017

Fixes #15900 in both C# and VB, by removing validation from ParseOptions, and adding tests to make sure that it doesn't throw exceptions.

Fixes #16913 only in C#, as VB parses input as tokens (not by splitting input), and has special back-compat reasons for keeping this behavior.

Note to self: inspect breaking API change.

@@ -3263,7 +3263,6 @@ override Microsoft.CodeAnalysis.CSharp.Syntax.XmlTextSyntax.Accept<TResult>(Micr
override Microsoft.CodeAnalysis.CSharp.Syntax.YieldStatementSyntax.Accept(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor visitor) -> void
override Microsoft.CodeAnalysis.CSharp.Syntax.YieldStatementSyntax.Accept<TResult>(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor<TResult> visitor) -> TResult
static Microsoft.CodeAnalysis.CSharp.CSharpCommandLineParser.Default.get -> Microsoft.CodeAnalysis.CSharp.CSharpCommandLineParser
static Microsoft.CodeAnalysis.CSharp.CSharpCommandLineParser.ParseConditionalCompilationSymbols(string value, out System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.Diagnostic> diagnostics) -> System.Collections.Generic.IEnumerable<string>
Copy link
Member

@CyrusNajmabadi CyrusNajmabadi Feb 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this actually shipped? If so, this is a binary breaking change. #Resolved

@OmarTawfik
Copy link
Contributor Author

OmarTawfik commented Feb 3, 2017

@CyrusNajmabadi @jaredpar @dotnet/roslyn-compat-council
For the API change here, I'd prefer to undo it if it is going to break existing scenarios.
But looking at CSharpCommandLineParser, it looks like the only other public method there is the Parse(), and all others are:

  1. Private (to be used from the main Parse() method.
  2. Take a diagnostics list that they add errors to.

Is there a reason that this specific ParseConditionalCompilationSymbols was made public and made to have an out parameter? was it by error? is there some external user?
If not, and we're OK taking this change, I'd suggest to do it to keep the public surface aligned. #Resolved

@CyrusNajmabadi
Copy link
Member

CyrusNajmabadi commented Feb 3, 2017

First, let's find out when that API was added. If it was between 2015 and 2017, we can remove it. However, if it's been shipped from before 2017, then we basically can't remove it. Talk to @jaredpar if you want more info on our exceptionally high breaking-change bar. #Resolved

Assert.Throws<ArgumentException>(() => new CSharpParseOptions(preprocessorSymbols: ImmutableArray.Create<string>("Good", null, @"Bad\Symbol")));
var options = new CSharpParseOptions(preprocessorSymbols: new string[] { "valid1", "2invalid" });

Assert.Equal(2, options.PreprocessorSymbolNames.Count());
Copy link
Member

@jcouv jcouv Feb 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is an AssertEx.Equal overload that could be used for this comparison, and the one in the following test. #Resolved

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but the shipped API needs to be restored for back compat.

FYI @jaredpar @gafter regarding addition of new public API. My take is that we should not add the new one (only keep the old one, even though it is clunkier).

@OmarTawfik
Copy link
Contributor Author

OmarTawfik commented Feb 7, 2017

API changes reverted, per general guidance from team.
@dotnet/roslyn-compiler can I get a second review? #Resolved

@@ -1470,7 +1470,7 @@ private ImmutableArray<string> BuildSearchPaths(string sdkDirectoryOpt, List<str

public static IEnumerable<string> ParseConditionalCompilationSymbols(string value, out IEnumerable<Diagnostic> diagnostics)
{
Diagnostic myDiagnostic = null;
List<Diagnostic> myDiagnostics = new List<Diagnostic>();
Copy link
Member

@jcouv jcouv Feb 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: outputDiagnostics or resultDiagnostics maybe? #Resolved

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -1470,7 +1470,7 @@ private ImmutableArray<string> BuildSearchPaths(string sdkDirectoryOpt, List<str

public static IEnumerable<string> ParseConditionalCompilationSymbols(string value, out IEnumerable<Diagnostic> diagnostics)
{
Diagnostic myDiagnostic = null;
List<Diagnostic> myDiagnostics = new List<Diagnostic>();
Copy link
Contributor

@AlekseyTs AlekseyTs Feb 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

List myDiagnostics = new List(); [](start = 12, length = 56)

Can we use a DiagnosticBag instead (probably from the pool)? #Resolved

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or an ArrayBuilder? We usually don't use List of T.


In reply to: 100169189 [](ancestors = 100169189)

Copy link
Contributor

@AlekseyTs AlekseyTs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look like we are validating pre-processor symbols in parse options. I thought the plan was to move validation elsewhere.

@@ -8101,6 +8101,31 @@ End Module
Assert.Equal($"error BC2012: can't open '{sourceLinkPath}' for writing: Fake IOException{Environment.NewLine}", outWriter.ToString())
End Sub

<WorkItem(15900, "https://github.com/dotnet/roslyn/issues/15900")>
<Fact>
Public Sub CompilingCodeWithInvalidPreProcessorSymbolsShouldErrorOut()
Copy link
Contributor

@AlekseyTs AlekseyTs Feb 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CompilingCodeWithInvalidPreProcessorSymbolsShouldErrorOut [](start = 19, length = 57)

Could you include how the errors look like as text, as comments perhaps? #Resolved

@OmarTawfik
Copy link
Contributor Author

OmarTawfik commented Feb 8, 2017

It doesn't look like we are validating pre-processor symbols in parse options. I thought the plan was to move validation elsewhere.

@jaredpar can you please check @AlekseyTs's comment here per #15900 description?
Edit: Validation is done during compilation (not when creating API objects). We need to add it through compilation API as well.

@OmarTawfik
Copy link
Contributor Author

Based on discussion with AlekseyTs, there are surfaces that are not covered by this change.
For example SyntaxFactory.ParseTokens(). Closing for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants