-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Java8] Replace ConstantPoolTypeIntrospector #1178
Conversation
48dfb8b
to
43635cb
Compare
<dependency> | ||
<groupId>io.cucumber</groupId> | ||
<artifactId>gherkin</artifactId> | ||
<scope>provided</scope> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both are transitive dependencies through cucumber-core.
this.classFinder = classFinder; | ||
methodScanner = new MethodScanner(classFinder); | ||
this.objectFactory = objectFactory; | ||
this.methodScanner = new MethodScanner(classFinder); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rewrote the constructors to be idiomatic java.
@@ -157,44 +159,30 @@ void addStepDefinition(Annotation annotation, Method method) { | |||
} | |||
} | |||
|
|||
public void addStepDefinition(String regexp, long timeoutMillis, StepdefBody body, TypeIntrospector typeIntrospector) { | |||
try { | |||
glue.addStepDefinition(new Java8StepDefinition(Pattern.compile(regexp), timeoutMillis, body, typeIntrospector)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has moved into the generated code.
} | ||
} | ||
} | ||
|
||
public void addBeforeHookDefinition(String[] tagExpressions, long timeoutMillis, int order, HookBody body) { | ||
glue.addBeforeHook(new Java8HookDefinition(tagExpressions, order, timeoutMillis, body)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has moved into the generated code.
|
||
import static org.junit.Assert.assertEquals; | ||
|
||
public class AnonInnerClassStepdefs implements GlueBase { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved to cucumber.runtime.java8.test.AnonInnerClassStepdefs
} | ||
|
||
default void ${java.text.Normalizer.normalize(kw.replaceAll("[\\s',!]", ""), java.text.Normalizer.Form.NFC)}(final String regexp, final long timeoutMillis, final StepdefBody.A0 body) { | ||
JavaBackend.INSTANCE.get().addStepDefinition(regexp, timeoutMillis, body, ConstantPoolTypeIntrospector.INSTANCE); | ||
JavaBackend.INSTANCE.get().addStepDefinition( | ||
new Java8StepDefinition(regexp, timeoutMillis, StepdefBody.A0.class, body) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typetools resolves the arguments of the the generic type (StepdefBody.A{n} ) using the type variable information from body (the implementing class) so we pass these in here.
43635cb
to
cf553b7
Compare
} | ||
|
||
private void methodThatDeclaresException() throws Throwable { | ||
} | ||
private void methodWithAnArgument(Integer cuckes) throws Throwable { | ||
assertEquals(42, cuckes.intValue()); | ||
} | ||
private void methodWithAnIntArgument(int cuckes) throws Throwable { | ||
assertEquals(42, cuckes); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed by using TypeResolver
aba7380
to
1939498
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't find any problem with this design, but I feel a bit to unfamiliar with Java8 typing to really do a proper review of those aspects.
this.objectFactory = objectFactory; | ||
this(objectFactory, | ||
new ResourceLoaderClassFinder( | ||
new MultiLoader( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure all these line breaks improve readability, especially
new MultiLoader(currentThread().getContextClassLoader())
seems to fit better on one line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right. I was missing a constructor JavaBackend(ObjectFactory, ResourceLoader)
. This made look into the root cause, why do we have these constructors in the first place. It turns out they're only used by tests which needed them because they were poorly written.
I've added a commit which improves these test somewhat.
package cucumber.runtime.java; | ||
package cucumber.runtime.java8; | ||
|
||
import static java.util.Arrays.asList; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've found that the most common ordering of import in the code base is static imports after the other imports, so I've added that ordering to the Eclipse configuration I use for Cucumber-JVM, but you seems to have another configuration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been using the default that comes with IDEA. What does Eclipse do by default? I'd prefer a minimal amount of configuration if possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like I have the ability to quickly format the imports of the entire project. We can pick a standard now and adhere to it.
I am interested in your opinion about separating out the java8 bits from With the upcoming CucumberExpressions this might be a problem. CucumberExpressions need the the TypeRegistry to be instantiated. We kinda have to know how we'll solve that problem to solve this problem. |
1939498
to
3dc7047
Compare
I have a solution for the CucumberExpressions in mind. Rather then adding the Java8StepDefintion directly to the backend: JavaBackend.INSTANCE.get().addStepDefinition(
new Java8StepDefinition(regexp, timeoutMillis, StepdefBody.A0.class, body)
); We'd provide a Function<TypeRegistry,StepDefinition> (or the java7 equivalent) that will instantiate one: JavaBackend.INSTANCE.get().addStepDefinition((typeRegistry) ->
new Java8StepDefinition(typeRegistry, regexp, timeoutMillis, StepdefBody.A0.class, body)
); |
To determine which argument types a lambda function requires we created a ConstantPoolTypeIntrospector. However it has never functioned quite correctly (#937, #1140, #957), was prone to breaking (#912, #914) and hasn't been tested much (#1048). It is important to understand that while we will get a properly functioning and tested replacement, TypeResolver uses the same ConstantPool and thus has the same potential to break. However because TypeResolver is used by a much larger audience I expect these problems to be shallow. Because this change the interface of Java8StepDefinition it made sense to refactor all the Java8 related stuff out of cucumber-java. This will make it easier in the future to add things like KotlinStepDefintions without creating a separate KotlinBackend. Related issues: - #912 - #914 - #937 - #957 - #1140 - #1048 - #1140 Closes #937 Closes #1048
The JavaBackend had several test only constructors cluttering up the interface. Mostly due to poor setup in the tests themselves. By improving the test setup we can remove these constructors.
008c653
to
7f50aed
Compare
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Summary
Replace ConstantPoolTypeIntrospector with TypeResolver and refactor all the Java8 related stuff out of cucumber-java.
Motivation and Context
To determine which argument types a lambda function requires we created a ConstantPoolTypeIntrospector. However it has never functioned quite correctly (#937, #1140, #957), was prone to breaking (#912, #914) and hasn't been tested much (#1048).
It is important to understand that while we will get a properly functioning and tested replacement, TypeResolver uses the same ConstantPool and thus has the same potential to break. However because TypeResolver is used by a much larger audience I expect these problems to be shallow.
Because this changes the interface of Java8StepDefinition it made sense to refactor all the Java8 related stuff out of cucumber-java. This will make it easier in the future to add things like KotlinStepDefintions without creating a separate KotlinBackend.
How Has This Been Tested?
Check if the automated tests were still passing.
Types of changes
Checklist: