Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create support for auto converting includes to imports. #43

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Mitten-O
Copy link

@Mitten-O Mitten-O commented Nov 1, 2015

Added command line options
--import-filter
A regular expression. All includes matching this will be converted to imports.
Only the basename part of the file name is used to generate the import.
--import-prefix
A prefix to give the imports. The import will have the form ""

This could be extended in the future to support filter-prefix pairs to give different prefixes to
includes from different paths, but this was all I needed for now.

@jacob-carlborg
Copy link
Owner

  • The existing tests break
  • There are no tests for this feature
  • The code doesn't follow the existing style. The new code isn't even consistent in it self

@Mitten-O Mitten-O force-pushed the include2import branch 2 times, most recently from e381fe4 to 7f28f12 Compare November 2, 2015 19:35
@Mitten-O
Copy link
Author

Mitten-O commented Nov 2, 2015

Sorry, I had trouble noticing the tests (I even tried to look for some, though not very hard), being unfamiliar with cucumber.

I created one now for the change I made and fixed what broke. Is one sufficient or should I maybe test the defaults or something like that?

I also tried to align my white space with your style. I'm a bit blind to it, though.

@@ -109,21 +123,43 @@ class IncludeHandler
imports ~= "core.stdc.config";
}

/// Makes includes that match regex filter be converted to import with prefix.
void setAutoImportPrefix (string prefix)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use properties instead of Java style setters.

@jacob-carlborg
Copy link
Owner

I created one now for the change I made and fixed what broke. Is one sufficient or should I maybe test the defaults or something like that?

There is already a simple test for includes. Not sure if that's enough.

dub.json Outdated
@@ -19,7 +19,7 @@
"targetName": "dstep",
"sourcePaths": ["dstep", "clang"],
"importPaths": ["dstep", "clang"],
"lflags-posix": ["-lclang", "-rpath", ".", "-L."],
"lflags-posix": ["-lclang","-lz", "-rpath", ".", "-L."],
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why this is necessary.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got linker errors from tango without it. Ubuntu 15.04, ldc 0.14.0.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's weird. Can you see in the linker error which function is using libz? Could you please try with DMD as well. I've never compiled DStep with LDC.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the full output:

The determined compiler type "ldc" doesn't match the expected type "dmd". This will probably result in build errors.
Target tango 1.0.1+2.067 is up to date. Use --force to rebuild.
Target mambo 0.0.4 is up to date. Use --force to rebuild.
Target dstack 0.0.3 is up to date. Use --force to rebuild.
Building dstep 0.1.1+commit.34.g582f71b configuration "default", build type debug.
Running ldmd2...
/usr/bin/ld: ../../../.dub/packages/tango-1.0.1_2.067/libtango.a(libtango.o): undefined reference to symbol 'inflateInit2_'
/lib/x86_64-linux-gnu/libz.so.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Error: /usr/bin/gcc failed with status: 1
FAIL .dub/build/default-debug-linux.posix-x86_64-ldc_2065-16CE78E47BDF9B160EF11DDF27A84EA1/ dstep executable
Error executing command build:
ldmd2 failed with exit code 1.

Seems to be missing inflateInit2.

Works fine without it when using dmd, but isn't this a small price for supporting ldc (or Ubuntu, or whatever has the bug that causes this)?

@Mitten-O
Copy link
Author

Mitten-O commented Nov 6, 2015

There is already a simple test for includes. Not sure if that's enough.
The added test checks that imports are automatically generated from included files.

The imports are actually generated only for headers whose types are actually used in the file. This is arguably unintuitive, but it works for my needs and was the most fluent way to add it to the existing logic. I added a note about this in the dummy include README.

@@ -109,12 +121,39 @@ class IncludeHandler
imports ~= "core.stdc.config";
}

