public override Object Visit(CompoundExpression node, Object obj) { CompoundExpression clonedCompoundExpression = new CompoundExpression(node.Location); for (int i = 0; i < node.ExpressionCount; i++) { clonedCompoundExpression.AddExpression((Expression)node.GetExpressionElement(i).Accept(this, obj)); } return(clonedCompoundExpression); }
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]); }