📄 quercusclass.java
字号:
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */package com.caucho.quercus.env;import com.caucho.quercus.QuercusRuntimeException;import com.caucho.quercus.expr.ClassConstExpr;import com.caucho.quercus.expr.Expr;import com.caucho.quercus.expr.StringLiteralExpr;import com.caucho.quercus.module.ModuleContext;import com.caucho.quercus.program.AbstractFunction;import com.caucho.quercus.program.ClassDef;import com.caucho.quercus.program.InstanceInitializer;import com.caucho.quercus.program.JavaClassDef;import com.caucho.util.IntMap;import com.caucho.util.L10N;import java.util.ArrayList;import java.util.HashMap;import java.util.HashSet;import java.util.LinkedHashMap;import java.util.Map;import java.util.logging.Level;import java.util.logging.Logger;/** * Represents a Quercus runtime class. */public class QuercusClass { private static final L10N L = new L10N(QuercusClass.class); private static final Logger log = Logger.getLogger(QuercusClass.class.getName()); private final JavaClassDef _javaClassDef; private final ClassDef _classDef; private final String _className; private boolean _isJavaWrapper; private ClassDef []_classDefList; private QuercusClass _parent; private AbstractFunction _constructor; private AbstractFunction _fieldGet; private AbstractFunction _fieldSet; private AbstractFunction _call; private ArrayDelegate _arrayDelegate; private TraversableDelegate _traversableDelegate; private CountDelegate _countDelegate; private final ArrayList<InstanceInitializer> _initializers; private final ArrayList<StringValue> _fieldNames; private final IntMap _fieldMap; private final HashMap<StringValue,Expr> _fieldInitMap; /* private final IdentityHashMap<String,AbstractFunction> _methodMap = new IdentityHashMap<String,AbstractFunction>(); private final HashMap<String,AbstractFunction> _lowerMethodMap = new HashMap<String,AbstractFunction>(); */ private final MethodMap<AbstractFunction> _methodMap; private final HashMap<String,Expr> _constMap; private final HashMap<String,ArrayList<StaticField>> _staticFieldExprMap; private final HashMap<String,Value> _staticFieldMap = new LinkedHashMap<String,Value>(); public QuercusClass(ClassDef classDef, QuercusClass parent) { this(ModuleContext.getLocalContext(Thread.currentThread().getContextClassLoader()), classDef, parent); } public QuercusClass(ModuleContext moduleContext, ClassDef classDef, QuercusClass parent) { _classDef = classDef; _className = classDef.getName(); _parent = parent; _initializers = new ArrayList<InstanceInitializer>(); _fieldNames = new ArrayList<StringValue>(); _fieldMap = new IntMap(); _fieldInitMap = new HashMap<StringValue,Expr>(); _methodMap = new MethodMap<AbstractFunction>(); _constMap = new HashMap<String,Expr>(); _staticFieldExprMap = new LinkedHashMap<String,ArrayList<StaticField>>(); JavaClassDef javaClassDef = null; if (classDef instanceof JavaClassDef) { javaClassDef = (JavaClassDef) classDef; _isJavaWrapper = ! javaClassDef.isDelegate(); } for (QuercusClass cls = parent; cls != null; cls = cls.getParent()) { AbstractFunction cons = cls.getConstructor(); if (cons != null) { addMethod(cls.getName(), cons); } } ClassDef []classDefList; if (_parent != null) { classDefList = new ClassDef[parent._classDefList.length + 1]; System.arraycopy(parent._classDefList, 0, classDefList, 1, parent._classDefList.length); classDefList[0] = classDef; } else { classDefList = new ClassDef[] { classDef }; } _classDefList = classDefList; for (int i = 0; i < classDefList.length; i++) { if (classDefList[i] instanceof JavaClassDef) javaClassDef = (JavaClassDef) classDefList[i]; } _javaClassDef = javaClassDef; HashSet<String> ifaces = new HashSet<String>(); for (int i = classDefList.length - 1; i >= 0; i--) { classDef = classDefList[i]; if (classDef == null) { throw new NullPointerException("classDef:" + _classDef + " i:" + i + " parent:" + parent); } classDef.init(); for (String iface : classDef.getInterfaces()) { // XXX: php/0cn2, but this is wrong: QuercusClass cl = Env.getInstance().findClass(iface); if (cl == null) throw new QuercusRuntimeException(L.l("cannot find interface {0}", iface)); ClassDef ifaceDef = cl.getClassDef(); // ClassDef ifaceDef = moduleContext.findClass(iface); if (ifaceDef != null) { if (ifaces.add(iface)) ifaceDef.initClass(this); } } classDef.initClass(this); } if (_constructor == null && parent != null) _constructor = parent.getConstructor(); } /** * Copy based on a cached value */ public QuercusClass(QuercusClass cacheClass, QuercusClass parent) { _javaClassDef = cacheClass._javaClassDef; _classDef = cacheClass._classDef; _className = cacheClass._className; _isJavaWrapper = cacheClass._isJavaWrapper; _classDefList = cacheClass._classDefList; _parent = parent; _constructor = cacheClass._constructor; _fieldGet = cacheClass._fieldGet; _fieldSet = cacheClass._fieldSet; _call = cacheClass._call; _arrayDelegate = cacheClass._arrayDelegate; _traversableDelegate = cacheClass._traversableDelegate; _countDelegate = cacheClass._countDelegate; _initializers = cacheClass._initializers; _fieldNames = cacheClass._fieldNames; _fieldMap = cacheClass._fieldMap; _fieldInitMap = cacheClass._fieldInitMap; _methodMap = cacheClass._methodMap; _constMap = cacheClass._constMap; _staticFieldExprMap = cacheClass._staticFieldExprMap; } public ClassDef getClassDef() { return _classDef; } public JavaClassDef getJavaClassDef() { return _javaClassDef; } public MethodMap<AbstractFunction> getMethodMap() { return _methodMap; } /** * Returns the name. */ public String getName() { return _className; } /** * Returns the parent class. */ public QuercusClass getParent() { return _parent; } /* * Returns the class definitions for this class. */ public ClassDef []getClassDefList() { return _classDefList; } /* * Returns the name of the extension that this class is part of. */ public String getExtension() { return _classDef.getExtension(); } public boolean isInterface() { return _classDef.isInterface(); } public boolean isAbstract() { return _classDef.isAbstract(); } public boolean isFinal() { return _classDef.isFinal(); } /** * Sets the constructor. */ public void setConstructor(AbstractFunction fun) { _constructor = fun; } /** * Gets the constructor. */ public AbstractFunction getConstructor() { return _constructor; } /** * Sets the array delegate (see ArrayAccess) */ public void setArrayDelegate(ArrayDelegate delegate) { if (log.isLoggable(Level.FINEST)) log.log(Level.FINEST, L.l("{0} adding array delegate {1}", this, delegate)); _arrayDelegate = delegate; } /** * Gets the array delegate (see ArrayAccess) */ public final ArrayDelegate getArrayDelegate() { return _arrayDelegate; } /** * Sets the traversable delegate */ public void setTraversableDelegate(TraversableDelegate delegate) { if (log.isLoggable(Level.FINEST)) log.log(Level.FINEST, L.l("{0} setting traversable delegate {1}", this, delegate)); _traversableDelegate = delegate; } /** * Gets the traversable delegate */ public final TraversableDelegate getTraversableDelegate() { return _traversableDelegate; } /** * Sets the count delegate */ public void setCountDelegate(CountDelegate delegate) { if (log.isLoggable(Level.FINEST)) log.log(Level.FINEST, L.l("{0} setting count delegate {1}", this, delegate)); _countDelegate = delegate; } /** * Gets the count delegate */ public final CountDelegate getCountDelegate() { return _countDelegate; } /** * Sets the __fieldGet */ public void setFieldGet(AbstractFunction fun) { _fieldGet = fun; } /** * Returns the __fieldGet */ public AbstractFunction getFieldGet() { return _fieldGet; } /** * Sets the __fieldSet */ public void setFieldSet(AbstractFunction fun) { _fieldSet = fun; } /** * Returns the __fieldSet */ public AbstractFunction getFieldSet() { return _fieldSet; } /** * Sets the __call */ public void setCall(AbstractFunction fun) { _call = fun; } /** * Gets the __call */ public AbstractFunction getCall() { return _call; } /** * Adds an initializer */ public void addInitializer(InstanceInitializer init) { _initializers.add(init); } /** * Adds a field. */ public void addField(StringValue name, int index, Expr initExpr) { _fieldNames.add(name); _fieldMap.put(name, index); _fieldInitMap.put(name, initExpr); } /** * Adds a field. */ public int addFieldIndex(StringValue name) { int index = _fieldMap.get(name); if (index >= 0) return index; else { index = _fieldNames.size(); _fieldMap.put(name, index); _fieldNames.add(name); return index; } } /** * Returns a set of the fields and their initial values */ public HashMap<StringValue,Expr> getClassVars() { return _fieldInitMap; } /** * Returns the declared functions. */ public Iterable<AbstractFunction> getClassMethods() { return _methodMap.values(); } /** * Adds a method. */ public void addMethod(String name, AbstractFunction fun) { //php/09j9 // XXX: this is a hack to get Zend Framework running, the better fix is // to initialize all interface classes before any concrete classes AbstractFunction existingFun = _methodMap.get(name); if (existingFun == null || ! fun.isAbstract()) _methodMap.put(name, fun); } /** * Adds a static class field. */ public void addStaticFieldExpr(String className, String name, Expr value) { ArrayList<StaticField> fieldList = _staticFieldExprMap.get(className); if (fieldList == null) { fieldList = new ArrayList<StaticField>(); _staticFieldExprMap.put(className, fieldList); } fieldList.add(new StaticField(name, value)); } /** * Adds a constant definition */ public void addConstant(String name, Expr expr) { _constMap.put(name, expr); } /** * Returns the number of fields. */ public int getFieldSize() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -