Why do my SWC libraries not code hint? - actionscript-3

I recently took much of my reusable code and compiled them into SWCs for organization and ease-of-use purposes. Since doing so, none of my documentation has appeared in the code hints that Flash Builder provides. I have searched through project settings and I have been unable to find a setting for such a feature, and I am at a loss as to why it doesn't work anymore.
I compiled the SWCs using Flash Builder's Build Automatically functionality. I have not tried compiling with ANT yet, but will probably try the next time I build. asdocs was able to compile full documentation for all of my libraries with relative ease and the code hinting works if I use the raw AS files themselves, so I do not believe it has anything to do with the way I was writing the documentation. Example:
/**
* <p>Batch adds variables from a generic object using name-value pairs</p>
* #param variables A generic <code>Object</code> that contains name-value
* pairs that will be used as the arguments of the REST request
*/
public function addVariables( variables:Object ):void {}
Any idea why the code hinting no longer works?

Flash Builder uses ASDocs, which are embedded inside the SWC, to provide code hints - unfortunately, FB doesnt include the docs when it builds a SWC.
However, it can be done 'manually' with ANT:
<target name="insertASDocs">
<zip destfile="PATH_TO_YOUR_SWC" update="true">
<zipfileset dir="ASDOCS_FOLDER/tempdita" prefix="docs">
<include name="*.*"/>
<exclude name="ASDoc_Config.xml"/>
<exclude name="overviews.xml"/>
</zipfileset>
</zip>
</target>
PATH_TO_YOUR_SWC is the relative path and swc name (eg: myFolder/mySwc.swc).
ASDOCS_FOLDER is the folder where your generated docs are stored.
The ANT script just adds the ASDocs to the SWC - after this, code hints should appear.
Update:
Forgot to mention that you need to set keep-xml to true when generating the docs (if inserting them into a swc):
<asdoc keep-xml="true" ...

Related

Manifest for dependencies on items other than the main executable?

I'll explain what i'm trying to do (and why) first and then get more into the details.
I'm trying to get Registration Free COM activation working in the context of a language that is compiled JIT. I use Reg-Fre COM because i would like to avoid having to register my COM component and would like this application to be installable without administrative rights.
The JIT compiler is the main executable is signed and contains an embeded manifest. Latest versions of Windows prefer the embeded manifest over an external one, by default (it was the opposite on Windows XP).
Since the JIT is signed, i cannot extract/modify/update it's manifest without breaking the signing. Also, this would introduce complexity in the maintenance of our application (always making sure we embed a new manifest). And there's are also the legal implications of modifying a program for which i don't own the rights.
So, my idea was to try to get the WinSxS activation going thru a Win32 wrapper library for which i would provide a manifest that lists the dependencies. As a proof of concept, i decided to make a simple VB6 app, a C++ Wrapper Library and two COM library (1 in .NET and 1 in VB6).
The wrapper contains 3 methods, one that calls the VB6 COM, one that calls the .NET COM and one that returns a simple string.
As long as everything as my COM are registered, it works, of course.
If i unregister them, provide manifests for the COMs and add them as dependencies to the main executable's manifest, it works.
If i unregister them, provide manifests for the COMs and the C++ Wrapper and add the com as dependencies for the C++ Wrapper and then add the C++ Wrapper as the only dependency in the main executable's manifest, it works.
If i delete my main executable's manifest, the COM calls stop working but the simple string method still works.
Please note that for all my tests, i run a Powershell script that changes the Modified Date of all my files, making sure to trip the activation context cache (manifest).
From there, i started debugging using SXSTrace.exe and setting the COMPlus_LoadLogDir variable. I found out that if my manifest is external, it never gets taken into consideration. I also found out that if i embed it in the .DLL, sxstrace shows it is found, parsed and that the dependencies are found, their manifest found and i get the usual successful context activation lines in the log.
INFO: Parsing Manifest File C:\RegFreeComWrapper\bin\vbCom.MANIFEST.
INFO: Manifest Definition Identity is vbCom,type="win32",version="1.0.0.0".
INFO: Parsing Manifest File C:\RegFreeComWrapper\bin\netCom.MANIFEST.
INFO: Manifest Definition Identity is netCom,processorArchitecture="msil",version="1.0.0.0".
INFO: Activation Context generation succeeded.
End Activation Context Generation.
However, even tho the log says that, my COM calls still dont go thru.
When the call goes thru for the .NET COM call, i get some output in the COMPlus_CLRLoadLogDir configured path.
In this case, i don't get any output.
As soon as i add the manifest that only lists my C++ Wrapper as a dependency to my main executable, everything starts working again. I get a similar output from SXSTrace, but now the COM call works. As mentioned, in all cases, the C++ Wrapper's simple string method works. Meaning that even tho i have no manifest from my main executable, it can still find my .dll and call it.
Seems like the COMs don't work if i dont have the full manifest chain:
Application.Manifest > Wrapper.Manifest > COMs manifests
So, two things here...
1. Is the thing i'm trying to do even possible? (Having dependencies listed only in the manifest of a DLL that belongs to me, without touching the main executable's manifest)
2. If it is possible, i'm probably only missing a small thing to get everything going... what is it ? :)
I can provide all my code/executable as examples, should someone be interested in trying stuff with em.
Got it working!
I modified my C++ Wrapper to use the Activation Context API and force a context activation using 'ActivateActCtx'
http://msdn.microsoft.com/en-us/library/aa374151(v=vs.85).aspx
I wrapped my code with their example's code and made sure to reference my manifests and now all is working fine. No manifest on my main executable!

How can I set a compile time variable in a SWF with the same ID as a Maven artifact?

I would like to set a variable in my swf at compile time that reads the current commit/branch from git and also edits the pom.xml with that name as the artifact id.
I want to do this so that I can query a swf and retreive which version of the maven build it is.
Is this possible, and which plugins would I use to do this?
I have done this sort of thing using ANT in the past, but I need to be able to do it using Maven instead.
My searches on the internet have mostly revealed ways to do this in Java but not in Actionscript.
I assume you are using the flexmojo's plugin. Have a look at the flexmojo's definesDeclaration parameter. This will allow you to pass in values for the compiler variables you define in your Actionscript project with the -define option (per the Adobe article you've linked to).
Then it's just a matter of setting that value to the artifact ID, date/time, or whatever.

How do I disable code generation in my test plugin?

I have a couple of test files written in my DSL in my tests plugin/project. Most of the tests use inline multi-line strings and Xtend but in four cases, I need to test code which does some magic with URLs and the classpath, so I really need resources in the classpath for that.
Since loading the resources only works when the extension is correct, I can't give the files a fake extension.
Now my problem: My DSL also has a code generator. This means that eventually, I end up with a couple of generated files in places where I can't have them (they don't compile, for example, and one even contains an error to test error handling when information is split across several files).
I can't disable the Xtext nature because the tests project uses Xtend so for these files, I do need code generation.
Since the generator runs inside Eclipse (I have the DSL plugins installed for other projects), there is no way to override the code generator in Guice.
How can I disable the code generator in this case?
There is a simple way to achieve this:
Open the properties of your project
Expand the entry for your DSL
Select "Compiler"
Select "Enable project specific settings"
Disable/deselect "Compiler is activated" under "General"
If you don't have a properties entry for your DSL:
Add this fragment to your .mwe2 workflow file:
fragment = generator.GeneratorFragment {}
Regenerate your projects
Merge the new code from plugin.xml_gen into plugin.xml both in the base and the UI plugins.
The interesting parts are the two extension points org.eclipse.ui.preferencePages and org.eclipse.ui.propertyPages

Exported SWC doesn't preserve auto-complete functions' parameters' names

I am using Flash CS5 and I have created a large, rarely changing framework that I don't want to be recompiled every time I use it in my projects.
I must be doing something wrong because the "auto-complete" functionality doesn't show the names of the parameters of the functions.
For example, I have a function:
public class Hey {
public function show(name:String, num:Number, data:Array):void {...}
}
I export the SWC file and when I import it into another project, then the auto-complete for this function shows :
show(arg0:String, arg1:Number, arg2:Array):void
So, instead of "name", "num" and "data" I get "arg0", "arg1" and "arg2".
I have downloaded other SWC files and the auto-complete gets the names correctly.
Am I doing something wrong at export-time?
I have never been able to get an SWC generated with the Flash Pro IDE to supply the correct parameter names in code hints. For some reason, the Flash IDE either does not use the same compiler or does not use the same compiler options as the Flex SDK toolkit.
You can generate code-hinting-compatable SWCs with Flash Builder by creating a Flex Library project. The "Flex" part of "Flex Library" is a little misleading. You can build AS3-only SWC files with this project type.
Or if you don't feel like shelling out the money for Flash Builder, you can always download the free Flex SDK and use the compc compiler to generate the SWC for you. It's the same tool set that Flash Builder uses to generate SWCs, so you will get the same code-hinting ability. The syntax is pretty straight-forward if you're used to command line tools:
compc -source-path . -include-classes MyCustomClass -output=MyLibrary.swc
Hopefully someone can post a better answer and prove me wrong, but I've never seen a Flash-generated SWC include the parameters in code-hinting.
I suppose you compile with debug=false but should be debug=true to keep all necessary data in swc including arguments names.
Optimizing libraries means to remove debugging and other code from the library prior to deployment. For normal libraries that you are not using as RSLs, you do not need to optimize. This is because you will likely want to debug against the library during development, so you will need the debug code inside the library. And, when you compile the release version of your application, the compiler will exclude debug information as it links the classes from the library.
http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7ad5.html
For me the easiest way was to import the code to a Flash Develop project, and install a plugin to export swc's: http://sourceforge.net/projects/exportswc/
After installing Flash Develop go to Tools » Install Software and install the AIR SDK + ASC 2.0 (Action Script Compiler 2.0).
Furter information here: http://www.flashdevelop.org/community/viewtopic.php?t=2987

