/*public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) * { * TES5LocalScope localScope = codeScope.LocalScope; * ITES5Referencer timerReference = this.referenceFactory.CreateTimerReadReference(globalScope, multipleScriptsScope, localScope); * ITES5Referencer localTimeReference = this.referenceFactory.CreateGSPLocalTimerReadReference(globalScope, multipleScriptsScope, localScope); * TES5ObjectCallArguments methodArguments = new TES5ObjectCallArguments() { calledOn }; * return this.objectCallFactory.CreateObjectCall(timerReference, "getSecondsPassed", multipleScriptsScope, methodArguments); * }*/ public ITES5ValueCodeChunk ConvertFunction(ITES5Referencer calledOn, TES4Function function, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { const string newFunctionName = "GetSecondsPassed"; TES5BasicType returnType = TES5BasicType.T_FLOAT; /*globalScope.AddFunctionIfNotExists(newFunctionName, () => * { * const string getCurrentRealTime = "GetCurrentRealTime"; * TES5FunctionScope newFunctionScope = new TES5FunctionScope(newFunctionName); * TES5LocalScope newLocalScope = TES5LocalScopeFactory.CreateRootScope(newFunctionScope); * TES5CodeScope newCodeScope = TES5CodeScopeFactory.CreateCodeScope(newLocalScope); * TES5GlobalVariable calledYet = new TES5GlobalVariable("GSPCalledYet"); * TES5GlobalVariable lastSeconds = new TES5GlobalVariable("GSPLastSeconds"); * TES5SubBranch ifNotCalledYet = TES5BranchFactory.CreateSubBranch(new TES5ComparisonExpression(calledYet, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Bool(false)), newLocalScope); * ifNotCalledYet.CodeScope.AddChunk(TES5VariableAssignationFactory.CreateAssignation(calledYet, new TES5Bool(true))); * ifNotCalledYet.CodeScope.AddChunk(TES5VariableAssignationFactory.CreateAssignation(lastSeconds, this.objectCallFactory.CreateObjectCall(TES5StaticReference.Utility, getCurrentRealTime, multipleScriptsScope))); * ifNotCalledYet.CodeScope.AddChunk(new TES5Return(new TES5Float(0))); * TES5CodeScope ifCalledYetCodeScope = TES5CodeScopeFactory.CreateCodeScopeRoot(newFunctionScope); * ifCalledYetCodeScope.AddChunk(new TES5Return(new TES5ArithmeticExpression(this.objectCallFactory.CreateObjectCall(TES5StaticReference.Utility, getCurrentRealTime, multipleScriptsScope), TES5ArithmeticExpressionOperator.OPERATOR_SUBSTRACT, lastSeconds))); * TES5ElseSubBranch ifCalledYet = new TES5ElseSubBranch(ifCalledYetCodeScope); * TES5Branch branch = new TES5Branch(ifNotCalledYet, elseBranch: ifCalledYet); * TES5FunctionCodeBlock getSecondsPassedLocalFunction = new TES5FunctionCodeBlock(newFunctionScope, newCodeScope, returnType, true); * getSecondsPassedLocalFunction.AddChunk(branch); * return getSecondsPassedLocalFunction; * });*/ return(this.objectCallFactory.CreateObjectCall(calledOn, newFunctionName, multipleScriptsScope)); }
public BuildScopeCommandQFOrTIF(TES5PropertyFactory propertyFactory, FragmentsReferencesBuilder fragmentsReferencesBuilder, TES5BasicType scriptType, string scriptNamePrefix, TES5FragmentType fragmentType) { this.propertyFactory = propertyFactory; this.fragmentsReferencesBuilder = fragmentsReferencesBuilder; this.scriptType = scriptType; this.scriptNamePrefix = scriptNamePrefix; this.fragmentType = fragmentType; }
public void AddPlayerRefPropertyIfNotExists() { const string name = TES5PlayerReference.PlayerRefName; TES5BasicType playerType = TES5PlayerReference.TES5TypeStatic; TES5Property property = TES5PropertyFactory.ConstructWithTES4FormID(name, playerType, name, TES5PlayerReference.FormID); AddPropertyIfNotExists(property); }
public TES5LocalVariable(string nameWithSuffix, TES5BasicType type, TES5LocalVariableParameterMeaning[] meanings = null) : base(nameWithSuffix, type) { if (meanings == null) { meanings = new TES5LocalVariableParameterMeaning[] { }; } this.Meanings = meanings; }
private static ITES5Type?MemberByValue(string typeName) { if (typeName == TES5VoidType.OriginalNameConst) { return(TES5VoidType.Instance); } TES5BasicType?basicTypeFromName = TES5BasicType.GetFirstOrNullCaseInsensitive(typeName); return(basicTypeFromName); }
public TES5SignatureParameter(string nameWithSuffix, TES5BasicType type, bool hasFixedDeclaration, TES5LocalVariableParameterMeaning[]?meanings = null) { Name = nameWithSuffix; TES5Type = type; declarationType = type; this.hasFixedDeclaration = hasFixedDeclaration; if (meanings == null) { meanings = new TES5LocalVariableParameterMeaning[] { }; } this.Meanings = meanings; }
private static ITES5Type MemberByValue(string typeName, Func <TES5BasicType> basicTypeFunc) { ITES5Type?typeByName = MemberByValue(typeName); if (typeByName != null) { return(typeByName); } TES5BasicType customTypeBase = basicTypeFunc(); return(new TES5CustomType(typeName, TES4Prefix, customTypeBase)); }
private static TES5BasicType?GetCommonBaseTES5Type(IReadOnlyList <TES4Record> tes4Records) { if (!tes4Records.Any()) { return(null); } TES5BasicType[] tes5Types = tes4Records.Select(r => { TES5BasicType basicType = TypeMapper.GetTES5BasicType(r.RecordType); return(basicType); }).ToArray(); TES5BasicType commonBaseType = TES5InheritanceGraphAnalyzer.GetCommonBaseType(tes5Types); return(commonBaseType); }
private void InferenceTypeOfMethodArgument(TES5ObjectCall objectCall, ITES5Value argument, int argumentIndex) { ITES5Type calledOnType = objectCall.AccessedObject.TES5Type.NativeType; /* * Get the argument type according to TES5Inheritance graph. */ TES5BasicType argumentTargetType = TES5InheritanceGraphAnalyzer.FindTypeByMethodParameter(calledOnType.NativeType, objectCall.FunctionName, argumentIndex); if (argument.TES5Type != argumentTargetType) { /* * 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? :) */ ITES5Referencer?referencerArgument = argument as ITES5Referencer; if (referencerArgument != null && TES5InheritanceGraphAnalyzer.IsExtending(argumentTargetType, argument.TES5Type.NativeType)) { //HACKY! if (referencerArgument.ReferencesTo == null) { throw new NullableException(nameof(referencerArgument.ReferencesTo)); } this.InferenceType(referencerArgument.ReferencesTo, argumentTargetType); } 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.TES5Type == TES5BasicType.T_FLOAT) { TES5Castable?argumentCastable = argument as TES5Castable; if (argumentCastable != null) { //HACKY! When we"ll clean up this interface, it will dissapear :) argumentCastable.ManualCastTo = argumentTargetType; } } else if ( !TES5InheritanceGraphAnalyzer.IsExtending(argument.TES5Type, argumentTargetType) && !TES5InheritanceGraphAnalyzer.IsNumberTypeOrBoolAndInt(argument.TES5Type, argumentTargetType) && !(argument is TES5None && TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(argumentTargetType, TES5None.TES5TypeStatic))) { throw new ConversionTypeMismatchException("Argument type mismatch at " + objectCall.FunctionName + " index " + argumentIndex + ". Expected " + argumentTargetType.Name + ". Found " + argument.TES5Type.OriginalName + " : " + argument.TES5Type.NativeType.OriginalName + "."); } } } }
private void InferenceTypeOfCalledObject(TES5ObjectCall objectCall) { /* * Check if we have something to inference inside the code, not some static class or method call return */ if (objectCall.AccessedObject.ReferencesTo == null) { return; } ITES5Type inferencableType = objectCall.AccessedObject.TES5Type.NativeType; //this is not "exactly" nice solution, but its enough. For now. TES5BasicType inferenceType = TES5InheritanceGraphAnalyzer.FindTypeByMethod(objectCall, esmAnalyzer); if (TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(inferencableType, inferenceType)) { return; //We already have the good type. } this.InferenceType(objectCall.AccessedObject.ReferencesTo, inferenceType); }
/* * Try to inference variable"s type with type. * * * Needed for proxifying the properties to other scripts * - Will return true if inferencing succeeded, false otherwise. * @throws ConversionTypeMismatchException */ private void InferenceType(ITES5VariableOrProperty variable, TES5BasicType type) { if (!TES5InheritanceGraphAnalyzer.IsTypeOrExtendsTypeOrIsNumberType(type, variable.TES5Type.NativeType, false)) { if (TES5InheritanceGraphAnalyzer.IsExtending(variable.TES5Type.NativeType, type)) { return; } throw new ConversionTypeMismatchException("Could not extend " + variable.TES5Type.NativeType.Value + " to " + type.Value + "."); } if (variable.TES5Type.AllowInference) { variable.TES5Type = type; } else if (variable.TES5Type.AllowNativeTypeInference) { variable.TES5Type.NativeType = type; } else { throw new ConversionTypeMismatchException(variable.Name + " (" + variable.TES5DeclaredType.OriginalName + " : " + variable.TES5DeclaredType.NativeType.Name + ") could not be inferenced to a " + type.Name + " because inference was not allowed."); } }
/* * @param memberByValue string Type to be created. * @param basicType TES5BasicType You might override the basic type for this custom type created. */ public static ITES5Type MemberByValue(string memberByValue, ITES5Type basicType = null) { if (memberByValue == null) { throw new ArgumentNullException(nameof(memberByValue)); } if (memberByValue == "void") { return(new TES5VoidType()); } TES5BasicType tes5BasicType = TES5BasicType.GetFirstOrNull(PHPFunction.UCWords(memberByValue)); if (tes5BasicType != null) { return(tes5BasicType); } //Ugly - todo: REFACTOR THIS TO NON-STATIC CLASS AND MOVE THIS TO DI if (basicType == null) { ESMAnalyzer analyzer = ESMAnalyzer._instance(); basicType = analyzer.GetScriptType(memberByValue); } return(new TES5CustomType(memberByValue, TES4Prefix, basicType)); }
private static void InferEventBlockContainingType(string functionBlockName, TES5GlobalScope globalScope) { TES5BasicType[]? allowedTypes = eventNameToTypes[functionBlockName];//null indicates that any type is allowed if (allowedTypes == null || allowedTypes.Any(t => TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(globalScope.ScriptHeader.ScriptType, t))) { return; } if (allowedTypes.Length == 1) { TES5BasicType singleAllowedType = allowedTypes[0]; if (globalScope.ScriptHeader.ScriptType.AllowNativeTypeInference && TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(singleAllowedType, globalScope.ScriptHeader.ScriptType.NativeType)) { if (globalScope.ScriptHeader.ScriptType.NativeType != singleAllowedType) { globalScope.ScriptHeader.SetNativeType(singleAllowedType); } return; } } ITES5Type basicScriptType = globalScope.ScriptHeader.ScriptType.NativeType; bool expected = functionBlockName == "OnHit" && TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(basicScriptType, TES5BasicType.T_ACTIVEMAGICEFFECT); throw new ConversionTypeMismatchException("Event " + functionBlockName + " is not allowed on " + globalScope.ScriptHeader.ScriptType.Value + " (" + basicScriptType.Value + ").", expected: expected); }
public ITES5Referencer CreateReference(string referenceName, TES5BasicType typeForNewProperty, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope, TES5LocalScope localScope) { return(CreateReference(referenceName, typeForNewProperty, null, globalScope, multipleScriptsScope, localScope)); }
private ITES5Value ConvertComparisonExpression(ITES4BinaryExpression expression, TES5CodeScope codeScope, TES5GlobalScope globalScope, TES5MultipleScriptsScope multipleScriptsScope) { Tuple <ITES4Value, ITES4Value>[] tes4ValueTuples = new Tuple <ITES4Value, ITES4Value>[] { new Tuple <ITES4Value, ITES4Value>(expression.LeftValue, expression.RightValue), new Tuple <ITES4Value, ITES4Value>(expression.RightValue, expression.LeftValue) }; /* * Scenario 1 - Special functions converted on expression level */ foreach (Tuple <ITES4Value, ITES4Value> tes4ValueTuple in tes4ValueTuples) { ITES4Callable?valueTupleItem1 = tes4ValueTuple.Item1 as ITES4Callable; if (valueTupleItem1 == null) { continue; } TES4Function function = valueTupleItem1.Function; switch (function.FunctionCall.FunctionName.ToLower()) { case "getweaponanimtype": { ITES5Referencer calledOn = this.CreateCalledOnReferenceOfCalledFunction(valueTupleItem1, codeScope, globalScope, multipleScriptsScope); TES5ObjectCall equippedWeaponLeftValue = this.objectCallFactory.CreateObjectCall(this.objectCallFactory.CreateObjectCall(calledOn, "GetEquippedWeapon"), "GetWeaponType"); int[] targetedWeaponTypes; switch ((int)tes4ValueTuple.Item2.Data) { case 0: { targetedWeaponTypes = new int[] { 0 }; break; } case 1: { targetedWeaponTypes = new int[] { 1, 2, 3, 4 }; break; } case 2: { targetedWeaponTypes = new int[] { 5, 6, 8 }; break; } case 3: { targetedWeaponTypes = new int[] { 7, 9 }; break; } default: { throw new ConversionException("GetWeaponAnimType() - Unknown weapon type in expression"); } } List <TES5ComparisonExpression> expressions = new List <TES5ComparisonExpression>(); foreach (var targetedWeaponType in targetedWeaponTypes) { expressions.Add(TES5ExpressionFactory.CreateComparisonExpression(equippedWeaponLeftValue, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Integer(targetedWeaponType))); } ITES5Expression resultExpression = expressions[0]; expressions.RemoveAt(0); while (expressions.Any()) { resultExpression = TES5ExpressionFactory.CreateLogicalExpression(resultExpression, TES5LogicalExpressionOperator.OPERATOR_OR, expressions.Last()); expressions.RemoveAt(expressions.Count - 1); } return(resultExpression); } case "getdetected": { TES5ObjectCallArguments inversedArgument = new TES5ObjectCallArguments() { this.CreateCalledOnReferenceOfCalledFunction(valueTupleItem1, codeScope, globalScope, multipleScriptsScope) }; TES5ObjectCall getDetectedLeftValue = this.objectCallFactory.CreateObjectCall(this.referenceFactory.CreateReadReference(function.Arguments[0].StringValue, globalScope, multipleScriptsScope, codeScope.LocalScope), "isDetectedBy", inversedArgument); TES5Integer getDetectedRightValue = new TES5Integer(((int)tes4ValueTuple.Item2.Data == 0) ? 0 : 1); return(TES5ExpressionFactory.CreateComparisonExpression(getDetectedLeftValue, TES5ComparisonExpressionOperator.OPERATOR_EQUAL, getDetectedRightValue)); } case "getdetectionlevel": { if (!tes4ValueTuple.Item2.HasFixedValue) { throw new ConversionException("Cannot convert getDetectionLevel calls with dynamic comparision"); } TES5Bool tes5Bool = new TES5Bool(((int)tes4ValueTuple.Item2.Data) == 3); //true only if the compared value was 3 TES5ObjectCallArguments inversedArgument = new TES5ObjectCallArguments() { this.CreateCalledOnReferenceOfCalledFunction(valueTupleItem1, codeScope, globalScope, multipleScriptsScope) }; return(TES5ExpressionFactory.CreateComparisonExpression ( this.objectCallFactory.CreateObjectCall(this.referenceFactory.CreateReadReference(function.Arguments[0].StringValue, globalScope, multipleScriptsScope, codeScope.LocalScope), "isDetectedBy", inversedArgument), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, tes5Bool )); } case "getcurrentaiprocedure": { if (!tes4ValueTuple.Item2.HasFixedValue) { throw new ConversionException("Cannot convert getCurrentAIProcedure() calls with dynamic comparision"); } switch ((int)tes4ValueTuple.Item2.Data) { case 4: { return(TES5ExpressionFactory.CreateComparisonExpression( this.objectCallFactory.CreateObjectCall(this.CreateCalledOnReferenceOfCalledFunction(valueTupleItem1, codeScope, globalScope, multipleScriptsScope), "IsInDialogueWithPlayer"), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Bool(expression.Operator == TES4ComparisonExpressionOperator.OPERATOR_EQUAL) //cast to true if the original op was ==, false otherwise. )); } case 8: { //ref.getSleepState() == 3 return(TES5ExpressionFactory.CreateComparisonExpression( this.objectCallFactory.CreateObjectCall(this.CreateCalledOnReferenceOfCalledFunction(valueTupleItem1, codeScope, globalScope, multipleScriptsScope), "getSleepState"), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Integer(3) //SLEEPSTATE_SLEEP )); } case 13: { return(TES5ExpressionFactory.CreateComparisonExpression( this.objectCallFactory.CreateObjectCall(this.CreateCalledOnReferenceOfCalledFunction(valueTupleItem1, codeScope, globalScope, multipleScriptsScope), "IsInCombat"), TES5ComparisonExpressionOperator.OPERATOR_EQUAL, new TES5Bool(expression.Operator == TES4ComparisonExpressionOperator.OPERATOR_EQUAL) //cast to true if the original op was ==, false otherwise. )); } case 0: //Travel case 7: //Wander case 15: //Pursue case 17: //Done { //@INCONSISTENCE idk how to check it tbh. We return always true. Think about better representation return(new TES5Bool(expression.Operator == TES4ComparisonExpressionOperator.OPERATOR_EQUAL)); } default: { throw new ConversionException("Cannot convert GetCurrentAiProcedure - unknown TES4 procedure number arg " + ((int)tes4ValueTuple.Item2.Data).ToString()); } } } case "isidleplaying": case "getknockedstate": case "gettalkedtopc": { return(new TES5Bool(true)); //This is so unimportant that i think it"s not worth to find a good alternative and waste time. } case "getsitting": { //WARNING: Needs to implement Horse sittings, too. //SEE: http://www.gameskyrim.com/papyrus-isridinghorse-function-t255012.html int goTo; switch ((int)tes4ValueTuple.Item2.Data) { case 0: { goTo = 0; break; } case 1: case 2: case 11: case 12: { goTo = 2; break; } case 3: case 13: { goTo = 3; break; } case 4: case 14: { goTo = 4; break; } default: { throw new ConversionException("GetSitting - unknown state found"); } } //ref.getSleepState() == 3 return(TES5ExpressionFactory.CreateComparisonExpression ( this.objectCallFactory.CreateObjectCall(this.CreateCalledOnReferenceOfCalledFunction(valueTupleItem1, codeScope, globalScope, multipleScriptsScope), "GetSitState"), TES5ComparisonExpressionOperator.GetFirst(expression.Operator.Name), new TES5Integer(goTo) )); } } } ITES5Value leftValue = this.CreateValue(expression.LeftValue, codeScope, globalScope, multipleScriptsScope); ITES5Value rightValue = this.CreateValue(expression.RightValue, codeScope, globalScope, multipleScriptsScope); Tuple <ITES5Value, ITES5Value>[] tes5ValueTuples = new Tuple <ITES5Value, ITES5Value>[] { new Tuple <ITES5Value, ITES5Value>(leftValue, rightValue), new Tuple <ITES5Value, ITES5Value>(rightValue, leftValue) }; TES5BasicType objectReferenceType = TES5BasicType.T_FORM; //used just to make sure. TES5ComparisonExpressionOperator op = TES5ComparisonExpressionOperator.GetFirst(expression.Operator.Name); /* * Scenario 2: Comparision of ObjectReferences to integers ( quick formid check ) */ bool flipOperator = false; foreach (var valueTuple in tes5ValueTuples) { TES5ComparisonExpressionOperator newOp = !flipOperator ? op : op.Flip(); if (TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(valueTuple.Item1.TES5Type, objectReferenceType) || TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(valueTuple.Item1.TES5Type.NativeType, objectReferenceType)) { if (valueTuple.Item2.TES5Type == TES5BasicType.T_INT) { //Perhaps we should allow to try to cast upwards for primitives, .asPrimitive() or similar //In case we do know at compile time that we"re comparing against zero, then we can assume //we can compare against None, which allows us not call GetFormID() on most probably None object TES5Integer tes5SetItem2Integer = (TES5Integer)valueTuple.Item2; if (tes5SetItem2Integer.IntValue == 0) { newOp = op == TES5ComparisonExpressionOperator.OPERATOR_EQUAL ? op : TES5ComparisonExpressionOperator.OPERATOR_NOT_EQUAL; return(TES5ExpressionFactory.CreateComparisonExpression(valueTuple.Item1, newOp, new TES5None())); } else { ITES5Referencer callable = (ITES5Referencer)valueTuple.Item1; TES5ObjectCall tes5setNewItem1 = this.objectCallFactory.CreateObjectCall(callable, "GetFormID"); return(TES5ExpressionFactory.CreateComparisonExpression(tes5setNewItem1, newOp, valueTuple.Item2)); } } } else if (valueTuple.Item1.TES5Type.OriginalName == TES5VoidType.OriginalNameConst) { #if PHP_COMPAT TES5IntegerOrFloat tes5SetItem2Number = tes5set.Item2 as TES5IntegerOrFloat; if (tes5SetItem2Number != null && tes5SetItem2Number.ConvertedIntValue == 0) { return(TES5ExpressionFactory.createArithmeticExpression(tes5set.Item1, newOp, new TES5None())); } #else throw new ConversionException("Type was void.");//This shouldn't happen anymore. #endif } if (!TES5InheritanceGraphAnalyzer.IsTypeOrExtendsTypeOrIsNumberType(valueTuple.Item1.TES5Type, valueTuple.Item2.TES5Type, true))//WTM: Change: Added entire if branch { if (valueTuple.Item1.TES5Type.NativeType == TES5BasicType.T_QUEST && valueTuple.Item2.TES5Type == TES5BasicType.T_INT) { TES5ObjectCall getStage = this.objectCallFactory.CreateObjectCall((ITES5Referencer)valueTuple.Item1, "GetStage"); return(TES5ExpressionFactory.CreateComparisonExpression(getStage, newOp, valueTuple.Item2)); } if (valueTuple.Item1.TES5Type == TES5BasicType.T_BOOL && valueTuple.Item2.TES5Type == TES5BasicType.T_INT) { int item2Value = ((TES5Integer)valueTuple.Item2).IntValue; if (item2Value != 0 && item2Value != 1) { throw new ConversionException("Unexpected Value: " + item2Value.ToString()); } ITES5Value newItem2 = new TES5Bool(item2Value == 1); newOp = op == TES5ComparisonExpressionOperator.OPERATOR_EQUAL ? op : TES5ComparisonExpressionOperator.OPERATOR_NOT_EQUAL; return(TES5ExpressionFactory.CreateComparisonExpression(valueTuple.Item1, newOp, newItem2)); } if (valueTuple.Item1.TES5Type == TES5BasicType.T_ACTOR && valueTuple.Item2.TES5Type == TES5BasicType.T_ACTORBASE) { return(TES5ExpressionFactory.CreateComparisonExpression(objectCallFactory.CreateGetActorBase((TES5ObjectCall)valueTuple.Item1), newOp, valueTuple.Item2)); } //WTM: Change: Added for se08barriertriggerscript if (newOp == TES5ComparisonExpressionOperator.OPERATOR_EQUAL && TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(valueTuple.Item1.TES5Type, TES5BasicType.T_FORM) && TES5InheritanceGraphAnalyzer.IsTypeOrExtendsType(valueTuple.Item2.TES5Type, TES5BasicType.T_FORM)) { TES5Reference reference1 = (TES5Reference)valueTuple.Item1; TES5Reference reference2 = (TES5Reference)valueTuple.Item2; reference1.ManualCastTo = TES5BasicType.T_FORM; reference2.ManualCastTo = TES5BasicType.T_FORM; return(TES5ExpressionFactory.CreateComparisonExpression(reference1, newOp, reference2)); } throw new ConversionException("Type could not be converted."); } TES5ComparisonExpression?containsCall = ConvertGetItemCountCallToContainsItemCall(valueTuple.Item1, op, valueTuple.Item2); //WTM: Change: Added if (containsCall != null) { return(containsCall); } flipOperator = true; } return(TES5ExpressionFactory.CreateComparisonExpression(leftValue, op, rightValue)); }
/* * @param memberByValue string Type to be created. * @param basicType TES5BasicType You might override the basic type for this custom type created. */ public static ITES5Type MemberByValue(string typeName, TES5BasicType basicType) { return(MemberByValue(typeName, () => basicType)); }
public TES5LocalVariable(string nameWithSuffix, TES5BasicType type) { Name = nameWithSuffix; TES5Type = type; }
private TES5ArrayType(TES5BasicType elementType) : base(elementType.Name + "[]") { }