Encapsulates the program context relevant to a method declaration.
상속: IdContext
예제 #1
0
        /// <summary>
        /// Construct the method summarizer
        /// </summary>
        /// <param name="md"></param>
        public SwumSummary(MethodDefinition md)
        {
            this.Method = md;
            var classBelong = md.GetAncestors<TypeDefinition>().FirstOrDefault();

            //class name
            if (classBelong != null) {
                ClassName = classBelong.Name;
            }
            else {
                ClassName = "";
            }

            //return type
            string returnType = "void";
            if (md.ReturnType != null) {
                returnType = md.ReturnType.ToString();
            }

            //Check if md returns primitive
            bool IsPrimitive = IsPrimitiveType(md.ReturnType);

            HashSet<FormalParameterRecord> paras = new HashSet<FormalParameterRecord>();
            foreach (var para in md.Parameters) {
                var vType = para.VariableType;
                var tempPara = new FormalParameterRecord(vType.ToString(), BuiltInTypeFactory.IsBuiltIn(vType), para.Name);
                paras.Add(tempPara);
            }
            MethodContext mc = new MethodContext(returnType, IsPrimitive, ClassName, paras, false, md.IsConstructor, md.IsDestructor);
            this._mDeclarationNode = new MethodDeclarationNode(md.Name, mc);
            this._builder = new UnigramSwumBuilder();
            this.IsSummarized = false;
        }
예제 #2
0
    public static SUnit TranslateMethodCall(Statement statement)
    {
        var expressions = statement.GetExpressions();

        // Give an empty SUnit if statement has no expressions.
        if (expressions.Count() == 0)
        {
            return new SUnit(SUnitType.SingleMethodCall, "", "", "", new List<string>(), "void");
        }

        // Build a minimal method context and declaration node required by SWUM.
        var exp = expressions.First();
        string type = exp.ResolveType().ToString();
        MethodContext mc = new MethodContext(type);
        MethodDeclarationNode mdn = new MethodDeclarationNode(exp.ToString(), mc);

        // Apply the SWUM to our statement
        var swumRule = SetupBaseVerbRule();
        swumRule.InClass(mdn);
        swumRule.ConstructSwum(mdn);

        // Build and return SUnit from the SWUM
        SUnit sunit = new SUnit();
        sunit.action = GetAction(mdn);
        sunit.theme = GetTheme(mdn);
        sunit.args = GetArgs(mdn);

        return sunit;
    }
