📄 quercusclass.java
字号:
return _fieldNames.size(); } /** * Returns the field index. */ public int findFieldIndex(StringValue name) { return _fieldMap.get(name); } /** * Returns the key set. */ public ArrayList<StringValue> getFieldNames() { return _fieldNames; } public void validate(Env env) { if (! _classDef.isAbstract() && ! _classDef.isInterface()) { for (AbstractFunction fun : _methodMap.values()) { /* XXX: abstract methods need to be validated php/393g, php/393i, php/39j2 if (! (absFun instanceof Function)) continue; Function fun = (Function) absFun; */ boolean isAbstract; // php/093g constructor if (_constructor != null && fun.getName().equals(_constructor.getName())) isAbstract = _constructor.isAbstract(); else isAbstract = fun.isAbstract(); if (isAbstract) { throw env.createErrorException( _classDef.getLocation(), L.l("Abstract function '{0}' must be implemented in concrete class {1}.", fun.getName(), getName())); } } } } public void init(Env env) { for (Map.Entry<String,ArrayList<StaticField>> map : _staticFieldExprMap.entrySet()) { if (env.isInitializedClass(map.getKey())) continue; for (StaticField field : map.getValue()) { Value val; Expr expr = field._expr; //php/096f if (expr instanceof ClassConstExpr) val = ((ClassConstExpr) expr).eval(env); else val = expr.eval(env); _staticFieldMap.put(field._name, val); } env.addInitializedClass(map.getKey()); } } /* public void setStaticField(String name, Value val) { Var var = new Var(); var.set(val); _staticFieldMap.put(name, var); } */ public Var getStaticField(Env env, String name) { Value value = _staticFieldMap.get(name); if (value != null) { String fullName = _className + "::" + name; Var var = env.getGlobalRaw(fullName); if (var == null) { var = env.getGlobalVar(fullName); var.set(value); } return var; } QuercusClass parent = getParent(); if (parent != null) return parent.getStaticField(env, name); else return null; } /* * Returns the static fields. */ public HashMap<String, Value> getStaticFieldMap() { return _staticFieldMap; } // // Constructors // /** * Creates a new instance. */ /* public Value callNew(Env env, Expr []args) { Value object = _classDef.callNew(env, args); if (object != null) return object; object = newInstance(env); AbstractFunction fun = findConstructor(); if (fun != null) { fun.callMethod(env, object, args); } return object; } */ /** * Creates a new instance. */ public Value callNew(Env env, Value []args) { String oldCallingClass = env.setCallingClassName(_className); try { if (_classDef.isAbstract()) { throw env.createErrorException(L.l("abstract class '{0}' cannot be instantiated.", _className)); } else if (_classDef.isInterface()) { throw env.createErrorException(L.l("interface '{0}' cannot be instantiated.", _className)); } ObjectValue objectValue = null; if (_isJavaWrapper) { return _javaClassDef.callNew(env, args); } else if (_javaClassDef != null && _javaClassDef.isDelegate()) { objectValue = new ObjectExtValue(this); } else if (_javaClassDef != null && ! _javaClassDef.isDelegate()) { // php/0k3- Value javaWrapper = _javaClassDef.callNew(env, args); Object object = javaWrapper.toJavaObject(); objectValue = new ObjectExtJavaValue(this, object, _javaClassDef); } else { objectValue = _classDef.newInstance(env, this); } for (int i = 0; i < _initializers.size(); i++) { _initializers.get(i).initInstance(env, objectValue); } AbstractFunction fun = findConstructor(); if (fun != null) fun.callMethod(env, objectValue, args); else { // if expr } return objectValue; } finally { env.setCallingClassName(oldCallingClass); } } /** * Returns the parent class. */ public String getParentName() { return _classDefList[0].getParentName(); } /** * Returns true for an implementation of a class */ public boolean isA(String name) { for (int i = _classDefList.length - 1; i >= 0; i--) { if (_classDefList[i].isA(name)) { return true; } } return false; } /* * Returns an array of the interfaces that this class and its parents * implements. */ public ArrayValue getInterfaces(Env env, boolean autoload) { ArrayValue array = new ArrayValueImpl(); getInterfaces(env, array, autoload, true); return array; } /* * Puts the interfaces that this class and its parents implements * into the array. */ private void getInterfaces(Env env, ArrayValue array, boolean autoload, boolean isTop) { ClassDef [] defList = _classDefList; for (int i = 0; i < defList.length; i++) { ClassDef def = defList[i]; if (! isTop && def.isInterface()) { String name = def.getName(); array.put(name, name); } String []defNames = def.getInterfaces(); for (int j = 0; j < defNames.length; j++) { QuercusClass cls = env.findClass(defNames[j]); cls.getInterfaces(env, array, autoload, false); } } if (_parent != null) _parent.getInterfaces(env, array, autoload, false); } /* * Returns true if this class or its parents implements specified interface. */ public boolean implementsInterface(Env env, String name) { ClassDef [] defList = _classDefList; for (int i = 0; i < defList.length; i++) { ClassDef def = defList[i]; if (def.isInterface() && def.getName().equals(name)) return true; String []defNames = def.getInterfaces(); for (int j = 0; j < defNames.length; j++) { QuercusClass cls = env.findClass(defNames[j]); if (cls.implementsInterface(env, name)) return true; } } if (_parent != null) return _parent.implementsInterface(env, name); else return false; } /** * Finds the matching constructor. */ public AbstractFunction findConstructor() { return _constructor; } // // Fields // /** * Implements the __get method call. */ public Value getField(Env env, Value qThis, StringValue name) { if (_fieldGet != null) return _fieldGet.callMethod(env, qThis, name); else return UnsetValue.UNSET; } /** * Implements the __set method call. */ public void setField(Env env, Value qThis, StringValue name, Value value) { if (_fieldSet != null) _fieldSet.callMethod(env, qThis, name, value); } /** * Finds the matching function. */ public AbstractFunction findFunction(String name) { char []key = name.toCharArray(); int hash = MethodMap.hash(key, key.length); AbstractFunction fun = _methodMap.get(hash, key, key.length); return fun; } /** * Finds the matching function. */ public AbstractFunction findStaticFunction(String name) { return findFunction(name); } /** * Finds the matching function. */ public final AbstractFunction getFunction(String name) { char []key = name.toCharArray(); int hash = MethodMap.hash(key, key.length); return getFunction(hash, key, key.length); } /** * Finds the matching function. */ public final AbstractFunction getFunction(int hash, char []name, int nameLen) { AbstractFunction fun = _methodMap.get(hash, name, nameLen); if (fun != null) return fun; else if (_className.equalsIgnoreCase(toMethod(name, nameLen)) && _parent != null) { // php/093j return _parent.getFunction(_parent.getName()); } else { throw new QuercusRuntimeException(L.l("{0}::{1} is an unknown method", getName(), toMethod(name, nameLen))); } } /** * calls the function. */ public Value callMethod(Env env, Value thisValue, int hash, char []name, int nameLength, Expr []args) { String oldClassName = env.setCallingClassName(_className); try { AbstractFunction fun = _methodMap.get(hash, name, nameLength); if (fun != null) return fun.callMethod(env, thisValue, args); else if (getCall() != null) { Expr []newArgs = new Expr[args.length + 1]; newArgs[0] = new StringLiteralExpr(toMethod(name, nameLength)); System.arraycopy(args, 0, newArgs, 1, args.length); return getCall().callMethod(env, thisValue, newArgs); } else return env.error(L.l("Call to undefined method {0}::{1}", getName(), toMethod(name, nameLength))); } finally { env.setCallingClassName(oldClassName); } } /** * calls the function. */ public Value callMethod(Env env, Value thisValue, StringValue methodName, Expr []args) { String oldClassName = env.setCallingClassName(_className); try { AbstractFunction fun = _methodMap.get(methodName.toString()); if (fun != null) return fun.callMethod(env, thisValue, args); else if (getCall() != null) { Expr []newArgs = new Expr[args.length + 1]; newArgs[0] = new StringLiteralExpr(methodName.toString()); System.arraycopy(args, 0, newArgs, 1, args.length); return getCall().callMethod(env, thisValue, newArgs); } else return env.error(L.l("Call to undefined method {0}::{1}", getName(), methodName)); } finally { env.setCallingClassName(oldClassName); } } /** * calls the function. */ public Value callMethod(Env env, Value thisValue, int hash, char []name, int nameLen, Value []args) { String oldClassName = env.setCallingClassName(_className); try { AbstractFunction fun = _methodMap.get(hash, name, nameLen); if (fun != null) return fun.callMethod(env, thisValue, args); else if (getCall() != null) { return getCall().callMethod(env, thisValue, env.createString(name, nameLen), new ArrayValueImpl(args)); } else return env.error(L.l("Call to undefined method {0}::{1}()", getName(), toMethod(name, nameLen))); } finally { env.setCallingClassName(oldClassName); } } /** * calls the function. */ public Value callMethod(Env env, Value thisValue, StringValue name, Value []args) { String oldClassName = env.setCallingClassName(_className); try { AbstractFunction fun = _methodMap.get(name.toString()); if (fun != null) return fun.callMethod(env, thisValue, args); else if (getCall() != null) { return getCall().callMethod(env, thisValue, name, new ArrayValueImpl(args)); } else return env.error(L.l("Call to undefined method {0}::{1}()", getName(), name)); } finally { env.setCallingClassName(oldClassName); } } /** * calls the function. */ public Value callMethod(Env env, Value thisValue, int hash, char []name, int nameLen) { String oldClassName = env.setCallingClassName(_className); try { AbstractFunction fun = _methodMap.get(hash, name, nameLen); if (fun != null) return fun.callMethod(env, thisValue); else if (getCall() != null) { return getCall().callMethod(env, thisValue, env.createString(name, nameLen), new ArrayValueImpl()); } else return env.error(L.l("Call to undefined method {0}::{1}()", getName(), toMethod(name, nameLen))); } finally { env.setCallingClassName(oldClassName); } } /**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -