Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id B9F65200B53 for ; Tue, 12 Jul 2016 17:26:54 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id B886D160A56; Tue, 12 Jul 2016 15:26:54 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id AE652160A53 for ; Tue, 12 Jul 2016 17:26:53 +0200 (CEST) Received: (qmail 187 invoked by uid 500); 12 Jul 2016 15:26:47 -0000 Mailing-List: contact users-help@groovy.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: users@groovy.apache.org Delivered-To: mailing list users@groovy.apache.org Received: (qmail 177 invoked by uid 99); 12 Jul 2016 15:26:47 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 12 Jul 2016 15:26:47 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id 6A456C0B66 for ; Tue, 12 Jul 2016 15:26:47 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 0.299 X-Spam-Level: X-Spam-Status: No, score=0.299 tagged_above=-999 required=6.31 tests=[KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001] autolearn=disabled Received: from mx1-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id 0gCmKQB_hON5 for ; Tue, 12 Jul 2016 15:26:42 +0000 (UTC) Received: from smtp.czechia.com (smtp2.czechia.com [217.198.120.48]) by mx1-lw-eu.apache.org (ASF Mail Server at mx1-lw-eu.apache.org) with ESMTPS id 3B02960D10 for ; Tue, 12 Jul 2016 15:26:42 +0000 (UTC) Received: from [10.0.0.123] (31.4.broadband2.iol.cz [83.208.4.31]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) (Authenticated sender: ocs@ocs.cz) by smtp.czechia.com (Postfix) with ESMTPSA id 8C8D48462F43; Tue, 12 Jul 2016 17:26:35 +0200 (CEST) Content-Type: multipart/mixed; boundary="Apple-Mail=_11CFD8F1-AFFF-4DC2-9322-945177DF524A" Mime-Version: 1.0 (Mac OS X Mail 6.6 \(1510\)) Subject: Re: looks like a missing exception harness in a typechecker somewhere? From: OC In-Reply-To: <5784C9D6.7010201@gmx.org> Date: Tue, 12 Jul 2016 17:26:35 +0200 Message-Id: <56E1E0CD-74CC-4BB5-9C81-8A68F25331AE@ocs.cz> References: <5784C9D6.7010201@gmx.org> To: users@groovy.apache.org X-Mailer: Apple Mail (2.1510) archived-at: Tue, 12 Jul 2016 15:26:54 -0000 --Apple-Mail=_11CFD8F1-AFFF-4DC2-9322-945177DF524A Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=windows-1252 Jochen, On 12. 7. 2016, at 12:43, Jochen Theodorou wrote: > On 11.07.2016 23:26, OC wrote: >> Hi there, >>=20 >> with a pretty complex and heavily AST-transformed code, which, = nevertheless, *without typechecking builds and runs all right*, with a = typechecker compilation crashes in the following way (Groovy 2.4.7). >>=20 >> The problem might well be caused by a mistake in my own typechecking = extension script (which, essentially, turns all typechecker errors to = warnings); still, though, I think the compiler should not crash this way = (instead, it might report a reasonable error): >=20 > the reasonable error would have been crashing with a BUG exception = once you did set the genericstypes of that ClassNode to null? I do not think I did that. Definitely the only genericstypes-related = thing in my whole project is one line in my typechecking script, which = makes sure the first of genericstypes is used instead of the classnode = itself for lookups, namely, =3D=3D=3D def lookupMethods(ClassNode cln,String name,argtypes=3D[]) { if (cln=3D=3DclassNodeFor(Class) && cln.isUsingGenerics() && = cln.genericsTypes) cln=3Dcln.genericsTypes[0].type // ugh... got the = code from C=E9dric! ... ... ... =3D=3D=3D Note that the only things which changes is the local variable cln in = there. For reference, the complete typechecking script (not too = intelligible, I am afraid; but short enough, unlike all those ASTTs etc) = is attached at the end of this message. Thanks and all the best, OC --Apple-Mail=_11CFD8F1-AFFF-4DC2-9322-945177DF524A Content-Disposition: attachment; filename=TypeChecker.groovy Content-Type: application/octet-stream; name="TypeChecker.groovy" Content-Transfer-Encoding: quoted-printable //=20note=20that=20this=20script=20is=20handled=20in=20a=20quite=20= specific=20way:=20instead=20of=20being=20built,=20it=20is=20embedded=20= into=20the=20JAR=0A//=20see=20also=20DefaultImportsAST=20which=20= triggers=20its=20usage=20(it=20is=20very=20simple,=20not=20worth=20a=20= specific=20ASTT)=0A//=20for=20details=20of=20the=20contents,=20see=20= http://docs.codehaus.org/display/GROOVY/Type+checking+extensions=0A=0A= import=20org.apache.log4j.*=0Aimport=20groovy.util.logging.*=0Aimport=20= cz.ocs.*=0Aimport=20cz.ocs.ast.*=0Aimport=20static=20cz.ocs.Static.*=0A=0A= import=20org.codehaus.groovy.ast.*=0Aimport=20= org.codehaus.groovy.ast.stmt.*=0Aimport=20org.codehaus.groovy.control.*=0A= import=20org.codehaus.groovy.control.messages.*=0Aimport=20= org.codehaus.groovy.transform.stc.*=0A//import=20= org.objectweb.asm.Opcodes=20//=20brings=20nasty=20dependencies=20to=20= classpath.=20See=20details=20in=20cz.ocs.Static=0A=0Aimport=20= org.codehaus.groovy.syntax.*=0A=0Adef=20= log=3DLogger.getLogger('cz.ocs.ast.TypeChecker')=0A=0Asetup=20{=0A=20=20=20= =20def=20su=3DtypeCheckingVisitor.sourceUnit=0A=20=20=20=20= AST_A.recordCU(su)=0A=20=20=20=20AST_A.incrementProcessedFiles(su)=0A=20=20= =20=20log.info=20"=3D=3D=3D=20TypeChecker=20visits=20source=20'$su.name'=20= ($su.phaseDescription)=20cu=20${AST_A.cuId(su)}=20=3D=3D=3D"=0A=20=20=20=20= =0A=20=20=20=20try=20{=0A=20=20=20=20=20=20=20=20= context.pushErrorCollector()=0A=20=20=20=20}=20catch=20(e)=20{=0A=20=20=20= =20=20=20=20=20log.error=20"###=20error=20pushing=20EC:=20${e?.message}"=0A= =20=20=20=20}=0A}=0A=0Afinish=20{=0A=20=20=20=20try=20{=0A=20=20=20=20=20= =20=20=20def=20= ec=3Dcontext.popErrorCollector(),currec=3Dcontext.errorCollector=0A=20=20= =20=20=20=20=20=20if=20(ec.errors)=20{=0A=20=20=20=20=20=20=20=20=20=20=20= =20def=20su=3DtypeCheckingVisitor.sourceUnit=0A=20=20=20=20=20=20=20=20=20= =20=20=20log.debug=20"=3D=3D=3D=20TypeChecker:=20${ec.errors?.size()}=20= errors=20in=20${su.name}=20=3D=3D=3D"=0A=20=20=20=20=20=20=20=20=20=20=20= =20def=20wr=3Dnull=0A=20=20=20=20=20=20=20=20=20=20=20=20ec.errors.each=20= {=20//=20note:=20println=20->=20we=20are=20targeting=20Xcode=20directly,=20= not=20logger!=20For=20the=20!XCG.ocs.cz!=20see=20tools/foltergroovyc=0A=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20switch=20(it)=20{=0A=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20case=20= LocatedMessage:=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20= AST_A.addAndLogWarning(this,log,su,it.context.startLine,it.context.startCo= lumn,it.message)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20break=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20case=20SyntaxErrorMessage:=0A=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20def=20msg=3Dit.cause.message=0A=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20if=20= (msg.startsWith('[Static=20type=20checking]=20-=20'))=20= msg=3Dmsg.substring(25)=0A=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20def=20gulp=3D{=20log.debug=20"SWALLOWING:=20= ${msg.split(/\.?\n=20@=20line=20/)[0]}"=20;=20null=20}=0A=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20//=20these=20cases=20= should=20be=20consistently=20eaten=20up=0A=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20if=20(msg.startsWith('Cannot=20= return=20value=20of=20type=20java.lang.Object=20on=20method=20returning=20= type=20'))=20return=20gulp()=20//=20not=20yet=20supported,=20JIRA=206044=0A= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= if=20(msg.startsWith('Cannot=20return=20value=20of=20type=20= java.lang.Number=20on=20method=20returning=20type=20int'))=20return=20= gulp()=20//=20same=20problem=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20if=20(msg.startsWith('A=20closure=20shared=20= variable=20['))=20return=20gulp()//=20no=20JIRA=20for=20this,=20should=20= I=20raise=20one?=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20if=20(msg.startsWith('Reference=20to=20method=20is=20= ambiguous.=20Cannot=20choose=20between=20'))=20return=20gulp()//=20= timestamp=3D=3D,=20will=20be=20handled=20in=202.2=0A=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20if=20= (msg.startsWith('Multiple=20assignments=20without=20list=20expressions=20= on=20the=20right=20hand=20side=20are=20unsupported=20in=20static=20type=20= checking=20mode'))=20return=20gulp()=0A=0A=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20//TODO:=20these=20actually=20should=20NOT=20= happen,=20but=20at=20the=20moment=20I=20haven't=20time=20to=20fix=20them=20= properly:=20later...=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20if=20(msg.startsWith('Spread=20operator=20can=20only=20be=20= used=20on=20collection'))=20return=20gulp()=20//=20wtf?!?=20does=20not=20= make=20sense?=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20if=20(msg.startsWith('No=20such=20property:=20super=20for=20class:=20= java.lang.Object'))=20return=20gulp()=20//=20wtf?!?=20does=20not=20make=20= sense?=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20if=20= (msg.startsWith('Non=20static=20method=20')=20&&=20msg.contains('cannot=20= be=20called=20from=20static=20context'))=20return=20gulp()=20//=20ditto=0A= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=0A= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= //=20TEMPORARY=20--=20should=20get=20solved=20when=20I=20have=20the=20= all-classes=20list=20from=20Nazaret=0A//=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20if=20(msg.startsWith('Cannot=20= find=20matching=20method=20java.lang.Object#'))=20return=20gulp()=0A//=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20if=20= (msg.startsWith('Cannot=20find=20matching=20method=20java.lang.Class#'))=20= return=20gulp()=0A//=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20if=20(msg.startsWith('Cannot=20find=20matching=20= method=20java.util.Collection#'))=20return=20gulp()=20//=20as=20above=20= with=20find{}=20or=20type=20inference=0A//=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20if=20(msg.startsWith('Cannot=20= find=20matching=20method=20void#'))=20return=20gulp()=20//=20happens=20= if=20called=20of=20something=20not=20found=20before=0A//=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20if=20= (msg.startsWith('Cannot=20assign=20value=20of=20type=20')=20&&=20= msg.contains('=20to=20variable=20of=20type=20void'))=20return=20gulp()=20= //=20similar=20case=0A//=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20if=20(msg.startsWith('No=20such=20property:=20')=20= &&=20msg.contains('=20for=20class:=20java.lang.Object'))=20return=20= gulp()=0A//=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20if=20(msg.startsWith('No=20such=20property:=20')=20&&=20= msg.contains('=20for=20class:=20void'))=20return=20gulp()=20//=20as=20= above=0A//=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20if=20(msg.startsWith('No=20such=20property:=20')=20&&=20= msg.contains('=20for=20class:=20java.util.Collection'))=20return=20= gulp()=20//=20eg.after=20find{}.XXX=0A=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20//TODO:=20some=20warnings=20marked=20//WTF=20!=0A=0A=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= AST_A.addAndLogWarning(this,log,su,it.cause.startLine,it.cause.startColumn= ,msg.split(/\.?\n=20@=20line=20/)[0])=0A=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20break=0A=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20default:=0A=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20log.error=20"###=20Unknown=20= error=20message=20[${it.getClass()}],=20logged=20out=20to=20console..."=0A= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= if=20(!wr)=20wr=3Dnew=20PrintWriter(System.out)=0A=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20it.write(wr)=0A=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20wr.flush()=0A= =20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20}=0A=20=20=20=20=20=20=20= =20=20=20=20=20}=0A=20=20=20=20=20=20=20=20=20=20=20=20//log.debug=20= "=3D=3D=3D=20TypeChecker:=20shown=20all=20${ec.errors?.size()}=20errors=20= in=20${typeCheckingVisitor.sourceUnit.name}=20=3D=3D=3D"=0A=20=20=20=20=20= =20=20=20}=0A=20=20=20=20}=20catch=20(e)=20{=0A=20=20=20=20=20=20=20=20= log.error=20"###=20error=20popping=20EC:=20${e?.message}"=0A=20=20=20=20= }=0A}=0A=0Adef=20ocs_lookupClassNodeFor(String=20cname)=20{=0A=20=20=20=20= //println=20"///=20class=20'$cname'..."=0A=20=20=20=20def=20= found=3DlookupClassNodeFor(cname)=0A=20=20=20=20if=20(found)=20return=20= found=0A=20=20=20=20if=20= ((found=3DtypeCheckingVisitor.sourceUnit.ast.unit.getClass(cname)))=20= return=20found=0A=20=20=20=20try=20{=0A=20=20=20=20=20=20=20=20def=20= cl=3DClass.forName(cname,false,getClass().classLoader)=0A=20=20=20=20=20=20= =20=20//println=20"loaded=20$cl"=0A=20=20=20=20=20=20=20=20return=20= ClassHelper.make(cl)=0A=20=20=20=20}=20catch=20(exc)=20{=0A=20=20=20=20=20= =20=20=20println=20"oops:=20$ext.message"=0A=20=20=20=20}=0A=20=20=20=20= println=20"...=20wtf=20did=20not=20find=20class=20node=20for=20'$cname'"=0A= =20=20=20=20null=0A}=0A=0Adef=20info(ast)=20{=0A=20=20=20=20def=20= fn=3DtypeCheckingVisitor.sourceUnit.name=0A=20=20=20=20def=20= slash=3Dfn.lastIndexOf('/')=0A=20=20=20=20if=20(slash>0)=20= fn=3Dfn.substring(slash+1)=0A=20=20=20=20"IN=20= $fn:$ast.lineNumber:$ast.columnNumber"=0A}=0A//static=20private=20final=20= def=20VARARGS=3D10000=0A=20def=20prettyType(tnm,boolean=20= keepPackage=3Dfalse)=20{=0A=20=20=20=20if=20(tnm.startsWith('['))=20= return=20prettyType(tnm.substring(1))+'[]'=0A=20=20=20=20if=20= (tnm.startsWith('L')=20&&=20tnm.endsWith(';'))=20return=20= prettyType(tnm.substring(1,tnm.length()-1))=0A=20=20=20=20switch=20(tnm)=20= {=0A=20=20=20=20=20=20=20=20case=20'B':=20tnm=3D'byte';=20break=0A=20=20=20= =20=20=20=20=20case=20'C':=20tnm=3D'char';=20break=0A=20=20=20=20=20=20=20= =20case=20'D':=20tnm=3D'double';=20break=0A=20=20=20=20=20=20=20=20case=20= 'F':=20tnm=3D'float';=20break=0A=20=20=20=20=20=20=20=20case=20'I':=20= tnm=3D'int';=20break=0A=20=20=20=20=20=20=20=20case=20'J':=20tnm=3D'long';= =20break=0A=20=20=20=20=20=20=20=20case=20'S':=20tnm=3D'short';=20break=0A= =20=20=20=20=20=20=20=20case=20'Z':=20tnm=3D'boolean';=20break=0A=20=20=20= =20}=0A=20=20=20=20if=20(keepPackage)=20return=20tnm=0A=20=20=20=20= tnm.split('\\.').last()=0A}=0Adef=20prettyTypeWithPackage(tnm)=20{=0A=20=20= =20=20prettyType(tnm,true)=0A}=0A=20def=20= prettyField(owner,name,mods,type)=20{=0A=20=20=20=20= "${mods&ACC_STATIC?'+':'-'}${prettyType(type)}=20= ${prettyType(owner)}.$name"=0A}=0A=20def=20= prettyMethod(owner,name,mods,type,args)=20{=0A=20=20=20=20= "${prettyField(owner,name,mods,type)}(${args.collect{prettyType(it)}.join(= ',=20')}${mods&ACC_VARARGS?',=20...':''})"=0A}=0Adef=20= lookupMethods(ClassNode=20cln,String=20name,argtypes=3D[])=20{=0A=20=20=20= =20if=20(!name)=20return=20nil=20//TODO:=20probably=20should=20not=20= happen,=20sometimes=20does=20->=20no=20time=20now=20to=20solve,=20later!=0A= =20=20=20=20=0A=20=20=20=20=0A=20=20=20=20if=20(cln=3D=3DclassNodeFor(Clas= s)=20&&=20cln.isUsingGenerics()=20&&=20cln.genericsTypes)=20= cln=3Dcln.genericsTypes[0].type=20//=20ugh...=20got=20the=20code=20from=20= C=C3=A9dric!=0A=20=20=20=20=0A=20=20=20=20def=20mm/*,checkArgs=3D{=20= method=20->=0A=20=20=20=20=20=20=20=20//TODO:=20better=20checker=20--=20= at=20this=20moment,=20only=20#=20of=20arguments=20checked=0A=20=20=20=20= }*/=0A=20=20=20=20if=20= ((mm=3DtypeCheckingVisitor.findMethodsWithGenerated(cln,name)/*.findAll(ch= eckArgs)*/))=20return=20mm=0A=20=20=20=20if=20= ((mm=3DStaticTypeCheckingSupport.findDGMMethodsForClassNode(cln,name)))=20= return=20mm=0A=20=20=20=20=0A=20=20=20=20//println=20">>>>>=20failed=20= to=20find=20a=20method=20for=20'$name'=20in=20'$cln.text':"=0A=20=20=20=20= =0A=20=20=20=20def=20getter=3D"get${name.capitalize()}"=20//TODO:=20= should=20happen=20for=20properties=20only!=20Have=20to=20use=20= arguments....=0A=20=20=20=20//=20hmmmm.=20Since=20typechecker=20don't=20= see=20the=20inside=20extensions,=20I=20have=20to=20check=20fro=20getFoo=20= explicitly.=20And=20what=20about=20setFoo?!?=20Will=20have=20to=20test!=0A= =20=20=20=20=0A=20=20=20=20def=20= ext=3DAST_A.instanceExtensions(typeCheckingVisitor.sourceUnit),sext=3DAST_= A.staticExtensions(typeCheckingVisitor.sourceUnit)=0A//println=20= "~~~METADATA=20e=20$ext=20se=20$sext"=0A=20=20=20=20//=20note:=20the=20= above=20are=20those=20COMPILED=20NOW,=20would=20have=20to=20parse=20= META_INF=20to=20get=20the=20PREVIOUS=20ones=20for=20incremental...=20or=20= get=20them=20from=20buildscript?=20Not=20sure...=0A=20=20=20=20= mm=3D[*ext.asList(),*sext.asList()].unique().collectMany=20{=20= nodeOrName=20->=0A=20=20=20=20=20=20=20=20ClassNode=20cn=3DnodeOrName=20= in=20ClassNode?nodeOrName:ocs_lookupClassNodeFor(nodeOrName)=0A=20=20=20=20= =20=20=20=20if=20(!cn)=20{=0A=20=20=20=20=20=20=20=20=20=20=20=20= //println=20">>>=20unknown=20method=20'$name'=20->=20can't=20find=20CN=20= for=20$extname"=0A=20=20=20=20=20=20=20=20=20=20=20=20return=20[]=0A=20=20= =20=20=20=20=20=20}=0A=20=20=20=20=20=20=20=20//println=20">>>=20= searching=20${cn.methods.size()}=20methods=20of=20'$nodeOrName'=20->=20= '$cn'..."=0A=20=20=20=20=20=20=20=20cn.methods.findResults=20{=20method=20= ->=0A=20=20=20=20=20=20=20=20=20=20=20=20//println=20"...=20= $method.name"=0A=20=20=20=20=20=20=20=20=20=20=20=20if=20= (method.name=3D=3Dname=20||=20method.name=3D=3Dgetter)=20return=20method=0A= =20=20=20=20=20=20=20=20=20=20=20=20null=0A=20=20=20=20=20=20=20=20}?:[]=0A= =20=20=20=20}=0A=20=20=20=20=0A=20=20=20=20if=20(!mm)=20{=0A=20=20=20=20=20= =20=20=20try=20{=0A=20=20=20=20=20=20=20=20=20=20=20=20//println=20= "\n\n\n\n\n\n\n\n\n\n\n\n\n\n>>>>>=20time=20for=20both=20the=20= ClassBrowsers..."=0A=20=20=20=20=20=20=20=20=20=20=20=20ClassList=20= iclist=3DAST_A.genericStorage(typeCheckingVisitor.sourceUnit,'InternalClas= sList')=0A=20=20=20=20=20=20=20=20=20=20=20=20//println=20"IWUT=20!!=20= ${iclist?.methods?.getClass()}"=20;=20if=20(iclist?.methods=20in=20Map)=20= println=20"map=20of=20${iclist.methods.size()}=20items"=0A=20=20=20=20=20= =20=20=20=20=20=20=20if=20(iclist)=20{=0A=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20if=20(!(mm=3Diclist.lookupMethods(this,cln,name,argtypes))=20= &&=20getter)=20mm=3Diclist.lookupMethods(this,cln,getter,argtypes);=0A=20= =20=20=20=20=20=20=20=20=20=20=20}=0A=20=20=20=20=20=20=20=20=20=20=20=20= if=20(!mm)=20{=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= ClassList=20= clist=3DAST_A.genericStorage(typeCheckingVisitor.sourceUnit,'ExternalClass= List')=20{=20ClassList.withContentsOfStandardFile()=20}=0A=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20//println=20"EWUT=20!!=20= ${clist.methods?.getClass()}"=20;=20if=20(clist.methods=20in=20Map)=20= println=20"map=20of=20${clist.methods.size()}=20items"=0A=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20if=20(clist)=20{=0A=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20if=20= (!(mm=3Dclist.lookupMethods(this,cln,name,argtypes))=20&&=20getter)=20= mm=3Dclist.lookupMethods(this,cln,getter,argtypes);=0A=20=20=20=20=20=20=20= =20=20=20=20=20=20=20=20=20}=0A=20=20=20=20=20=20=20=20=20=20=20=20}=0A=20= =20=20=20=20=20=20=20}=20catch=20(exc)=20{=0A=20=20=20=20=20=20=20=20=20=20= =20=20println=20">>>>=20crashed:=20$exc.message"=0A=20=20=20=20=20=20=20=20= =20=20=20=20exc.printStackTrace()=0A=20=20=20=20=20=20=20=20=20=20=20=20= println=20">>>>=20that=20would=20be=20all...\n\n\n"=0A=20=20=20=20=20=20=20= =20=20=20=20=20throw=20exc=0A=20=20=20=20=20=20=20=20}=0A=20=20=20=20}=0A= =20=20=20=20=0A=20=20=20=20//println=20"=20=20=20->=20$mm"=0A=20=20=20=20= mm=0A}=0A=0AunresolvedVariable=20{=20var=20->=0A=20=20=20=20log.trace=20= "---=20variable=20'$var.name'=20unresolved=20in=20= '${enclosingClassNode.text}'=20${info(var)}"=0A=20=20=20=20//=20try=20to=20= find=20a=20getter=20method=20just=20as=20(C)DPA=20would=20--=20check=20= also=20property=20below!=0A=20=20=20=20def=20= meth=3DlookupMethods(enclosingClassNode,var.name)=0A=20=20=20=20if=20= (meth)=20{=20//TODO:=20if=20there's=20more=20of=20them,=20what=20now?!?=0A= =20=20=20=20=20=20=20=20storeType(var,meth[0].returnType)=0A=20=20=20=20=20= =20=20=20handled=3DYES=0A=20=20=20=20}=0A=20=20=20=20=0A=20=20=20=20if=20= (handled)=20log.debug=20"---=20variable=20'$var.name'=20in=20= '${enclosingClassNode.text}'=20->=20'${meth[0].returnType}'=20= ${info(var)}"=0A}=0AunresolvedProperty=20{=20prop=20->=0A=20=20=20=20def=20= unch=3Dprop.getNodeMetaData('cz.ocs.Safe_Unchecked')=0A=20=20=20=20= log.trace=20"---=20property=20'$prop.text'=20of=20= '${getType(prop.objectExpression).text}'=20uncheched=20$unch=20= unresolved=20in=20'$prop.objectExpression.text'=20${info(prop)}"=0A=20=20= =20=20//=20try=20to=20find=20a=20getter=20method=20just=20as=20(C)DPA=20= would=20--=20check=20also=20variable=20above!=20Even=20if=20unchecked=20= --=20better=20to=20know=20the=20RIGHT=20return=20value=20if=20possible=0A= =20=20=20=20def=20= meth=3DlookupMethods(getType(prop.objectExpression),prop.propertyAsString)= =0A=20=20=20=20def=20storedtype=3Dnull=0A=20=20=20=20if=20(meth)=20{=20= //TODO:=20if=20there's=20more=20of=20them,=20what=20now?!?=0A=20=20=20=20= =20=20=20=20storeType(prop,storedtype=3Dmeth[0].returnType)=0A=20=20=20=20= =20=20=20=20handled=3DYES=0A=20=20=20=20}=0A=20=20=20=20if=20(!handled=20= &&=20unch)=20{=0A=20=20=20=20=20=20=20=20= storeType(prop,storedtype=3DclassNodeFor(Object))=0A=20=20=20=20=20=20=20= =20handled=3DYES=0A=20=20=20=20}=0A=0A=20=20=20=20if=20(handled)=20= log.debug=20"---=20property=20'$prop.text'=20of=20= '${getType(prop.objectExpression).text}'=20in=20= '$prop.objectExpression.text'=20->=20'$storedtype.text'=20${info(prop)}"=0A= }=0A//unresolvedAttribute=20{=20attr=20->=0A//=20=20=20=20log.debug=20= "'$attr.text'=20unresolved=20attribute=20${info(attr)}"=0A//=20=20=20=20= storeType(attr,classNodeFor(Object))=0A//=20=20=20=20handled=3DYES=0A//}=0A= methodNotFound=20{=20receiver,name,argList,argTypes,call=20->=0A=20=20=20= =20def=20unch=3Dcall.getNodeMetaData('cz.ocs.Safe_Unchecked')=0A=20=20=20= =20log.trace=20"---=20method=20'$name'=20of=20$receiver.text=20with=20= ${argTypes*.text}=20uncheched=20$unch=20unresolved=20${info(call)}"=0A=20= =20=20=20log.trace=20"=20=20=20=20as:=20'$call.text'"=0A=20=20=20=20//=20= try=20to=20find=20the=20method=20by=20name=20--=20perhaps=20we=20are=20= giving=20it=20def=20arguments=20instead=20of=20the=20proper=20ones!=0A=20= =20=20=20def=20meth=3DlookupMethods(receiver,name,argTypes)=0A=20=20=20=20= if=20(!meth=20&&=20unch)=20{=0A=20=20=20=20=20=20=20=20= //meth=3D[newMethod(name,classNodeFor(Object))]=20=20=20=20=20=20=20=20=20= =20=20=20=20=20=20=20//=20this=20one=20crashes=20typechecker,=20= outofbounds=0A=20=20=20=20=20=20=20=20def=20n=3D1=0A=20=20=20=20=20=20=20= =20def=20pp=3DargTypes.collect=20{=0A=20=20=20=20=20=20=20=20=20=20=20=20= new=20Parameter(it,"p${n++}")=0A=20=20=20=20=20=20=20=20}=20as=20= Parameter[]=0A=20=20=20=20=20=20=20=20meth=3D[new=20MethodNode(name,=20= ACC_PUBLIC|ACC_SYNTHETIC,=20classNodeFor(Object),=20pp,=20[]=20as=20= ClassNode[],=20EmptyStatement.INSTANCE)]=0A=20=20=20=20}=0A=20=20=20=20=0A= =20=20=20=20def=20result=3Dnull=0A=20=20=20=20=0A=20=20=20=20if=20(meth)=20= result=3Dmeth[0]=20//TODO:=20not=20quite=20right!=0A=20=20=20=20=0A=20=20= =20=20if=20(result)=20{=0A=20=20=20=20=20=20=20=20log.debug=20"---=20= method=20'$name'=20of=20$receiver.text=20with=20${argTypes*.text}=20= resolved=20${info(call)}"=0A=20=20=20=20=20=20=20=20log.debug=20"=20=20=20= =20'$call.text'=20->=20$result.text"=0A=20=20=20=20=20=20=20=20return=20= result=0A=20=20=20=20}=0A=0A=20=20=20=20return=20meth=0A}=0A= afterMethodCall=20{=20call=20->=0A=20=20=20=20if=20= (call.methodAsString=3D=3D'nssizeCollectionsAndMaps')=20{=0A=20=20=20=20=20= =20=20=20def=20type=3DgetType(call.receiver)=0A=20=20=20=20=20=20=20=20= if=20(!type.implementsInterface(classNodeFor(Collection))=20&&=20= !type.implementsInterface(classNodeFor(Map)))=20{=0A=20=20=20=20=20=20=20= =20=20=20=20=20log.debug=20"---=20inferring=20receiver=20type=20= '$type.text'=20for=20'$call.text'=20${info(call)}"=0A=20=20=20=20=20=20=20= =20=20=20=20=20storeType(call,type)=0A=20=20=20=20=20=20=20=20}=0A=20=20=20= =20}=0A}=0AincompatibleAssignment=20{=20ltype,=20rtype,=20expr=20->=0A=20= =20=20=20log.trace=20"---=20'$expr.text'=20incompatible=20assignment=20= $ltype.name=3D$rtype.name=20${info(expr)}"=0A=20=20=20=20if=20= (rtype=3D=3DClassHelper.OBJECT_TYPE)=20handled=3DYES=20//=20object=20can=20= be=20assigned=20to=20anything,=20like,=20Foo=20foo=3Darray[1]=0A=20=20=20= =20else=20if=20(ClassHelper.isNumberType(ltype)=20&&=20= rtype=3D=3DClassHelper.Number_TYPE)=20handled=3DYES=20//=20autoboxing=20= //TODO:=20should=20isKindOf,=20not=20=3D=3D!=0A=20=20=20=20=0A=20=20=20=20= //=20BEWARE=20unlike=20others=20we=20report=20UNHANDLED=20cases=20here.=20= Makes=20sense=20--=20in=20other=20cases=20we=20want=20to=20know=20how=20= we=20handle=20them,=20here=20why=20we=20did=20not!=0A=20=20=20=20if=20= (!handled)=20log.debug=20"---=20'$expr.text'=20unhandled=20incompatible=20= assignment=20$ltype.name=3D$rtype.name=20${info(expr)}"=0A}=0A= --Apple-Mail=_11CFD8F1-AFFF-4DC2-9322-945177DF524A--