public function createProperties(TES4VariableDeclarationList $variableList, TES5GlobalScope $globalScope)
 {
     /**
      * @var TES4VariableDeclaration[] $alreadyDefinedVariables
      */
     $alreadyDefinedVariables = [];
     foreach ($variableList->getVariableList() as $variable) {
         $theVariableName = strtolower($variable->getVariableName());
         if (isset($alreadyDefinedVariables[$theVariableName])) {
             if ($variable->getVariableType() == $alreadyDefinedVariables[$theVariableName]->getVariableType()) {
                 continue;
                 //Same variable defined twice, smack the original script developer and fallthrough silently.
             }
             throw new ConversionException("Double definition of variable named " . $variable->getVariableName() . " with different types ( " . $alreadyDefinedVariables[$theVariableName]->getVariableType()->value() . " and " . $variable->getVariableType()->value() . " )");
         }
         switch ($variable->getVariableType()) {
             case TES4Type::T_FLOAT():
                 $property = new TES5Property($variable->getVariableName(), TES5BasicType::T_FLOAT(), null);
                 break;
             case TES4Type::T_INT():
             case TES4Type::T_SHORT():
             case TES4Type::T_LONG():
                 $property = new TES5Property($variable->getVariableName(), TES5BasicType::T_INT(), null);
                 break;
             case TES4Type::T_REF():
                 $property = $this->createPropertyFromReference($variable);
                 break;
             default:
                 throw new ConversionException("Unknown variable declaration type.");
         }
         $globalScope->add($property);
         $alreadyDefinedVariables[$theVariableName] = $variable;
     }
 }
 public function getType()
 {
     if ($this->leftValue->getType() == TES5BasicType::T_FLOAT() || $this->rightValue->getType() == TES5BasicType::T_FLOAT()) {
         return TES5BasicType::T_FLOAT();
     }
     return TES5BasicType::T_INT();
 }
 public function createGlobalScopes()
 {
     $globalScopes = [];
     $globalScope = new TES5GlobalScope(new TES5ScriptHeader("TES4TimerHelper", "TES4TimerHelper", TES5BasicType::T_QUEST(), ""));
     $globalScopes[] = $globalScope;
     $globalScope = new TES5GlobalScope(new TES5ScriptHeader("TES4Container", "TES4Container", TES5BasicType::T_QUEST(), ""));
     $globalScope->add(new TES5Property("isInJail", TES5BasicType::T_BOOL(), "isInJail"));
     $globalScope->add(new TES5Property("isMurderer", TES5BasicType::T_BOOL(), "isMurderer"));
     $globalScopes[] = $globalScope;
     return $globalScopes;
 }
 public function createFromFragmentType(TES5FragmentType $fragmentType)
 {
     $localScope = new TES5LocalScope();
     switch ($fragmentType) {
         case TES5FragmentType::T_TIF():
             $localScope->addVariable(new TES5LocalVariable("akSpeakerRef", TES5BasicType::T_OBJECTREFERENCE(), [TES5LocalVariableParameterMeaning::ACTIVATOR()]));
             break;
         case TES5FragmentType::T_PF():
             $localScope->addVariable(new TES5LocalVariable("akActor", TES5BasicType::T_ACTOR(), [TES5LocalVariableParameterMeaning::ACTIVATOR()]));
             break;
         case TES5FragmentType::T_QF():
             break;
     }
     return $localScope;
 }
 /**
  * @param $memberByValue string Type to be created.
  * @param $basicType TES5BasicType You might override the basic type for this custom type created.
  * @return \Eloquent\Enumeration\ValueMultitonInterface|TES5CustomType|TES5VoidType
  */
 public static function memberByValue($memberByValue, TES5BasicType $basicType = null)
 {
     if ($memberByValue == "void") {
         return new TES5VoidType();
     }
     try {
         return TES5BasicType::memberByValue(ucwords($memberByValue));
     } catch (\Exception $e) {
         //Ugly - todo: REFACTOR THIS TO NON-STATIC CLASS AND MOVE THIS TO DI
         if ($basicType === null) {
             $analyzer = ESMAnalyzer::instance();
             $basicType = $analyzer->getScriptType($memberByValue);
         }
         return new TES5CustomType(TES5NameTransformer::transform($memberByValue, self::$scriptsPrefix), self::$scriptsPrefix, $basicType);
     }
 }
 /**
  * @param string $scriptName
  * @param TES4VariableDeclarationList $variableList
  * @param TES4CodeChunks $script
  * @return TES5Script
  * @throws ConversionException
  */
 public function convert($scriptName, TES4VariableDeclarationList $variableList, TES4CodeChunks $script)
 {
     //Create the header.
     $scriptHeader = new TES5ScriptHeader($this->nameTransformer->transform($scriptName, ''), $scriptName, TES5BasicType::T_TOPICINFO(), '', true);
     $globalScope = new TES5GlobalScope($scriptHeader);
     foreach ($this->esmAnalyzer->getGlobalVariables() as $globalVariable) {
         $globalScope->addGlobalVariable($globalVariable);
     }
     if ($variableList !== null) {
         //Converting the variables to the properties.
         $this->propertiesFactory->createProperties($variableList, $globalScope);
     }
     $fragment = $this->fragmentFactory->createFragment(TES5FragmentType::T_TIF(), "Fragment_0", $globalScope, new TES5MultipleScriptsScope([$globalScope]), $script);
     $blockList = new TES5BlockList();
     $blockList->add($fragment);
     return new TES5Script($scriptHeader, $globalScope, $blockList);
 }
 private function inferenceTypeOfMethodArguments(TES5ObjectCall $objectCall, TES5MultipleScriptsScope $multipleScriptsScope)
 {
     /**
      * Inference the arguments
      */
     $arguments = $objectCall->getArguments();
     $argumentNumber = 0;
     $calledOnType = $objectCall->getAccessedObject()->getType()->getNativeType();
     foreach ($arguments->getArguments() as $argument) {
         /**
          * Get the argument type according to TES5Inheritance graph.
          */
         $argumentTargetType = TES5InheritanceGraphAnalyzer::findTypeByMethodParameter($calledOnType, $objectCall->getFunctionName(), $argumentNumber);
         if ($argument->getType() == $argumentTargetType) {
             ++$argumentNumber;
             continue;
             //Same type matched. We do not need to do anything :)
         }
         /**
          * todo - maybe we should move getReferencesTo() to TES5Value and make all of the rest TES5Values just have null references as they do not reference anything? :)
          */
         if (TES5InheritanceGraphAnalyzer::isExtending($argumentTargetType, $argument->getType()->getNativeType()) && $argument instanceof TES5Referencer) {
             //HACKY!
             $this->inferenceType($argument->getReferencesTo(), $argumentTargetType, $multipleScriptsScope);
         } else {
             //So there's one , one special case where we actually have to cast a var from one to another even though they are not ,,inheriting" from themselves, because they are primitives.
             //Scenario: there's an T_INT argument, and we feed it with a T_FLOAT variable reference. It won't work :(
             //We need to cast it on call level ( NOT inference it ) to make it work and not break other possible scenarios ( more specifically, when a float would be inferenced to int and there's a
             //float assigment somewhere in the code )
             if ($argumentTargetType == TES5BasicType::T_INT() && $argument->getType() == TES5BasicType::T_FLOAT()) {
                 if ($argument instanceof TES5Reference) {
                     //HACKY! When we'll clean up this interface, it will dissapear :)
                     $argument->setManualCastTo(TES5BasicType::T_INT());
                 }
             }
         }
         ++$argumentNumber;
     }
 }
 public function createCodeChunk(TES4VariableDeclarationList $chunk, TES5CodeScope $codeScope)
 {
     foreach ($chunk->getVariableList() as $variable) {
         switch ($variable->getVariableType()) {
             case TES4Type::T_FLOAT():
                 $property = new TES5LocalVariable($variable->getVariableName(), TES5BasicType::T_FLOAT());
                 break;
             case TES4Type::T_INT():
             case TES4Type::T_SHORT():
             case TES4Type::T_LONG():
                 $property = new TES5LocalVariable($variable->getVariableName(), TES5BasicType::T_INT());
                 break;
             case TES4Type::T_REF():
                 //most basic one, if something from inherited class is used, we will set to the inheriting class
                 $property = new TES5LocalVariable($variable->getVariableName(), TES5BasicType::T_FORM());
                 break;
             default:
                 throw new ConversionException("Unknown local variable declaration type.");
         }
         $codeScope->getLocalScope()->addVariable($property);
     }
     return null;
 }
 public function createFromBlockType($blockType, TES5GlobalScope $globalScope)
 {
     $localScope = new TES5LocalScope();
     switch ($blockType) {
         case 'OnUpdate':
             break;
         case 'OnActivate':
             $localScope->addVariable(new TES5LocalVariable("akActivateRef", TES5BasicType::T_OBJECTREFERENCE(), [TES5LocalVariableParameterMeaning::ACTIVATOR()]));
             break;
         case 'OnInit':
             break;
         case 'OnSell':
             $localScope->addVariable(new TES5LocalVariable("akSeller", TES5BasicType::T_ACTOR(), [TES5LocalVariableParameterMeaning::ACTIVATOR()]));
             break;
         case 'OnDeath':
             $localScope->addVariable(new TES5LocalVariable("akKiller", TES5BasicType::T_ACTOR(), [TES5LocalVariableParameterMeaning::ACTIVATOR()]));
             break;
         case 'OnLoad':
             break;
         case 'OnObjectEquipped':
             $localScope->addVariable(new TES5LocalVariable("akBaseObject", TES5BasicType::T_FORM(), [TES5LocalVariableParameterMeaning::CONTAINER()]));
             $localScope->addVariable(new TES5LocalVariable("akReference", TES5BasicType::T_OBJECTREFERENCE()));
             break;
         case 'OnTriggerEnter':
             $localScope->addVariable(new TES5LocalVariable("akActivateRef", TES5BasicType::T_OBJECTREFERENCE(), [TES5LocalVariableParameterMeaning::ACTIVATOR(), TES5LocalVariableParameterMeaning::CONTAINER()]));
             break;
         case 'OnEquipped':
             $localScope->addVariable(new TES5LocalVariable("akActor", TES5BasicType::T_ACTOR(), [TES5LocalVariableParameterMeaning::ACTIVATOR(), TES5LocalVariableParameterMeaning::CONTAINER()]));
             break;
         case 'OnUnequipped':
             $localScope->addVariable(new TES5LocalVariable("akActor", TES5BasicType::T_ACTOR(), [TES5LocalVariableParameterMeaning::ACTIVATOR()]));
             break;
         case 'OnContainerChanged':
             $localScope->addVariable(new TES5LocalVariable("akNewContainer", TES5BasicType::T_OBJECTREFERENCE()));
             $localScope->addVariable(new TES5LocalVariable("akOldContainer", TES5BasicType::T_OBJECTREFERENCE()));
             break;
         case 'OnTrigger':
             $localScope->addVariable(new TES5LocalVariable("akActivateRef", TES5BasicType::T_OBJECTREFERENCE(), [TES5LocalVariableParameterMeaning::ACTIVATOR()]));
             break;
         case 'OnHit':
             $localScope->addVariable(new TES5LocalVariable("akAggressor", TES5BasicType::T_OBJECTREFERENCE(), [TES5LocalVariableParameterMeaning::ACTIVATOR()]));
             $localScope->addVariable(new TES5LocalVariable("akSource", TES5BasicType::T_FORM()));
             $localScope->addVariable(new TES5LocalVariable("akProjectile", TES5BasicType::T_PROJECTILE()));
             $localScope->addVariable(new TES5LocalVariable("abPowerAttack", TES5BasicType::T_BOOL()));
             $localScope->addVariable(new TES5LocalVariable("abSneakAttack", TES5BasicType::T_BOOL()));
             $localScope->addVariable(new TES5LocalVariable("abBashAttack", TES5BasicType::T_BOOL()));
             $localScope->addVariable(new TES5LocalVariable("abHitBlocked", TES5BasicType::T_BOOL()));
             break;
         case 'OnCombatStateChanged':
             $localScope->addVariable(new TES5LocalVariable("akTarget", TES5BasicType::T_ACTOR(), [TES5LocalVariableParameterMeaning::ACTIVATOR()]));
             $localScope->addVariable(new TES5LocalVariable("aeCombatState", TES5BasicType::T_INT()));
             break;
         case 'OnPackageStart':
             $localScope->addVariable(new TES5LocalVariable("akNewPackage", TES5BasicType::T_PACKAGE()));
             break;
         case 'OnPackageDone':
             $localScope->addVariable(new TES5LocalVariable("akDonePackage", TES5BasicType::T_PACKAGE()));
             break;
         case 'OnPackageEnd':
             $localScope->addVariable(new TES5LocalVariable("akOldPackage", TES5BasicType::T_PACKAGE()));
             break;
         case 'OnPackageChange':
             $localScope->addVariable(new TES5LocalVariable("akOldPackage", TES5BasicType::T_PACKAGE()));
             break;
         case 'OnMagicEffectApply':
             $localScope->addVariable(new TES5LocalVariable("akCaster", TES5BasicType::T_OBJECTREFERENCE(), [TES5LocalVariableParameterMeaning::ACTIVATOR()]));
             $localScope->addVariable(new TES5LocalVariable("akMagicEffect", TES5BasicType::T_MAGICEFFECT()));
             break;
         case 'OnReset':
             break;
         case 'OnEffectStart':
             $localScope->addVariable(new TES5LocalVariable("akTarget", TES5BasicType::T_ACTOR()));
             $localScope->addVariable(new TES5LocalVariable("akCaster", TES5BasicType::T_ACTOR(), [TES5LocalVariableParameterMeaning::ACTIVATOR()]));
             break;
         case 'OnEffectFinish':
             $localScope->addVariable(new TES5LocalVariable("akTarget", TES5BasicType::T_ACTOR()));
             $localScope->addVariable(new TES5LocalVariable("akCaster", TES5BasicType::T_ACTOR(), [TES5LocalVariableParameterMeaning::ACTIVATOR()]));
             break;
         default:
             throw new ConversionException("Cannot find new block type local scope variables out of " . $blockType);
     }
     return $localScope;
 }
 public function getType()
 {
     return TES5BasicType::T_BOOL();
 }
 /**
  * Extracts implicit reference from calls.
  * Returns a reference from calls like:
  * Enable
  * Disable
  * Activate
  * GetInFaction whatsoever
  * @param TES5GlobalScope $globalScope
  * @param TES5MultipleScriptsScope $multipleScriptsScope
  * @param TES5LocalScope $localScope
  * @return TES5Referencer
  * @throws \Ormin\OBSLexicalParser\TES5\Exception\ConversionException
  */
 private function extractImplicitReference(TES5GlobalScope $globalScope, TES5MultipleScriptsScope $multipleScriptsScope, TES5LocalScope $localScope)
 {
     switch ($globalScope->getScriptHeader()->getBasicScriptType()) {
         case TES5BasicType::T_OBJECTREFERENCE():
             return $this->referenceFactory->createReferenceToSelf($globalScope);
         case TES5BasicType::T_ACTIVEMAGICEFFECT():
             $self = $this->referenceFactory->createReferenceToSelf($globalScope);
             return $this->createObjectCall($self, "GetTargetActor", $multipleScriptsScope);
         case TES5BasicType::T_QUEST():
             //todo - this should not be done like this
             //we should actually not try to extract the implicit reference on the non-reference oblivion functions like "stopQuest"
             //think of this line as a hacky way to just get code forward.
             return $this->referenceFactory->createReferenceToSelf($globalScope);
             /**
              * TIF Fragments
              */
         /**
          * TIF Fragments
          */
         case TES5BasicType::T_TOPICINFO():
             return $this->createReadReference('akSpeakerRef', $globalScope, $multipleScriptsScope, $localScope);
         default:
             throw new ConversionException("Cannot extract implicit reference - unknown basic script type.");
     }
 }
 /**
  * @param string $EDID
  * @return TES5Type
  * @throws ConversionException
  */
 public function getFormTypeByEDID($EDID)
 {
     $len = strlen($EDID);
     $len = $len + 1;
     $hex = dechex($len);
     if (strlen($hex) == 1) {
         $hex = '0' . $hex;
     }
     preg_match("#EDID\\x{" . $hex . "}." . $EDID . "\\x{00}#i", $this->esm, $matches, PREG_OFFSET_CAPTURE);
     if (isset($matches[0])) {
         $offset = $matches[0][1] - 20;
         $type = substr($this->esm, $offset, 4);
         return TypeMapper::map($type);
     } else {
         $npc = $this->getNpcByEDID($EDID);
         if ($npc === null) {
             throw new ConversionException("Cannot find type for EDID " . $EDID);
         }
         return TES5BasicType::T_ACTOR();
     }
 }
 /**
  * @param TES4CodeBlock $block
  * @param TES5EventBlockList $blockList
  * @param TES5EventCodeBlock $newBlock
  * @param TES5MultipleScriptsScope $multipleScriptsScope
  * @param TES5GlobalScope $globalScope
  */
 public function modify(TES4CodeBlock $block, TES5EventBlockList $blockList, TES5EventCodeBlock $newBlock, TES5GlobalScope $globalScope, TES5MultipleScriptsScope $multipleScriptsScope)
 {
     $blockLocalScope = $newBlock->getLocalScope();
     switch (strtolower($block->getBlockType())) {
         case "gamemode":
         case 'scripteffectupdate':
             $onInitLocalScope = $this->blockLocalScopeFactory->createFromBlockType("OnInit", $globalScope);
             $newInitBlock = new TES5EventCodeBlock("OnInit", $onInitLocalScope, $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($onInitLocalScope)));
             $args = new TES5ObjectCallArguments();
             $args->add(new TES5Float(self::ON_UPDATE_TICK));
             $function = $this->valueFactory->createObjectCall($this->referenceFactory->createReferenceToSelf($globalScope), "RegisterForUpdate", $multipleScriptsScope, $args);
             $newInitBlock->addChunk($function);
             $blockList->add($newInitBlock);
             break;
         case "onactivate":
             $onInitLocalScope = $this->blockLocalScopeFactory->createFromBlockType("OnInit", $globalScope);
             $newInitBlock = new TES5EventCodeBlock("OnInit", $onInitLocalScope, $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($onInitLocalScope)));
             $function = $this->valueFactory->createObjectCall($this->referenceFactory->createReferenceToSelf($globalScope), "BlockActivation", $multipleScriptsScope);
             $newInitBlock->addChunk($function);
             $blockList->add($newInitBlock);
             break;
         case 'onactorequip':
             $parameterList = $block->getBlockParameterList();
             if ($parameterList == null) {
                 break;
             }
             $parameterList = $parameterList->getVariableList();
             $tesEquippedTarget = $parameterList[0];
             $localScope = $newBlock->getCodeScope()->getLocalScope();
             $newContainer = $this->valueFactory->createReadReference($tesEquippedTarget->getBlockParameter(), $globalScope, $multipleScriptsScope, $localScope);
             $expression = $this->expressionFactory->createArithmeticExpression($this->referenceFactory->createReferenceToVariable($localScope->findVariableWithMeaning(TES5LocalVariableParameterMeaning::CONTAINER())), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), $newContainer);
             $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope));
             $outerBranchCode = unserialize(serialize($newBlock->getCodeScope()));
             $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope());
             $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode)));
             $newBlock->setCodeScope($newCodeScope);
             break;
         case "ontriggeractor":
             $parameterList = $block->getBlockParameterList();
             $localScope = $newBlock->getCodeScope()->getLocalScope();
             $activator = $localScope->findVariableWithMeaning(TES5LocalVariableParameterMeaning::ACTIVATOR());
             $castedToActor = new TES5LocalVariable("akAsActor", TES5BasicType::T_ACTOR());
             $referenceToCastedVariable = $this->referenceFactory->createReferenceToVariable($castedToActor);
             $referenceToNonCastedVariable = $this->referenceFactory->createReferenceToVariable($activator);
             $expression = $this->expressionFactory->createArithmeticExpression($referenceToCastedVariable, TES5ArithmeticExpressionOperator::OPERATOR_NOT_EQUAL(), new TES5None());
             $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope));
             $newCodeScope->getLocalScope()->addVariable($castedToActor);
             $newCodeScope->add($this->assignationFactory->createAssignation($referenceToCastedVariable, $referenceToNonCastedVariable));
             if ($parameterList !== null) {
                 //NOT TESTED
                 $parameterList = $parameterList->getVariableList();
                 $targetActor = $this->valueFactory->createReadReference($parameterList[0]->getBlockParameter(), $globalScope, $multipleScriptsScope, $localScope);
                 $interExpression = $this->expressionFactory->createArithmeticExpression($this->referenceFactory->createReferenceToVariable($activator), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), $targetActor);
                 $interBranchCode = unserialize(serialize($newBlock->getCodeScope()));
                 $outerBranchCode = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($newCodeScope->getLocalScope()));
                 $interBranchCode->getLocalScope()->setParentScope($outerBranchCode->getLocalScope());
                 $outerBranchCode->add(new TES5Branch(new TES5SubBranch($interExpression, $interBranchCode)));
             } else {
                 $outerBranchCode = unserialize(serialize($newBlock->getCodeScope()));
                 $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope());
             }
             $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode)));
             $newBlock->setCodeScope($newCodeScope);
             break;
         case 'onadd':
             $parameterList = $block->getBlockParameterList();
             if ($parameterList == null) {
                 break;
             }
             $parameterList = $parameterList->getVariableList();
             $tesEquippedTarget = $parameterList[0];
             $localScope = $newBlock->getCodeScope()->getLocalScope();
             $newContainer = $this->valueFactory->createReadReference($tesEquippedTarget->getBlockParameter(), $globalScope, $multipleScriptsScope, $localScope);
             $expression = $this->expressionFactory->createArithmeticExpression($this->referenceFactory->createReferenceToVariable($localScope->getVariableByName("akNewContainer")), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), $newContainer);
             $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope));
             $outerBranchCode = unserialize(serialize($newBlock->getCodeScope()));
             $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope());
             $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode)));
             $newBlock->setCodeScope($newCodeScope);
             break;
         case 'ondrop':
             $parameterList = $block->getBlockParameterList();
             if ($parameterList == null) {
                 break;
             }
             $parameterList = $parameterList->getVariableList();
             $tesEquippedTarget = $parameterList[0];
             $localScope = $newBlock->getCodeScope()->getLocalScope();
             $newContainer = $this->valueFactory->createReadReference($tesEquippedTarget->getBlockParameter(), $globalScope, $multipleScriptsScope, $localScope);
             $expression = $this->expressionFactory->createArithmeticExpression($this->referenceFactory->createReferenceToVariable($localScope->getVariableByName("akOldContainer")), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), $newContainer);
             $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope));
             $outerBranchCode = unserialize(serialize($newBlock->getCodeScope()));
             $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope());
             $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode)));
             $newBlock->setCodeScope($newCodeScope);
             break;
         case 'onpackagestart':
             $parameterList = $block->getBlockParameterList();
             if ($parameterList == null) {
                 break;
             }
             $parameterList = $parameterList->getVariableList();
             $tesEquippedTarget = $parameterList[0];
             $localScope = $newBlock->getCodeScope()->getLocalScope();
             $newContainer = $this->valueFactory->createReadReference($tesEquippedTarget->getBlockParameter(), $globalScope, $multipleScriptsScope, $localScope);
             $expression = $this->expressionFactory->createArithmeticExpression($this->referenceFactory->createReferenceToVariable($localScope->getVariableByName("akNewPackage")), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), $newContainer);
             $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope));
             $outerBranchCode = unserialize(serialize($newBlock->getCodeScope()));
             $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope());
             $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode)));
             $newBlock->setCodeScope($newCodeScope);
             break;
         case 'onpackagedone':
         case 'onpackagechange':
         case 'onpackageend':
             $parameterList = $block->getBlockParameterList()->getVariableList();
             $tesEquippedTarget = $parameterList[0];
             $localScope = $newBlock->getCodeScope()->getLocalScope();
             $newContainer = $this->valueFactory->createReadReference($tesEquippedTarget->getBlockParameter(), $globalScope, $multipleScriptsScope, $localScope);
             $expression = $this->expressionFactory->createArithmeticExpression($this->referenceFactory->createReferenceToVariable($localScope->getVariableByName("akOldPackage")), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), $newContainer);
             $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope));
             $outerBranchCode = unserialize(serialize($newBlock->getCodeScope()));
             $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope());
             $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode)));
             $newBlock->setCodeScope($newCodeScope);
             break;
         case 'onalarm':
             //@INCONSISTENCE - We don't account for alarm type.
             $expression = $this->expressionFactory->createArithmeticExpression($this->valueFactory->createObjectCall($this->referenceFactory->createReferenceToSelf($globalScope), "IsAlarmed", $multipleScriptsScope), TES5ArithmeticExpressionOperator::OPERATOR_EQUAL(), new TES5Bool(true));
             $newCodeScope = $this->codeScopeFactory->createCodeScope($this->blockLocalScopeFactory->createRecursiveScope($blockLocalScope));
             $outerBranchCode = unserialize(serialize($newBlock->getCodeScope()));
             $outerBranchCode->getLocalScope()->setParentScope($newCodeScope->getLocalScope());
             $newCodeScope->add(new TES5Branch(new TES5SubBranch($expression, $outerBranchCode)));
             $newBlock->setCodeScope($newCodeScope);
             break;
             /**
             
                     case 'onalarm':
                     {
             
             $this->skyrimGroupEventName = 'onhit';
             
             if ($this->eventArgs[1] != 3) {
                 //Nothing eelse is supported really..
                 $this->omit = true;
                 break;
             }
             
             $branch = new TES4ConditionalBranch();
             $expression = new TES4Expression();
             $leftConstant = new TES4Constant("akAggressor", "ObjectReference");
             //                $actionConstant        = new TES4Constant($this->eventArgs[1],"Package");
             
             $actionConstant = TES4Factories::createReference($this->eventArgs[2], $this);
             
             $expression->left_side = $leftConstant;
             $expression->right_side = $actionConstant;
             $expression->comparision_operator = TES4Expression::COMPARISION_OPERATOR_EQUAL;
             
             $codeBlock = new TES4CodeBlock();
             $codeBlock->chunks = $this->chunks;
             
             $branch->ifs[] = array(
                 'rawExpression' => 'SCRIPT_GENERATED',
                 'expression' => $expression,
                 'codeBlock' => $codeBlock
             );
             $this->chunks = new TES4ChunkContainer();
             $this->chunks->parent = $this;
             $this->chunks->addChunk($branch);
             
             break;
                     }
             */
     }
 }
