Jump to page: 1 2
Thread overview
__FILE__ and __LINE__ in case of import expression
Aug 21, 2020
Andrey Zherikov
Aug 21, 2020
Adam D. Ruppe
Aug 21, 2020
Andrey Zherikov
Aug 21, 2020
Andrey Zherikov
Aug 21, 2020
Andrey Zherikov
Aug 21, 2020
Adam D. Ruppe
Aug 21, 2020
Adam D. Ruppe
Aug 21, 2020
Adam D. Ruppe
Aug 23, 2020
Andrey Zherikov
Aug 23, 2020
Andrey Zherikov
Aug 23, 2020
Adam D. Ruppe
August 21, 2020
How can I get __FILE__ and __LINE__ values correct in case of import expression?
Below is my test code.
/////////////////////////////////////////
test.d:
module test;
import std.stdio;

void test(string file = __FILE__, size_t line = __LINE__,
          string mod = __MODULE__, string func = __FUNCTION__,
          string pretty = __PRETTY_FUNCTION__,
          string fileFullPath = __FILE_FULL_PATH__)
{
    writefln("file: '%s', line: '%s', module: '%s',\nfunction: '%s', " ~
             "pretty function: '%s',\nfile full path: '%s'",
             file, line, mod, func, pretty, fileFullPath);
}

int main(string[] args)
{
    test();                  // line #16    (1)
    mixin(import("foo.d"));  // line #17    (2)
    return 0;
}
/////////////////////////////////////////
foo.d:
// empty line 1
// empty line 2
// empty line 3
// empty line 4
// empty line 5
test(); // line 6
/////////////////////////////////////////


Execution result is:
>dmd -J. -run test.d
file: 'test.d', line: '16', module: 'test',
function: 'test.main', pretty function: 'int test.main(string[] args)',
file full path: 'C:\Users\andrey\test.d'
file: 'test.d-mixin-17', line: '22', module: 'test',
function: 'test.main', pretty function: 'int test.main(string[] args)',
file full path: 'C:\Users\andrey\test.d-mixin-17'


So the output from line #16 (1) is correct although from line #17 (2) is not: file name is neither 'test.d' not 'foo.d' and line number is 22 although both test.d and foo.d are shorter.

I understand that I can create a workaround but want to check first whether this is desired behavior or a bug that should be fixed?
August 21, 2020
On Friday, 21 August 2020 at 14:01:24 UTC, Andrey Zherikov wrote:
>     mixin(import("foo.d"));  // line #17    (2)

Why are you doing this? This kind of thing is almost never an ideal solution in D.

See, the compiler just sees a big string literal there. It isn't a separate file at that point, the import expression just pastes in the file contents as a string, and then mixin makes a chunk of code from it.

These two features are not really meant to be used together, at least not without some custom translation code in the middle.
August 21, 2020
On 8/21/20 10:01 AM, Andrey Zherikov wrote:
> How can I get __FILE__ and __LINE__ values correct in case of import expression?
...
> 
> So the output from line #16 (1) is correct although from line #17 (2) is not: file name is neither 'test.d' not 'foo.d' and line number is 22 although both test.d and foo.d are shorter.

You can override the filename and line number to the lexer: https://dlang.org/spec/lex.html#special-token-sequence

vibe.d does this so when errors from the trans-piled diet files happen, they match (mostly) back to the diet file, not the source file where they are mixed in.

> I understand that I can create a workaround but want to check first whether this is desired behavior or a bug that should be fixed?

That's a good question. I would say it should say line 17 or line 6 (preferably the latter). That may be considered a bug, I don't know.

-Steve
August 21, 2020
On Friday, 21 August 2020 at 15:27:14 UTC, Adam D. Ruppe wrote:
> On Friday, 21 August 2020 at 14:01:24 UTC, Andrey Zherikov wrote:
>>     mixin(import("foo.d"));  // line #17    (2)
>
> Why are you doing this? This kind of thing is almost never an ideal solution in D.
>
> See, the compiler just sees a big string literal there. It isn't a separate file at that point, the import expression just pastes in the file contents as a string, and then mixin makes a chunk of code from it.
>
> These two features are not really meant to be used together, at least not without some custom translation code in the middle.

Currently this is for illustration only but why can't I do this?
This can be an alternative to `rdmd --eval` that takes code from a file, not as CLI parameter.

August 21, 2020
On Friday, 21 August 2020 at 15:34:49 UTC, Steven Schveighoffer wrote:
> On 8/21/20 10:01 AM, Andrey Zherikov wrote:
>> How can I get __FILE__ and __LINE__ values correct in case of import expression?
> ...
>> 
>> So the output from line #16 (1) is correct although from line #17 (2) is not: file name is neither 'test.d' not 'foo.d' and line number is 22 although both test.d and foo.d are shorter.
>
> You can override the filename and line number to the lexer: https://dlang.org/spec/lex.html#special-token-sequence
>
> vibe.d does this so when errors from the trans-piled diet files happen, they match (mostly) back to the diet file, not the source file where they are mixed in.
>
>> I understand that I can create a workaround but want to check first whether this is desired behavior or a bug that should be fixed?
>
> That's a good question. I would say it should say line 17 or line 6 (preferably the latter). That may be considered a bug, I don't know.

