斯威夫特のコンパイルエラーの仕组み

そンパイルエラーが出たときに原因を(りたンパイラのソース分析的に)探りたいときがある。その水深1cmまでをまとめてみたい。

これを読む阳离子(水深0.1cm)

手元にSwiftのコードがあること。下の场所から入手できる。私は下载Zip bonタンロードした。

苹果/斯威夫特

swift – Swift编程语言

github.com

エラーメッセージのありか(水深0.3cm)

普段,プログラミンミ中に目にするエラーメッセージの文章は

/ include / swift / AST

の中にある

诊断***。def

という,拡张子がdefのファイルにまとめて书かれている。このファイルは复数あって,***には化化された名前が入る。

以下のものがある。

  • DiagnosticsParse.def
  • DiagnosticsSema.def
  • DiagnosticsClangImporter.def
  • 诊断SIL.def
  • 诊断IRGen.def
  • DiagnosticsFrontend.def
  • DiagnosticsDriver.def
  • DiagnosticsRefactoring.def
  • DiagnosticsCommon.def
  • DiagnosticsAll.def

での中で,DiagnosticsParse.def变成一个を抜粋するとこんな感じである。これは闭じ波括弧が多いというエラーメッセージ。

 错误(extra_rbrace,none, 
“顶级的外部'}'”,()

定义数が多いものは,Swift4.1の时点で

  • DiagnosticsParse.defに500以上
  • S800以上

ある。

***の记事ではこのDiagnostics ***。defを「メッセージ定义ファイル」または「.defファイル」ということにする。

メッセージ定义の形式(水深0.7cm)

メッセージ定义ファイル内の个々の定义は基本的に

 错误(ID,选项,文本,签名) 

の形で行う。

  • ID
    エラーを识别を文字列。エラー発生处理でエラーを指定するのに用いる。
  • 选项
    何か付加情报を入れるようだが何もないことが多い
  • 文本
    コンパイル时に确定する部分は%が付けられている。これはC言语のprintfやObj-CのNSLog方式に似ている。
  • 签名
    Textのメーメッセージの中でコンパイル时に确定する部分の型をタプル形式で与える。文字の中でこれらが入る部分にはあらかじめ%が付けられている。

さっきのメッセージをあらためて见ると

 错误(extra_rbrace,none, 
“顶级的外部'}'”,()

IDがextra_rbrace选项がnone文本が"extraneous '}' at top level” extra_rbrace "extraneous '}' at top level”签名は()でコンパイル时に确定するものは何もない。

メッセージ定义の注意点は3つある。

ひとつは,Textはコンパイル时に决定する情报が抜けているので,表示されたメッセージの文字列を検索を検际する,そこをうまく予测して省いてやること。

もうひとつは,Textの项目は头文字が小文字で书かれていても,Xcodeでメッのージの头文字は大文字で书かれるということ。検索の际に注意が必要。定义されたメッセージの头がsuper .init()のときに,Xcode上の表示はSuper.init()となるのはこれが原因である。

例えばenumのRaw値の型がふさわしくない时のメッセージ本体は

  “%0声明了原始类型%1,但不符合RawRepresentable” 
“并且一致性无法综合”

表示されたメッセージの中からRawRepresentable and conformanceの部分を选択して検索しても引っかからないので注意。

Swiftコード解析处理からエラーを出を处理(水深0.9cm)

Swiftコード解析处理において,エラーが発覚したところで

 诊断(P-> getLoc(),diag :: cannot_infer_type_for_pattern); 

この例では1番目の引数にソースコード上の场所,2番目の引数に,エラー识别の文字列(エラー定义部のID)を与える。

必要的な情报がコンパイル时に决定する场合はそれも引数に追加するので,この关数はいくつかパターンがある。

まとめ(水深1.0cm)

つまり,メッセージの文字をたよりにしてメッセージ定义を见つけ,そのID IDってSwiftってード解析处理の中を検索する,というやり方++行える。そのあとは个々のC ++のソースコードを頑張って解読することになる。