private IType CreateConcreteCallableType(Node sourceNode, AnonymousCallableType anonymousType)
{
Module module = TypeSystemServices.GetCompilerGeneratedTypesModule();
TypeMember enclosing = (sourceNode.GetAncestor(NodeType.ClassDefinition) ?? sourceNode.GetAncestor(NodeType.InterfaceDefinition) ?? sourceNode.GetAncestor(NodeType.EnumDefinition) ?? sourceNode.GetAncestor(NodeType.Module)) as TypeMember;
string prefix = "";
string postfix = "";
if(enclosing != null)
{
prefix += enclosing.Name;
enclosing = (sourceNode.GetAncestor(NodeType.Method)
?? sourceNode.GetAncestor(NodeType.Property)
?? sourceNode.GetAncestor(NodeType.Event)
?? sourceNode.GetAncestor(NodeType.Field)) as TypeMember;
if(enclosing != null)
{
prefix += "_" + enclosing.Name;
}
prefix += "$";
}
else if (!sourceNode.LexicalInfo.Equals(LexicalInfo.Empty))
{
prefix += System.IO.Path.GetFileNameWithoutExtension(sourceNode.LexicalInfo.FileName) + "$";
}
if(!sourceNode.LexicalInfo.Equals(LexicalInfo.Empty))
{
postfix = "$" + sourceNode.LexicalInfo.Line + "_" + sourceNode.LexicalInfo.Column + postfix;
}
string name = "__" + prefix + "callable" + module.Members.Count + postfix + "__";
ClassDefinition cd = TypeSystemServices.CreateCallableDefinition(name);
cd.Modifiers |= TypeMemberModifiers.Public;
cd.LexicalInfo = sourceNode.LexicalInfo;
cd.Members.Add(CreateInvokeMethod(anonymousType));
Method beginInvoke = CreateBeginInvokeMethod(anonymousType);
cd.Members.Add(beginInvoke);
cd.Members.Add(CreateEndInvokeMethod(anonymousType));
module.Members.Add(cd);
CreateCallableTypeBeginInvokeExtensions(anonymousType, beginInvoke);
return (IType)cd.Entity;
}