groovy simple trait fail - groovy

I am learning groovy now. And in my case some simple code with trait is not working.
Here's code:
trait Mark {
void DisplayMarks() {
println("Display Marks");
}
}
public class MarkOwner implements Mark {
int StudentID
int Marks1;
static void main(String[] args) {
MarkOwner m = new MarkOwner();
m.DisplayMarks();
}
}
And here's error:
msangel#msangel-np6:~/work/groov$ groovy scr2.groovy
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
/home/msangel/work/groov/scr2.groovy: 2: Method definition not expected here. Please define the method at an appropriate place or perhaps try using a block/Closure instead. at line: 2 column: 4. File: /home/msangel/work/groov/scr2.groovy # line 2, column 4.
void DisplayMarks() {
^
1 error
I was also looked to different tutorial but the syntax seems to be correct.
Here s my default groovy version number:
msangel#msangel-np6:~/work/groov$ groovy --version
Groovy Version: 1.8.6 JVM: 1.8.0_91 Vendor: Oracle Corporation OS: Linux

Related

MissingMethodException when using Groovy and JUnit 5 Assertions

Trying to use JUnit 5 class Assertions, specifically assertAll() with Groovy.
Basic Java proves the following syntax:
#Test
public void someTest() {
assertAll('heading',
() -> assertTrue(firstName),
() -> assertTrue(lastName)
);
}
Since I'm stuck to Groovy v2.4, which does not support lambdas, what I do looks like (tried several options, however all of those provide the same error):
#Test
void 'Some test'() {
assertAll('heading',
{ -> assert firstName },
{ -> assert lastName }
)
}
Error message:
groovy.lang.MissingMethodException:
No signature of method: static org.junit.jupiter.api.Assertions.assertAll() is applicable for argument
types: (path.GeneralTests$_Some_test_closure10...)
values: [path.GeneralTests$_Some_test_losure10#1ef13eab, ...]
Looks like the problem is with assertAll() method itself, exception is quite obvious, however that's quite a challenge to get the possible solution, since I had to switch to Groovy from Python just recently.
Indeed, I am going to take some courses with Groovy in future, but you know, you always have to provide results for yesterday.
Would highly appreciate your suggestions!
In this particular case, you need to cast Groovy closure to org.junit.jupiter.api.function.Executable interface explicitly:
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.function.Executable
import static org.junit.jupiter.api.Assertions.*
class Test {
#Test
void 'Some test'() {
assertAll('heading',
{ assertTrue(true) } as Executable,
{ assertFalse(false) } as Executable)
}
}

Compilation customizer is not called during compilation of groovy DSL script

I want to write a groovy DSL with syntax:
returnValue when booleanCondition
I want to use compilation customizers to transform this expression to a typical if return statement using AST transformations.
For this script:
2 when 1 == 1
I get exception message:
MultipleCompilationErrorsException: startup failed:
Script1.groovy: 1: expecting EOF, found '1' # line 1, column 8.
I don't understand why my compilation customizer is not called at all?
I need it to be called before compilation so I can make it into a valid groovy code.
If the script contains valid groovy code, then my compilation customizer is called.
My code:
class MyDslTest {
public static void main(String[] args) {
String script = '''2 when 1 == 1
'''
def compilerConfig = new CompilerConfiguration()
compilerConfig.addCompilationCustomizers(new MyCompilationCustomizer())
GroovyShell groovyShell = new GroovyShell(compilerConfig)
groovyShell.evaluate(script)
}
}
class MyCompilationCustomizer extends CompilationCustomizer {
MyCompilationCustomizer() {
super(CompilePhase.CONVERSION)
}
#Override
void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException {
println 'in compilation customizer'
}
}
The problem is that your code is not syntactically valid. A compilation customizer will not workaround that: to be able to get an AST, on which the customizer will work, you have to produce syntactically correct code. One option is to use a different AntlrParserPlugin, but in general I don't recommend to do it because it will modify the sources before parsing, and therefore create a mismatch between the AST and the actual source.

Compilation error while passing method argument to inline interface implementation

Have a look on the following Groovy code example:
class PersonCreator {
static void main(String[] args) {
println createPerson('Smith')
}
static createPerson(String aLastname) {
new Person() {
final String firstname = 'John'
final String lastname = aLastname
}
}
}
interface Person {
String getFirstname()
String getLastname()
}
When I try to run it exception is thrown
Exception in thread "main" groovy.lang.MissingPropertyException: No such property: aLastname for class: PersonCreator
The exact same code runs fine with Groovy 2.3.2, but with version 2.3.3 and above it fails. Should I raise a bug in Groovy JIRA or is it a feature?
EDIT: for some reason the above example compilation with #CompileStatic added fails with Error:(1, 1) Groovyc: [Static type checking] - Unimplemented node type

How to override method Class<?>.getAt in Groovy

Currently I'm using Groovy 1.8.2 and the following code works for me as expected:
Class.metaClass.getAt = { args ->
println "Called ${delegate}[${args}]"
TypeDefinition.create(delegate, args)
}
I use that in my DSL as shown:
TypeDefinition instance = List[MyOwnClass]
When I moved to Groovy 2.0.5 this functinality failed with "Missing method: static java.util.List.getAt() with parameter some.package.MyOwnClass". So the question is how can I make it work with Groovy 2?
Using a category works with 2.0.5:
class ClassHelperCategory {
static getAt(Class cls, String arg) {
"Called $cls[$arg]"
}
}
Class.metaClass.mixin(ClassHelperCategory)
assert List['hello'] == 'Called interface java.util.List[hello]'

Generic type arguments in derived classes

Groovy seems to be unable to compile a class where I've derived from a Generic base class and overloaded a method returning a generic array. The same example in Java appears to compile correctly, which is surprising as I expected Groovy to have source-level compatibility [ref].
This can be reproduced with the following adapter example. This example can also be executed online at the awesome Groovy Web Console.
class Person {}
​abstract class Base​Adapter<T> {
public T[] getAll() {
return getAllInternal();
}
protected abstract T[] getAllInternal()
}
class PersonAdapter extends BaseAdapter<Person> {
protected Person[] getAllInternal() {
return new Person[0];
}
}​
Compiling this produces the message:
Script1.groovy: 12: The return type of Person[] getAllInternal() in PersonAdapter is incompatible with [Ljava.lang.Object; getAllInternal() in BaseAdapter
. At [12:5] # line 12, column 5.
protected Person[] getAllInternal() {
^
1 error
Have I got the syntax incorrect? Or, is this a Groovy issue?
I expected Groovy to have source-level compatibility.
The source-level compatibility is maybe 90% but not perfect (nor is this a goal).
Have I got the syntax incorrect? Or, is this a Groovy issue?
Probably a bug. Please file a bug report.

Resources