📄 symbol.cs
字号:
TypeEntry tDefiningClass, // class we're defined in
TypeEntry tReturnType // return type
)
: this(stName, nodeClass, tDefiningClass, tReturnType, false)
{
}
// User-declared
public MethodExpEntry(
string stName, // name of the method
AST.MethodDecl nodeClass, // node of ast defining us (can be null)
TypeEntry tDefiningClass, // class we're defined in
TypeEntry tReturnType, // return type
bool fIsSpecialName
)
{
Debug.Assert(tDefiningClass != null);
this.m_strName = stName;
this.m_classDefined = tDefiningClass;
this.m_decl = nodeClass;
this.m_type = tReturnType;
this.m_fIsSpecialName = fIsSpecialName;
}
// Imported
public MethodExpEntry(
ISemanticResolver s,
System.Reflection.MethodBase info // CLR info for this method
)
{
Debug.Assert(info != null);
this.m_infoMethod = info;
this.m_fIsSpecialName = info.IsSpecialName;
this.m_strName = info.Name;
this.m_classDefined = s.ResolveCLRTypeToBlueType(info.DeclaringType);
// Set return type for non-constructors
System.Reflection.MethodInfo mInfo = info as System.Reflection.MethodInfo;
if (mInfo != null)
{
// not a ctor
this.m_type = s.ResolveCLRTypeToBlueType(mInfo.ReturnType);
}
else
{
// ctor
this.m_type = null;
m_strName = m_classDefined.Name;
}
}
#endregion
#region Checks
public override string ToString()
{
//return "MethodExp:" + m_classDefined.ToString() + "." + m_strName;
return "MethodExp:" + this.PrettyDecoratedName;
}
// Write out this Entry's name, attributes, (and if fRecursive, then nested scope too)
public override void Dump(XmlWriter o, bool fRecursive)
{
o.WriteStartElement("MethodExpEntry");
o.WriteAttributeString("name", m_strName);
o.WriteAttributeString("rettype", (m_type == null) ? "null" : m_type.ToString());
o.WriteAttributeString("class", (m_classDefined == null) ? "null" : m_classDefined.ToString());
if (fRecursive && (m_scope != null))
{
m_scope.Dump(o, true);
}
o.WriteEndElement();
}
// Debugging support
public override void DebugCheck(ISemanticResolver s)
{
//Debug.Assert(AST.Node.m_DbgAllowNoCLRType || m_typeCLR != null);
if (Node != null)
{
Debug.Assert(Node.Symbol == this);
// Non-null means that we're a user method. So we'd better
// have a scope
Debug.Assert(m_scope != null);
m_scope.DebugCheck(s);
}
else
{
// If Node is null, then we're imported.
// Can't have a scope & body for an imported function...
Debug.Assert(m_scope == null);
}
if (!IsCtor)
{
// Must have a return type (even Void is still non-null)
Debug.Assert(RetType != null);
RetType.DebugCheck(s);
}
// Must be defined in some class
Debug.Assert(m_classDefined != null);
}
#endregion
#region Properties & Data
// For building a linked list of methods for searching for overloads
// Only MethodHeaderEntry should change this.
internal MethodExpEntry m_next;
// Location in AST that this method is declared
protected AST.MethodDecl m_decl;
public AST.MethodDecl Node
{
get { return m_decl; }
}
// Scope containing our parameters & locals
public Scope m_scope;
/*
public Scope Scope
{
get { return m_scope; }
}
*/
// Class that we're defined in
protected TypeEntry m_classDefined;
public TypeEntry SymbolClass
{
get { return m_classDefined; }
}
bool m_fIsSpecialName;
public bool IsSpecialName
{
get { return m_fIsSpecialName; }
set { m_fIsSpecialName = value; }
}
// m_type is the return type of this method
// It's null if we're a ctor
public bool IsCtor
{
get { return m_type == null; }
}
// Return type for this method
public TypeEntry RetType
{
get { return m_type; }
}
#endregion
#region Convenience Helpers
// return a string that fully represents the method exp
public string PrettyDecoratedName
{
get {
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append(this.SymbolClass.FullName);
sb.Append('.');
sb.Append(this.Name);
sb.Append('(');
for(int i = 0; i < ParamCount; i++)
{
if (i != 0)
sb.Append(',');
Type t = ParamCLRType(i);
sb.Append(t.ToString());
}
sb.Append(')');
return sb.ToString();
}
}
// Convenience helpers
/*
public TypeEntry ParamType(int iParam)
{
if (this.Node != null)
{
return Node.Params[iParam].Symbol.m_type;
}
else if (this.Info != null)
{
// Can't convert from clr -> blue without a context,
// and we don't want to pass a context around
return Info.GetParameters()[iParam].ParameterType.###;
}
else
{
return null;
}
} // end ParamType
*/
// Get an array of all params (never includes a this pointer)
// If fStripRefs is true, then we automatically convert T& --> T
public System.Type [] ParamTypes(bool fStripRefs)
{
Type [] al = new Type[this.ParamCount];
for(int i = 0; i < ParamCount; i++)
{
Type t = ParamCLRType(i);
Debug.Assert(t != null, "Only call site can have null param types");
if (fStripRefs)
if (t.IsByRef)
t = t.GetElementType();
al[i] = t;
}
return al;
}
// @todo - how does the numbering here work? Start at 0 or 1?
// does it include the 'this' parameter
public System.Type ParamCLRType(int iParam)
{
// Parameter can be either a actual type or a reference to a type
if (this.Node != null)
{
ParamVarExpEntry sym = Node.Params[iParam].ParamSymbol;
return sym.m_type.CLRType;
}
else if (this.Info != null)
{
return Info.GetParameters()[iParam].ParameterType;
}
else
{
return null;
}
} // end ParamCLRType
public int ParamCount
{
get
{
if (this.Node != null)
{
return Node.Params.Length;
}
else if (this.Info != null)
{
return Info.GetParameters().Length;
}
else
{
return -1;
}
}
} // end ParamCount
#endregion
#region CLR Properties
// Method Info
protected System.Reflection.MethodBase m_infoMethod;
public System.Reflection.MethodBase Info
{
get { return m_infoMethod; }
}
public void SetInfo(ICLRtypeProvider provider)
{
Debug.Assert(m_infoMethod == null);
m_infoMethod = provider.CreateCLRMethod(this);
}
#endregion
// @todo - parameter info
public bool IsStatic
{
get
{
if (m_decl != null)
{
return m_decl.Mods.IsStatic;
}
else
{
return m_infoMethod.IsStatic;
}
}
}
// Has Virtual, bot not NewSlot
public bool IsOverride
{
get {
// @dogfood - these should be const & unsigned..
int i = (int) m_infoMethod.Attributes;
int v = (int) System.Reflection.MethodAttributes.Virtual;
int n = (int) System.Reflection.MethodAttributes.NewSlot;
return (i & (v | n)) == v;
}
}
}
#endregion
#region Simple Variables (Locals & Params)
//-----------------------------------------------------------------------------
// Local variables
//-----------------------------------------------------------------------------
public abstract class VarExpEntry : ExpEntry
{
// Write out this Entry's name, attributes, (and if fRecursive, then nested scope too)
public override void Dump(XmlWriter o, bool fRecursive)
{
o.WriteStartElement("LocalExpEntry");
o.WriteAttributeString("name", m_strName);
o.WriteAttributeString("type", (m_type == null) ? "null" : m_type.ToString());
o.WriteEndElement();
}
public TypeEntry VarType
{
get { return m_type; }
}
}
//-----------------------------------------------------------------------------
// Local variables
//-----------------------------------------------------------------------------
public class LocalVarExpEntry : VarExpEntry
{
public LocalVarExpEntry()
{
//m_iCodeGenSlot = -1;
}
public override string ToString()
{
return "LocalVarExp:" + m_strName;
}
// Let codegen associate its builder with the symbol
protected System.Reflection.Emit.LocalBuilder m_bldLocal;
public System.Reflection.Emit.LocalBuilder Builder
{
get { return m_bldLocal; }
set { m_bldLocal = value; }
}
// Codegen needs to assign each local a slot
/*
protected int m_iCodeGenSlot;
public int CodeGenSlot
{
get { Debug.Assert(m_iCodeGenSlot != -1); return m_iCodeGenSlot; }
set { Debug.Assert(value >= 0); m_iCodeGenSlot = value; }
}
*/
}
//-----------------------------------------------------------------------------
// Parameters
// Note that the CLR requires 'this' be parameter 0
//-----------------------------------------------------------------------------
public class ParamVarExpEntry : VarExpEntry
{
public ParamVarExpEntry()
{
}
public override string ToString()
{
return "ParamVarExp:" + m_strName;
}
// Let codegen associate its builder with the symbol
protected System.Reflection.Emit.ParameterBuilder m_ParameterBuilder;
public System.Reflection.Emit.ParameterBuilder Builder
{
get { return m_ParameterBuilder; }
set { m_ParameterBuilder = value; }
}
// Codegen needs to assign each param a slot
#if true
protected int m_iCodeGenSlot = -1;
public int CodeGenSlot
{
get { Debug.Assert(m_iCodeGenSlot != -1); return m_iCodeGenSlot; }
set { Debug.Assert(value >= 0); m_iCodeGenSlot = value; }
}
#else
public int CodeGenSlot
{
get { return m_ParameterBuilder.Position; }
set { }
}
#endif
}
#endregion
#endregion
} // end namespace
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -