Roslyn context.SemanticModel.GetDeclaredSymbol() returning NULL from InvocationExpression - vb.net

Trying to develop an VS extension to help with migration from vb6 to Vb.net using Roslyn.
Unfortunately I am not having much luck with detecting the "DoEvents" expression in my source as I get NULL from my GetDeclaredSymbol during the detection.
My bad coding is......
Register the action:
context.RegisterSyntaxNodeAction(AddressOf ExpressionStatementDec, SyntaxKind.InvocationExpression)
Try and detect the "DoEvents" expression:
Private Sub ExpressionStatementDec(context As SyntaxNodeAnalysisContext)
Dim GotYou = context.SemanticModel.GetDeclaredSymbol(context.Node)
Dim WhatExpression = context.Node.ToFullString.ToString
' Find DoEvents.
If RemoveWhitespace(WhatExpression) = "DoEvents" Then
Dim diag = Diagnostic.Create(Rule, GotYou.Locations(0), GotYou.Name)
context.ReportDiagnostic(diag)
End If
End Sub
I have tried loads of options for trying to get the right type of object for "GotYou" but no luck so far.
Any pointers appreciated :)
Edit Additional info:
I have tried GetSymbolInfo but when I am detecting "DoEvents" in the context.Node.ToFullString.ToString I am still not getting anything in the context.SemanticModel.GetSymbolInfo(context.Node) as below.
Thanks,
Richard

If you want to look at what a invocation is referencing, call GetSymbolInfo not GetDeclaredSymbol.

Don’t have Visual Studio handy in order to get the code, but...
I believe what you want is something like:
Dim WhatExpression = TryCast(CType(context.Node, InvocationExpressionSyntax).Expression, IdentifierNameSyntax)?.Identifier.Text
This isn’t all of it, you could be dealing with a memberaccessexpression, in which case it’s probably not what you are looking for. The options would be a bit easier to handle with pattern matching in C#, but that’s the general idea. You don’t need the semantic tree at this point, because you first want to verify that you are dealing with the right text. Once you’ve got that, you can see where it comes from and whether it is something you need to deal with. Getting the semantic model is expensive, no reason to do so when (outside of your unit test) it is rarely going to be needed.

Related

LINQ query to filter a list returns nothing

Following a tutorial, i've built a LINQ query to filter a List of objects:
Dim Query = From FilteredItem In Items, FiltSupp In FilteredItem.Suppliers
Where ((SuppliersComboBox.SelectedItem.ToString = "All Suppliers" OrElse FiltSupp.CompanyName = SelectedSupplier) And
(String.IsNullOrEmpty(TxtItemCode.Text) OrElse FilteredItem.ItemCode.ToString.Contains(TxtItemCode.Text)) And
(String.IsNullOrEmpty(TxtName.Text) OrElse FilteredItem.Name.ToLower.Contains(TxtName.Text.ToLower)) And
(String.IsNullOrEmpty(TxtPkgCost.Text) OrElse FilteredItem.PkgCost.ToString.Contains(TxtPkgCost.Text)))
Select FilteredItem
The problem is that the query returns nothing even when the list is being populated.
At debugging, the list value is correct (populated with few items), but the query doesn't returning anything. I can't figure out what is wrong, so any suggestion would be greatly appreciated!
Ps. I'm using vb.net, but answers in C# are also wellcome
To start off with, this answer is obviously not complete yet, so please hold off any downvotes until I finalize it. I have every intention of helping the OP if I can, however at this time there is no way for me to even begin helping out because the information needed is not present.
#ISAE, Can you please provide the following:
hoping the Items being queried is a strongly typed DataTable; the class file for the Items object type, preferably the designer files also (.xsc, .xsd, and .xss)
the forms' designer files and code behinds.
Alternatively, if the project can be put on GitHub, that would be even better. If you can't release all of that code, then really need to know enough to somewhat reconstruct what's going on. As one of the comments pointed out, that LINQ query is really messy and it's hard to dissect right now.

The specified RegistryOptions value is invalid

What im trying to do is write a key to the registry but im stepping from one problem to another, first permissions problem, now this..
This is the line of code.
If PNGchk.Checked = True Then
My.Computer.Registry.Users.CreateSubKey(UserSID & "\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.png\UserChoice", True, Security.AccessControl.RegistryRights.FullControl).SetValue("Progid", "SIV.png", Microsoft.Win32.RegistryValueKind.String)
End If
You must have Option Strict Off for that code to even compile, so you might want to fix that to start with. Option Strict On would have flagged issues with that code right away. You should read the documentation or at least pay attention to Intellisense for that method because your second and third arguments make no sense. No overload that I can see has a Boolean parameter and if you want to use a RegistryRights value you do so within a RegistrySecurity object as far as I can see.
RegistryKeyPermissionCheck.ReadWriteSubTree worked for me.
Using clsid64 = view64.CreateSubKey("Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.png\UserChoice", RegistryKeyPermissionCheck.ReadWriteSubTree)
clsid64.SetValue("StubPath", "SIV.png")
clsid64.Close()
End Using

Using colons to put two statements on the same line in Visual Basic [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
Is it considered bad practice to use colons to put two statements on the same line in Visual Basic?
There is nothing inherently wrong with using the colon to combine statements. It really depends on the context but as long as it doesn't reduce readability, there is nothing wrong with it.
As a general rule I avoid using the colon for this purpose. I find it's more readable to have one statement per line. However this is not a colon specific issue. I avoid doing the same with a semi-colon in C# or C++. It's just a personal preference.
It's a good practice in moderation, because sometimes readability is enhanced by concatenating two lines:
when the lines are short and intimately
related
when the lines are short and trivial
Option Compare Database: Option Explicit ''My favorite!
rsDataSet.Close: Set rsDataSet= Nothing
Don't do it if:
it hurts readability.
it complicates debugging. Control structures such as If...Then need to stay clean. You'll be glad you kept it simple when it's time to set a break point.
it compromises future editing. Often you want to keep sections portable. Moving or re-structuring a block of code is easily hindered by attempts to minimize your code.
In general, I'd advise against it, as it makes for busier code.
However, for simple tasks, there is nothing wrong with it. For instance:
for i = 1 to 10: ProcessFoo(i): next
I think a line like this is short enough not to cause confusion.
I'll take the other side. I don't like dense lines of code. It is easier to skim code when lines are not combined.
Combining statements also makes it easier to create long functions that still fit on a single screen.
It isn't a major sin, I just don't like it.
I also don't like one line If statements.
To me you shouldn't say "never do thus", you should just say "If you do this, a possible problem is such and such." Then just weigh the pros and cons for yourself. The pro is brevity/few lines of code. Sometimes this can aid readability. For instance some people use it to do vb.Net declarations:
Dim x As Long: x = 1
Or wait loops:
Do Until IE.ReadyState = READYSTATE_COMPLETE: DoEvents: Loop
But obviously you can really make it rough on someone too:
Public Sub DoYouKnowWhatThisDoes()
MsgBox Example
End Sub
Private Function Example()
Const s$ = "078243185105164060193114247147243200250160004134202029132090174000215255134164128142"
Const w% = 3: Const l% = 42: Dim i%, r$: For i = 1 To l Step w: r = r & ChrW$(Mid$(s, i, w) Xor Mid$(s, i + l, w)): Next: Example = r
End Function
Another practical reason that you might not want to use this approach is breakpoints. Breakpoints can only be set by the line. So if you have several things executing on the same line you can't isolate the second thing. It will stop on the first statement. (This is also one of the reasons some people don't like single line ifs.) It just complicates debugging a little.
I usually don't use colons in production code for this reason. However I do use them to improve the brevity of "copy/paste" code that I post in forums and elsewhere. YMMV:)
I realize this is a very old question, but it was the first result on my Google search, so I hope I can be forgiven for chiming in here.
There is one situation (exactly what led me here in fact) in which this approach is not only useful, it's the only way to accomplish the desired result: the Immediate window. Any code you want to execute in the Immediate window must all be on one line. So in order to use any form of Do, Case, For, While, or With in the Immediate window, you will need to use colons.
It is considered bad practice in most of the sites at which I have worked. And by most of the VB developers with whom I have worked. And in my head. If I see it, I will admit that I would almost certainly change it. I say "almost" because I admit there's a possibility that I could find a piece of code that looked better that way. I don't expect to see it in my lifetime, though.
I also really don't like one-line **If**s either.
Both are most likely hangovers from the days of VGA (640x480) monitors; that's no excuse these days.
I've only ever used it when I'm clsoing a recordset and setting the variable to nothing. I figure one line instead of two gives me more lines of code on the screen and doesn't detract from readability.
I've seen it used in simple select cases such as the following but that would be as far as I would go.
Select Case success
Case ERROR_FILE_NO_ASSOCIATION: msg = "no association"
Case ERROR_FILE_NOT_FOUND: msg = "file not found"
Case ERROR_PATH_NOT_FOUND: msg = "path not found"
Case ERROR_BAD_FORMAT: msg = "bad format"
from http://vbnet.mvps.org/index.html?code/system/findexecutable.htm
And even then I would've lined up the "msg =" portion.
I've never seen this mentioned in an official capacity at any of the companies which I've worked. But I do think that using colons excessively can start to make your code less readable and more of a pain to maintain.
I do tend to use these myself at times, for example when checking for cancel in one of my recent projects:
If _bCancel Then Status = CancelProcess() : Return Status
Putting this in kept my code readable than the alternative IF block.
But it can be taken too far, I've recently inherited a project which is replete with examples of taking colon usage too far :
Select Case GetStringValue(Index).Trim.ToLower
Case "yes", "y" : GetBooleanValue = True
Case "no", "n" : GetBooleanValue = False
Case Else : GetBooleanValue = Nothing
End Select
Personally I find the above to be a bit much.
I like this one
Using pro As New Process() : With pro
...
End With
End Using
I've seen it used in class declarations when using inheritance or implementing an interface:
Public Class DerivedClass : Inherits BaseClass
...
End Class
But like the others, I also discourage its use.
Chris
The answer to the question is No. Anything beyond No is purely subjective and wasteful irrespective of the answer outside of a simple No. Below is my waste of typing.
Are you some sort of slave? Do as you wish. You are the center of your universe not some stranger from StackOverflow. If you work for a company the question is mute because coding style would already be defined and completely out of your control. As for one's self, who in this universe is going to ever in all eternity look at let along care about your code.
I would choose A over B. As evident this shows the purpose of a colon without the use of a colon. It's to save space. Below saves space and makes code far more readable. Keeps It Simple Stupid. Same for ternary ? : usage. When the code is inherently complex then a colon, single line if then else, or ternary no longer should be considered.
'================================================================
'A
If somevalue1 = 0 Then AddLogTry("True") Else AddLogFalse("False")
If somevalue2 = 0 Then AddLogTry("True") Else AddLogFalse("False")
If somevalue3 = 0 Then AddLogTry("True") Else AddLogFalse("False")
'================================================================
'================================================================
'B
If somevlaue1 = 0 Then
AddLogTrue("True")
Else
AddLogFalse("False")
EndIf
If somevlaue2 = 0 Then
AddLogTrue("True")
Else
AddLogFalse("False")
EndIf
If somevlaue3 = 0 Then
AddLogTrue("True")
Else
AddLogFalse("False")
EndIf
'================================================================

