Skip to content

Commit

Permalink
* Fix Parser observing Info.virtualize for non-virtual functions…
Browse files Browse the repository at this point in the history
… (pull #658)
  • Loading branch information
HGuillemet committed Mar 21, 2023
1 parent 7a72aac commit ea4e5f7
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 29 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

* Fix `Parser` observing `Info.virtualize` for non-virtual functions ([pull #658](https://github.com/bytedeco/javacpp/pull/658))
* Use regex in `Parser` to match more robustly templates and namespaces ([pull #657](https://github.com/bytedeco/javacpp/pull/657))
* Fix `Builder` default output path for class names with the same length ([pull #654](https://github.com/bytedeco/javacpp/pull/654))
* Add `Info.friendly` to have `Parser` map some `friend` functions to Java methods ([pull #649](https://github.com/bytedeco/javacpp/pull/649))
Expand Down
71 changes: 42 additions & 29 deletions src/main/java/org/bytedeco/javacpp/tools/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -2355,6 +2355,10 @@ boolean function(Context context, DeclarationList declList) throws ParserExcepti
}
}

type = functionAfter(context, decl, dcl, type);
context = new Context(context);
context.virtualize &= type.virtual;

List<Declarator> prevDcl = new ArrayList<Declarator>();
boolean first = true;
for (int n = -2; n < Integer.MAX_VALUE; n++) {
Expand Down Expand Up @@ -2440,32 +2444,8 @@ boolean function(Context context, DeclarationList declList) throws ParserExcepti
}
}

// check for const, other attributes, and pure virtual functions, ignoring the body if present
for (Token token = tokens.get(); !token.match(Token.EOF); token = tokens.get()) {
if (token.match(Token.CONST, Token.__CONST, Token.CONSTEXPR)) {
decl.constMember = true;
token = tokens.next();
} else if (token.match(Token.OVERRIDE)) {
type.virtual = true;
// token = tokens.next();
// let through for user defined annotations
}
if (token.match('&', "&&")) {
// ignore?
token = tokens.next();
}
Attribute attr = attribute();
if (attr != null && attr.annotation) {
dcl.type.annotations += attr.javaName;
} else if (attr == null) {
break;
}
}
if (tokens.get().match("->")) {
// auto type
tokens.next();
type = type(context);
}
type = functionAfter(context, decl, dcl, type);

if (tokens.get().match('{')) {
body();
} else {
Expand Down Expand Up @@ -2527,7 +2507,7 @@ boolean function(Context context, DeclarationList declList) throws ParserExcepti
}

// add @Const annotation only for const virtual functions
if (decl.constMember && type.virtual && context.virtualize) {
if (decl.constMember && context.virtualize) {
if (type.annotations.contains("@Const")) {
type.annotations = incorporateConstAnnotation(type.annotations, 2, true);
} else {
Expand All @@ -2536,7 +2516,7 @@ boolean function(Context context, DeclarationList declList) throws ParserExcepti
}

// add @Virtual annotation on user request only, inherited through context
if (type.virtual && context.virtualize) {
if (context.virtualize) {
modifiers = "@Virtual" + (decl.abstractMember ? "(true) " : " ")
+ (context.inaccessible ? "protected native " : "public native ");
}
Expand Down Expand Up @@ -2591,7 +2571,7 @@ boolean function(Context context, DeclarationList declList) throws ParserExcepti
first = false;
if (extraDecl != null) declList.add(extraDecl);
}
if (type.virtual && context.virtualize) {
if (context.virtualize) {
// Prevent creation of overloads, that are not supported by the generated C++ proxy class.
break;
}
Expand All @@ -2604,6 +2584,39 @@ boolean function(Context context, DeclarationList declList) throws ParserExcepti
return true;
}

/** Parse function declaration or definition after parameters:
* const, attributes, trailing type, pure virtual functions.
* Updates dcl, decl and/or type accordingly. */
Type functionAfter(Context context, Declaration decl, Declarator dcl, Type type) throws ParserException {
// check for const, other attributes, and pure virtual functions, ignoring the body if present
for (Token token = tokens.get(); !token.match(Token.EOF); token = tokens.get()) {
if (token.match(Token.CONST, Token.__CONST, Token.CONSTEXPR)) {
decl.constMember = true;
token = tokens.next();
} else if (token.match(Token.OVERRIDE)) {
type.virtual = true;
// token = tokens.next();
// let through for user defined annotations
}
if (token.match('&', "&&") || token.match(Token.VOLATILE)) {
// ignore?
token = tokens.next();
}
Attribute attr = attribute();
if (attr != null && attr.annotation) {
dcl.type.annotations += attr.javaName;
} else if (attr == null) {
break;
}
}
if (tokens.get().match("->")) {
// auto type
tokens.next();
type = type(context);
}
return type;
}

boolean variable(Context context, DeclarationList declList) throws ParserException {
int backIndex = tokens.index;
String spacing = tokens.get().spacing;
Expand Down

0 comments on commit ea4e5f7

Please sign in to comment.