public function generateTargetCode(TokenPool $aTokenPool, Token $aObject) { if (!$aObject instanceof ClassDefine) { throw new ClassCompileException(null, $aObject, "传入的类新必须为 ClassDefine: %s", Type::detectType($aObject)); } $aClassEnd = $aObject->bodyToken()->theOther(); $sTargetClassName = $aObject->fullName(); // 反射父类的所有方法 $arrParentMethodNames = array(); $aRefParentClass = null; if ($aObject->isClass()) { foreach ($aObject->parentClassNameIterator() as $sParentClass) { if (!class_exists($sParentClass)) { throw new ClassCompileException(null, $aObject, "编译class时遇到错误,class %s 的父类 %s 不存在 ", array($sTargetClassName, $sParentClass)); } $aRefParentClass = new \ReflectionClass($sParentClass); foreach ($aRefParentClass->getMethods() as $aRefParentMethod) { if (!$aRefParentMethod->isPrivate() and !$aRefParentMethod->isAbstract() and !$aRefParentMethod->isFinal()) { $arrParentMethodNames[$aRefParentMethod->getName()] = $aRefParentMethod; } } } } // 需要编入的方法 $arrNeedWeaveMethods = array(); foreach ($this->aop()->aspects()->iterator() as $aAspect) { foreach ($aAspect->pointcuts()->iterator() as $aPointcut) { foreach ($aPointcut->jointPoints()->iterator() as $aJointPoint) { if (!$aJointPoint instanceof JointPointMethodDefine) { continue; } // 模糊匹配函数名 ----------------------- if ($aJointPoint->weaveMethodIsPattern()) { foreach ($aTokenPool->functionIterator($aObject->fullName()) as $aMethodToken) { // bingo ! if ($aJointPoint->matchExecutionPoint($aMethodToken)) { $sMethodName = $aMethodToken->name(); if (empty($arrNeedWeaveMethods[$sMethodName])) { $arrNeedWeaveMethods[$sMethodName] = new GenerateStat($aTokenPool, $aMethodToken); } $arrNeedWeaveMethods[$sMethodName]->addAdvices($aPointcut->advices()->iterator()); } } } else { if (!$aJointPoint->matchClass($sTargetClassName)) { continue; } $sFuncName = $aJointPoint->weaveMethod(); if (empty($arrNeedWeaveMethods[$sFuncName])) { $arrNeedWeaveMethods[$sFuncName] = new GenerateStat($aTokenPool); } $arrNeedWeaveMethods[$sFuncName]->addAdvices($aPointcut->advices()->iterator()); // 目标类的方法 if ($aMethodToken = $aTokenPool->findFunction($sFuncName, $sTargetClassName)) { $arrNeedWeaveMethods[$sFuncName]->aExecutePoint = $aMethodToken; } else { if (isset($arrParentMethodNames[$sFuncName])) { $aMethodRef = $arrParentMethodNames[$sFuncName]; $aMethodRef instanceof \ReflectionMethod; // 产生函数定义和函数调用的参数表 $this->generateArgvsByReflection($arrNeedWeaveMethods[$sFuncName], $aMethodRef); if ($aMethodRef->isPublic()) { $sAccess = 'public'; } else { if ($aMethodRef->isProtected()) { $sAccess = 'protected'; } else { if ($aMethodRef->isPrivate()) { $sAccess = 'private'; } } } // 创建一个覆盖父类的方法用于 aop $aMethodToken = $this->createMethod($sFuncName, $arrNeedWeaveMethods[$sFuncName]->sOriginCallArgvsLit, $sAccess, $aMethodRef->isStatic(), $aTokenPool, $aClassEnd, 'insertBefore'); $aMethodToken->setBelongsClass($aObject); $aMethodToken->setBelongsNamespace($aObject->belongsNamespace()); $arrNeedWeaveMethods[$sFuncName]->aExecutePoint = $aMethodToken; // 创建函数内容 $aTokenPool->insertAfter($aMethodToken->bodyToken(), new Token(T_STRING, "\n\t\t\t// 调用父类方法\n\t\t\treturn parent::{$sFuncName}({$arrNeedWeaveMethods[$sFuncName]->sOriginCallArgvsLit}) ;\n\t\t")); } else { // 创建一个全新的方法用于 aop $aMethodToken = $this->createMethod($sFuncName, $arrNeedWeaveMethods[$sFuncName]->sOriginCallArgvsLit, 'private', false, $aTokenPool, $aClassEnd, 'insertBefore'); $aMethodToken->setBelongsClass($aObject); $aMethodToken->setBelongsNamespace($aObject->belongsNamespace()); $arrNeedWeaveMethods[$sFuncName]->aExecutePoint = $aMethodToken; $aTokenPool->insertAfter($aMethodToken->bodyToken(), new Token(T_STRING, " // 这只是一个影子方法 ")); } } } } } } // 开始编织 foreach ($arrNeedWeaveMethods as $aState) { if (!empty($aState->arrAdvices)) { $this->weave($aState); } } }