Access source code information from the Visual Studio editor - visual-studio

I'm trying to get into creating Visual Studio extensions. There are a few examples in the online documentation from Microsoft about creating custom stuff but I can't find anything on how to access Intellisense (or any other code analysis).
I know there are some questions about this topic (namely how do you get c++ Intellisense data in a visual Studio Extention?) but those are from 2012 or earlier and not up to date anymore (at least I hope so).
The following is only applied to C++ source code.
What I specifically want, is to examine the expression that the cursor is at. Then I want to check whether the expression is either
an object declaration / instanciation, like string s("my string");, or
a function call, like std::max(1, 2);
From those expressions I want to get the full qualified name (including the namespace) of the type / function and possibly the types of the function / constructor arguments. For example:
// ...
using namespace std;
auto x = max(1, 2);
// ...
Now, if the cursor enters max I need the full qualified name ::std::max and the argument types [int, int].
Another example:
// ...
using namespace std;
string s("my string");
// ...
Here I need the full qualified name ::std::string and the argument types [const char*, std::allocator].
Is this somehow possible? I'm also interested in partial solutions. Any guidance or hints to some sort of documentation is very welcome.

We can only get partial information via code model.
https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.vccodemodel.vccodemodel?view=visualstudiosdk-2017

Related

TypeScript cast (assertion) results in Syntax Error compiler warning?

I've got a TypeScript script that has to interact with a third-party vendor that uses global functions as callbacks (you can't pass in a callback). For instance, to "listen" for a result from their "API", you define the function SetElqContent. E.g.,
window.SetElqContent = function(){/* handle result */};
When the TypeScript compiler sees this line, it complains that The property 'SetElqContent' does not exist on value of type 'Window'.
I thought I could get around this by simply casting to type "any". Actually, this isn't type casting but type assertion, but I think of it as casting, although I understand it's not quite the same. So, I tried:
(<any>window).SetElqContent = function(){/* handle result */};;
To m y surprise, this results in Syntax error, and the line number and column points to the < character in the <any> cast. I tried a few other variants, and I get Syntax error on the initial < of the cast no matter what kind of cast I was doing:
var windowAny = <any>window;
var docElement = <HTMLElement>window.document;
What is it about my type assertions that is invalid syntax?
I'm using Visual Studio 2013 with Update 2, which has a "compile on save" feature for TypeScript files. That's how I'm compiling my .ts files, and it's from in Visual Studio where the Syntax error message is emitted.
UPDATE: Apparently this is related to Visual Studio. When I use the standalone tsc compiler to compile the same file, it emits no errors or warnings.
Apparently my syntax is correct but there is a bug in the Visual Studio tooling. I can't provide exact reproduce steps, and in fact, deleting everything in the .ts file, saving, then restoring the code (via ctrl-z) and resaving caused the "syntax error" warning to disappear.
If I can determine any more specifics about what causes this issue to manifest, I'll report back.
Best way is to create a type definitions file for it
If the library name is eloqua.js, you create a eloqua.d.ts file and refer to it in your .js file like
/// < reference path="../typings/eloqua.d.ts" />
There are many type definition files online available at definitelyTyped website.
https://github.com/borisyankov/DefinitelyTyped
You can contribute yours to there as well.
If you extend the Window interface definition, you'll remove the error:
interface Window {
SetElqContent: Function;
}
window.SetElqContent = function(){/* handle result */};
Here is how you can do the assertion properly:
function SetElqContent(){/* handle result */};
// FINE
(<any>window).SetElqContent = SetElqContent;
or
// FINE
(<any>window).SetElqContent = function SetElqContent(){/* handle result */};
However you should avoid asserting and just do what Steve Fenton recommends as it is more discoverable
Update
Demo in VS:

Visual studio 2010: how to watch a memory hex location

