Пример #1
0
        // 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;
            }
        }
Пример #2
0
        // Imported field
        public FieldExpEntry(
            ISemanticResolver s,
            System.Reflection.FieldInfo fInfo
            )
        {
            m_strName       = fInfo.Name;
            m_type          = s.ResolveCLRTypeToBlueType(fInfo.FieldType);
            m_nodeDecl      = null;
            m_tClassDefined = s.ResolveCLRTypeToBlueType(fInfo.DeclaringType);

            m_info = fInfo;
        }
Пример #3
0
 public ResolvedTypeSig(System.Type t, ISemanticResolver s)
 {
     Debug.Assert(!t.IsByRef, "Don't expect ref types");
     Debug.Assert(t != null);
     Debug.Assert(s != null);
     m_type = s.ResolveCLRTypeToBlueType(t);
 }
Пример #4
0
 public override void DebugCheck(ISemanticResolver s)
 {        
     Debug.Assert(m_type != null);
     TypeEntry t = BlueType;
     
     if (t.IsRef)
         return;
     
     System.Type clrType = t.CLRType;
     
     // Make sure that our CLR type matches our TypeEntry
     if (clrType != null)
     {
         // @todo - Enums aren't entered into the hash.
         if (!(t is EnumTypeEntry))
         {
             TypeEntry t2 = s.ResolveCLRTypeToBlueType(clrType);
             Debug.Assert(t == t2);
         }
     }
     if (clrType == null)
     {   
         // Even now, the only way we can have no clr type is if we
         // are a user declared class
         Debug.Assert(t.Node != null);            
     }
             
 } // DebugCheck   
Пример #5
0
 // Create an array node given an existing CLR array type
 public ArrayTypeSig(System.Type tArray, ISemanticResolver s)    
 {
     Debug.Assert(tArray != null);
     
     m_filerange = null;
     m_cDimension = tArray.GetArrayRank();        
     Debug.Assert(m_cDimension == 1, "@todo - only 1d arrays currently implemented");
     
     m_ArrayTypeRec = s.ResolveCLRTypeToBlueType(tArray).AsArrayType;
     m_sigBase = null; // left as null.
 }
Пример #6
0
        // 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();
             */
        }
Пример #7
0
        // Imported events
        public EventExpEntry(
            System.Reflection.EventInfo eInfo,
            ISemanticResolver s
            )
        {
            Debug.Assert(eInfo != null);
            Debug.Assert(s != null);

            this.m_strName       = eInfo.Name;
            this.m_tClassDefined = s.ResolveCLRTypeToBlueType(eInfo.DeclaringType);
            this.m_type          = s.ResolveCLRTypeToBlueType(eInfo.EventHandlerType);

            this.m_node = null;

            System.Reflection.MethodInfo mAdd    = eInfo.GetAddMethod();
            System.Reflection.MethodInfo mRemove = eInfo.GetRemoveMethod();

            SetAddMethod(new MethodExpEntry(s, mAdd));
            SetRemoveMethod(new MethodExpEntry(s, mRemove));

            this.m_mods = new Modifiers(mAdd);
        }
Пример #8
0
 // Search for an overloaded operator. Return the symbol for the method if found.
 // Return null if not found.
 MethodExpEntry SearchForOverloadedOp(ISemanticResolver s)
 {
     Type [] alParams = new Type[2];
     alParams[0] = m_left.CLRType;
     alParams[1] = m_right.CLRType;
     
     
     
     string stName = MethodDecl.GetOpOverloadedName(this.Op);
     
     MethodExpEntry sym;
     
     if (m_left.CLRType != null)
     {
         TypeEntry t1 = s.ResolveCLRTypeToBlueType(m_left.CLRType);
         sym = t1.LookupOverloadedOperator(s, stName, alParams);
         if (sym != null)
             return sym;
     }
     
     if (m_right.CLRType != null)
     {
         TypeEntry t2 = s.ResolveCLRTypeToBlueType(m_right.CLRType);
         sym = t2.LookupOverloadedOperator(s, stName, alParams);
         if (sym != null)
             return sym;
     }
             
     return null; 
 }
