Open paul1956 opened 7 years ago
@jcouv do you need a list of all the places I found where this doesn't work? In addition to the list above If forEachStatement.Expression.Type is an ArrayType you also get nothing, there are more.
Let me start with those two and see if there is a common cause. If it feels like each scenario needs to be addressed separately, I'll ask you to list scenarios you ran into. Thanks
I have found workarounds for many of the cases where Nothing is returned but the case below (found in VisualBasicExtensions.vb) completely stumps me
Dim syntax As SyntaxToken
For Each diag In syntax.Errors
@paul1956 I tried this with latest bits (15.5 bits) and didn't see a problem.
<Fact>
Public Sub ForeachRepro()
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(
<compilation>
<file name="a.vb">
Module Module1
Sub M(s As String)
For Each c In s
Next
End Sub
End Module
</file>
</compilation>)
Dim tree = comp.SyntaxTrees(0)
Dim model = comp.GetSemanticModel(tree)
Dim nodes = tree.GetCompilationUnitRoot().DescendantNodes()
Dim node = nodes.OfType(Of ForEachStatementSyntax)().Single()
Dim foreachInfo = model.GetForEachStatementInfo(node)
Assert.Equal("System.Char", foreachInfo.ElementType.ToTestDisplayString())
End Sub
@jcouv I agree many of the cases I first reported are fixed in 2.6 but I am still seeing other cases where nothing is returned. How can I find out what was fixed? I am working on how to step through ElementType so I can report the path causing the issues. For Example from AbstractFlowPass.vb
Private Sub ResolveBreaks(breakState As LocalState, breakLabel As LabelSymbol)
Dim newPendingBranches As ArrayBuilder(Of PendingBranch) = ArrayBuilder(Of PendingBranch).GetInstance()
For Each pending In Me.PendingBranches
I am also looking at using your example so I can produce simple tests that fail.
@jcouv where do I get CreateCompilationWithMscorlibAndVBRuntime the one in Roslyn Master uses all kinds of Internal stuff and is not easily isolated for use by VB.
@paul1956 I wrote that test in context of Roslyn tests (for example in CodeGenTuples.vb
as a random place) as it was expedient.
You could either do the same, or set up your own compilation. The code for CreateCompilation...
is in src\Compilers\Test\Utilities\VisualBasic\CompilationTestUtils.vb
and basically does VisualBasicCompilation.Create
with a source tree (parsed from the test input), some assembly references (typically mscorlib and a reference for VB types) and trivial options.
Found the source for CreateCompilationWithMscorlibAndVBRuntime but getting the references from VB has provide to be difficult.
@jcouv what do you need more information about, The original issue ForEachStatementInfo.ElementType Returns Nothing in VB is still not fixed in 2.6 in the majority of cases but some of my original test cases are fixed.
@paul1956 Could you share a case that still not working? The case describe in OP and which I tried above was working:
For Each c In s
Next
Thanks
In Roslyn BasicCodeAnalysis the are 1123 places (out of 1208 For Each loops) that Nothing is returned most require other parts of Roslyn so I am having difficulty producing short examples. I would be happy to share the test that runs over the whole project and counts the number of times ElementType is Nothing's if that would help. I could also output the file name and line. For example from EmitStatement.VB line 142. I am normally doing this in the context of a CodeFix so I am not 100% sure these tests I faked are correct.
For Each catchBlock In statement.CatchBlocks
EmitCatchBlock(catchBlock)
Next
Also 2 tests I was able to put together that fail.
<Fact>
Public Sub ForeachRepro3()
Dim comp As VisualBasicCompilation = CreateCompilationWithMscorlibAndVBRuntime(
"Imports Microsoft.CodeAnalysis
Imports System.Runime
Class Class1
Sub Main()
Dim triviaToMove As SyntaxTriviaList = Nothing
For Each trivia In triviaToMove
Next
End Sub
End Class", "a.vb")
Dim tree As SyntaxTree = comp.SyntaxTrees(0)
Dim model As SemanticModel = comp.GetSemanticModel(tree)
Dim nodes As IEnumerable(Of SyntaxNode) = tree.GetCompilationUnitRoot().DescendantNodes()
Dim node As ForEachStatementSyntax = nodes.OfType(Of ForEachStatementSyntax)().Single()
Dim foreachInfo As ForEachStatementInfo = model.GetForEachStatementInfo(node)
Assert.NotNull(foreachInfo.ElementType)
End Sub
<Fact>
Public Sub ForeachRepro4()
Dim comp As VisualBasicCompilation = CreateCompilationWithMscorlibAndVBRuntime(
"Imports Microsoft.CodeAnalysis
Imports System.Runime
Class Class1
Sub Main()
Dim triviaToMove As SyntaxTriviaList = Nothing
For Each trivia In triviaToMove
Next
End Sub
End Class", "a.vb")
Dim tree As SyntaxTree = comp.SyntaxTrees(0)
Dim model As SemanticModel = comp.GetSemanticModel(tree)
Dim nodes As IEnumerable(Of SyntaxNode) = tree.GetCompilationUnitRoot().DescendantNodes()
Dim node As ForEachStatementSyntax = nodes.OfType(Of ForEachStatementSyntax)().Single()
Dim foreachInfo As ForEachStatementInfo = model.GetForEachStatementInfo(node)
Assert.NotNull(foreachInfo.ElementType)
End Sub
Thanks a bunch @paul1956 I'll check on those examples.
Those tests fail because the code is incomplete (SyntaxTriviaList
is undefined). I tried to provide minimal implementation of those types, but then GetForEachSatementInfo
returned a proper value.
I'll try your method of running an analyzer on the entire Roslyn codebase to repro.
I thought the test might be incomplete, I am not that familiar with writing them. But in real use 80% of the For Each statements in Roslyn return nothing. I have worked around some of it by using DetermineType but that only works 95% of the time. There are still a few that I can't figure out and way to get the Type.
Version Used: VS 15.3.5, VisualBasicCodeAalysis 2.3.2 Steps to Reproduce:
1 Set AnyString to any string for example "123abc"
Expected Behavior: It would contain the type of the elements Char in this case Actual Behavior: it returns Nothing There are many other cases were this happens, Is it better to list all here on one issue per type, right now I know about Class and Struct that implement IEnumbable(Of