package php.runtime.invoke; import php.runtime.Memory; import php.runtime.common.Messages; import php.runtime.env.Environment; import php.runtime.env.TraceInfo; import php.runtime.reflection.ClassEntity; import php.runtime.reflection.MethodEntity; import php.runtime.reflection.ParameterEntity; public class StaticMethodInvoker extends Invoker { protected final MethodEntity method; protected final String calledClass; public StaticMethodInvoker(Environment env, TraceInfo trace, String calledClass, MethodEntity method) { super(env, trace); this.method = method; this.calledClass = calledClass; } @Override public ParameterEntity[] getParameters() { return method.getParameters(); } @Override public void check(String name, TraceInfo trace) { if (!method.isStatic()) env.warning(trace, name + "(): non-static method " + method.getSignatureString(false) +" should not be called statically"); } @Override public String getName() { return calledClass + "::" + method.getName(); } @Override public int getArgumentCount() { return method.getParameters() == null ? 0 : method.getParameters().length; } public MethodEntity getMethod() { return method; } public String getCalledClass() { return calledClass; } @Override public void pushCall(TraceInfo trace, Memory[] args) { env.pushCall(trace, null, args, method.getName(), method.getClazz().getName(), calledClass); } @Override protected Memory invoke(Memory... args) throws Throwable { return InvokeHelper.callStatic(env, trace == null ? TraceInfo.UNKNOWN : trace, method, null, args, false); } @Override public int canAccess(Environment env) { return method.canAccess(env); } public static StaticMethodInvoker valueOf(Environment env, TraceInfo trace, String className, String methodName){ ClassEntity classEntity = env.fetchClass(className, true); if (classEntity == null) classEntity = env.fetchMagicClass(className); MethodEntity methodEntity = classEntity == null ? null : classEntity.findMethod(methodName.toLowerCase()); if (methodEntity == null /*|| !methodEntity.isStatic()*/){ if (classEntity != null && classEntity.methodMagicCallStatic != null){ return new MagicStaticMethodInvoker( env, trace, className, classEntity.methodMagicCallStatic, methodName ); } if (trace == null) return null; env.error(trace, Messages.ERR_CALL_TO_UNDEFINED_METHOD.fetch(className + "::" + methodName)); return null; } return new StaticMethodInvoker(env, trace, className, methodEntity); } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof StaticMethodInvoker)) return false; StaticMethodInvoker that = (StaticMethodInvoker) o; return calledClass.equals(that.calledClass) && method.equals(that.method); } @Override public int hashCode() { int result = method.hashCode(); result = 31 * result + calledClass.hashCode(); return result; } }