Пример #9
0
    // Determine the CLR Type of this expression
    // As a convenience, return the clr type to saves us from having to 
    // call CLRType
    public System.Type CalcCLRType(ISemanticResolver s)
    {
        Type tOld = m_clrType;
        m_clrType = CalcCLRTypeHelper(s);   
        Debug.Assert(m_clrType != null || Exp.CanBeNullType(this));
     
        // Assert that if we called this multiple times, the value hasn't changed on us
        Debug.Assert(((tOld == null)) || (tOld == m_clrType));

        // @todo - we don't resolve pointers yet....
        // The only place we can use them is in evaluating a MethodPtr for a delegate ctor.
        if (m_clrType == Type.GetType("System.IntPtr"))
        {
            Debug.Assert(this is MethodPtrExp);
            return m_clrType;
        }


        // @todo - move this into a place w/ better perf...
        // EnsureResolved
        if (m_clrType != null)
        {
            TypeEntry t = s.ResolveCLRTypeToBlueType(m_clrType);
            t.EnsureResolved(s);
        }

        return m_clrType;
    }
Пример #10
0
 // Internal helper. Since the left & right cases are close enough
 // we want to merge them into a function.
 private Exp ResolveInternal(ISemanticResolver s, bool fIsLeft)
 {
     ResolveExpAsRight(ref m_oeLeft, s);
     ResolveExpAsRight(ref m_expIndex, s);
     
 // @todo - check that m_expIndex is an integer
 
 // Check for indexers:
 // If the Left is not an array, then we must be an indexer.
 // Strip references, So T[]& --> T[]
     System.Type t = m_oeLeft.CLRType;
     if (t.IsByRef)
         t = t.GetElementType();
         
     if (!t.IsArray)
     {            
         m_fIsIndexer = true;
         
         
         // If we're the leftside, we have a problem. We don't know the exp on the RS,
         // so we don't have a full signature, so we don't know what we're supposed to
         // change too. So just leave it that we're an indexer and let our parent
         // in the AST resolve us.
         // But this also means that we don't have a good thing to set our CLR type too.
         // So we just don't call CalcCLRType(). That's ok since our parent will drop
         // this node immediately anyways.
         if (fIsLeft)
         {
             return this;
         }
         
         // Rightside: get_Item(idx);
         System.Type [] alParams = new Type [] {
             this.ExpIndex.CLRType
         };
         
         TypeEntry tLeft = s.ResolveCLRTypeToBlueType(m_oeLeft.CLRType);            
         MethodExpEntry m = tLeft.LookupIndexer(m_oeLeft.Location, s, alParams, fIsLeft);
         
         
         Exp e = new MethodCallExp(
             this.Left,
             m,
             new ArgExp[] {
                 new ArgExp(EArgFlow.cIn, ExpIndex)
             },
             s);
             
         Exp.ResolveExpAsRight(ref e, s);
         return e;
         
     }
 
 
 
 
     CalcCLRType(s);
     
     return this;
 }