예제 #3
0
        /// <summary>
        /// Builds a MethodContext object based on the given method element.
        /// </summary>
        /// <param name="methodTag">An XElement representing the method to build the context for. This can be either a function, constructor or destructor element.</param>
        /// <returns>A MethodContext object based on the given method.</returns>
        /// <exception cref="System.ArgumentException">The passed XElement does not represent a function, constructor, or destructor element.</exception>
        /// <exception cref="System.ArgumentNullException">methodTag is null.</exception>
        public static MethodContext BuildMethodContext(XElement methodTag)
        {
            if (methodTag == null)
            {
                throw new ArgumentNullException("methodTag");
            }
            else if (!(methodTag.Name == SRC.Function || methodTag.Name == SRC.Constructor || methodTag.Name == SRC.Destructor))
            {
                throw new ArgumentException(string.Format("The passed XElement must represent a <function>, <constructor> or <destructor> element. Received a <{0}> element.", methodTag.Name.ToString()), "methodTag");
            }

            MethodContext mc = new MethodContext();

            //set return type
            if (methodTag.Name == SRC.Function)
            {
                bool isPrimitive;
                mc.IdType = ConstructTypeName(methodTag.Element(SRC.Type), out isPrimitive);
                mc.IdTypeIsPrimitive = isPrimitive;
            }

            //record if constructor
            if (methodTag.Name == SRC.Constructor) { mc.IsConstructor = true; }
            //record if destructor
            if (methodTag.Name == SRC.Destructor) { mc.IsDestructor = true; }

            //record if static
            //look for the static keyword (at the function definition)
            //This is not entirely sufficient because it's possible for the static keyword to be present at only the function declaration and not the definition
            //Also, some other word may be #defined to static and used instead
            var typeElement = methodTag.Element(SRC.Type);
            if (typeElement != null)
            {
                foreach (var typeNameTag in typeElement.Elements(SRC.Name))
                {
                    if (typeNameTag.Value.Equals("static", StringComparison.InvariantCultureIgnoreCase))
                    {
                        mc.IsStatic = true;
                        break;
                    }
                }
            }

            //formal parameters
            mc.FormalParameters = new List<FormalParameterRecord>();
            XElement paramList = methodTag.Element(SRC.ParameterList);
            if (paramList != null)
            {
                foreach (var param in paramList.Elements(SRC.Parameter))
                {
                    //a param (usually) looks like: <param><decl><type><name>...</name></type> <name>...</name></decl></param>
                    string type = string.Empty;
                    string name = string.Empty;
                    bool isPrimitive = false;
                    var declElement = param.Element(SRC.Declaration);
                    if (declElement != null && declElement.Element(SRC.Type) != null)
                    {
                        type = ConstructTypeName(declElement.Element(SRC.Type), out isPrimitive);
                    }
                    if (declElement != null && declElement.Element(SRC.Name) != null)
                    {
                        name = param.Element(SRC.Declaration).Element(SRC.Name).Value;
                    }
                    //add parameter, if it's valid
                    if(!(string.IsNullOrEmpty(type) && string.IsNullOrEmpty(name)) && type != "void")
                    {
                        mc.FormalParameters.Add(new FormalParameterRecord(type, isPrimitive, name));
                    }
                }
            }

            //Determine declaring class
            XElement classNameTag = SrcMLElement.GetClassNameForMethod(methodTag);
            if (classNameTag != null)
            {
                //class name listed with method name: <ClassName>::<MethodName>
                mc.DeclaringClass = classNameTag.Value;
            }
            else if (classNameTag == null && mc.IsConstructor)
            {
                //class name not listed, but the method is a constructor
                //I'm not sure if this is actually possible
                mc.DeclaringClass = SrcMLElement.GetNameForMethod(methodTag).Value;
            }
            else if (classNameTag == null)
            {
                //no class name listed, but this might be an inline method in the class declaration
                //search for the enclosing <class> or <struct> tag
                XElement classElement = FindEnclosingClassElement(methodTag);
                if (classElement != null && classElement.Element(SRC.Name) != null)
                {
                    mc.DeclaringClass = GetNameFromNameElement(classElement.Element(SRC.Name));
                }
            }

            return mc;
        }
        /// <summary>
        /// Checks if each SwumRule (13) returns (InClass = true) for the given method name.  returns a dictionary of the SwumRule and boolean.  
        /// Note that to build the swum you still have to run InClass for that method name.
        /// </summary>
        /// <param name="name">The name of the method</param>
        /// <param name="mc">The MethodContext object generated from the top-level method.  This is required to generate a swum for any method</param>
        /// <returns>Dictionary of SwumRules and boolean thats true if InClass = true</returns>
        Dictionary<SwumRule, bool> InClassChecker(String name, MethodContext mc)
        {
            MethodDeclarationNode mdn = new MethodDeclarationNode(name, mc);

            Dictionary<SwumRule, bool> rules = new Dictionary<SwumRule, bool>
            {
                {new BaseVerbRule(posData, tagger, splitter), false},
                {new CheckerRule (posData, tagger, splitter), false},
                {new ConstructorRule(posData, tagger, splitter), false},
                {new DefaultBaseVerbRule(posData, tagger, splitter), false},
                {new DestructorRule(posData, tagger, splitter), false},
                {new EmptyNameRule(posData, tagger, splitter), false},
                {new EventHandlerRule(posData, tagger, splitter), false},
                {new FieldRule(posData, tagger, splitter), false},
                {new LeadingPrepositionRule(posData, tagger, splitter), false},
                {new NonBaseVerbRule(posData, tagger, splitter), false},
                {new NounPhraseRule(posData, tagger, splitter), false},
                {new ReactiveRule(posData, tagger, splitter), false},
                {new SpecialCaseRule(posData, tagger, splitter), false}
                //{new SwumRule(posData, tagger, splitter),""},     these are abstract
                //{new UnigramMethodRule(posData, tagger, splitter),""},
                //{new UnigramRule(posData, tagger, splitter),""}
            };

            var listing = rules.Keys.ToList();

            foreach (SwumRule ent in listing)
            {
                // Console.WriteLine(ent.GetType() + "   InClass = " + ent.InClass(mdn));
                if (ent.InClass(mdn))
                {
                    rules[ent] = true;
                }
            }

            return rules;
        }
        /// <summary>
        /// Returns the verb given a method name using all of the SwumRules.
        /// This does not make sure all of the rules returned the same verb, it returns the first one found.
        /// </summary>
        /// <param name="name">The name of the method</param>
        /// <param name="mc">The MethodContext object generated from the top-level method.  This is required to generate a swum for any method</param>
        String GetMethodVerb(String name, MethodContext mc)
        {
            Dictionary<SwumRule, bool> inClasses = InClassChecker(name, mc);
            bool found = false;
            Dictionary<SwumRule, MethodDeclarationNode> validSwums = BuildValidSwums(name, mc);

            foreach (KeyValuePair<SwumRule, MethodDeclarationNode> entry in validSwums)
            {
                if (entry.Value.Action.ToPlainString().Length > 0)
                {
                    found = true;
                    return entry.Value.Action.ToPlainString();
                }
            }

            if (!found)
            {
                return "!!NONE FOUND!!"; //TODO
            }
            else
            {  //should never get to this code but its needed to make the compiler happy
                return null;
            }
        }
        /// <summary>
        /// Given a method name, check if the generated swums are all the same.
        /// </summary>
        /// <param name="name">The name of the method</param>
        /// <param name="mc">The MethodContext object generated from the top-level method.  This is required to generate a swum for any method</param>
        /// <returns>True - if they are all the same
        /// False - if any are different</returns>
        bool CompareSwums(string name, MethodContext mc)
        {
            Dictionary<SwumRule, bool> inClasses = InClassChecker(name, mc);
            List<MethodDeclarationNode> mdns = BuildValidSwums(name, mc).Values.ToList<MethodDeclarationNode>();
            List<string> swums = new List<string>();

            foreach (MethodDeclarationNode m in mdns)
            {
                swums.Add(m.ToString());
            }

            // Compare

            //returns true if something different is found
            if (swums.Any(o => o != swums[0]))
            {
                return false;
            }
            else return true;
        }
        Dictionary<SwumRule, MethodDeclarationNode> BuildValidSwums(String name, MethodContext mc)
        {
            Dictionary<SwumRule, bool> inClasses = InClassChecker(name, mc);
            MethodDeclarationNode mdn = null;
            Dictionary<SwumRule, MethodDeclarationNode> validSwums = new Dictionary<SwumRule, MethodDeclarationNode>();

            foreach (KeyValuePair<SwumRule, bool> entry in inClasses)
            {
                if (entry.Value)
                {
                    mdn = new MethodDeclarationNode(name, mc);
                    entry.Key.InClass(mdn);
                    entry.Key.ConstructSwum(mdn);

                    validSwums.Add(entry.Key, mdn);

                }
            }

            return validSwums;
        }
