//------------------------------------------------------------ // SymWithType.CreateCorrespondingInstance (static) // /// <summary> /// /// </summary> /// <param name="sym"></param> /// <param name="ats"></param> /// <returns></returns> //------------------------------------------------------------ static internal SymWithType CreateCorrespondingInstance(SYM sym, AGGTYPESYM ats) { if (sym == null) { return(new SymWithType()); } SymWithType swt = null; switch (sym.Kind) { case SYMKIND.METHSYM: return(new MethWithType(sym as METHSYM, ats) as SymWithType); case SYMKIND.PROPSYM: return(new PropWithType(sym as PROPSYM, ats) as SymWithType); case SYMKIND.EVENTSYM: return(new EventWithType(sym as EVENTSYM, ats) as SymWithType); case SYMKIND.MEMBVARSYM: return(new FieldWithType(sym as MEMBVARSYM, ats) as SymWithType); default: break; } return(new SymWithType(sym, ats)); }
//------------------------------------------------------------ // FieldWithType.Convert // /// <summary> /// If swt is FieldWithType, convert to FieldWithType and return it. /// Otherwise, create a FieldWithType instance by swt and return it. /// </summary> /// <param name="swt"></param> /// <returns></returns> //------------------------------------------------------------ static internal FieldWithType Convert(SymWithType swt) { FieldWithType fwt = swt as FieldWithType; if (fwt != null) { return(fwt); } return(new FieldWithType(swt)); }
//------------------------------------------------------------ // EventWithType.Convert // /// <summary> /// If swt is EventWithType, convert to EventWithType and return it. /// Otherwise, create a EventWithType instance by swt and return it. /// </summary> /// <param name="swt"></param> /// <returns></returns> //------------------------------------------------------------ static internal EventWithType Convert(SymWithType swt) { EventWithType ewt = swt as EventWithType; if (ewt != null) { return(ewt); } return(new EventWithType(swt)); }
//------------------------------------------------------------ // PropWithType.Convert // /// <summary> /// If swt is PropWithType, convert to PropWithType and return it. /// Otherwise, create a PropWithType instance by swt and return it. /// </summary> /// <param name="swt"></param> /// <returns></returns> //------------------------------------------------------------ static new internal PropWithType Convert(SymWithType swt) { PropWithType pwt = swt as PropWithType; if (pwt != null) { return(pwt); } return(new PropWithType(swt)); }
//------------------------------------------------------------ // MethWithType.Convert // /// <summary> /// If swt is MethWithType, convert to MethWithType and return it. /// Otherwise, create a MethWithType instance by swt and return it. /// </summary> /// <param name="swt"></param> /// <returns></returns> //------------------------------------------------------------ static new internal MethWithType Convert(SymWithType swt) { MethWithType mwt = swt as MethWithType; if (mwt != null) { return(mwt); } return(new MethWithType(swt)); }
//------------------------------------------------------------ // MethPropWithType.Convert // /// <summary> /// If swt is MethPropWithType, convert to MethPropWithType and return it. /// Otherwise, create a MethPropWithType instance by swt and return it. /// </summary> /// <param name="swt"></param> /// <returns></returns> //------------------------------------------------------------ static internal MethPropWithType Convert(SymWithType swt) { MethPropWithType mpwt = swt as MethPropWithType; if (mpwt != null) { return(mpwt); } return(new MethPropWithType(swt)); }
//------------------------------------------------------------ // SymWithType.Equals // /// <summary>Override.</summary> /// <param name="obj"></param> //------------------------------------------------------------ public override bool Equals(object obj) { SymWithType swt = obj as SymWithType; if (swt != null) { return(this.Sym == swt.Sym && this.AggTypeSym == swt.AggTypeSym); } return(false); }
//------------------------------------------------------------ // EventWithType Constructor (3) // /// <summary></summary> /// <param name="swt"></param> //------------------------------------------------------------ internal EventWithType(SymWithType swt) { if (swt != null && swt.Sym != null) { Set(swt.Sym as EVENTSYM, swt.AggTypeSym); } else { Set(null, null); } }
//------------------------------------------------------------ // PropWithType Constructor (3) // /// <summary></summary> /// <param name="swt"></param> //------------------------------------------------------------ internal PropWithType(SymWithType swt) { if (swt != null && swt.Sym != null) { Set(swt.Sym as PROPSYM, swt.AggTypeSym); } else { Set(null, null); } }
//------------------------------------------------------------ // MethWithType Constructor (3) // /// <summary></summary> /// <param name="swt"></param> //------------------------------------------------------------ internal MethWithType(SymWithType swt) { if (swt != null && swt.Sym != null) { Set(swt.Sym as METHSYM, swt.AggTypeSym); } else { Set(null, null); } }
//------------------------------------------------------------ // SymWithType.Set (2) // /// <summary></summary> /// <param name="swt"></param> //------------------------------------------------------------ internal void Set(SymWithType swt) { if (swt != null) { this.Set(swt.Sym, swt.AggTypeSym); } else { this.Set(null, null); } }
//------------------------------------------------------------ // FieldWithType Constructor (3) // /// <summary></summary> /// <param name="swt"></param> //------------------------------------------------------------ internal FieldWithType(SymWithType swt) { if (swt != null && swt.Sym != null) { MEMBVARSYM fieldSym = swt.Sym as MEMBVARSYM; if (fieldSym != null) { Set(fieldSym, swt.AggTypeSym); return; } } Set(null, null); }
//------------------------------------------------------------ // FUNCBREC.CreateAutoImplementedGetAccessor // /// <summary></summary> /// <param name="methodSym"></param> /// <returns></returns> //------------------------------------------------------------ internal EXPR CreateAutoImplementedGetAccessor(METHSYM methodSym) { CreateNewScope(); SCOPESYM scopeSym = this.currentScopeSym; this.currentScopeSym.ScopeFlags = SCOPEFLAGS.NONE; this.currentBlockExpr = NewExprBlock(treeNode); this.currentBlockExpr.ScopeSym = this.currentScopeSym; SymWithType symWithType = new SymWithType(); AGGTYPESYM parentAts = methodSym.ParentAggSym.GetThisType(); symWithType.Set( methodSym.PropertySym.BackFieldSym, parentAts); EXPR fieldExpr = BindToField( null, BindThisImplicit(null), FieldWithType.Convert(symWithType), BindFlagsEnum.RValueRequired); //TYPESYM retTypeSym = methodSym.ReturnTypeSym; EXPRRETURN returnExpr = NewExpr(null, EXPRKIND.RETURN, null) as EXPRRETURN; returnExpr.ObjectExpr = fieldExpr; this.currentBlockExpr.StatementsExpr = returnExpr; EXPRBLOCK blockExpr = this.currentBlockExpr; this.currentBlockExpr = blockExpr.OwingBlockExpr; CloseScope(); CorrectAnonMethScope(blockExpr.ScopeSym); return(blockExpr); }
//------------------------------------------------------------ // MetaDataHelper.GetExplicitImplName // /// <summary> /// Get a synthesized name for explicit interface implementations. /// The name we use is: "InterfaceName.MethodName", where InterfaceName is the fully qualified name /// of the interface containing the implemented method. /// This name has a '.' in it, so it can't conflict with any "real" name or be confused with one. /// </summary> /// <remarks> /// Returns true if the buffer had enough space for the name. /// If not enough space, then adds as much of name as possible to buffer. /// Always NULL terminates buffer. /// </remarks> /// <param name="sym"></param> /// <param name="strBuilder"></param> //------------------------------------------------------------ public void GetExplicitImplName(SYM sym, StringBuilder strBuilder) { DebugUtil.Assert(sym.IsEVENTSYM || sym.IsMETHPROPSYM); SymWithType swtImpl = new SymWithType(); ERRORSYM errSym = null; string implName = null; string aliasName = null; switch (sym.Kind) { case SYMKIND.EVENTSYM: EVENTSYM eventSym = sym as EVENTSYM; DebugUtil.Assert(eventSym.IsExpImpl); swtImpl = eventSym.SlotEventWithType; errSym = eventSym.ExpImplErrorSym; break; case SYMKIND.METHSYM: case SYMKIND.PROPSYM: { METHPROPSYM mpSym = sym as METHPROPSYM; DebugUtil.Assert(mpSym.IsExplicitImplementation); swtImpl = mpSym.SlotSymWithType; errSym = mpSym.ExpImplErrorSym; BASENODE nameNode = null; if (sym.IsMETHSYM && (sym as METHSYM).ParseTreeNode != null && (sym as METHSYM).ParseTreeNode.Kind == NODEKIND.METHOD) { nameNode = ((sym as METHSYM).ParseTreeNode as METHODNODE).NameNode; } else if ( sym.IsPROPSYM && (sym as PROPSYM).ParseTreeNode != null && (sym as PROPSYM).ParseTreeNode.Kind == NODEKIND.PROPERTY) { nameNode = ((sym as PROPSYM).ParseTreeNode as PROPERTYNODE).NameNode; } while (nameNode != null && nameNode.Kind == NODEKIND.DOT) { nameNode = nameNode.AsDOT.Operand1; } if (nameNode != null && nameNode.Kind == NODEKIND.ALIASNAME) { aliasName = nameNode.AsANYNAME.Name; } if (!sym.IsPROPSYM || !(sym as PROPSYM).IsIndexer) { break; } implName = (swtImpl != null ? (swtImpl.Sym as PROPSYM).GetRealName() : "Item"); // fish out any user specified alias break; } default: // gcc -Wall (all warnings enabled) complains if all cases // aren't handled, so we explicitly handle default and assert DebugUtil.Assert(false); break; } DebugUtil.Assert(swtImpl != null || errSym != null); if (aliasName != null) { strBuilder.Append(aliasName); strBuilder.Append("::"); } if (swtImpl != null) { GetExplicitImplTypeName(swtImpl.AggTypeSym, strBuilder); if (implName == null) { implName = swtImpl.Sym.Name; } } else { GetExplicitImplTypeName(errSym, strBuilder); } if (implName != null) { // Add dot seperator. strBuilder.Append('.'); strBuilder.Append(implName); } }
//------------------------------------------------------------ // FUNCBREC.BindObjectInitializer // /// <summary></summary> /// <param name="newNode"></param> /// <param name="typeSym"></param> /// <param name="locVarSym"></param> /// <param name="objectExpr"></param> /// <param name="builder"></param> /// <returns></returns> //------------------------------------------------------------ internal EXPR BindObjectInitializer( NEWNODE newNode, TYPESYM typeSym, LOCVARSYM locVarSym, EXPR objectExpr, StatementListBuilder builder) { DebugUtil.Assert(newNode != null && typeSym != null && builder != null); DebugUtil.Assert( (locVarSym != null && objectExpr == null) || (locVarSym == null && objectExpr != null)); BindFlagsEnum bindFlags = BindFlagsEnum.RValueRequired; string localFormat = "<{0}><{1}>__local"; //-------------------------------------------------------- // Bind the local variable. //-------------------------------------------------------- if (locVarSym == null) { string typeName = typeSym.IsAGGTYPESYM ? (typeSym as AGGTYPESYM).GetAggregate().Name : typeSym.Name; string locName = String.Format(localFormat, typeName, (this.localCount)++); locVarSym = Compiler.LocalSymbolManager.CreateLocalSym( SYMKIND.LOCVARSYM, locName, this.currentScopeSym) as LOCVARSYM; locVarSym.TypeSym = typeSym; locVarSym.LocSlotInfo.HasInit = true; locVarSym.DeclTreeNode = newNode; StoreInCache(newNode, locName, locVarSym, null, true); } EXPR locVarExpr = BindToLocal( newNode, locVarSym, bindFlags | BindFlagsEnum.MemberSet); //-------------------------------------------------------- // If objectExpr is not null, assign it to the local variable. //-------------------------------------------------------- if (objectExpr != null) { EXPR assignLocExpr = BindAssignment( newNode, locVarExpr, objectExpr, false); builder.Add(SetNodeStmt(newNode, MakeStmt(newNode, assignLocExpr, 0))); } //-------------------------------------------------------- // Assign each value. //-------------------------------------------------------- DECLSTMTNODE decNode = newNode.InitialNode as DECLSTMTNODE; DebugUtil.Assert(decNode != null); BASENODE node = decNode.VariablesNode; while (node != null) { VARDECLNODE varDecl; if (node.Kind == NODEKIND.LIST) { varDecl = node.AsLIST.Operand1 as VARDECLNODE; node = node.AsLIST.Operand2; } else { varDecl = node as VARDECLNODE; node = null; } BINOPNODE assignNode = varDecl.ArgumentsNode as BINOPNODE; if (assignNode == null || assignNode.Operator != OPERATOR.ASSIGN || assignNode.Operand1 == null || assignNode.Operand1.Kind != NODEKIND.NAME || assignNode.Operand2 == null) { continue; } //---------------------------------------------------- // LHS //---------------------------------------------------- NAMENODE nameNode = assignNode.Operand1 as NAMENODE; DebugUtil.Assert(nameNode != null); bindFlags = BindFlagsEnum.MemberSet; MemberLookup mem = new MemberLookup(); EXPR leftExpr = null; if (mem.Lookup( Compiler, typeSym, locVarExpr, this.parentDeclSym, nameNode.Name, 0, MemLookFlagsEnum.UserCallable)) { SymWithType swt = mem.FirstSymWithType; DebugUtil.Assert(swt != null && swt.IsNotNull); switch (swt.Sym.Kind) { case SYMKIND.MEMBVARSYM: leftExpr = BindToField( assignNode, locVarExpr, FieldWithType.Convert(swt), bindFlags); break; case SYMKIND.PROPSYM: leftExpr = BindToProperty( assignNode, locVarExpr, PropWithType.Convert(swt), bindFlags, null, null); break; default: leftExpr = NewError(nameNode, null); break; } } else { mem.ReportErrors(nameNode); leftExpr = NewError(nameNode, null); } //---------------------------------------------------- // Collection initializer //---------------------------------------------------- if (assignNode.Operand2.Kind == NODEKIND.ARRAYINIT) { if (!leftExpr.TypeSym.IsARRAYSYM) { BindCollectionInitializer( newNode, (assignNode.Operand2 as UNOPNODE).Operand, leftExpr.TypeSym, //typeSym, null, //locVarSym, leftExpr, null, builder); continue; } } //---------------------------------------------------- // RHS //---------------------------------------------------- EXPR rightExpr = BindExpr( assignNode.Operand2, BindFlagsEnum.RValueRequired); //---------------------------------------------------- // Assign //---------------------------------------------------- EXPR assignExpr = BindAssignment( assignNode, leftExpr, rightExpr, false); builder.Add(SetNodeStmt(decNode, MakeStmt(decNode, assignExpr, 0))); } return(locVarExpr); }
//------------------------------------------------------------ // FUNCBREC.CreateAutoImplementedSetAccessor // /// <summary></summary> /// <param name="methodSym"></param> /// <returns></returns> //------------------------------------------------------------ internal EXPR CreateAutoImplementedSetAccessor(METHSYM methodSym) { CreateNewScope(); SCOPESYM scopeSym = this.currentScopeSym; this.currentScopeSym.ScopeFlags = SCOPEFLAGS.NONE; this.currentBlockExpr = NewExprBlock(treeNode); this.currentBlockExpr.ScopeSym = this.currentScopeSym; //-------------------------------------------------------- // Back filed //-------------------------------------------------------- SymWithType fieldSwt = new SymWithType(); AGGTYPESYM parentAts = methodSym.ParentAggSym.GetThisType(); fieldSwt.Set( methodSym.PropertySym.BackFieldSym, parentAts); EXPR fieldExpr = BindToField( null, BindThisImplicit(null), FieldWithType.Convert(fieldSwt), BindFlagsEnum.RValueRequired); //-------------------------------------------------------- // Parameter "value" //-------------------------------------------------------- // The SYM instance of parameter "value" is a LOCVARSYM instance, // and is created in CLSDREC.FillMethInfoCommon. LOCVARSYM locSym = Compiler.LocalSymbolManager.LookupLocalSym( Compiler.NameManager.GetPredefinedName(PREDEFNAME.VALUE), this.OuterScopeSym, SYMBMASK.LOCVARSYM) as LOCVARSYM; DebugUtil.Assert(locSym != null); SymWithType valueSwt = new SymWithType(); valueSwt.Set(locSym, null); EXPR valueExpr = BindToLocal(null, locSym, BindFlagsEnum.RValueRequired); //-------------------------------------------------------- // BackField = value //-------------------------------------------------------- EXPR assignExpr = NewExprBinop( null, EXPRKIND.ASSG, fieldExpr.TypeSym, fieldExpr, valueExpr); //-------------------------------------------------------- // Statement //-------------------------------------------------------- EXPRSTMTAS stmt = NewExpr(null, EXPRKIND.STMTAS, null) as EXPRSTMTAS; stmt.Expr = assignExpr; //-------------------------------------------------------- // Block //-------------------------------------------------------- this.currentBlockExpr.StatementsExpr = stmt; EXPRBLOCK blockExpr = this.currentBlockExpr; this.currentBlockExpr = blockExpr.OwingBlockExpr; CloseScope(); CorrectAnonMethScope(blockExpr.ScopeSym); return(blockExpr); }