/// <summary> /// Parses the given typeElement and returns a TypeDefinition object. /// </summary> /// <param name="typeElement">the type XML typeUseElement.</param> /// <param name="context">the parser context</param> /// <returns>A new TypeDefinition object</returns> public override void ParseTypeElement(XElement typeElement, ParserContext context) { base.ParseTypeElement(typeElement, context); var partials = from specifiers in typeElement.Elements(SRC.Specifier) where specifiers.Value == "partial" select specifiers; (context.CurrentScope as TypeDefinition).IsPartial = partials.Any(); }
/// <summary> /// Creates a method definition object from <paramref name="methodElement"/>. For C++, it looks for /// <code>int A::B::Foo(){ }</code> and adds "A->B" to <see cref="NamedScope.ParentScopeCandidates"/> /// </summary> /// <param name="methodElement">The method typeUseElement</param> /// <param name="context">The parser context</param> /// <returns>the method definition object for <paramref name="methodElement"/></returns> public override void ParseMethodElement(XElement methodElement, ParserContext context) { var nameElement = methodElement.Element(SRC.Name); base.ParseMethodElement(methodElement, context); var prefix = ParseNamedScopeUsePrefix(nameElement, context); if(null != prefix) { (context.CurrentScope as NamedScope).ParentScopeCandidates.Add(prefix); } }
/// <summary> /// Parses a java file unit. This handles the "package" directive by calling <see cref="ParseNamespaceElement"/> /// </summary> /// <param name="unitElement">The file unit to parse</param> /// <param name="context">The parser context to place the global scope in</param> public override void ParseUnitElement(XElement unitElement, ParserContext context) { if(null == unitElement) throw new ArgumentNullException("unitElement"); if(unitElement.Name != SRC.Unit) throw new ArgumentException("should be a unit", "unitElement"); context.FileUnit = unitElement; var aliases = from aliasStatement in GetAliasElementsForFile(unitElement) select ParseAliasElement(aliasStatement, context); context.Aliases = new Collection<Alias>(aliases.ToList()); ParseNamespaceElement(unitElement, context); }
/// <summary> /// Creates a NamespaceDefinition object for the given namespace typeUseElement. This must be one of the typeUseElement types defined in NamespaceElementNames. /// </summary> /// <param name="namespaceElement">the namespace element</param> /// <param name="context">The parser context</param> /// <returns>a new NamespaceDefinition object</returns> public override void ParseNamespaceElement(XElement namespaceElement, ParserContext context) { if(namespaceElement == null) throw new ArgumentNullException("namespaceElement"); if(!NamespaceElementNames.Contains(namespaceElement.Name)) throw new ArgumentException(string.Format("Not a valid namespace typeUseElement: {0}", namespaceElement.Name), "namespaceElement"); var nameElement = namespaceElement.Element(SRC.Name); var namespaceName = nameElement != null ? nameElement.Value : string.Empty; var namespaceDefinition = new NamespaceDefinition { Name = namespaceName }; context.Push(namespaceDefinition); }
/// <summary> /// Parses a Java package directive /// </summary> /// <param name="namespaceElement">A file unit</param> /// <param name="context">The parser context</param> public override void ParseNamespaceElement(XElement namespaceElement, ParserContext context) { var javaPackage = context.FileUnit.Elements(SRC.Package).FirstOrDefault(); // Add a global namespace definition var globalNamespace = new NamespaceDefinition(); context.Push(globalNamespace); if(null != javaPackage) { var namespaceElements = from name in javaPackage.Elements(SRC.Name) select name; foreach(var name in namespaceElements) { var namespaceForName = new NamespaceDefinition() { Name = name.Value, ProgrammingLanguage = ParserLanguage, }; namespaceForName.AddSourceLocation(context.CreateLocation(name)); context.Push(namespaceForName, globalNamespace); } } }
/// <summary> /// Parses a C# namespace block /// </summary> /// <param name="namespaceElement">the namespace element to parse</param> /// <param name="context">the parser context</param> public override void ParseNamespaceElement(XElement namespaceElement, ParserContext context) { if(namespaceElement == null) throw new ArgumentNullException("namespaceElement"); if(!NamespaceElementNames.Contains(namespaceElement.Name)) throw new ArgumentException(string.Format("Not a valid namespace element: {0}", namespaceElement.Name), "namespaceElement"); var nameElement = namespaceElement.Element(SRC.Name); string namespaceName; if(nameElement == null) { namespaceName = string.Empty; } else { NamespaceDefinition root = null; foreach(var name in NameHelper.GetNameElementsFromName(nameElement)) { var namespaceForName = new NamespaceDefinition() { Name = name.Value, ProgrammingLanguage = ParserLanguage, }; if(root == null) { root = namespaceForName; } else { namespaceForName.AddSourceLocation(context.CreateLocation(name)); } context.Push(namespaceForName, root); } } }
/// <summary> /// Parses the given <paramref name="aliasElement"/> and creates an ImportStatement or AliasStatement from it. /// </summary> /// <param name="aliasElement">The alias element to parse.</param> /// <param name="context">The parser context to use.</param> /// <returns>An ImportStatement if the element is an import, or an AliasStatement if it is an alias.</returns> protected override Statement ParseAliasElement(XElement aliasElement, ParserContext context) { if(aliasElement == null) throw new ArgumentNullException("aliasElement"); if(aliasElement.Name != AliasElementName) throw new ArgumentException(string.Format("Must be a SRC.{0} element", AliasElementName.LocalName), "aliasElement"); if(context == null) throw new ArgumentNullException("context"); Statement stmt = null; if(GetTextNodes(aliasElement).Any(n => n.Value.Contains("("))) { //using block stmt = ParseUsingBlockElement(aliasElement, context); } else if(aliasElement.Element(SRC.Init) != null) { //alias var alias = new AliasStatement() {ProgrammingLanguage = ParserLanguage}; alias.AddLocation(context.CreateLocation(aliasElement)); var nameElement = aliasElement.Element(SRC.Name); if(nameElement != null) { alias.AliasName = nameElement.Value; } var initElement = aliasElement.Element(SRC.Init); alias.Target = ParseExpression<TypeContainerUse>(GetFirstChildExpression(initElement), context); stmt = alias; } else { //import var import = new ImportStatement() {ProgrammingLanguage = ParserLanguage}; import.AddLocation(context.CreateLocation(aliasElement)); var nameElement = aliasElement.Element(SRC.Name); if(nameElement != null) { import.ImportedNamespace = ParseNameUseElement<NamespaceUse>(nameElement, context); } stmt = import; } return stmt; }
/// <summary> /// Parses the given <paramref name="aliasElement"/> and creates an ImportStatement or AliasStatement from it. /// </summary> /// <param name="aliasElement">The alias element to parse.</param> /// <param name="context">The parser context to use.</param> /// <returns>An ImportStatement if the element is an import, or an AliasStatement if it is an alias.</returns> protected override Statement ParseAliasElement(XElement aliasElement, ParserContext context) { if(aliasElement == null) throw new ArgumentNullException("aliasElement"); if(aliasElement.Name != AliasElementName) throw new ArgumentException(string.Format("Must be a SRC.{0} element", AliasElementName.LocalName), "aliasElement"); if(context == null) throw new ArgumentNullException("context"); var isNamespaceImport = aliasElement.Descendants(SRC.Name).Any(n => n.Value.Contains("*")); //Elements("name").Any(n => n.Value.Contains("*")); //).Any(n => n.Value.Contains("*")); Statement stmt = null; if(isNamespaceImport) { //namespace import var import = new ImportStatement() {ProgrammingLanguage = ParserLanguage}; import.AddLocation(context.CreateLocation(aliasElement)); var nameElement = aliasElement.Element(SRC.Name); if(nameElement != null) { //we have an import that ends with .*. We remove the . and *. nameElement.LastNode.Remove();//remove * nameElement.LastNode.Remove();//remove . import.ImportedNamespace = ParseNameUseElement<NamespaceUse>(nameElement, context); //TODO: fix to handle the trailing operator tag } stmt = import; } else { //importing a single member, i.e. an alias var alias = new AliasStatement() {ProgrammingLanguage = ParserLanguage}; alias.AddLocation(context.CreateLocation(aliasElement)); var nameElement = aliasElement.Element(SRC.Name); if(nameElement != null) { alias.Target = ParseExpression(nameElement, context); alias.AliasName = NameHelper.GetLastName(nameElement); } stmt = alias; } return stmt; }
/// <summary> /// Parses a C# namespace block /// </summary> /// <param name="namespaceElement">the namespace element to parse</param> /// <param name="context">the parser context</param> protected override NamespaceDefinition ParseNamespaceElement(XElement namespaceElement, ParserContext context) { if(namespaceElement == null) throw new ArgumentNullException("namespaceElement"); if(!NamespaceElementNames.Contains(namespaceElement.Name)) throw new ArgumentException(string.Format("Not a valid namespace element: {0}", namespaceElement.Name), "namespaceElement"); if(context == null) throw new ArgumentNullException("context"); var nameElement = namespaceElement.Element(SRC.Name); if(nameElement == null) { throw new ParseException(context.FileName, namespaceElement.GetSrcLineNumber(), namespaceElement.GetSrcLinePosition(), this, "No SRC.Name element found in namespace.", null); } //parse the name and create a NamespaceDefinition for each component NamespaceDefinition topNS = null; NamespaceDefinition lastNS = null; foreach(var name in NameHelper.GetNameElementsFromName(nameElement)) { var newNS = new NamespaceDefinition { Name = name.Value, ProgrammingLanguage = ParserLanguage }; newNS.AddLocation(context.CreateLocation(name)); if(topNS == null) { topNS = newNS; } if(lastNS != null) { lastNS.AddChildStatement(newNS); } lastNS = newNS; } //add body of namespace to lastNS var blockElement = namespaceElement.Element(SRC.Block); if(blockElement != null) { foreach(var child in blockElement.Elements()) { lastNS.AddChildStatement(ParseStatement(child, context)); } } return topNS; }
/// <summary> /// Creates a resolvable use from an expression /// </summary> /// <param name="element">The element to parse</param> /// <param name="context">The parser context</param> /// <returns>A resolvable use object</returns> // TODO make this fit in with the rest of the parse methods (rename to parse) public virtual IResolvesToType CreateResolvableUse(XElement element, ParserContext context) { var use = new VariableUse() { Location = context.CreateLocation(element, true), ParentScope = context.CurrentScope, ProgrammingLanguage = ParserLanguage, }; return use; }
/// <summary> /// Creates a ForStatement or ForeachStatement from the given element. /// </summary> /// <param name="forElement">The SRC.For element to parse.</param> /// <param name="context">The parser context to use.</param> /// <returns>A ForStatement or ForeachStatement corresponding to forElement.</returns> protected override ConditionBlockStatement ParseForElement(XElement forElement, ParserContext context) { if(forElement == null) throw new ArgumentNullException("forElement"); if(forElement.Name != SRC.For) throw new ArgumentException("Must be a SRC.For element", "forElement"); if(context == null) throw new ArgumentNullException("context"); var controlElement = forElement.Element(SRC.Control); if(controlElement.Element(SRC.Condition) != null) { //this is a standard for-loop, use the base processing return base.ParseForElement(forElement, context); } //else, this is a Java-style foreach loop var foreachStmt = new ForeachStatement() {ProgrammingLanguage = ParserLanguage}; foreachStmt.AddLocation(context.CreateLocation(forElement)); foreach(var child in forElement.Elements()) { if(child.Name == SRC.Init) { //fill in condition/initializer var expElement = GetFirstChildExpression(child); if(expElement != null) { foreachStmt.Condition = ParseExpression(expElement, context); } } else if(child.Name == SRC.Block) { //add children from block var blockStatements = child.Elements().Select(e => ParseStatement(e, context)); foreachStmt.AddChildStatements(blockStatements); } else { //add child foreachStmt.AddChildStatement(ParseStatement(child, context)); } } return foreachStmt; }
/// <summary> /// Parses an element corresponding to a type definition and creates a TypeDefinition object /// </summary> /// <param name="typeElement">The type element to parse. This must be one of the elements contained in TypeElementNames.</param> /// <param name="context">The parser context</param> /// <returns>A TypeDefinition parsed from the element</returns> protected override TypeDefinition ParseTypeElement(XElement typeElement, ParserContext context) { var typeDefinition = base.ParseTypeElement(typeElement, context); typeDefinition.IsPartial = ElementHasPartialKeyword(typeElement); return typeDefinition; }
/// <summary> /// Creates a variable use from the given element. Must be a <see cref="ABB.SrcML.SRC.Expression"/>, <see cref="ABB.SrcML.SRC.Name"/>, or <see cref="ABB.SrcML.SRC.ExpressionStatement"/> /// </summary> /// <param name="element">The element to parse</param> /// <param name="context">The parser context</param> /// <returns>A variable use object</returns> // TODO make this fit in with the rest of the parse methods public virtual VariableUse CreateVariableUse(XElement element, ParserContext context) { XElement nameElement; if(element.Name == SRC.Name) { nameElement = element; } else if(element.Name == SRC.Expression) { nameElement = element.Element(SRC.Name); } else if(element.Name == SRC.ExpressionStatement || element.Name == SRC.Argument) { nameElement = element.Element(SRC.Expression).Element(SRC.Name); } else { throw new ArgumentException("element should be an expression, expression statement, argument, or name", "element"); } var lastNameElement = NameHelper.GetLastNameElement(nameElement); var variableUse = new VariableUse() { Location = context.CreateLocation(lastNameElement, true), Name = lastNameElement.Value, ParentScope = context.CurrentScope, ProgrammingLanguage = ParserLanguage, }; return variableUse; }
/// <summary> /// Creates a <see cref="PropertyDefinition"/> object for <paramref name="propertyElement"/>. /// </summary> /// <param name="propertyElement">The SRC.Declaration element to parse. This must be a declaration of a property.</param> /// <param name="context">The context to use.</param> /// <returns>A <see cref="PropertyDefinition"/> corresponding to <paramref name="propertyElement"/>.</returns> protected virtual PropertyDefinition ParsePropertyDeclarationElement(XElement propertyElement, ParserContext context) { if(propertyElement == null) throw new ArgumentNullException("propertyElement"); if(propertyElement.Name != SRC.Property) throw new ArgumentException("Must be a SRC.Property element", "propertyElement"); if(context == null) throw new ArgumentNullException("context"); var propertyDef = new PropertyDefinition {ProgrammingLanguage = ParserLanguage}; propertyDef.AddLocation(context.CreateLocation(propertyElement)); foreach(var child in propertyElement.Elements()) { if(child.Name == SRC.Type) { propertyDef.Accessibility = GetAccessModifierFromTypeUseElement(child); propertyDef.ReturnType = ParseTypeUseElement(child, context); } else if(child.Name == SRC.Name) { propertyDef.Name = child.Value; } else if(child.Name == SRC.Block) { //add children from block. This should be the getter/setter methods var blockStatements = child.Elements().Select(e => ParseStatement(e, context)); propertyDef.AddChildStatements(blockStatements); } else { propertyDef.AddChildStatement(ParseStatement(child, context)); } } return propertyDef; }
/// <summary> /// Creates a NamespaceDefinition object for the given namespace typeUseElement. This must /// be one of the typeUseElement types defined in NamespaceElementNames. /// </summary> /// <param name="namespaceElement">the namespace element</param> /// <param name="context">The parser context</param> /// <returns>a new NamespaceDefinition object</returns> protected override NamespaceDefinition ParseNamespaceElement(XElement namespaceElement, ParserContext context) { if(namespaceElement == null) throw new ArgumentNullException("namespaceElement"); if(!NamespaceElementNames.Contains(namespaceElement.Name)) throw new ArgumentException(string.Format("Not a valid namespace element: {0}", namespaceElement.Name), "namespaceElement"); if(context == null) throw new ArgumentNullException("context"); var nameElement = namespaceElement.Element(SRC.Name); var namespaceName = nameElement != null ? nameElement.Value : string.Empty; var nd = new NamespaceDefinition { Name = namespaceName, ProgrammingLanguage = ParserLanguage, }; nd.AddLocation(context.CreateLocation(namespaceElement)); //add children var blockElement = namespaceElement.Element(SRC.Block); if(blockElement != null) { foreach(var child in blockElement.Elements()) { nd.AddChildStatement(ParseStatement(child, context)); } } return nd; }
/// <summary> /// This method parses and returns the children within the public/protected/private block under a C++ class, /// and sets the specified access modifier on the children that support it. /// </summary> private IEnumerable <Statement> ParseClassChildren(XElement accessBlockElement, ParserContext context, AccessModifier accessModifier) { if (accessBlockElement == null) { throw new ArgumentNullException("accessBlockElement"); } if (!(new[] { SRC.Public, SRC.Protected, SRC.Private }.Contains(accessBlockElement.Name))) { throw new ArgumentException("Not a valid accessibility block element", "accessBlockElement"); } if (context == null) { throw new ArgumentNullException("context"); } var children = accessBlockElement.Elements().Select(e => ParseStatement(e, context)).ToList(); foreach (var ne in children.OfType <INamedEntity>()) { ne.Accessibility = accessModifier; } return(children); }
private NamespaceUse CreateNamespaceUsePrefix(XElement nameElement, ParserContext context) { IEnumerable<XElement> parentNameElements = Enumerable.Empty<XElement>(); parentNameElements = NameHelper.GetNameElementsExceptLast(nameElement); NamespaceUse current = null, root = null; if(parentNameElements.Any()) { foreach(var element in parentNameElements) { var namespaceUse = new NamespaceUse { Name = element.Value, Location = context.CreateLocation(element, false), ProgrammingLanguage = this.ParserLanguage, }; if(null == root) { root = namespaceUse; } if(current != null) { current.ChildScopeUse = namespaceUse; } current = namespaceUse; } } return root; }
/// <summary> /// Parses the given <paramref name="aliasElement"/> and creates an ImportStatement or AliasStatement from it. /// </summary> /// <param name="aliasElement">The alias element to parse.</param> /// <param name="context">The parser context to use.</param> /// <returns>An ImportStatement if the element is an import, or an AliasStatement if it is an alias.</returns> protected override Statement ParseAliasElement(XElement aliasElement, ParserContext context) { if (null == aliasElement) { throw new ArgumentNullException("aliasElement"); } if (aliasElement.Name != AliasElementName) { throw new ArgumentException(string.Format("Must be a SRC.{0} element", AliasElementName.LocalName), "aliasElement"); } if (context == null) { throw new ArgumentNullException("context"); } Statement stmt = null; bool containsNamespaceKeyword = (from textNode in GetTextNodes(aliasElement) where textNode.Value.Contains("namespace") select textNode).Any(); if (containsNamespaceKeyword) { //import statement var import = new ImportStatement() { ProgrammingLanguage = ParserLanguage }; import.AddLocation(context.CreateLocation(aliasElement)); var nameElement = aliasElement.Element(SRC.Name); if (nameElement != null) { import.ImportedNamespace = ParseNameUseElement <NamespaceUse>(nameElement, context); } stmt = import; } else { //alias statement var alias = new AliasStatement() { ProgrammingLanguage = ParserLanguage }; alias.AddLocation(context.CreateLocation(aliasElement)); var nameElement = aliasElement.Element(SRC.Name); var initElement = aliasElement.Element(SRC.Init); if (initElement != null) { //example: using foo = std::bar; if (nameElement != null) { alias.AliasName = nameElement.Value; } //TODO check this once srcml is updated to see if it's accurate alias.Target = ParseExpression(GetFirstChildExpression(initElement), context); } else { //example: using std::cout; if (nameElement != null) { alias.Target = ParseTypeUseElement(nameElement, context); alias.AliasName = NameHelper.GetLastName(nameElement); } } stmt = alias; } return(stmt); }
/// <summary> /// Creates a NamespaceDefinition object for the given namespace typeUseElement. This must /// be one of the typeUseElement types defined in NamespaceElementNames. /// </summary> /// <param name="namespaceElement">the namespace element</param> /// <param name="context">The parser context</param> /// <returns>a new NamespaceDefinition object</returns> protected override NamespaceDefinition ParseNamespaceElement(XElement namespaceElement, ParserContext context) { if (namespaceElement == null) { throw new ArgumentNullException("namespaceElement"); } if (!NamespaceElementNames.Contains(namespaceElement.Name)) { throw new ArgumentException(string.Format("Not a valid namespace element: {0}", namespaceElement.Name), "namespaceElement"); } if (context == null) { throw new ArgumentNullException("context"); } var nameElement = namespaceElement.Element(SRC.Name); var namespaceName = nameElement != null ? nameElement.Value : string.Empty; var nd = new NamespaceDefinition { Name = namespaceName, ProgrammingLanguage = ParserLanguage, }; nd.AddLocation(context.CreateLocation(namespaceElement)); //add children var blockElement = namespaceElement.Element(SRC.Block); if (blockElement != null) { foreach (var child in blockElement.Elements()) { nd.AddChildStatement(ParseStatement(child, context)); } } return(nd); }
/// <summary> /// Creates a method definition object from /// <paramref name="methodElement"/>. For C++, it looks for something like <code>int A::B::Foo(){ }</code> /// and adds "A::B" as the NamePrefix. /// </summary> /// <param name="methodElement">The method element to parse. This must be one of the elements contained in MethodElementNames.</param> /// <param name="context">The parser context</param> /// <returns>The method definition object for <paramref name="methodElement"/></returns> protected override MethodDefinition ParseMethodElement(XElement methodElement, ParserContext context) { var md = base.ParseMethodElement(methodElement, context); var nameElement = methodElement.Element(SRC.Name); if (nameElement != null) { md.Prefix = ParseNamePrefix(nameElement, context); } return(md); }
/// <summary> /// Parses the given <paramref name="usingElement"/> and creates a <see cref="UsingBlockStatement"/> from it. /// </summary> /// <param name="usingElement">The SRC.Using element to parse.</param> /// <param name="context">The parser context to use.</param> /// <returns>A UsingBlockStatement created from the given usingElement.</returns> protected override UsingBlockStatement ParseUsingBlockElement(XElement usingElement, ParserContext context) { if(usingElement == null) throw new ArgumentNullException("usingElement"); if(usingElement.Name != SRC.Using_Stmt) throw new ArgumentException("Must be a SRC.Using element", "usingElement"); if(context == null) throw new ArgumentNullException("context"); var usingStmt = new UsingBlockStatement() {ProgrammingLanguage = ParserLanguage}; usingStmt.AddLocation(context.CreateLocation(usingElement)); foreach(var child in usingElement.Elements()) { if(child.Name == SRC.Init) { //TODO: waiting for update to srcml usingStmt.Initializer = ParseExpression(GetChildExpressions(child), context); } else if(child.Name == SRC.Block) { var blockStatements = child.Elements().Select(e => ParseStatement(e, context)); usingStmt.AddChildStatements(blockStatements); } else { usingStmt.AddChildStatement(ParseStatement(child, context)); } } return usingStmt; }
/// <summary> /// Parses an element corresponding to a type definition and creates a TypeDefinition object /// </summary> /// <param name="typeElement">The type element to parse. This must be one of the elements contained in TypeElementNames.</param> /// <param name="context">The parser context</param> /// <returns>A TypeDefinition parsed from the element</returns> protected override TypeDefinition ParseTypeElement(XElement typeElement, ParserContext context) { if(null == typeElement) throw new ArgumentNullException("typeElement"); if(context == null) throw new ArgumentNullException("context"); var typeDefinition = new TypeDefinition() { Accessibility = GetAccessModifierForType(typeElement), Kind = XNameMaps.GetKindForXElement(typeElement), Name = GetNameForType(typeElement), ProgrammingLanguage = ParserLanguage }; typeDefinition.AddLocation(context.CreateLocation(typeElement, ContainerIsReference(typeElement))); foreach(var parentTypeElement in GetParentTypeUseElements(typeElement)) { var parentTypeUse = ParseTypeUseElement(parentTypeElement, context); typeDefinition.AddParentType(parentTypeUse); } var typeBlock = typeElement.Element(SRC.Block); if(typeBlock != null) { foreach(var child in typeBlock.Elements()) { if(child.Name == SRC.Private) { typeDefinition.AddChildStatements(ParseClassChildren(child, context, AccessModifier.Private)); } else if(child.Name == SRC.Protected) { typeDefinition.AddChildStatements(ParseClassChildren(child, context, AccessModifier.Protected)); } else if(child.Name == SRC.Public) { typeDefinition.AddChildStatements(ParseClassChildren(child, context, AccessModifier.Public)); } else { typeDefinition.AddChildStatement(ParseStatement(child, context)); } } } return typeDefinition; }
/// <summary> /// Creates a <see cref="MethodDefinition"/> object for <paramref name="methodElement"/>. /// </summary> /// <param name="methodElement">The element to parse</param> /// <param name="context">The context to use</param> protected override MethodDefinition ParseMethodElement(XElement methodElement, ParserContext context) { var methodDefinition = base.ParseMethodElement(methodElement, context); var typeElement = methodElement.Elements(SRC.Type).FirstOrDefault(); methodDefinition.IsPartial = ElementHasPartialKeyword(null == typeElement ? methodElement : typeElement); return methodDefinition; }
/// <summary> /// Parses the given <paramref name="aliasElement"/> and creates an ImportStatement or AliasStatement from it. /// </summary> /// <param name="aliasElement">The alias element to parse.</param> /// <param name="context">The parser context to use.</param> /// <returns>An ImportStatement if the element is an import, or an AliasStatement if it is an alias.</returns> protected override Statement ParseAliasElement(XElement aliasElement, ParserContext context) { if(null == aliasElement) throw new ArgumentNullException("aliasElement"); if(aliasElement.Name != AliasElementName) throw new ArgumentException(string.Format("Must be a SRC.{0} element", AliasElementName.LocalName), "aliasElement"); if(context == null) throw new ArgumentNullException("context"); Statement stmt = null; var namespaceElement = aliasElement.Element(SRC.Namespace); if(namespaceElement != null) { //import statement var import = new ImportStatement() {ProgrammingLanguage = ParserLanguage}; import.AddLocation(context.CreateLocation(aliasElement)); var nameElement = namespaceElement.Element(SRC.Name); if(nameElement != null) { import.ImportedNamespace = ParseNameUseElement<NamespaceUse>(nameElement, context); } stmt = import; } else { //alias statement var alias = new AliasStatement() {ProgrammingLanguage = ParserLanguage}; alias.AddLocation(context.CreateLocation(aliasElement)); //TODO: Make sure that using descendant is correct for nameElement var nameElement = aliasElement.Element(SRC.Name); var initElement = aliasElement.Element(SRC.Init); if(initElement != null) { //example: using foo = std::bar; if(nameElement != null) { alias.AliasName = nameElement.Value; } //TODO check this once srcml is updated to see if it's accurate alias.Target = ParseExpression(GetFirstChildExpression(initElement), context); } else { //example: using std::cout; if(nameElement != null) { alias.Target = ParseTypeUseElement(nameElement, context); alias.AliasName = NameHelper.GetLastName(nameElement); } } stmt = alias; } return stmt; }
/// <summary> /// Creates a <see cref="Statement"/> object for <paramref name="stmtElement"/>. /// The expression contained within <paramref name="stmtElement"/> will be parsed and placed in /// Statement.Content. /// </summary> /// <param name="stmtElement">The SRC.ExpressionStatement element to parse.</param> /// <param name="context">The context to use.</param> /// <returns>A <see cref="Statement"/> corresponding to <paramref name="stmtElement"/>.</returns> protected override Statement ParseDeclarationStatementElement(XElement stmtElement, ParserContext context) { if(stmtElement == null) throw new ArgumentNullException("stmtElement"); if (stmtElement.Name != SRC.DeclarationStatement && stmtElement.Name != SRC.Property) throw new ArgumentException("Must be a SRC.DeclarationStatement element", "stmtElement"); if(context == null) throw new ArgumentNullException("context"); //first check if this is a property and parse accordingly if (stmtElement.Name == SRC.Property) { return ParsePropertyDeclarationElement(stmtElement, context); } else { var stmt = new DeclarationStatement() { ProgrammingLanguage = ParserLanguage, Content = ParseExpression(GetChildExpressions(stmtElement), context) }; stmt.AddLocation(context.CreateLocation(stmtElement)); return stmt; } }
/// <summary> /// Parses a literal use element /// </summary> /// <param name="literalElement">The literal element to parse</param> /// <param name="context">The parser context</param> /// <returns>A literal use object</returns> public virtual LiteralUse ParseLiteralElement(XElement literalElement, ParserContext context) { if(literalElement == null) throw new ArgumentNullException("literalElement"); if(literalElement.Name != LIT.Literal) throw new ArgumentException("should be a literal", "literalElement"); var kind = LiteralUse.GetLiteralKind(literalElement); string typeName = string.Empty; var use = new LiteralUse() { Kind = kind, Location = context.CreateLocation(literalElement), Name = GetTypeForLiteralValue(kind, literalElement.Value), ParentScope = context.CurrentScope, }; return use; }
/// <summary> /// Creates a method definition object from /// <paramref name="methodElement"/>. For C++, it looks for something like <code>int A::B::Foo(){ }</code> /// and adds "A::B" as the NamePrefix. /// </summary> /// <param name="methodElement">The method element to parse. This must be one of the elements contained in MethodElementNames.</param> /// <param name="context">The parser context</param> /// <returns>The method definition object for <paramref name="methodElement"/></returns> protected override MethodDefinition ParseMethodElement(XElement methodElement, ParserContext context) { var md = base.ParseMethodElement(methodElement, context); var nameElement = methodElement.Element(SRC.Name); if(nameElement != null) { md.Prefix = ParseNamePrefix(nameElement, context); } return md; }
/// <summary> /// Creates a <see cref="Statement"/> object for <paramref name="stmtElement"/>. /// The expression contained within <paramref name="stmtElement"/> will be parsed and placed in /// Statement.Content. /// </summary> /// <param name="stmtElement">The SRC.ExpressionStatement element to parse.</param> /// <param name="context">The context to use.</param> /// <returns>A <see cref="Statement"/> corresponding to <paramref name="stmtElement"/>.</returns> protected override Statement ParseDeclarationStatementElement(XElement stmtElement, ParserContext context) { if(stmtElement == null) throw new ArgumentNullException("stmtElement"); if(stmtElement.Name != SRC.DeclarationStatement) throw new ArgumentException("Must be a SRC.DeclarationStatement element", "stmtElement"); if(context == null) throw new ArgumentNullException("context"); //first check if this is a property and parse accordingly var declElement = stmtElement.Element(SRC.Declaration); if(declElement != null) { var blockElement = declElement.Element(SRC.Block); if(blockElement != null) { //this is a property return ParsePropertyDeclarationElement(declElement, context); } } //otherwise, parse as base: return base.ParseDeclarationStatementElement(stmtElement, context); }
protected override UsingBlockStatement ParseUsingBlockElement(XElement usingElement, ParserContext context) { return new UsingBlockStatement(); }
/// <summary> /// Creates a NamespaceDefinition object from the given Java package element. /// This will create a NamespaceDefinition for each component of the name, e.g. com.java.foo.bar, and link them as children of each other. /// This will not add any child statements to the bottom namespace. /// </summary> /// <param name="packageElement">The SRC.Package element to parse.</param> /// <param name="context">The parser context to use.</param> /// <returns>A NamespaceDefinition corresponding to <paramref name="packageElement"/>.</returns> protected override NamespaceDefinition ParseNamespaceElement(XElement packageElement, ParserContext context) { if(packageElement == null) throw new ArgumentNullException("packageElement"); if(packageElement.Name != SRC.Package) throw new ArgumentException("must be a SRC.Package", "packageElement"); if(context == null) throw new ArgumentNullException("context"); var nameElement = packageElement.Element(SRC.Name); if(nameElement == null) { throw new ParseException(context.FileName, packageElement.GetSrcLineNumber(), packageElement.GetSrcLinePosition(), this, "No SRC.Name element found in namespace.", null); } //parse the name and create a NamespaceDefinition for each component NamespaceDefinition topNS = null; NamespaceDefinition lastNS = null; foreach(var name in NameHelper.GetNameElementsFromName(nameElement)) { var newNS = new NamespaceDefinition { Name = name.Value, ProgrammingLanguage = ParserLanguage }; newNS.AddLocation(context.CreateLocation(name)); if(topNS == null) { topNS = newNS; } if(lastNS != null) { lastNS.AddChildStatement(newNS); } lastNS = newNS; } return topNS; }
/// <summary> /// Creates a <see cref="Statement"/> object for <paramref name="stmtElement"/>. /// The expression contained within <paramref name="stmtElement"/> will be parsed and placed in /// Statement.Content. /// </summary> /// <param name="stmtElement">The SRC.DeclarationStatement element to parse.</param> /// <param name="context">The context to use.</param> /// <returns>A <see cref="DeclarationStatement"/> corresponding to <paramref name="stmtElement"/>. /// The return type is <see cref="Statement"/> so that subclasses can return another type, as necessary. </returns> protected override Statement ParseDeclarationStatementElement(XElement stmtElement, ParserContext context) { if (stmtElement == null) throw new ArgumentNullException("stmtElement"); if (stmtElement.Name != SRC.DeclarationStatement && stmtElement.Name != SRC.Property) throw new ArgumentException("Must be a SRC.DeclarationStatement or SRC.Property element", "stmtElement"); if (context == null) throw new ArgumentNullException("context"); var stmt = new DeclarationStatement() { ProgrammingLanguage = ParserLanguage, Content = ParseExpression(GetChildExpressions(stmtElement), context) }; stmt.AddLocation(context.CreateLocation(stmtElement)); return stmt; }
/// <summary> /// Parses a java file unit. This handles the "package" directive by calling /// <see cref="ParseNamespaceElement"/> /// </summary> /// <param name="unitElement">The file unit to parse.</param> /// <param name="context">The parser context to use.</param> protected override NamespaceDefinition ParseUnitElement(XElement unitElement, ParserContext context) { if(null == unitElement) throw new ArgumentNullException("unitElement"); if(SRC.Unit != unitElement.Name) throw new ArgumentException("should be a SRC.Unit", "unitElement"); if(context == null) throw new ArgumentNullException("context"); context.FileUnit = unitElement; //var aliases = from aliasStatement in GetAliasElementsForFile(unitElement) // select ParseAliasElement(aliasStatement, context); //context.Aliases = new Collection<Alias>(aliases.ToList()); //create a global namespace for the file unit var namespaceForUnit = new NamespaceDefinition() {ProgrammingLanguage = ParserLanguage}; namespaceForUnit.AddLocation(context.CreateLocation(unitElement)); NamespaceDefinition bottomNamespace = namespaceForUnit; //create a namespace for the package, and attach to global namespace var packageElement = unitElement.Element(SRC.Package); if(packageElement != null) { var namespaceForPackage = ParseNamespaceElement(packageElement, context); namespaceForUnit.AddChildStatement(namespaceForPackage); bottomNamespace = namespaceForPackage.GetDescendantsAndSelf<NamespaceDefinition>().Last(); } //add children to bottom namespace foreach(var child in unitElement.Elements()) { var childStmt = ParseStatement(child, context); if(childStmt != null) { bottomNamespace.AddChildStatement(childStmt); } } return namespaceForUnit; }
/// <summary> /// This method parses and returns the children within the public/protected/private block under a C++ class, /// and sets the specified access modifier on the children that support it. /// </summary> private IEnumerable<Statement> ParseClassChildren(XElement accessBlockElement, ParserContext context, AccessModifier accessModifier) { if(accessBlockElement == null) throw new ArgumentNullException("accessBlockElement"); if(!(new[] {SRC.Public, SRC.Protected, SRC.Private}.Contains(accessBlockElement.Name))) throw new ArgumentException("Not a valid accessibility block element", "accessBlockElement"); if(context == null) throw new ArgumentNullException("context"); var children = accessBlockElement.Elements().Select(e => ParseStatement(e, context)).ToList(); foreach(var ne in children.OfType<INamedEntity>()) { ne.Accessibility = accessModifier; } return children; }
/// <summary> /// Creates a type use element /// </summary> /// <param name="typeUseElement">the element to parse. Must be of a <see cref="ABB.SrcML.SRC.Type"/> or <see cref="ABB.SrcML.SRC.Name"/></param> /// <param name="context">the parser context</param> /// <returns>A Type Use object</returns> public virtual TypeUse ParseTypeUseElement(XElement typeUseElement, ParserContext context) { if(typeUseElement == null) throw new ArgumentNullException("typeUseElement"); XElement typeNameElement; // validate the type use typeUseElement (must be a SRC.Name or SRC.Type) if(typeUseElement.Name == SRC.Type) { typeNameElement = typeUseElement.Elements(SRC.Name).LastOrDefault(); } else if(typeUseElement.Name == SRC.Name) { typeNameElement = typeUseElement; } else { throw new ArgumentException("typeUseElement should be of type type or name", "typeUseElement"); } XElement lastNameElement = null; // this is the name element that identifies the type being used NamedScopeUse prefix = null; // This is the prefix (in A::B::C, this would be the chain A::B) XElement typeParameterArgumentList = null; // the argument list element holds the parameters for generic type uses var typeParameters = Enumerable.Empty<TypeUse>(); // enumerable for the actual generic parameters // get the last name element and the prefix if(typeNameElement != null) { lastNameElement = NameHelper.GetLastNameElement(typeNameElement); prefix = ParseNamedScopeUsePrefix(typeNameElement, context); } // if the last name element exists, then this *may* be a generic type use // go look for the argument list element if(lastNameElement != null) { if(prefix == null) { // if there is no prefix, then the argument list element will be the first sibling of lastNameElement typeParameterArgumentList = lastNameElement.ElementsAfterSelf(SRC.ArgumentList).FirstOrDefault(); } else { // otherwise, it will be the first *child* of lastNameElement typeParameterArgumentList = lastNameElement.Elements(SRC.ArgumentList).FirstOrDefault(); } } if(typeParameterArgumentList != null) { typeParameters = from argument in typeParameterArgumentList.Elements(SRC.Argument) where argument.Elements(SRC.Name).Any() select ParseTypeUseElement(argument.Element(SRC.Name), context); // if this is a generic type use and there is a prefix (A::B::C) then the last name element will actually be the first child of lastNameElement if(prefix != null) { lastNameElement = lastNameElement.Element(SRC.Name); } } // construct the type use var typeUse = new TypeUse() { Name = (lastNameElement != null ? lastNameElement.Value : string.Empty), ParentScope = context.CurrentScope, Location = context.CreateLocation(lastNameElement != null ? lastNameElement : typeUseElement), Prefix = prefix, ProgrammingLanguage = this.ParserLanguage, }; typeUse.AddTypeParameters(typeParameters); typeUse.AddAliases(context.Aliases); return typeUse; }