NRefactory parsed code - is class currently inheriting? - nrefactory

What is the best way to identify, on a NFactory parsed tree, if the current class is actually inheriting (or not) from another class?

you should see if the parsed tree has any basetypes or not.
TypeDeclaration typeDeclaration = new CSharpParser().Parse("public class A:B{}").Children.OfType<TypeDeclaration>().First();
if(typeDeclaration.ClassType==ClassType.Class && typeDeclaration.BaseTypes.Count>=1)
{
//this class is inherited..
}

Related

How to decorate the final class DocumentGenerator

I am having problems to decorate the final class "DocumentGenerator" (in vendor/shopware/core/Checkout/Document/Service/DocumentGenerator.php) and overwrite the "generate" function inside of it.
I tried to decorate it the usual way, but an error is thrown because the "DocumentController" class excepts the original class and not my decorated one?
Argument 2 passed to Shopware\Core\Checkout\Document\DocumentGeneratorController::__construct() must be an instance of Shopware\Core\Checkout\Document\Service\DocumentGenerator
Its also not possible to extend from the class in my decorated class, because the "DocumentGenerator" is a final class.
My goal is to execute additional code, after an order document is generated. Previously I successfully used to decorate the "DocumentService" Class, but its marked as deprecated and shouldnt be used anymore. Also the "DocumentGenerator" class is used for the new "bulkedit" function for documents as of Version 6.4.14.0
I'm grateful for every tip.
As #j_elfering already wrote it's by design that you should not extend that class and therefore also shouldn't decorate it.
To offer a potential alternative:
Depending on what you want to do after a document has been generated it might be enough to add a subscriber to listen to document.written, check if it was a new document created and then work with the data from the payload for fetching/persisting data depending on that.
public static function getSubscribedEvents()
{
return [
'document.written' => 'onDocumentWritten',
];
}
public function onDocumentWritten(EntityWrittenEvent $event): void
{
foreach ($event->getWriteResults() as $result) {
if ($result->getOperation() !== EntityWriteResult::OPERATION_INSERT) {
// skip if the it's not a new document created
continue;
}
$payload = $result->getPayload();
// do something with the payload
}
}
Probably not what you want to hear but: The service is final in purpose as it is not intended to be decorated.
So the simple answer is you can't. Depending on your use case there may be other ways that don't rely on decoration.

In which sequence does method call work in groovy?

