| 4126 | } |
| 4127 | |
| 4128 | static class InvokeExpr implements Expr{ |
| 4129 | public final Expr fexpr; |
| 4130 | public final Object tag; |
| 4131 | public final IPersistentVector args; |
| 4132 | public final int line; |
| 4133 | public final int column; |
| 4134 | public final boolean tailPosition; |
| 4135 | public final String source; |
| 4136 | public boolean isProtocol = false; |
| 4137 | public boolean isDirect = false; |
| 4138 | public int siteIndex = -1; |
| 4139 | public Class protocolOn; |
| 4140 | public java.lang.reflect.Method onMethod; |
| 4141 | static Keyword onKey = Keyword.intern("on"); |
| 4142 | static Keyword methodMapKey = Keyword.intern("method-map"); |
| 4143 | Class jc; |
| 4144 | |
| 4145 | static Object sigTag(int argcount, Var v){ |
| 4146 | Object arglists = RT.get(RT.meta(v), arglistsKey); |
| 4147 | Object sigTag = null; |
| 4148 | for(ISeq s = RT.seq(arglists); s != null; s = s.next()) |
| 4149 | { |
| 4150 | APersistentVector sig = (APersistentVector) s.first(); |
| 4151 | int restOffset = sig.indexOf(_AMP_); |
| 4152 | if(argcount == sig.count() || (restOffset > -1 && argcount >= restOffset)) |
| 4153 | return tagOf(sig); |
| 4154 | } |
| 4155 | return null; |
| 4156 | } |
| 4157 | |
| 4158 | // Callsites are only registered in a function context |
| 4159 | // In KEYWORD/PROTOCOL_CALLSITES, null indicates "do not register" |
| 4160 | static boolean shouldRegisterCallsites(Var callSiteVar) { |
| 4161 | return callSiteVar.deref() != null; |
| 4162 | } |
| 4163 | |
| 4164 | public InvokeExpr(String source, int line, int column, Symbol tag, Expr fexpr, IPersistentVector args, boolean tailPosition) { |
| 4165 | this.source = source; |
| 4166 | this.fexpr = fexpr; |
| 4167 | this.args = args; |
| 4168 | this.line = line; |
| 4169 | this.column = column; |
| 4170 | this.tailPosition = tailPosition; |
| 4171 | |
| 4172 | if(fexpr instanceof VarExpr) |
| 4173 | { |
| 4174 | Var fvar = ((VarExpr)fexpr).var; |
| 4175 | Var pvar = (Var)RT.get(fvar.meta(), protocolKey); |
| 4176 | if(pvar != null && shouldRegisterCallsites(PROTOCOL_CALLSITES)) |
| 4177 | { |
| 4178 | this.isProtocol = true; |
| 4179 | this.siteIndex = registerProtocolCallsite(((VarExpr)fexpr).var); |
| 4180 | Object pon = RT.get(pvar.get(), onKey); |
| 4181 | this.protocolOn = HostExpr.maybeClass(pon,false); |
| 4182 | if(this.protocolOn != null) |
| 4183 | { |
| 4184 | IPersistentMap mmap = (IPersistentMap) RT.get(pvar.get(), methodMapKey); |
| 4185 | Keyword mmapVal = (Keyword) mmap.valAt(Keyword.intern(fvar.sym)); |