Пример #11
0
 // 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)
 {
     string stText = this.m_strId.Text;
     // Left must already be resolved, then we resolve right in the context of left
     Debug.Assert(m_left != null);
     Exp eResolved = null;
                
     // @todo, what if left is a NullExp?                       
     if (m_left is NamespaceExp)
     {
         // We're either a nested namespace or a class
         NamespaceEntry n = (m_left as NamespaceExp).Symbol;
         SymEntry sym = n.ChildScope.LookupSymbol(stText);
         if (sym is NamespaceEntry)
         {
             eResolved = new NamespaceExp(sym as NamespaceEntry);
         }
         else if (sym is TypeEntry)
         {
             eResolved = new TypeExp(sym as TypeEntry);
         } else {
             //ThrowError_UndefinedSymbolInNamespace(s, n, m_strId);            
             ThrowError(SymbolError.UndefinedSymbolInNamespace(n, m_strId));
         }
     }
     
     // Check for statics
     else if (m_left is TypeExp)
     {
         TypeEntry t = ((TypeExp) m_left).Symbol;
         t.EnsureResolved(s);
         SymEntry sym = t.MemberScope.LookupSymbol(stText);
         if (sym is FieldExpEntry)
         {
             Debug.Assert(((FieldExpEntry) sym).IsStatic);
             eResolved = new FieldExp(sym as FieldExpEntry, null); // static
         }
         
         else if (sym is PropertyExpEntry)
         {
             eResolved = new PropertyExp(sym as PropertyExpEntry, null);
         } 
         
         else if (sym is EventExpEntry)
         {
             eResolved = new EventExp(sym as EventExpEntry, null);
         }
         
         // Allow nested types
         else if (sym is TypeEntry)
         {
             eResolved = new TypeExp(sym as TypeEntry);
         }
         
         else 
         {
             // Must be a method. The node transform occurs higher up though.
             Debug.Assert((sym = t.LookupMethodHeader(stText)) != null);                
             eResolved = this;
         }
         
         if (eResolved == null) {
             //ThrowError_UndefinedSymbolInType(s, t, m_strId);
             ThrowError(SymbolError.UndefinedSymbolInType(t, m_strId));
         }
     }
     
     // m_left is a variable, and we're doing an instance member dereference
     else {
         TypeEntry t = null;
         
         t = s.ResolveCLRTypeToBlueType(this.m_left.CLRType);
         t.EnsureResolved(s);
                    
         Scope scope = t.MemberScope;
         
         // @todo - broken for an interface. IA : IB, scope for IA doesn't link to IB.
         SymEntry sym = scope.LookupSymbol(stText);
         if (sym is FieldExpEntry)
         {
             eResolved = new FieldExp(sym as FieldExpEntry, this.m_left);
         } 
         else if (sym is PropertyExpEntry)
         {
             eResolved = new PropertyExp(sym as PropertyExpEntry, this.m_left);
         }
         
         else if (sym is EventExpEntry)
         {
             eResolved = new EventExp(sym as EventExpEntry, this.m_left);            
         }
         
         else 
         {
             // Must be a method. The node transform occurs higher up though.
             sym = t.LookupMethodHeader(stText);
             if (sym != null)
                 eResolved = this;
         }
         
         if (eResolved == null) 
         {                
             ThrowError(SymbolError.UndefinedSymbolInType(t, m_strId));
         }
     }
     
     
     Debug.Assert(eResolved != null);
     return eResolved;
     
 }
