private Dictionary <string, AccessModifier> builtClass(TypeDefinition node, Object obj) { Dictionary <string, AccessModifier> membersWithIntersectionTypes = new Dictionary <string, AccessModifier>(); Dictionary <string, List <AccessModifier> > members = new Dictionary <string, List <AccessModifier> >(); List <int> remove = new List <int>(); AccessModifier accessModifier = null; int count = 0; for (int i = 0; i < node.MemberCount; i++) { accessModifier = (AccessModifier)(node.GetMemberElement(i).Accept(this, obj)); if (accessModifier != null) { accessModifier.Class = (UserType)(node.TypeExpr); accessModifier.TypeDefinition = node; if (!(members.ContainsKey(accessModifier.MemberIdentifier))) { members.Add(accessModifier.MemberIdentifier, new List <AccessModifier>()); } // Insert element. The accessModifier list only can have one FieldType if (((members[accessModifier.MemberIdentifier].Count != 0) && (accessModifier.Type is FieldType)) || ((members[accessModifier.MemberIdentifier].Count == 1) && (members[accessModifier.MemberIdentifier][0].Type is FieldType))) { remove.Add(i); ErrorManager.Instance.NotifyError(new DeclarationFoundError(accessModifier.MemberIdentifier, new Location(this.currentFile, node.GetMemberElement(i).Location.Line, node.GetMemberElement(i).Location.Column))); } else { members[accessModifier.MemberIdentifier].Add(accessModifier); //accessModifier.WriteType.BuildTypeExpressionString(TypeExpression.MAX_DEPTH_LEVEL_TYPE_EXPRESSION); } } } // Removes incorrect declarations for (int i = 0; i < remove.Count; i++, count++) { node.RemoveMemberElement(remove[i] - count); } // * Converts method overload into intersection types foreach (KeyValuePair <string, List <AccessModifier> > pair in members) { if (pair.Value.Count == 1) { // * No intersection is necessary membersWithIntersectionTypes[pair.Key] = pair.Value[0]; } else { // * We add an intersection type // * An access modifier is taken AccessModifier am = pair.Value[0]; // * We add each type to the intersection type IntersectionMemberType intersection = new IntersectionMemberType(); foreach (AccessModifier accMod in pair.Value) { MethodType method = (MethodType)accMod.Type; if (!intersection.AddMethod(method)) { AstNode astMethodNode = method.ASTNode; ErrorManager.Instance.NotifyError(new OverloadError(am.MemberIdentifier, astMethodNode.Location)); } } am.Type = intersection; membersWithIntersectionTypes[pair.Key] = am; } } return(membersWithIntersectionTypes); }
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); }