How to edit default code generation in VS22 - visual-studio

I want to modify how some code in Visual Studio 22 is generated.
For instance, in methods I can generate null check on using the Add null check (MS docs link) for arguments in the following way.
public void MyMethod(object parameter)
{
if (object is null)
{
throw new ArgumentNullException(nameof(parameter));
}
// rest of the method
// ...
}
What I would like to be generated is this:
public void MyMethod(object parameter)
{
if (object is null) throw new ArgumentNullException(nameof(parameter));
// rest of the method
// ...
}
I was looking at code snippet settings and refactoring settings but I can not find the Add null check option anywhere. Let alone change it.
The best option I came up with is to create a code snippet (MS docs link) but that does not serve my purpose fully.
Is there an option I can modify to say how is the code generated?

Rewriting an answer by canton7 from the comments:
The Add null check is not generated by any code snippet. Rather it is based on the standard analyzer infrastructure (defined here and seen here). This means it is just a semantically generated if statement with a throw inside of it. Then based on your .editorconfig (or defaults if not specified) it formates the code accordingly.
One is left with the following options:
Edit the .editorconfig file to make the code format as pleased. Note that this approach applies globally.
Wait for the C# 11 !! syntax.
Write your own analyzer and code fix (tutorial).
Edit it by hand :).

Related

Why does Sonarqube mark try as a critical issue?

I'm currently facing an issue with some SonarQube's analysis being performed over some Kotlin code I wrote.
I'm trying to implement a method that connects to the database and returns accordingly to the query's result. I'm not sure how related this can be, but I added the following maven dependencies to my project:
Quarkus
Arrow
Ktorm
The code is the following:
#ApplicationScoped
class Repository(private val database: Database) {
override fun get(name: String): Either<Error, Brand> =
try {
database.brands.find { it.name eq name }.rightIfNotNull {
MissingBrandError("Missing brand")
}
} catch (e: Exception) {
Either.Left(DatabaseError(e.message))
}
}
class Error(val message: String)
class MissingUserError(val message: String) : Error(message)
class DatabaseError(val message: String? = null) : Error(message ?: "Some database error")
NOTE: Database object is of type org.ktorm.database.Database and brands is of type org.ktorm.entity.EntitySequence
The code is working and I also wrote unit tests for it that pass and give enough coverage (accordingly to the code coverage analysis tool), but at some point in my pipeline SonarQube marks the try as a critical issue with the following message:
Possible null pointer dereference in (...)Repository(String) due to return value of called method
I checked it online and I could find some related questions, but none of the provided answers worked for me. Amongst the many attempts these are the ones I can remember I tried without any success:
Not inlining any code (pretty much using Java style code)
Extracting the query result to a variable
Check with if/else statements for nullability instead (both with inlined try and without)
I'd also like to highlight that all I can see on Sonar is the generated report and CLI for the running build. I don't have access to any of its configuration or intended to change them (unless of course it comes down to that). The line I mentioned seems to be the only one affected by this problem according to Sonar's report, that's why this is the solo class I provided.
I hope I provided enough info and that any of you can help me with this. Thanks in advance.

Xpath Part NULL, with xpaths set via content control toolkit

