Whole Tomato Software Forums
Whole Tomato Software Forums
Main Site | Profile | Register | Active Topics | Members | Search | FAQ
User name:
Password:
Save Password
Forgot your password?

 All Forums
 Visual Assist
 Feature Requests
 #line directives
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic  

stevenkucera
New Member

Australia
4 Posts

Posted - Dec 05 2013 :  2:03:54 PM  Show Profile  Reply with Quote
Hi,

I am using Lazy C++ (http://www.lazycplusplus.com/) and what I would like is for Visual Assist to recognise #line directives and go to the appropriate file (in the generating .lzz file) when browsing etc (rather than the generated .cpp file). Visual Studio doesn't do this either (although surely it's possible, as the compile tools and debugger do understand #line). I would surely buy this software if it was added.

Steve

feline
Whole Tomato Software

United Kingdom
19024 Posts

Posted - Dec 09 2013 :  6:08:17 PM  Show Profile  Reply with Quote
What #line directives? I have not downloaded this yet, I have never heard of this tool before, but the first page, with the sample code that explains the concept, does not show any #line directives.

A google has produced this page, explaining #line:

http://msdn.microsoft.com/en-us/library/34dk387t%28v=vs.80%29.aspx

but I don't understand what you are asking for. These are instructions to the compiler, and just change the line number for errors. Use Ctrl-G and type in the line number to tell the IDE to jump to the line you want.

zen is the art of being at one with the two'ness
Go to Top of Page

stevenkucera
New Member

Australia
4 Posts

Posted - Dec 09 2013 :  6:20:30 PM  Show Profile  Reply with Quote
Hi,

Lazy C++ basically generates .cpp and .h files from a .lzz program, which is basically a C++ implementation file without need of forward declarations. It has an option (-sl and -hl) that puts #line directives in the generated .cpp and .h file. That way Visual Studio reports errors in the right file and line (in the .lzz program) rather than in the mangled .cpp and .h files. If you double click on the error it jumps to the right line in the .lzz file. Also, debugging works so you step through the .lzz file rather than the .cpp file. The Class View however, displays (it slurps through the .h and .cpp files) but when you click to go to the definition it goes to the .cpp file rather than the .lzz ... same with VA. It would be good if it jumps to the right place in the .lzz file. Anyway this is no biggie I was just wondering if it is trivial/easy to add the feature where it jumps to the .lzz file (I'm guessing it probably wouldn't not be that easy).

Regards,
Steve
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
19024 Posts

Posted - Dec 09 2013 :  7:24:18 PM  Show Profile  Reply with Quote
I am assuming that the .lzz file is not a standard .cpp file, so VA may have difficulties parsing it correctly, but if it is close enough then VA may work well enough.

Is VA active in the .lzz files? Does VA attempt to show syntax highlighting? Is the VA context and navigation bar shown? This is normally placed at the top of the editor. If not, then you need to tell VA that the .lzz files are C++ cpp files, so it will parse them as such. Doing this is explained in this FAQ entry:

http://docs.wholetomato.com?W328

If this works, VA may then realise there are two implementations for each function, and offer both of them in the Alt-G menu. I am not actually sure if this will work or not, but its worth a try.

zen is the art of being at one with the two'ness
Go to Top of Page

stevenkucera
New Member

Australia
4 Posts

Posted - Dec 09 2013 :  7:29:47 PM  Show Profile  Reply with Quote
Hi,

Nope you actually don't need to parse the .lzz file as the program lzz.exe does that for you. You just have to parse the generated .cpp files. VS does not even know that Lazy C++ exists (except as a custom build step).

Syntax highlighting doesn't work, but the context and navigation bar are there (but when I click them, they do go to the .cpp file rather than .lzz as I was hoping).

Steve
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
19024 Posts

Posted - Dec 10 2013 :  10:45:52 PM  Show Profile  Reply with Quote
Are you just looking for Alt-g on the #line lines to work, or for something more complex? If we are not trying to parse the .lzz file, we are not going to map any symbols back to it.

I am a little surprised that there is no syntax highlighting if the context and navigation fields are showing. Does Alt-m show anything? I am wondering what file extension .lzz has been mapped to on your system, since if it was mapped as C++ I would expect at least some limited syntax highlighting.

zen is the art of being at one with the two'ness
Go to Top of Page

stevenkucera
New Member

Australia
4 Posts

Posted - Dec 10 2013 :  11:04:44 PM  Show Profile  Reply with Quote
Oops you're right, Alt-M doesn't work in .lzz files, only .cpp. It should be possible to link back to the Lzz files, but not trivial. I think I'll go back to plain C++ since it is better supported by VS in general.

Thanks,
Steve
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
19024 Posts

Posted - Dec 18 2013 :  9:43:34 PM  Show Profile  Reply with Quote
This makes sense. If you want VA to be active in .lzz files, this FAQ tells you how to do it, but since I have not tested this with Lazy C++ I am not sure how well it will work for you:

http://docs.wholetomato.com?W328

zen is the art of being at one with the two'ness
Go to Top of Page

alexk7
Starting Member

Canada
1 Posts

Posted - Apr 09 2014 :  11:05:41 AM  Show Profile  Reply with Quote
I would like to request this feature as well. Here is exactly how I think it should work:
As soon as there is a #line directive in a file,

    [*] Parse the generated file and use this result for the global list of symbols.
    [*] Parse the original file only for local operations (this is a "best effort" since the source may not even be C++...)
    [*] Use the original file for all operations including "Go" and "Open Corresponding File"
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
19024 Posts

Posted - Apr 10 2014 :  3:17:21 PM  Show Profile  Reply with Quote
Where are these generated files coming from? Is this a Lazy C++ file you are talking about, or some form of general "any input to any output file" situation?

Our focus is C++ and C# inside Visual Studio, while this sounds like you are looking to start adding support for other, unrelated languages, and asking VA to guess what is going on in their files, especially since you say the original file may not even be C++.

zen is the art of being at one with the two'ness
Go to Top of Page

Queequeg
Senior Member

Germany
36 Posts

Posted - May 04 2015 :  05:48:56 AM  Show Profile  Reply with Quote
We are currently facing the same issue, so maybe I can explain the problem.

Code generators like Lazy C++ output C++ code files from their own DSL files. In order to tell the compiler that the code originated from a DSL file, they add #line directives. That #line directive has an optional file parameter, which points to the original DSL file.

Example A.lzz
quote:

class A {
  int five(){return 5;}
};

This would generate a header file, and maybe something like this .cpp file:
quote:

#line 2 "A.lzz"
int A::five(){return 5;}

Now if there's a compiler error in the five() function, it works well because VS will jump to the correct file, namely A.lzz, because it respects the #line directive. What doesn't work is code navigation with VA, because VA doesn't know the #line directive, and that's what this topic is about:

Let's say we use this code somewhere else.
quote:

#include "A.hpp"
void main()
{
  A a;
  printf("Five = %d\\n", a.five());
}

If we position the cursor on a.five() and use Visual Assist's "Goto Implementation" we will end up in the .cpp file. However, we would have preferred to jump into the .lzz file instead. It would be possible for VA to do that by using the line directive above any place it jumped to.

So yes, in my opinion that counts as C++/C# support, since #line is part of both languages.
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
19024 Posts

Posted - May 04 2015 :  2:39:40 PM  Show Profile  Reply with Quote
What compiler are you using to compile the cpp files? Using VS2013 I have added the two lines:

#line 5 "test_general.h"
	nInvalidVariable1 = 2;


to the file "test_general.cpp". The variable is not declared, as the name suggests. When I compile this, and then jump to the error, I am taken to this line, in the cpp file. The #line directive has no effect on the error handling in this case.

So I am wondering why you are getting a different result here.

zen is the art of being at one with the two'ness
Go to Top of Page

Queequeg
Senior Member

Germany
36 Posts

Posted - May 08 2015 :  04:25:05 AM  Show Profile  Reply with Quote
VS is really not good with relative paths. I believe you have to specify a full path.

I'm using VS2010 SP1. When I place the two lines you mentioned in a .cpp file, the compiler says:
quote:
1>------ Build started: Project: Tests, Configuration: Debug x64 ------
1>Build started 08.05.2015 11:17:34.
1>ClCompile:
1> Test.cpp
1>b:\\build_2.6_x64\\tests\\test_general.h(5): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:00.45



Note that the Test.cpp file is in a completely different directory, even on a different drive. When I press F4, VS says "The system can not find the file specified".
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
19024 Posts

Posted - May 09 2015 :  6:16:37 PM  Show Profile  Reply with Quote
Do you have a code sample that shows the IDE jumping to a line indicated by a #line directive?

Using VS2010, a simple file name and a complete path both report the filename in the error list, but the IDE will never jump to this filename in either case.

zen is the art of being at one with the two'ness
Go to Top of Page

Queequeg
Senior Member

Germany
36 Posts

Posted - May 11 2015 :  03:58:11 AM  Show Profile  Reply with Quote
If you send me an email I can send you a zip file of the entire project, including the solution.

Not really minimal, but I hope it helps.

A.lzz
quote:
#src
#include <stdio.h>
#include <iostream>
#end

/**
 * An A is a pretty cool cat.
 */
class A(int m_x)
{
public:
  void func(int i)
  {
    m_x = i;
    printeff("A::func(i): m_x == %i\\n", m_x);
  }
  void g(int j = 0) { m_x += j; }
protected:
  friend bool operator == (A const & a1, A const & a2);
};

bool operator == (A const & a1, A const & a2) { return a1.m_x == a2.m_x; }

using namespace std;

void iAmFree()
{
  cout << "like a bird" << endl;
}



A.hpp
quote:
// A.hpp
//

#ifndef LZZ_A_hpp
#define LZZ_A_hpp
#define LZZ_INLINE inline
#line 9 "T:/LzzTest/A.lzz"
class A
{
#line 9 "T:/LzzTest/A.lzz"
  int m_x;
#line 11 "T:/LzzTest/A.lzz"
public:
#line 12 "T:/LzzTest/A.lzz"
  void func (int i);
#line 17 "T:/LzzTest/A.lzz"
  void g (int j = 0);
#line 18 "T:/LzzTest/A.lzz"
protected:
#line 19 "T:/LzzTest/A.lzz"
  friend bool operator == (A const & a1, A const & a2);
#line 9 "T:/LzzTest/A.lzz"
public:
#line 9 "T:/LzzTest/A.lzz"
  explicit A (int m_x);
#line 9 "T:/LzzTest/A.lzz"
  ~ A ();
};
#line 22 "T:/LzzTest/A.lzz"
bool operator == (A const & a1, A const & a2);
#line 26 "T:/LzzTest/A.lzz"
void iAmFree ();
#line 9 "T:/LzzTest/A.lzz"
LZZ_INLINE A::A (int m_x)
#line 9 "T:/LzzTest/A.lzz"
  : m_x (m_x)
#line 9 "T:/LzzTest/A.lzz"
      {}
#undef LZZ_INLINE
#endif



A.cpp
quote:
// A.cpp
//

#include "A.hpp"
#line 2 "T:/LzzTest/A.lzz"
#include <stdio.h>
#include <iostream>
#define LZZ_INLINE inline
#line 24 "T:/LzzTest/A.lzz"
using namespace std;
#line 12 "T:/LzzTest/A.lzz"
void A::func (int i)
#line 13 "T:/LzzTest/A.lzz"
  {
    m_x = i;
    printeff("A::func(i): m_x == %i\\n", m_x);
  }
#line 17 "T:/LzzTest/A.lzz"
void A::g (int j)
#line 17 "T:/LzzTest/A.lzz"
                    { m_x += j; }
#line 9 "T:/LzzTest/A.lzz"
A::~ A ()
#line 9 "T:/LzzTest/A.lzz"
      {}
#line 22 "T:/LzzTest/A.lzz"
bool operator == (A const & a1, A const & a2)
#line 22 "T:/LzzTest/A.lzz"
                                              { return a1.m_x == a2.m_x; }
#line 26 "T:/LzzTest/A.lzz"
void iAmFree ()
#line 27 "T:/LzzTest/A.lzz"
{
  cout << "like a bird" << endl;
}
#undef LZZ_INLINE



Output window
quote:
1>------ Build started: Project: LzzTest, Configuration: Debug x64 ------
1>Build started 11.05.2015 10:51:02.
1>ClCompile:
1>  A.cpp
1>T:/LzzTest/A.lzz(15): error C3861: 'printeff': identifier not found
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:00.27
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========



Jumps to A.lzz:15 a, not the .cpp file.

CMake script to add .lzz files to solution: http://stackoverflow.com/a/9669388/872616

Edited by - Queequeg on May 11 2015 04:00:50 AM
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
19024 Posts

Posted - May 11 2015 :  3:40:18 PM  Show Profile  Reply with Quote
I have this working now, thank you for the sample code. I am not sure why my earlier experiments with #line were not working, but I never had anywhere near this many #line entries in my tests.

Are these files representative of what you are normally working with?

I ask since nearly every other line of code in the cpp file is a #line statement, making this very off putting to read and move through.

VA is based around understanding symbols, not "lines". So when you ask to go to where a symbol is defined, we look in our database for where that symbol was defined, and go there.

Now I have a working code sample, I think you are asking for VA to handle something more like:


#line 12 "C:/A.lzz"
void func()
#line 13 "C:/A.lzz"
{
    A a;
    printf("Five = %d\\n", a.five());  // doing alt-g on "a.five" on this line
}


the thing is, the #line directives have nothing to do with this. You are asking us to understand the definition and location of the type "A", presumably a class, and its members. Do I understand correctly?

But from your sample code above, the class declaration may well look like this:

class A(int m_x)
{
    // ...
};


which is not valid C++ code. So VA will instead want to take you to the .hpp file, since that is where the member function is declared. So are you then trying to jump from the .hpp file into the .lzz file, based on the #line directives?

zen is the art of being at one with the two'ness
Go to Top of Page

Queequeg
Senior Member

Germany
36 Posts

Posted - May 13 2015 :  04:51:17 AM  Show Profile  Reply with Quote
Hehe, yea, it is offputting, but the idea is that you're only ever looking at the .lzz files, and Lazy C++ takes care of the rest. You only look at the .hpp/.cpp file if something in the file generation goes wrong, not in day-to-day coding.

Of course it would be nice if there was a way to extend VisualAssist, and teach it new languages or grammars, but that is a bit much to ask. I don't really expect VA to understand the Lazy C++ language.

VA understands the generated C++ code though. What I imagine is this: VA is told to go to the definition of some symbol. That definition is in X.cpp:18 according to the VA database, so normally it would go there. However, in X.cpp:16 it says `#line 4 "X.lzz"`. So that means X.cpp:17 is supposed to be treated as X.lzz:4, and X.cpp:18 as X.lzz:5. That's why VA should jump to X.lzz:5 instead. Even though it doesn't know or understand what it actually says in that .lzz file. It just looks at the previous #line directive, takes the difference in line numbers into account, and replaces the location (file:number).

A remaining problem is that once you're in the X.lzz file, how do you continue navigation? Maybe VA could use a simple tokenizer to identify symbols to jump to.
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
19024 Posts

Posted - May 13 2015 :  11:03:37 PM  Show Profile  Reply with Quote
Have you considered writing an IDE macro to allow alt-g behaviour on the #line directives? Since these lines are in a standard format, and give the full path and line number it should be relatively straight forward to parse the line and know where you want to go. This sample macro to provide alt-o behaviour opens files, showing its easy enough:

http://docs.wholetomato.com/default.asp?W439

Unfortunately adding support for new languages is not something we are currently considering.

What sort of further navigation are you after? If you are after a "simple tokenizer" then you need to just use the IDE Find in Files command, matching whole words probably.

If you only want to mark a few specific places to jump to then VA Hashtags may help. If comments are cascaded from the .lzz files to the generated files, then you could a hashtag comment marker on functions of particular interest, and then use alt-g on these hashtags to navigate:

http://docs.wholetomato.com/default.asp?W574

zen is the art of being at one with the two'ness
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
© 2023 Whole Tomato Software, LLC Go To Top Of Page
Snitz Forums 2000