public void AddMatch(MethodExpEntry symbol) { #if DEBUG if (m_fLog) { Console.WriteLine("Adding match:{0}", //TypeEntry.GetDecoratedParams(symbol), symbol.PrettyDecoratedName); } #endif // If we're ambiguous, then start tracking it for error info // Don't create the string builder until we hit our first ambiguous overload if (m_count == 1) { m_sbOverloads = new System.Text.StringBuilder(); // Add the first entry // @dogfood - should be able to match 0 non-varargs //m_sbOverloads.AppendFormat("\t(1):"); m_sbOverloads.Append("\t(1):"); m_sbOverloads.Append(m_symbol.PrettyDecoratedName); m_sbOverloads.Append('\n'); } m_count++; m_symbol = symbol; if (m_count > 1) { // Keep appending the overload entries m_sbOverloads.AppendFormat("\t({0}):", m_count); m_sbOverloads.Append(symbol.PrettyDecoratedName); m_sbOverloads.Append('\n'); } }
public override string ToString() { int count = 0; MethodExpEntry h = m_head; while (h != null) { h = h.m_next; count++; } return("MethodHeaderEntry (" + count + " overloads)"); }
// Ctor for imported properties public PropertyExpEntry( ISemanticResolver s, System.Reflection.PropertyInfo info ) { m_info = info; m_strName = m_info.Name; // Class that we're defined in? System.Type tClrClass = info.DeclaringType; m_tClassDefined = s.ResolveCLRTypeToBlueType(tClrClass); // Symbol type this.m_type = s.ResolveCLRTypeToBlueType(info.PropertyType); // Spoof accessors if (info.CanRead) // Has Get { System.Reflection.MethodInfo mGet = info.GetGetMethod(); m_symbolGet = new MethodExpEntry(s, mGet); } if (info.CanWrite) // Has Set { System.Reflection.MethodInfo mSet = info.GetSetMethod(); m_symbolSet = new MethodExpEntry(s, mSet); } // Get modifiers System.Reflection.MethodInfo [] m = info.GetAccessors(); m_mods = new Modifiers(m[0]); /* * m_mods = new Modifiers(); * if (m[0].IsStatic) m_mods.SetStatic(); * if (m[0].IsAbstract) m_mods.SetAbstract(); * if (m[0].IsVirtual) m_mods.SetVirtual(); */ }
//----------------------------------------------------------------------------- // Missing an method inherited from an interface //----------------------------------------------------------------------------- public static SymbolErrorException MissingInterfaceMethod( FileRange location, MethodExpEntry mInterface, TypeEntry tClass ) { string stClass = tClass.FullName; string stMethod = mInterface.PrettyDecoratedName; string stInterface = mInterface.SymbolClass.FullName; return new SymbolErrorException( Code.cMissingInterfaceMethod, location, "The type '"+stClass+"' does not implement method '"+ stMethod + "' from interface '" + stInterface + "'"); }
public void AddMethodNode(MethodExpEntry entry) { Debug.Assert(entry.m_next == null); entry.m_next = m_head; m_head = entry; }
public void SetRemoveMethod(MethodExpEntry m) { Debug.Assert(m_methodRemove == null); m_methodRemove = m; }
//----------------------------------------------------------------------------- // When doing 'base.X(.....)', X must not be static. // If it was, we should have done 'T.X(.....)' //----------------------------------------------------------------------------- public static SymbolErrorException BaseAccessCantBeStatic(FileRange location, MethodExpEntry m) { return new SymbolErrorException( Code.cBaseAccessCantBeStatic, location, "Can't access static member '"+m.PrettyDecoratedName+"' via a 'base' accessor."); }
//----------------------------------------------------------------------------- // Can't override a non-virtual method. //----------------------------------------------------------------------------- public static SymbolErrorException CantOverrideNonVirtual( MethodExpEntry m, MethodExpEntry mSuper) { return new SymbolErrorException( Code.cCantOverrideNonVirtual, m.Node.Location, "'" + m.PrettyDecoratedName + "' can't override the non-virtual method '" + mSuper.PrettyDecoratedName + "'." ); }
// Ctor for imported properties public PropertyExpEntry( ISemanticResolver s, System.Reflection.PropertyInfo info ) { m_info = info; m_strName = m_info.Name; // Class that we're defined in? System.Type tClrClass = info.DeclaringType; m_tClassDefined = s.ResolveCLRTypeToBlueType(tClrClass); // Symbol type this.m_type = s.ResolveCLRTypeToBlueType(info.PropertyType); // Spoof accessors if (info.CanRead) // Has Get { System.Reflection.MethodInfo mGet = info.GetGetMethod(); m_symbolGet = new MethodExpEntry(s, mGet); } if (info.CanWrite) // Has Set { System.Reflection.MethodInfo mSet = info.GetSetMethod(); m_symbolSet = new MethodExpEntry(s, mSet); } // Get modifiers System.Reflection.MethodInfo [] m = info.GetAccessors(); m_mods = new Modifiers(m[0]); /* m_mods = new Modifiers(); if (m[0].IsStatic) m_mods.SetStatic(); if (m[0].IsAbstract) m_mods.SetAbstract(); if (m[0].IsVirtual) m_mods.SetVirtual(); */ }
public void SetRemoveMethod(MethodExpEntry m) { Debug.Assert(m_methodRemove == null); m_methodRemove = m; }
public void SetAddMethod(MethodExpEntry m) { Debug.Assert(m_methodAdd == null); m_methodAdd = m; }
public MethodPtrExp( MethodExpEntry symbol ) { Debug.Assert(symbol != null); m_symbol = symbol; }
// Resolve protected override Exp ResolveExpAsRight(ISemanticResolver s) { // Resolve the type we're allocating m_tType.ResolveType(s); // One major exception for creating a new delegate, of the form: // new T(E.i) //if (m_tType.CLRType.BaseType == typeof(System.MulticastDelegate)) if (DelegateDecl.IsDelegate(m_tType.CLRType)) { //Debug.Assert(false, "@todo - Impl Delegates in New"); if (Params.Length != 1) { // When this is resolved, we actually have 2 params (not just one). // Make sure we've already resolved this. return this; } Exp.ResolveExpAsRight(ref m_arParams[0], s); DotObjExp e = m_arParams[0] as DotObjExp; Debug.Assert(e != null); Exp expInstance = null; TypeEntry tLeft = null; if (e.LeftExp is TypeExp) { // Static expInstance = new NullExp(Location); tLeft = ((TypeExp) e.LeftExp).Symbol; } else { // Instance expInstance = e.LeftExp; tLeft = s.ResolveCLRTypeToBlueType(e.LeftExp.CLRType); } // Use the parameter list off the delegate type to discern for overloads. System.Type [] alDelegateParams = DelegateDecl.GetParams(m_tType.BlueType); // Lookup what function we're passing to the delegate. bool fIsOut; MethodExpEntry m = tLeft.LookupMethod(s, e.Id, alDelegateParams, out fIsOut); Debug.Assert(!fIsOut, "@todo - can't have a delegate reference a vararg function"); // Change parameters m_arParams = new Exp [] { expInstance, new MethodPtrExp(m) }; } // Resolve all parameters System.Type [] alParamTypes = new Type[Params.Length]; for(int i = 0; i < this.m_arParams.Length; i++) { Exp.ResolveExpAsRight(ref m_arParams[i], s); alParamTypes[i] = m_arParams[i].CLRType; //Debug.Assert(alParamTypes[i] != null); } // Now we're back to normal... // Figure out what constructor we're calling if (m_tType.BlueType.IsStruct && (alParamTypes.Length == 0)) { // Structs have no default constructor } else { // Else resolve the ctor bool fIsVarArg; m_symCtor = m_tType.BlueType.LookupMethod( s, new Identifier(m_tType.BlueType.Name, this.Location), alParamTypes, out fIsVarArg); } //(m_tType.TypeRec, s); CalcCLRType(s); return this; }
// Semantic resolution protected override Exp ResolveExpAsRight(ISemanticResolver s) { // Only resolve once. if (m_symbol != null) return this; // First, resolve our parameters (because of overloading) // We need to know the URT types for our parameters // in order to resolve between overloaded operators Type [] alParamTypes = new Type[m_arParams.Length]; for(int i = 0; i < m_arParams.Length; i++) { Exp e = m_arParams[i]; ResolveExpAsRight(ref e, s); Debug.Assert(e == m_arParams[i]); Type tParam = e.CLRType; //if ((tParam !=null) && tParam.IsByRef) // tParam = tParam.GetElementType(); alParamTypes[i] = tParam; //Debug.Assert(alParamTypes[i] != null); } TypeEntry tCur = s.GetCurrentClass(); TypeEntry tLeft = null; // Type to lookup in // Is this a 'base' access? // Convert to the real type and set a non-virtual flag if (m_objExp is SimpleObjExp) { SimpleObjExp e = m_objExp as SimpleObjExp; if (e.Name.Text == "base") { // Set the scope that we lookup in. tLeft = tCur.Super; // Still need to resolve the expression. m_objExp = new SimpleObjExp("this"); m_fIsNotPolymorphic = true; } } #if true // See if we have a delegate here Exp eDelegate = null; if (m_objExp == null) { Exp e = new SimpleObjExp(m_idName); Exp.ResolveExpAsRight(ref e, s); if (!(e is SimpleObjExp)) eDelegate = e; } else { // If it's an interface, then we know we can't have a delegate field on it, // so short-circuit now. Exp.ResolveExpAsRight(ref m_objExp, s); if (!m_objExp.CLRType.IsInterface) { Exp e = new DotObjExp(m_objExp, m_idName); Exp.ResolveExpAsRight(ref e, s); if (!(e is DotObjExp)) eDelegate = e; } } if (eDelegate != null) { if (!DelegateDecl.IsDelegate(eDelegate.CLRType)) { //Debug.Assert(false, "@todo - " + m_strName + " is not a delegate or function"); // @todo - legit // Just fall through for now, method resolution will decide if this is a valid function } else { Exp e = new MethodCallExp( eDelegate, new Identifier("Invoke"), this.m_arParams ); Exp.ResolveExpAsRight(ref e, s); return e; } } #endif // No delegate, carry on with a normal function call // If there's no objexp, then the function is a method // of the current class. // make it either a 'this' or a static call if (m_objExp == null) { // Lookup bool fIsVarArgDummy; MethodExpEntry sym = tCur.LookupMethod(s, m_idName, alParamTypes, out fIsVarArgDummy); if (sym.IsStatic) { m_objExp = new TypeExp(tCur); } else { m_objExp = new SimpleObjExp("this"); } } // Need to Lookup m_strName in m_objExp's scope (inherited scope) Exp.ResolveExpAsRight(ref m_objExp, s); // Get type of of left side object // This call can either be a field on a variable // or a static method on a class bool fIsStaticMember = false; // If we don't yet know what TypeEntry this methodcall is on, then figure // it out based off the expression if (tLeft == null) { if (m_objExp is TypeExp) { fIsStaticMember = true; tLeft = ((TypeExp) m_objExp).Symbol; } else { fIsStaticMember = false; tLeft = s.ResolveCLRTypeToBlueType(m_objExp.CLRType); } } // Here's the big lookup. This will jump through all sorts of hoops to match // parameters, search base classes, do implied conversions, varargs, // deal with abstract, etc. bool fIsVarArg; m_symbol = tLeft.LookupMethod(s, m_idName, alParamTypes, out fIsVarArg); Debug.Assert(m_symbol != null); if (m_fIsNotPolymorphic) { // of the form 'base.X(....)' if (m_symbol.IsStatic) ThrowError(SymbolError.BaseAccessCantBeStatic(this.Location, m_symbol)); // @todo - PrintError? } else { // normal method call /* if (fIsStaticMember && !m_symbol.IsStatic) ThrowError(SymbolError.ExpectInstanceMember(this.Location)); // @todo - PrintError? else if (!fIsStaticMember && m_symbol.IsStatic) ThrowError(SymbolError.ExpectStaticMember(this.Location)); // @todo - PrintError? */ Debug.Assert(fIsStaticMember == m_symbol.IsStatic, "@todo - user error. Mismatch between static & instance members on line."); } // If we have a vararg, then transform it if (fIsVarArg) { // Create the array int cDecl = m_symbol.ParamCount; int cCall = this.ParamExps.Length; ArrayTypeSig tSig = new ArrayTypeSig(m_symbol.ParamCLRType(cDecl - 1), s); Node [] list = new Node[cCall - cDecl + 1]; for(int i = 0; i < list.Length; i++) { list[i] = this.ParamExps[i + cDecl - 1]; } Exp eArray = new NewArrayObjExp( tSig, new ArrayInitializer( list ) ); Exp.ResolveExpAsRight(ref eArray, s); // Change the parameters to use the array ArgExp [] arParams = new ArgExp[cDecl]; for(int i = 0; i < cDecl - 1; i++) arParams[i] = m_arParams[i]; arParams[cDecl - 1] = new ArgExp(EArgFlow.cIn, eArray); m_arParams = arParams; } // end vararg transformation this.CalcCLRType(s); return this; }
// Use this when we already have a static method to call // and we already have the symbols public MethodCallExp( Exp eInstance, // null if static MethodExpEntry symMethod, ArgExp [] arParams, ISemanticResolver s ) { this.m_idName = new Identifier(symMethod.Name); m_arParams = arParams; m_symbol = symMethod; // Spoof Left if (eInstance == null) { //m_objExp = new SimpleObjExp(symMethod.SymbolClass.Name); m_objExp = new TypeExp(symMethod.SymbolClass); } else m_objExp = eInstance; Exp.ResolveExpAsRight(ref m_objExp, s); // Resolve args, just in case foreach(ArgExp eArg in arParams) { Exp e = eArg; Exp.ResolveExpAsRight(ref e, s); Debug.Assert(e == eArg); } //ResolveAsExpEntry(m_symbol, s); CalcCLRType(s); }
//----------------------------------------------------------------------------- // The methdo must be public because it is implementing an interface. //----------------------------------------------------------------------------- public static SymbolErrorException IMethodMustBePublic( FileRange location, MethodExpEntry mInterface, TypeEntry tClass ) { string stClass = tClass.FullName; string stMethod = mInterface.PrettyDecoratedName; string stInterface = mInterface.SymbolClass.FullName; return new SymbolErrorException( Code.cIMethodMustBePublic, location, "The method '" + stMethod + "' must be public to implement interface '" + stInterface + "'"); }
//----------------------------------------------------------------------------- // No suitable method to override. //----------------------------------------------------------------------------- public static SymbolErrorException NoMethodToOverride( MethodExpEntry m ) { return new SymbolErrorException( Code.cNoMethodToOverload, m.Node.Location, "There is no possible method in '" + m.SymbolClass.Super.FullName + "' for the method '" + m.PrettyDecoratedName + "' to override." ); }
public void AddMethodNode(MethodExpEntry entry) { Debug.Assert(entry.m_next == null); entry.m_next = m_head; m_head = entry; }
//----------------------------------------------------------------------------- // Can't change visibility when overriding //----------------------------------------------------------------------------- public static SymbolErrorException VisibilityMismatch( MethodExpEntry m ) { return new SymbolErrorException( Code.cVisibilityMismatch, m.Node.Location, "'" +m.PrettyDecoratedName + "' changes visibility when overriding."); }
public MethodExpEntry GetNextMethod(MethodExpEntry entry) { Debug.Assert(entry != null); return entry.m_next; }
public void SetAddMethod(MethodExpEntry m) { Debug.Assert(m_methodAdd == null); m_methodAdd = m; }
public MethodEnumerator(MethodExpEntry mStart) { m_methodCurrent = null; m_method = mStart; }
public void SetCurrentMethod(MethodExpEntry m) { m_curMethod = m; }
// Must resolve all our parameters and the specific ctor that // we chain to. public override void ResolveStatement(ISemanticResolver s) { Debug.Assert(m_nodeCtor != null); for(int i = 0; i < Params.Length; i++) { Exp.ResolveExpAsRight(ref Params[i], s); } // Lookup what ctor we chain to. TypeEntry tClass = m_nodeCtor.Symbol.SymbolClass; if (TargetType == ETarget.cBase) { tClass = tClass.Super; } System.Type [] alParamTypes = new Type[Params.Length]; for(int i = 0; i < Params.Length; i++) { alParamTypes[i] = Params[i].CLRType; } bool fVarArg; m_symTarget = tClass.LookupMethod( s, new Identifier(tClass.Name, this.Location), alParamTypes, out fVarArg); Debug.Assert(!fVarArg); Debug.Assert(m_symTarget != null); Debug.Assert(m_symTarget.SymbolClass == tClass); // @todo -legit? Make sure we actually get a method from tClass? }
public MethodExpEntry GetNextMethod(MethodExpEntry entry) { Debug.Assert(entry != null); return(entry.m_next); }
// Semantic checking public override void ResolveMember( TypeEntry symDefiningClass, ISemanticResolver s, ICLRtypeProvider provider ) { //TypeEntry tRetType = null; if (!IsCtor) { m_tRetType.ResolveType(s); //tRetType = m_tRetType.TypeRec; } else { ClassDecl nodeClass = symDefiningClass.Node; if (Mods.IsStatic) { // Checks on static ctors if (this.Params.Length != 0) { //s.ThrowError_NoParamsOnStaticCtor(this); ThrowError(SymbolError.NoParamsOnStaticCtor(this)); } // Rename to avoid a naming collision w/ a default ctor. // Since no one will call a static ctor (and codegen ignores ctor names), // we can pick anything here. //this.m_strName = "$static_ctor"; this.m_idName = new Identifier("$static_ctor", m_idName.Location); // Is there a static field initializer to chain to? if (nodeClass.StaticInitMethod != null) { /* Statement stmt = new ExpStatement( new MethodCallExp( null, new Identifier(nodeClass.StaticInitMethod.Name, nodeClass.StaticInitMethod.Location), new ArgExp[0] )); */ // If there are Static, ReadOnly fields, then they must be assigned directly // in a constructor, not in a function called by the constructor. Statement stmt = nodeClass.StaticInitMethod.Body; Body.InjectStatementAtHead(stmt); } } // static ctor else { if (nodeClass.InstanceInitMethod != null) { // Chain to an instance-field initializer if we don't chain to // a this() ctor. CtorChainStatement chain = (this.Body.Statements[0]) as CtorChainStatement; Debug.Assert(chain != null); if (chain.TargetType == CtorChainStatement.ETarget.cBase) { /* Statement stmt = new MethodCallStatement( new MethodCallExp( null, new Identifier(nodeClass.InstanceInitMethod.Name, nodeClass.InstanceInitMethod.Location), new ArgExp[0] )); */ // PEVerify barfs if we try to do an instance method call in the ctor, // so just inject the raw method body. It's just a bunch of assigns anyway, // so we're ok. Statement stmt = nodeClass.InstanceInitMethod.Body; Body.InjectStatementAtHead(stmt); } } } // instance ctor } // Add new sym entry to our parent class's scope MethodExpEntry m = new MethodExpEntry( Name, this, symDefiningClass, IsCtor ? null : m_tRetType.BlueType ); m.m_scope = new Scope( "method: " + symDefiningClass.m_strName + "." + Name, this, symDefiningClass.MemberScope); m_symbol = m; //s.PushScope(m.m_scope); Scope prev = s.SetCurrentContext(m.m_scope); // resolve params (because we'll need them for overloading) // Add param 0 for 'this' (if not static) // For structs, "this" is a reference, for classes, it's a value. if (!Mods.IsStatic) { ParamVarExpEntry e = new ParamVarExpEntry(); e.m_strName = "this"; TypeEntry t = m_symbol.SymbolClass; if (t.IsStruct) { t = new RefTypeEntry(t, s); } e.m_type = t; // 'this' is the type of the containg class e.CodeGenSlot = 0; s.GetCurrentContext().AddSymbol(e); } // do rest of the params foreach(ParamVarDecl param in m_arParams) { param.ResolveVarDecl(s); } //s.PopScope(m.m_scope); s.RestoreContext(prev); symDefiningClass.AddMethodToScope(m); }
public MethodEnumerator(MethodExpEntry mStart) { m_methodCurrent = null; m_method = mStart; }
public void AddVarargMatch(MethodExpEntry symbol) { #if DEBUG if (m_fLog) Console.WriteLine("Adding vararg match:{0}", TypeEntry.GetDecoratedParams(symbol)); #endif m_symbolVarArg = symbol; }