@property{
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer that you put the @property attribute on each method.

@jacob-carlborg
Copy link
Owner

The imports are actually generated only for headers whose types are actually used in the file. This is arguably unintuitive, but it works for my needs and was the most fluent way to add it to the existing logic

One could argue that C includes are not very intuitive 😃. The problem with C includes is that they're not reliable. Often includes are missing because they're included implicitly through other includes. In some cases it's not even possible to add all required includes even if you wanted to. I have seen header files that don't include a single header file yet they still use types declared in other files.

Instead DStep looks at type (or similar) that is used in a header file and asks Clang where it's declared. Then it maps that answer from Clang to a corresponding D module.

@Mitten-O
Copy link
Author

Mitten-O commented Nov 8, 2015

I moved the attribute to its proper place. Yes, that looks much nicer. Thanks for bearing with me, I'm new to D. Even worse, because of my job, I'm pretty steeped in the dark age logic of c++.

BTW, if and when I finish polishing this to the standards of the project, would you like it to be rebased into a neater story or do you want to keep the full journey?

@jacob-carlborg
Copy link
Owner

BTW, if and when I finish polishing this to the standards of the project, would you like it to be rebased into a neater story or do you want to keep the full journey?

In this case I think it's best to squash all commits to one.

@@ -133,11 +172,33 @@ private:

string isKnownInclude (string include)
{
include = Path.stripExtension(include);
include = Path.stripExtension (include);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be no space between the function name and the opening parenthesis.

Added command line options
--import-filter
A regular expression. All includes matching this will be converted to imports.
Only the basename part of the file name is used to generate the import.
--import-prefix
A prefix to give the imports. The import will have the form "<prefix>.<basename>"

Includes a simple test case.
@Mitten-O
Copy link
Author

I'm back! I fixed the latest style deviations and squashed everything together. Also, it seems with the updates you have done, the need for the "lz" flag is gone so I got rid of that addition. So good updates, thanks.

@jacob-carlborg
Copy link
Owner

I have been thinking about this. I'm wondering if it's possible to automatically translate all includes as long as the files are nested within a given root directory. Given a directory layout as:

foo
  |- bar
  |   | - a.h
  |
  b.h

And b.h containing: #include "bar/a.h". When running DStep like dstep b.h --root foo, b.h would be translated to import foo.bar.a;, because a.h is located inside the given root, foo. Thoughts?

@Mitten-O
Copy link
Author

You mean to actually look for the includes in the file system and run dstep on them, too? That sounds rather useful. For projects that have one master header that includes the rest, one could translate the whole thing with one command.

My main interest lies in wrapping libgit2 for D (the available bindings are a bit outdated) and their header structure is fairly flat, so nested translation is not entirely necessary for my needs, though.

The other interpretation of what you suggest is to just translate the names, not reading the file system or anything, just converting includes that start with the root name to dotted form. That would be simpler to implement and certainly help already.

Either way a bit beyond the scope of this pull request. It's perfectly fine if you choose to reject this if my changes are in the way of some proper vision for include conversion.

@jacob-carlborg
Copy link
Owner

You mean to actually look for the includes in the file system and run dstep on them, too? That sounds rather useful. For projects that have one master header that includes the rest, one could translate the whole thing with one command.

No, that's not what I'm thinking.

The other interpretation of what you suggest is to just translate the names, not reading the file system or anything, just converting includes that start with the root name to dotted form. That would be simpler to implement and certainly help already.

That's kind of what I'm thinking.

DStep would continue to only add imports for what's used. The include directives are not reliable since includes are basically like public imports in D. I've also seen header files without a single include directive, yet they refer to symbols not present in the header file.

The idea of the --root flag is to get the top level package in D, and all the nested packages. For any symbol that is referenced in a header file that is declared in some other header file, which path is included in the root directory, specified with the --root flag, will be translated to an import statement.

Not sure if that explanation clarifies anything 😃. Would that be of any help for you?

Either way a bit beyond the scope of this pull request. It's perfectly fine if you choose to reject this if my changes are in the way of some proper vision for include conversion.

I don't think what I have in mind is any more complicated than this pull request (I hope 😃). I'm not saying that you need to implement my suggestion instead.

@Mitten-O
Copy link
Author

Ah, I think I get you now. In cases where there are no subfolders in foo, your dstep b.h --root foo would be equivalent with my dstep b.h --include-filter "foo/.*" --include-prefix "foo". It would have nesting, which my solution does not, and be more semantic, but less powerful than regexes. You're right, it does not sound too complicated. But it is a solution to the same problem my changes are trying to solve, so if you do go that way, this pull request will be obsolete.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants