Beispiel #1
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 #2
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 #3
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);
            }
        }
        //TODO: implement support for using blocks, once SrcML has been fixed to parse them correctly
        ///// <summary>
        ///// Gets all of the variable declarations from a container
        ///// </summary>
        ///// <param name="container">the container</param>
        ///// <param name="fileUnit">the containing file unit</param>
        ///// <returns>An enumerable of variable declarations</returns>
        //public override IEnumerable<VariableDeclaration> GetVariableDeclarationsFromContainer(XElement container, XElement fileUnit, Scope parentScope) {
        //    if(null == container) return Enumerable.Empty<VariableDeclaration>();

        // if(container.Name != SRC.Using) { return
        // base.GetVariableDeclarationsFromContainer(container, fileUnit, parentScope); } //parse
        // using typeUseElement

        //}

        #region Private methods

        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 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);
        }
Beispiel #6
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);
        }
        /// <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 #8
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>
        /// Parses the given typeUseElement and returns a TypeUse object. This handles the "var"
        /// keyword for C# if used
        /// </summary>
        /// <param name="typeUseElement">The XML type use element</param>
        /// <param name="context">The parser context</param>
        /// <returns>A new TypeUse object</returns>
        public override ITypeUse ParseTypeUseElement(XElement typeUseElement, ParserContext context)
        {
            if (typeUseElement == null)
            {
                throw new ArgumentNullException("typeUseElement");
            }

            XElement typeElement;
            XElement typeNameElement;

            // validate the type use typeUseElement (must be a SRC.Name or SRC.Type)
            if (typeUseElement.Name == SRC.Type)
            {
                typeElement     = typeUseElement;
                typeNameElement = typeUseElement.Elements(SRC.Name).LastOrDefault();
            }
            else if (typeUseElement.Name == SRC.Name)
            {
                typeElement     = typeUseElement.Ancestors(SRC.Type).FirstOrDefault();
                typeNameElement = typeUseElement;
            }
            else
            {
                throw new ArgumentException("typeUseElement should be of type type or name", "typeUseElement");
            }

            if (typeNameElement.Value == "var")
            {
                var initElement       = typeElement.ElementsAfterSelf(SRC.Init).FirstOrDefault();
                var expressionElement = (null == initElement ? null : initElement.Element(SRC.Expression));
                var callElement       = (null == expressionElement ? null : expressionElement.Element(SRC.Call));

                IResolvesToType initializer = (null == callElement ? null : ParseCallElement(callElement, context));
                var             typeUse     = new CSharpVarTypeUse()
                {
                    Name                = typeNameElement.Value,
                    Initializer         = initializer,
                    ParentScope         = context.CurrentScope,
                    Location            = context.CreateLocation(typeNameElement),
                    ProgrammingLanguage = this.ParserLanguage,
                };
                return(typeUse);
            }
            else
            {
                return(base.ParseTypeUseElement(typeUseElement, context));
            }
        }
Beispiel #10
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="PropertyDefinition"/> object for <paramref name="declElement"/>.
        /// </summary>
        /// <param name="declElement">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="declElement"/>.</returns>
        protected virtual PropertyDefinition ParsePropertyDeclarationElement(XElement declElement, ParserContext context)
        {
            if (declElement == null)
            {
                throw new ArgumentNullException("declElement");
            }
            if (declElement.Name != SRC.Declaration)
            {
                throw new ArgumentException("Must be a SRC.Declaration element", "declElement");
            }
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            var propertyDef = new PropertyDefinition {
                ProgrammingLanguage = ParserLanguage
            };

            propertyDef.AddLocation(context.CreateLocation(declElement));

            foreach (var child in declElement.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>
        /// 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 virtual UsingBlockStatement ParseUsingBlockElement(XElement usingElement, ParserContext context)
        {
            if (usingElement == null)
            {
                throw new ArgumentNullException("usingElement");
            }
            if (usingElement.Name != SRC.Using)
            {
                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);
        }
Beispiel #13
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 #14
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);
                }
            }
        }
        /// <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);
        }
