From 82f2dd2a393620236683e8759ef7cf3c0191c057 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Guillemet?= Date: Tue, 2 Jan 2024 10:14:08 +0100 Subject: [PATCH 01/13] Untemplate class name before adding them to infoMap --- src/main/java/org/bytedeco/javacpp/tools/Parser.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/bytedeco/javacpp/tools/Parser.java b/src/main/java/org/bytedeco/javacpp/tools/Parser.java index 05d669bf..f4dfe088 100644 --- a/src/main/java/org/bytedeco/javacpp/tools/Parser.java +++ b/src/main/java/org/bytedeco/javacpp/tools/Parser.java @@ -3657,7 +3657,10 @@ boolean group(Context context, DeclarationList declList) throws ParserException if (type.javaName.length() > 0 && context.javaName != null) { type.javaName = context.javaName + "." + type.javaName; } - infoMap.put(info = new Info(type.cppName).pointerTypes(type.javaName)); + // Adding this info allows proper ns resolution for next declarations, but + // we don't want it to trigger template instantiation, so we untemplate the + // name first. + infoMap.put(info = new Info(Templates.strip(type.cppName)).pointerTypes(type.javaName)); } /* Propagate the need for downcasting from base classes */ From 13eda5d19c6cc75d8b4884c6d0f01bb0fe49fa0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Guillemet?= Date: Tue, 2 Jan 2024 20:24:04 +0100 Subject: [PATCH 02/13] Fix template instance friend functions --- .../org/bytedeco/javacpp/tools/Parser.java | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/bytedeco/javacpp/tools/Parser.java b/src/main/java/org/bytedeco/javacpp/tools/Parser.java index f4dfe088..5fc1d21b 100644 --- a/src/main/java/org/bytedeco/javacpp/tools/Parser.java +++ b/src/main/java/org/bytedeco/javacpp/tools/Parser.java @@ -1381,18 +1381,14 @@ Declarator declarator(Context context, String defaultName, int infoNumber, boole } } else if (token.match('<')) { // template arguments - dcl.cppName += token; - int count2 = 0; - for (token = tokens.next(); !token.match(Token.EOF); token = tokens.next()) { - dcl.cppName += token; - if (count2 == 0 && token.match('>')) { - break; - } else if (token.match('<')) { - count2++; - } else if (token.match('>')) { - count2--; - } - } + Type[] types = templateArguments(context); + dcl.cppName += "<"; + for (int i = 0; i 0) dcl.cppName += ","; + dcl.cppName += types[i].cppName; + } + if (dcl.cppName.endsWith(">")) dcl.cppName += " "; + dcl.cppName += ">"; } else if (token.match(Token.IDENTIFIER) && (dcl.cppName.length() == 0 || dcl.cppName.endsWith("::"))) { dcl.cppName += token; @@ -1640,7 +1636,7 @@ Declarator declarator(Context context, String defaultName, int infoNumber, boole // pick the Java name from the InfoMap if appropriate String originalName = fieldPointer ? groupInfo.pointerTypes[0] : dcl.javaName; if (attr == null && defaultName == null && info != null && info.javaNames != null && info.javaNames.length > 0 - && (dcl.operator || Templates.notExists(info.cppNames[0]) || (context.templateMap != null && context.templateMap.type == null))) { + && (dcl.operator || Templates.notExists(info.cppNames[0]) || dcl.cppName.equals(info.cppNames[0]))) { dcl.javaName = info.javaNames[0]; } @@ -1813,6 +1809,12 @@ Declarator declarator(Context context, String defaultName, int infoNumber, boole localName = dcl.cppName.substring(context.namespace.length() + 2); } String simpleName = Templates.strip(localName); + if (dcl.type.friend) { + /* Friend functions are called with ADL, but ADL is not performed when a function is called + with explicit template arguments. So we remove template arguments from @Name and bet that + the compiler will be able to locate the proper instance. */ + localName = simpleName; + } if (!localName.equals(dcl.javaName) && (!simpleName.contains("::") || context.javaName == null)) { type.annotations += "@Name(\"" + localName + "\") "; } From 09e2ba2d60621df85a925ff6516be2beee8a2e34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Guillemet?= Date: Thu, 4 Jan 2024 09:40:23 +0100 Subject: [PATCH 03/13] Check argument count when instantiating templates --- src/main/java/org/bytedeco/javacpp/tools/Parser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/bytedeco/javacpp/tools/Parser.java b/src/main/java/org/bytedeco/javacpp/tools/Parser.java index 5fc1d21b..d4195a6c 100644 --- a/src/main/java/org/bytedeco/javacpp/tools/Parser.java +++ b/src/main/java/org/bytedeco/javacpp/tools/Parser.java @@ -4436,7 +4436,7 @@ void declarations(Context context, DeclarationList declList) throws ParserExcept continue; } Type type = new Parser(this, info.cppNames[0]).type(context); - if (type.arguments == null) { + if (type.arguments == null || type.arguments.length > map.size()) { continue; } int count = 0; From 69dc9e0bb5d9d43ff4837fde89a95f3ce2877d41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Guillemet?= Date: Thu, 4 Jan 2024 11:37:01 +0100 Subject: [PATCH 04/13] Prevent automatic instantiation of full template specializations --- src/main/java/org/bytedeco/javacpp/tools/TemplateMap.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/bytedeco/javacpp/tools/TemplateMap.java b/src/main/java/org/bytedeco/javacpp/tools/TemplateMap.java index 825cb5c7..32456b1f 100644 --- a/src/main/java/org/bytedeco/javacpp/tools/TemplateMap.java +++ b/src/main/java/org/bytedeco/javacpp/tools/TemplateMap.java @@ -48,7 +48,7 @@ boolean empty() { return false; } } - return !isEmpty(); + return true; } boolean full() { From 67071649145e40bc8e90e1dc1345fff1570b566f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Guillemet?= Date: Fri, 5 Jan 2024 19:22:22 +0100 Subject: [PATCH 05/13] Use Info.define to force template instanciation when javaText is not null --- .../bytedeco/javacpp/tools/DeclarationList.java | 2 ++ .../java/org/bytedeco/javacpp/tools/Parser.java | 16 ++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/bytedeco/javacpp/tools/DeclarationList.java b/src/main/java/org/bytedeco/javacpp/tools/DeclarationList.java index 7fe7ca6c..16741f58 100644 --- a/src/main/java/org/bytedeco/javacpp/tools/DeclarationList.java +++ b/src/main/java/org/bytedeco/javacpp/tools/DeclarationList.java @@ -67,6 +67,8 @@ public boolean add(Declaration decl, String fullName) { if (templateMap != null && templateMap.empty() && !decl.custom && (decl.type != null || decl.declarator != null)) { // method templates cannot be declared in Java, but make sure to make their // info available on request (when Info.javaNames or Info.define is set) to be able to create instances + // decl.custom is true when info has a javaText and define is false. This allows to apply a javaText + // to a template without instantiating it. define forces instantiation. if (infoIterator == null) { Type type = templateMap.type = decl.type; Declarator dcl = templateMap.declarator = decl.declarator; diff --git a/src/main/java/org/bytedeco/javacpp/tools/Parser.java b/src/main/java/org/bytedeco/javacpp/tools/Parser.java index d4195a6c..cbc8a3a8 100644 --- a/src/main/java/org/bytedeco/javacpp/tools/Parser.java +++ b/src/main/java/org/bytedeco/javacpp/tools/Parser.java @@ -1777,7 +1777,7 @@ Declarator declarator(Context context, String defaultName, int infoNumber, boole if (info != null && info.javaText != null) { definition.signature = definition.text = info.javaText; definition.declarator = null; - definition.custom = true; + definition.custom = !info.define; } if (info == null || !info.skip) { dcl.definition = definition; @@ -2749,7 +2749,7 @@ boolean function(Context context, DeclarationList declList) throws ParserExcepti if (info != null && info.javaText != null) { if (first) { decl.signature = decl.text = info.javaText; - decl.custom = true; + decl.custom = !info.define; } else { break; } @@ -2992,7 +2992,7 @@ boolean variable(Context context, DeclarationList declList) throws ParserExcepti if (info != null && info.javaText != null) { decl.signature = decl.text = info.javaText; decl.declarator = null; - decl.custom = true; + decl.custom = !info.define; } int count = 0; for (Token token = tokens.get(); !token.match(Token.EOF); token = tokens.next()) { @@ -3232,7 +3232,7 @@ boolean macro(Context context, DeclarationList declList) throws ParserException } if (info != null && info.javaText != null) { decl.signature = decl.text = info.javaText; - decl.custom = true; + decl.custom = !info.define; break; } } @@ -3392,7 +3392,7 @@ boolean typedef(Context context, DeclarationList declList) throws ParserExceptio if (info != null && info.javaText != null) { decl.signature = decl.text = info.javaText; - decl.custom = true; + decl.custom = !info.define; } String comment = commentAfter(); decl.text = comment + decl.text; @@ -3431,7 +3431,7 @@ boolean using(Context context, DeclarationList declList) throws ParserException // inherit constructors decl.signature = decl.text = info.javaText; decl.declarator = dcl; - decl.custom = true; + decl.custom = !info.define; } String comment = commentAfter(); decl.text = comment + decl.text; @@ -3981,7 +3981,7 @@ boolean group(Context context, DeclarationList declList) throws ParserException } int end = text.lastIndexOf('}'); decl.text += text.substring(start, end).replace(base2.javaName, type.javaName); - decl.custom = true; + decl.custom = !info.define; } } if (polymorphic) { @@ -4019,7 +4019,7 @@ boolean group(Context context, DeclarationList declList) throws ParserException decl.type = type; if (info != null && info.javaText != null) { decl.signature = decl.text = info.javaText; - decl.custom = true; + decl.custom = !info.define; } else if (info != null && info.flatten) { info.javaText = decl.text; } From ca923d712ba4f8033d5baa14b2705221714fde7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Guillemet?= Date: Fri, 5 Jan 2024 19:24:39 +0100 Subject: [PATCH 06/13] Prevent double annotations of templated functions --- src/main/java/org/bytedeco/javacpp/tools/Parser.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/bytedeco/javacpp/tools/Parser.java b/src/main/java/org/bytedeco/javacpp/tools/Parser.java index cbc8a3a8..93f8500a 100644 --- a/src/main/java/org/bytedeco/javacpp/tools/Parser.java +++ b/src/main/java/org/bytedeco/javacpp/tools/Parser.java @@ -2701,10 +2701,12 @@ boolean function(Context context, DeclarationList declList) throws ParserExcepti if (context.namespace != null && context.javaName == null) { decl.text += "@Namespace(\"" + context.namespace + "\") "; } - // append annotations specified for a full function declaration only to avoid overlap with type.annotations + // append annotations specified for a full function declaration only, to avoid overlap with type.annotations if (fullInfo != null && fullInfo.annotations != null) { for (String s : fullInfo.annotations) { - type.annotations += s + " "; + if (!type.annotations.contains(s)) { // We can still have overlap since fullinfo are created dynamically from partial info + type.annotations += s + " "; + } } } if (type.constructor && params != null) { From bd0ed7ad8a7593f263827577f8941c0fe434da42 Mon Sep 17 00:00:00 2001 From: Samuel Audet Date: Sat, 6 Jan 2024 10:58:27 +0900 Subject: [PATCH 07/13] Update CHANGELOG.md and fix nits --- CHANGELOG.md | 1 + src/main/java/org/bytedeco/javacpp/tools/Parser.java | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf8c0e6c..071b30f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ + * Fix `Parser` handling of `template` specialization and their `friend` declarations ([pull #733](https://github.com/bytedeco/javacpp/pull/733)) * Improve `Parser` capabilities for `operator` and function templates ([pull #732](https://github.com/bytedeco/javacpp/pull/732)) * Fix `Parser` failing on nested initializer lists and on attributes found inside `enum` declarations * Fix `Parser` for basic containers like `std::optional >` ([issue #718](https://github.com/bytedeco/javacpp/issues/718)) diff --git a/src/main/java/org/bytedeco/javacpp/tools/Parser.java b/src/main/java/org/bytedeco/javacpp/tools/Parser.java index 93f8500a..d86f0816 100644 --- a/src/main/java/org/bytedeco/javacpp/tools/Parser.java +++ b/src/main/java/org/bytedeco/javacpp/tools/Parser.java @@ -1383,11 +1383,15 @@ Declarator declarator(Context context, String defaultName, int infoNumber, boole // template arguments Type[] types = templateArguments(context); dcl.cppName += "<"; - for (int i = 0; i 0) dcl.cppName += ","; + for (int i = 0; i < types.length; i++) { + if (i > 0) { + dcl.cppName += ","; + } dcl.cppName += types[i].cppName; } - if (dcl.cppName.endsWith(">")) dcl.cppName += " "; + if (dcl.cppName.endsWith(">")) { + dcl.cppName += " "; + } dcl.cppName += ">"; } else if (token.match(Token.IDENTIFIER) && (dcl.cppName.length() == 0 || dcl.cppName.endsWith("::"))) { @@ -1636,7 +1640,7 @@ Declarator declarator(Context context, String defaultName, int infoNumber, boole // pick the Java name from the InfoMap if appropriate String originalName = fieldPointer ? groupInfo.pointerTypes[0] : dcl.javaName; if (attr == null && defaultName == null && info != null && info.javaNames != null && info.javaNames.length > 0 - && (dcl.operator || Templates.notExists(info.cppNames[0]) || dcl.cppName.equals(info.cppNames[0]))) { + && (dcl.operator || Templates.notExists(info.cppNames[0]) || dcl.cppName.equals(info.cppNames[0]))) { dcl.javaName = info.javaNames[0]; } From d0bcdccac3c11e7a36b208215338c593a802f512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Guillemet?= Date: Sun, 7 Jan 2024 13:29:36 +0100 Subject: [PATCH 08/13] Fix doubled template args in function infoMap query --- .../java/org/bytedeco/javacpp/tools/Parser.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/bytedeco/javacpp/tools/Parser.java b/src/main/java/org/bytedeco/javacpp/tools/Parser.java index 93f8500a..2194023d 100644 --- a/src/main/java/org/bytedeco/javacpp/tools/Parser.java +++ b/src/main/java/org/bytedeco/javacpp/tools/Parser.java @@ -2377,7 +2377,10 @@ boolean function(Context context, DeclarationList declList) throws ParserExcepti } Info info = null, fullInfo = null; String templateArgs = declList.templateMap != null ? declList.templateMap.toString() : ""; - String fullname = dcl.cppName + templateArgs; + String fullname = dcl.cppName; + if (!fullname.endsWith(">")) { + fullname += templateArgs; + } String param1 = "", param2 = ""; if (dcl.parameters != null) { param1 = "("; @@ -2417,8 +2420,12 @@ boolean function(Context context, DeclarationList declList) throws ParserExcepti fullname += param1; info = fullInfo = infoMap.getFirst(fullname, false); if (info == null) { - info = infoMap.getFirst(dcl.cppName + templateArgs + param2, false); - if (info == null && !templateArgs.isEmpty()) { + String cppName = dcl.cppName; + if (!cppName.endsWith(">")) { + cppName += templateArgs; + } + info = infoMap.getFirst(cppName + param2, false); + if (info == null && !cppName.equals(dcl.cppName)) { info = infoMap.getFirst(dcl.cppName + param1, false); if (info == null) { info = infoMap.getFirst(dcl.cppName + param2, false); @@ -2442,7 +2449,7 @@ boolean function(Context context, DeclarationList declList) throws ParserExcepti // For constructor, we'd better not make this lookup, because of confusion // with the class info. Kept for now for backwards compatibility. if (info == null) { - info = infoMap.getFirst(dcl.cppName + templateArgs); + info = infoMap.getFirst(dcl.cppName + (dcl.cppName.endsWith(">") ? "" : templateArgs)); } if (!type.constructor && !type.destructor && !type.operator && (context.templateMap == null || context.templateMap.full())) { infoMap.put(info != null ? new Info(info).cppNames(fullname).javaNames(null) : new Info(fullname)); From cf0b6ffb23f2be38e6ed32e2413ab14a43692efa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Guillemet?= Date: Sun, 7 Jan 2024 13:32:49 +0100 Subject: [PATCH 09/13] Fix tracking of virtual inheritance for downcasting --- .../org/bytedeco/javacpp/tools/Parser.java | 61 +++++++++++++------ 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/bytedeco/javacpp/tools/Parser.java b/src/main/java/org/bytedeco/javacpp/tools/Parser.java index 2194023d..b07c694d 100644 --- a/src/main/java/org/bytedeco/javacpp/tools/Parser.java +++ b/src/main/java/org/bytedeco/javacpp/tools/Parser.java @@ -98,17 +98,40 @@ public Parser(Logger logger, Properties properties, String encoding, String line String lineSeparator = null; /** Java names of classes needing upcast from their subclasses. */ Set upcasts = new HashSet<>(); - /** Classes that have a base class appearing as key in this map need a downcast constructor. The associated value gives the class to downcast from. */ - Map> downcasts = new HashMap<>(); + + static private class Inheritance { + Type base; + boolean virtual; + + public Inheritance(Type b, boolean v) { + base = b; + virtual = v; + } + + @Override + public boolean equals(Object o) { + Inheritance i = (Inheritance) o; + return i != null && i.base.equals(base) && i.virtual == virtual; + } + + @Override + public int hashCode() { + return base.hashCode() + (virtual ? 1 : 0); + } + } + + /** Classes that have a base class appearing as a key in this map need a downcast constructor. + * The associated value gives the class to downcast from and whether the inheritance is virtual. */ + Map> downcasts = new HashMap<>(); /** Java names of classes recognized as polymorphic. */ Set polymorphicClasses = new HashSet<>(); - private void addDowncast(String base, Type from) { - Set types = downcasts.get(base); - if (types == null) { - downcasts.put(base, types = new HashSet<>(1)); + private void addDowncast(String base, Type from, boolean virtual) { + Set inh = downcasts.get(base); + if (inh == null) { + downcasts.put(base, inh = new HashSet<>(1)); } - types.add(from); + inh.add(new Inheritance(from, virtual)); } static String removeAnnotations(String s) { @@ -3450,9 +3473,9 @@ boolean using(Context context, DeclarationList declList) throws ParserException return true; } - String downcast(Type derived, Type base) { + String downcast(Type derived, Type base, boolean virtual) { final String downcastType; - if (base.virtual) { + if (virtual) { if (polymorphicClasses.contains(base.javaName)) { downcastType = "dynamic"; } else { @@ -3676,10 +3699,10 @@ boolean group(Context context, DeclarationList declList) throws ParserException /* Propagate the need for downcasting from base classes */ for (Type t : baseClasses) { - Set froms = downcasts.get(t.cppName); + Set froms = downcasts.get(t.cppName); if (froms != null) { - for (Type from : froms) { - addDowncast(type.cppName, from); + for (Inheritance from : froms) { + addDowncast(type.cppName, from.base, t.virtual || from.virtual); } } } @@ -3713,7 +3736,7 @@ boolean group(Context context, DeclarationList declList) throws ParserException Info baseInfo = infoMap.getFirst(t.cppName); if (!t.javaName.equals("Pointer") && (baseInfo == null || !baseInfo.skip)) { casts += upcast(type, t, false); - addDowncast(t.cppName, t); + addDowncast(t.cppName, t, false); } } } @@ -3724,11 +3747,11 @@ boolean group(Context context, DeclarationList declList) throws ParserException if (upcasts.contains(base.javaName)) { // Base classes explicitly set as needing upcast in infoMap casts += upcast(type, base, true); - addDowncast(base.cppName, base); + addDowncast(base.cppName, base, false); } else if (polymorphicClasses.contains(base.javaName) && base.virtual) { // In this case we know we need upcast casts += upcast(type, base, false); - addDowncast(base.cppName, base); + addDowncast(base.cppName, base, false); } decl.signature = type.javaName; @@ -3954,17 +3977,17 @@ boolean group(Context context, DeclarationList declList) throws ParserException } } - Set froms = downcasts.get(base.cppName); - for (Type t : froms != null ? froms : new HashSet()) { + Set froms = downcasts.get(base.cppName); + for (Inheritance i : froms != null ? froms : new HashSet()) { boolean found = false; for (Declaration d : declList2) { - if ((shortName + "_" + t.javaName).equals(d.signature)) { + if ((shortName + "_" + i.base.javaName).equals(d.signature)) { found = true; break; } } if (!found) { - constructors += downcast(type, t); + constructors += downcast(type, i.base, i.virtual || base.virtual); } } From 80083453997c4df3ca6acdb3b0da8de5e4bca758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Guillemet?= Date: Mon, 8 Jan 2024 10:30:44 +0100 Subject: [PATCH 10/13] Remove class Inheritance --- .../org/bytedeco/javacpp/tools/Parser.java | 60 +++++++------------ 1 file changed, 21 insertions(+), 39 deletions(-) diff --git a/src/main/java/org/bytedeco/javacpp/tools/Parser.java b/src/main/java/org/bytedeco/javacpp/tools/Parser.java index ac0302e1..fc986258 100644 --- a/src/main/java/org/bytedeco/javacpp/tools/Parser.java +++ b/src/main/java/org/bytedeco/javacpp/tools/Parser.java @@ -99,39 +99,19 @@ public Parser(Logger logger, Properties properties, String encoding, String line /** Java names of classes needing upcast from their subclasses. */ Set upcasts = new HashSet<>(); - static private class Inheritance { - Type base; - boolean virtual; - - public Inheritance(Type b, boolean v) { - base = b; - virtual = v; - } - - @Override - public boolean equals(Object o) { - Inheritance i = (Inheritance) o; - return i != null && i.base.equals(base) && i.virtual == virtual; - } - - @Override - public int hashCode() { - return base.hashCode() + (virtual ? 1 : 0); - } - } - /** Classes that have a base class appearing as a key in this map need a downcast constructor. * The associated value gives the class to downcast from and whether the inheritance is virtual. */ - Map> downcasts = new HashMap<>(); + Map> downcasts = new HashMap<>(); + /** Java names of classes recognized as polymorphic. */ Set polymorphicClasses = new HashSet<>(); private void addDowncast(String base, Type from, boolean virtual) { - Set inh = downcasts.get(base); - if (inh == null) { - downcasts.put(base, inh = new HashSet<>(1)); + Map inheritance = downcasts.get(base); + if (inheritance == null) { + downcasts.put(base, inheritance = new HashMap<>(1)); } - inh.add(new Inheritance(from, virtual)); + inheritance.put(from, virtual); } static String removeAnnotations(String s) { @@ -3703,10 +3683,10 @@ boolean group(Context context, DeclarationList declList) throws ParserException /* Propagate the need for downcasting from base classes */ for (Type t : baseClasses) { - Set froms = downcasts.get(t.cppName); + Map froms = downcasts.get(t.cppName); if (froms != null) { - for (Inheritance from : froms) { - addDowncast(type.cppName, from.base, t.virtual || from.virtual); + for (Map.Entry from: froms.entrySet()) { + addDowncast(type.cppName, from.getKey(), t.virtual || from.getValue()); } } } @@ -3981,17 +3961,19 @@ boolean group(Context context, DeclarationList declList) throws ParserException } } - Set froms = downcasts.get(base.cppName); - for (Inheritance i : froms != null ? froms : new HashSet()) { - boolean found = false; - for (Declaration d : declList2) { - if ((shortName + "_" + i.base.javaName).equals(d.signature)) { - found = true; - break; + Map froms = downcasts.get(base.cppName); + if (froms != null) { + for (Map.Entry i : froms.entrySet()) { + boolean found = false; + for (Declaration d : declList2) { + if ((shortName + "_" + i.getKey().javaName).equals(d.signature)) { + found = true; + break; + } + } + if (!found) { + constructors += downcast(type, i.getKey(), i.getValue() || base.virtual); } - } - if (!found) { - constructors += downcast(type, i.base, i.virtual || base.virtual); } } From 84cfdc8e8784546455172b3466d56e78fcc0b12f Mon Sep 17 00:00:00 2001 From: Samuel Audet Date: Mon, 8 Jan 2024 22:25:31 +0900 Subject: [PATCH 11/13] Fix javadoc --- src/main/java/org/bytedeco/javacpp/tools/Parser.java | 2 +- src/main/java/org/bytedeco/javacpp/tools/Templates.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/bytedeco/javacpp/tools/Parser.java b/src/main/java/org/bytedeco/javacpp/tools/Parser.java index fc986258..1b3446fe 100644 --- a/src/main/java/org/bytedeco/javacpp/tools/Parser.java +++ b/src/main/java/org/bytedeco/javacpp/tools/Parser.java @@ -767,7 +767,7 @@ Type[] templateArguments(Context context) throws ParserException { /** * Read and return the operator following an operator keyword: - * any of new, delete, + - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= <=>(since C++20) && || ++ -- , ->* -> ( ) [ ] + * any of {@code new, delete, + - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= <=>(since C++20) && || ++ -- , ->* -> ( ) [ ]} * taking care of template arguments, if any. */ private String operator(Context context) throws ParserException { diff --git a/src/main/java/org/bytedeco/javacpp/tools/Templates.java b/src/main/java/org/bytedeco/javacpp/tools/Templates.java index ee5e1c97..8f754cd8 100644 --- a/src/main/java/org/bytedeco/javacpp/tools/Templates.java +++ b/src/main/java/org/bytedeco/javacpp/tools/Templates.java @@ -32,7 +32,7 @@ class Templates { static final Pattern templatePattern = Pattern.compile("<[^<>=]*>"); - /** Remove template arguments from s, taking care of nested templates, default arguments (xxx<>), operator <=>, ->, etc... */ + /** Remove template arguments from s, taking care of nested templates, default arguments {@code (xxx<>), operator <=>, ->}, etc */ static String strip(String s) { Matcher m; do { From 2e1f5c9985b3fc450a05e651fd2f956cabff135c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Guillemet?= Date: Tue, 9 Jan 2024 00:45:26 +0100 Subject: [PATCH 12/13] Support `<>` in templateArguments --- src/main/java/org/bytedeco/javacpp/tools/Parser.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/org/bytedeco/javacpp/tools/Parser.java b/src/main/java/org/bytedeco/javacpp/tools/Parser.java index fc986258..38f1a605 100644 --- a/src/main/java/org/bytedeco/javacpp/tools/Parser.java +++ b/src/main/java/org/bytedeco/javacpp/tools/Parser.java @@ -688,6 +688,9 @@ Type[] templateArguments(Context context) throws ParserException { } List arguments = new ArrayList<>(); for (Token token = tokens.next(); !token.match(Token.EOF); token = tokens.next()) { + if (token.match('>')) { + break; + } Type type = type(context); arguments.add(type); token = tokens.get(); From 108b9f3af5b1aa641873926d15436842ccd55785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Guillemet?= Date: Tue, 9 Jan 2024 00:49:51 +0100 Subject: [PATCH 13/13] Prevent Context.qualify to add template arguments if some are already present --- .../org/bytedeco/javacpp/tools/Context.java | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/bytedeco/javacpp/tools/Context.java b/src/main/java/org/bytedeco/javacpp/tools/Context.java index 2e46c2ce..ce09fa44 100644 --- a/src/main/java/org/bytedeco/javacpp/tools/Context.java +++ b/src/main/java/org/bytedeco/javacpp/tools/Context.java @@ -99,24 +99,26 @@ String[] qualify(String cppName, String parameters) { name = name.substring(0, name.length() - parameters.length()); } TemplateMap map = templateMap; - while (map != null) { - String name2 = map.getName(); - if (parameters != null && name2 != null && name2.endsWith(parameters)) { - name2 = name2.substring(0, name2.length() - parameters.length()); - } - if (name.equals(name2)) { - String args = "<", separator = ""; - for (Type t : map.values()) { - // assume that missing arguments have default values - if (t != null) { - args += separator + t.cppName; - separator = ","; + if (!name.endsWith(">")) { + while (map != null) { + String name2 = map.getName(); + if (parameters != null && name2 != null && name2.endsWith(parameters)) { + name2 = name2.substring(0, name2.length() - parameters.length()); + } + if (name.equals(name2)) { + String args = "<", separator = ""; + for (Type t : map.values()) { + // assume that missing arguments have default values + if (t != null) { + args += separator + t.cppName; + separator = ","; + } } + names.add(name + args + (args.endsWith(">") ? " >" : ">") + (parameters != null ? parameters : "")); + break; } - names.add(name + args + (args.endsWith(">") ? " >" : ">") + (parameters != null ? parameters : "")); - break; + map = map.parent; } - map = map.parent; } names.add(name);