I would like to enforce static linking for a whole package in groovy. Static linking requires use of CompileStatic. I would like to avoid restating this on every class. How can I apply this as a package-level annotation. I have found no reference to package-level annotations in groovy.
Can you please provide a piece of code that shows how to apply the annotation to a package a.b.c?
This is untested, but I think it should be possible to create a nice combination of a configurationScript, a Source aware customizer and a AST transformation customizer explained in dsl docs.
something like:
withConfig(configuration) {
source(unitValidator: { unit -> unit.AST.classes.any { it.packageName== 'a.b.c' } }) {
ast(CompileStatic)
}
}
Related
I'm working on project, where we're using Stripe library for Node. We also want to use TypeScript on this project.
I've figured out that Stripe isn't providing official TypeScript definitions but I've found some community definitions #types/stripe on NPM. So I installed them and after a while I got an error:
Property 'sources' does not exist on type 'Stripe'.
Well there are missing some definitions, for example for this stripe.sources-related functionality.
I want to add missing definitions locally. So I need to extend this file:
#types/stripe/index.d.ts
I think that for the problem above I need:
to add property sources: Stripe.resources.Sources; to class Stripe,
to add class Sources to namespace resources,
to add missing function declarations to class Sources.
The problem is that I really don't know how. How should the .d.ts file with extensions look like? I've made many attempts according some examples and TypeScript docs but it always doesn't work. Do you have any idea?
I don't believe there's a way to augment the export-assigned Stripe class; the problem is similar to this open issue about augmenting a default-exported class. At this time, since you can't use augmentation, you'll have to fork the #types/stripe definitions for your project, and then you may as well make all the desired changes that way.
I think my colleague has found a solution that works for me. Here is how he made it:
import ST from 'stripe'
declare module 'stripe' {
namespace sources {
interface ISource extends IResourceObject {
...
}
interface ISourceCreationData {
...
}
}
namespace resources {
class Sources {
create(data: sources.ISourceCreationData): Promise<sources.ISource>;
retrieve(source: string, client_secret?: string): Promise<sources.ISource>;
}
}
class Stripe extends ST {
sources: ST.resources.Sources;
}
}
I have a groovy class "Utils.groovy" which contains the method "makeHttpCall()".
This is a summarized version of the method:
static String makeHTTPCall() {
...
request.setHeader(javax.ws.rs.core.HttpHeaders.AUTHORIZATION, authHeader)
...
}
The compiler complains:
Groovy:Apparent variable 'javax' was found in a static scope but
doesn't refer to a local variable, static field or class.
If I make the method non-static though, it will stop complaining;
String makeHTTPCall() {
...
request.setHeader(javax.ws.rs.core.HttpHeaders.AUTHORIZATION, authHeader)
...
}
this way it doesn't complain. Why does the compiler complain about this?
Note that the method runs with no problems; it is run as part of a Jenkins shared library.
Thanks!
EDIT: Using
import javax.ws.rs.core.HttpHeaders gives
Groovy:unable to resolve class javax.ws.rs.core.HttpHeaders
So that class is not resolvable by the compiler, but it is when run inside Jenkins.
You need to add the library that provides "javax.ws.rs.core.HttpHeaders" to your project's buildpath. Alternatively, you can use an #Grab to your class/script. This is probably not what you want in this case since Jenkins is providing that dependency at runtime.
What is the purpose of runtime mixins in groovy?
Mixins overall one of the ways to add functionallity to class without multiple inheritance issues. But what is its purpose in Groovy? Traits can do the same.
Annotation #Mixin is considered deprecated at all. Will runtime mixins have the same fate one day?
Runtime mixins give us the ability to add methods to existed classes at runtime. The important part of the answer is "existed" and "runtime".
So, you can easily add new methods to any 3rd party library at runtime.
Actually, recently I found a case where using mixins helped me a lot.
String.metaClass {
invokeMethod {
String name, args ->
System.out.println "[$name] invokation with $args"
}
}
class GroovyInterceptableWrapper
implements GroovyInterceptable {
}
String.mixin(GroovyInterceptableWrapper)
Though again if I used there trait instead of class and then invoked withTraits I would have achieved the same result.
I have an annotation which adds some methods and default constructor to annotated class.
I have managed to create a gdsl, to enable autocompletion in idea for methods, but I'm stuck with constructor and documentation is very poor.
Does anyone have any ideas, how to do this?
Maybe I could find a solution, in existing gdsl, but I can't remember any Transformation, related to constructors. Maybe you can remind me of any of them.
def objectContext = context(ctype: "java.lang.Object")
contributor(objectContext) {
if (hasAnnotation("com.xseagullx.SomeAnnotation")) {
// Here I want to add constructor's declaration(with empty arg's)
// …
// And then my methods.
method name: 'someMethod', type: 'void', params: [:]
}
}
EDITED: OK, if it's as #jasp say, and there is no DSL construct for declaring Constructors, I'm still asking for a good documentation sources, other than JB's confluence page. Tutorials and other sources. I'm familiar with embedded dsl's for groovy, grails and gradle.
Need smth. more structured, if it's possible.
All function invocations inside of GroovyDSL are just calls to wrappers around internal IDEA's Program Structure Interface (PCI). However it doesn't cover all of PCI's abilities, including default constructors functionality I believe. One of an evidence for that is singletonTransform.gdsl, which is bundled into IDEA from 9 version and describes #Singleton AST transformation. Here is it's code:
contributor(context()) {
if (classType?.hasAnnotation("groovy.lang.Singleton")) {
property name: "instance",
type: classType?.getQualifiedName() ?: "java.lang.Object",
isStatic: true
}
}
As you can see it doesn't change a constructor and it's visibility, so IDEA will autocomplete this invalid code:
#Singleton class Foo {}
def foo = new Foo()
Futhermore GDSL that describes the semantics of GroovyDSL (which is actually the part of /plugins/groovy/resources/standardDsls/metaDsl.gdsl of IDEA sources) doesn't provide any ability for describing of constructors.
In this case I suggest you use newify transformation which allows you to describe targetClass.name method returning created instance.
I know this is a bit old, but I found myself looking for something similar.
The DSL you are looking for is
method params: [:], constructor: true although I don't understand why you'd need it; if a class doesn't declare any constructors doesn't IDEA always suggest the default one?
I mainly program in groovy, but occasionally it's too slow. So I write a separate .java class, and put the code that needs to run faster in a java method and call that java method from my groovy code.
This causes me to end up with two separate files and two separate classes. Is there any way I could embed a java method right into the groovy file, maybe marking it with an annotation to indicate that it is java?
This is the idea behind groovy++. Marking a class or method with the #Typed annotation will cause it to use static typing instead of dynamic typing, while still retaining a lot of goodness of groovy.
While not exactly java, typed groovy++ methods generally perform about the same as java would.
More information on groovy++ is available at: https://code.google.com/p/groovypptest/wiki/Welcome
You don't need to do anything special.
Just write the Java class behind the groovy class. 99% of all Java source is valid groovy source as well.
class GroovyClass {
def a;
def doSomething(x,y) { return x*y; }
}
class JavaClass {
SomeType someVar;
public JavaClass() { /* ... */ } // some contructor
public void doit(String a, int b) {} // full typed method, that is java
}
Groovy++ is somethign completely different.
The JavaClass needs to have everything fully typed to be "Java" however your problem can be solved far easyer if you just use types in the relevant groovy methods.
class AnotherGroovyClass {
// typed
public Result someMethod(SomeArg arg1, SomeOtherArg arg2) {
}
def someVariable; // untyped
}
If you think the lack of speed comes from the dynamic nature of groovy then just use full types at the relevant points.