Beispiel #16
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);
                }
            }
        }
        /// <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 #18
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 variable declaration objects from the given declaration element 
        /// </summary>
        /// <param name="declarationElement">The variable declaration to parse. Must belong to <see cref="VariableDeclarationElementNames"/></param>
        /// <param name="context">The parser context</param>
        /// <returns>One variable declaration object for each declaration in <paramref name="declarationElement"/></returns>
        public virtual IEnumerable<VariableDeclaration> ParseDeclarationElement(XElement declarationElement, ParserContext context) {
            if(declarationElement == null) throw new ArgumentNullException("declaration");
            if(!VariableDeclarationElementNames.Contains(declarationElement.Name)) throw new ArgumentException("XElement.Name must be in VariableDeclarationElementNames");

            XElement declElement;
            if(declarationElement.Name == SRC.Declaration || declarationElement.Name == SRC.FunctionDeclaration) {
                declElement = declarationElement;
            } else {
                declElement = declarationElement.Element(SRC.Declaration);
            }

            var typeElement = declElement.Element(SRC.Type);

            var declarationType = ParseTypeUseElement(typeElement, context);

            foreach(var nameElement in declElement.Elements(SRC.Name)) {
                var variableDeclaration = new VariableDeclaration() {
                    VariableType = declarationType,
                    Name = nameElement.Value,
                    Location = context.CreateLocation(nameElement),
                    Scope = context.CurrentScope,
                };
                yield return variableDeclaration;
            }
        }
        /// <summary>
        /// Creates a method call object
        /// </summary>
        /// <param name="callElement">The XML element to parse</param>
        /// <param name="context">The parser context</param>
        /// <returns>A method call for <paramref name="callElement"/></returns>
        public virtual MethodCall ParseCallElement(XElement callElement, ParserContext context) {
            string name = String.Empty;
            bool isConstructor = false;
            bool isDestructor = false;
            IEnumerable<XElement> callingObjectNames = Enumerable.Empty<XElement>();

            var nameElement = callElement.Element(SRC.Name);
            if(null != nameElement) {
                name = NameHelper.GetLastName(nameElement);
                callingObjectNames = NameHelper.GetNameElementsExceptLast(nameElement);
            }

            var precedingElements = callElement.ElementsBeforeSelf();

            foreach(var pe in precedingElements) {
                if(pe.Name == OP.Operator && pe.Value == "new") {
                    isConstructor = true;
                } else if(pe.Name == OP.Operator && pe.Value == "~") {
                    isDestructor = true;
                }
            }

            var methodCall = new MethodCall() {
                Name = name,
                IsConstructor = isConstructor,
                IsDestructor = isDestructor,
                ParentScope = context.CurrentScope,
                Location = context.CreateLocation(callElement),
            };

            var arguments = from argument in callElement.Element(SRC.ArgumentList).Elements(SRC.Argument)
                            select CreateResolvableUse(argument, context);
            methodCall.Arguments = new Collection<IResolvesToType>(arguments.ToList<IResolvesToType>());

            IResolvesToType current = methodCall;
            // This foreach block gets all of the name elements included in the actual <call> element
            // this is done primarily in C# and Java where they can reliably be included there
            foreach(var callingObjectName in callingObjectNames.Reverse()) {
                var callingObject = this.CreateVariableUse(callingObjectName, context);
                current.CallingObject = callingObject;
                current = callingObject;
            }

            // after getting those, we look at the name elements that appear *before* a call
            // we keep taking name elements as long as they are preceded by "." or "->"
            // we want to accept get 'a', 'b', and 'c' from "a.b->c" only 'b' and 'c' from
            // "a + b->c"
            var elementsBeforeCall = callElement.ElementsBeforeSelf().ToArray();
            int i = elementsBeforeCall.Length - 1;

            while(i > 0 && elementsBeforeCall[i].Name == OP.Operator &&
                  (elementsBeforeCall[i].Value == "." || elementsBeforeCall[i].Value == "->")) {
                i--;
                if(i >= 0 && elementsBeforeCall[i].Name == SRC.Name) {
                    var callingObject = CreateVariableUse(elementsBeforeCall[i], context);
                    current.CallingObject = callingObject;
                    current = callingObject;
                }
                i--;
            }
            if(methodCall.CallingObject == null) {
                methodCall.AddAliases(context.Aliases);
            }
            // TODO can we add aliases to calling object?
            return methodCall;
        }
        /// <summary>
        /// Generates a parameter declaration for the given declaration
        /// </summary>
        /// <param name="declElement">The declaration XElement from within the parameter element. Must be a <see cref="ABB.SrcML.SRC.Declaration"/> or <see cref="ABB.SrcML.SRC.FunctionDeclaration"/></param>
        /// <param name="context">the parser context</param>
        /// <returns>A parameter declaration object</returns>
        public virtual ParameterDeclaration ParseMethodParameterElement(XElement declElement, ParserContext context) {
            if(declElement == null) throw new ArgumentNullException("declElement");
            if(declElement.Name != SRC.Declaration && declElement.Name != SRC.FunctionDeclaration) throw new ArgumentException("must be of element type SRC.Declaration or SRC.FunctionDeclaration", "declElement");

            var typeElement = declElement.Element(SRC.Type);
            var nameElement = declElement.Element(SRC.Name);
            var name = (nameElement == null ? String.Empty : nameElement.Value);

            var parameterDeclaration = new ParameterDeclaration {
                VariableType = ParseTypeUseElement(typeElement, context),
                Name = name,
                Scope = context.CurrentScope
            };
            parameterDeclaration.Locations.Add(context.CreateLocation(declElement));
            return parameterDeclaration;
        }
        /// <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 #23
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;
            }

        }
