Tutorials, extensions, and source files for ActionScript, Flash, and other Adobe products.

 

Flash Player Compiler Errors and How to Fix Them

The following lists common compiler errors found with Flash Player and what you can do to fix them. Also available, Runtime Errors.

Compiler Error #1047

1047: Parameter initializer unknown or is not a compile-time constant.

This compiler error revolves around ASC's (ActionScript Compiler) inability to resolve variable references for default parameter values in parameter lists for functions. Example:

public function foo(bar:int = SomeClass.CONSTANT_VALUE):void {
	...
}

In the above example, SomeClass.CONSTANT_VALUE is the parameter initializer (default parameter value). In general, variables are not allowed in parameter lists. Instead, only primitive literals including numbers, strings, booleans, and null/undefined should be used. But exceptions are made as long as they satisfy the following conditions (valid as of Flash 10 version timeframe):

  • The variables are constants, defined with the const keyword
  • ASC has previous knowledge of the constant

The second point is the more important of the two. This can lead to situations where the above example may work sometimes and may not work, producing a 1047 error, others. Situations where it will consistently work include:

  • Use of constants defined in the same class
  • Use of constants native to Flash Player's ActionScript API (e.g. flash.events::Event.COMPLETE)

These values are known to exist by the time ASC is comiling the parameter list. Inconsistently working situaitons include:

  • Use of constants defined in classes other than the one specifying the parameter list

When a constant is coming from another class, depending on the order in which ASC compiles the classes, the parameter value may not yet be known. If that is the case, a 1047 error will occur.

Compiling with ASC directly gives you control over the order of the classes being compiled. When compiling a SWF with something like Adobe Flash Professional, that tool controls the order, sending it to ASC in the background. Logic dictates this order - logic heavily dependant on a dependency analysis of the classes that are to be compiled. This analysis determines what classes are required to be compiled before others. This is done for namespace definitions as well for class inheritance, where superclass definitions need to exist before their subclasses.

Flash's dependency analysis does not include default parameter initializers. However, even if it did, you would have situations where it wouldn't work because you could potentially have two classes which use each others' constants in their own parameter lists. How can each class be compiled before the other? Given the current implementation of ASC, there is no solution for kinds of circular references.

Workaround

Something you can do as a workaround for default parameter intializers is use Flash's dependency analysis for inheritance to help influence compile order. This will allow your classes with constant definitions to be used parameter inializers to be compiled before the classes that use them. This method revolves around the fact that classes subclassing other classes (other than the already core base class of Object) tend to be compiled after classes that don't. By keeping enum-style classes with your constants - final, static classes which contain only constant values, and making sure any custom classes you have that use those values for default parameter initializers extend some other class, you can pretty much guarantee that the constants will be available to your functional classes when needed for the parameter lists. Example:

package {
	public final class Constants {
		public const CONSTANT:int = 1;
	}
}
package {
	
	import flash.utils.Dictionary;
	
	// without extending Dictionary, you get a #1047 Error
	public class UsesCompileTimeConstants extends Dictionary {
		public function UsesCompileTimeConstants(param:int = Constants.CONSTANT){
			super();
		}
	}
}

Because the UsesCompileTimeConstants class extends Dictionary (a pretty generic class if you have nothing else to extend), it will be compiled after the Constants class.*

*Note: I have used this successfully on a small number of projects, though I don't know how reliable it is.

Compiler Error #1061

1119: Access of possibly undefined method [method] through a reference with static type [Type].

This error is a compiler error - an error that occurs when publishing or testing a SWF, not running it - that relates to method access of an object instance with respect to it's type. This means that code is attempting to call a function of an object which is not recognized by that object's type. The object may, in fact, have the function, but if the reference is not part of that object's type definition, this error would occur as the compiler assumes that you're using an object in a manner that is not expected. For more information, see Compiler Error #1119.

Compiler Error #1119

1119: Access of possibly undefined property [property] through a reference with static type [Type].

This error is a compiler error - an error that occurs when publishing or testing a SWF, not running it - that relates to property access of an object instance with respect to it's type. This means that code is attempting to access a property of an object which is not recognized by that object's type. The object may, in fact, have the property, but if the reference is not part of that object's type definition, this error would occur as the compiler assumes that you're using an object in a manner that is not expected.

