Checking for clashes between field names and generated field names.
authorWouter van Oortmerssen <wvo@google.com>
Thu, 21 Aug 2014 22:02:15 +0000 (15:02 -0700)
committerWouter van Oortmerssen <wvo@google.com>
Fri, 22 Aug 2014 21:02:32 +0000 (14:02 -0700)
This happens when the schema is parsed, to avoid compile time errors
later, which would be harder to understand.

Bug: 16325216
Change-Id: I24cabf1adaf1700796b91e3a9641bca43a68bfbd
Tested: on OS X.

src/idl_parser.cpp
tests/test.cpp

index d3b9519..8b7f78e 100644 (file)
@@ -800,6 +800,31 @@ void Parser::ParseDecl() {
       }
     }
   }
+  // Check that no identifiers clash with auto generated fields.
+  // This is not an ideal situation, but should occur very infrequently,
+  // and allows us to keep using very readable names for type & length fields
+  // without inducing compile errors.
+  auto CheckClash = [&fields, &struct_def](const char *suffix,
+                                           BaseType basetype) {
+    auto len = strlen(suffix);
+    for (auto it = fields.begin(); it != fields.end(); ++it) {
+      auto &name = (*it)->name;
+      if (name.length() > len &&
+          name.compare(name.length() - len, len, suffix) == 0 &&
+          (*it)->value.type.base_type != BASE_TYPE_UTYPE) {
+        auto field = struct_def.fields.Lookup(
+                       name.substr(0, name.length() - len));
+        if (field && field->value.type.base_type == basetype)
+          Error("Field " + name +
+                " would clash with generated functions for field " +
+                field->name);
+      }
+    }
+  };
+  CheckClash("_type", BASE_TYPE_UNION);
+  CheckClash("Type", BASE_TYPE_UNION);
+  CheckClash("_length", BASE_TYPE_VECTOR);
+  CheckClash("Length", BASE_TYPE_VECTOR);
   Expect('}');
 }
 
index 07545a0..edb971a 100644 (file)
@@ -488,6 +488,7 @@ void ErrorTest() {
   TestError("struct X { Y:int; } root_type X;", "a table");
   TestError("union X { Y }", "referenced");
   TestError("union Z { X } struct X { Y:int; }", "only tables");
+  TestError("table X { Y:[int]; YLength:int; }", "clash");
 }
 
 // Additional parser testing not covered elsewhere.