예제 #8
0
    private static SUnit TranslateAssignment(Statement statement)
    {
        // action = "Assign"
        // define left-hand-side (lhs)
        // theme = right hand side

        var fieldRule = SetupFieldRule();

        //        var equalsSign = statement.GetDescendants<OperatorUse>()
        //                                .Where(o => o.Text.Equals("=")).First();

        //        var lhs = equalsSign.GetSiblingsBeforeSelf<VariableUse>().First();

        var assignExpression = (VariableDeclaration) statement.GetExpressions().First();
        var lhs = assignExpression.Name;

        var lhsFieldContext = new FieldContext(assignExpression.VariableType.ToString(), false, "");
        var lhsDecNode = new FieldDeclarationNode(lhs.ToString(), lhsFieldContext);
        fieldRule.InClass(lhsDecNode);
        fieldRule.ConstructSwum(lhsDecNode);

        var rhsString = "";
        var rhsAction = "";
        var rhsTheme = "";
        Expression rhs = new Expression();
        if (assignExpression.Initializer != null)
        {
            rhs = assignExpression.Initializer;
        }

        if (rhs is VariableUse)
        {
            var rhsFieldContext = new FieldContext(rhs.ResolveType().First().ToString(), false, "");
            var rhsDecNode = new FieldDeclarationNode(rhs.ToString(), lhsFieldContext);
            fieldRule.InClass(rhsDecNode);
            fieldRule.ConstructSwum(rhsDecNode);
            rhsAction = "Assign";
            rhsString = rhsDecNode.ToPlainString();

        }
        else if (rhs is MethodCall)
        {

            string type = rhs.ResolveType().ToString();

            MethodContext mc = new MethodContext(type);
            MethodDeclarationNode mdn = new MethodDeclarationNode(rhs.ToString(), mc);

            var swumRule = SetupBaseVerbRule();
            swumRule.InClass(mdn);
            swumRule.ConstructSwum(mdn);

            rhsAction = mdn.Action.ToPlainString();
            rhsTheme = mdn.Action.ToPlainString();
            rhsString = mdn.ToPlainString();
        }
        else
        {
            rhsString = rhs.ToString();
        }

        var sunit = new SUnit();
        sunit.type = SUnitType.Assignment;
        sunit.action = rhsString;
        //sunit.lhs = lhsDecNode.ToPlainString();
        sunit.lhs = lhs.ToString();
        sunit.theme = rhsString;

        return sunit;
    }
        /// <summary>
        /// Builds a MethodContext object based on the given method element.
        /// </summary>
        /// <param name="methodTag">An XElement representing the method to build the context for. This can be either a function, constructor or destructor element.</param>
        /// <returns>A MethodContext object based on the given method.</returns>
        /// <exception cref="System.ArgumentException">The passed XElement does not represent a function, constructor, or destructor element.</exception>
        /// <exception cref="System.ArgumentNullException">methodTag is null.</exception>
        public static MethodContext BuildMethodContext(XElement methodTag)
        {
            if (methodTag == null)
            {
                throw new ArgumentNullException("methodTag");
            }
            else if (!(methodTag.Name == SRC.Function || methodTag.Name == SRC.Constructor || methodTag.Name == SRC.Destructor))
            {
                throw new ArgumentException(string.Format("The passed XElement must represent a <function>, <constructor> or <destructor> element. Received a <{0}> element.", methodTag.Name.ToString()), "methodTag");
            }

            MethodContext mc = new MethodContext();

            //set return type
            if (methodTag.Name == SRC.Function)
            {
                bool isPrimitive;
                mc.IdType            = ConstructTypeName(methodTag.Element(SRC.Type), out isPrimitive);
                mc.IdTypeIsPrimitive = isPrimitive;
            }

            //record if constructor
            if (methodTag.Name == SRC.Constructor)
            {
                mc.IsConstructor = true;
            }
            //record if destructor
            if (methodTag.Name == SRC.Destructor)
            {
                mc.IsDestructor = true;
            }

            //record if static
            //look for the static keyword (at the function definition)
            //This is not entirely sufficient because it's possible for the static keyword to be present at only the function declaration and not the definition
            //Also, some other word may be #defined to static and used instead
            var typeElement = methodTag.Element(SRC.Type);

            if (typeElement != null)
            {
                foreach (var typeNameTag in typeElement.Elements(SRC.Name))
                {
                    if (typeNameTag.Value.Equals("static", StringComparison.InvariantCultureIgnoreCase))
                    {
                        mc.IsStatic = true;
                        break;
                    }
                }
            }

            //formal parameters
            mc.FormalParameters = new List <FormalParameterRecord>();
            XElement paramList = methodTag.Element(SRC.ParameterList);

            if (paramList != null)
            {
                foreach (var param in paramList.Elements(SRC.Parameter))
                {
                    //a param (usually) looks like: <param><decl><type><name>...</name></type> <name>...</name></decl></param>
                    string type        = string.Empty;
                    string name        = string.Empty;
                    bool   isPrimitive = false;
                    var    declElement = param.Element(SRC.Declaration);
                    if (declElement != null && declElement.Element(SRC.Type) != null)
                    {
                        type = ConstructTypeName(declElement.Element(SRC.Type), out isPrimitive);
                    }
                    if (declElement != null && declElement.Element(SRC.Name) != null)
                    {
                        name = param.Element(SRC.Declaration).Element(SRC.Name).Value;
                    }
                    //add parameter, if it's valid
                    if (!(string.IsNullOrEmpty(type) && string.IsNullOrEmpty(name)) && type != "void")
                    {
                        mc.FormalParameters.Add(new FormalParameterRecord(type, isPrimitive, name));
                    }
                }
            }

            //Determine declaring class
            XElement classNameTag = SrcMLElement.GetClassNameForMethod(methodTag);

            if (classNameTag != null)
            {
                //class name listed with method name: <ClassName>::<MethodName>
                mc.DeclaringClass = classNameTag.Value;
            }
            else if (classNameTag == null && mc.IsConstructor)
            {
                //class name not listed, but the method is a constructor
                //I'm not sure if this is actually possible
                mc.DeclaringClass = SrcMLElement.GetNameForMethod(methodTag).Value;
            }
            else if (classNameTag == null)
            {
                //no class name listed, but this might be an inline method in the class declaration
                //search for the enclosing <class> or <struct> tag
                XElement classElement = FindEnclosingClassElement(methodTag);
                if (classElement != null && classElement.Element(SRC.Name) != null)
                {
                    mc.DeclaringClass = GetNameFromNameElement(classElement.Element(SRC.Name));
                }
            }

            return(mc);
        }
예제 #10
0
        public void TestBuildMethodContext_InlineFunction() {
            string testSrcML = "<class>class <name>CBidMarkup</name><block>{<private type=\"default\"> <function><type><name>int</name></type> <name>run</name><parameter_list>(<param><decl><type><name>CGVDate</name> <type:modifier>&amp;</type:modifier></type> <name>CurrDate</name></decl></param>)</parameter_list> <block>{ <return>return <expr><op:operator>-</op:operator><lit:literal type=\"number\">1</lit:literal></expr>;</return>}</block></function> </private>}</block>;</class>";
            XElement xml = XElement.Parse(string.Format(srcMLFormat, testSrcML), LoadOptions.PreserveWhitespace);
            var formals = new FormalParameterRecord[] {new FormalParameterRecord("CGVDate&", false, "CurrDate")};

            MethodContext mc1 = new MethodContext("int", true, "CBidMarkup", formals, false, false, false);
            MethodContext mc2 = ContextBuilder.BuildMethodContext(xml.Descendants(SRC.Function).First());
            Assert.IsTrue(MethodContextsAreEqual(mc1, mc2));
        }
예제 #11
0
        public void TestBuildMethodContext_GlobalFunction() {
            string testSrcML = "<function><type><name>int</name></type> <name>GetZero</name><parameter_list>()</parameter_list> <block>{<return>return <expr><lit:literal type=\"number\">0</lit:literal></expr>;</return>}</block></function>";
            XElement xml = XElement.Parse(string.Format(srcMLFormat, testSrcML), LoadOptions.PreserveWhitespace);

            MethodContext mc1 = new MethodContext("int", true, "", new List<FormalParameterRecord>(), false, false, false);
            MethodContext mc2 = ContextBuilder.BuildMethodContext(xml.Descendants(SRC.Function).First());
            Assert.IsTrue(MethodContextsAreEqual(mc1, mc2));
        }
예제 #12
0
        public void TestBuildMethodContext_Destructor() {
            string testSrcML = "<destructor><name><name>CBidMarkup</name><op:operator>::</op:operator>~<name>CBidMarkup</name></name><parameter_list>()</parameter_list> <block>{ }</block></destructor>";
            XElement xml = XElement.Parse(string.Format(srcMLFormat, testSrcML), LoadOptions.PreserveWhitespace);

            MethodContext mc1 = new MethodContext("", false, "CBidMarkup", new List<FormalParameterRecord>(), false, false, true);
            MethodContext mc2 = ContextBuilder.BuildMethodContext(xml.Element(SRC.Destructor));
            Assert.IsTrue(MethodContextsAreEqual(mc1, mc2));
        }
예제 #13
0
        public void TestBuildMethodContext_Constructor() {
            string testSrcML = "<constructor><name><name>CBidMarkup</name><op:operator>::</op:operator><name>CBidMarkup</name></name><parameter_list>(<param><decl><type><name>SGVData</name> <type:modifier>*</type:modifier></type> <name>p</name></decl></param>, <param><decl><type><name>ASSchedule</name> <type:modifier>*</type:modifier></type> <name>p2</name></decl></param>)</parameter_list> <block>{ }</block></constructor>";
            XElement xml = XElement.Parse(string.Format(srcMLFormat, testSrcML), LoadOptions.PreserveWhitespace);
            var formals = new FormalParameterRecord[] {new FormalParameterRecord("SGVData*", false, "p"), new FormalParameterRecord("ASSchedule*", false, "p2")};

            MethodContext mc1 = new MethodContext("", false, "CBidMarkup", formals, false, true, false);
            MethodContext mc2 = ContextBuilder.BuildMethodContext(xml.Element(SRC.Constructor));
            Assert.IsTrue(MethodContextsAreEqual(mc1, mc2));
        }
