public override void CaseAMethodDecl(AMethodDecl node) { Write("\n"); if (node.GetStatic() != null) { Write("static "); } if (node.GetNative() != null) { Write("native "); } node.GetReturnType().Apply(this); Write(" " + node.GetName().Text + "("); bool first = true; foreach (AALocalDecl formal in node.GetFormals()) { if (!first) { Write(", "); } formal.Apply(this); first = false; } if (node.GetBlock() != null) { Write(")\n"); node.GetBlock().Apply(this); } else { Write(");\n\n"); } }
public override void CaseAMethodDecl(AMethodDecl node) { if (node.GetNative() == null && node.GetBlock() == null) { return; } if (node.GetStatic() != null) { return; } string inputStr = "native " + TypeToString(node.GetReturnType()) + " " + node.GetName().Text + "("; bool first = true; foreach (AALocalDecl formal in node.GetFormals()) { if (!first) { inputStr += ", "; } inputStr += TypeToString(formal.GetType()) + " " + formal.GetName().Text; first = false; } inputStr += ");"; writer.WriteLine(inputStr); AStructDecl str = Util.GetAncestor <AStructDecl>(node); List <AMethodDecl> methodList; if (str != null) { methodList = StructMethods[str]; } else { methodList = Methods; } string sig = Util.GetMethodSignature(node); if (methodList.Any(otherMethod => Util.GetMethodSignature(otherMethod) == sig)) { return; } methodList.Add(node); node.SetBlock(null); node.Parent().RemoveChild(node); }
public static bool IsStaticContext(Node node) { //Must be in a struct/enrichment, and in a static method/property/localdecl if (HasAncestor <AStructDecl>(node) || HasAncestor <AEnrichmentDecl>(node)) { AMethodDecl pMethod = GetAncestor <AMethodDecl>(node); APropertyDecl pProperty = GetAncestor <APropertyDecl>(node); AALocalDecl pLocalDecl = GetAncestor <AALocalDecl>(node); return(pMethod != null && pMethod.GetStatic() != null || pProperty != null && pProperty.GetStatic() != null || pLocalDecl != null && pLocalDecl.GetStatic() != null); } return(false); }
public MethodDescription(AMethodDecl method) { Parser parser = new Parser(method); Start = parser.Start; End = parser.End; ReturnType = parser.ReturnType; Name = parser.Name; Formals = parser.Formals; Locals = parser.Locals; if (method.Parent() != null) { method.Parent().RemoveChild(method); } IsDelegate = method.GetDelegate() != null; //if (!IsDelegate) Decl = method; IsStatic = method.GetStatic() != null; Visibility = method.GetVisibilityModifier(); realType = (PType)method.GetReturnType().Clone(); Position = TextPoint.FromCompilerCoords(method.GetName()); }
private static void GetMatchingTypes(ANamedType node, List <string> names, List <ATypedefDecl> typeDefs, List <AStructDecl> structs, List <AMethodDecl> delegates, List <ANamespaceDecl> namespaces, List <TIdentifier> generics) { List <IList> decls = new List <IList>(); List <string> currentNamespace = Util.GetFullNamespace(node); AASourceFile currentSourceFile = Util.GetAncestor <AASourceFile>(node); if (names.Count == 1) { string name = names[0]; //Check generic vars AStructDecl currentStruct = Util.GetAncestor <AStructDecl>(node); if (currentStruct != null) { foreach (TIdentifier genericVar in currentStruct.GetGenericVars()) { if (genericVar.Text == name) { generics.Add(genericVar); } } } //Get all type decls and namespaces matching this name, visible from this location List <IList> visibleDecls = Util.GetVisibleDecls(node, ((AAName)node.GetName()).GetIdentifier().Count == 1); foreach (IList declList in visibleDecls) { bool sameFile = false; if (declList.Count > 0) { sameFile = currentSourceFile == Util.GetAncestor <AASourceFile>((PDecl)declList[0]); } foreach (PDecl decl in declList) { bool sameNS = Util.NamespacesEquals(currentNamespace, Util.GetFullNamespace(decl)); if (decl is ANamespaceDecl) { ANamespaceDecl aDecl = (ANamespaceDecl)decl; if (aDecl.GetName().Text == name) { namespaces.Add(aDecl); } continue; } if (decl is ATypedefDecl) { if (Util.IsAncestor(node, decl)) { continue; } ATypedefDecl aDecl = (ATypedefDecl)decl; if (aDecl.GetStatic() != null && !sameFile || aDecl.GetVisibilityModifier() is APrivateVisibilityModifier && !sameNS) { continue; } ANamedType namedType = (ANamedType)aDecl.GetName(); AAName aName = (AAName)namedType.GetName(); string n = ((TIdentifier)aName.GetIdentifier()[0]).Text; if (n == name) { typeDefs.Add(aDecl); } continue; } if (decl is AStructDecl) { AStructDecl aDecl = (AStructDecl)decl; if (!sameNS && aDecl.GetVisibilityModifier() is APrivateVisibilityModifier) { continue; } if (aDecl.GetName().Text == name) { structs.Add(aDecl); } continue; } if (decl is AMethodDecl) { AMethodDecl aDecl = (AMethodDecl)decl; if (!sameNS && aDecl.GetVisibilityModifier() is APrivateVisibilityModifier || !sameFile && aDecl.GetStatic() != null) { continue; } if (aDecl.GetDelegate() != null && aDecl.GetName().Text == name) { delegates.Add(aDecl); } continue; } } } } else { string name = names[names.Count - 1]; List <ANamespaceDecl> baseNamespaces = new List <ANamespaceDecl>(); List <string> baseNames = new List <string>(); baseNames.AddRange(names); baseNames.RemoveAt(baseNames.Count - 1); GetMatchingTypes(node, baseNames, new List <ATypedefDecl>(), new List <AStructDecl>(), new List <AMethodDecl>(), baseNamespaces, generics); foreach (ANamespaceDecl ns in baseNamespaces) { bool sameFile = currentSourceFile == Util.GetAncestor <AASourceFile>(ns); foreach (PDecl decl in ns.GetDecl()) { bool sameNS = Util.NamespacesEquals(currentNamespace, Util.GetFullNamespace(decl)); if (decl is ANamespaceDecl) { ANamespaceDecl aDecl = (ANamespaceDecl)decl; if (aDecl.GetName().Text == name) { namespaces.Add(aDecl); } continue; } if (decl is ATypedefDecl) { ATypedefDecl aDecl = (ATypedefDecl)decl; ANamedType namedType = (ANamedType)aDecl.GetName(); AAName aName = (AAName)namedType.GetName(); string n = ((TIdentifier)aName.GetIdentifier()[0]).Text; if (n == name) { typeDefs.Add(aDecl); } continue; } if (decl is AStructDecl) { AStructDecl aDecl = (AStructDecl)decl; if (!sameNS && aDecl.GetVisibilityModifier() is APrivateVisibilityModifier) { continue; } if (aDecl.GetName().Text == name) { structs.Add(aDecl); } continue; } if (decl is AMethodDecl) { AMethodDecl aDecl = (AMethodDecl)decl; if (!sameNS && aDecl.GetVisibilityModifier() is APrivateVisibilityModifier || !sameFile && aDecl.GetStatic() != null) { continue; } if (aDecl.GetDelegate() != null && aDecl.GetName().Text == name) { delegates.Add(aDecl); } continue; } } } } }
//private List<ErrorCollection.Error> multipleEntryCandidates = new List<ErrorCollection.Error>(); public override void CaseAMethodDecl(AMethodDecl node) { //Done in a previous iteration /*if (node.GetName().Text == "InitMap" && node.GetFormals().Count == 0) * { * if (finalTrans.multipleMainEntries) * { * multipleEntryCandidates.Add(new ErrorCollection.Error(node.GetName(), Util.GetAncestor<AASourceFile>(node.GetName()), "Candidate")); * } * else if (finalTrans.mainEntry != null) * { * multipleEntryCandidates.Add(new ErrorCollection.Error(finalTrans.mainEntry.GetName(), Util.GetAncestor<AASourceFile>(finalTrans.mainEntry.GetName()), "Candidate")); * multipleEntryCandidates.Add(new ErrorCollection.Error(node.GetName(), Util.GetAncestor<AASourceFile>(node.GetName()), "Candidate")); * //finalTrans.errors.Add(new ErrorCollection.Error(node.GetName(), Util.GetAncestor<AASourceFile>(node), "Found multiple candidates for a main entry", true)); * finalTrans.multipleMainEntries = true; * finalTrans.mainEntry = null; * } * else * finalTrans.mainEntry = node; * }*/ AStructDecl str = Util.GetAncestor <AStructDecl>(node); if (str != null) { if (node.GetStatic() == null) { structMethods.Add(node); } //Move the method outside the struct str.RemoveChild(node.Parent()); AASourceFile file = (AASourceFile)str.Parent(); int i = file.GetDecl().IndexOf(str); file.GetDecl().Insert(i /* + 1*/, node); node.GetName().Text = GetUniqueStructMethodName(str.GetName().Text + "_" + node.GetName().Text); if (node.GetStatic() == null) { //Add the struct as a parameter PType structType = new ANamedType(new TIdentifier(str.GetName().Text), null); finalTrans.data.StructTypeLinks[(ANamedType)structType] = str; if (str.GetClassToken() != null) { structType = new APointerType(new TStar("*"), structType); } structFormal = new AALocalDecl(new APublicVisibilityModifier(), null, str.GetClassToken() == null ? new TRef("ref") : null, null, null, structType, new TIdentifier("currentStruct", node.GetName().Line, node.GetName().Pos), null); node.GetFormals().Add(structFormal); data.Locals[(AABlock)node.GetBlock()].Add(structFormal); } else { node.SetStatic(null); } finalTrans.data.Methods.Add(new SharedData.DeclItem <AMethodDecl>(file, node)); if (node.GetStatic() == null) { OldParentStruct[node] = str; } //Fix refferences to other struct stuff); base.CaseAMethodDecl(node); //Will visit later, since it's added after the struct //base.CaseAMethodDecl(node); //if (str.GetLocals().Count == 0) // str.Parent().RemoveChild(str); return; } AEnrichmentDecl enrichment = Util.GetAncestor <AEnrichmentDecl>(node); if (enrichment != null) { if (node.GetStatic() == null) { structMethods.Add(node); } //Move the method outside the struct enrichment.RemoveChild(node); AASourceFile file = (AASourceFile)enrichment.Parent(); int i = file.GetDecl().IndexOf(enrichment); file.GetDecl().Insert(i /* + 1*/, node); node.GetName().Text = GetUniqueStructMethodName(Util.TypeToIdentifierString(enrichment.GetType()) + "_" + node.GetName().Text); if (node.GetStatic() == null) { //Add the struct as a parameter PType structType = Util.MakeClone(enrichment.GetType(), finalTrans.data); structFormal = new AALocalDecl(new APublicVisibilityModifier(), null, new TRef("ref"), null, null, structType, new TIdentifier("currentEnrichment", node.GetName().Line, node.GetName().Pos), null); node.GetFormals().Add(structFormal); } finalTrans.data.Methods.Add(new SharedData.DeclItem <AMethodDecl>(file, node)); //Fix refferences to other struct stuff); base.CaseAMethodDecl(node); //Will visit later, since it's added after the struct //base.CaseAMethodDecl(node); //if (str.GetLocals().Count == 0) // str.Parent().RemoveChild(str); return; } //Build a list of overloads List <AMethodDecl> overloads = new List <AMethodDecl>(); List <string> prefixMatches = new List <string>(); foreach (SharedData.DeclItem <AMethodDecl> declItem in finalTrans.data.Methods) { if (!Util.IsSameNamespace(declItem.Decl, node)) { continue; } if (declItem.Decl.GetName().Text == node.GetName().Text) { overloads.Add(declItem.Decl); } if (declItem.Decl.GetName().Text.StartsWith(node.GetName().Text + "O")) { prefixMatches.Add(declItem.Decl.GetName().Text); } } foreach (AMethodDecl method in finalTrans.data.Libraries.Methods) { if (method.GetBlock() != null || method.GetNative() != null) { if (method.GetName().Text == node.GetName().Text) { overloads.Add(method); } if (method.GetName().Text.StartsWith(node.GetName().Text + "O")) { prefixMatches.Add(method.GetName().Text); } } } //Add fields foreach (SharedData.DeclItem <AFieldDecl> declItem in finalTrans.data.Fields) { if (declItem.Decl.GetName().Text.StartsWith(node.GetName().Text + "O")) { prefixMatches.Add(declItem.Decl.GetName().Text); } } foreach (AFieldDecl field in finalTrans.data.Libraries.Fields) { if (field.GetName().Text.StartsWith(node.GetName().Text + "O")) { prefixMatches.Add(field.GetName().Text); } } //Dont want to hit another method by appending O# string postfix = ""; while (true) { postfix += "O"; if (prefixMatches.Any(text => text.StartsWith(node.GetName().Text + postfix))) { continue; } break; } if (overloads.Count > 1) { int i = 0; foreach (AMethodDecl method in overloads) { if (node == finalTrans.mainEntry || (node.GetTrigger() != null && finalTrans.data.HasUnknownTrigger)) { continue; } i++; method.GetName().Text += postfix + i; } } if (node != finalTrans.mainEntry && (node.GetTrigger() == null || !finalTrans.data.HasUnknownTrigger)) { node.GetName().Text = namespacePrefix + node.GetName().Text; } base.CaseAMethodDecl(node); }
public override void CaseASimpleInvokeExp(ASimpleInvokeExp node) { AMethodDecl decl = finalTrans.data.SimpleMethodLinks[node]; if (structMethods.Contains(decl)) { //The target is a struct method that has been moved out if (node.GetArgs().Count < decl.GetFormals().Count&& Util.HasAncestor <AStructDecl>(node)) { //If this is the case, we Must be inside the same struct as the target. - Not with enheritance ALocalLvalue local = new ALocalLvalue(new TIdentifier("tempName")); ALvalueExp exp = new ALvalueExp(local); finalTrans.data.LvalueTypes[local] = finalTrans.data.ExpTypes[exp] = structFormal.GetType(); finalTrans.data.LocalLinks[local] = structFormal; //If we're calling from class to struct, we must depointer it AStructDecl currentStruct = finalTrans.data.StructMethods.First( pair => pair.Value.Contains(Util.GetAncestor <AMethodDecl>(node))).Key; AStructDecl baseStruct = finalTrans.data.StructMethods.First( pair => pair.Value.Contains(decl)).Key; if (currentStruct.GetClassToken() != baseStruct.GetClassToken()) //It's not possible to call from struct to class { APointerLvalue pointerLvalue = new APointerLvalue(new TStar("*"), exp); exp = new ALvalueExp(pointerLvalue); finalTrans.data.LvalueTypes[pointerLvalue] = finalTrans.data.ExpTypes[exp] = ((APointerType)structFormal.GetType()).GetType(); } node.GetArgs().Add(exp); } } else if (Util.GetAncestor <AStructDecl>(decl) != null && OldParentStruct.ContainsKey(Util.GetAncestor <AMethodDecl>(node))) { //The target is a struct method that hasn't been moved out if (Util.GetAncestor <AStructDecl>(decl) == OldParentStruct[Util.GetAncestor <AMethodDecl>(node)] && decl.GetStatic() == null) { //We have an internal struct call. Expect to have one too many args if (node.GetArgs().Count == decl.GetFormals().Count) { ALocalLvalue local = new ALocalLvalue(new TIdentifier("tempName")); ALvalueExp exp = new ALvalueExp(local); finalTrans.data.LvalueTypes[local] = finalTrans.data.ExpTypes[exp] = structFormal.GetType(); finalTrans.data.LocalLinks[local] = structFormal; //If we're calling from class to struct, we must depointer it AStructDecl currentStruct = finalTrans.data.StructMethods.First( pair => pair.Value.Contains(Util.GetAncestor <AMethodDecl>(node))).Key; AStructDecl baseStruct = finalTrans.data.StructMethods.First( pair => pair.Value.Contains(decl)).Key; if (currentStruct.GetClassToken() != baseStruct.GetClassToken()) //It's not possible to call from struct to class { APointerLvalue pointerLvalue = new APointerLvalue(new TStar("*"), exp); exp = new ALvalueExp(pointerLvalue); finalTrans.data.LvalueTypes[pointerLvalue] = finalTrans.data.ExpTypes[exp] = ((APointerType)structFormal.GetType()).GetType(); } node.GetArgs().Add(exp); } } } base.CaseASimpleInvokeExp(node); }