private Object builtMethod(MethodDeclaration node) { bool interfaceMember = false; if (!((node is MethodDefinition) || (node is ConstructorDefinition))) { interfaceMember = true; } TypeExpression ret = this.searchType(node.ReturnTypeInfo, node.Location.Line, node.Location.Column); if (ret == null) { ErrorManager.Instance.NotifyError(new UnknownTypeError(node.ReturnTypeInfo, node.Location)); ret = this.searchType("void", node.Location.Line, node.Location.Column); } MethodType type = new MethodType(ret); type.ASTNode = node; // * Binds the MethodType with the appropriate AST node for (int i = 0; i < node.ParametersInfo.Count; i++) { TypeExpression paramType = this.searchType(node.ParametersInfo[i].ParamType, node.ParametersInfo[i].Line, node.ParametersInfo[i].Column); if (paramType == null) { ErrorManager.Instance.NotifyError(new UnknownTypeError(node.ParametersInfo[i].ParamType, new Location(node.Location.FileName, node.ParametersInfo[i].Line, node.ParametersInfo[i].Column))); } type.AddParameter(paramType); } AccessModifier accessModifierInfo = new AccessModifier(node.ModifiersInfo, node.Identifier, type, interfaceMember); type.MemberInfo = accessModifierInfo; node.TypeExpr = type; return(accessModifierInfo); }
public void testUnify3Wrong() { // * "Array(Var(alpha))->Var(alpha)" TypeExpression alpha = TypeVariable.NewTypeVariable; MethodType type1 = new MethodType(alpha); type1.AddParameter(new ArrayType(alpha)); // * "Array(Array(int))->double" MethodType type2 = new MethodType(DoubleType.Instance); type2.AddParameter(new ArrayType(new ArrayType(IntType.Instance))); Unify(type1, type2); }
public void testUnify6OK() { // * "( Var(alpha) -> Array( int )" TypeExpression alpha = TypeVariable.NewTypeVariable; MethodType type1 = new MethodType(new ArrayType(IntType.Instance)); type1.AddParameter(alpha); // * "( Var(beta) -> Array( Var(beta) )" TypeExpression beta = TypeVariable.NewTypeVariable; MethodType type2 = new MethodType(new ArrayType(beta)); type2.AddParameter(beta); Unify(type1, type2); }
public void testUnify4Wrong() { // * "Array(Var(alpha))->Var(alpha)" TypeExpression alpha = TypeVariable.NewTypeVariable; MethodType type1 = new MethodType(alpha); type1.AddParameter(new ArrayType(alpha)); // * "(Array(Array(int))->Var(beta)) -> Var(gamma)" TypeExpression beta = TypeVariable.NewTypeVariable; TypeExpression gamma = TypeVariable.NewTypeVariable; MethodType type2 = new MethodType(gamma); MethodType type3 = new MethodType(beta); type3.AddParameter(new ArrayType(new ArrayType(IntType.Instance))); type2.AddParameter(type3); Unify(type1, type2); }
public void testUnify5OK() { // <A(B(v),C(u,v)), A(B(w),C(w,D(x,))> // * "( Var(alpha)->Var(beta) ) -> Pointer(alpha)" TypeExpression alpha = TypeVariable.NewTypeVariable; TypeExpression beta = TypeVariable.NewTypeVariable; MethodType type1 = new MethodType(new ArrayType(alpha)); MethodType typeAux = new MethodType(beta); typeAux.AddParameter(alpha); type1.AddParameter(typeAux); // * "( (double->double)->Var(gamma) ) -> Pointer(Var(gamma))" TypeExpression gamma = TypeVariable.NewTypeVariable; MethodType type2 = new MethodType(new ArrayType(gamma)); MethodType typeAux1 = new MethodType(gamma); MethodType typeAux2 = new MethodType(DoubleType.Instance); typeAux2.AddParameter(DoubleType.Instance); typeAux1.AddParameter(typeAux2); type2.AddParameter(typeAux1); Unify(type1, type2); }
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(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); }