When is it OK to use the GoTo statement in VB.Net?

I have process that needs to create a bunch of records in the database and roll everything back if anything goes wrong. What I want to do is this:
Public Structure Result
Public Success as Boolean
Public Message as String
End Structure
Private _Repository as IEntityRepository
Public Function SaveOrganization( _
ByVal organization As rv_o_Organization) As Result
Dim result = Result.Empty
_Repository.Connection.Open()
_Repository.Transaction = _Repository.Connection.BeginTransaction()
''//Performs validation then saves it to the database
''// using the current transaction
result = SaveMasterOrganization(organization.MasterOrganization)
If (Not result.Success) Then
GoTo somethingBadHappenedButNotAnException
End If
''//Performs validation then saves it to the database
''//using the current transaction
result = SaveOrganziation(dbOrg, organization)
If (Not result.Success) Then GoTo somethingBadHappenedButNotAnException
somethingBadHappenedButNotAnException:
_Repository.Transaction.Commit()
_Repository.Connection.Close()
Return result
End Sub
Is this an ok use of the GoTo statement, or just really bad design? Is there a more elegant solution? Hopefully this sample is able to get the point across
If you have to ask, don't do it.
For your specific code, you could do it like this:
Public Function SaveOrganization(ByVal organization As rv_o_Organization) As Result
Dim result As Result = Result.Empty
_Repository.Connection.Open()
_Repository.Transaction = _Repository.Connection.BeginTransaction()
'Performs validation then saves it to the database
'using the current transaction
result = SaveMasterOrganization(organization.MasterOrganization)
'Performs validation then saves it to the database
'using the current transaction
If result.Success Then result = SaveOrganziation(dbOrg, organization)
_Repository.Transaction.Commit()
_Repository.Connection.Close()
Return result
End Sub
Goto has such a terrible reputation that it will cause other developers to instantly think poorly of your code. Even if you can demonstrate that using a goto was the best design choice - you'll have to explain it again and again to anyone who sees your code.
For the sake of your own reputation, just don't do it.
Really bad design. Yes.
There might be some extreme edge cases where it is applicable, but almost unequivocally, no, do not use it.
In this specific case, you should be using the Using statement to handle this in a better manner. Generally, you would create a class which would implement IDisposable (or use one that already does) and then handle cleanup in the Dispose method. In this case, you would close the connection to the database (apparently, it is reopened again from your design).
Also, I would suggest using the TransactionScope class here as well, you can use that to scope your transaction and then commit it, as well as auto-abort in the face of exceptions.
The only time you should use a goto, is when there is no other alternative.
The only way to find out if there are no other alternatives is to try them all.
In your particular example, you should use try...finally instead, like this (sorry, I only know C#)
void DoStuff()
{
Connection connection = new Connection();
try
{
connection.Open()
if( SomethingBadHappened )
return;
}
finally
{
connection.Close();
}
}
I would say extremely sparingly. Anytime I have had to think about using a GOTO statement, I try and refactor the code. The only exception I can think of was in vb with the statement On Error Goto.
There is nothing inherently wrong with goto, but this isn't a very ideal use of it. I think you are putting too fine a point on the definition of an exception.
Just throw a custom exception and put your rollback code in there. I would assume you would also want to rollback anyway if a REAL exception occured, so you get double duty out of it that way too.
Gotos are simply an implementation detail. A try/catch is much like a goto (an inter-stack goto at that!) A while loop (or any construct) can be written with gotos if you want. Break and early return statements are the most thinly disguised gotos of them all--they are blatant(and some people dislike them because of the similarity)
So technically there is nothing really WRONG with them, but they do make for more difficult code. When you use the looping structures, you are bound to the area of your braces. There is no wondering where you are actually going to, searching or criss-crossing.
On top of that, they have a REALLY BAD rep. If you do decide to use one, even in the best of possible cases, you'll have to defend your decision against everyone who ever reads your code--and many of those people you'll be defending against won't have the capability to make the judgment call themselves, so you're encouraging bad code all around.
One solution for your case might be to use the fact that an early return is the same as a goto (ps. Worst psuedocode ever):
dbMethod() {
start transaction
if(doWriteWorks())
end Transaction success
else
rollback transaction
}
doWriteWorks() {
validate crap
try Write crap
if Fail
return false
validate other crap
try Write other crap
if Fail
return false
return true
}
I think this pattern would work in VB, but I haven't used it since VB 3 (around the time MS bought it) so if transactions are somehow bound to the executing method context or something, then I dunno. I know MS tends to bind the database very closely to the structure of the code or else I wouldn't even consider the possibility of this not working...
I use goto's all the time in particular places, for example right above a Try Catch, in case a you prompt the user, "Retry?, Cancel", if retry then Goto StartMyTask: and increment the Current Try of Maximum retries depending on the scenario.
They're also handy in for each loops.
For each Items in MyList
If VaidationCheck1(Item) = false then goto SkipLine
If ValidationCheck(Item) = false then goto skipline
'Do some logic here, that can be avoided by skipping it to get better performance.
'I use then like short circuit operands, why evaluate more than you actually have to?
SkipLine:
Next
I wouldn't substitute them for functions and make really huge blocks of long code, just in little places where they can really help, mostly to skip over things.
Everytime I've seen a goto used, simple refactoring could have handle it. I'd reccomend never using it unless you "know" that you have to use it
I'm tempted to say never, but I suppose there is always one case where it may be the best solution. However, I've programmed for the last 20 years or so without using a Goto statement and can't foresee needing one any time soon.
Why not wrap each function call in a try catch block and when that is done, if one of your exceptions are thrown, you can catch it and close the connection. This way, you avoid the GOTO statement altogether.
In short, the GOTO statement is NOT a good thing, except in unusual situations, and even then it is usually a matter of refactoring to avoid it. Don't forget, it is a leftover from early languages, in this case BASIC.
I'd say use very sparingly as it's generally associated with introducing spagetti code. Try using methods instead of Labels.
A good case I think for using GOTO is to create a flow through select which is available in C# but not VB.
The go to statement has a tendency to make the program flow difficult to understand. I cannot remember using it during the last ten years, except in visual basic 6 in combination with "on error".
Your use of the go to is acceptable as far as I am concerned, because the program flow is very clear. I don't think using try ... catch would improve things much, because you would need to throw the exceptions on the locations where the go tos are now.
The formatting, however, is not very appealing:-)
I would change the name of the go to label to something else, because this location is also reached when everything is successful. clean_up: would be nice.
Eh, there was a decent use for it in VBscript/ASP for handling errors. We used it to return error handling back to ASP once we were done using on error resume next.
in .net? Heavens, no!
Everyone says avoid it but why.
The GOTO syntax is a jump statement in assembly - very efficient.
Main reason to avoid it is code readability. You need to find the GOTO label in the code which is hard to eyeball.
Some people think that it might cause memory leaks but I've seen that experts say that this is not true in .NET.

What's bad about the VB With/End With keyword?

In this question, a user commented to never use the With block in VB. Why?
"Never" is a strong word.
I think it fine as long as you don't abuse it (like nesting)
IMHO - this is better:
With MyCommand.Parameters
.Count = 1
.Item(0).ParameterName = "#baz"
.Item(0).Value = fuz
End With
Than:
MyCommand.Parameters.Count = 1
MyCommand.Parameters.Item(0).ParameterName = "#baz"
MyCommand.Parameters.Item(0).Value = fuz
There is nothing wrong about the With keyword. It's true that it may reduce readibility when nested but the solution is simply don't use nested With.
There may be namespace problems in Delphi, which doesn't enforce a leading dot but that issue simply doesn't exist in VB.NET so the people that are posting rants about Delphi are losing their time in this question.
I think the real reason many people don't like the With keyword is that is not included in C* languages and many programmers automatically think that every feature not included in his/her favourite language is bad.
It's just not helpful compared to other options.
If you really miss it you can create a one or two character alias for your object instead. The alias only takes one line to setup, rather than two for the With block (With + End With lines).
The alias also gives you a quick mouse-over reference for the type of the variable. It provides a hook for the IDE to help you jump back to the top of the block if you want (though if the block is that large you have other problems). It can be passed as an argument to functions. And you can use it to reference an index property.
So we have an alternative that gives more function with less code.
Also see this question:
Why is the with() construct not included in C#, when it is really cool in VB.NET?
The with keyword is only sideswiped in a passing reference here in an hilarious article by the wonderful Verity Stob, but it's worth it for the vitriol: See the paragraph that starts
While we are on identifier confusion. The with keyword...
Worth reading the entire article!
The With keyword also provides another benefit - the object(s) in the With statement only need to be "qualified" once, which can improve performance. Check out the information on MSDN here:
http://msdn.microsoft.com/en-us/library/wc500chb(VS.80).aspx
So by all means, use it.