One of the purposes of associating types with variables is that it can help identify errors during development. Compilers use types to essentially build a map of the properties and methods that can be used on each variable reference. If a variable is used in a way that does not match that mapping, an error occurs. For example, if you create a variable of the type Sprite, a compiler will know that, when using the variable, it should only be used with properties and methods that are part of the Sprite class.

var mySprite:Sprite = new Sprite();
mySprite.foo = "bar"; // Compiler Error #1119

In the example above, type checking correctly identified an incorrect usage of a sprite instance where an attempt was made to set the property foo to the value "bar" when foo is not a valid property of the Sprite class. If the compiler allowed this, it would have resulted in a Error #1056 during runtime.

Type error checking, in general, is a very good thing to have. If this occurs, it's likely you're using an object the wrong way and will be informed to fix it before your code even has a chance to run. But there is a circumstance in which it fails to work properly. In programming, subtype polymorphism dictates that a variable of any given type is allowed to reference a value of that type or any of it's subtypes. In other words, a Sprite variable can reference a Sprite object, or an object that is an instance of any subclass of Sprite, such as MovieClip. Because subclasses are based on the original class, all of the original class's members (properties and methods) would still exist within a subclass value, meaning a type would still be correct in it's interpretation of it's referenced value's members - at least up to a point. It knows of those members defined by it's type (e.g. Sprite) but not those of the subclass (e.g. MovieClip). This becomes a problem if you attempt to access properties of the subtype that do not exist in the original type - the type defined for the variable.

var mySprite:Sprite = new MovieClip(); // allowed
mySprite.trackAsMenu = true; // Error #1119

Even though, as it references a MovieClip instance, the mySprite variable has a trackAsMenu property, the compiler still warns of a "possibly undefined property". Even the error knows that it might be wrong, but it is still there to make sure you know what you're doing since you're using a variable in a way that does not match the type you gave it.

To handle situations where you have a variable with a non-specific type that should be able to access a member value not associated with that type, you have a couple of options:

  1. Turn strict mode off. Your compiler should allow turning off strict mode - the compiler setting that informs you of these possible errors. It is not suggested that you do that, so I won't tell you how, but know that it's an option.
  2. Store the value in an untyped (*) variable. If you create a new, untyped variable and set it's value to the value of your variable, you can use the new variable to access your values. Since there is no type, no type checking will occur and every member of your specific value type will be accessible without error.
    var mySprite:Sprite = new MovieClip();
    var myGenericValue:* = mySprite;
    myGenericValue.trackAsMenu = true; // OK
  3. Cast the variable to it's correct, more specific type (recommended). Probably the best thing you can do is re-associate the value with a correct variable type. You can do this by casting with a cast function or the as operator. This can be done inline as the variable is being used, or saved to a new variable as with the previous example. Cast functions:
    var mySprite:Sprite = new MovieClip();
    	
    // new variable
    var myMovieClip:MovieClip = MovieClip(mySprite);
    myMovieClip.trackAsMenu = true; // OK
    
    // inline
    MovieClip(mySprite).trackAsMenu = true; // OK
    Using a cast function (in the form of Type(value) - which is not exactly a function; it's the form that is function-like), if the cast fails an error will be thrown. If you are unsure as to whether or not the variable actually contains a reference to the type to which you're casting it, you will want to wrap your cast in a try-catch block.

    Using the as operator:
    var mySprite:Sprite = new MovieClip();
    	
    // new variable
    var myMovieClip:MovieClip = mySprite as MovieClip;
    myMovieClip.trackAsMenu = true; // OK
    
    // inline
    (mySprite as MovieClip).trackAsMenu = true; // OK
    When the as operator fails, instead of returning an error, it returns null. You may need to check for a null value if you're as unsure as to whether or not the variable actually contains a reference to the type to which you're casting it.
  4. Cast the variable to a dynamic type. Classes defined as "dynamic" also are not subject to type checking. These classes include Object (of which all other classes are based), MovieClip, and a few others. If casting to a dynamic type, assuming the value is that type, type errors can also be avoided. You may have noticed that in the previous example, casts were made to MovieClip which, because MovieClip is dynamic, allows type checking to be skipped.