Generate C# delegate method stub in VS 2010? - c#

There are a similar question Generate a C# delegate method stub and a feature request at microsoft.com Generate method stub should support non-existent method names passed as delegates referenced in its author's blog (No "Add Method Stub" When Passing or Assigning Delegates). In the question they said the feature was going to be available in VS 2010, and the feature request is marked as fixed. However, I don't get any hints for creating delegate handlers in my code (using VS 2010). How is this and what am I doing wrong? Here is an example code:
class BaseEditor { }
delegate void ObjectEditorCreatedDelegate( BaseEditor editor );
class ArrayPropertyEditor
{
public ObjectEditorCreatedDelegate OnObjectEditorCreated;
}
class SomeUserCode
{
public void someMethod()
{
ArrayPropertyEditor ape = new ArrayPropertyEditor();
ape.OnObjectEditorCreated = new ObjectEditorCreatedDelegate( OnEditorCreated );
// -------------------------------------------------------------------------^
}
private void OnEditorCreated( BaseEditor editor ) { }
}
When the cursor is at the pointed place (after OnEditorCreated usage) and OnEditorCreated is not yet created, VS 2010 suggests "generate property stub" and "generate field stub". How do I generate a method?

Related

Is there a way in which I can access the currently loaded code in the debugger from my Visual Studio 2022 extension

I am trying to develop an extension for Visual Studio 2022 that needs to run a method from a class that is loaded as a .dll file in the current instance of VS while debugging. I want to do something like this:
We don't really care what we are debugging as long as we have access to a library loaded as a .dll file.
Let's say that library contains a class like this one:
class MyDebuggedProgram
{
public static void MyMethod()
{
Console.WriteLine("Hello World");
}
}
And in the source code of my Visual Studio extension I want to be able to call that code like this:
class MyExampleExtensionClass
{
public void onBtnClick()
{
var resultOfCallingLibraryMethod = SomeMethodThatCallsMyMethod();
}
}
I want to have access to all the classes, their methods and properties that are loaded in the current program that we are debugging.
Is there an easy way to do this?

Make diagnostic errors reported by a C# source generator appear in the Visual Studio editor

I am attempting to write a C# source generator that throws a warning/error under certain conditions using GeneratorExecutionContext.ReportDiagnostic. My source generator is able to run and output errors successfully upon building a sample project in Visual Studio. However, my errors do not show up as green/red squiggles in the Visual Studio editor. This is supposed to be possible with Roslyn analyzers, according to Microsoft's documentation, but nothing is said of source generators specifically. Since source generators are treated like Roslyn analyzers, though, I imagine this should be possible. I've managed to replicate my issue with a small example, consisting of a source generator project and a test project on which to run the generator. As a test, the generator reports a diagnostic error whenever it sees a method that doesn't return void. I intend for red squiggles to appear under the offending method's name:
Source generator:
[Generator]
public class SampleGenerator : ISourceGenerator
{
public void Execute(GeneratorExecutionContext context)
{
DataReceiver r = (DataReceiver)context.SyntaxReceiver;
foreach(MethodDeclarationSyntax method in r.Methods)
{
IMethodSymbol symbol = (IMethodSymbol)context.Compilation.GetSemanticModel(method.SyntaxTree).GetDeclaredSymbol(method);
if(symbol.ReturnType.SpecialType != SpecialType.System_Void)
{
context.ReportDiagnostic(Diagnostic.Create(
new DiagnosticDescriptor(
"SG0001",
"Non-void method return type",
"Method {0} returns {1}. All methods must return void.",
"yeet",
DiagnosticSeverity.Error,
true), symbol.Locations.FirstOrDefault(), symbol.Name, symbol.ReturnType.Name));
}
}
context.AddSource("yert", "namespace test { public class testclass { } }");
}
public void Initialize(GeneratorInitializationContext context)
{
context.RegisterForSyntaxNotifications(() => new DataReceiver());
}
}
public class DataReceiver : ISyntaxReceiver
{
public List<MethodDeclarationSyntax> Methods { get; } = new List<MethodDeclarationSyntax>();
public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
{
if(syntaxNode is MethodDeclarationSyntax synt)
{
Methods.Add(synt);
}
}
}
Example code:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
static string ok() => "hello";
}
When I compile the example code with the generator, Visual Studio tells me that the build has errors, and correctly reports the custom diagnostic in the error list. I can click on the custom error, and my cursor moves to the offending method in the editor. However, no red squiggles appear. I know that my source generator is being run by Intellisense, because I am able to see the custom test namespace and class my generator defines.
Does Visual Studio support code underlining for diagnostics reported by C# source generators? If so, what is wrong with the above code? Thanks in advance.
I solved this by separating out the code analysis logic into its own class and adding an analyzer and source generator into the same assembly, with the analysis logic only doing code emmission in the source generator. The analysis logic runs in different contexts, each context having a different reportdiagnostic, so it accepted an Action to report diagnostic.

ICommandHandler not executing for SaveCommandArgs (Visual Studio for Mac Extension)

I'm trying to create simple extension for Visual Studio for Mac which will handle the moment when user saves the document (sample project is on GitHub, right here).
Here's how looks my implementation of ICommandHandler<SaveCommandArgs>:
[Export(typeof(ICommandHandler))]
[Name(nameof(SaveCommandHandler))]
[ContentType(StandardContentTypeNames.Code)]
[TextViewRole(PredefinedTextViewRoles.PrimaryDocument)]
public class SaveCommandHandler : ICommandHandler<SaveCommandArgs>
{
public string DisplayName => nameof(SaveCommandHandler);
private readonly IEditorCommandHandlerServiceFactory _editorCommandHandlerServiceFactory;
[ImportingConstructor]
public SaveCommandHandler(IEditorCommandHandlerServiceFactory editorCommandHandlerServiceFactory)
{
_editorCommandHandlerServiceFactory = editorCommandHandlerServiceFactory;
}
public bool ExecuteCommand(SaveCommandArgs args, CommandExecutionContext executionContext)
{
try
{
var service = _editorCommandHandlerServiceFactory.GetService(args.TextView);
Debug.WriteLine($"I am executing something on save with {service.GetType()}");
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
return true;
}
public CommandState GetCommandState(SaveCommandArgs args)
{
return CommandState.Available;
}
}
Good point: system call the constructor of this handler, when you start editing the first file
Bad point: ExecuteCommand method never called, as well as GetCommandState method
Any ideas why it doesn't work?
I was trying to do all the things according to the documentation on official wiki in github project for visual studio api
Unfortunately, there're only samples for quick info and autocomplete features. No samples for ICommandHandler-s, haven't found any similar projects for Visual Studio for Mac as well
I agree the examples since Microsoft Visual Studio SDK documentation is horrible with no good examples of ICommandHandler.
I tried your exact code in visual studio 2022 on Windows 10 and the ExecuteCommand function is called.
So your code is fine.
I think the core problem here is that the ICommandHandler interface structure is somewhat newer and Microsoft did a poor job of properly checking for custom command handlers and adding calls.
I am trying to do a similar thing where I add an ICommandHandler to intercept the GoToDefinition command using an ICommandHandler, using this very similar code I can't get the ExecuteCommand function to fire ever.
I have been able to intercept commands using Microsofts older, yuckier DTE or DTE2 interface.
//provider constructor code
var dte2 = (DTE2)Package.GetGlobalService(typeof(DTE));
dte2.Events.CommandEvents.BeforeExecute += CommandEvents_BeforeExecute;
private static void CommandEvents_BeforeExecute(string guid, int id, object customIn, object customOut, ref bool cancelDefault)
{ //All events fired here use, the guid you want is likely
// Microsoft.VisualStudio.VSConstants.CMDSETID.StandardCommandSet97_string
// With an ID defined in
// Microsoft.VisualStudio.VSConstants.VSStd97CmdID
Debug.WriteLine("CommandEvents_BeforeExecute1 " + String.Format(
"dte2 GUID: {0}\nID: {1}\nIn: {2}\nOut: {3}",
guid, id, customIn, customOut));
}

Logging.Logger does not contain a definition for SetLogWriter

Copied code from here: https://www.c-sharpcorner.com/article/logging-block-in-microsoft-enterprise-library-6-0/
public class LoggerBlock
{
protected LogWriter logWriter;
public LoggerBlock()
{
InitLogging();
}
private void InitLogging()
{
logWriter = new LogWriterFactory().Create();
Logger.SetLogWriter(logWriter, false);
}
public LogWriter LogWriter
{
get
{
return logWriter;
}
}
}
The compile error is:
Microsoft.Practies.EnterpriseLibrary.Logging.Logger does not contain a
definition for 'SetLogWriter"
Sorry, I don't even know which version of the library I have installed. I'm trying to add some logging statements to an existing program that seems to have the app.config set up for Enterprise Library Logging.
Intellisense provides the following similar method only:
Logger.SetContextItemLog (object key, object value)
I'm guessing you are using an older version that doesn't have the Logger.SetLogWriter() method. I just installed the latest version and the code you pasted works fine. Can you update the version you are using?
Edit: It looks like the Logger.SetLogWriter() method just sets the default Logger to use the LogWriter you just created. How about using the created LogWriter directly instead of the default Logger?
var logWriter = new LogWriterFactory().Create();
logWriter.Write("Message");
The following article might also give you some more information. Creating and Writing Log Entries

Why repassing dynamic parameter to params parameter fails to build

When repassing a dynamic parameter to a method with params keyword the solution fails to build, I am using .NET 4.6 and VS2015, but the problem also happens with previous versions of .NET Framework. No error is produced on Error List, just a "Build Failed" message at the bottom.
This is the sample code I am trying to run:
public void MethodWithDynamicParameter(dynamic dyn)
{
MethodWithParams(dyn); //This fails to build!
MethodWithParams(new object[] { dyn }); //This compiles!
}
public void MethodWithParams(params object[] objects)
{
}
Can someone explain what is wrong with the first call?
EDIT 1:
I´ve created a new solution with the sample provided by Dave and it builds with no problems. But in my solution the problems persists even after "Close, clean and build". It does not matter if I pass a string, a object, a dynamic or anythin else. At the image below there are no calls to method and the solution still does not build.
I have created a new Console Application using the following code as a test:
class Program
{
static void Main(string[] args)
{
// Test with object:
object x = new object();
MethodWithDynamicParameter(x);
// Test with specific type of object, a string:
MethodWithDynamicParameter("string");
Console.ReadKey();
}
static void MethodWithDynamicParameter(dynamic dyn)
{
MethodWithParams(dyn);
MethodWithParams(new object[] { dyn });
}
static void MethodWithParams(params object[] objects)
{
}
}
For me, the program both compiles and runs without error.
May I suggest the standard "close all documents, clean all, rebuild all" and/or "restart Visual Studio" solutions, if you have not yet attempted this?
Additionally, they dynamic keyword might be the source of your troubles, as it bypasses many of the typing checks until compile time. Try checking your code from where dyn would be declared, prior to making the call to MethodWithDynamicParameter(dynamic dyn).

Categories