How to get line number on IClassifier.GetClassificationSpans? - c#

I am developing a Visual Studio extension in C# and I want to add classifications on a file based on an analysis of this file that is already provided. I have got analysis results with a set of locations (file, line, column) for each defect.
Based on MS doc, I have seen that we should implement the IClassifier.GetClassificationSpans method. I can see that we are given a set of SnapshotSpan. It looks like these spans are mostly complete lines from the open file: the visible lines currently shown and the line currently being edited.
However, as said previouly, I already have a set of defects with their location. I would like to get the current span line number so I can check I have got a defect registered on that line. I have browsed the whole SnapshotSpan structure with the debugger and I couldn't find anything looking the line number.
How to get current SnapshotSpan line number?
What is the logic of the framework when I already have results given with their location and I want to place glyphs/classifications/tooltips/outlining regions/etc in the editor based on these locations?

I finally found out that I can get the line number the following way:
var lineNumber= span.Snapshot.GetLineNumberFromPosition(span.Start.Position) + 1;
+1 because internal values start at 0 while visible lines in the editor start at 1 (or because my file analysis gives me lines starting at 1).

Related

How do i start reading a text file from a specific point?

So my question is basically, how do i start reading a file from a specific line, like for example line 14 until line 18?
Im working on a simple ContactList app and the only thing missing is deleting the information from a specific name. The user can create a new contact which has a name, a number and an address as information. I want the user to also be able to delete the data of that person by typing in their name. Then, the program should read the name and all of the 4 lines under it and remove them from the text File. How could i achieve this?
You can jump to any offset within a file. However, there isn't any way to know where a particular line begins unless you know the length of every line.
If you are writing a contact app, you should not use a regular text file unless:
You pad line lengths so that you can easily calculate the position of each line.
You are loading the entire file into memory.
You can't. You need to read the first n lines in order to find out which line has which number. Except if your records have a fixed length per line (which is not a good idea - there's always someone with a longer name that you could think of).
Likewise, you can't delete a line from the text file. The space on disk does not move by itself. You need an algorithm that implements safe saving and rearranges the data:
foreach line in input_file:
if line is needed:
write line to temporary_output_file
else:
ignore (don't write = delete)
delete input_file
move temporary_output_file to input_file
Disadvantage: you need about double the disk space while input_file and temporary_output_file both exist.
With safe saving, the NTFS file system driver will give the moved file the same time stamp that it had before deleting the file. Read the Windows Internals 7 book (should be part 2, chapter 11) to understand it in detail.
Depending on how large the contact list is (probably it's less than 10M entries), there's no problem of loading the whole database into memory, deleting the record and then writing everything back.

Label obj not working as expected

I am trying to achieve a file lister, which will list all files in specified path. To do so I used mixture of panel, labels and File objects. The code to achieve this is as follow
label_songlist[i].Text=filename[i];
label_songlist[i].Height=25;
label_songlist[i].Location=new Point(x,y);
label_songlist[i].AutoSize=true;
label_songlist[i].Font=new Font(FontFamily.GenericSansSerif,10);
label_songlist[i].BorderStyle=BorderStyle.FixedSingle;
label_songlist[i].Padding=new Padding(0,0,0,5);
panel.Controls.Add(label_songlist[i]);
This works fine for first 5 file. After first five files it some how add space to left for remaining file giving output something like this
.
However, the value of x is never changed through out the execution of program. I did collect value of x and y for each label and wrote it to file. After execution I checked file. The value of X is 0. No change at all.

Why can't this read integers from my text file? Sytem.FormatException

Okay, so I am making a game that reads data from a text file to create events. What happens is as each year advances if something exciting happens a popup box with three options appears, clicking them affects the game and so on.
I have created a function which can take various arguments and make the form automatically - so far so good- but writing large event descriptions in the code is messy and disorganized. Instead I decided to create another function which takes values from a text file, organizes them and then calls the second function to create the 'event'.
Now, as I said each event comes with three choices (See below) and each choice has a consequence on one of three factors (approval, prestige, power), I haven't quite worked out the mechanics properly but all in good time, everything runs wonderfully until I need to load this integers from the text file.
It keeps having trouble converting the string to an integer, why is this and how can I fix it?
Line 11 of the text file: 10 (yes I checked and it is the right line to read)
The code:
List<int> affecta = new List<int>();
affecta.Add(Int32.Parse(System.IO.File.ReadLines(filename).Take(11).First()))
I can load the other things such as the picture file's location perfectly, so 'filename' points to the correct .txt
It might be something really obvious to someone with more experience, but I just can't see why.
I don't think Take does what you think - It grabs the first 11 items and returns all of them, so you get an IEnumerable of 11 items. When you do First on that, you get item at position 0, not position 10. I think you want Skip and then First, which will skip the first 10 items and return the next (11th) item:
affecta.Add(Int31.Parse(System.IO.File.ReadLines(filename).Skip(10).First()))
If you use Take(11) this means "get 11 rows from the source". After that you have First(), so you'll get first of them. You're essentially trying to convert the first line into integer.
I assume you want to use Skip(10) since you want the 11th line.
Take(11).First() returns the First element from the IEnumerable containing the 11 elements.
Instead, Skip the first 10 and select the First from the IEnumerable.
affecta.Add(Int32.Parse(System.IO.File.ReadLines(filename).Skip(10).First()))
Alternatively, Take the first 11 and select the Last from the IEnumerable.
affecta.Add(Int32.Parse(System.IO.File.ReadLines(filename).Take(11).Last()))

Is there a way to create programmatically something similar to the Visual Studio 'Go To Implementation' functionality?

I'm looking for a way to read the contents of a method/function call, something similar to the Visual Studio 'Go To Implementation' functionality (or F11 in debug) but using code.
For example, if I had a C# .cs file that contained the following code:
var characters = "AAAAAABBBBBBCCCCCCDDDDDD";
var position = 0;
var newPosition;
//Example #1
myObject.FirstSixCharacters = characters.SubString(position, 6);
position += 6;
//Example #2
myObject.SecondSetOfSixCharacters = AStaticObject.AMethod(characters, position, 6, out newPosition);
position += newPosition;
I'd like to know if there is a way to programatically 'drop' into the 'AMethod' method of the 'AStaticObject' object and read the code?
To put the question into context, I have a large enterprise solution that in essence - parses a very large string of characters into lots of DTO fields. I'm thinking of writing something that will open a 'parser' .cs file, read the contents of the code then determine the position and length of each DTO field based upon the processing applied at the time of the assignment.
This is fairly straight forward to achieve for statements where the field assignment is the result of a simple 'substring' function (as per example #1, above). But on occassion the code uses static objects/methods to extract the characters of the string and update the positional variable (as per example #2, above). This led me to the question - "how can I, programmatically, read the code within the .cs file and when necessary follow calls made to objects/methods when they appear within the code and read the contents of those .cs file"?
Note: The code that I'm attempting to analyse is un-compiled, so decompiliers are not necessary to achieve the result.

In ASP, C#, and VB.Net how to retrieve current line number

Does ASP, C#, VB.NET have a way to retrieve what line its on in code as its processing commands?
Example
1 <%
2 response.write("Your on line " & retreiveCurrentLineNumber)
3 %>
Output: Your on line 2
You can do this:
var line = new StackFrame(0, true).GetFileLineNumber();
Note there are several caveats to this.
You will need to make sure the source file and PDB are reachable.
This will get you the current line of the method you are in, not exactly where you are.
The Jit may perform optimizations that result in incorrect information, such as a method being inlined.
For VB.NET it's the same thing:
Dim line As Integer = New StackFrame(0, True).GetFileLineNumber()
As far as Classic ASP goes - I don't believe this is possible.
While vcsjones answer may be exactly what you're looking for, for the purposes of debugging/troubleshooting VB.NET you may want to take a look at the Erl property of the Err object. It returns an integer indicating the line number of the last executed statement - and by line number, that means a numeric label, not the physical line number of the source file.
Peppering one's code with line numbers at critical points is helpful at troubleshooting the unexpected exceptions, and one doesn't need the source file and PDB to make Erl work.

Categories