From f983c1bbb01ec8f5fb08c3248cac9a095b001497 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Mon, 5 Feb 2024 23:04:18 -0800 Subject: [PATCH 1/2] Escape special characters in type arguments. This resolves multiple FIXMEs in the code as well as issue #2179. --- .../generator/c/TypeParameterizedReactor.java | 38 +++++++++++++------ test/C/src/generics/TypeSanitization.lf | 25 ++++++++++++ 2 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 test/C/src/generics/TypeSanitization.lf diff --git a/core/src/main/java/org/lflang/generator/c/TypeParameterizedReactor.java b/core/src/main/java/org/lflang/generator/c/TypeParameterizedReactor.java index 1c5ae863c0..2cfe7f77f7 100644 --- a/core/src/main/java/org/lflang/generator/c/TypeParameterizedReactor.java +++ b/core/src/main/java/org/lflang/generator/c/TypeParameterizedReactor.java @@ -6,7 +6,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.stream.Collectors; import org.eclipse.emf.common.util.URI; import org.lflang.InferredType; import org.lflang.ast.ASTUtils; @@ -101,16 +100,35 @@ private static Map addTypeArgs( /** Return the name of the reactor given its type arguments. */ public String getName() { - // FIXME: Types that are not just a single token need to be escaped or hashed - return reactor.getName() - + typeArgs.values().stream().map(ASTUtils::toOriginalText).collect(Collectors.joining("_")); + return reactor.getName() + argsString(); } /** Return a string representation of the type args of this. */ public String argsString() { - return typeArgs.values().stream() - .map(ASTUtils::toOriginalText) - .collect(Collectors.joining("_")); + var stringRepresentation = new StringBuilder(); + int hash = 0; + var first = false; + for (var key : typeParams) { + if (!first) { + stringRepresentation.append('_'); + } + var value = typeArgs.get(key); + var valueString = ASTUtils.toOriginalText(value); + for (int idx = 0; idx < valueString.length(); idx++) { + var c = valueString.charAt(idx); + if (Character.isLetterOrDigit(c)) { + stringRepresentation.append(c); + } else { + hash = hash * 31 + idx; + hash = hash * 31 + c; + } + } + } + if (hash != 0) { + stringRepresentation.append('_'); + stringRepresentation.append(Integer.toHexString(hash)); + } + return stringRepresentation.toString(); } /** #define type names as concrete types. */ @@ -154,11 +172,7 @@ public InferredType resolveType(InferredType t) { */ public String uniqueName() { var resolved = ASTUtils.toDefinition(reactor); - return "_" - + uniqueName(resolved) - + typeParams.stream() - .map(it -> typeArgs.get(it).getId()) // FIXME: may be more than just an ID - .collect(Collectors.joining("_")); + return "_" + uniqueName(resolved) + argsString(); } @Override diff --git a/test/C/src/generics/TypeSanitization.lf b/test/C/src/generics/TypeSanitization.lf new file mode 100644 index 0000000000..1cc8faabc2 --- /dev/null +++ b/test/C/src/generics/TypeSanitization.lf @@ -0,0 +1,25 @@ +target CCpp + +preamble {= + #include + #include +=} + +reactor TestGeneric { + input test_input: T + + reaction(test_input) {= + if (test_input->is_present) + { + lf_print("Got the test input"); + } + =} +} + +main reactor { + test = new TestGeneric>() + + reaction(startup) -> test.test_input {= + lf_set(test.test_input, std::make_shared(*(new std::string("test")))); + =} +} From 258755a68c94a561b0407603a40f243a8d08c709 Mon Sep 17 00:00:00 2001 From: Peter Donovan Date: Tue, 6 Feb 2024 16:02:32 -0800 Subject: [PATCH 2/2] Move to same category as other CCpp tests. I think this is OK; this test is inherently both a generics test and a CCpp test (because the special characters come from using C++), so it seems fine to put it in either category. But it should be in the target category so that it is not run on Windows. --- test/C/src/{generics => target}/TypeSanitization.lf | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/C/src/{generics => target}/TypeSanitization.lf (100%) diff --git a/test/C/src/generics/TypeSanitization.lf b/test/C/src/target/TypeSanitization.lf similarity index 100% rename from test/C/src/generics/TypeSanitization.lf rename to test/C/src/target/TypeSanitization.lf