def guessClassmember(self, klass):
return dict([(n.attrib['name'], n) for n in klass.findall('./Stmt/Assign/AssName')])
def calc(self, klass):
classmembers = self.guessClassmember(klass)
for func in klass.findall('./Stmt/Function/'):
if self.isClassMethod(func):
continue
for assattr in func.findall('.//Assign/AssAttr'):
if self.isClassMemberAssign(assattr, classmembers):
print 'defined at', classmembers[assattr.attrib['attrname']].attrib['lineno']
print 'substitute at', assattr.attrib['lineno']
klass.findall('./Stmt/Assign/AssName')]
はクラスノード直下でStmtノードAssignノードAssNameノードのすべてと読むのですが、(つまりクラス変数の代入)のこと。
どーも綺麗にかけない。名前のscopeの関係上必要となるものを全部渡してあげないといけない。継承の処理やimportの関係の処理をちゃんとやると大変。
多分、継承やimport関係はもっといろいろなruleを考えると共通化できて、treeを作ったときにまず最初に処理して使いまわすのが筋だろうね。nodeの受け取る関数とそのnodeを指定するpathの組でやるruleのモデリングが駄目すぎ。もうちょっと考えないとruleの数が増えてくるとfindallの回数が多すぎて耐え難いスピードになるだろう。でも考えるにはruleがそれなりに手に入らないと駄目なんだけどね。
最初はobjectにすることすら避けてruleをmethod + docでやろうかと思ったのだ、それだとruleを増やしていくとクラスが馬鹿でかくなる。Naming Conventionのチェッカーとか。xpathとhandlerの集合を受け取って、最小の回数のvisitで処理をしてほしいのだが。xpathをマージしてhandlerを呼ぶような何かを作るのは自明でないし。
findallの中身は、多分visitをやっているときのstackの中身とxpathのマッチなので、大筋としては{xpath: handler}なものを渡してしまえばよいだろう。
handler同士での相対pathと絶対pathの問題とそのときのデータ共有が解決しないとくさいfor文が消えてくれない。
普通はclass変数を先に書くが、メソッドのあとに書いてもよく、名前がどこで出てくるかはnodeをvisitした瞬間には解決できず、あとでまとめてやらなきゃいけない。handlerをruleが生成して、handlerはruleにreportする、最後にruleが問題を確定させるというような構造にせざるを得ないだろう。もちろん、単にxpathにmatchするnodeをかえされてもどこの何かわからないので、rootからのnode listをもらうほうがうれしいだろう、まあstackのcopyそのものだ。reportされたものをグループ化する仕組みがないとはまりそう。諸所の作業量からして2009年に持ち越しです。まあ、デザインが絞れただけよかったか。
taintみたいなことはしないので、classmemberへの参照から変更をやられるともちろん駄目。そもそもにそんなものはstaticには解決できない。
さて夕飯でもつくるか。
0 件のコメント:
コメントを投稿