How to override a Magento function in app/code/core/Mage/Core/functions.php

I need to override a function in this file:
app/code/core/Mage/Core/functions.php
The problem is that this is so core that there’s no class associated to it, probably because Core isn’t even a module. Does anybody know how to override a function in the file without a class?
Any help would be appreciated.
Copying the file to app/code/local/Mage/Core/functions.php should not be used because of the following reasons:
The entire file has to be copied over making it harder for us to identify what changes have been made.
Future upgrades could introduce new features that would not be available unless it is remembered to copy across the new version of that file and implement the changes again.
Future upgrades could address bugs with core that we would miss unless it is remembered to copy across the new version of that file and implement the changes again.
In respect to points 2 & 3 each upgrade could change the way things work that means revisiting what changes we need to make. In some cases this will be true for overriden methods as well but at least we can easily identify where those changes effect us.
What do you do if another person wants to use the same technique? Being able to identify what is core code and what is ours becomes more and more complex.
Keeping our code together as a “module” becomes more difficult as by copying in the core file means that we have effectively locked it into being “guaranteed” to run on the version of the software that we have copied the original code from. It also means reusing this work is a lot more difficult to do.
Identifying why the code was changed it much harder as it is outside our namespacing, ie all development related to “Example_Module” is in the namespace:
/app/code/core/local/Example/Module
whereas code copied to app/code/core/local/Mage only indicates that we have made a change to support an unknown feature etc.
Also Magento occasionally release patches which fixes bugs – these will only patch files inside core leaving your copied file without the patch.
What I would suggest instead is that you write your own function to do what you want and override the function to call your new function instead.
Maybe I did not understood your question right but why not just copy this file into
app/code/**local**/Mage/Core/functions.php
and modify it there in any way you want?
As mentioned by #tweakmag the disadvantages of creating a folder structure and copying the entire Model or controller for a single function override, most important being,
"Future upgrades could introduce new features that would not be
available unless it is remembered to copy across the new version of
that file and implement the changes again."
Thus a solution can be, to extend the core class (Model or controller) and just write the method you want to override, instead of copying all the methods.
For example, if you want to say, override a method getProductCollection in Mage_Catalog_Model_Category, here will be the steps:
Create a Custom Namespace/Module folder with etc folder in it
Register the module in app/etc folder by creating Namespace_Module.xml
setup the config.xml in Namespace/Module/etc/ :
<?xml version="1.0"?>
<config>
<modules>
<Namespace_Module>
<version>1.0</version>
</Namespace_Module>
</modules>
<global>
<models>
<catalog>
<rewrite>
<category>Namespace_Module_Model_Category</category>
</rewrite>
</catalog>
</models>
</global>
</config>
create Model folder in Namespace_Module and a Php File Category.php
Now the main difference here is we extend the Magento's core class instead of writing all the methods
<?php
/**
* Catalog category model
*/
class Namespace_Module_Model_Category extends Mage_Catalog_Model_Category
{
public function getProductCollection()
{
// Include your custom code here!
$collection = Mage::getResourceModel('catalog/product_collection')
->setStoreId($this->getStoreId())
->addCategoryFilter($this);
return $collection;
}
}
The getProductCollection method is overridden so it'll be called instead of the method defined in the core model class.
Also an important point is:
When you override any methods in models, you should make sure that the data type of the return value of that method matches with the data type of the base class method. Since model methods are called from several core modules, we should make sure that it doesn't break other features!
This link gives a step by step approach to it
1. UOPZ
There's a way to do it without having to copy and maintain functions.php file from core, but it involves extension uopz (pecl install uopz), then you can rename magento's function (from foo to foo_uopzOLD for example) and define your own (https://secure.php.net/uopz)
It works and is very useful for magento - usually you'll bump into something you can not change. Uopz is very helpful in such cases.
pros: works ;), you don't have to redo it everytime you update Magento (if you do it right, because inside you still can call foo_uopzOLD so you can assure some backward compatibility... in some cases).
cons: it's little bit implicit
2. Composer post-install-cmd
If you don't like the above, but you use composer you can patch any file you want:
"scripts": {
"post-install-cmd": "patch -p0 < change-core-functions.patch"
}
pros: explicit (when patch fail - composer install fails), and since it's explicit - you can revisit and fix the patch every time you upgrade magento
cons: you have modified core file, so you probably would want to add it to .gitignore
3. Ugly solution (uglier than those above)
If none of the above is possible for you (really, give it a try with composer - there's no excuse for not using it). But when you really can not the only way I can think of
- create app/local/Mage/Core/functions.php
- define this one function you need
- load original /app/core/Mage/Core/functions.php
- surround every function foo() {...} with
if(!function_exists("foo"){
function foo() {...}
}
hold on to your chair and
eval this SOB ;)