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

Fix #2529: explicit protection package #3651

Merged
merged 13 commits into from Aug 26, 2014
Merged

Fix #2529: explicit protection package #3651

merged 13 commits into from Aug 26, 2014

Conversation

mihails-strasuns
Copy link

https://issues.dlang.org/show_bug.cgi?id=2529

This does not implement original proposal from linked bugzilla entry but addresses same goal.

Currently there is no way to use package protection attribute with deeply nested package hierarchy, forcing to either use flat one or public protection. This is one of blocking issues for further usage of package.d in Phobos and one of reasons why namespace hacks are so popular.

For example, if helpers in std.internal will be marked as package, only std.internal will be able to access those, but not rest of std. This PR fixes it by allowing package(<pkgname>) syntax to explicitly define owning package.

This new syntax will work:

module std.internal.mod1;
package(std) void foo() {}
module std.mod2;
import std.internal.mod2;
void bar() { foo(); }

Exact semantics can are described by added "protection" tests to test/compilable (last commit in this PR).

Plain package behavior is unchanged and thus no breaking changes introduced.

@jacob-carlborg
Copy link
Contributor

Perhaps you could add a couple of failing tests. Like accessing a symbol which you don't have access to. Also pass some invalid stuff to the package keyword.

@jacob-carlborg
Copy link
Contributor

Could you also create a pull request which updates the documentation.

@mihails-strasuns
Copy link
Author

Perhaps you could add a couple of failing tests.

Added tests have failing one too, via !is(typeof(foo())). I wanted to put all relevant tests in one place and thus didn't separate those into "failing" directory. Don't know what is better - to keep locality or actually check the error message.

Also pass some invalid stuff to the package keyword.

Any valid identifier is valid there right now and it is kind of intended. You may define protection for a package not yet encountered. I can't see any reason why it should be prohibited but I may have missed something.

@mihails-strasuns
Copy link
Author

Could you also create a pull request which updates the documentation.

Updated linked grammar PR to include doc changes too.

@jacob-carlborg
Copy link
Contributor

Added tests have failing one too, via !is(typeof(foo())). I wanted to put all relevant tests in one place and thus didn't separate those into "failing" directory. Don't know what is better - to keep locality or actually check the error message.

I thought it would be nice to check the error message as well. I don't know what others think.

Any valid identifier is valid there right now and it is kind of intended. You may define protection for a package not yet encountered. I can't see any reason why it should be prohibited but I may have missed something.

Then add a test that doesn't use a valid identifier 😉, or something that is not an identifier at all. I don't know if I'm too cautious, but I don't think it hurts add.

* Returns:
* see description
*/
bool Package::isSubpackage(Package* pkg)
Copy link

Choose a reason for hiding this comment

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

This reads funny as a binary relation.

x.isSubpackage(y);

I would read that as "is x a subpackage of y?" It took me a while to figure it out, and I only understood it by reading the document comment in the end. I would rename the function to something like isAncestorPacakgeOf or similar.

That's literally the only thing wrong I found with this diff.

@mihails-strasuns
Copy link
Author

Will update according to all comments as soon as I will figure out what this DDOC test failure is about :)

@mihails-strasuns
Copy link
Author

Also link to NG discussion : http://forum.dlang.org/post/cwjqwlkakjuwhfewvlhf@forum.dlang.org
So far no objections against feature itself.

@jacob-carlborg
Copy link
Contributor

Why does the error message says: "attribute __anonymous"?

@mihails-strasuns
Copy link
Author

