Add checks for interface name symbol clashes

This commit is contained in:
William S Fulton 2016-03-03 22:48:35 +00:00
commit 7d76617dc3
4 changed files with 40 additions and 8 deletions

View file

@ -2081,6 +2081,7 @@ public:
if (proxy_flag) { if (proxy_flag) {
proxy_class_name = NewString(Getattr(n, "sym:name")); proxy_class_name = NewString(Getattr(n, "sym:name"));
String *interface_name = Getattr(n, "feature:interface") ? Getattr(n, "interface:name") : 0;
if (Node *outer = Getattr(n, "nested:outer")) { if (Node *outer = Getattr(n, "nested:outer")) {
String *outerClassesPrefix = Copy(Getattr(outer, "sym:name")); String *outerClassesPrefix = Copy(Getattr(outer, "sym:name"));
for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) { for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) {
@ -2090,13 +2091,16 @@ public:
String *fnspace = nspace ? NewStringf("%s.%s", nspace, outerClassesPrefix) : outerClassesPrefix; String *fnspace = nspace ? NewStringf("%s.%s", nspace, outerClassesPrefix) : outerClassesPrefix;
if (!addSymbol(proxy_class_name, n, fnspace)) if (!addSymbol(proxy_class_name, n, fnspace))
return SWIG_ERROR; return SWIG_ERROR;
if (interface_name && !addInterfaceSymbol(interface_name, n, fnspace))
return SWIG_ERROR;
if (nspace) if (nspace)
Delete(fnspace); Delete(fnspace);
Delete(outerClassesPrefix); Delete(outerClassesPrefix);
} } else {
else {
if (!addSymbol(proxy_class_name, n, nspace)) if (!addSymbol(proxy_class_name, n, nspace))
return SWIG_ERROR; return SWIG_ERROR;
if (interface_name && !addInterfaceSymbol(interface_name, n, nspace))
return SWIG_ERROR;
} }
if (!nspace) { if (!nspace) {
@ -2135,7 +2139,6 @@ public:
if (Getattr(n, "feature:interface")) { if (Getattr(n, "feature:interface")) {
interface_class_code = NewString(""); interface_class_code = NewString("");
String *interface_name = Getattr(n, "interface:name");
String *output_directory = outputDirectory(nspace); String *output_directory = outputDirectory(nspace);
f_interface = getOutputFile(output_directory, interface_name); f_interface = getOutputFile(output_directory, interface_name);
addOpenNamespace(nspace, f_interface); addOpenNamespace(nspace, f_interface);

View file

@ -2136,17 +2136,21 @@ public:
} }
} }
String *interface_name = Getattr(n, "feature:interface") ? Getattr(n, "interface:name") : 0;
if (outerClassesPrefix) { if (outerClassesPrefix) {
String *fnspace = nspace ? NewStringf("%s.%s", nspace, outerClassesPrefix) : outerClassesPrefix; String *fnspace = nspace ? NewStringf("%s.%s", nspace, outerClassesPrefix) : outerClassesPrefix;
if (!addSymbol(proxy_class_name, n, fnspace)) if (!addSymbol(proxy_class_name, n, fnspace))
return SWIG_ERROR; return SWIG_ERROR;
if (interface_name && !addInterfaceSymbol(interface_name, n, fnspace))
return SWIG_ERROR;
if (nspace) if (nspace)
Delete(fnspace); Delete(fnspace);
Delete(outerClassesPrefix); Delete(outerClassesPrefix);
} } else {
else {
if (!addSymbol(proxy_class_name, n, nspace)) if (!addSymbol(proxy_class_name, n, nspace))
return SWIG_ERROR; return SWIG_ERROR;
if (interface_name && !addInterfaceSymbol(interface_name, n, nspace))
return SWIG_ERROR;
} }
// Each outer proxy class goes into a separate file // Each outer proxy class goes into a separate file
@ -2185,7 +2189,6 @@ public:
if (Getattr(n, "feature:interface")) { if (Getattr(n, "feature:interface")) {
interface_class_code = NewString(""); interface_class_code = NewString("");
String *interface_name = Getattr(n, "interface:name");
String *output_directory = outputDirectory(nspace); String *output_directory = outputDirectory(nspace);
String *filen = NewStringf("%s%s.java", output_directory, interface_name); String *filen = NewStringf("%s%s.java", output_directory, interface_name);
f_interface = NewFile(filen, "w", SWIG_output_files()); f_interface = NewFile(filen, "w", SWIG_output_files());

View file

@ -3118,6 +3118,31 @@ int Language::addSymbol(const String *s, const Node *n, const_String_or_char_ptr
return 1; return 1;
} }
/* -----------------------------------------------------------------------------
* Language::addInterfaceSymbol()
*
* Adds a symbol entry into the target language symbol tables - for the interface
* feature only.
* Returns 1 if the symbol is added successfully.
* The scope is as per addSymbol.
* ----------------------------------------------------------------------------- */
int Language::addInterfaceSymbol(const String *interface_name, Node *n, const_String_or_char_ptr scope) {
if (interface_name) {
Node *existing_symbol = symbolLookup(interface_name, scope);
if (existing_symbol) {
String *proxy_class_name = Getattr(n, "sym:name");
Swig_error(input_file, line_number, "The interface feature name '%s' for proxy class '%s' is already defined in the generated target language module in scope '%s'.\n",
interface_name, proxy_class_name, scope);
Swig_error(Getfile(existing_symbol), Getline(existing_symbol), "Previous declaration of '%s'\n", interface_name);
return 0;
}
if (!addSymbol(interface_name, n, scope))
return 0;
}
return 1;
}
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Language::symbolAddScope() * Language::symbolAddScope()
* *
@ -3214,7 +3239,7 @@ void Language::dumpSymbols() {
* Language::symbolLookup() * Language::symbolLookup()
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
Node *Language::symbolLookup(String *s, const_String_or_char_ptr scope) { Node *Language::symbolLookup(const String *s, const_String_or_char_ptr scope) {
Hash *symbols = Getattr(symtabs, scope ? scope : ""); Hash *symbols = Getattr(symtabs, scope ? scope : "");
if (!symbols) { if (!symbols) {
return NULL; return NULL;

View file

@ -208,8 +208,9 @@ public:
/* Miscellaneous */ /* Miscellaneous */
virtual int validIdentifier(String *s); /* valid identifier? */ virtual int validIdentifier(String *s); /* valid identifier? */
virtual int addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope = ""); /* Add symbol */ virtual int addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope = ""); /* Add symbol */
virtual int addInterfaceSymbol(const String *interface_name, Node *n, const_String_or_char_ptr scope = "");
virtual void dumpSymbols(); virtual void dumpSymbols();
virtual Node *symbolLookup(String *s, const_String_or_char_ptr scope = ""); /* Symbol lookup */ virtual Node *symbolLookup(const String *s, const_String_or_char_ptr scope = ""); /* Symbol lookup */
virtual Hash* symbolAddScope(const_String_or_char_ptr scope); virtual Hash* symbolAddScope(const_String_or_char_ptr scope);
virtual Hash* symbolScopeLookup(const_String_or_char_ptr scope); virtual Hash* symbolScopeLookup(const_String_or_char_ptr scope);
virtual Hash* symbolScopePseudoSymbolLookup(const_String_or_char_ptr scope); virtual Hash* symbolScopePseudoSymbolLookup(const_String_or_char_ptr scope);