//------------------------------------------------------------ // CParser.ParseObjectInitializer // /// <summary></summary> /// <param name="newNode"></param> //------------------------------------------------------------ internal void ParseObjectInitializer(NEWNODE newNode) { DebugUtil.Assert(CurrentTokenID() == TOKENID.OPENCURLY); NextToken(); DECLSTMTNODE stmtNode = AllocNode(NODEKIND.DECLSTMT, newNode) as DECLSTMTNODE; CListMaker list = new CListMaker(this); int comma = -1; while ( CurrentTokenID() != TOKENID.CLOSECURLY && CurrentTokenID() != TOKENID.ENDFILE) { if (CurrentTokenID() == TOKENID.IDENTIFIER && PeekToken(1) == TOKENID.EQUAL) { list.Add( ParseVariableDeclarator( stmtNode, stmtNode, (uint)PARSEDECLFLAGS.LOCAL, false, // isFirst, -1), comma); } else { Error(CSCERRID.ERR_InvalidInitializerDeclarator); TOKENID tid = CurrentTokenID(); while ( tid != TOKENID.COMMA && tid != TOKENID.CLOSECURLY && tid != TOKENID.ENDFILE) { NextToken(); tid = CurrentTokenID(); } } if (CurrentTokenID() != TOKENID.COMMA) { break; } comma = CurrentTokenIndex(); NextToken(); } Eat(TOKENID.CLOSECURLY); stmtNode.VariablesNode = list.GetList(stmtNode); newNode.InitialNode = stmtNode; newNode.Flags |= NODEFLAGS.NEW_HAS_OBJECT_INITIALIZER; if (newNode.ParentNode != null && newNode.ParentNode.Kind == NODEKIND.VARDECL) { VARDECLNODE vdNode = newNode.ParentNode as VARDECLNODE; if (vdNode != null) { newNode.Flags |= NODEFLAGS.NEW_IN_VARDECL; vdNode.NewFlags |= NODEFLAGS.NEW_HAS_OBJECT_INITIALIZER; } } else if (newNode.ParentNode != null && newNode.ParentNode.Kind == NODEKIND.BINOP && newNode.Operator == OPERATOR.ASSIGN) { VARDECLNODE vdNode = newNode.ParentNode.ParentNode as VARDECLNODE; if (vdNode != null) { newNode.Flags |= NODEFLAGS.NEW_IN_VARDECL; vdNode.NewFlags |= NODEFLAGS.NEW_HAS_OBJECT_INITIALIZER; } } BASENODE node = newNode.ParentNode; while (node != null && !node.IsStatement) { node = node.ParentNode; } if (node != null) { (node as STATEMENTNODE).NewFlags |= NODEFLAGS.NEW_HAS_OBJECT_INITIALIZER; } }
//------------------------------------------------------------ // 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); }