I am using groovy 2.3.8
I am trying to figure out how method calls work in groovy. Specifically if we have a Java class hierarchy each having a metaClass like below
class A {
}
A.metaClass.hello = {
"hello superclass"
}
class B extends A {
}
B.metaClass.hello = {
"hello subclass"
}
If I use new B().hello() I get hello subclass. If I remove meta class of B then I get hello superclass.
Based on changing the above example I think groovy goes in the below sequence to find which method to call
method-in-subclass's-metaclass ?: subclass-metho ?: method-in-superclass's metaclass ?: method-in-superclass
So how does groovy lookup which method to call?
Well, the hierarchy is the expected object oriented programming method overloading, which is what you witnessed. What differs is the dispatching. Instead of starting with a method lookup in instance's class, it begins with the MOP (meta object protocol).
In layman's terms, because the MOP is programmable, so is the way methods are invoked :)
How it works
The following diagram from Groovy's documentation shows how methods are looked up.
What's not clear in the diagram is that there's an instance metaclass as well, and it comes before the class's metaclass.
Something that may help is looking at an object's or class's .metaClass.methods Methods added through inheritance, traits, metaclass, etc are listed in a flat list. The inheritance hierarchy is flattened. .metaClass.metaMethods on the other hand seems to contain methods added via the GDK. From the list I could not tell method precedence :(
Based on observation, the rule seems to be this: the last MetaClass standing wins.
class A { }
class B extends A { }
A.metaClass.hello = {
"hello superclass"
}
B.metaClass.hello = {
"hello subclass"
}
def b = new B()
assert b.hello() == "hello subclass"
b.metaClass = A.metaClass
assert b.hello() == "hello superclass"

Cannot make a generic fake for a class using object

Cannot make a generic fake for a class using object like
Fakes.ShimDataServiceRepository<object>.AllInstances.GetEntitiesExpressionOfFuncOfT0Boolean = (instance, filter) =>
{
return null;
}
The call goes to actual code implementation.
But when we specify the object type, it is working
Fakes.ShimDataServiceRepository<Customer>.AllInstances.GetEntitiesExpressionOfFuncOfT0Boolean = (instance, filter) =>
{
return null;
}
But i need a general single fake for all objects so no need to repeat the code for each objects.
My question is why the fake with <object> is not working?. As it is the parent of all the classes.
Please any one help me :(
My question is why the fake with is not working?. As it is the parent of all the classes.
Object is the parent of all classes, but DataServiceRepository<object> is not the parent of DataServiceRepository<Customer>.
A generic class with different concrete types is no longer "the same class". The two types don't share statics or fakes.

Grails: How to make everything I create Upper Case?

I am currently using CSS to change everything I write to upperCase when I create an entry, but that is not enough. When I save things, the text shown in the text fields is upper case, but the real value that Grails stores stays in lower case.
I am assuming I'd need to change something in the controller or anything.
Maybe transforming the $fieldValue CSS could work??
Any ideas would help!
Thnks!
You could just write setters for your domain object?
class Domain {
String aField
void setAField( String s ){
aField = s?.toUpperCase()
}
}
I think you are asking how to change values on your domain objects to uppercase. If this is not the case please clarify the question.
You have a bunch of options. I would recommend
1) In a service method, before you save, using String.toUpperCase() to modify the appropriate values on the domain object.
or
2) You can use the underlying Hibernate interceptors by defining a beforeInsert method on your domain object, and doing the toUpperCase there. (see 5.5.1 of the grails documentation)
or
3) You could do this client side. However, if it is a "business requirement" that the values are stored as upper, then I recommend doing the translation server side. It is easier to wrap tests around that code....
Using annotations is cleanest approach
import org.grails.databinding.BindingFormat
class Person {
#BindingFormat('UPPERCASE')
String someUpperCaseString
#BindingFormat('LOWERCASE')
String someLowerCaseString
}
Here is link for it: Grails doc for data binding
You can use Groovy metaprogramming to change the setter for all domain class String-typed properties without actually writing a custom setter for each property.
To do this, add something like the following to the init closure of Bootstrap.groovy
def init = { servletContext ->
for (dc in grailsApplication.domainClasses) {
dc.class.metaClass.setProperty = { String name, value ->
def metaProperty = delegate.class.metaClass.getMetaProperty(name)
if (metaProperty) {
// change the property value to uppercase if it's a String property
if (value && metaProperty.type == String) {
value = value.toUpperCase()
}
metaProperty.setProperty(delegate, value)
} else {
throw new MissingPropertyException(name, delegate.class)
}
}
}
}

How to Parse multiple classes from groovy file

Is there a way to parse all all the classes in a groovy script?
To Parse ONE class right now:
java.lang.Class clazz = groovyClassLoader.parseClass(new File("MainApp.groovy"))
MainApp.groovy:
class MainApp {
def doIt() {}
}
class OtherMainApp {
def doTheRest() {}
}
This will return only MainApp.
I would like something like this:
java.lang.Class[] clazz = groovyClassLoader.parseClass(new File("MainApp.groovy"))
where clazz contains will contain both MainApp class and OtherMainApp class
Basically I want to be able to extract all the declared classes in a script.
Because of the nature of the app that I'm building groovyc command won't help
Thanks,
Federico
No can do:
https://issues.apache.org/jira/browse/GROOVY-3793
You could do it yourself though: you could parse the class yourself (just count the {} pairs), dump it out to a new file, and away you go. Ugly? yes. Painful? Very. Possible? Maybe. Better solution? Not until Groovy fixes the bug.
It's been 12 years since this question was asked and answered, but it arrived at the top of my Google results when I was trying to figure out how to do the same thing.
This ended up working for me:
def loader = new GroovyClassLoader()
loader.parseClass(new File("Company.groovy"))
Class Location = loader.loadClass("tk.vallerance.spacecompanies.models.Location")
Class Event = loader.loadClass("tk.vallerance.spacecompanies.models.Event")
Class Company = loader.loadClass("tk.vallerance.spacecompanies.models.Company")
println Location
println Event
println Company

Resources