Thanks for this link! I can use "#line" to fix line number but not file name:

file: 'foo.d-mixin-1', line: '6', module: 'test',
function: 'test.main', pretty function: 'int test.main(string[] args)',
file full path: 'C:\Users\andrey\foo.d-mixin-1'

August 21, 2020
On Friday, 21 August 2020 at 20:44:27 UTC, Andrey Zherikov wrote:
> Thanks for this link! I can use "#line" to fix line number but not file name:
>
> file: 'foo.d-mixin-1', line: '6', module: 'test',
> function: 'test.main', pretty function: 'int test.main(string[] args)',
> file full path: 'C:\Users\andrey\foo.d-mixin-1'

I can actually fix this issue as well.

Changes in test.d:

    test();                                          // line #16  (1)
    mixin("#line 1 \"foo.d\"\n" ~ import("foo.d"));  // line #17  (2)
    test();                                          // line #18  (3)

Output:

file: 'test.d', line: '16', module: 'test',
function: 'test.main', pretty function: 'int test.main(string[] args)',
file full path: 'C:\Users\andrey\test.d'
file: 'foo.d', line: '6', module: 'test',
function: 'test.main', pretty function: 'int test.main(string[] args)',
file full path: 'C:\Users\andrey\foo.d'
file: 'test.d', line: '18', module: 'test',
function: 'test.main', pretty function: 'int test.main(string[] args)',
file full path: 'C:\Users\andrey\test.d'
August 21, 2020
On 8/21/20 4:54 PM, Andrey Zherikov wrote:
> On Friday, 21 August 2020 at 20:44:27 UTC, Andrey Zherikov wrote:
>> Thanks for this link! I can use "#line" to fix line number but not file name:
>>
>> file: 'foo.d-mixin-1', line: '6', module: 'test',
>> function: 'test.main', pretty function: 'int test.main(string[] args)',
>> file full path: 'C:\Users\andrey\foo.d-mixin-1'
> 
> I can actually fix this issue as well.
> 
> Changes in test.d:
> 
>      test();                                          // line #16 (1)
>      mixin("#line 1 \"foo.d\"\n" ~ import("foo.d"));  // line #17 (2)
>      test();                                          // line #18 (3)
> 
> Output:
> 
> file: 'test.d', line: '16', module: 'test',
> function: 'test.main', pretty function: 'int test.main(string[] args)',
> file full path: 'C:\Users\andrey\test.d'
> file: 'foo.d', line: '6', module: 'test',
> function: 'test.main', pretty function: 'int test.main(string[] args)',
> file full path: 'C:\Users\andrey\foo.d'
> file: 'test.d', line: '18', module: 'test',
> function: 'test.main', pretty function: 'int test.main(string[] args)',
> file full path: 'C:\Users\andrey\test.d'

Was just in the process of responding with this technique!

I think what you probably did first is:

int main(string[] args)
{
    test();
#line 1 "foo.d"
    mixin(import("foo.d"));
    return 0;
}

Which sets the line and file of test.d at that point. But when the mixin happens, I believe the parser/lexer sets the filename, but does not set the line number to something different.

The hybrid line number (original source line number + mixin line number) seems like a bug to me.

-Steve
August 21, 2020
On Friday, 21 August 2020 at 21:06:11 UTC, Steven Schveighoffer wrote:
> The hybrid line number (original source line number + mixin line number) seems like a bug to me.

I'm not so sure without seeing all the code. Remember to the compiler, the mixin thing is just a big string literal at the location of the import statement.

So it adds the number of \n's in the string literal to the original line number to get the mixin line number.
August 21, 2020
On 8/21/20 5:08 PM, Adam D. Ruppe wrote:
> On Friday, 21 August 2020 at 21:06:11 UTC, Steven Schveighoffer wrote:
>> The hybrid line number (original source line number + mixin line number) seems like a bug to me.
> 
> I'm not so sure without seeing all the code. Remember to the compiler, the mixin thing is just a big string literal at the location of the import statement.
> 
> So it adds the number of \n's in the string literal to the original line number to get the mixin line number.

Look at the OP. It says line 22. Neither test.d nor the imported foo.d has 22 lines.

While not necessarily a "bug", it's not very useful. The compiler should output a useful line number. I shouldn't have to do math to figure out what it "really" means.

I'd argue that should be the line number based on the mixin source. The file name already is based on the line the string was mixed in, so both items contain useful data.

To be fair to the compiler, when you are mixing in an import, the mixin doesn't know that the string came from an imported file, so it can't really determine the file automatically. But the line number should be reasonable.

-Steve
August 21, 2020
On Friday, 21 August 2020 at 21:42:21 UTC, Steven Schveighoffer wrote:
> While not necessarily a "bug", it's not very useful.

Maybe not in this case, but it is perfectly accurate for cases like:

mixin(q{
   some code here
});

Where it will actually line back up to the original file's line number perfectly.


« First   ‹ Prev
1 2