Name of class conflicts with loaded class
by ericlin


Have you ever met this mysterious error message like this:

**Error** Test.as: Line 2: The name of this class, 'Test', conflicts with the name of another class that was loaded, 'Test'.

class Test {

It is mysterious. It appears unexpectedly and may disappear unexpectedly before you even touch the code.

People know that it occurs when we refer classes "circularly". ClassA accesses ClassB and ClassB accesses back ClassA. Some have successful experience that just manipulating the aso file (the cache of AS class file) may fix the problems.

You may argue that, you have only one single file defining the Test class. What is "another class that was loaded ?"

Think about that, when you check syntax, there are two versions of "Test" class. One is the Test class you are editing and checking syntax of. The other is the class which import from the saved "file". The file in the disk gets loaded to create corresponding aso file if we try to import that class. The script details of these two versions (the one under editing and the one saved in file) may be different if you modified it but not yet saved.

Now, lets check the error message deeper.


Welcome the error message

Before everything, try it yourself. Create a class file, save it as Test.as. Dont argue about the silliness of the script. It is just a demo.

import Test;
class Test{}

Now, check syntax. That mysterious error message pops up. 

Check syntax" again, it compiles well without that error messages. 

Click "save" and check syntax. Well, we have that error message back again.


What is aso file ? 

As you guess, this does have something to do with the aso file.

Any property in AS2 class file must be declared first, so that compiler knows it is "static property", or "instance property" or "no such property".

Let's check this example:

import dir.*;
class ClassA extends ClassB {
   
function show(){
   
     trace(Blah.v);
   
}
}

What is "Blah.v" ? How will compiler translate that "Blah.v"?

Blah may be a class and v is the static property of that class.

Flash tries to search a file named as "Blah.as". It search through all the class path and all the import. If found, it will check the validity of Blah.as and check whether there exists a static propety named as "v". If it succeeds, the script will be translated into "trace(dir.Blah.v);";

Or, Blah may be a property inherited from super-class ClassB.

Along the inheritance chain, Flash tries to check the validity of the super-class and check whether there is a property named as "v"; If it succeeds, the script is translated into "ClassB.Blah.v" if "Blah" is static property, or into "this.Blah.v" if "Blah" is an instance property. If the inheritance chain is long, the job is very hard. It gets to search the super-super of ClassB.

If there is no match, it reports "no such property".

Before it reports "no such properties", the compiler must load every class that gets imported in or extends from. Those classes get loaded, validity checked and all existing properties are parsed out. In other word, Flash load that class file and does a job similar to parital compilation. It is not an easy job.

It is silly to repeat the same job, re-load those imported class files and re-check the validity from the begining each time we "check syntax".  Except the class we are currently editing, the result of those classes can be saved in a cache, so that Flash can check the casche instead of re-do from the beginning. That casche is the aso file. It would be handy to use those aso file than re-compiling.

The aso file has the same name as the class file. It is created at the subdirectory of mx.aso;


Rule of loading for creation of aso file

If there is any specified classes get imported, it finds that coresponding as file by "filename". It tries to compile and create corresponding aso files for those imported classes , if there is no corresponding aso file or the time-stamp of the aso file is older than the as file.

Please note that, if we use wide card in importing, such as "import dir.*", it skips that line. It will not compile and create aso files for "all" class files in that subdirectory. It will wait later to see which sepcified files are really needed.

Also note that, if the time-stamp of corresponding aso file is newer than the as file, then it does not re-create the aso file again. That aso file is used directly. A click for "save" will always make as file newer than aso file and surely compiler will re-create aso file. Modifying "current" file will also invalidate the aso file.

If our class extends some superClass, the rules are applied for all class files in the inheritance chain.

If obviously, we are accessing some static properties of imported class, then an aso file will be created for that imported class.


The simple example

Now lets go back to our example Test.as:

import Test;
class Test{}

When checking syntax, it meets "import" with specified class name "Test". It search for a file as "Test.as" and load the file up to create corresponding "Test.aso".

Please note that, the aso file is compiled from loading the saved file. It is the "saved version". The content may be different from what you see on the "editor", the "current editing version" of the Test.as. So, the attempts to create the Test.aso results in a warning that there is confliction between this class name and the loaded class.

Anyway, this is just a warning not a fetal error such as "no such property". The Test.aso is still created by loading the file.

Next time we check syntax, it meets the import, it tries the same task. However, there is already the Test.aso which is newer than the saved file. So, it wont bother to load the file to check validity and parsing. It will use the aso file if necessary.  No warning or error messages gets popup.

If we click "save", then the time-stamp of the saved Text.as is newer than that of Test.aso. Syntax checking will try to update the Test.aso. Thus, the file is re-loaded  and the error messages gets pop up.


Circular reference of Classes

I want to implement a system similar to radiobuttons with radioButtonGroup.  Class Radio has a method: setGroup(gr:RadioGroup); While Class RadioGroup has a method: addElement(r:Radio); 

file Radio.as

class Radio {
    function setGroup(gr:RadioGroup) {}
}

file RadioGroup.as

class RadioGroup {
    function addElement(r:Radio) {}
}

You see, we have a problem about circular reference. Class Radio needs to import Class RadioGroup and Class RadioGroup needs to import Class Radio; On checking syntax, the confliction error messages repeatedly pops up.

How to solve this ?

There are options.

1. import needed class in the first line. The error messages pops up once and then disappear. For example:

import RadioGroup;
class Radio {
    function setGroup(gr:RadioGroup) { }
}

¡@

2. We may try to open a new ActionScript file or a new Flash document fla to import one of those class. Just type:

import Radio;

Check syntax, it shows no error. Go back to our Radio class or RadioGroup class. No error messages now when we check syntax.

We dont need to save that new action script file. 

The trick is that, because checking the syntax of that new script, either Radio class nor RadioGroup class is under editing, the loading will not conflicts with "this class". Those aso files will be created successfully for later usages. 


Summary notes:

Confliction error is a warning that we are importing a class that is currently under editing. It is not necessarily a fetal error. However, under such error messages, other syntax error messages might not be correctly reported.

If corresponding aso file is created successfully, the loading of class file will be omited during import. The aso file is used directly. Thus, there will be no "another class that was loaded". Thus, there will be no confliction.

If we import that class from other ActionScript files or Flash documents, then the class file is loaded and aso file will be created without conflict with "the name of this class". (In such condition, there is no "the name of this class"). This is a way to solve the confliction when we are handling "circular reference".

Once we modify or save the class file, the corresponding aso file is treated as "out-of-date". Flash will try to load the class file and re-create the aso file. Everything is back to the beginning again. 

If we get that message, the source of error is the class currently under editing. Do not waste time to search other subdirectory for "another file" with the same name. That is not what the error message means.

If we get error once but no error on second syntax check, do not feel paranoid. It is all right. Do not waste time to try to find back the error message for kill on alive.

Deleting the aso files in mx/aso subdirectory might not kill the error message. In contrary, deleting the aso files may make that error messages re-appear.


ericlin@ms1.hinet.net