Since yesterday, I've been trying to port an ActionScript Mobile project from Flash Builder 4.6 to Flash Builder 4.7, and I've run into a little bit of a problem that's probably a compiler bug. In FB 4.6, this works:
Temp.as:
package
{
import flash.display.Sprite;
public class Temp extends Sprite
{
public function Temp()
{
new StartMenu();
}
}
}
Screen1.as:
package
{
import flash.display.*;
internal class Screen1 extends Sprite
{
private static var m_vScreens:Vector.<Screen1> = new Vector.<Screen1>();
public function Screen1()
{
m_vScreens.push(this);
onScreenSizeDetermined();return;
var strFunction:String = "useSmallPortraitLayout";
for each (var screen:Screen1 in m_vScreens)
{
trace(1)
screen[strFunction]();
}
}
protected function useSmallPortraitLayout():void
{
}
private static function onScreenSizeDetermined():void
{
var strFunction:String = "useSmallPortraitLayout";
for each (var screen:Screen1 in m_vScreens)
{
trace(2)
screen[strFunction](); // Error thrown here in 4.7.
}
}
}
}
StartMenu.as:
package
{
public final class StartMenu extends Screen1
{
override protected function useSmallPortraitLayout():void
{
}
}
}
But in 4.7, it doesn't work. The error I get back is this:
ReferenceError: Error #1069: Property useSmallPortraitLayout not found on StartMenu and
there is no default value.
Now that being said, this can be fixed in one of at least two ways:
onScreenSizeDetermined();return;
, thereby using a member function to call useSmallPortraitLayout()
, instead of a static function. This doesn't require using the constructor; it works just fine, as long as Screen1
is calling useSmallPortraitLayout()
from pretty much any non-static method.Unfortunately the static method will fail, even when it's called from outside the constructor and/or from a timed delay. One thing I don't specifically remember in 4.6, but I am seeing it in at least 4.7, is that using an unrelated class to call a static method directly through an instance won't compile - it has to be done in a staticky way in unrelated classes. Not that I do things like that in real code, but it does make me wonder if the relationship between static and non-static has intentionally changed.
This is probably just some trivial compiler bug specific to FB 4.7, and I would just go right back to 4.6, but pure ActionScript library projects are directly supported only in 4.7. (This is a mobile project, but I was going to add a library project to the solution.)
One thing to note is the code will not compile in FB 4.7 if the static function calls useSmallPortraitLayout
this way:
screen.useSmallPortraitLayout();
It has to call it dynamically for it to even compile.
Is there an easy-enough fix for this? Has there been a little bit of syntactical weirdness that 4.6 has simply been overlooking this whole time? What's wrong, and what's a good solution/work-around?
UPDATE
If worst comes to worst, it does seem to work to partially replace the Vector.<Screen1>
with a Vector.<Function>
, and then just make calls to the members of the function vector, instead of to functions of the members of the Screen1
vector. (This is simplified from production code.) But that's just a fallback.
Also, something I wasn't paying a lot of attention to previously (specifically as far as this one problem goes), but BotMaster kind of brought it to my attention, is that in the process of going from FB 4.6 to FB 4.7, I also went from AIR 3.1 to AIR 3.4.
This is more a scope issue imo. Protected method can only be called within the instance scope and not within a static scope. Of course changing the modifier to public fixes the issue here. PO might argue that protected is wanted here but in reality if there is intention of directly calling a method on an instance outside the scope of that instance then logically that method needs to be public.
Btw FB 4.6 compiler is provided by the used AIR/FLEX SDK and so cannot behave differently from FB 4.7 using the same SDK.