/// <summary> /// Compares the current map with the argument map to create a list of /// MoveStatement in base of their information. /// </summary> /// <param name="ifBlockMap">SSAMap to if block.</param> /// <param name="elseBlockMap">SSAMap to else block.</param> /// <param name="filename">File name.</param> /// <param name="line">Line to assign.</param> /// <returns>Returns the list of MoveStatement.</returns> public List <MoveStatement> GetMoveStatementsForIf(SSAMap ifBlockMap, SSAMap elseBlockMap, string filename, int line) { List <MoveStatement> stat = new List <MoveStatement>(); if ((this.map.Count == ifBlockMap.ScopesCount) && (this.map.Count == elseBlockMap.ScopesCount)) { for (int i = 0; i < this.map.Count; i++) { if ((this.map[i].Count == ifBlockMap[i].Count) && (this.map[i].Count == elseBlockMap[i].Count)) { Dictionary <string, SSAElement> .KeyCollection keys = this.map[i].Keys; foreach (string key in keys) { if (((this.map[i][key].IndexSSA == ifBlockMap[i][key].IndexSSA) && (this.map[i][key].IndexSSA != elseBlockMap[i][key].IndexSSA)) || ((ifBlockMap[i][key].IndexSSA == elseBlockMap[i][key].IndexSSA) && (this.map[i][key].IndexSSA != elseBlockMap[i][key].IndexSSA))) { SingleIdentifierExpression right = this.createNewExpression(this, key, i, filename, line); SingleIdentifierExpression left = new SingleIdentifierExpression(key, new Location(filename, 0, 0)); left.IndexOfSSA = elseBlockMap[i][key].IndexSSA + 1; stat.Add(new MoveStatement(left, right, filename, line)); } } } } } return(stat); }
/// <summary> /// Compares the current map with the argument map to create a list of /// MoveStatement in base of their information. /// </summary> /// <param name="mapX">SSAMap to compare.</param> /// <param name="mapY">SSAMap to obtain their values to assign in Move Statements.</param> /// <param name="filename">File name.</param> /// <param name="line">Line to assign.</param> /// <returns>Returns the list of MoveStatement.</returns> public List <MoveStatement> GetMoveStatements(SSAMap mapX, SSAMap mapY, string filename, int line) { List <MoveStatement> stat = new List <MoveStatement>(); if (this.map.Count == mapX.ScopesCount) { for (int i = 0; i < this.map.Count; i++) { if (this.map[i].Count == mapX[i].Count) { Dictionary <string, SSAElement> .KeyCollection keys = this.map[i].Keys; foreach (string key in keys) { if (this.map[i][key].IndexSSA != mapX[i][key].IndexSSA) { SingleIdentifierExpression right = this.createNewExpression(mapX, key, i, filename, line); SingleIdentifierExpression left = new SingleIdentifierExpression(key, new Location(filename, 0, 0)); left.IndexOfSSA = mapY[i][key].IndexSSA; stat.Add(new MoveStatement(left, right, filename, line)); } } } } } return(stat); }
// Expressions #region Visit(AssignmentExpression node, Object obj) public override Object Visit(AssignmentExpression node, Object obj) { Object aux = null; node.SecondOperand.LeftExpression = false; if ((aux = node.SecondOperand.Accept(this, false)) is SingleIdentifierExpression) { node.SecondOperand = (SingleIdentifierExpression)aux; } node.FirstOperand.LeftExpression = true; if ((aux = node.FirstOperand.Accept(this, false)) is SingleIdentifierExpression) { node.FirstOperand = (SingleIdentifierExpression)aux; } // * If the left expression is an SingleID expression, we do not add it to the used // references because the theta function sets its type as a union type SingleIdentifierExpression singleId = node.FirstOperand as SingleIdentifierExpression; if (singleId != null) { if (this.referencesUsedInIfElseBody != null) { this.referencesUsedInIfElseBody.Remove(singleId); } if (this.referencesUsedInCaseBody != null) { this.referencesUsedInCaseBody.Remove(singleId); } } return(null); }
/// <summary> /// Compares the current map with both maps to create a list of /// ThetaStatement in base of their information. /// </summary> /// <param name="mapX">SSMap to compare.</param> /// <param name="filename">File name.</param> /// <param name="line">Line to assign.</param> /// <returns>Returns the list of ThetaStatement.</returns> public List <ThetaStatement> GetThetaStatements(ref SSAMap mapX, string filename, int line) { List <ThetaStatement> stat = new List <ThetaStatement>(); if (this.map.Count == mapX.ScopesCount) { for (int i = 0; i < this.map.Count; i++) { if (this.map[i].Count == mapX[i].Count) { Dictionary <string, SSAElement> .KeyCollection keys = this.map[i].Keys; foreach (string key in keys) { if (this.map[i][key].IndexSSA != mapX[i][key].IndexSSA) { List <SingleIdentifierExpression> list = new List <SingleIdentifierExpression>(); list.Add(createNewExpression(this, key, i, filename, line)); list.Add(createNewExpression(mapX, key, i, filename, line)); SingleIdentifierExpression id = new SingleIdentifierExpression(key, new Location(filename, line, 0)); id.IndexOfSSA = mapX[i][key].IndexSSA + 1; stat.Add(new ThetaStatement(id, list, new Location(filename, line, 0))); mapX[i][key].UpdateIndexSSA(mapX[i][key].IndexSSA + 1); } } } } } return(stat); }
public override Object Visit(SingleIdentifierExpression node, Object obj) { SSAMap mapX; SSAMap mapY; if (obj is SSAInfo) { if (((mapX = ((SSAInfo)obj).FirstOperandToUpdateId) != null) && ((mapY = ((SSAInfo)obj).SecondOperandToUpdateId) != null)) { if (!(node.LeftExpression)) { int iValueX; int iValueY; if (((iValueX = mapX.Search(node.Identifier)) != -1) && ((iValueY = mapY.Search(node.Identifier)) != -1)) { if (node.IndexOfSSA == iValueX) { if (iValueX != iValueY) { node.IndexOfSSA = iValueY; } } } } } } return(null); }
// Expressions #region Visit(NewArrayExpression node, Object obj) public override Object Visit(NewArrayExpression node, Object obj) { string tmpName = auxiliarVar + CurrentAuxiliarSuffix++; SingleIdentifierExpression sId = new SingleIdentifierExpression(tmpName, node.Location); IdDeclaration id = new IdDeclaration(sId, -1, node.TypeInfo, node.Location); id.TypeExpr = node.ILTypeExpression; if (TemporalVariablesTable.Instance.SearchId(id.FullName) == null) // it's a new inserction { TemporalVariablesTable.Instance.Insert(id.FullName, id.ILName); } node.Identifier = id.Identifier; //decls.Add(id); this.decls.Add(id); if (node.Size != null) { node.Size.Accept(this, obj); } if (node.Init != null) { node.Init.Accept(this, obj); } return(this.decls); }
private void parameterSymbol(MethodDefinition node) { var method = node as MethodDefinition; if (method == null || method.TypeExpr == null) { return; } for (int i = 0; i < ((MethodType)node.TypeExpr).ParameterListCount; i++) { string id = node.ParametersInfo[i].Identifier; var exp = new SingleIdentifierExpression(id, node.Location); var type = ((MethodType)node.TypeExpr).GetParameter(i); IdDeclaration dec = new IdDeclaration(exp, type.FullName, node.Location); dec.TypeExpr = type; this.table.Insert(id, dec); //this.table.Insert(id, ((MethodType)node.TypeExpr).GetParameter(i), false); //if (!(((MethodType)node.TypeExpr).GetParameter(i) is ArrayType)) // id += ": (parameter)"; ////if (this.table.Insert(id, ((MethodType)node.TypeExpr).GetParameter(i), searchDynInfo(node.ParametersInfo[i].Identifier)) == null) //if (this.table.Insert(id, ((MethodType)node.TypeExpr).GetParameter(i), false) == null) // ErrorManager.Instance.NotifyError(new DeclarationFoundError(node.ParametersInfo[i].Identifier, new Location(this.currentFile, node.Location.Line, node.Location.Column))); } }
public override Object Visit(SingleIdentifierExpression node, Object obj) { // * Is the identifier a class, interface or namespace? node.ExpressionType = searchType(node.Identifier, node.Location.Line, node.Location.Column); if (node.ExpressionType is UserType) { node.IdMode = IdentifierMode.UserType; return(null); } // * If the identifier is the starting name of all the BCL namespaces (System) // a BCL namespace is created if (node.Identifier.Equals("System")) { node.IdMode = IdentifierMode.NameSpace; node.ExpressionType = new BCLNameSpaceType(node.Identifier); return(null); } // * Is the identifier a namespace defined by the user? if (usings.Contains(node.Identifier)) { node.IdMode = IdentifierMode.NameSpace; node.ExpressionType = new NameSpaceType(node.Identifier); return(null); } // * Is the identifier the starting name of the user's namespaces? foreach (string userUsing in usings) { if (userUsing.Contains(".")) { string firstName = userUsing.Split(new char[] { '.' })[0]; if (firstName.Equals(node.Identifier)) { node.IdMode = IdentifierMode.NameSpace; node.ExpressionType = new NameSpaceType(firstName); return(null); } } } // * Is the identifier contained in the name of the user's namespaces? foreach (string userUsing in usings) { if (userUsing.Contains("." + node.Identifier)) { node.IdMode = IdentifierMode.NameSpace; node.ExpressionType = new NameSpaceType(node.Identifier, userUsing.Substring(0, userUsing.IndexOf("." + node.Identifier) + ("." + node.Identifier).Length)); return(null); } } // * Otherwise, it must be an instance node.IdMode = IdentifierMode.Instance; return(null); }
// Expressions #region createMoveStatement private MoveStatement createMoveStatement(string id, SSAMap mapX, SSAMap mapY, string filename, int line) { SingleIdentifierExpression left = new SingleIdentifierExpression(id, new Location(filename, line, 0)); left.IndexOfSSA = mapY.Search(id) + 1; SingleIdentifierExpression right = new SingleIdentifierExpression(id, new Location(filename, line, 0)); right.IndexOfSSA = mapX.Search(id); return(new MoveStatement(left, right, filename, line)); }
/// <summary> /// Compares the current map with both maps to create a list of /// ThetaStatement in base of their information. /// </summary> /// <param name="maps">List of SSMap to compare.</param> /// <param name="map3">SSMap to compare and updates their values.</param> /// <param name="defaultFound">True if default case is found.</param> /// <param name="filename">File name.</param> /// <param name="line">Line to assign.</param> /// <returns>Returns the list of ThetaStatement.</returns> public List <ThetaStatement> GetThetaStatements(List <SSAMap> maps, ref SSAMap map3, bool defaultFound, string filename, int line) { List <ThetaStatement> stat = new List <ThetaStatement>(); bool useCondition = !defaultFound; if (this.map.Count == map3.ScopesCount) { for (int i = 0; i < this.map.Count; i++) { if (this.map[i].Count == map3[i].Count) { Dictionary <string, SSAElement> .KeyCollection keys = this.map[i].Keys; foreach (string key in keys) { if (this.map[i][key].IndexSSA != map3[i][key].IndexSSA) { List <SingleIdentifierExpression> list = new List <SingleIdentifierExpression>(); for (int j = 0; j < maps.Count; j++) { if ((this.map.Count == maps[j].ScopesCount) && (this.map[i].Count == maps[j][i].Count)) { if (((j == 0) && (this.map[i][key].IndexSSA != maps[j][i][key].IndexSSA)) || ((j != 0) && (maps[j - 1][i][key].IndexSSA != maps[j][i][key].IndexSSA))) { list.Add(createNewExpression(maps[j], key, i, filename, line)); } else { useCondition = true; } } } if (useCondition) { list.Add(createNewExpression(this, key, i, filename, line)); useCondition = !defaultFound; } list.Add(createNewExpression(map3, key, i, filename, line)); SingleIdentifierExpression id = new SingleIdentifierExpression(key, new Location(filename, line, 0)); id.IndexOfSSA = map3[i][key].IndexSSA + 1; stat.Add(new ThetaStatement(id, list, new Location(filename, line, 0))); map3[i][key].UpdateIndexSSA(map3[i][key].IndexSSA + 1); } } } } } return(stat); }
public override Object Visit(IdDeclaration node, Object obj) { SingleIdentifierExpression clonedIdentifierExp = (SingleIdentifierExpression)node.IdentifierExp.Accept(this, obj); IdDeclaration clonedIdDeclaration = new IdDeclaration(clonedIdentifierExp, clonedIdentifierExp.IndexOfSSA, node.TypeExpr.typeExpression, node.Location); clonedIdDeclaration.TypeExpr = node.TypeExpr.CloneType(this.typeVariableMappings, this.typeExpresionVariableMapping); Symbol originalSymbol = node.Symbol; Symbol symbol = new Symbol(originalSymbol.Name, originalSymbol.Scope, originalSymbol.SymbolType.CloneType(this.typeVariableMappings, this.typeExpresionVariableMapping), originalSymbol.IsDynamic); clonedIdDeclaration.Symbol = symbol; return(clonedIdDeclaration); }
public override Object Visit(SingleIdentifierExpression node, Object obj) { this.printIndentation(Convert.ToInt32(obj)); if (node.IndexOfSSA != -1) { this.output.WriteLine("{0}{1} Type: {2} [{3}:{4}]", node.Identifier, node.IndexOfSSA, printType(node.ExpressionType), node.Location.Line, node.Location.Column); } else { this.output.WriteLine("{0} Type: {1} [{2}:{3}]", node.Identifier, printType(node.ExpressionType), node.Location.Line, node.Location.Column); } return(null); }
public override object Exec(SingleIdentifierExpression s, object arg) { // * 2. A message is sent with without the implicit object "method(...)" //// * 2.1 A method is called (not a constructor) MethodType actualMethodCalled = TypeExpression.As <MethodType>(node.ActualMethodCalled); if ((((MethodType)node.ActualMethodCalled).MemberInfo.ModifierMask & Modifier.Static) == 0) { this.codeGenerator.ldarg(this.indent, 0); } this.node.Arguments.Accept(this.visitor, this.objArgs); this.codeGenerator.Call(this.indent, actualMethodCalled, actualMethodCalled.MemberInfo.Class, s.Identifier); return(null); }
// Statements #region Visit(Definition node, Object obj) public override Object Visit(Definition node, Object obj) { SingleIdentifierExpression clonedIdentifierExp = new SingleIdentifierExpression(node.IdentifierExp.Identifier, node.IdentifierExp.Location); Expression init = (Expression)node.Init.Accept(this, obj); Definition clonedDefinition = new Definition(clonedIdentifierExp, node.TypeExpr.typeExpression, init, node.Location); clonedIdentifierExp.IndexOfSSA = node.IdentifierExp.IndexOfSSA; clonedDefinition.TypeExpr = node.TypeExpr.CloneType(this.typeVariableMappings, this.typeExpresionVariableMapping); Symbol originalSymbol = node.Symbol; Symbol symbol = new Symbol(originalSymbol.Name, originalSymbol.Scope, originalSymbol.SymbolType.CloneType(this.typeVariableMappings, this.typeExpresionVariableMapping), originalSymbol.IsDynamic); clonedDefinition.Symbol = symbol; return(clonedDefinition); }
/// <summary> /// Creates a new SingleIdentifierExpression to use in the new statement /// </summary> /// <param name="map">Map to use.</param> /// <param name="tmpName">Key to access to the specified position in the map.</param> /// <param name="position">Position to access in the map.</param> /// <param name="fileName">File name.</param> /// <param name="line">Line to assign.</param> /// <returns>Returns the SingleIdentifierExpression created.</returns> private SingleIdentifierExpression createNewExpression(SSAMap map, string key, int position, string filename, int line) { SingleIdentifierExpression id; //if ((position == 0) && (map[position][tmpName].IndexSSA == 0)) // use a real field //{ // id = new SingleIdentifierExpression(tmpName.Substring(6, tmpName.Length - 6), filename, line, 0); // id.IndexOfSSA = -1; //} //else //{ id = new SingleIdentifierExpression(key, new Location(filename, line, 0)); id.IndexOfSSA = map[position][key].IndexSSA; //} return(id); }
public override object Exec(SingleIdentifierExpression s, object arg) { // * 2. A message is sent with without the implicit object "method(...)" //// * 2.1 A method is called (not a constructor) MethodType actualMethodCalled = TypeExpression.As <MethodType>(node.ActualMethodCalled); if ((((MethodType)node.ActualMethodCalled).MemberInfo.ModifierMask & Modifier.Static) == 0) { this.codeGenerator.ldarg(this.indent, 0); } this.node.Arguments.Accept(this.visitor, this.objArgs); this.codeGenerator.Call(this.indent, actualMethodCalled, actualMethodCalled.MemberInfo.Class, s.Identifier); //If the actualMethodCalled returns a TypeVariable and the InvocationExpression returns a ValueType an unboxing is needed, becasue there is not auto-unboxing from object to a ValueType. //if (actualMethodCalled.Return is TypeVariable && actualMethodCalled.Return.IsFreshVariable() && node.ExpressionType.IsValueType()) // this.codeGenerator.UnboxAny(this.indent, node.ExpressionType); return(null); }
//#region Visit(MethodDefinition node, Object obj) public override Object Visit(InvocationExpression node, Object obj) { node.Identifier.Accept(this, null); if (node.FrozenTypeExpression.IsValueType()) { SingleIdentifierExpression sid = new SingleIdentifierExpression(auxiliarValue + this.CurrentAuxiliarSuffix++, node.Location); IdDeclaration id = new IdDeclaration(sid, node.ILTypeExpression.ILType(), node.Location); id.TypeExpr = node.ExpressionType; if (TemporalVariablesTable.Instance.SearchId(id.FullName) == null) // it's a new inserction { TemporalVariablesTable.Instance.Insert(id.FullName, id.ILName); decls.Add(id); } } node.Arguments.Accept(this, obj); return(null); }
public override Object Visit(FieldAccessExpression node, Object obj) { if (node.Expression.ExpressionType.IsValueType()) { SingleIdentifierExpression sId = new SingleIdentifierExpression(auxiliarValue + this.CurrentAuxiliarSuffix++, node.Location); IdDeclaration id = new IdDeclaration(sId, node.Expression.ExpressionType.ILType(), node.Location); id.TypeExpr = node.Expression.ExpressionType; // temporal variables of the same type are forbidden if (TemporalVariablesTable.Instance.SearchId(id.FullName) == null) // it's a new inserction { TemporalVariablesTable.Instance.Insert(id.FullName, id.ILName); decls.Add(id); } } node.FieldName.Accept(this, obj); return(null); }
public override Object Visit(SingleIdentifierExpression node, Object obj) { SingleIdentifierExpression clonedSingleIdentifierExpression = new SingleIdentifierExpression(node.Identifier, node.Location); if (node.ExpressionType != null) { clonedSingleIdentifierExpression.ExpressionType = node.ExpressionType.CloneType(this.typeVariableMappings, this.typeExpresionVariableMapping); } if (node.IdSymbol != null) { Symbol originalSymbol = node.IdSymbol; Symbol symbol = new Symbol(originalSymbol.Name, originalSymbol.Scope, originalSymbol.SymbolType.CloneType(this.typeVariableMappings, this.typeExpresionVariableMapping), originalSymbol.IsDynamic); clonedSingleIdentifierExpression.IdSymbol = symbol; } clonedSingleIdentifierExpression.IndexOfSSA = node.IndexOfSSA; clonedSingleIdentifierExpression.IdMode = node.IdMode; return(clonedSingleIdentifierExpression); }
// Literals #region Visit(SingleIdentifierExpression node, Object obj) public override Object Visit(SingleIdentifierExpression node, Object obj) { if (node.Location == ((AstNode)obj).Location || found) { found = true; return(this.table); } //Symbol sym = null; //if (node.IndexOfSSA != -1) // sym = this.table.Search(node.Identifier + node.IndexOfSSA); //else // sym = this.table.Search(node.Identifier); //if (sym != null) // node.IdSymbol = (Symbol)sym; return(this.table); }
// Literals #region Visit(SingleIdentifierExpression node, Object obj) public override Object Visit(SingleIdentifierExpression node, Object obj) { Symbol sym = null; if (node.IndexOfSSA != -1) { sym = this.table.Search(node.Identifier + node.IndexOfSSA); } else { sym = this.table.Search(node.Identifier); } if (sym != null) { node.IdSymbol = (Symbol)sym; } return(null); }
/// <summary> /// Adds new assignment statements at the end of the specified block. /// </summary> /// <param name="vars">Information of the current scope in SSAMap.</param> /// <param name="node">Block of statement to add the new declarations.</param> private void addAssignmentStatements(Dictionary <string, SSAElement> vars, Block node) { FieldAccessExpression op1; SingleIdentifierExpression eop1; SingleIdentifierExpression op2; ThisExpression th = new ThisExpression(node.Location); foreach (KeyValuePair <string, SSAElement> pair in vars) { if (pair.Value.IndexSSA > 0) { eop1 = new SingleIdentifierExpression(pair.Key.Substring(6, pair.Key.Length - 6), node.Location); eop1.IndexOfSSA = -1; op1 = new FieldAccessExpression(th, eop1, node.Location); op2 = new SingleIdentifierExpression(pair.Key, node.Location); op2.IndexOfSSA = pair.Value.IndexSSA; node.AddStatement(new AssignmentExpression(op1, op2, AssignmentOperator.Assign, node.Location)); } } }
/// <summary> /// The obj parameter indicates if it is an explicit member of another object (e.g., obj.member => obj false and member true) /// </summary> public override Object Visit(SingleIdentifierExpression node, Object obj) { // * Is our father a field access bool isMember = true; if (obj != null) { isMember = getInheritedAttributes <Boolean>(obj); } // * If we are in a if statement, we add the reference to the list of used references (node IfElseStatement of the AST) if (!isMember) { if (this.referencesUsedInIfElseBody != null && !this.referencesUsedInIfElseBody.Contains(node)) { this.referencesUsedInIfElseBody.Add(node); } if (this.referencesUsedInCaseBody != null && !this.referencesUsedInCaseBody.Contains(node)) { this.referencesUsedInCaseBody.Add(node); } } int iValue; if (node.LeftExpression) { this.map.Increment(node.Identifier); } if ((iValue = this.map.Search(node.Identifier)) != -1) { node.IndexOfSSA = iValue; } return(null); }
/// <summary> /// Compares the current map with the argument map to create a list of /// MoveStatement in base of their information. /// </summary> /// <param name="maps">List of SSAMap.</param> /// <param name="filename">File name.</param> /// <param name="line">Line to assign.</param> /// <returns>Returns the list of MoveStatement.</returns> public List <MoveStatement> GetMoveStatementsForSwitch(List <SSAMap> maps, string filename, int line) { List <MoveStatement> stat = new List <MoveStatement>(); SSAMap finalMap = maps[maps.Count - 1]; if (this.map.Count == finalMap.ScopesCount) { for (int i = 0; i < this.map.Count; i++) { if (this.map[i].Count == finalMap[i].Count) { Dictionary <string, SSAElement> .KeyCollection keys = this.map[i].Keys; foreach (string key in keys) { if (this.map[i][key].IndexSSA != finalMap[i][key].IndexSSA) { for (int j = 0; j < maps.Count; j++) { // No updates. I need to use the condition value if (((j == 0) && (this.map[i][key].IndexSSA == maps[j][i][key].IndexSSA)) || ((j != 0) && (maps[j - 1][i][key].IndexSSA == maps[j][i][key].IndexSSA))) { SingleIdentifierExpression right = this.createNewExpression(this, key, i, filename, line); SingleIdentifierExpression left = new SingleIdentifierExpression(key, new Location(filename, 0, 0)); left.IndexOfSSA = finalMap[i][key].IndexSSA + 1; stat.Add(new MoveStatement(left, right, filename, line)); break; } } } } } } } return(stat); }
public override object Exec(SingleIdentifierExpression s, object arg) { return(s.ExpressionType); }
public override Object Visit(MethodDefinition node, Object obj) { typeVariableMappings = new Dictionary <TypeVariable, TypeVariable>(); typeExpresionVariableMapping = new Dictionary <TypeExpression, TypeExpression>(); var previouslyUnified = new List <Pair <TypeExpression, TypeExpression> >(); MethodType originalMethodType = (MethodType)node.TypeExpr; TypeExpression[] args = (TypeExpression[])obj; TypeExpression[] clonedArgs = new TypeExpression[args.Count()]; List <Parameter> clonedParametersInfo = new List <Parameter>(); for (int i = 0; i < node.ParametersInfo.Count; i++) { Parameter originalParameter = node.ParametersInfo[i]; TypeExpression originalParamType = originalMethodType.GetParameter(i); if (originalParamType is TypeVariable) { TypeVariable clonedParamType = (TypeVariable)originalParamType.CloneType(typeVariableMappings); if (clonedParamType.EquivalenceClass != null) { clonedParamType.EquivalenceClass.add(args[i], SortOfUnification.Override, previouslyUnified); typeExpresionVariableMapping.Add(originalParamType, clonedParamType); originalParamType = clonedParamType; } else { typeExpresionVariableMapping.Add(originalParamType, args[i]); originalParamType = args[i]; } } originalParamType.ValidTypeExpression = false; clonedArgs[i] = originalParamType.Simplify(); var parameter = new Parameter() { Identifier = originalParameter.Identifier, Column = originalParameter.Column, Line = originalParameter.Line, ParamType = clonedArgs[i].typeExpression }; if (parameter.ParamType == null || !originalParameter.ILName.Equals(parameter.ILName)) { var rebuildParamType = clonedArgs[i].ToString(); parameter.ParamType = clonedArgs[i].typeExpression; } clonedParametersInfo.Add(parameter); } foreach (var constraint in originalMethodType.Constraints.Constraints) { if (constraint is CloneConstraint) { CloneConstraint cc = constraint as CloneConstraint; if (typeExpresionVariableMapping.ContainsKey(cc.FirstOperand)) { typeExpresionVariableMapping.Add(cc.ReturnType, typeExpresionVariableMapping[cc.FirstOperand]); } } } MethodType clonedMethodType = new MethodType(originalMethodType.Return.CloneType(typeVariableMappings, typeExpresionVariableMapping)); currentMethodType = clonedMethodType; SingleIdentifierExpression clonedSingleIdentifierExpression = new SingleIdentifierExpression(node.IdentifierExp.Identifier, node.IdentifierExp.Location); Block clonedBlock = (Block)node.Body.Accept(this, null); MethodDefinition clonedMethodDefinition = null; if (node is ConstructorDefinition) { clonedMethodDefinition = new ConstructorDefinition(clonedSingleIdentifierExpression, node.ModifiersInfo, clonedParametersInfo, null, clonedBlock, node.Location); } else { clonedMethodDefinition = new MethodDefinition(clonedSingleIdentifierExpression, clonedBlock, clonedMethodType.Return.typeExpression, clonedParametersInfo, node.ModifiersInfo, node.Location); } clonedMethodDefinition.FullName = node.FullName; clonedMethodType.MemberInfo = new AccessModifier(originalMethodType.MemberInfo.Modifiers, clonedSingleIdentifierExpression.Identifier, clonedMethodType, false); clonedMethodType.MemberInfo.Class = originalMethodType.MemberInfo.Class; clonedMethodType.MemberInfo.TypeDefinition = originalMethodType.MemberInfo.TypeDefinition; for (int i = 0; i < originalMethodType.ParameterListCount; i++) { clonedMethodType.AddParameter(clonedArgs[i]); } clonedMethodType.ASTNode = clonedMethodDefinition; clonedMethodDefinition.TypeExpr = clonedMethodType; var previousShowMessages = ErrorManager.Instance.ShowMessages; ErrorManager.Instance.UnNotifiedErrors = false; ErrorManager.Instance.ShowMessages = false; clonedMethodDefinition.Accept(this.visitorSpecializer.visitorTypeInference, null); ErrorManager.Instance.ShowMessages = previousShowMessages; if (ErrorManager.Instance.UnNotifiedErrors) { ErrorManager.Instance.UnNotifiedErrors = false; return(null); } TypeDefinition originalTypeDefinition = clonedMethodType.MemberInfo.TypeDefinition; originalTypeDefinition.AddMethod(clonedMethodDefinition); UserType originalClass = clonedMethodType.MemberInfo.Class; AccessModifier am = originalClass.Members[clonedMethodDefinition.Identifier]; IntersectionMemberType intersectionMemberType = am.Type as IntersectionMemberType; if (intersectionMemberType != null) { intersectionMemberType.TypeSet.Add(clonedMethodType); } else { am = clonedMethodType.MemberInfo; IntersectionMemberType intersection = new IntersectionMemberType(); intersection.TypeSet.Add(originalMethodType); intersection.TypeSet.Add(clonedMethodType); am.Type = intersection; originalClass.Members[clonedMethodDefinition.Identifier] = am; } clonedMethodDefinition.IdentifierExp.ExpressionType = clonedMethodDefinition.TypeExpr; return(clonedMethodDefinition); }
private MethodDefinition CreateMethod(string fullMethodIndentificator, string originalMethodIndentificator, MethodDefinition originalMethodDefinition, TypeExpression[] args, BaseCallExpression node) { if (!specilizedMethods.ContainsKey(fullMethodIndentificator)) { String methodIndentificator = fullMethodIndentificator.Replace(originalMethodDefinition.FullName, originalMethodDefinition.Identifier); List <MethodDefinition> methods = new List <MethodDefinition>(); foreach (TypeExpression[] listOfArgs in GetTypes(args)) { String currentMethodIdentificator = MethodIndentificator(originalMethodDefinition.FullName, listOfArgs); MethodDefinition md; if (currentMethodIdentificator.Equals(originalMethodIndentificator)) { md = originalMethodDefinition; } else { md = SpecilizeMethod(currentMethodIdentificator, originalMethodDefinition, listOfArgs); } if (md != null && !methods.Any(m => m.ILTypeExpression.Equals(md.ILTypeExpression))) { methods.Add(md); } } MethodType originalMethodType = (MethodType)originalMethodDefinition.TypeExpr; isCurrentMethodDynamic = IsCurrentMethodDynamic(originalMethodType); MethodType newMethodType = new MethodType(originalMethodType.Return); Location location = originalMethodDefinition.IdentifierExp.Location; SingleIdentifierExpression newSingleIdentifierExpression = new SingleIdentifierExpression(methodIndentificator, location); Block newBlock = new Block(location); IList <InvocationExpression> invocations = new List <InvocationExpression>(); IList <CastExpression> castExpressions = new List <CastExpression>(); int methodsCount = 0; foreach (var methodDefinition in methods) { MethodType methodType = (MethodType)methodDefinition.TypeExpr; IList <IsExpression> isExpressions = new List <IsExpression>(); CompoundExpression compoundExpression = new CompoundExpression(location); for (int i = 0; i < methodDefinition.ParametersInfo.Count; i++) { SingleIdentifierExpression identifier = new SingleIdentifierExpression(methodDefinition.ParametersInfo[i].Identifier, location); identifier.IndexOfSSA = 0; if (args[i] is UnionType || (args[i] is TypeVariable && ((TypeVariable)args[i]).Substitution is UnionType)) { IsExpression isExpression = new IsExpression(identifier, methodType.GetParameter(i).Freeze().ILType(), location); isExpression.TypeExpr = methodType.GetParameter(i).Freeze(); isExpressions.Add(isExpression); CastExpression castExpression = new CastExpression(isExpression.TypeExpr.ILType(), identifier, location); castExpressions.Add(castExpression); castExpression.CastType = isExpression.TypeExpr; compoundExpression.AddExpression(castExpression); } else { compoundExpression.AddExpression(identifier); } } Expression condition = isExpressions[0]; if (isExpressions.Count > 1) { for (int i = 1; i < isExpressions.Count; i++) { condition = new LogicalExpression(condition, isExpressions[i], LogicalOperator.And, location); } } InvocationExpression invocationExpression = new InvocationExpression(methodDefinition.IdentifierExp, compoundExpression, location); invocations.Add(invocationExpression); ReturnStatement returnStatement = new ReturnStatement(invocationExpression, location); if (++methodsCount < methods.Count || isCurrentMethodDynamic) { IfElseStatement ifElseStatement = new IfElseStatement(condition, returnStatement, location); newBlock.AddStatement(ifElseStatement); } else if (!isCurrentMethodDynamic) { newBlock.AddStatement(returnStatement); } } //If there is any dynamic union type then it is necessary invoke the original method if (isCurrentMethodDynamic) { CompoundExpression compoundExpression = new CompoundExpression(location); foreach (var parameter in originalMethodDefinition.ParametersInfo) { SingleIdentifierExpression identifier = new SingleIdentifierExpression(parameter.Identifier, location); identifier.IndexOfSSA = 0; compoundExpression.AddExpression(identifier); } newBlock.AddStatement(new ReturnStatement(new InvocationExpression(new SingleIdentifierExpression(originalMethodDefinition.Identifier, location), compoundExpression, location), location)); } MethodDefinition newMethodDefinition = new MethodDefinition(newSingleIdentifierExpression, newBlock, originalMethodDefinition.ReturnTypeInfo, originalMethodDefinition.ParametersInfo, originalMethodDefinition.ModifiersInfo, location); newMethodDefinition.FullName = fullMethodIndentificator; newMethodType.MemberInfo = new AccessModifier(originalMethodType.MemberInfo.Modifiers, newSingleIdentifierExpression.Identifier, newMethodType, false); newMethodType.MemberInfo.Class = originalMethodType.MemberInfo.Class; newMethodType.MemberInfo.TypeDefinition = originalMethodType.MemberInfo.TypeDefinition; for (int i = 0; i < originalMethodType.ParameterListCount; i++) { newMethodType.AddParameter(args[i].Simplify()); } newMethodType.ASTNode = newMethodDefinition; newMethodDefinition.TypeExpr = newMethodType; newMethodDefinition.TypeExpr.BuildFullName(); newMethodDefinition.TypeExpr.BuildTypeExpressionString(4); TypeDefinition originalTypeDefinition = newMethodType.MemberInfo.TypeDefinition; originalTypeDefinition.AddMethod(newMethodDefinition); UserType originalClass = newMethodType.MemberInfo.Class; originalClass.AddMember(methodIndentificator, newMethodType.MemberInfo); newMethodDefinition.Accept(new VisitorSymbolIdentification(null), null); bool previousDynamism = DynVarOptions.Instance.EverythingDynamic; DynVarOptions.Instance.EverythingDynamic = false; newMethodDefinition.Accept(visitorTypeInference, null); DynVarOptions.Instance.EverythingDynamic = previousDynamism; foreach (var invocation in invocations) { if (invocation.ActualMethodCalled is UnionType) { invocation.ActualMethodCalled = ((UnionType)invocation.ActualMethodCalled).TypeSet[1]; } } foreach (var castExpression in castExpressions) { ((SingleIdentifierExpression)castExpression.Expression).FrozenTypeExpression = new ClassType("System.Object"); castExpression.Expression.ExpressionType = new ClassType("System.Object"); } specilizedMethods.Add(fullMethodIndentificator, newMethodDefinition); return(newMethodDefinition); } return(specilizedMethods[fullMethodIndentificator]); }
public override Object Visit(SingleIdentifierExpression node, Object obj) { return(null); }
public abstract Object Visit(SingleIdentifierExpression node, Object obj);
public virtual object Exec(SingleIdentifierExpression s, object arg) { return(Exec((IdentifierExpression)s, arg)); }