Beispiel #24
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>
        /// 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 #26
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>
        /// 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;
        }
        /// <summary>
        /// Creates an <see cref="Alias"/> object from a using import (such as using in C++ and C# and import in Java).
        /// </summary>
        /// <param name="aliasStatement">The statement to parse. Should be of type <see cref="AliasElementName"/></param>
        /// <param name="context">The context to place the resulting alias in</param>
        /// <returns>a new alias object that represents this alias statement</returns>
        public Alias ParseAliasElement(XElement aliasStatement, ParserContext context) {
            if(null == aliasStatement) throw new ArgumentNullException("aliasStatement");
            if(aliasStatement.Name != AliasElementName) throw new ArgumentException(String.Format("must be a {0} statement", AliasElementName), "usingStatement");

            var alias = new Alias() {
                Location = context.CreateLocation(aliasStatement, true),
                ProgrammingLanguage = ParserLanguage,
            };

            IEnumerable<XElement> namespaceNames = GetNamesFromAlias(aliasStatement);

            if(!AliasIsNamespaceImport(aliasStatement)) {
                var lastNameElement = namespaceNames.LastOrDefault();
                namespaceNames = from name in namespaceNames
                                 where name.IsBefore(lastNameElement)
                                 select name;

                alias.ImportedNamedScope = new NamedScopeUse() {
                    Name = lastNameElement.Value,
                    Location = context.CreateLocation(lastNameElement),
                    ProgrammingLanguage = ParserLanguage,
                };
            }

            NamespaceUse current = null;
            foreach(var namespaceName in namespaceNames) {
                var use = new NamespaceUse() {
                    Name = namespaceName.Value,
                    Location = context.CreateLocation(namespaceName),
                    ProgrammingLanguage = ParserLanguage,
                };

                if(alias.ImportedNamespace == null) {
                    alias.ImportedNamespace = use;
                    current = use;
                } else {
                    current.ChildScopeUse = use;
                    current = use;
                }
            }

            return alias;
        }
        /// <summary>
        /// This is the main function that parses srcML nodes. It selects the appropriate parse element to call and then adds declarations, method calls, and children to it
        /// </summary>
        /// <param name="element">The element to parse</param>
        /// <param name="context">The parser context</param>
        /// <returns>The scope representing <paramref name="element"/></returns>
        public virtual Scope ParseElement_Concurrent(XElement element, ParserContext context) {
            if(element.Name == SRC.Unit) {
                ParseUnitElement(element, context);
            } else if(TypeElementNames.Contains(element.Name)) {
                ParseTypeElement(element, context);
            } else if(NamespaceElementNames.Contains(element.Name)) {
                ParseNamespaceElement(element, context);
            } else if(MethodElementNames.Contains(element.Name)) {
                ParseMethodElement(element, context);
            } else {
                ParseContainerElement(element, context);
            }

            IEnumerable<XElement> Elements = GetDeclarationsFromElement(element);
            foreach(var declarationElement in Elements) {
                foreach(var declaration in ParseDeclarationElement(declarationElement, context)) {
                    context.CurrentScope.AddDeclaredVariable(declaration);
                }
            }

            IEnumerable<XElement> methodCalls = GetMethodCallsFromElement(element);
            foreach(var methodCallElement in methodCalls) {
                var methodCall = ParseCallElement(methodCallElement, context);
                context.CurrentScope.AddMethodCall(methodCall);
            }

            IEnumerable<XElement> children = GetChildContainers(element);
            ConcurrentQueue<Exception> exceptions = new ConcurrentQueue<Exception>();

            ConcurrentQueue<Scope> cq = new ConcurrentQueue<Scope>();
            Parallel.ForEach(children, currentChild => {
                try {
                    var subContext = new ParserContext() {
                        Aliases = context.Aliases,
                        FileUnit = context.FileUnit,
                    };

                    Scope childScope = ParseElement(currentChild, subContext);
                    cq.Enqueue(childScope);
                } catch(Exception e) { exceptions.Enqueue(e); }
            });

            if(exceptions.Count > 0) throw new Exception();

            while(!cq.IsEmpty) {
                Scope childScope = new Scope();
                cq.TryDequeue(out childScope);
                context.CurrentScope.AddChildScope(childScope);
            }

            var currentScope = context.Pop();
            currentScope.AddSourceLocation(context.CreateLocation(element, ContainerIsReference(element)));
            currentScope.ProgrammingLanguage = ParserLanguage;

            return currentScope;
        }
        /// <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>
        /// 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 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 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 #34
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 #35
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;
        }
Beispiel #36
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>
        /// 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;
        }
Beispiel #38
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;
        }
Beispiel #39
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;
        }
        /// <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 #41
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;
        }
        /// <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>
        /// This is the main function that parses srcML nodes. It selects the appropriate parse element to call and then adds declarations, method calls, and children to it
        /// </summary>
        /// <param name="element">The element to parse</param>
        /// <param name="context">The parser context</param>
        /// <returns>The scope representing <paramref name="element"/></returns>
        public virtual Scope ParseElement(XElement element, ParserContext context) {
            if(element.Name == SRC.Unit) {
                ParseUnitElement(element, context);
            } else if(TypeElementNames.Contains(element.Name)) {
                ParseTypeElement(element, context);
            } else if(NamespaceElementNames.Contains(element.Name)) {
                ParseNamespaceElement(element, context);
            } else if(MethodElementNames.Contains(element.Name)) {
                ParseMethodElement(element, context);
            } else {
                ParseContainerElement(element, context);
            }

            IEnumerable<XElement> Elements = GetDeclarationsFromElement(element);
            foreach(var declarationElement in Elements) {
                foreach(var declaration in ParseDeclarationElement(declarationElement, context)) {
                    context.CurrentScope.AddDeclaredVariable(declaration);
                }
            }

            IEnumerable<XElement> methodCalls = GetMethodCallsFromElement(element);
            foreach(var methodCallElement in methodCalls) {
                var methodCall = ParseCallElement(methodCallElement, context);
                context.CurrentScope.AddMethodCall(methodCall);
            }

            IEnumerable<XElement> children = GetChildContainers(element);
            foreach(var childElement in children) {
                //var subContext = new ParserContext() {
                //    Aliases = context.Aliases,
                //    FileUnit = context.FileUnit,
                //};

                var childScope = ParseElement(childElement, context);
                //Scope childScope = ParseElement(childElement, subContext);
                context.CurrentScope.AddChildScope(childScope);
            }

            var currentScope = context.Pop();
            currentScope.AddSourceLocation(context.CreateLocation(element, ContainerIsReference(element)));
            currentScope.ProgrammingLanguage = ParserLanguage;

            return currentScope;
        }