예제 #14
0
        public void TestBuildMethodContext_StaticFunctionWithClassAndParams() {
            string testSrcML = "<function><type><name>static</name> <name>char</name></type> <name><name>CBidMarkup</name><op:operator>::</op:operator><name>run</name></name><parameter_list>(<param><decl><type><name>CGVDate</name> <type:modifier>&amp;</type:modifier></type> <name>CurrDate</name></decl></param>)</parameter_list> <block>{ <return>return <expr><lit:literal type=\"char\">'a'</lit:literal></expr>;</return> }</block></function>";
            XElement xml = XElement.Parse(string.Format(srcMLFormat, testSrcML), LoadOptions.PreserveWhitespace);
            var formals = new FormalParameterRecord[] {new FormalParameterRecord("CGVDate&", false, "CurrDate")};

            MethodContext mc1 = new MethodContext("char", true, "CBidMarkup", formals, true, false, false);
            MethodContext mc2 = ContextBuilder.BuildMethodContext(xml.Element(SRC.Function));
            Assert.IsTrue(MethodContextsAreEqual(mc1, mc2));
        }
예제 #15
0
        public void TestBuildMethodContext_FunctionWithClassAndParams() {
            string testSrcML = "<function><type><name>int</name></type> <name><name>CBidMarkup</name><op:operator>::</op:operator><name>modifyBid</name></name><parameter_list>(<param><decl><type><name>bool</name></type> <name>Recalc</name></decl></param>, <param><decl><type><name>char</name><type:modifier>*</type:modifier></type> <name>Foo</name></decl></param>)</parameter_list><block>{ <return>return <expr><lit:literal type=\"number\">0</lit:literal></expr>;</return> }</block></function>";
            XElement xml = XElement.Parse(string.Format(srcMLFormat, testSrcML), LoadOptions.PreserveWhitespace);
            var formals = new FormalParameterRecord[] {new FormalParameterRecord("bool", true, "Recalc"), new FormalParameterRecord("char*", true, "Foo")};

            MethodContext mc1 = new MethodContext("int", true, "CBidMarkup", formals, false, false, false);
            MethodContext mc2 = ContextBuilder.BuildMethodContext(xml.Element(SRC.Function));
            Assert.IsTrue(MethodContextsAreEqual(mc1, mc2));
        }
예제 #16
0
 private bool MethodContextsAreEqual(MethodContext mc1, MethodContext mc2) {
     if(mc1 == null && mc2 == null) {
         return true;
     }
     if((mc1 == null) ^ (mc2 == null)) {
         return false;
     }
     if(mc1.DeclaringClass != mc2.DeclaringClass
        || mc1.IsConstructor != mc2.IsConstructor
        || mc1.IsDestructor != mc2.IsDestructor
        || mc1.IsStatic != mc2.IsStatic
        || mc1.IdType != mc2.IdType
        || mc1.IdTypeIsPrimitive != mc2.IdTypeIsPrimitive
        || mc1.FormalParameters.Count != mc2.FormalParameters.Count) {
         return false;
     }
     for(int i = 0; i < mc1.FormalParameters.Count; i++) {
         if(!mc1.FormalParameters[i].Equals(mc2.FormalParameters[i])) {
             return false;
         }
     }
     return true;
 }