Пример #12
0
 // Delegates are really just blessed Types.
 void CreateProxyType(ISemanticResolver s)
 {
     Debug.Assert(m_nodeProxy == null, "only create proxy once");
 // The delegate R F(A) (where R is a return type, and A is a parameter list)
 // Can be converted into the type:
 // sealed class F : System.MulticastDelegate {
 //      F(object, native int) { }
 //      BeginInvoke() { }
 //      EndInvoke() { }
 //      R Invoke(A) { }
 // }
     BlockStatement stmtEmpty = new BlockStatement(null, new Statement[0]);
     Modifiers modsPublic = new Modifiers();
     modsPublic.SetPublic();
     
     Modifiers modsVirtual = modsPublic;
     modsVirtual.SetVirtual();
     
 
     //System.Type tNativeInt = typeof(int);
     System.Type tNativeInt = Type.GetType("System.IntPtr");
 
     TypeEntry t_IAsyncResult = s.ResolveCLRTypeToBlueType(typeof(System.IAsyncResult));
     
     // Create the parameters for the BeginInvoke()
     ParamVarDecl [] paramBeginInvoke = new ParamVarDecl[m_arParams.Length + 2];
     m_arParams.CopyTo(paramBeginInvoke, 0);
     paramBeginInvoke[m_arParams.Length]= new ParamVarDecl(
         new Identifier("cb"), 
         new ResolvedTypeSig(typeof(System.AsyncCallback), s), 
         EArgFlow.cIn
     );
     
     paramBeginInvoke[m_arParams.Length + 1] = new ParamVarDecl(
         new Identifier("state"), 
         new ResolvedTypeSig(typeof(System.Object), s), 
         EArgFlow.cIn
     );
 
     m_nodeProxy = new ClassDecl(
         m_idName,
         new TypeSig[] {
             new ResolvedTypeSig(typeof(System.MulticastDelegate), s)
         },
         new MethodDecl[] {
         // Ctor
             new MethodDecl(
                 m_idName, null, new ParamVarDecl[] {
                     new ParamVarDecl(new Identifier("instance"),    new ResolvedTypeSig(typeof(object), s),  EArgFlow.cIn),
                     new ParamVarDecl(new Identifier("func"),        new ResolvedTypeSig(tNativeInt, s),  EArgFlow.cIn)
                 },
                 stmtEmpty, modsPublic
             ),
         // Invoke,
             new MethodDecl(
                 new Identifier("Invoke"),
                 this.m_tRetType,
                 this.m_arParams,
                 stmtEmpty,
                 modsVirtual),
                 
         // Begin Invoke
             new MethodDecl(
                 new Identifier("BeginInvoke"),
                 new ResolvedTypeSig(t_IAsyncResult),
                 paramBeginInvoke,
                 stmtEmpty,
                 modsVirtual),                    
         
         // End Invoke
             new MethodDecl(
                 new Identifier("EndInvoke"),
                 this.m_tRetType,
                 new ParamVarDecl[] {
                     new ParamVarDecl(new Identifier("result"), new ResolvedTypeSig(t_IAsyncResult), EArgFlow.cIn)
                 },
                 stmtEmpty,
                 modsVirtual)
                                         
         },
         new PropertyDecl[0],
         new FieldDecl[0],
         new EventDecl[0],
         new TypeDeclBase[0],
         m_mods,
         true); // isClass
         
 }
Пример #13
0
    // 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;
    }
Пример #14
0
    // Now that all the types have been stubbed and established their context,
    // we can recursively run through and resolve all of our base types.
    void FixBaseTypes(
        ISemanticResolver s,  
        ICLRtypeProvider provider
    )
    {
        TypeEntry tSuper = null;
        
        BeginCheckCycle(s);
        
        ArrayList alInterfaces = new ArrayList();
        
        // Decide who our super class is and which interfaces we're inheriting
        foreach(TypeSig sig in this.m_arSuper)
        {
            sig.ResolveType(s);
            
            TypeEntry t = sig.BlueType;
            
            // Make sure this base type is resolved. Do this recursively
            ClassDecl c = t.Node;
            if (c != null)
            {
                c.ResolveTypesAsCLR(s, provider);
            }
            
            if (t.IsClass)
            {
                Debug.Assert(this.IsClass, "Only a class can have a super-class");
                
                if (tSuper != null)
                {
                    ThrowError(SymbolError.OnlySingleInheritence(this));                
                }
                tSuper = t;
            } else {
                // Both structs & interfaces can only derive from interfaces (not classes)
                if (!t.IsInterface)
                    ThrowError(SymbolError.MustDeriveFromInterface(this, t));
                alInterfaces.Add(t);
            }
        }
        
        TypeEntry [] tInterfaces = new TypeEntry[alInterfaces.Count];
        for(int i = 0; i < alInterfaces.Count; i++)
            tInterfaces[i] = (TypeEntry) alInterfaces[i];
        
        // If no super class is specified, then we use as follows:
        // 'Interface' has no super class,
        // 'Class'     has 'System.Object'
        // 'Struct'    has 'System.ValueType'        
        if (!IsInterface && (tSuper == null))
        {
            if (IsClass)
                tSuper = s.ResolveCLRTypeToBlueType(typeof(object));
            if (IsStruct)
                tSuper = s.ResolveCLRTypeToBlueType(typeof(System.ValueType));                
        }
        
        
        Debug.Assert(IsInterface ^ (tSuper != null));

        // Just to sanity check, make sure the symbol stub is still there
        #if DEBUG               
        TypeEntry sym = (TypeEntry) s.GetCurrentContext().LookupSymbolInThisScopeOnly(m_strName);        
        Debug.Assert(sym == m_symbol);
        #endif

        m_symbol.InitLinks(tSuper, tInterfaces);
                
        // Make sure all of our base types are resolved        
        foreach(TypeEntry t in this.Symbol.BaseInterfaces)
        {               
            t.EnsureResolved(s);
        }
            
        if (Symbol.Super != null)                   
            Symbol.Super.EnsureResolved(s);
                
        // Final call. Set super scope
        m_symbol.FinishInit();
        
        
        EndCheckCycle();
    }
