📄 objexpast.cs
字号:
CalcCLRType(s);
return this;
}
#endregion
public override void GenerateAsRight(CodeGen.EmitCodeGen gen)
{
gen.Generate(this);
}
}
//-----------------------------------------------------------------------------
// For events
// This is only a temporary node (like properties) and should be transformed
// into method calls.
//-----------------------------------------------------------------------------
public class EventExp : Exp
{
public EventExp(
EventExpEntry symbol,
Exp expInstance // null for statics
)
{
Debug.Assert(symbol != null);
m_symbol = symbol;
m_expInstance = expInstance;
}
EventExpEntry m_symbol;
public EventExpEntry Symbol
{
get { return m_symbol; }
}
Exp m_expInstance;
public Exp InstanceExp
{
get { return m_expInstance; }
}
#region Checks
public override void DebugCheck(ISemanticResolver s)
{
Debug.Assert(false, "EventExp node should be replaced by end of resolution");
Debug.Assert(m_symbol != null);
}
public override void Dump(XmlWriter o)
{
}
public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)
{
sb.Write("<E>{0}", m_symbol.Name);
}
#endregion
#region Resolution
protected override Type CalcCLRTypeHelper(ISemanticResolver s)
{
return m_symbol.EventType.CLRType;
}
// Ok to resolve as a LS thing (really only in += and -=).
// This node will get replaced with a method call anyways..
protected override Exp ResolveExpAsLeft(ISemanticResolver s)
{
CalcCLRType(s);
return this;
}
// See section 10.7 of the C# spec.
// Outside of our class, we can only use an event as the LS in += and -=
// However, within our class, we can use an event on the RS, like a delegate.
// This is a little goofy.
// We can actually never use an event on the RS. When try to, we're actually
// using a compiler generated delegate (that has the exact same name) instead.
// However, we can't put both an event & a delegate in the same scope (because
// the names would conflict). So the delegate has a different name than the event.
// When the user tries to access an event as a RHS, we switch it to the delegate here.
protected override Exp ResolveExpAsRight(ISemanticResolver s)
{
FieldExpEntry f = m_symbol.Field;
if (f == null)
{
// Events aren't allowed as RHS expressions.
ThrowError(SymbolError.NoEventOnRHS(this));
}
Exp e = new FieldExp(f, this.InstanceExp);
Exp.ResolveExpAsRight(ref e, s);
return e;
}
#endregion
}
//-----------------------------------------------------------------------------
// For fields
//-----------------------------------------------------------------------------
public class FieldExp : Exp
{
public FieldExp(
FieldExpEntry symbol,
Exp expInstance // null for statics
)
{
Debug.Assert(symbol != null);
m_symbol = symbol;
m_expInstance = expInstance;
}
#region Properties & Data
SymbolEngine.FieldExpEntry m_symbol;
public FieldExpEntry Symbol
{
get { return m_symbol; }
}
Exp m_expInstance;
public Exp InstanceExp
{
get { return m_expInstance; }
}
public bool IsStatic
{
get { return m_expInstance == null; }
}
#endregion
#region Checks
public override void DebugCheck(ISemanticResolver s)
{
Debug.Assert(m_symbol != null);
Debug.Assert(m_symbol.IsStatic == IsStatic);
}
public override void Dump(XmlWriter o)
{
}
public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)
{
if (m_expInstance == null)
//sb.Write("[static]");
sb.Write(m_symbol.SymbolClass.FullName);
else
m_expInstance.ToSource(sb);
sb.Write(".<field>{0}", m_symbol.Name);
}
#endregion
#region Resolution
protected override Type CalcCLRTypeHelper(ISemanticResolver s)
{
return m_symbol.CLRType;
}
protected override Exp ResolveExpAsLeft(ISemanticResolver s)
{
CalcCLRType(s);
return this;
}
protected override Exp ResolveExpAsRight(ISemanticResolver s)
{
CalcCLRType(s);
return this;
}
#endregion
#region Generate
public override void GenerateAsLeftPre(CodeGen.EmitCodeGen gen)
{
gen.GenerateAsLeftPre(this);
}
public override void GenerateAsRight(CodeGen.EmitCodeGen gen)
{
gen.Generate(this);
}
public override void GenerateAsLeftPost(CodeGen.EmitCodeGen gen)
{
gen.GenerateAsLeftPost(this);
}
public override void GenerateAddrOf(CodeGen.EmitCodeGen gen)
{
gen.GenerateAddrOf(this);
}
#endregion
}
#endregion
//-----------------------------------------------------------------------------
// ObjExp -> id
// Resolve to another, more-specific, Node
//-----------------------------------------------------------------------------
public class SimpleObjExp : Exp
{
public SimpleObjExp(Identifier id)
{
m_filerange = id.Location;
m_strId = id;
}
public SimpleObjExp(string st)
{
m_filerange = null;
m_strId = new Identifier(st, m_filerange);
}
#region Properties & Data
Identifier m_strId;
public Identifier Name
{
get { return m_strId; }
}
#endregion
#region Checks
public override void DebugCheck(ISemanticResolver s)
{
Debug.Assert(false, "Temporary node still in Final pass");
}
// Dump as XML
public override void Dump(XmlWriter o)
{
o.WriteStartElement("SimpleObjExp");
o.WriteAttributeString("id", m_strId.Text);
o.WriteEndElement();
}
public override string ToString()
{
return this.m_strId.Text;
}
public override void ToSource(System.CodeDom.Compiler.IndentedTextWriter sb)
{
sb.Write("'{0}'", this.Name.Text);
}
#endregion
// m_type is only null if we're a namespace, in which case we have an ancestor
// DotObjExp which will have the type
// Resolve as a LHS
protected override Exp ResolveExpAsLeft(ISemanticResolver s)
{
Exp e = GetResolvedNode(s, false);
Debug.Assert(e != this);
Exp.ResolveExpAsLeft(ref e, s);
e.SetLocation(this.Location);
return e;
}
// Resolve as a RHS
protected override Exp ResolveExpAsRight(ISemanticResolver s)
{
Exp e = GetResolvedNode(s, true);
if (e != this)
Exp.ResolveExpAsRight(ref e, s);
e.SetLocation(this.Location);
return e;
}
// An ObjExp is just a temporary node. But that's the best a Context-Free parse can
// do. So now that we're building a symbol table, we can do a Context-Sensitive resolution
// and figure out what type of node this really is.
public Exp GetResolvedNode(ISemanticResolver s, bool fRight)
{
Exp eResolved = null;
// Lookup the symbol and determine what we are
//SymEntry sym = s.LookupSymbol(this.m_strId, true);
string stName = this.m_strId.Text;
SymEntry sym = s.LookupSymbolWithContext(this.m_strId, false); // allow methods
// Namespace
if (sym is NamespaceEntry)
{
eResolved = new NamespaceExp(sym as NamespaceEntry);
}
// Local Variable
else if (sym is LocalVarExpEntry)
{
eResolved = new LocalExp(sym as LocalVarExpEntry);
}
// Parameter
else if (sym is ParamVarExpEntry)
{
eResolved = new ParamExp(sym as ParamVarExpEntry);
}
// A type name
else if (sym is TypeEntry)
{
eResolved = new TypeExp(sym as TypeEntry);
}
// A field (w/ an implied 'this' pointer)
else if (sym is FieldExpEntry)
{
// When a single identifier resolves to a field, it can be either
// an instance field with an implied 'this' ref, or a static field of this class.
FieldExpEntry f = sym as FieldExpEntry;
Exp expInstance = null;
if (!f.IsStatic)
{
expInstance = new SimpleObjExp("this");
Exp.ResolveExpAsRight(ref expInstance, s);
}
eResolved = new FieldExp(f, expInstance);
}
// An event (w/ an implied 'this' ptr)
else if (sym is EventExpEntry)
{
EventExpEntry e = (EventExpEntry) sym;
Exp expInstance = null;
if (!e.Mods.IsStatic)
{
expInstance = new SimpleObjExp("this");
Exp.ResolveExpAsRight(ref expInstance, s);
}
eResolved = new EventExp(e, expInstance);
}
// A property (w/ an implied 'this' ptr).
// Properties will eventually be converted into method calls.
else if (sym is PropertyExpEntry)
{
PropertyExpEntry p = (PropertyExpEntry) sym;
Exp expInstance = null;
if (!p.IsStatic)
{
expInstance = new SimpleObjExp("this");
Exp.ResolveExpAsRight(ref expInstance, s);
}
eResolved = new PropertyExp(p, expInstance);
}
// Not recognized.
else {
if (stName == "this") // check a common error case...
Debug.Assert(false, "Can't access 'this'. Are we in a static?");
if (sym == null)
{
MethodHeaderEntry h = s.GetCurrentClass().LookupMethodHeader(this.m_strId.Text);
if (h != null)
{
return this;
}
ThrowError(SymbolError.UndefinedSymbol(m_strId));
//Debug.Assert(false, "Unknown name in SimpleObjExp:" + stName);
}
Debug.Assert(false, "Unknown symbol type:" + ((sym == null) ? "null" : sym.ToString()));
}
Debug.Assert(eResolved != null);
return eResolved;
}
}
//-----------------------------------------------------------------------------
// DotObjExp -> ObjExp '.' id
//-----------------------------------------------------------------------------
public class DotObjExp : Exp
{
#region Construction
public DotObjExp(Exp left, Identifier id)
{
m_left = left;
m_strId = id;
m_filerange = id.Location;
}
#endregion
#region Properties & Data
Exp m_left;
public Exp LeftExp
{
get { return m_left; }
}
readonly Identifier m_strId;
public Identifier Id
{
get { return m_strId; }
}
#endregion
#region Resolution
// Resolve as a LHS
protected override Exp ResolveExpAsLeft(ISemanticResolver s)
{
Exp.ResolveExpAsRight(ref m_left, s);
Exp e = GetResolvedNode(s);
Exp.ResolveExpAsLeft(ref e, s);
e.SetLocation(this.Location);
return e;
}
// Resolve as a RHS
protected override Exp ResolveExpAsRight(ISemanticResolver s)
{
// E.i
// First resolve the exp on the left of the dot.
Exp.ResolveExpAsRight(ref m_left, s);
// Now we can figure out what we ought to be.
Exp e = GetResolvedNode(s);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -