public static bool Extends(AStructDecl baseType, AStructDecl cType, SharedData data) { if (cType == null) { return(false); } if (baseType == cType) { return(true); } if (cType.GetBase() == null) { return(false); } return(Extends(baseType, data.StructTypeLinks[(ANamedType)cType.GetBase()], data)); }
public override void CaseAStructDecl(AStructDecl node) { if (parsedStructs.Contains(node)) { return; } parsedStructs.Add(node); if (node.GetBase() != null) { AStructDecl baseStruct = finalTrans.data.StructTypeLinks[(ANamedType)node.GetBase()]; if (!parsedStructs.Contains(baseStruct)) { CaseAStructDecl(baseStruct); } } base.CaseAStructDecl(node); }
//Check that there are no circular enhritance private void CheckEnheritanceList(AStructDecl str, List <AStructDecl> list) { if (list.Contains(str)) { List <ErrorCollection.Error> subErrors = new List <ErrorCollection.Error>(); for (int i = list.IndexOf(str); i < list.Count; i++) { subErrors.Add(new ErrorCollection.Error(list[i].GetName(), (list[i].GetClassToken() == null ? "Struct" : "class") + " in cycle.")); } errors.Add(new ErrorCollection.Error(str.GetName(), "You can not make a cycle of enheritance.", false, subErrors.ToArray())); throw new ParserException(str.GetName(), ""); } list.Add(str); if (str.GetBase() != null) { CheckEnheritanceList(Lookup((ANamedType)str.GetBase()), list); } }
public StructDescription(AStructDecl structDecl) { Parser parser = new Parser(structDecl); Name = parser.Name; IsEnum = Name.StartsWith("enum "); if (IsEnum) { Name = Name.Substring(5); foreach (VariableDescription field in parser.Fields) { field.PlacementPrefix = "Enum Field"; } } Fields = parser.Fields; Methods = parser.Methods; Constructors = parser.Constructors; Deconstructors = parser.Deconstructors; LineFrom = structDecl.GetName().Line; LineTo = structDecl.GetEndToken().Line; if (structDecl.GetBase() is AGenericType) { BaseRef = (ANamedType)((AGenericType)structDecl.GetBase()).GetBase(); } else { BaseRef = (ANamedType)structDecl.GetBase(); } structDecl.RemoveChild(BaseRef); foreach (TIdentifier identifier in structDecl.GetGenericVars()) { GenericVars.Add(identifier.Text); } IsClass = structDecl.GetClassToken() != null; Visibility = (PVisibilityModifier)structDecl.GetVisibilityModifier().Clone(); Position = TextPoint.FromCompilerCoords(structDecl.GetName()); }
public override void CaseAStructDecl(AStructDecl node) { if (checkedStructs.Contains(node)) { return; } checkedStructs.Add(node); //Set where they originate from. foreach (PLocalDecl localDecl in node.GetLocals()) { if (localDecl is AALocalDecl) { fieldOriginatesFrom[(AALocalDecl)localDecl] = node; } else //Is DeclLocalDecl { ADeclLocalDecl aLocalDecl = (ADeclLocalDecl)localDecl; PDecl decl = aLocalDecl.GetDecl(); if (decl is AMethodDecl) { methodOriginatesFrom[(AMethodDecl)decl] = node; } else if (decl is APropertyDecl) { propertyOriginatesFrom[(APropertyDecl)decl] = node; } else if (decl is AThisArrayPropertyDecl) { arrayPropertyOriginatesFrom[(AThisArrayPropertyDecl)decl] = node; } } } if (node.GetBase() == null) { return; } AStructDecl baseStr = Lookup((ANamedType)node.GetBase()); if (!checkedStructs.Contains(baseStr)) { CaseAStructDecl(baseStr); } CheckEnheritanceList(node, new List <AStructDecl>()); //A struct may not enhrit from a class if (node.GetClassToken() == null && baseStr.GetClassToken() != null) { errors.Add(new ErrorCollection.Error(node.GetName(), "A struct can not enherit from a class.", false, new ErrorCollection.Error(baseStr.GetName(), "Enherited class"))); } //Copy everything in base struct to here (Except from constructors) List <PLocalDecl> stuffToAdd = new List <PLocalDecl>(); foreach (AALocalDecl baseLocalVar in data.StructFields[baseStr]) { //Check that it is not overwritten foreach (AALocalDecl localVar in node.GetLocals().OfType <AALocalDecl>()) { if (baseLocalVar.GetName().Text == localVar.GetName().Text) { errors.Add(new ErrorCollection.Error(localVar.GetName(), "It is not possible to override fields.", false, new ErrorCollection.Error( fieldOriginatesFrom[baseLocalVar].GetName(), "Overridden " + Util.GetTypeName(fieldOriginatesFrom[baseLocalVar])))); throw new ParserException(null, null); } } foreach (APropertyDecl localProperty in data.StructProperties[node]) { if (localProperty.GetName().Text == baseLocalVar.GetName().Text) { errors.Add(new ErrorCollection.Error(localProperty.GetName(), "It is not possible to override fields.", false, new ErrorCollection.Error( fieldOriginatesFrom[baseLocalVar].GetName(), "Overridden " + Util.GetTypeName(fieldOriginatesFrom[baseLocalVar])))); throw new ParserException(null, null); } } //Insert at top AALocalDecl newLocalVar = (AALocalDecl)baseLocalVar.Clone(); baseLocalVar.Apply(new FixNamedRefferences(newLocalVar, data)); stuffToAdd.Add(newLocalVar); data.StructFields[node].Add(newLocalVar); fieldOriginatesFrom[newLocalVar] = fieldOriginatesFrom[baseLocalVar]; if (data.EnheritanceLocalMap.ContainsKey(baseLocalVar)) { data.EnheritanceLocalMap[newLocalVar] = data.EnheritanceLocalMap[baseLocalVar]; } else { data.EnheritanceLocalMap[newLocalVar] = baseLocalVar; } } for (int i = stuffToAdd.Count - 1; i >= 0; i--) { node.GetLocals().Insert(0, stuffToAdd[i]); } //Methods foreach (AMethodDecl baseMethod in data.StructMethods[baseStr]) { //Check that it is not overwritten foreach (AMethodDecl localMethod in node.GetLocals().OfType <ADeclLocalDecl>().Select(l => l.GetDecl()).OfType <AMethodDecl>()) { if (Util.GetMethodSignature(baseMethod) == Util.GetMethodSignature(localMethod)) { errors.Add(new ErrorCollection.Error(localMethod.GetName(), "It is not possible to override methods.", false, new ErrorCollection.Error( methodOriginatesFrom[baseMethod].GetName(), "Overridden " + Util.GetTypeName(methodOriginatesFrom[baseMethod])))); throw new ParserException(null, null); } } data.StructMethods[node].Add(baseMethod); } //Properties foreach (APropertyDecl baseProperty in data.StructProperties[baseStr]) { //Check that it is not overwritten foreach (APropertyDecl localProperty in data.StructProperties[node]) { if (localProperty.GetName().Text == baseProperty.GetName().Text) { errors.Add(new ErrorCollection.Error(localProperty.GetName(), "It is not possible to override properties.", false, new ErrorCollection.Error( propertyOriginatesFrom[baseProperty].GetName(), "Overridden " + Util.GetTypeName(propertyOriginatesFrom[baseProperty])))); throw new ParserException(null, null); } } foreach (AALocalDecl localVar in node.GetLocals().OfType <AALocalDecl>()) { if (baseProperty.GetName().Text == localVar.GetName().Text) { errors.Add(new ErrorCollection.Error(localVar.GetName(), "It is not possible to override properties.", false, new ErrorCollection.Error( propertyOriginatesFrom[baseProperty].GetName(), "Overridden " + Util.GetTypeName(propertyOriginatesFrom[baseProperty])))); throw new ParserException(null, null); } } data.StructProperties[node].Add(baseProperty); } }
/*private class IsThisOnLeftSide : DepthFirstAdapter * { * private PType type; * private SharedData data; * public bool IsAssignedTo; * private List<AMethodDecl> investigatedMethods = new List<AMethodDecl>(); * * public IsThisOnLeftSide(PType type, SharedData data) * { * this.type = type; * this.data = data; * } * * //Check assignments, method invocations and nonstatic method invocations. * * public override void CaseAMethodDecl(AMethodDecl node) * { * investigatedMethods.Add(node); * } * * public override void CaseAThisLvalue(AThisLvalue node) * { * if (IsAssignedTo) * return; * * Node iParent = GetClosestNodeOfType(node, typeof (AAssignmentExp), * typeof (ASimpleInvokeExp), * typeof (ANonstaticInvokeExp), * typeof (AAsyncInvokeStm), * typeof (ASyncInvokeExp), * typeof(AArrayLvalue), * typeof(APointerLvalue), * typeof(APropertyLvalue), * typeof(AStructLvalue)); * if (iParent == null) * return; * * if (iParent is AAssignmentExp) * { * AAssignmentExp aParent = (AAssignmentExp) iParent; * if (Util.IsAncestor(node, aParent.GetLvalue())) * { * IsAssignedTo = true; * } * return; * } * if (iParent is ASimpleInvokeExp) * { * ASimpleInvokeExp aParent = (ASimpleInvokeExp) iParent; * AMethodDecl method = data.SimpleMethodLinks[aParent]; * if (investigatedMethods.Contains(method)) * return; * * if (Util.IsAncestor(node, aParent.GetLvalue())) * { * IsAssignedTo = true; * } * return; * } * } * * private Node GetClosestNodeOfType(Node node, params Type[] types) * { * if (node == null) * return null; * if (types.Contains(node.GetType())) * return node; * return GetClosestNodeOfType(node.Parent(), types); * } * }*/ public override void CaseADeconstructorDecl(ADeconstructorDecl node) { AStructDecl str = Util.GetAncestor <AStructDecl>(node); AEnrichmentDecl enrichment = Util.GetAncestor <AEnrichmentDecl>(node); AMethodDecl replacer = new AMethodDecl(new APublicVisibilityModifier(), null, null, null, null, null, new AVoidType(new TVoid("void")), node.GetName(), new ArrayList(), node.GetBlock()); replacer.GetName().Text += "_Deconstructor"; //Move the method outside the struct AASourceFile file = Util.GetAncestor <AASourceFile>(node); if (str != null) { str.RemoveChild(node.Parent()); } /*else * enrichment.RemoveChild(node);*/ int i = file.GetDecl().IndexOf(str ?? (PDecl)enrichment); file.GetDecl().Insert(i /* + 1*/, replacer); //Add the struct as a parameter PType type; if (str != null) { ANamedType structType = new ANamedType(new TIdentifier(str.GetName().Text), null); finalTrans.data.StructTypeLinks[structType] = str; type = structType; } else { type = Util.MakeClone(enrichment.GetType(), finalTrans.data); } finalTrans.data.DeconstructorMap[node] = replacer; AALocalDecl structFormal = new AALocalDecl(new APublicVisibilityModifier(), null, null, null, null, new APointerType(new TStar("*"), type), new TIdentifier("currentStruct", replacer.GetName().Line, replacer.GetName().Pos), null); replacer.GetFormals().Add(structFormal); finalTrans.data.Methods.Add(new SharedData.DeclItem <AMethodDecl>(file, replacer)); //Call base deconstructor before each return if (str != null && str.GetBase() != null) { AStructDecl baseStruct = data.StructTypeLinks[(ANamedType)str.GetBase()]; if (data.StructDeconstructor.ContainsKey(baseStruct)) { baseStruct.Apply(this); replacer.Apply(new CallDeconstructors(baseStruct, structFormal, data)); /*AMethodDecl baseDeconstructor = data.DeconstructorMap[data.StructDeconstructor[baseStruct]]; * * * ALocalLvalue structFormalRef = new ALocalLvalue(new TIdentifier("currentStruct")); * ALvalueExp structFormalRefExp = new ALvalueExp(structFormalRef); * ASimpleInvokeExp invoke = new ASimpleInvokeExp(new TIdentifier("baseDeconstructor"), * new ArrayList() {structFormalRefExp}); * AABlock block = (AABlock) replacer.GetBlock(); * block.GetStatements().Insert(0, new AExpStm(new TSemicolon(";"), invoke)); * * data.LocalLinks[structFormalRef] = structFormal; * data.SimpleMethodLinks[invoke] = baseDeconstructor; * data.LvalueTypes[structFormalRef] = data.ExpTypes[structFormalRefExp] = structFormal.GetType(); * data.ExpTypes[invoke] = baseDeconstructor.GetReturnType();*/ } } this.structFormal = structFormal; base.CaseAMethodDecl(replacer); }