Пример #15
0
 public DeclareLocalStmtExp(System.Type t, ISemanticResolver s)
     : this(s.ResolveCLRTypeToBlueType(t))
 {           
 }
Пример #16
0
 // Imported events
 public EventExpEntry(
     System.Reflection.EventInfo eInfo,
     ISemanticResolver s
 )
 {   
     Debug.Assert(eInfo != null);
     Debug.Assert(s != null);
     
     this.m_strName = eInfo.Name;
     this.m_tClassDefined = s.ResolveCLRTypeToBlueType(eInfo.DeclaringType);
     this.m_type = s.ResolveCLRTypeToBlueType(eInfo.EventHandlerType);
     
     this.m_node = null;
              
     System.Reflection.MethodInfo mAdd = eInfo.GetAddMethod();
     System.Reflection.MethodInfo mRemove = eInfo.GetRemoveMethod();
                                 
     SetAddMethod(new MethodExpEntry(s, mAdd));
     SetRemoveMethod(new MethodExpEntry(s, mRemove));
     
     this.m_mods = new Modifiers(mAdd);
 }
Пример #17
0
 // 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;
     }
 }
Пример #18
0
 // Imported field        
 public FieldExpEntry(
     ISemanticResolver s,
     System.Reflection.FieldInfo fInfo            
     )
 {
     m_strName = fInfo.Name;
     m_type = s.ResolveCLRTypeToBlueType(fInfo.FieldType);
     m_nodeDecl = null;
     m_tClassDefined = s.ResolveCLRTypeToBlueType(fInfo.DeclaringType);
     
     m_info = fInfo;
 }
Пример #19
0
 // 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();
     */
     
 }
