Skip to content

Commit

Permalink
fix Issue 10302 - Package module conflicts with package name
Browse files Browse the repository at this point in the history
  • Loading branch information
9rnsr committed Jun 10, 2013
1 parent 61de9e5 commit 03236ad
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 4 deletions.
13 changes: 13 additions & 0 deletions src/dsymbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,19 @@ Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags)
//printf("%s->ScopeDsymbol::search(ident='%s', flags=x%x)\n", toChars(), ident->toChars(), flags);
//if (strcmp(ident->toChars(),"c") == 0) *(char*)0=0;

if (Package *pkg = isPackage())
{
if (!pkg->isModule() && pkg->mod)
{
// Prefer full package name.
Dsymbol *s = pkg->symtab ? pkg->symtab->lookup(ident) : NULL;
if (s)
return s;
//printf("[%s] through pkdmod: %s\n", loc.toChars(), pkg->toChars());
return pkg->mod->search(loc, ident, flags);
}
}

// Look in symbols declared in this module
Dsymbol *s = symtab ? symtab->lookup(ident) : NULL;
//printf("\ts = %p, imports = %p, %d\n", s, imports, imports ? imports->dim : 0);
Expand Down
2 changes: 1 addition & 1 deletion src/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -7460,7 +7460,7 @@ Expression *DotIdExp::semanticY(Scope *sc, int flag)
ScopeDsymbol *sds = s->isScopeDsymbol();
if (sds)
{
//printf("it's a ScopeDsymbol\n");
//printf("it's a ScopeDsymbol %s\n", ident->toChars());
e = new ScopeExp(loc, sds);
e = e->semantic(sc);
if (eleft)
Expand Down
20 changes: 20 additions & 0 deletions src/import.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,26 @@ void Import::load(Scope *sc)
{
::error(loc, "%s %s conflicts with %s", s->kind(), s->toPrettyChars(), id->toChars());
}
else if (Package *p = s->isPackage())
{
if (p->isPkgMod == PKGunknown)
{
mod = Module::load(loc, packages, id);
if (!mod)
p->isPkgMod = PKGpackage;
else
assert(p->isPkgMod == PKGmodule);
}
else if (p->isPkgMod == PKGmodule)
{
mod = p->mod;
}
if (p->isPkgMod != PKGmodule)
{
::error(loc, "can only import from a module, not from package %s.%s",
p->toPrettyChars(), id->toChars());
}
}
else if (pkg)
{
::error(loc, "can only import from a module, not from package %s.%s",
Expand Down
44 changes: 41 additions & 3 deletions src/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,34 @@ void Module::parse()
}

// Insert module into the symbol table
if (!dst->insert(this))
Dsymbol *s = this;
bool isPackageMod = strcmp(srcfile->name->name(), "package.d") == 0;
if (isPackageMod)
{
/* If the source tree is as follows:
* pkg/
* +- package.d
* +- common.d
* the 'pkg' will be incorporated to the internal package tree in two ways:
* import pkg;
* and:
* import pkg.common;
*
* If both are used in one compilation, 'pkg' as a module (== pkg/package.d)
* and a package name 'pkg' will conflict each other.
*
* To avoid the confliction,
* 1. If preceding package name insertion had occurred by Package::resolve,
* later package.d loading will change Package::isPkgMod to PKGmodule and set Package::mod.
* 2. Otherwise, 'package.d' wrapped by 'Package' is inserted to the internal tree in here.
*/
Package *p = new Package(ident);
p->isPkgMod = PKGmodule;
p->mod = this;
p->symtab = new DsymbolTable();
s = p;
}
if (!dst->insert(s))
{
/* It conflicts with a name that is already in the symbol table.
* Figure out what went wrong, and issue error message.
Expand All @@ -561,8 +588,17 @@ void Module::parse()
{
Package *pkg = prev->isPackage();
assert(pkg);
error(pkg->loc, "from file %s conflicts with package name %s",
srcname, pkg->toChars());
if (pkg->isPkgMod == PKGunknown && isPackageMod)
{
/* If the previous inserted Package is not yet determined as package.d,
* link it to the actual module.
*/
pkg->isPkgMod = PKGmodule;
pkg->mod = this;
}
else
error(pkg->loc, "from file %s conflicts with package name %s",
srcname, pkg->toChars());
}
}
else
Expand Down Expand Up @@ -1038,6 +1074,8 @@ char *ModuleDeclaration::toChars()
Package::Package(Identifier *ident)
: ScopeDsymbol(ident)
{
this->isPkgMod = PKGunknown;
this->mod = NULL;
}


Expand Down
10 changes: 10 additions & 0 deletions src/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,19 @@ union tree_node; typedef union tree_node elem;
struct elem;
#endif

enum PKG
{
PKGunknown, // not yet determined whether it's a package.d or not
PKGmodule, // already determined that's an actual package.d
PKGpackage, // already determined that's an actual package
};

class Package : public ScopeDsymbol
{
public:
PKG isPkgMod;
Module *mod; // != NULL if isPkgMod == PKGmodule

Package(Identifier *ident);
const char *kind();

Expand Down
2 changes: 2 additions & 0 deletions test/compilable/extra-files/pkgDIP37_10302/liba.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module pkgDIP37_10302.liba;
void foo() {}
11 changes: 11 additions & 0 deletions test/compilable/extra-files/pkgDIP37_10302/libb.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module pkgDIP37_10302.libb;
import pkgDIP37_10302.liba;
void bar()
{
foo();

// should be error, but unfortunately this works by bug 314 now.
//lib.foo();

pkgDIP37_10302.liba.foo();
}
2 changes: 2 additions & 0 deletions test/compilable/extra-files/pkgDIP37_10302/package.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module pkgDIP37_10302;
public import pkgDIP37_10302.liba;
8 changes: 8 additions & 0 deletions test/compilable/testDIP37_10302.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -c -Icompilable/extra-files
// REQUIRED_ARGS: compilable/extra-files/pkgDIP37_10302/liba.d
// REQUIRED_ARGS: compilable/extra-files/pkgDIP37_10302/libb.d

module test;
import pkgDIP37_10302;
void main() {}
7 changes: 7 additions & 0 deletions test/fail_compilation/test64.d
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/*
TEST_OUTPUT:
---
Error: module imports from file fail_compilation/imports/test64a.d conflicts with package name imports
---
*/

// PERMUTE_ARGS:

import std.stdio;
Expand Down

0 comments on commit 03236ad

Please sign in to comment.