// 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 }
// For overloaded operators // No modifiers needed since op overloading must be public & static. // Have a special constructor so that we can set the IsOp flag and // get a safe string name. public MethodDecl( BinaryExp.BinaryOp op, TypeSig tRetType, ParamVarDecl[] arParams, BlockStatement stmtBody ) { m_fIsOpOverload = true; string strName = GetOpOverloadedName(op); m_idName = new Identifier(strName, tRetType.Location); m_tRetType = tRetType; m_arParams = (arParams != null) ? arParams : new ParamVarDecl[0]; m_stmtBody = stmtBody; //m_mods = new Modifiers(Modifiers.EFlags.Public | Modifiers.EFlags.Static); m_mods = new Modifiers(); m_mods.SetPublic(); m_mods.SetStatic(); Debug.Assert(m_idName != null); Debug.Assert(m_stmtBody != null); Debug.Assert(m_arParams != null); }
public DelegateDecl( Identifier idName, TypeSig tRetType, ParamVarDecl[] arParams, Modifiers mods ) { Debug.Assert(idName != null); Debug.Assert(tRetType != null); Debug.Assert(arParams != null); m_idName = idName; m_tRetType = tRetType; m_arParams = arParams; m_mods = mods; // Implied sealed m_mods.SetSealed(); }
MethodDecl( Identifier idName, TypeSig tRetType, ParamVarDecl[] arParams, BlockStatement stmtBody, Modifiers mods ) { //m_strName = idName.Text; m_idName = idName; m_tRetType = tRetType; m_mods = mods; if (m_mods.IsAbstract && !m_mods.IsOverride) m_mods.SetVirtual(); m_arParams = (arParams != null) ? arParams : new ParamVarDecl[0]; m_stmtBody = stmtBody; Debug.Assert(m_idName != null); Debug.Assert((m_stmtBody != null) ^ mods.IsAbstract); Debug.Assert(m_arParams != null); // @todo - this is wrong m_filerange = idName.Location; }
MethodDecl( Identifier idName, TypeSig tRetType, ParamVarDecl[] arParams ) { //m_strName = idName.Text; m_idName = idName; m_tRetType = tRetType; m_mods = new Modifiers(); m_mods.SetAbstract(); m_mods.SetVirtual(); m_mods.SetPublic(); m_arParams = (arParams != null) ? arParams : new ParamVarDecl[0]; m_stmtBody = null; Debug.Assert(m_idName != null); Debug.Assert(m_arParams != null); // @todo - this is wrong m_filerange = idName.Location; }
public PropertyDecl( Identifier idName, TypeSig tType, ParamVarDecl param, // optional param, may be null BlockStatement stmtGet, bool fHasGet, BlockStatement stmtSet, bool fHasSet, Modifiers mods ) { m_stmtGet = stmtGet; m_stmtSet = stmtSet; m_idName = idName; m_tType = tType; Debug.Assert(idName != null); Debug.Assert(tType != null); Debug.Assert(fHasGet || fHasSet); m_mods = mods; //m_expParam = expParam; // Spoof bodies. Note that we just pass the attributes (static, virtual) // right to the new methods. Also, if we're abstract, the XXXStmt will be null // and the methods will just deal with that too. if (fHasGet) { Debug.Assert(mods.IsAbstract ^ (stmtGet != null)); // T get_XXX(); Identifier idName2 = new Identifier("get_"+Name.Text, m_idName.Location); m_declGet = new MethodDecl( idName2, m_tType, (param == null) ? new ParamVarDecl[0] : new ParamVarDecl[] { param }, GetStmt, mods ); } if (fHasSet) { Debug.Assert(mods.IsAbstract ^ (stmtSet != null)); // void set_XXX(T value); Identifier idP1 = new Identifier("value", new FileRange()); ParamVarDecl T = new ParamVarDecl(idP1, (NonRefTypeSig) m_tType, EArgFlow.cIn); ParamVarDecl [] p = (param == null) ? new ParamVarDecl[] { T } : new ParamVarDecl[] { param, T }; Identifier idName2 = new Identifier("set_"+Name.Text, m_idName.Location); AST.TypeSig tVoid = new SimpleTypeSig(new SimpleObjExp(new Identifier("void", new FileRange()))); //AST.TypeSig tVoid = new ResolvedTypeSig(typeof(void), s); m_declSet = new MethodDecl(idName2, tVoid,p, SetStmt, mods); } }
//----------------------------------------------------------------------------- // Parse a parameter list (including opening & closing parens) // -> '(' (''|'ref'|'out') typesig id ',' typesig id ',' ... ')' //----------------------------------------------------------------------------- // @todo - allow out,ref protected ParamVarDecl [] ParseParamList() { ReadExpectedToken(Token.Type.cLParen); // Read parameter list. Keep looping until we get the closing ')' // param-> Typesig id // paramlist-> <comma separated list of 'param'> ArrayList alParams = new ArrayList(); Token t = m_lexer.PeekNextToken(); if (t.TokenType == Token.Type.cRParen) ConsumeNextToken(); bool fUsedParams = false; while (t.TokenType != Token.Type.cRParen) { Debug.Assert(!fUsedParams, "@todo - 'params' only allowed on last thing"); t = m_lexer.PeekNextToken(); // Check for flow modifier AST.EArgFlow eFlow = EArgFlow.cIn; if (t.TokenType == Token.Type.cRef) eFlow = EArgFlow.cRef; else if (t.TokenType == Token.Type.cOut) eFlow = EArgFlow.cOut; // Allow 'params' modifier for a vararg on last parameter else if (t.TokenType == Token.Type.cParams) { fUsedParams = true; ConsumeNextToken(); t = m_lexer.PeekNextToken(); } if (eFlow != EArgFlow.cIn) { ConsumeNextToken(); } // param-> Typesig id NonRefTypeSig type = ParseTypeSig(); Identifier stName = ReadExpectedIdentifier(); VarDecl nodeDecl = new ParamVarDecl(stName, type, eFlow); alParams.Add(nodeDecl); t = m_lexer.GetNextToken(); CheckError_UnexpectedToken(t, new Token.Type [] { Token.Type.cComma, Token.Type.cRParen } ); } ParamVarDecl [] arParams = ParamVarDeclFromArray(alParams); return arParams; }
//----------------------------------------------------------------------------- // Helpes to convert from ArrayLists to normal arrays // Have to do this until mscorlib works the bugs out of its array conversion // stuff. //----------------------------------------------------------------------------- protected ParamVarDecl[] ParamVarDeclFromArray(ArrayList alParams) { ParamVarDecl[] v = new ParamVarDecl[alParams.Count]; for(int i = 0; i < alParams.Count; i++) v[i] = (ParamVarDecl) alParams[i]; return v; }