You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by nw...@apache.org on 2013/07/01 20:48:09 UTC
[lucy-commits] [4/4] git commit: refs/heads/master - Check for class name and
nickname clashes
Check for class name and nickname clashes
Project: http://git-wip-us.apache.org/repos/asf/lucy/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/25b290f5
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/25b290f5
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/25b290f5
Branch: refs/heads/master
Commit: 25b290f56009dc942583085a921dbf4d76b5eb36
Parents: 2198b8b
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Mon Jul 1 02:36:29 2013 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Mon Jul 1 20:41:33 2013 +0200
----------------------------------------------------------------------
clownfish/compiler/perl/t/105-object_type.t | 7 +-
clownfish/compiler/perl/t/401-class.t | 26 ++++-
clownfish/compiler/perl/t/404-file.t | 102 ++++++++++---------
clownfish/compiler/perl/t/502-clash.t | 24 +----
clownfish/compiler/perl/t/600-parser.t | 2 +-
.../perl/t/cfclash/class/Animal/DogClash.cfh | 4 +-
.../perl/t/cfclash/class/AnimalExtension.cfp | 5 +
clownfish/compiler/src/CFCClass.c | 38 +++++--
clownfish/compiler/src/CFCTestFile.c | 5 +-
clownfish/compiler/src/CFCTestParser.c | 2 +-
clownfish/compiler/src/CFCTestType.c | 4 +-
11 files changed, 126 insertions(+), 93 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy/blob/25b290f5/clownfish/compiler/perl/t/105-object_type.t
----------------------------------------------------------------------
diff --git a/clownfish/compiler/perl/t/105-object_type.t b/clownfish/compiler/perl/t/105-object_type.t
index 2298f91..d20d01f 100644
--- a/clownfish/compiler/perl/t/105-object_type.t
+++ b/clownfish/compiler/perl/t/105-object_type.t
@@ -86,7 +86,7 @@ ok( !$foo_type->equals($bar_type), "different specifier spoils equals" );
my $foreign_foo_class = Clownfish::CFC::Model::Class->create(
parcel => 'Foreign',
- class_name => 'Foo',
+ class_name => 'Foreign::Foo',
);
my $foreign_foo = Clownfish::CFC::Model::Type->new_object(
specifier => 'Foo',
@@ -117,14 +117,11 @@ ok( !$foo_type->equals($decremented_foo),
"different decremented spoils equals"
);
-my $foo_class = Clownfish::CFC::Model::Class->create(
- class_name => 'Foo',
-);
my $const_foo = Clownfish::CFC::Model::Type->new_object(
specifier => 'Foo',
const => 1,
);
-$const_foo->resolve([ $foo_class ]);
+$const_foo->resolve(\@classes);
ok( !$foo_type->equals($const_foo), "different const spoils equals" );
like( $const_foo->to_c, qr/const/, "const included in C representation" );
http://git-wip-us.apache.org/repos/asf/lucy/blob/25b290f5/clownfish/compiler/perl/t/401-class.t
----------------------------------------------------------------------
diff --git a/clownfish/compiler/perl/t/401-class.t b/clownfish/compiler/perl/t/401-class.t
index d611440..5e37cc3 100644
--- a/clownfish/compiler/perl/t/401-class.t
+++ b/clownfish/compiler/perl/t/401-class.t
@@ -16,7 +16,7 @@
use strict;
use warnings;
-use Test::More tests => 52;
+use Test::More tests => 54;
use Clownfish::CFC::Model::Class;
use Clownfish::CFC::Parser;
@@ -49,15 +49,33 @@ my $foo = Clownfish::CFC::Model::Class->create(%foo_create_args);
$foo->add_function($tread_water);
$foo->add_member_var($thing);
$foo->add_inert_var($widget);
-eval { Clownfish::CFC::Model::Class->create(%foo_create_args) };
-like( $@, qr/conflict/i,
- "Can't call create for the same class more than once" );
my $should_be_foo = Clownfish::CFC::Model::Class->fetch_singleton(
parcel => 'Neato',
class_name => 'Foo',
);
is( $$foo, $$should_be_foo, "fetch_singleton" );
+eval { Clownfish::CFC::Model::Class->create(%foo_create_args) };
+like( $@, qr/two classes with name/i,
+ "Can't call create for the same class more than once" );
+eval {
+ Clownfish::CFC::Model::Class->create(
+ parcel => 'Neato',
+ class_name => 'Other::Foo',
+ );
+};
+like( $@, qr/class name conflict/i,
+ "Can't create classes wth the same final component" );
+eval {
+ Clownfish::CFC::Model::Class->create(
+ parcel => 'Neato',
+ class_name => 'Bar',
+ cnick => 'Foo',
+ );
+};
+like( $@, qr/class nickname conflict/i,
+ "Can't create classes wth the same nickname" );
+
my $foo_jr = Clownfish::CFC::Model::Class->create(
parcel => 'Neato',
class_name => 'Foo::FooJr',
http://git-wip-us.apache.org/repos/asf/lucy/blob/25b290f5/clownfish/compiler/perl/t/404-file.t
----------------------------------------------------------------------
diff --git a/clownfish/compiler/perl/t/404-file.t b/clownfish/compiler/perl/t/404-file.t
index 8f8a700..11668c4 100644
--- a/clownfish/compiler/perl/t/404-file.t
+++ b/clownfish/compiler/perl/t/404-file.t
@@ -40,50 +40,60 @@ my $file_spec = Clownfish::CFC::Model::FileSpec->new(
source_dir => '.',
path_part => $path_part,
);
-my $file
- = $parser->_parse_file( "$parcel_declaration\n$class_content\n$c_block",
- $file_spec );
-
-is( $file->get_source_dir, ".", "get_source_dir" );
-is( $file->get_path_part, $path_part, "get_path_part" );
-ok( !$file->included, "included" );
-
-my $guard_name = $file->guard_name;
-is( $guard_name, "H_STUFF_THING", "guard_name" );
-like( $file->guard_start, qr/$guard_name/, "guard_start" );
-like( $file->guard_close, qr/$guard_name/,
- "guard_close includes guard_name" );
-
-ok( !$file->get_modified, "modified false at start" );
-$file->set_modified(1);
-ok( $file->get_modified, "set_modified, get_modified" );
-
-my $path_sep = $^O =~ /^mswin/i ? '\\' : '/';
-my $path_to_stuff_thing = join( $path_sep, qw( path to Stuff Thing ) );
-is( $file->cfh_path('path/to'), "$path_to_stuff_thing.cfh", "cfh_path" );
-is( $file->c_path('path/to'), "$path_to_stuff_thing.c", "c_path" );
-is( $file->h_path('path/to'), "$path_to_stuff_thing.h", "h_path" );
-
-my $classes = $file->classes;
-is( scalar @$classes, 3, "classes() filters blocks" );
-my $class = $classes->[0];
-my ( $foo, $bar ) = @{ $class->member_vars };
-$foo->resolve_type($classes);
-$bar->resolve_type($classes);
-is( $foo->get_type->get_specifier,
- 'stuff_Foo', 'file production picked up parcel def' );
-is( $bar->get_type->get_specifier, 'stuff_Bar', 'parcel def is sticky' );
-
-my $blocks = $file->blocks;
-is( scalar @$blocks, 5, "all five blocks" );
-isa_ok( $blocks->[0], "Clownfish::CFC::Model::Parcel" );
-isa_ok( $blocks->[1], "Clownfish::CFC::Model::Class" );
-isa_ok( $blocks->[2], "Clownfish::CFC::Model::Class" );
-isa_ok( $blocks->[3], "Clownfish::CFC::Model::Class" );
-isa_ok( $blocks->[4], "Clownfish::CFC::Model::CBlock" );
-
-$file = $parser->_parse_file( $class_content, $file_spec );
-($class) = @{ $file->classes };
-( $foo, $bar ) = @{ $class->member_vars };
-is( $foo->get_type->get_specifier, 'Foo', 'file production resets parcel' );
+
+{
+ my $file
+ = $parser->_parse_file( "$parcel_declaration\n$class_content\n$c_block",
+ $file_spec );
+
+ is( $file->get_source_dir, ".", "get_source_dir" );
+ is( $file->get_path_part, $path_part, "get_path_part" );
+ ok( !$file->included, "included" );
+
+ my $guard_name = $file->guard_name;
+ is( $guard_name, "H_STUFF_THING", "guard_name" );
+ like( $file->guard_start, qr/$guard_name/, "guard_start" );
+ like( $file->guard_close, qr/$guard_name/,
+ "guard_close includes guard_name" );
+
+ ok( !$file->get_modified, "modified false at start" );
+ $file->set_modified(1);
+ ok( $file->get_modified, "set_modified, get_modified" );
+
+ my $path_sep = $^O =~ /^mswin/i ? '\\' : '/';
+ my $path_to_stuff_thing = join( $path_sep, qw( path to Stuff Thing ) );
+ is( $file->cfh_path('path/to'), "$path_to_stuff_thing.cfh", "cfh_path" );
+ is( $file->c_path('path/to'), "$path_to_stuff_thing.c", "c_path" );
+ is( $file->h_path('path/to'), "$path_to_stuff_thing.h", "h_path" );
+
+ my $classes = $file->classes;
+ is( scalar @$classes, 3, "classes() filters blocks" );
+ my $class = $classes->[0];
+ my ( $foo, $bar ) = @{ $class->member_vars };
+ $foo->resolve_type($classes);
+ $bar->resolve_type($classes);
+ is( $foo->get_type->get_specifier,
+ 'stuff_Foo', 'file production picked up parcel def' );
+ is( $bar->get_type->get_specifier, 'stuff_Bar', 'parcel def is sticky' );
+
+ my $blocks = $file->blocks;
+ is( scalar @$blocks, 5, "all five blocks" );
+ isa_ok( $blocks->[0], "Clownfish::CFC::Model::Parcel" );
+ isa_ok( $blocks->[1], "Clownfish::CFC::Model::Class" );
+ isa_ok( $blocks->[2], "Clownfish::CFC::Model::Class" );
+ isa_ok( $blocks->[3], "Clownfish::CFC::Model::Class" );
+ isa_ok( $blocks->[4], "Clownfish::CFC::Model::CBlock" );
+
+ Clownfish::CFC::Model::Class->_clear_registry();
+}
+
+{
+ my $file = $parser->_parse_file( $class_content, $file_spec );
+ my ($class) = @{ $file->classes };
+ my ( $foo, $bar ) = @{ $class->member_vars };
+ is( $foo->get_type->get_specifier, 'Foo', 'file production resets parcel' );
+
+ Clownfish::CFC::Model::Class->_clear_registry();
+}
+
http://git-wip-us.apache.org/repos/asf/lucy/blob/25b290f5/clownfish/compiler/perl/t/502-clash.t
----------------------------------------------------------------------
diff --git a/clownfish/compiler/perl/t/502-clash.t b/clownfish/compiler/perl/t/502-clash.t
index b095c34..85df4d0 100644
--- a/clownfish/compiler/perl/t/502-clash.t
+++ b/clownfish/compiler/perl/t/502-clash.t
@@ -16,7 +16,7 @@
use strict;
use warnings;
-use Test::More tests => 6;
+use Test::More tests => 5;
use Clownfish::CFC::Model::Hierarchy;
use File::Spec::Functions qw( catdir catfile splitpath );
@@ -32,21 +32,6 @@ my $file_clash_dir = catdir(qw( t cfclash file ));
my $hierarchy = Clownfish::CFC::Model::Hierarchy->new(dest => $dest_dir);
$hierarchy->add_source_dir($base_dir);
- $hierarchy->add_source_dir($class_clash_dir);
-
- eval { $hierarchy->build; };
-
- like( $@, qr/Conflict with existing class Animal::Dog/,
- "source/source class name clash" );
-
- Clownfish::CFC::Model::Class->_clear_registry();
- Clownfish::CFC::Model::Parcel->reap_singletons();
-}
-
-{
- my $hierarchy = Clownfish::CFC::Model::Hierarchy->new(dest => $dest_dir);
-
- $hierarchy->add_source_dir($base_dir);
$hierarchy->add_source_dir($file_clash_dir);
eval { $hierarchy->build; };
@@ -62,13 +47,12 @@ my $file_clash_dir = catdir(qw( t cfclash file ));
{
my $hierarchy = Clownfish::CFC::Model::Hierarchy->new(dest => $dest_dir);
- $hierarchy->add_source_dir($base_dir);
- $hierarchy->add_include_dir($class_clash_dir);
+ $hierarchy->add_source_dir($class_clash_dir);
+ $hierarchy->add_include_dir($base_dir);
eval { $hierarchy->build; };
- like( $@, qr/Class .* from include dir .* parcel .* from source dir/,
- "source/include class name clash" );
+ like( $@, qr/Two classes with name/, "source/include class name clash" );
Clownfish::CFC::Model::Class->_clear_registry();
Clownfish::CFC::Model::Parcel->reap_singletons();
http://git-wip-us.apache.org/repos/asf/lucy/blob/25b290f5/clownfish/compiler/perl/t/600-parser.t
----------------------------------------------------------------------
diff --git a/clownfish/compiler/perl/t/600-parser.t b/clownfish/compiler/perl/t/600-parser.t
index 5ac2269..6d9f297 100644
--- a/clownfish/compiler/perl/t/600-parser.t
+++ b/clownfish/compiler/perl/t/600-parser.t
@@ -156,7 +156,7 @@ SKIP: {
is( $parser->parse(qq|class Foodie$_ cnick $_ { }|)->get_cnick,
$_, "cnick: $_" )
- for (qw( Foo FF ));
+ for (qw( Food FF ));
SKIP: {
skip( "Can't recover from bad cnick under flex/lemon parser", 3 );
http://git-wip-us.apache.org/repos/asf/lucy/blob/25b290f5/clownfish/compiler/perl/t/cfclash/class/Animal/DogClash.cfh
----------------------------------------------------------------------
diff --git a/clownfish/compiler/perl/t/cfclash/class/Animal/DogClash.cfh b/clownfish/compiler/perl/t/cfclash/class/Animal/DogClash.cfh
index 6d54baa..3eba020 100644
--- a/clownfish/compiler/perl/t/cfclash/class/Animal/DogClash.cfh
+++ b/clownfish/compiler/perl/t/cfclash/class/Animal/DogClash.cfh
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-parcel Animal;
+parcel AnimalExtension;
-class Animal::Dog inherits Animal {
+class Animal::Dog inherits Clownfish::Obj {
public inert incremented Dog*
new();
http://git-wip-us.apache.org/repos/asf/lucy/blob/25b290f5/clownfish/compiler/perl/t/cfclash/class/AnimalExtension.cfp
----------------------------------------------------------------------
diff --git a/clownfish/compiler/perl/t/cfclash/class/AnimalExtension.cfp b/clownfish/compiler/perl/t/cfclash/class/AnimalExtension.cfp
new file mode 100644
index 0000000..76f31d3
--- /dev/null
+++ b/clownfish/compiler/perl/t/cfclash/class/AnimalExtension.cfp
@@ -0,0 +1,5 @@
+{
+ "name": "AnimalExtension",
+ "nickname": "AniExt",
+ "version": "v0.1.0"
+}
http://git-wip-us.apache.org/repos/asf/lucy/blob/25b290f5/clownfish/compiler/src/CFCClass.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCClass.c b/clownfish/compiler/src/CFCClass.c
index a84c5f6..2476071 100644
--- a/clownfish/compiler/src/CFCClass.c
+++ b/clownfish/compiler/src/CFCClass.c
@@ -254,10 +254,6 @@ CFCClass_destroy(CFCClass *self) {
static void
S_register(CFCClass *self) {
- /*
- * TODO: Verify that there isn't a class with the same class_name in
- * another parcel. Verify that cnick is unique within this parcel.
- */
if (registry_size == registry_cap) {
size_t new_cap = registry_cap + 10;
registry = (CFCClassRegEntry*)REALLOCATE(
@@ -269,15 +265,35 @@ S_register(CFCClass *self) {
}
registry_cap = new_cap;
}
- CFCParcel *parcel = CFCClass_get_parcel(self);
+
+ CFCParcel *parcel = CFCClass_get_parcel(self);
+ const char *prefix = CFCParcel_get_prefix(parcel);
const char *class_name = CFCClass_get_class_name(self);
- CFCClass *existing = CFCClass_fetch_singleton(parcel, class_name);
- const char *key = self->full_struct_sym;
- if (existing) {
- CFCBase_decref((CFCBase*)self);
- CFCUtil_die("Conflict with existing class %s",
- CFCClass_get_class_name(existing));
+ const char *cnick = CFCClass_get_cnick(self);
+ const char *key = self->full_struct_sym;
+
+ for (size_t i = 0; i < registry_size; i++) {
+ CFCClass *other = registry[i].klass;
+ CFCParcel *other_parcel = CFCClass_get_parcel(other);
+ const char *other_prefix = CFCParcel_get_prefix(other_parcel);
+ const char *other_class_name = CFCClass_get_class_name(other);
+ const char *other_cnick = CFCClass_get_cnick(other);
+
+ if (strcmp(class_name, other_class_name) == 0) {
+ CFCUtil_die("Two classes with name %s", class_name);
+ }
+ if (strcmp(registry[i].key, key) == 0) {
+ CFCUtil_die("Class name conflict between %s and %s",
+ class_name, other_class_name);
+ }
+ if (strcmp(prefix, other_prefix) == 0
+ && strcmp(cnick, other_cnick) == 0
+ ) {
+ CFCUtil_die("Class nickname conflict between %s and %s",
+ class_name, other_class_name);
+ }
}
+
registry[registry_size].key = CFCUtil_strdup(key);
registry[registry_size].klass = (CFCClass*)CFCBase_incref((CFCBase*)self);
registry_size++;
http://git-wip-us.apache.org/repos/asf/lucy/blob/25b290f5/clownfish/compiler/src/CFCTestFile.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCTestFile.c b/clownfish/compiler/src/CFCTestFile.c
index f62b919..ad1cd5c 100644
--- a/clownfish/compiler/src/CFCTestFile.c
+++ b/clownfish/compiler/src/CFCTestFile.c
@@ -119,6 +119,8 @@ S_run_tests(CFCTest *test) {
OK(test, blocks[5] == NULL, "blocks[5]");
CFCBase_decref((CFCBase*)file);
+
+ CFCClass_clear_registry();
}
{
@@ -135,12 +137,13 @@ S_run_tests(CFCTest *test) {
"file production resets parcel");
CFCBase_decref((CFCBase*)file);
+
+ CFCClass_clear_registry();
}
CFCBase_decref((CFCBase*)file_spec);
CFCBase_decref((CFCBase*)parser);
- CFCClass_clear_registry();
CFCParcel_reap_singletons();
}
http://git-wip-us.apache.org/repos/asf/lucy/blob/25b290f5/clownfish/compiler/src/CFCTestParser.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCTestParser.c b/clownfish/compiler/src/CFCTestParser.c
index 04c39e7..ca8ad2c 100644
--- a/clownfish/compiler/src/CFCTestParser.c
+++ b/clownfish/compiler/src/CFCTestParser.c
@@ -293,7 +293,7 @@ S_run_tests(CFCTest *test) {
}
{
- static const char *const cnicks[2] = { "Foo", "FF" };
+ static const char *const cnicks[2] = { "Food", "FF" };
for (int i = 0; i < 2; ++i) {
const char *cnick = cnicks[i];
char *class_string
http://git-wip-us.apache.org/repos/asf/lucy/blob/25b290f5/clownfish/compiler/src/CFCTestType.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCTestType.c b/clownfish/compiler/src/CFCTestType.c
index d1d9b08..af85017 100644
--- a/clownfish/compiler/src/CFCTestType.c
+++ b/clownfish/compiler/src/CFCTestType.c
@@ -354,8 +354,8 @@ S_run_object_tests(CFCTest *test) {
CFCParcel *foreign_parcel
= CFCParcel_new("Foreign", NULL, NULL, false);
CFCClass *foreign_foo_class
- = CFCClass_create(foreign_parcel, NULL, "Foo", NULL, NULL, NULL,
- NULL, NULL, false, false);
+ = CFCClass_create(foreign_parcel, NULL, "Foreign::Foo", NULL, NULL,
+ NULL, NULL, NULL, false, false);
CFCClass *foreign_class_list[2] = { foreign_foo_class, NULL };
CFCType *foreign_foo = CFCType_new_object(0, foreign_parcel, "Foo", 1);
CFCType_resolve(foreign_foo, foreign_class_list);