I've been able to set, via code, the xpaths for the placeholders found in the document.
for (Object o : finderSdtRun.results) {
if (o instanceof SdtRun){
SdtPr sdtPr=((SdtRun) o).getSdtPr();
Tag t = sdtPr.getTag();
CTDataBinding ctDataBinding = Context.getWmlObjectFactory().createCTDataBinding();
//JAXBElement jaxbDB = Context.getWmlObjectFactory().createSdtPrDataBinding(ctDataBinding);
sdtPr.setDataBinding(ctDataBinding);
ctDataBinding.setXpath("tuttappostaferragost");
ctDataBinding.setStoreItemID("something");
ObjectFactory factory = new org.opendope.xpaths.ObjectFactory();
DataBinding db = factory.createXpathsXpathDataBinding();
db.setXpath("tuttappostaferragost");
db.setStoreItemID("something");
Xpaths.Xpath xp = factory.createXpathsXpath();
xp.setDataBinding(db);
xp.setId("something");
try {
wordMLPackage.getMainDocumentPart().getXPathsPart().getContents().getXpath().add(xp);
} catch (Docx4JException e) {
e.printStackTrace();
}
;
The problem is that, once set, they are not recognized by word, so I thought to add the created Xpaths to a new XpathPart, and then add it to the main Document part.
But I failed because the method:
wordMLPackage.getMainDocumentPart().getXPathsPart()
returns null. This sounded reasonable, since only content control was set, without any Xpath.
Then I set the Xpaths via content control toolkit and the same line of code like above, returned me null, which added a lot of confusion in my yet confused ideas.
Is there any way to tell the document that new Xpath have been added to the document?
I mean, if there is a way to add Xpath via code (the w:databinding w:storedItemId tags), why it is not possible to make it work?
In general I want to add Xpath and all information necessary, via code, avoiding the use of any toolkit.
Thank you :D
First, you have to decide whether you want plain old Word databinding, or the additional OpenDoPE capabilities (which use the content control tag to support repeats, conditionals etc).
You only need an XPaths part if you are using the OpenDoPE extensions.
I'll assume for now that you are just looking to do basic Word content control databinding.
To set that up programmatically, you need to add a custom xml part, and a rel from it to its itemProps.xml part, which contains something like:
<ds:datastoreItem ds:itemID="{5448916C-134B-45E6-B8FE-88CC1FFC17C3}" xmlns:ds="http://schemas.openxmlformats.org/officeDocument/2006/customXml">
<ds:schemaRefs/>
</ds:datastoreItem>
(to add a part B to part A, use partA.addTargetPart)
You can see it is this part with gives the custom xml part its itemID; this corresponds with the value you set in:
DataBinding db = factory.createXpathsXpathDataBinding();
db.setStoreItemID("something");
Then, set the XPath via the method you were using.

Java 7 watcherservice - filtering files to watch

I am using the watcher service and it works great. I need to only watch for files with a certain extension, e.g. .xml. How can I implement this?
Thanks.
It appears that there is no built-in file extension filter (like there is using the old java.io.FileFilter interface). I solved this same issue by adding an "if" statement in my processing code like so:
// Watcher gives key and you get event...
WatchEvent<Path> ev = (WatchEvent<Path>) event;
Path file = dir.resolve(ev.context());
if (isCorrectFileType(file)) {
// Do you processing here.
}
And the simple check:
private boolean isCorrectFileType(Path file) {
return (file.toString().endsWith(".xml"));
}

Copy object values in Visual Studio debug mode

In Visual Studio debug mode it's possible to hover over variables to show their value and then right-click to "Copy", "Copy Expression" or "Copy Value".
In case the variable is an object and not just a basic type, there's a + sign to expand and explore the object. It there a way to copy all that into the clipboard?
In the immediate window, type
?name_of_variable
This will print out everything, and you can manually copy that anywhere you want, or use the immediate window's logging features to automatically write it to a file.
UPDATE: I assume you were asking how to copy/paste the nested structure of the values so that you could either search it textually, or so that you can save it on the side and then later compare the object's state to it. If I'm right, you might want to check out the commercial extension to Visual Studio that I created, called OzCode, which lets you do these thing much more easily through the "Search" and "Compare" features.
UPDATE 2 To answer #ppumkin's question, our new EAP has a new Export feature allows users to Export the variable values to Json, XML, Excel, or C# code.
Full disclosure: I'm the co-creator of the tool I described here.
You can run below code in immediate window and it will export to an xml file the serialized XML representation of an object:
(new System.Xml.Serialization.XmlSerializer(obj.GetType())).Serialize(new System.IO.StreamWriter(#"c:\temp\text.xml"), obj)
Source: Visual Studio how to serialize object from debugger
Most popular answer from https://stackoverflow.com/a/23362097/2680660:
With any luck you have Json.Net in you appdomain already. In which
case pop this into your Immediate window:
Newtonsoft.Json.JsonConvert.SerializeObject(someVariable)
Edit: With .NET Core 3.0, the following works too:
System.Text.Json.JsonSerializer.Serialize(someVariable)
There is a extension called Object Exporter that does this conveniently.
http://www.omarelabd.net/exporting-objects-from-the-visual-studio-debugger/
Extension: https://visualstudiogallery.msdn.microsoft.com/c6a21c68-f815-4895-999f-cd0885d8774f
You can add a watch for that object, and in the watch window, expand and select everything you want to copy and then copy it.
By using attributes to decorate your classes and methods you can have a specific value from your object display during debugging with the DebuggerDisplay attribute e.g.
[DebuggerDisplay("Person - {Name} is {Age} years old")]
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
I always use:
string myJsonString = JsonConvert.SerializeObject(<some object>);
Then I copy the string value which unfortunately also copies the back slashes.
To remove the backlashes go here:
https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_replace
Then within the <p id="demo">Visit Microsoft!</p> element replace the text with the text you copied.
then replace the var res = str.replace("Microsoft", "W3Schools"); line with
var res = str.replace(/\\/g, '')
Run these new changes but don't forget to click the "try it" button on the right.
Now you should have all the text of the object in json format that you can drop in a json formatter like http://jsonformatter.org or to create a POCO you can now use http://json2csharp.com/
ObjectDumper.NET
This is an awesome way!
You probably need this data for a unit test, so create a Sandbox.cs temporary test or you can create a Console App.
Make sure to get NuGet package, ObjectDumper.NET, not ObjectDumper.
Run this test (or console app)
View test output or text file to get the C# initializer code!
Code:
[TestClass]
public class Sandbox
{
[TestMethod]
public void GetInitializerCode()
{
var db = TestServices.GetDbContext();
var list = db.MyObjects.ToList();
var literal = ObjectDumper.Dump(list, new DumpOptions
{
DumpStyle = DumpStyle.CSharp,
IndentSize = 4
});
Console.WriteLine(literal); // Some test runners will truncate this, so use the file in that case.
File.WriteAllText(#"C:\temp\dump.txt", literal);
}
}
I used to use Object Exporter, but it is 5 years old and no longer supported in Visual Studio. It seems like Visual Studio Extensions come and go, but let's hope this NuGet package is here to stay! (Also it is actively maintained as of this writing.)
Google led me to this 8-year-old question and I ended up using ObjectDumper to achieve something very similar to copy-pasting debugger data. It was a breeze.
I know the question asked specifically about information from the debugger, but ObjectDumper gives information that is basically the same. I'm assuming those who google this question are like me and just need the data for debugging purposes and don't care whether it technically comes from the debugger or not.
I know I'm a bit late to the party, but I wrote a JSON implementation for serializing an object, if you prefer to have JSON output. Uses Newtonsoft.Json reference.
private static void WriteDebugJSON (dynamic obj, string filePath)
{
using (StreamWriter d = new StreamWriter(filePath))
{
d.Write(JsonConvert.SerializeObject(obj));
}
}
I've just right clicked on the variable and selected AddWatch, that's bring up watch window that consists of all the values. I selected all and paste it in a text a text editor, that's all.
Object Dumper is a free and open source extension for Visual Studio and Visual Studio Code.
"Dump as" commands are available via context menu in the Code and Immediate windows.
It's exporting objects to:
C# object initialization code,
JSON,
Visual Basic object initialization code,
XML,
YAML.
I believe that combined with the Diff tool it can be helpful.
I'm the author of this tool.
if you have a list and you want to find a specific variable:
In the immediate window, type
myList.Any(s => s.ID == 5062);
if this returns true
var myDebugVar = myList.FirstOrDefault(s => s.ID == 5062);
?myDebugVar
useful tips here, I'll add my preference for when i next end up here asking this question again in the future.
if you don't mind adding an extension that doesn't require output files or such there's the Hex Visualizer extension for visual studio, by mladen mihajlovic, he's done versions since 2015.
provides a nice display of the array via the usual magnifine glass view object from the local variables window.
https://marketplace.visualstudio.com/items?itemName=Mika76.HexVisualizer2019 is the 2019 version.
If you're in debug mode, you can copy any variable by writing copy() in the debug terminal.
This works with nested objects and also removes truncation and copies the complete value.
Tip: you can right click a variable, and click Copy as Expression and then paste that in the copy-function.
System.IO.File.WriteAllText("b.json", page.DebugInfo().ToJson())
Works great to avoid to deal with string debug format " for quote.
As #OmerRaviv says, you can go to Debug → Windows → Immediate where you can type:
myVariable
(as #bombek pointed out in the comments you don't need the question mark) although as some have found this limits to 100 lines.
I found a better way was to right click the variable → Add Watch, then press the + for anything I wanted to expand, then used #GeneWhitaker's solution, which is Ctrl+A, then copy Ctrl+C and paste into a text editor Ctrl+V.

Is there a way to specify outlining defaults in Visual Studio 2008 so that a file opens up with members collapsed by default?

What I would like to do is have VS2008, when I open a code file, collapse all members of the classes/interfaces in the file by default (including, crucially, any XML documentation and comments).
I do not want to use regions, at all.
I would also like to be able to use the ctrl+m, ctrl+l chord to toggle all member outlining (for example, if everything is collapsed, I would like it to expand all of the members, but not the comments or XML documentation).
Possible? How?
Yes to part 1.
Unsure about part 2.
To have VS2008 automatically open files in a Collapsed state you'll need to create an addin to run the "Edit.CollapsetoDefinition" when each document opens.
This isn't overly tricky - The difficult parts seems to be the that you have to run the code a few milliseconds after the document is actually opened so you need to use the threed pool to do that.
Create an Addin project for VS2008.
Add this code (see following) to the end of the OnConnection Method of the Connect class.
switch (connectMode)
{
case ext_ConnectMode.ext_cm_UISetup:
case ext_ConnectMode.ext_cm_Startup:
//Do nothing OnStartup will be called once IDE is initialised.
break;
case ext_ConnectMode.ext_cm_AfterStartup:
//The addin was started post startup so we need to call its initialisation manually
InitialiseHandlers();
break;
}
Add this method to the Connect class
private void InitialiseHandlers()
{
this._openHandler = new OnOpenHandler(_applicationObject);
}
Add a call to InitialiseHandlers() to the OnStartupComplete method of the Connect class.
public void OnStartupComplete(ref Array custom)
{
InitialiseHandlers();
}
Add this class to the project.
using System;
using System.Collections.Generic;
using System.Text;
using EnvDTE80;
using EnvDTE;
using System.Threading;
namespace Collapser
{
internal class OnOpenHandler
{
DTE2 _application = null;
EnvDTE.Events events = null;
EnvDTE.DocumentEvents docEvents = null;
internal OnOpenHandler(DTE2 application)
{
_application = application;
events = _application.Events;
docEvents = events.get_DocumentEvents(null);
docEvents.DocumentOpened +=new _dispDocumentEvents_DocumentOpenedEventHandler(OnOpenHandler_DocumentOpened);
}
void OnOpenHandler_DocumentOpened(EnvDTE.Document document)
{
if (_application.Debugger.CurrentMode != dbgDebugMode.dbgBreakMode)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Collapse));
}
}
private void Collapse(object o)
{
System.Threading.Thread.Sleep(150);
_application.ExecuteCommand("Edit.CollapsetoDefinitions", "");
}
}
}
And now all opened files should be fully collapsed.
It would be much easier to use the Visual Studio Macros to do the same thing. Editing the "EnvironmentEvents" Macro file in MyMacros and adding a handler for DocumentEvents.DocumentOpened with :
DTE.ExecuteCommand("Edit.CollapsetoDefinitions")
A quick way to collapse all outlining to function-definitions is to press:
Contextmenu-button*(next to your right windows button)*, L, O
I use it all the time. If there is a real hotkey for this please tell me :)
I had tried working out some Visual Basic code for a macro myself, borrowing from different places, and couldn't get anything to work. So what did I do? Why, I asked a question on StackOverflow of course! It got answered, I added the suggested code to my EnvironmentEvents macro, and now when I open CS files, after about a second, all my definitions are collapsed. :)

Resources