I tried some suggestions found online but it does not work for me. Im using Visual Studio 2010. Basically I typed loc(kcs(1,4)) (thats my variable) and I obtained 157510036. Its hex is 9636994. So then I typed (INTEGER*)0x9636994 but on the watch window under the "value"column it says "undefined variable INTEGER". I trid lowercase integer or real and same answer. Any suggestion?
I typed (INTEGER*)0x9636994 but on the watch window under the "value"column it says "undefined variable INTEGER".
According to Restrictions on Native C++ Expressions:
Type Casting
If you cast to a type, the type must be known to the debugger. You must have another object of that type in your program. Types created using typedef statements are not supported.
Try using the underlying type. So, for example, if INTEGER is actually an int you would try to watch (int *)0x9636994.
This also assumes that the variable is fixed at 0x9636994 (basically that you're not trying to refer to something transient on the stack).

Visual Studio 2010 IntelliSense: hints on F# operators

Is it possible to make Visual Studio to display tooltips on operators?
The following image demonstrates a tooltip hint for a function, but it does not work for operators.
Operators usually have simple type specs like 'T -> 'T -> 'T, but such hints can be useful for custom ones.
Following Daniel's suggestion, I'm posting a workaround that I've been using for myself.
The workaround is only partially helpful, and I'm still looking for any better ideas.
let (!><) a = ()
let z1 = op_BangGreaterLess 5
This code is fully valid, since an operator expression generates a function with a compiler-generated name. See this MSDN article, section "Overloaded Operator Names" for complete list of operator names.
Good news is that op_BangGreaterLess supports IntelliSense hints and it also supports "Go to Definition" (F12) command of IDE, pointing to an original operator declaration.
Bad news is that IntelliSense does not allow rapid entry of the full operator name (Ctrl+Space), so you have to type the entire name manually.
I'm afraid this is not possible (and even in Visual Studio 2012, I don't get tooltips for operators).
I suppose this could be implemented, but as you say, operators usually have simple types. When using custom operators, these should be probably simple enough so that people can use them without looking at their type (or the associated XML documentation). Otherwise, it might be better to use a named function.
That said, if you're using F# Interactive, then you can easily use that to explore the operator type:
> (!><);;
val it : ('a -> unit) = <fun:clo#2>
If I cannot use F# Interactive, I usually define a simple dummy symbol to get the IntelliSense:
let dummy () = (!><)
Note that I added unit argument to define a function and avoid value restriction error.

Visual Studio 2010 C++ CLR Debugging Windows: How to override 'Value' part?

I did a research on web and cannot find anything so maybe you know a way to solve my problem.
I am using MS VS 2010, and I use VS C++ (only CLR).. Let's say I have a class smt like this:
class A
{
public:
int x;
float a;
char* str;
};
While debugging my application, I open "Locals Window" and I see my variable name, value and Type. I would like to change (write) something to my value part. Like I habe a class A object a:
Name Value Type
a x: 4 a: 2.03f str: 'Hello!' A
I hope this was a clear example. I want to override value part in locals, autos ... windows.. Any way to do it?
Thanks...
If the class is a managed class then you can decorate it with a DebuggerDisplayAttribute. If it is unmanaged, which your example seems to be, then you need to edit a file called autoexp.dat. There's a fairly old article on MSDN about it here, I have done this a long time ago and remember it was a pain to get working. Also, there is a bug filed on Connect that autoexp.dat doesn't work for C++/CLI projects in VS 2010, though I haven't tried this myself.

Macro expansion in Visual Studio macro or add in

I have a VS project with an IntermediateDirectory like this: "....\temp\$(SolutionName)\$(ProjectName)".
I can read this value using a macro or add in, however, I would need the actual directory to manipulate files there. Right now, I manually replace the "$(SolutionName)" and "$(ProjectName)" with the respective values, which works fine but might become complicated when different macros or even user macros from property sheets are used.
So my question is:
Does the Visual Studio API have a built in function to expand macros like these? Or is there some other elegant solution?
There is an elegant solution! But I only know the one that applies to C++ projects.
Assuming you're in a C# add-in:
// Get the main project from the first startup project
VCProject vcMainProject = (VCProject)(_applicationObject.Solution.SolutionBuild.StartupProjects as IVCCollection).Item(1);
Project mainProj = (Project)_vcMainProject .Object;
// Get the configuration we'll be using
IVCCollection cfgs = (IVCCollection)_vcMainProject .Configurations;
VCConfiguration vcCfg = (VCConfiguration) cfgs.Item(mainProj.ConfigurationManager.ActiveConfiguration.ConfigurationName + "|" + mainProj.ConfigurationManager.ActiveConfiguration.PlatformName);
string finalString = vcCfg.Evaluate("....\temp\$(SolutionName)\$(ProjectName)");
You can also check out this page:
http://msdn.microsoft.com/en-us/library/czt44k0x%28VS.71%29.aspx
If you're not using this for C++, there should be a similar interface for the Project, Configuration, and Solution classes provided for other languages (C# and VB).
As far as i know, there is no API available that will expand those macro values. Although it shouldn't be too hard to write a quick and dirty implementation that deals with only the values that you care about.
For instance, in this case you only care about 2 values (SolutionName and ProjectName). If these are the values you are primarily interested in use a simple search and replace with the best values.
Yes this is a sub-optimal solution. But it may help to unblock your progress.

Resources