AIR テクノロジープレビューに含まれる新しい ActionScript のコンパイラ ASC 2.0 は、既存のコンパイラと動作が異なります。これは、より AS3 の言語仕様に対する準拠の度合いを高めるための変更であるとのことです。
これまで、言語仕様には合わないものの、たまたまコンパイラが見逃していた、あるいは謝った扱いをしていた、というケースが修正されます。
英語では変更点の一覧表が公開されていますので、ざっと翻訳した物を掲載しておきます。正規の文書ではないので、間違いがあったらご容赦ください。
変更された振る舞い |
従来のコンパイラでの動作 |
ASC 2.0 での動作 |
変更の影響を受ける例 |
'public', 'private', 'protected' がキーワードとして扱われる |
'public', 'private', 'protected' は特定のコンテキストのみで識別子として扱われる。そのため、場所によっては使用可能。 |
'public', 'private', 'protected' はキーワードとして扱われ、その解釈が使われた場所に依存しない。 |
'public' をメンバーとして使用: a.public = "foo"; |
'internal' がキーワードとして扱われる |
'internal' はキーワードではなく、変数名の名前にも利用できる。 |
'internal' はキーワードとして扱われ、識別子として使用するとエラーになる。 |
'internal' を var 宣言で識別子として使用: var internal:String; |
CONFIG ブロックに波括弧が必要 |
CONFIG ブロックを波括弧無しで記述できる: CONFIG::debug |
CONFIG ブロックのコードを波括弧で囲まないとエラーとして扱われる: CONFIG::debug |
CONFIG ブロックを波括弧無しで記述した |
Vector に 1 つだけ型を指定できる |
複数の型を指定しても、余分な指定が無視されるだけ。 |
文法エラーとして扱われる。 |
Vector の宣言に複数の型を指定: var x:Vector.<String, int>; |
'default' が識別子として利用できない |
以下のコードを記述可能: var x = <{default} /> (但しランタイムエラーになる) |
'default' はキーワードとして扱われ、識別子として使用するとエラーになる。 |
XML リテラル内に 'default' を識別子の名前として使用 |
関数の引数とローカル変数の名前が同じ場合には警告される |
関数の引数とローカル変数の名前が同じでも警告されない |
関数の引数とローカル変数の名前が同じ場合には警告される |
以下の様な関数を宣言: function foo(x:int) |
ローカル関数の宣言が重複していると警告される |
ローカル関数の宣言が重複していても警告されない |
ローカル関数の宣言が重複していると警告される |
以下の様な関数を宣言: function foo() |
public:: 修飾子がコンテキストに応じて複数の名前空間に解釈される |
パッケージ内での public:: 宣言は以下のように解釈される: public(package-name) |
パッケージ内での public:: 宣言は以下のように解釈される: public(package-name), unnamed public |
式を public:: で修飾した場合 |
型の名前のローカル変数への使用に対する厳格化 |
型注釈がローカル変数だと判明してもエラー扱いしない場合がある |
型注釈が型以外に使われていたらエラーを発行 |
型と重複するコードを記述: var String:String; |
Package 宣言が最初に必要 |
package 宣言は最初に記述されなければならない |
Package はグローバルスコープに記述 |
package 宣言を他のコードの後に記述した場合 |
定数の評価に関する改善 |
多くての定数がコンパイル時に評価されず、実行時に参照して値を取得する。そのため事前に参照先のクラスの初期化が必要 |
より多くの定数がコンパイル時に評価され、定数への参照は計算済みの値と置き換えられる。そのため、事前に参照先のクラスの初期化を行う必要も無い |
静的な定数を参照している場合、クラスの初期化の順番に依存している場合 |
標準の名前空間をスコープとして持つ場合の警告の一貫性の向上 |
クラスとクラスのメソッドのみ 'public' などの名前空間が無いと警告 |
関数や変数も名前空間に関する警告を発する |
変数を名前空間に関連づけずに宣言 |
ローカル変数を早い段階で確認 |
ローカル変数は見つかった時点で認識され、宣言前に使用された識別子は別扱いされる可能性がある |
全てのローカル変数は識別子を処理する前に確認される |
ローカル変数を宣言前に参照している場合 |
“CONFIG const” の表現が正しく処理される |
“CONFIG const” の初期化式が正しく処理されない場合がある |
初期値を評価する式が他の式と同様のルールで処理される |
“CONFIG const” に式を使用: CONFIG const myConst = 10 || 0; |
メタデータのデバッグ SWF からの削除 |
-keep-as3-metadata オプションで指定してもデバッグ用の SWF からメタデータは削除されない |
メタデータがデバッグ SWF から削除される |
-keep-as3-metadata オプションを使用した場合 |
埋め込みアセット用に生成するクラス数の削減 |
同じアセットタグを参照していても、Embed メタデータごとにクラスが生成される |
アセットタグごとにクラスが生成される |
アセットを埋め込んだ場合 |
配列やオブジェクトのリテラルで始まる文の禁止 |
リテラルで始まる文がエラー無しにコンパイルされる |
リテラルで始まる文はコンパイルエラーとなる |
配列やオブジェクトのリテラルを文頭で使用: [1,2].length |
for ループ内で既存の変数と重複する定数の使用の禁止 |
for ループ内に変数と同名の const 宣言があってもエラーとならずコンパイルされる |
for ループ内に変数と同名の const 宣言があるとコンパイルエラーとなる |
for ループ内で変数と同名の const 宣言をした場合: var x; |
引数と重複するローカル定数宣言の禁止 |
引数と重複するローカル定数宣言があってもエラーとならずコンパイルされる |
引数と重複するローカル定数宣言があるとコンパイルエラーとなる |
引数と重複するローカル定数を宣言した場合: function f(p:*) |
式としての void の使用禁止 |
void が式として使用されていてもエラーとならずコンパイルされる |
void が式として使用されているとコンパイルエラーとなる |
void を型修飾または演算子以外に使用した場合: foo(void) |
with 文内での波括弧無しの関数宣言の禁止 |
with 文内での波括弧無しの関数を宣言してもエラーとならずコンパイルされる |
with 文内での波括弧無しの関数を宣言するとコンパイルエラーとなる |
with 文内で関数を宣言している場合: with(...) function x() {} |
無名関数の式文としての利用の許可 |
無名関数を式文として利用出来ない |
そのままコンパイルできる |
無名関数を宣言して戻り値を変数に代入しない場合 |
複合代入演算子の左辺が一度だけ評価される |
複合代入演算子の左辺が 2 開票化されることがある |
複合代入演算子の左辺は 1 度だけ評価される |
複合代入演算子の左辺に複雑な表現を記述した場合: onlyOnce().a += 1 |
グローバル関数へのメタデータ生成 |
グローバル関数へのメタデータ宣言は処理されない |
グローバル関数用のメタデータが生成される |
グローバル関数の上にメタデータを宣言している場合: [Foo] |
常に static モードとして解釈される |
-strict フラグにより、解釈を切り替えられる |
常に -strict フラグがオンの状態 |
コンパイルと実行に異なるライブラリを使用している場合 |
異なる名前空間に対する同名の関数定義の許可 |
名前空間が異なっても同名の関数が宣言されるとコンパイルエラーになる |
名前空間が異なれば同名の関数が宣言できる |
同名の関数を複数宣言した場合: public class Foo {} |
全ての重複したな定義を報告 |
2 つ目以降の重複の存在のみが報告される |
重複している全ての定義が報告される |
同じ名前で複数の宣言をした場合 |
const と var の重複の禁止 |
const と var の定義が重複すると、const は var で上書きされ、エラーにならない |
const と var の定義が重複するとコンパイルエラーとなる |
const と var が同じ名前で宣言された場合: var foo; |
定数のインクリメントとデクリメントの禁止 |
定数をインクリメントする記述があってもコンパイルエラーにならない |
定数をインクリメントする式があるとコンパイルエラーとなる |
定数をインクリメントする場合: const i; |
import 文からのパッケージスコープの扱いの厳密化 |
import p.C の記述で p が import 文のスコープ外でもパッケージとして扱われる |
import p.C の記述で p は import 文のスコープ内だけでパッケージとして扱われる |
import 文無しで型の完全修飾名を使用している場合 |
ソースへのパスに重複した名前の使用の禁止 |
ソースパスに同じ名前のファイルが存在してもコンパイルエラーにならず、実行時に参照が行われた時点でエラーになる |
同じ名前のファイルが存在するとコンパイルエラーとなる |
ソースパスに同名のファイルが存在する場合: src/X.mxml, src/X.as |
名前のついた関数の再定義の禁止 |
名前付きの関数に別の値を定義することが出来る |
名前付きの関数に別の値を定義するとコンパイルエラーとなる |
名前付きの関数を再定義している場合 |
実行時に評価が必要なメタデータの禁止 |
実行時の評価が必要な式の含まれるメタデータはコンパイル時に無視される |
実行時に評価の必要な表現を含むメタデータはコンパイルエラーとなる |
実行時の評価が必要なメタデータを記述した場合 |
不正な Vector への代入の禁止 |
型の異なる Vector 間の代入はコンパイルエラーとならず、実行時にエラーとなる |
型の異なる Vector 間の代入がコンパイルエラーとなる |
或る Vector 型を他の Vector 型に代入した場合: Vector.<int> から Vector.<uint> |
null への除算を許可 |
null を何らかの値で割る記述はコンパイルエラーとなる |
null への除算はコンパイルエラーとならない |
null を何かの値で割る場合: x = null / 2; |
if/esle 文による反復の存在を検知 |
反復する記述が存在しても無視される |
反復する記述が報告される |
以下の様なコードを記述した場合: function f():int |
try, catch, finally 内のクラス定義の禁止 |
パッケージレベルやファイルレベルの try - finally ブロック内に定義可能 |
コンパイルエラーになる |
クラスを try, catch, finally ブロック内に定義する場合 |
条件式での代入に対する警告 |
if 文に直接代入式が使われたとき飲み警告する |
数値計算や比較演算を除き、条件式内の代入の使用に対して警告する |
条件として代入式が使用された場合: while (x = 3) |
import 文による重複したクラス名の検知 |
パッケージが定義スコープであるかのようにクラス名を参照する |
import 文により他のパッケ ージ内への重複した参照が発生したことを検知する |
同名のクラスを別パッケージに宣言して import した場合: package P1 package P2 |
ローカル定数が定義されるタイミングで初期化される |
定数は宣言された行が実行されるタイミングで初期化される |
定数は定義が認識された時点で初期化される |
定義前に定数を使用している場合: function test() |
'goto' がキーワードとして扱われる |
'goto' をクラス名や変数名に使用可能 |
'goto' はキーワードとして扱われる |
'goto' を名前として使用している場合 |
バインドされないメタデータの警告 |
定義のすぐ上に無いメタデータは単純に無視 |
定義のすぐ上に無いメタデータは無視するが警告を表示 |
メタデータを記述した場合 |
コメントする