public void Visit(FuncDecl decl) { Deserialize(decl); decl.Virtual = LoadEnum <Virtual>(this.Element.Attribute("Virtual").Value); decl.Function = LoadEnum <Function>(this.Element.Attribute("Function").Value); decl.Type = TypeDecl.Deserialize(this.Element.Element("Type").Elements().First()); }
public static bool ParseType(string[] tokens, ref int index, out TypeDecl decl, out string name) { decl = null; name = null; TypeDecl miniType = null; if (ParseMiniType(tokens, ref index, out miniType)) { CallingConvention callingConvention = CallingConvention.Default; TypeDecl continuationDecl = null; Action<TypeDecl> continuation = null; ParseTypeContinue(tokens, ref index, out callingConvention, out continuationDecl, out continuation, out name); if (callingConvention != CallingConvention.Default) { throw new ArgumentException("Failed to parse."); } if (continuationDecl != null) { continuation(miniType); decl = continuationDecl; } else { decl = miniType; } return true; } else { return false; } }
public void Visit(FunctionTypeDecl decl) { Deserialize(decl); decl.CallingConvention = LoadEnum <CallingConvention>(this.Element.Attribute("CallingConvention").Value); decl.Const = bool.Parse(this.Element.Attribute("Const").Value); decl.ReturnType = TypeDecl.Deserialize(this.Element.Element("ReturnType").Elements().First()); decl.Parameters = this.Element.Element("Parameters").Elements().Select(x => (VarDecl)SymbolDecl.Deserialize(x)).ToList(); }
private void Serialize(TypeDecl decl) { if (decl.ReferencingNameKey != null) { this.Element.Add(new XAttribute("ReferencingNameKey", decl.ReferencingNameKey)); } if (decl.ReferencingOverloadKeys != null) { this.Element.Add(new XElement("ReferencingOverloadKeys", decl.ReferencingOverloadKeys.Select(x => new XElement("Key", new XAttribute("Value", x))))); } }
private void Deserialize(TypeDecl decl) { if (this.Element.Attribute("ReferencingNameKey") != null) { decl.ReferencingNameKey = this.Element.Attribute("ReferencingNameKey").Value; } if (this.Element.Element("ReferencingOverloadKeys") != null) { decl.ReferencingOverloadKeys = this.Element.Element("ReferencingNameKey").Elements("Key").Select(x => x.Attribute("Value").Value).ToList(); } }
public TypeDecl FindRefType(TypeDecl type) { while (type != null) { var generic = type as GenericTypeDecl; if (generic != null) { type = generic.Element; continue; } break; } return(type); }
private void AddError(TypeDecl decl, string name) { List <SymbolDecl> decls = null; if (this.Environment.AvailableNames.TryGetValue(name, out decls)) { decls = decls .Where(x => !(x is FuncDecl) && !(x is VarDecl) && !(x is EnumDecl)) .ToList(); if (decls.Count == 0) { if (!this.SupressError) { this.Environment.AddError(false, "Failed to resolve {0} in {1}.", name, this.Symbol); } } else { decl.ReferencingOverloadKeys = decls .Select(x => x.OverloadKey) .Distinct() .ToList(); var printingKeys = decl.ReferencingOverloadKeys.Aggregate("", (a, b) => a + "\r\n" + b); if (!this.SupressError) { this.Environment.AddError(false, "Failed to resolve {0} in {1}, treated as a open type:" + printingKeys, name, this.Symbol); } } } else { if (!this.SupressError) { this.Environment.AddError(true, "Failed to resolve {0} in {1}.", name, this.Symbol); } } }
public void Visit(SubTypeDecl decl) { Deserialize(decl); decl.Name = Element.Attribute("Name").Value; decl.Parent = TypeDecl.Deserialize(this.Element.Element("Parent").Elements().First()); }
internal static List<SymbolDecl> FindSymbolInContent(ResolveEnvironment environment, SymbolDecl symbol, TypeDecl decl, string name, Dictionary<string, List<SymbolDecl>> content, bool typeAndNamespaceOnly, bool addError) { if (content == null) { return null; } List<SymbolDecl> decls = null; if (content.TryGetValue(name, out decls)) { if (typeAndNamespaceOnly) { decls = decls .Where(x => !(x is FuncDecl) && !(x is VarDecl) && !(x is EnumDecl)) .ToList(); if (decls.Count == 0) { return null; } } var nameKeys = decls.Select(x => x.NameKey).Distinct().ToList(); var overloadKeys = decls.Select(x => x.OverloadKey).Distinct().ToList(); if (overloadKeys.Count > 0) { decl.ReferencingOverloadKeys = overloadKeys; } if (nameKeys.Count > 1) { if (addError) { var printingKeys = overloadKeys.Aggregate("", (a, b) => a + "\r\n" + b); environment.AddError(false, "Found multiple symbols for {0} in {1}: " + printingKeys, name, symbol); } return null; } decl.ReferencingNameKey = nameKeys[0]; return decls; } return null; }
public void Visit(TypedefDecl decl) { Deserialize(decl); decl.Type = TypeDecl.Deserialize(this.Element.Element("Type").Elements().First()); }
public void Visit(TemplateDecl decl) { Deserialize(decl); decl.TypeParameters = this.Element.Element("TypeParameters").Elements().Select(x => (TypeParameterDecl)SymbolDecl.Deserialize(x)).ToList(); decl.Specialization = this.Element.Element("Specialization").Elements().Select(x => TypeDecl.Deserialize(x)).ToList(); decl.Element = SymbolDecl.Deserialize(this.Element.Element("Element").Elements().First()); }
public void Visit(VarDecl decl) { Deserialize(decl); decl.Static = bool.Parse(this.Element.Attribute("Static").Value); decl.Type = TypeDecl.Deserialize(this.Element.Element("Type").Elements().First()); }
static bool ParseMiniType(string[] tokens, ref int index, out TypeDecl decl) { decl = null; if (CppParser.Token(tokens, ref index, "const")) { decl = new DecorateTypeDecl { Decoration = Decoration.Const, Element = EnsureMiniType(tokens, ref index), }; return true; } else if (CppParser.Token(tokens, ref index, "volatile")) { decl = new DecorateTypeDecl { Decoration = Decoration.Volatile, Element = EnsureMiniType(tokens, ref index), }; return true; } else if (CppParser.Token(tokens, ref index, "signed")) { decl = new DecorateTypeDecl { Decoration = Decoration.Signed, Element = EnsureMiniType(tokens, ref index), }; return true; } else if (CppParser.Token(tokens, ref index, "unsigned")) { decl = new DecorateTypeDecl { Decoration = Decoration.Unsigned, Element = EnsureMiniType(tokens, ref index), }; return true; } else if (CppParser.Token(tokens, ref index, "decltype")) { CppParser.EnsureToken(tokens, ref index, "("); int oldIndex = index; CppParser.SkipUntil(tokens, ref index, ")"); decl = new DeclTypeDecl { Expression = tokens .Skip(oldIndex) .Take(index - 1 - oldIndex) .Aggregate((a, b) => a + " " + b), }; return true; } else if (CppParser.Token(tokens, ref index, "false") || CppParser.Token(tokens, ref index, "true")) { decl = new ConstantTypeDecl { Value = tokens[index - 1], }; return true; } else { if (index < tokens.Length) { int value = 0; if (int.TryParse(tokens[index], out value)) { index++; decl = new ConstantTypeDecl { Value = tokens[index - 1], }; return true; } } string token = null; CppParser.Token(tokens, ref index, "typename"); if (CppParser.Id(tokens, ref index, out token)) { decl = new RefTypeDecl { Name = token, }; if (token != "operator") { while (true) { if (CppParser.Token(tokens, ref index, "<")) { var genericDecl = new GenericTypeDecl { Element = decl, TypeArguments = new List<TypeDecl>(), }; decl = genericDecl; if (!CppParser.Token(tokens, ref index, ">")) { while (true) { genericDecl.TypeArguments.Add(EnsureTypeWithoutName(tokens, ref index)); if (CppParser.Token(tokens, ref index, ">")) { break; } else { CppParser.EnsureToken(tokens, ref index, ","); } } } } else if (CppParser.Token(tokens, ref index, ":")) { CppParser.EnsureToken(tokens, ref index, ":"); CppParser.Token(tokens, ref index, "template"); if (CppParser.Id(tokens, ref index, out token)) { decl = new SubTypeDecl { Parent = decl, Name = token, }; } else { index -= 2; break; } } else { break; } } } return true; } else { return false; } } }
private void AddError(TypeDecl decl, string name) { List<SymbolDecl> decls = null; if (this.Environment.AvailableNames.TryGetValue(name, out decls)) { decls = decls .Where(x => !(x is FuncDecl) && !(x is VarDecl) && !(x is EnumDecl)) .ToList(); if (decls.Count == 0) { if (!this.SupressError) { this.Environment.AddError(false, "Failed to resolve {0} in {1}.", name, this.Symbol); } } else { decl.ReferencingOverloadKeys = decls .Select(x => x.OverloadKey) .Distinct() .ToList(); var printingKeys = decl.ReferencingOverloadKeys.Aggregate("", (a, b) => a + "\r\n" + b); if (!this.SupressError) { this.Environment.AddError(false, "Failed to resolve {0} in {1}, treated as a open type:" + printingKeys, name, this.Symbol); } } } else { if (!this.SupressError) { this.Environment.AddError(true, "Failed to resolve {0} in {1}.", name, this.Symbol); } } }
public void Visit(GenericTypeDecl decl) { Deserialize(decl); decl.Element = TypeDecl.Deserialize(this.Element.Element("Element").Elements().First()); decl.TypeArguments = this.Element.Element("TypeArguments").Elements().Select(x => TypeDecl.Deserialize(x)).ToList(); }
public TypeDecl FindRefType(TypeDecl type) { while (type != null) { var generic = type as GenericTypeDecl; if (generic != null) { type = generic.Element; continue; } break; } return type; }
static void ParseTypeContinue(string[] tokens, ref int index, out CallingConvention callingConvention, out TypeDecl decl, out Action<TypeDecl> continuation, out string name) { callingConvention = CallingConvention.Default; decl = null; continuation = null; name = null; if (CppParser.Token(tokens, ref index, "__cdecl")) { callingConvention = CallingConvention.CDecl; } else if (CppParser.Token(tokens, ref index, "__clrcall")) { callingConvention = CallingConvention.ClrCall; } else if (CppParser.Token(tokens, ref index, "__stdcall")) { callingConvention = CallingConvention.StdCall; } else if (CppParser.Token(tokens, ref index, "__fastcall")) { callingConvention = CallingConvention.FastCall; } else if (CppParser.Token(tokens, ref index, "__thiscall")) { callingConvention = CallingConvention.ThisCall; } else if (CppParser.Token(tokens, ref index, "__vectorcall")) { callingConvention = CallingConvention.VectorCall; } TypeDecl beforeDecl = null; Action<TypeDecl> beforeContinuation = null; ParseTypeContinueBeforeName(tokens, ref index, out beforeDecl, out beforeContinuation, out name); TypeDecl middleDecl = null; Action<TypeDecl> middleContinuation = null; if (name == null) { int middleIndex = index; bool recursive = false; if (CppParser.Token(tokens, ref middleIndex, "(")) { string token = null; CppParser.SkipUntil(tokens, ref middleIndex, out token, ",", ")"); if (token == ")") { recursive = tokens[middleIndex] == "(" || tokens[middleIndex] == "["; } } if (recursive) { CppParser.EnsureToken(tokens, ref index, "("); var middleCallingConvention = CallingConvention.Default; ParseTypeContinue(tokens, ref index, out middleCallingConvention, out middleDecl, out middleContinuation, out name); CppParser.EnsureToken(tokens, ref index, ")"); if (middleCallingConvention != CallingConvention.Default) { if (callingConvention == CallingConvention.Default) { callingConvention = middleCallingConvention; } else { throw new ArgumentException("Failed to parse."); } } } } TypeDecl afterDecl = null; Action<TypeDecl> afterContinuation = null; ParseTypeContinueAfterName(tokens, ref index, ref callingConvention, out afterDecl, out afterContinuation); decl = middleDecl; continuation = middleContinuation; if (afterDecl != null) { if (decl == null) { decl = afterDecl; } else { continuation(afterDecl); } continuation = afterContinuation; } if (beforeDecl != null) { if (decl == null) { decl = beforeDecl; } else { continuation(beforeDecl); } continuation = beforeContinuation; } }
public void Visit(DecorateTypeDecl decl) { Deserialize(decl); decl.Decoration = LoadEnum <Decoration>(this.Element.Attribute("Decoration").Value); decl.Element = TypeDecl.Deserialize(this.Element.Element("Element").Elements().First()); }
internal static void ParseTypeContinueAfterName(string[] tokens, ref int index, ref CallingConvention callingConvention, out TypeDecl decl, out Action<TypeDecl> continuation) { decl = null; continuation = null; while (true) { if (CppParser.Token(tokens, ref index, "[")) { var oldIndex = index; CppParser.SkipUntil(tokens, ref index, "]"); var arrayDecl = new ArrayTypeDecl { Expression = tokens .Skip(oldIndex) .Take(index - 1 - oldIndex) .Aggregate("", (a, b) => a == "" ? b : a + " " + b), }; if (decl == null) { continuation = x => arrayDecl.Element = x; } else { arrayDecl.Element = decl; } decl = arrayDecl; } else if (CppParser.Token(tokens, ref index, "(")) { var funcDecl = new FunctionTypeDecl { Const = false, CallingConvention = callingConvention, Parameters = new List<VarDecl>(), }; callingConvention = CallingConvention.Default; if (decl == null) { continuation = x => funcDecl.ReturnType = x; } else { funcDecl.ReturnType = decl; } decl = funcDecl; bool skipParameters = false; if (CppParser.Token(tokens, ref index, "void")) { if (CppParser.Token(tokens, ref index, ")")) { skipParameters = true; } else { index--; } } if (!skipParameters && !CppParser.Token(tokens, ref index, ")")) { while (true) { string name = null; var parameterType = EnsureType(tokens, ref index, out name); funcDecl.Parameters.Add(new VarDecl { Static = false, Name = name, Type = parameterType, }); if (CppParser.Token(tokens, ref index, "=")) { CppParser.SkipUntilInTemplate(tokens, ref index, ",", ")", ";"); index--; } if (CppParser.Token(tokens, ref index, ")")) { break; } CppParser.EnsureToken(tokens, ref index, ","); } } while (true) { if (CppParser.Token(tokens, ref index, "const")) { funcDecl.Const = true; } else if (CppParser.Token(tokens, ref index, "override")) { } else { break; } } } else { break; } } }
static void ParseTypeContinueBeforeName(string[] tokens, ref int index, out TypeDecl decl, out Action<TypeDecl> continuation, out string name) { decl = null; continuation = null; name = null; while (true) { Decoration? decoration = null; if (CppParser.Token(tokens, ref index, "const")) { decoration = Decoration.Const; } else if (CppParser.Token(tokens, ref index, "volatile")) { decoration = Decoration.Volatile; } else if (CppParser.Token(tokens, ref index, "*")) { decoration = Decoration.Pointer; } else if (CppParser.Token(tokens, ref index, "&")) { if (CppParser.Token(tokens, ref index, "&")) { decoration = Decoration.RightRef; } else { decoration = Decoration.LeftRef; } } else if (CppParser.Token(tokens, ref index, ".")) { CppParser.EnsureToken(tokens, ref index, "."); CppParser.EnsureToken(tokens, ref index, "."); var vaDecl = new VariadicArgumentTypeDecl { }; if (decl == null) { continuation = x => vaDecl.Element = x; } else { vaDecl.Element = decl; } decl = vaDecl; } else { TypeDecl classType = null; if (ParseMiniType(tokens, ref index, out classType)) { if (CppParser.Token(tokens, ref index, ":")) { CppParser.EnsureToken(tokens, ref index, ":"); var classMemberTypeDecl = new ClassMemberTypeDecl { ClassType = classType, }; if (decl == null) { continuation = x => classMemberTypeDecl.Element = x; } else { classMemberTypeDecl.Element = decl; } decl = classMemberTypeDecl; } else { var subType = classType as SubTypeDecl; var refType = classType as RefTypeDecl; if (subType != null) { name = subType.Name; var classMemberTypeDecl = new ClassMemberTypeDecl { ClassType = subType.Parent, }; if (decl == null) { continuation = x => classMemberTypeDecl.Element = x; } else { classMemberTypeDecl.Element = decl; } decl = classMemberTypeDecl; } else if (refType != null) { name = refType.Name; } else { throw new ArgumentException("Failed to parse."); } if (name == "operator") { if (tokens[index + 1] == "(") { name += " " + tokens[index]; index += 1; } else if (tokens[index + 2] == "(") { name += " " + tokens[index] + tokens[index + 1]; index += 2; } else { throw new ArgumentException("Failed to parse."); } } break; } } else { break; } } if (decoration != null) { var decorateDecl = new DecorateTypeDecl { Decoration = decoration.Value, }; if (decl == null) { continuation = x => decorateDecl.Element = x; } else { decorateDecl.Element = decl; } decl = decorateDecl; } } }
public void Visit(ArrayTypeDecl decl) { Deserialize(decl); decl.Element = TypeDecl.Deserialize(this.Element.Element("Element").Elements().First()); decl.Expression = this.Element.Attribute("Expression").Value; }
internal static List <SymbolDecl> FindSymbolInContent(ResolveEnvironment environment, SymbolDecl symbol, TypeDecl decl, string name, Dictionary <string, List <SymbolDecl> > content, bool typeAndNamespaceOnly, bool addError) { if (content == null) { return(null); } List <SymbolDecl> decls = null; if (content.TryGetValue(name, out decls)) { if (typeAndNamespaceOnly) { decls = decls .Where(x => !(x is FuncDecl) && !(x is VarDecl) && !(x is EnumDecl)) .ToList(); if (decls.Count == 0) { return(null); } } var nameKeys = decls.Select(x => x.NameKey).Distinct().ToList(); var overloadKeys = decls.Select(x => x.OverloadKey).Distinct().ToList(); if (overloadKeys.Count > 0) { decl.ReferencingOverloadKeys = overloadKeys; } if (nameKeys.Count > 1) { if (addError) { var printingKeys = overloadKeys.Aggregate("", (a, b) => a + "\r\n" + b); environment.AddError(false, "Found multiple symbols for {0} in {1}: " + printingKeys, name, symbol); } return(null); } decl.ReferencingNameKey = nameKeys[0]; return(decls); } return(null); }
public void Visit(ClassMemberTypeDecl decl) { Deserialize(decl); decl.Element = TypeDecl.Deserialize(this.Element.Element("Element").Elements().First()); decl.ClassType = TypeDecl.Deserialize(this.Element.Element("ClassType").Elements().First()); }
private List <SymbolDecl> FindSymbolInContent(TypeDecl decl, string name, Dictionary <string, List <SymbolDecl> > content, bool typeAndNamespaceOnly, bool addError) { return(FindSymbolInContent(this.Environment, this.Symbol, decl, name, content, typeAndNamespaceOnly, addError)); }
public void Visit(VariadicArgumentTypeDecl decl) { Deserialize(decl); decl.Element = TypeDecl.Deserialize(this.Element.Element("Element").Elements().First()); }
private List<SymbolDecl> FindSymbolInContent(TypeDecl decl, string name, Dictionary<string, List<SymbolDecl>> content, bool typeAndNamespaceOnly, bool addError) { return FindSymbolInContent(this.Environment, this.Symbol, decl, name, content, typeAndNamespaceOnly, addError); }