What does #:keep mean in Haxe? - haxe

I am new to Haxe and playing with the OpenFL Starling Sample code -
I noticed a #:keep metadata before the class declaration. What does it mean?
#:keep class TouchScene extends Scene {
// ...
}

Haxe allows metadata tags on classes and functions.
#:keep is a metadata tag that instructs the compiler's dead code elimination feature not to remove the class or function, even if it believes that the class or function is unused.
There are many other built-in metadata tags.
FYI, for advanced users, you can create schemas and specify your own metadata tags (and parse them using macros). For example, my lazy-props library does exactly this.

Related

JOOQ generator: use existing enums

I am using nu.studer.jooq gradle plugin to generate pojos, tables and records for a PostgreSQL database with tables that have fields of type ENUM.
We already have the enums in the application, so I would like that the generator uses those enums instead of generating new ones.
I defined in build.gradle for the generator: udts = false, so it doesn't generate the enums, and I wrote a custom generator strategy that sets the package for the enums to be the one of the already existing enums.
I have an issue in the generated table fields, the SQLDataType.VARCHAR.asEnumDataType(mypackage.ExistingEnum) doesn't work because the mypackage.ExistingEnum does not implement org.jooq.EnumType.
public enum ExistingEnum {
VAL1, VAL2
}
Generated table record:
public class EntryTable extends TableImpl<EntryRecord> {
public final TableField<EntryRecord, ExistingEnum> MY_FIELD = createField(DSL.name("my_field"), SQLDataType.VARCHAR.asEnumDataType(mypackage.ExistingEnum.class), this, "");
}
Is there something I can do to fix this issue? Also we have a lot of enums, so writing a converter for each of them is not suitable.
The point of having custom enum types is that they are individual types, independent of whatever you encode with your database enum types. As such, the jOOQ code generator cannot make any automated assumptions related to how to map the generated types to the custom types. You'll have to implement Converter types of some sort.
If you're not relying on the jOOQ provided EnumType types, you could use the <enumConverter/> configuration, or write implementations based on org.jooq.impl.EnumConverter, which help reduce boilerplate code.
If you have some conventions or rules how to map things a bit more automatically (just because jOOQ doesn't know your convention doesn't mean you don't know it either), you could implement a programmatic code generation configuration, where you query your dictionary views (e.g. PG_CATALOG.PG_ENUM) to generate ForcedType objects. You can even use jOOQ-meta for that purpose.

Is there a way to add an extension to AnyObject?

In Objective-C, I created a very handy category (an extension, in Swift terms) of NSObject that added the ability to add arbitrary key/value pairs to any NSObject at runtime. It uses associated objects to attach a mutable dictionary to the object, and then provides get and set methods that get/set key/value pairs to/from that dictionary. It's only a few lines of code.
This makes it possible to attach arbitrary key/value pairs to ANY object at runtime, including objects created by the system. That's the key. There are cases where a system framework returns an object to you and you need to be able to attach a value to it.
This trick also makes it possible to create categories that have new instance variables. (Ok, they don't really, but for it does let you add new state variables to objects in a category.)
This isn't possible in Swift 1.2 because:
Swift doesn't have a base class for all objects like NSObject in
Objective-C. It uses AnyObject, which is a protocol.
Swift 1.2
doesn't allow extensions to protocols.
I had to give up on this under Swift 1.2.
But Swift 2 allows extensions to protocols. I thought "Great, now I can add my extension that lets me add key/value pairs to AnyObject!"
No joy.
When I try to create my extension for AnyObject:
extension AnyObject: AssociatedObjectProtocol
I get the error message
'AnyObject' Protocol cannot be extended
Arghh! So close, but nope. It seems like the language explicitly forbids extending AnyObject. Why is this, and is there any way around it?
I don't use my category on NSObject that often, but when I do, it's a lifesaver. I'd like to add it to my bag of tricks in Swift.
I could add it to NSObject just like I do in Objective-C, but that means it only works for objects that inherit from NSObject - making it not work for native Swift classes.
Unfortunately a workaround which does exactly the same as you want doesn't exist. So I would suggest to make a protocol which has an extension to add default implementations:
protocol A: AnyObject {}
// in Swift you would rather use this
protocol A: class {}
// add default implementations
extension A {
func aMethod() {
// code
}
}
// Example
class B: A {}
// use the method
B().aMethod()
This approach does not make all classes automatically conform to this protocol (but only classes can conform to it). So you have to make them conform yourself. Since you don't use this as much this would be a reasonable solution.
Along the lines of #Qbyte's answer, declaring that NSObject conforms to a protocol means that almost every class in the entire Cocoa/UIKit/Foundation universe will inherit that functionality:
protocol MyProtocol {
func doSomething()
}
extension MyProtocol {
func doSomething() {
print("This is me, doing something.")
}
}
extension NSObject: MyProtocol { }
You've just conformed 99% of Apple's framework classes to MyProtocol. You can make your own classes conform to MyProtocol by inheriting from NSObject or by simply conforming to it.
I feel like you had the answer in front of you. Extending NSObject works perfectly in Swift too. (Maybe not 6 years before tho 🥲)
extension NSObject { }

SearchDomainFactory.Instance is obsolete: 'Inject me!' ( Can't find out how to create instance)

I'm in the process of trying to migrate a R# extension project from R# 6 to R# 8. (I've taken over a project that someone wrote, and I'm new to writing extensions.)
In the existing v6 project there is a class that derives from RenameWorkflow, and the constructor used to look like this;
public class RenameStepWorkflow : RenameWorkflow
{
public RenameStepWorkflow(ISolution Solution, string ActionId)
: base(Solution, ActionId)
{
}
This used to work in R# SDK v 6, but now in V8, RenameWorkflow no longer has a constructor that takes Solution and actionId. The new constructor signature now looks like this;
public RenameWorkflow(
IShellLocks locks,
SearchDomainFactory searchDomainFactory,
RenameRefactoringService renameRefactoringService,
ISolution solution,
string actionId);
now heres my problem that I need help with (I think)
I've copied the constructor, and now the constructor of this class has to satisfy these new dependancies. Through some digging I've managed to find a way to satisfy all the dependencies, except for 'SearchDomainFactory'. The closest I can come to instantiating via the updated constructor is as follows;
new RenameStepWorkflow(Solution.Locks, JetBrains.ReSharper.Psi.Search.SearchDomainFactory.Instance, RenameRefactoringService.Instance, this.Solution, null)
All looks good, except that JetBrains.ReSharper.Psi.Search.SearchDomainFactory.Instance is marked as Obsolete, and gives me a compile error that I cannot work around, even using #pragma does not allow me to compile the code. The exact error message I get when I compile is Error 16 'JetBrains.ReSharper.Psi.Search.SearchDomainFactory.Instance' is obsolete: 'Inject me!'
Obvious next question..ok, how? How do I 'inject you'? I cannot find any documentation over this new breaking change, in fact, I cannot find any documentation (or sample projects) that even mentions DrivenRefactoringWorkflow or RenameWorkflow, (the classes that now require the new SearchDomainFactory), or any information on SearchDomainFactory.Instance suddenly now obsolete and how to satisfy the need to 'inject' it.
Any help would be most appreciated! Thank you,
regards
Alan
ReSharper has its own IoC container, which is responsible for creating instances of classes, and "injecting" dependencies as constructor parameters. Classes marked with attributes such as [ShellComponent] or [SolutionComponent] are handled by the container, created when the application starts or a solution is loaded, respectively.
Dependencies should be injected as constructor parameters, rather than using methods like GetComponent<TDependency> or static Instance properties, as this allows the container to control dependency lifetime, and ensure you're depending on appropriate components, and not creating leaks - a shell component cannot depend on a solution component for instance, it won't exist when the shell component is being created.
ReSharper introduced the IoC container a few releases ago, and a large proportion of the codebase has been updated to use it correctly, but there are a few hold-outs, where things are still done in a less than ideal manner - static Instance properties and calls to GetComponent. This is what you've encountered. You should be able to get an instance of SearchDomainFactory by putting it as a constructor parameter in your component.
You can find out more about the Component Model (the IoC container and related functionality) in the devguide: https://www.jetbrains.com/resharper/devguide/Platform/ComponentModel.html

Buiding Orchard Module - Telling Autofac to use different implementations

As I exposed here, I would like to be able to query freely on the index without Orchard building the query for me.
I built a module, and inserted a copy of the SearchController, adding a new route...
To override default Orchard behavior concerning the query, I had to create new implementations of : ISearchService, IIndexManager, ISearchBuilder, IIndexProvider.
There are minor modifications from their default implementations, but they are needed.
That works as expected, but it currently override the default search too.
This is because I used the same interfaces and autofac takes my implementations.
I would like to be able to leave the default implementation untouched (at url /Search), and add my implementation at url (/LuceneSearch for example)
I suppose I must tell Autofac to use my implementations only for my controller by creating a class that inherits the autofac Module class.
Here is my problem : I don't know how to tell Autofac to use by default the Orchard Implementation, and just for my controller, use my implementation....
Another possibility is to create new interfaces, but it seems to me not really beautiful...
Can someone help me ? :)
Metadata feature will help you here. Also you have to register your implementations with PreserveExistingDefaults() modifier to preserve orchard's implementations by default.
Update:
Orchard registers all dependencies from Autofac's IModule implementation and from Orchard's IDependency one. All magic happen in Orchard's ShellContainerFactory class. Since ISearchService inherits from IDependency your implementation is registered by Orchard which overwrites default one.
You have two ways here:
Introduce your own empty interface IMySearchService which inherits from ISearchService. Implement and use it in your code where you need your implementation. Orchard will handle all registrations for your.
Orchard registers all IDependency implementations with "Feature" Metadata in ShellContainerFactory.RegisterType method. You can read this metadata in your code and choose your implementation (see link to wiki above). Feature class contains all necessary information about your module.
Hope this will help you.
A simpler method without dabbling with the intricacies of Autofac would be to use an IEnumerable<IInterface> variable in your controller/driver at url "/LuceneSearch" to hold all implementations of IInterface and choose which to consume.
For example, in order to consume your implementation of IIndexManager, you would put the following in your controller or driver
public class MyCustomPartDriver : ContentPartDriver<MyCustomPart> {
private readonly IEnumerable<IIndexManager> _indexManagers;
public MyCustomPartDriver(IEnumerable<IIndexManager> indexManagers) {
_indexManagers = indexManager;
}
protected override DriverResult Display(MyCustomPart part, string displayType, dynamic shapeHelper) {
//Use your implementation of IIndexManager
var indexManager = _indexManagers.First(im => im is MyCustomIndexManager);
//Get the ISearchBuilder from your implementation of IIndexManager
var searchBuilder = indexManager.HasIndexProvider() ? indexManager.GetSearchIndexProvider().CreateSearchBuilder("Search") : new NullSearchBuilder();
//perform search on the indexing engine
var contentItemIds = searchBuilder.
.WithField("type", "MyCustomType").Mandatory().ExactMatch()
.Parse("mycustompart-keyword", part.Keyword).Mandatory()
.Search()
.Select(h => h.ContentItemId)
.ToList();
//do stuff with the results returned and return a DriverResult using the ContentShape method. Well, you know the drill.
}
}
If you don't want to have autofac resolve your own implementation by default, then don't implement the public interface.

How do you load data into an attributed database class generated by the MFC application wizard?

Using the MFCApplication wizard in Visual C++ 2012, if "Generate attributed database class" is checked, a header with some special syntax (attributed C++ classes) are generated, which look like this:
// MFCApplication2Set.h: interface of the CMFCApplication2Set class
//
#pragma once
// code generated on March-05-13, 9:26 AM
[
db_source(L"Provider=SQLNCLI11.1;..."),
db_table(L"dbo.tblEmployee")
]
class CMFCApplication2Set
{
public:
... big list of stuff that corresponds to the fields in your db table omitted ...
}
The above header corresponds to a mostly empty implementation file:
// MFCApplication2Set.cpp : implementation of the CMFCApplication2Set class
//
#include "stdafx.h"
#include "MFCApplication2.h"
#include "MFCApplication2Set.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMFCApplication2Set implementation
That was the WHOLE implementation class. Notice that:
A. No parent class name is specified anywhere.
B. There's some "Visual C++ magic" going on here, that is, as a novice to modern C++, I'm lost.
db_source is documented here but the documentation is pretty thin or at least opaque to me.
Questions:
I was mystified by this syntax when I first saw it, but I figured out it's probably a variant of this Attributes feature in Visual C++. It is that, right?
How am I meant to I use these generated "attributed database class" objects? I found this documentation but if you look carefully at that documentation, that code sample is showing people the Old Way and the New Way, and is not telling me what I want to know which is how to use this new object that the IDE can not give me any documentation or code completion features for. Also since the generated code for the CMFCApplication2Set class generated by the wizard does not reference any types or class names, I'm lost. If I could even use some IDE feature to know what methods and stuff have been Magically Injected into this Magical mystery Object, I'd be better off. The only think I can think to do is to learn the old way and learn all the things you can call from the old two-separate-ATL-types world, and then somehow learn to combine them.
In a nutshell, I'm looking for the minimum syntax I need to know to actually use one of these Attributed Database Class instances, variables, as they are generated in a new MFC app by the wizard. The instance shown below is a member of an MFC document class and CMFCApplication2Set m_MFCApplication2Set is declared as a field inside the MFC document class.
What I have tried is to use this "untyped object". This object appears to have lots of data fields (m_X) and has only one method that shows up in IDE code completion, called GetRowSetProperties. Thanks to whatever magic or injection is going on, this generated Attributed Database Class (which does not visibly inherit anything) is a complete mystery to me at edit time and compile time.
Here's me just trying to inspect this thing to see if it even initialized itself when its constructor ran:
BOOL CMFCApplication2Doc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE;
TRACE( m_MFCApplication2Set.m_AStringFieldName); // outputs NOISE.
return TRUE; }
At compile time and edit time, the IDE gives me NO help about the types involved in this "anonymous" class that inherits from nothing, but which gets lots of secret powers due to some kind of Injection via those attributes I'm guessing. At debug time, I can see that there is more than just a bunch of data fields in this C++ class, but this still doesn't help me know how to use it. A minimal code sample of using one of these to go get a recordset from the database, would be great.
Update: Calling OpenDataSource is fun, because it compiles but the IDE doesn't think it should be valid. Nevertheless, it runs, and returns 0 as the result, but that doesn't actually initialize this CThingyThatVisualStudioGaveYouThatYouDontKnowWhatItIs:
This is a deprecated feature of attributed C++ code. Pre-processor expands code and replaces attributes with actual base classes. If you enable generation of these intermediate files, things are going to be more clear to you:
You will have XXX.mrg.cpp and XXX.mrg.h files generated, which you can review and see the real C++ code forwarded to compiler.
The attributes will be replaced with substituted bases classes, maps like BEGIN_COLUMN_MAP etc. The attributed source code is compact, but the feature is deprecated and looking into expanded code it should be easy (if necessary) to strip the attributes and copy expanded code right into source. It's easy with DB attributes, and more difficult with COM attributes since the internal dependencies are most sophisticated.

Resources