Пример #20
0
 // Semantic resolution.
 // This is where we check for Set-Property transformations (where an
 // assignment gets changed into a methodcall)
 protected override Exp ResolveExpAsRight(ISemanticResolver s)
 {
     // Resolve the leftside of the operator                
     Exp.ResolveExpAsLeft(ref m_oeLeft, s);
     
     
     // Event transform  actually occurs in the assignment node.
     // A.e = A.e + d --> A.add_e(d)            
     // We have to do this before we resolve the RHS of the operator (Since we
     // can't resolve events as a RHS).
     if (m_oeLeft is EventExp)
     {   
         EventExp nodeEvent = (EventExp)m_oeLeft;
         EventExpEntry e = nodeEvent.Symbol;         
         
         // Here we just do some asserts.
         BinaryExp b = this.m_expRight as BinaryExp;
         Debug.Assert(b != null, "bad formed event +=,-=");  
      
         // By now, we know we have something of the form A = B + C   
         // Make sure that A=B. Since we resolved A as left, must resolve B as left too.
         Exp eTempLeft = b.Left;
         Exp.ResolveExpAsLeft(ref eTempLeft, s);
         Debug.Assert(eTempLeft is EventExp);
         Debug.Assert(Object.ReferenceEquals(((EventExp) eTempLeft).Symbol, e)); // symbols should be exact references
         
         // Resolve C (the delegate that we're adding to the event)
         Exp eTempRight = b.Right;
         Exp.ResolveExpAsRight(ref eTempRight, s);            
         Debug.Assert(AST.DelegateDecl.IsDelegate(eTempRight.CLRType), "Event only ops w/ delegates"); // @todo -legit/            
         
         Debug.Assert(b.Op == BinaryExp.BinaryOp.cAdd || b.Op == BinaryExp.BinaryOp.cSub);
             
         
         MethodExpEntry m2 = (b.Op == BinaryExp.BinaryOp.cAdd) ? e.AddMethod : e.RemoveMethod;
             
         Exp e2 = new MethodCallExp(
             nodeEvent.InstanceExp,
             m2,
             new ArgExp[] {
                 new ArgExp(EArgFlow.cIn, eTempRight)
             },
             s
         );
                 
         Exp.ResolveExpAsRight(ref e2, s);
         return e2;            
     }
     
     Exp.ResolveExpAsRight(ref m_expRight, s);
                     
     
     // Check for calling add_, remove on events
     // a.E += X 
     // a.E = a.E + X (parser transforms)
     // if E is a delegate, and RHS is structured like E + X
     // then transform to a.add_E(X) or a.remove_E(x)
     
     // @todo - use the EventInfo to get exact add / remove functions
     if (DelegateDecl.IsDelegate(m_oeLeft.CLRType))
     {   
         // Events can only exist on a class
         AST.FieldExp f = m_oeLeft as FieldExp;
         if (f == null)
             goto NotAnEvent;
             
         Exp eInstance = f.InstanceExp; // ok if static                
         
         BinaryExp rhs = m_expRight as BinaryExp;
         if (rhs == null)
             goto NotAnEvent;            
         
         // Check if RHS is a.E + X
         if ((rhs.Left != m_oeLeft) || (rhs.Right.CLRType != rhs.Left.CLRType))
             goto NotAnEvent;
         
                     
         string stEventName = f.Symbol.Name;
         string stOpName;
         if (rhs.Op == BinaryExp.BinaryOp.cAdd)
             stOpName = "add_" + stEventName;
         else if (rhs.Op == BinaryExp.BinaryOp.cSub)
             stOpName = "remove_" + stEventName;                        
         else
             goto NotAnEvent;                
          
         // a.add_E(X);    
         Exp e = new MethodCallExp(
             eInstance,
             new Identifier(stOpName),
             new ArgExp[] {
                 new ArgExp(EArgFlow.cIn, rhs.Right)
             }
         );            
         
         Exp.ResolveExpAsRight(ref e, s);
         e.SetLocation(this.Location);    
         return e;
                     
         
     NotAnEvent:
         ;            
     }
     
     // Check for set-indexer
     if (m_oeLeft is ArrayAccessExp)
     {
         ArrayAccessExp a = m_oeLeft as ArrayAccessExp;
         if (a.IsIndexer) 
         {
             // Leftside: get_Item(idx, value);
             System.Type [] alParams = new Type [] {
                 a.ExpIndex.CLRType,
                 m_expRight.CLRType
             };
         
             TypeEntry t = s.ResolveCLRTypeToBlueType(a.Left.CLRType);            
             MethodExpEntry m = t.LookupIndexer(a.Left.Location, s, alParams, true);
             
             Exp e = new MethodCallExp(
                 a.Left,
                 m,
                 new ArgExp[] { 
                     new ArgExp(EArgFlow.cIn, a.ExpIndex),
                     new ArgExp(EArgFlow.cIn, m_expRight) 
                 },
                 s);
             
             Exp.ResolveExpAsRight(ref e, s);
             e.SetLocation(this.Location);    
             return e;
         }        
     }
     
     // Check for transforming properties into MethodCalls
     if (m_oeLeft is PropertyExp)
     {
         PropertyExp p = (PropertyExp) m_oeLeft;
         
         Exp e = new MethodCallExp(
             p.InstanceExp, 
             p.Symbol.SymbolSet, 
             new ArgExp[] { 
                 new ArgExp(EArgFlow.cIn, m_expRight) 
             },
             s);
             
         Exp.ResolveExpAsRight(ref e, s);
         e.SetLocation(this.Location);
         return e;
     }
     
     CalcCLRType(s);
 
     // Ensure type match        
     s.EnsureAssignable(m_expRight, m_oeLeft.CLRType);        
     
     return this;
 }
Пример #21
0
    // 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;
    }