Beispiel #1
0
        /// <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);
            }
        }
Beispiel #3
0
        /// <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);
        }
Beispiel #5
0
        /// <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);
                }
            }
        }
Beispiel #6
0
        /// <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);
                }
            }
        }
Beispiel #7
0
        /// <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;
        }
Beispiel #8
0
        /// <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;
        }
Beispiel #9
0
        /// <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;
 }
Beispiel #11
0
        /// <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;
        }
Beispiel #12
0
 /// <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;
        }
Beispiel #14
0
        /// <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);
        }
Beispiel #17
0
        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);
        }
Beispiel #21
0
        /// <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;
        }
Beispiel #23
0
        /// <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;
        }
Beispiel #25
0
        /// <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(); }
Beispiel #30
0
        /// <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;
        }
Beispiel #32
0
        /// <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;
        }