Because this is how defailt formatting for attribute / dsymbol is defined. And I have no idea how it supposed to be changed (other than overriding all relevant methods) :( Need someone more experienced with dmd to chime in here.

@mihails-strasuns
Copy link
Author

Ok, kind of of figured out that error message thing, does not look pretty but it works.

All previous review comments should be addressed by now.

@mihails-strasuns
Copy link
Author

Test failed: Invalid UTF-8 sequence (at index 1)
can't reproduce this locally >_<

@andralex
Copy link
Member

status?

@mihails-strasuns
Copy link
Author

  • trying to guess why auto-tester has considered added samples invalid UTF-8
  • waiting if @9rnsr has any other objections / comments

@mihails-strasuns
Copy link
Author

This failure drives me crazy. @DmitryOlshansky maybe you have any ideas? Exception refers to Invalid UTF sequence: e9 but I can't even find such byte in hexdump of source files. And other added protattr cases work just fine X_X

@mihails-strasuns
Copy link
Author

Nailed it. Exception was referring not to source file but compiler output. Stupid invalid memory access mistake :)

@Safety0ff
Copy link
Contributor

Hmm, 0xe9 in a file with 0xe9 bytes.

Looks like its passing on the build hosts it was failing on, glad I could be of help!

@mihails-strasuns
Copy link
Author

Yay, green.

@@ -283,14 +303,14 @@ class ScopeDsymbol : public Dsymbol

private:
Dsymbols *imports; // imported Dsymbol's
PROT *prots; // array of PROT, one for each import
PROTKIND *prots; // array of PROTTYPE, one for each import
Copy link
Contributor

Choose a reason for hiding this comment

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

s/PROTTYPE/PROTKIND/

@9rnsr
Copy link
Contributor

9rnsr commented Jun 15, 2014

The overall direction looks fine to me.

@mihails-strasuns
Copy link
Author

That should be all, waiting for an auto-tester.

// protection to
if ((pAttrs->protection.kind == PROTpackage) && (token.value == TOKlparen))
{
pkg_prot_idents = parseQualifiedIdentifier("protection package");
Copy link
Member

Choose a reason for hiding this comment

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

whitespace problem

@WalterBright
Copy link
Member

Meta comment - renaming PROT to Prot made for a lot of extra diffs, making it harder to see what was actually changing. It also likely makes for frequent rebasing of this and other PR's.

@mihails-strasuns
Copy link
Author

Thanks for comments!

Meta comment - renaming PROT to Prot made for a lot of extra diffs, making it harder to see what was actually changing. It also likely makes for frequent rebasing of this and other PR's.

Keeping old name will only hide the issue, most of conflicts come from the fact that Prot is not a plain enum anymore and this pretty much any new code that works with it results in a failure. If same name is kept it may not result in conflict but will still stop compiling.

Will update to latest master this weekend.

Dicebot added 10 commits August 24, 2014 16:45
Makes it possible to easily add additional protection
information and differentiates between protected imports
and actual attribute.
This commit adds capability of parsing and resolving
explicit package defined for package protection attribute. Adjusting
acess checks to use it will be done in separate commit.
Fix relevant issue by allowing to explicitly define
package to bind protection attribute to. Defaults
remain unchanged.
Using non-existent or non-parent package as an argument to
'package' protection attribute will result in compile-time error.

Test cases with error message output added.
Now includes actual protection attribute kind and package name (if any)
    into error message. Also stores location information from the parser.
@mihails-strasuns
Copy link
Author

Rebased, addressed all but one @WalterBright comment (asked clarification for that one)

@mihails-strasuns
Copy link
Author

Green

WalterBright added a commit that referenced this pull request Aug 26, 2014
@WalterBright WalterBright merged commit a41dccc into dlang:master Aug 26, 2014
@mihails-strasuns
Copy link
Author

Thanks! A most pleasant surprise :)

9rnsr added a commit that referenced this pull request Aug 28, 2014
[Refactoring] around protection code fixed in the PR #3651
@MartinNowak MartinNowak added this to the 2.067 milestone Mar 6, 2015
@MartinNowak
Copy link
Member

Needs to go into the changelog.

@mihails-strasuns
Copy link
Author

Assign me please

@MartinNowak
Copy link
Member

Assign me please

Github wouldn't let, sorry @Dicebot, but I can ping you for a reminder.

John-Colvin pushed a commit to John-Colvin/dlang.org that referenced this pull request Mar 17, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet