/// <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; }
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; }
/// <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; }
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); }
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>&</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)); }
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)); }
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)); }
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)); }
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>&</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)); }
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)); }
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; }