コード例 #1
0
 private function inferenceTypeOfCalledObject(TES5ObjectCall $objectCall, TES5MultipleScriptsScope $multipleScriptsScope)
 {
     $inferencableType = $objectCall->getAccessedObject()->getType()->getNativeType();
     /**
      * Check if we have something to inference inside the code, not some static class or method call return
      */
     if ($objectCall->getAccessedObject()->getReferencesTo() !== null) {
         //this is not "exactly" nice solution, but its enough. For now.
         $inferenceType = TES5InheritanceGraphAnalyzer::findTypeByMethod($objectCall);
         if ($inferencableType === null) {
             throw new ConversionException("Cannot inference a null type");
         }
         if ($inferencableType == $inferenceType) {
             return;
             //We already have the good type.
         }
         if ($this->inferenceType($objectCall->getAccessedObject()->getReferencesTo(), $inferenceType, $multipleScriptsScope)) {
             return;
         }
     }
 }
 /**
  * @param TES5ObjectCall $objectCall
  * @return mixed|TES5Type
  * @throws \Ormin\OBSLexicalParser\TES5\Exception\ConversionException
  *
  */
 public static function findTypeByMethod(TES5ObjectCall $objectCall)
 {
     $methodName = $objectCall->getFunctionName();
     $possibleMatches = [];
     foreach (self::$callReturns as $type => $methods) {
         foreach ($methods as $method => $functionData) {
             if (strtolower($method) == strtolower($methodName)) {
                 $possibleMatches[] = TES5TypeFactory::memberByValue($type);
             }
         }
     }
     $calledOn = $objectCall->getAccessedObject()->getReferencesTo();
     $extendingMatches = [];
     $actualType = $calledOn->getPropertyType()->getNativeType();
     /**
      * @var TES5Type[] $possibleMatches
      */
     foreach ($possibleMatches as $possibleMatch) {
         if ($possibleMatch == $actualType) {
             return $possibleMatch;
             //if the possible match matches the actual basic type, it means that it surely IS one of those.
         }
         //Ok, so are those matches somehow connected at all?
         if (TES5InheritanceGraphAnalyzer::isExtending($possibleMatch, $actualType) || TES5InheritanceGraphAnalyzer::isExtending($actualType, $possibleMatch)) {
             $extendingMatches[] = $possibleMatch;
         }
     }
     switch (count($extendingMatches)) {
         case 0:
             $concatTypes = [];
             foreach ($possibleMatches as $possibleMatch) {
                 $concatTypes[] = $possibleMatch->value();
             }
             throw new ConversionException("Cannot find any possible type for method " . $methodName . ", trying to extend " . $actualType->value() . " with following types: " . implode(', ', $concatTypes));
         case 1:
             return current($extendingMatches);
         default:
             //We analyze the property name and check inside the ESM analyzer.
             $formType = ESMAnalyzer::instance()->getFormTypeByEDID($calledOn->getReferenceEdid());
             if (!in_array($formType, $extendingMatches)) {
                 throw new ConversionException("ESM <-> Inheritance Graph conflict, ESM returned " . $formType->value() . ", which is not present in possible matches from inheritance graph");
             }
             return $formType;
     }
 }