public MetadataFile Clone(AinFile ainFile) { var clone = new MetadataFile(ainFile); foreach (var pair in this.EnumerationTypes) { clone.EnumerationTypes.Add(pair.Key, pair.Value.Clone()); } foreach (var pair in this.Metadata) { var variable = pair.Key.Canonicalize(ainFile); if (variable != null) { var metaData = pair.Value.Clone(); if (metaData.FuncTypeIndex != -1) { var funcType = this.ainFile.GetFuncType(metaData.FuncTypeIndex); if (funcType != null) { var otherFuncType = ainFile.GetFuncType(funcType.Name); int newFuncTypeIndex = otherFuncType.Index; metaData.FuncTypeIndex = newFuncTypeIndex; } } clone.Metadata.Add(variable, metaData); } } return(clone); }
/// <summary> /// Checks if a variable object is a reference to a variable registered in the AinFile, and returns the original variable from the AinFile if it exists, otherwise returns null. /// </summary> /// <param name="variable">The variable to find</param> /// <param name="ainFile">The AinFile to find the variable in.</param> /// <returns>returns the original variable from the AinFile if it exists, otherwise returns null</returns> public static IVariable Canonicalize(this IVariable variable, AinFile ainFile) { int index = variable.Index; int parentIndex = -1; if (variable == null || ainFile == null) { return(null); } var root = variable.Root; var parent = variable.Parent; if (parent != null) { parentIndex = parent.Index; } if (root == ainFile || root == null) { if (parent is Function) { if (parent.Name.StartsWith("system.")) { return(AinFile.GetSystemCallParameter(parentIndex, index)); } return(ainFile.GetFunctionParameter(parentIndex, index)); } if (parent is Struct) { return(ainFile.GetStructMember(parentIndex, index)); } if (variable is Global) { return(ainFile.GetGlobal(index)); } if (parent is FunctionType) { return(ainFile.GetFuncTypeParameter(parentIndex, index)); } if (parent is HllFunction) { if (parent.Parent != null) { return(ainFile.GetLibraryFunctionParameter(parent.Parent.Index, parentIndex, index)); } else { return(null); } } if (variable is Function) { if (variable.Name.StartsWith("system.")) { return(AinFile.GetSystemCall(index)); } return(ainFile.GetFunction(index)); } if (variable is Struct) { return(ainFile.GetStruct(index)); } if (variable is HllFunction) { return(ainFile.GetLibraryFunction(parentIndex, index)); } if (variable is FunctionType) { return(ainFile.GetFuncType(index)); } } else { if (parent is Function) { if (parent.Name.StartsWith("system.")) { return(AinFile.GetSystemCallParameter(parentIndex, index)); } return(ainFile.GetFunctionParameter(parent.Name, variable.Name)); } if (variable is Global) { return(ainFile.GetGlobal(variable.Name)); } if (parent is Struct) { return(ainFile.GetStructMember(parent.Name, variable.Name)); } if (parent is FunctionType) { return(ainFile.GetFuncTypeParameter(parent.Name, variable.Index)); } if (parent is HllFunction) { if (parent.Parent != null) { return(ainFile.GetLibraryFunctionParameter(parent.Parent.Name, parent.Name, index)); } else { return(null); } } if (variable is Function) { if (variable.Name.StartsWith("system.")) { return(AinFile.GetSystemCall(index)); } return(ainFile.GetFunction(variable.Name)); } if (variable is Struct) { return(ainFile.GetStruct(variable.Name)); } if (variable is HllFunction) { return(ainFile.GetLibraryFunction(parent.Name, variable.Name)); } if (variable is FunctionType) { return(ainFile.GetFuncType(variable.Name)); } } return(null); }
private void ReadMetadata() { //quit if we're not attached to anything if (variable == null || ainFile == null) { return; } //display variable name declaration this.VariableTextBox.ReadOnly = false; this.VariableTextBox.Text = variable.ToString(); this.VariableTextBox.SelectionStart = 0; this.VariableTextBox.SelectionLength = 0; this.VariableTextBox.ScrollToCaret(); this.VariableTextBox.ReadOnly = true; //get metadata or use a blank variable Metadata metaData; if (ainFile.MetadataFile.Metadata.ContainsKey(variable)) { metaData = ainFile.MetadataFile.Metadata[variable]; } else { metaData = new Metadata(); } //set alternative name - either the default for what is specified string defaultAlternativeName = ainFile.AlternativeNames.GetOrNull(variable.Name); AlternativeNameTextBox.Text = metaData.ReplacementName ?? defaultAlternativeName; //is this a function parameter? Allow a default value if (variable.Parent is Function && variable.Index < variable.Parent.ParameterCount) { this.currentDefaultValue = metaData.DefaultValue; } else if (variable is Global) { //if it's a global, display the initial value specified in the AIN file, and don't allow editing this.currentDefaultValue = ainFile.GlobalInitialValues.Where(i => i.GlobalVariable == variable).FirstOrDefault(); } else { //DefaultValueTextBox.ReadOnly = true; findDefaultValueButton.Enabled = false; } if (this.currentDefaultValue != null) { string defaultValueString = this.currentDefaultValue.GetValue(); DefaultValueTextBox.Text = defaultValueString; if (variable is Global) { //DefaultValueTextBox.ReadOnly = true; findDefaultValueButton.Enabled = false; } } //get enumeration type EnumerationType enumerationType = null; if (variable.DataType.GetTypeOfArrayElement().IsInteger()) { enumerationType = metaData.EnumerationType; if (enumerationType != null) { EnumerationTypeComboBox.Text = enumerationType.Name; } } else if (variable.DataType.IsFunction()) { EditEnumerationTypeButton.Visible = false; spreadEnumerationTypeButton.Visible = false; if (variable.DataType.IsFuncType()) { int structType = variable.StructType; if (metaData.FuncTypeIndex != -1) { structType = metaData.FuncTypeIndex; } var functionType = ainFile.GetFuncType(structType); if (functionType != null) { EnumerationTypeComboBox.Text = functionType.ToString(); } } else //it's a delegate { int structType = variable.StructType; if (metaData.FuncTypeIndex != -1) { structType = metaData.FuncTypeIndex; } var delegateType = ainFile.Delegates.GetOrNull(structType); if (delegateType != null) { EnumerationTypeComboBox.Text = delegateType.ToString(); } } } else { EnumerationTypeComboBox.Enabled = false; EditEnumerationTypeButton.Enabled = false; spreadEnumerationTypeButton.Enabled = false; } //get description DescriptionTextBox.Text = metaData.Description ?? ""; }
private bool FindFunctionTypeForVariable(IVariable variable, Expression code, bool MakeNewStuffUp) { bool variableIsFunction = variable as Function != null; bool variableIsFuncType = variable.DataType.IsFuncType(); bool variableIsDelegate = variable.DataType.IsDelegate(); foreach (var e in code.GetChildExpressions()) { Expression otherExpression = null; IVariable expVariable = null; if (e.ExpressionType == Instruction.CALLFUNC2 && variableIsFuncType) { bool isVoid = e.IsVoidContext(); if (!isVoid) { otherExpression = e.GetOtherSideOfBinaryExpression(); } IVariable otherExpressionVariable = null; if (otherExpression != null) { otherExpressionVariable = otherExpression.Variable; } DataType otherExpressionDataType = DataType.Void; int otherExpressionStructType = -1; if (otherExpressionVariable != null) { otherExpressionDataType = otherExpressionVariable.DataType; otherExpressionStructType = otherExpressionVariable.StructType; } else { if (isVoid) { otherExpressionDataType = DataType.Void; } else { otherExpressionDataType = DataType.AnyNonVoidType; } } var argExpressions = (e.Arg3 ?? Expression.Empty).FlattenContainerExpression(Instruction.Comma).ToArray(); var variables = GetVariablesFromExpressions(argExpressions); var matchingFuncTypes = ainFile.MatchingFunctionTypes(otherExpressionDataType, otherExpressionStructType, variables, variables.Length).Distinct().ToArray(); var firstMatchingFuncType = matchingFuncTypes.FirstOrDefault(); if (firstMatchingFuncType != null) { if (MakeNewStuffUp || matchingFuncTypes.Skip(1).FirstOrDefault() == null) { variable.StructType = firstMatchingFuncType.Index; } } } if (variableIsFunction && e.ExpressionType == Instruction.RETURN) { otherExpression = e.Arg1; expVariable = variable; } else { expVariable = e.Variable; if (variable == expVariable) { otherExpression = e.GetOtherSideOfBinaryExpression(); } } if (otherExpression != null) { Function otherFunction = null; if (otherExpression.ExpressionType == Instruction.PUSH) { otherFunction = ainFile.GetFunction(otherExpression.Value); } else if (otherExpression.ExpressionType == Instruction.S_PUSH) { otherFunction = ainFile.GetFunction(ainFile.GetString(otherExpression.Value)); } else { var otherVariable = otherExpression.Variable; if (otherVariable != null && !variableIsDelegate && otherVariable.DataType.IsFuncType() && otherVariable.StructType != -1) { variable.StructType = otherVariable.StructType; return(true); } if (otherVariable != null && variableIsDelegate && otherVariable.DataType.IsDelegate() && otherVariable.StructType != -1) { variable.StructType = otherVariable.StructType; return(true); } } if (otherFunction != null) { FunctionType matchingFuncType = null; if (!variableIsDelegate) { if (!MakeNewStuffUp) { matchingFuncType = ainFile.GetFuncTypeUnique(otherFunction); } else { matchingFuncType = ainFile.GetFuncType(otherFunction); } if (matchingFuncType != null) { variable.StructType = matchingFuncType.Index; return(true); } } else { if (!MakeNewStuffUp) { matchingFuncType = ainFile.GetDelegateUnique(otherFunction); } else { matchingFuncType = ainFile.GetDelegateType(otherFunction); } if (matchingFuncType != null) { variable.StructType = matchingFuncType.Index; return(true); } } } } else { var functionParameter = e.GetFunctionCallParameter(); if (functionParameter != null) { if (functionParameter != null && !variableIsDelegate && functionParameter.DataType.IsFuncType() && functionParameter.StructType != -1) { variable.StructType = functionParameter.StructType; return(true); } if (functionParameter != null && variableIsDelegate && functionParameter.DataType.IsDelegate() && functionParameter.StructType != -1) { variable.StructType = functionParameter.StructType; return(true); } } else if (variable.DataType.IsArray()) { var parent = e.Parent; if (parent != null && (parent.ExpressionType == Instruction.A_PUSHBACK || parent.ExpressionType == Instruction.A_INSERT)) { var arg2 = parent.Arg2; IVariable var2 = null; if (arg2 != null) { var2 = arg2.Variable; } if (var2 != null) { if (!variableIsDelegate && var2.DataType.IsFuncType() && var2.StructType != -1) { variable.StructType = var2.StructType; return(true); } if (variableIsDelegate && var2.DataType.IsDelegate() && var2.StructType != -1) { variable.StructType = var2.StructType; return(true); } } } } else if (e.ExpressionType == Instruction.CALLFUNC2) { } } } return(false); }