/// <summary>
/// Sets the Theme, SecondaryArguments and UnknownArguments properties of the given MethodDeclarationNode.
/// </summary>
/// <param name="node">The node to set the properties for.</param>
private void SetPrepositionThemeAndArguments(MethodDeclarationNode node)
{
List<VariableDeclarationNode> unusedArgs = new List<VariableDeclarationNode>();
//populate UnknownArgs
if (node.ParsedName.Size() > 0 && BooleanArgumentVerbs.Contains(node.ParsedName[0].Text))
{
node.AddUnknownArguments(node.FormalParameters);
}
else
{
//only add non-boolean arguments
foreach (VariableDeclarationNode arg in node.FormalParameters)
{
if (arg.Type.Name.ToLower().Contains("bool"))
{
unusedArgs.Add(arg);
}
else
{
node.AddUnknownArgument(arg);
}
}
}
int prepIndex = FindFirstPreposition(node.ParsedName, 0);
PhraseNode nameTheme = GetNounPhrase(node.ParsedName);
bool checkDO = false; //check Direct Object in name for overlap
bool checkIO = false; //check Indirect Object in name for overlap
//Assign args
if (prepIndex > -1)
{
//There's a preposition in the name
WordNode prep = node.ParsedName[prepIndex];
PhraseNode indirectObject = GetNounPhrase(node.ParsedName, prepIndex + 1);
//set IO or P->NM
if (!indirectObject.IsEmpty()) //IO in name
{
node.AddSecondaryArgument(indirectObject, prep);
checkIO = true;
}
else if (node.UnknownArguments != null && node.UnknownArguments.Count() > 0) //or IO = f
{
node.AddSecondaryArgument(node.UnknownArguments[0], prep);
}
else
{
//The preposition doesn't seem to have an object, so change it to a NounModifier
prep.Tag = PartOfSpeechTag.NounModifier;
nameTheme = GetNounPhrase(node.ParsedName); //reset name theme after changing prep POS tag
}
//set Theme
if (!nameTheme.IsEmpty())
{
//theme is in the name
nameTheme.SetLocation(Location.Name);
node.Theme = nameTheme;
checkDO = true;
}
else //use class as theme
{
node.Theme = node.DeclaringClass;
}
}
else
{
//no prep in name, so set Theme only
if (!nameTheme.IsEmpty())
{
//theme is in the name
nameTheme.SetLocation(Location.Name);
node.Theme = nameTheme;
checkDO = true;
}
else
{
//theme is first UnknownArg, or class name
//also, potentially leaves class on list of unknown args, which is intentional
if (node.DeclaringClass != null)
{
node.AddUnknownArgument(node.DeclaringClass);
}
if (node.UnknownArguments != null && node.UnknownArguments.Count > 0)
{
node.Theme = node.UnknownArguments[0];
node.UnknownArguments.RemoveAt(0);
}
}
}
//find equivalences
if ((checkDO || checkIO) && node.UnknownArguments != null && node.UnknownArguments.Count > 0)
{
CheckOverlap(node, checkDO, checkIO);
}
//do cleanup
node.AddUnknownArguments(unusedArgs);
if(node.ReturnType != null && node.ReturnType.Name.ToLower() != "void") {
//TODO: should this be done for primitive return types? SetDefaultUnknownArguments() excludes them
node.AddUnknownArgument(node.ReturnType);
}
// Note: adding class as unknown arg indep of checkIO
// if checkIO = true, and not checkDO, then DO will be class
// if check IO = true and checkDO, then this will be executed
// if no prep & DO not in name, class will already be on unused args
// list for finding theme.
if (checkDO && node.DeclaringClass != null)
{
node.AddUnknownArgument(node.DeclaringClass);
}
}