Ejemplo n.º 14
0
 public function getType()
 {
     return TES5BasicType::T_FORM();
 }
 /**
  * Create a generic-purpose reference.
  * @param $referenceName
  * @param TES5GlobalScope $globalScope
  * @param TES5MultipleScriptsScope $multipleScriptsScope
  * @param TES5LocalScope $localScope
  * @return \Ormin\OBSLexicalParser\TES5\AST\Object\TES5ObjectProperty|TES5PlayerReference|TES5Reference
  */
 public function createReference($referenceName, TES5GlobalScope $globalScope, TES5MultipleScriptsScope $multipleScriptsScope, TES5LocalScope $localScope)
 {
     //Papyrus compiler somehow treats properties with ,,temp" in them in a special way, so we change them to tmp to accomodate that.
     if (preg_match('#temp#', $referenceName)) {
         $referenceName = preg_replace("#temp#i", "tmp", $referenceName);
     }
     if (strtolower($referenceName) == "player") {
         return $this->createReferenceToPlayer();
     }
     if (preg_match("#([0-9a-zA-Z]+)\\.([0-9a-zA-Z]+)#i", $referenceName, $matches)) {
         $mainReference = $this->createReference($matches[1], $globalScope, $multipleScriptsScope, $localScope);
         $propertyReference = $this->objectPropertyFactory->createObjectProperty($multipleScriptsScope, $mainReference, $matches[2]);
         //Todo rethink the prefix adding
         return $propertyReference;
     }
     $property = $localScope->getVariableByName($referenceName);
     if ($property === null) {
         $property = $globalScope->getPropertyByName($referenceName);
         //todo rethink how to unify the prefix searching
         if ($property === null) {
             foreach ($this->special_conversions as $special_conversion_name => $special_type) {
                 if ($special_conversion_name == $referenceName) {
                     $property = new TES5Property($referenceName, $special_type, $referenceName);
                     break;
                 }
             }
             if ($property === null) {
                 if (!$globalScope->hasGlobalVariable($referenceName)) {
                     $property = new TES5Property($referenceName, TES5BasicType::T_FORM(), $referenceName);
                 } else {
                     $property = new TES5Property($referenceName, TES5BasicType::T_GLOBALVARIABLE(), $referenceName);
                 }
             }
             $globalScope->add($property);
         }
     }
     return new TES5Reference($property);
 }
Ejemplo n.º 16
0
 public function getType()
 {
     return TES5BasicType::T_STRING();
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     set_time_limit(10800);
     $target = 'Standalone';
     $errorLog = fopen("graph_error_log", "w+");
     $log = fopen("graph_debug_log", "w+");
     $buildTarget = BuildTargetFactory::get($target);
     if (count(array_slice(scandir($buildTarget->getWorkspacePath()), 2)) > 0 || count(array_slice(scandir($buildTarget->getTranspiledPath()), 2)) > 0 || count(array_slice(scandir($buildTarget->getArtifactsPath()), 2)) > 0) {
         $output->writeln("Target " . $target . " current build dir not clean, archive it manually.");
         return;
     }
     $sourceFiles = array_slice(scandir($buildTarget->getSourcePath()), 2);
     $inferencer = new TES5TypeInferencer(new ESMAnalyzer(new TypeMapper()), $buildTarget->getSourcePath());
     $dependencyGraph = [];
     $usageGraph = [];
     $progressBar = new CliProgressBar(count($sourceFiles));
     $progressBar->display();
     foreach ($sourceFiles as $sourceFile) {
         try {
             $scriptName = substr($sourceFile, 0, -4);
             $AST = $buildTarget->getAST($buildTarget->getSourceFromPath($scriptName));
             /**
              * @var TES4ObjectProperty[] $propertiesAccesses
              */
             $propertiesAccesses = [];
             $AST->filter(function ($data) use(&$propertiesAccesses) {
                 if ($data instanceof TES4ObjectProperty) {
                     $propertiesAccesses[] = $data;
                 }
             });
             /**
              * @var TES5Property[] $preparedProperties
              */
             $preparedProperties = [];
             /**
              * @var TES5Type[] $preparedPropertiesTypes
              */
             $preparedPropertiesTypes = [];
             foreach ($propertiesAccesses as $property) {
                 preg_match("#([0-9a-zA-Z]+)\\.([0-9a-zA-Z]+)#i", $property->getData(), $matches);
                 $propertyName = $matches[1];
                 $propertyKeyName = strtolower($propertyName);
                 if (!isset($preparedProperties[$propertyKeyName])) {
                     $preparedProperty = new TES5Property($propertyName, TES5BasicType::T_FORM(), $matches[1]);
                     $preparedProperties[$propertyKeyName] = $preparedProperty;
                     $inferencingType = $inferencer->resolveInferenceTypeByReferenceEdid($preparedProperty);
                     $preparedPropertiesTypes[$propertyKeyName] = $inferencingType;
                 } else {
                     $preparedProperty = $preparedProperties[$propertyKeyName];
                     $inferencingType = $inferencer->resolveInferenceTypeByReferenceEdid($preparedProperty);
                     if ($inferencingType != $preparedPropertiesTypes[$propertyKeyName]) {
                         throw new ConversionException("Cannot settle up the properties types - conflict.");
                     }
                 }
             }
             fwrite($log, $scriptName . " - " . count($preparedProperties) . " prepared" . PHP_EOL);
             foreach ($preparedProperties as $preparedPropertyKey => $preparedProperty) {
                 //Only keys are lowercased.
                 $lowerPropertyType = strtolower($preparedPropertiesTypes[$preparedPropertyKey]->value());
                 $lowerScriptType = strtolower($scriptName);
                 if (!isset($dependencyGraph[$lowerPropertyType])) {
                     $dependencyGraph[$lowerPropertyType] = [];
                 }
                 $dependencyGraph[$lowerPropertyType][] = $lowerScriptType;
                 if (!isset($usageGraph[$lowerScriptType])) {
                     $usageGraph[$lowerScriptType] = [];
                 }
                 $usageGraph[$lowerScriptType][] = $lowerPropertyType;
                 fwrite($log, 'Registering a dependency from ' . $scriptName . ' to ' . $preparedPropertiesTypes[$preparedPropertyKey]->value() . PHP_EOL);
             }
             $progressBar->progress();
         } catch (\Exception $e) {
             fwrite($errorLog, $sourceFile . PHP_EOL . $e->getMessage());
             continue;
         }
     }
     $progressBar->end();
     $graph = new TES5ScriptDependencyGraph($dependencyGraph, $usageGraph);
     file_put_contents('app/graph', serialize($graph));
     fclose($errorLog);
     fclose($log);
 }
 public function getType()
 {
     return TES5BasicType::T_STRING();
     //concatenated value is always a string ( what else.. :) )
 }
 public function getType()
 {
     return TES5BasicType::T_ACTOR();
 }