/* Production 27 chapter 3.4, corba 2.3.1 */ public void const_dcl() { /*@bgen(jjtree) const_dcl */ ASTconst_dcl jjtn000 = new ASTconst_dcl(this, IDLParserTreeConstants.JJTCONST_DCL); bool jjtc000 = true; jjtree.openNodeScope(jjtn000);String ident = ""; try { jj_consume_token(32); const_type(); switch ((jj_ntk==-1)?jj_ntk_calc():jj_ntk) { case IDLParserConstants.ID: ident = identifier(); break; case 33: jj_consume_token(33); ident = "NotANumber"; break; default: jj_la1[32] = jj_gen; jj_consume_token(-1); throw new ParseException(); break; } jj_consume_token(34); const_exp(); jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; jjtn000.setIdent(ident); Scope currentScope = m_symbolTable.getCurrentScope(); currentScope.addSymbolValue(ident); } catch (Exception jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } {if (true) throw ;} } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } } }
/** * @see parser.IDLParserVisitor#visit(ASTconst_dcl, Object) * @param data expects a BuildInfo instance * The following two cases are possible here: * constant directly declared in module: ((BuildInfo)data).GetContainerType() is null * constant declared in an interface or value type: ((BuildInfo)data).GetContainerType() is not null * * remark: fields in interfaces are not CLS-compliant! */ public Object visit(ASTconst_dcl node, Object data) { CheckParameterForBuildInfo(data, node); BuildInfo buildInfo = (BuildInfo)data; Scope enclosingScope = buildInfo.GetBuildScope(); SymbolValue constSymbol = (SymbolValue)enclosingScope.getSymbol(node.getIdent()); // check if type is known from a previous run over a parse tree --> if so: skip // not needed to check if const is nested inside a type, because parent type should already be skipped // --> code generation for all nested types skipped too if (m_typeManager.CheckSkip(constSymbol)) { return null; } TypeContainer constType = (TypeContainer)node.jjtGetChild(0).jjtAccept(this, data); Literal val = (Literal)node.jjtGetChild(1).jjtAccept(this, data); if (val == null) { throw new InvalidIdlException("constant can't be evaluated: " + constSymbol.getSymbolName()); } // set the value of the constant: constSymbol.SetValueAsLiteral(val); TypeBuilder constContainer = m_typeManager.StartTypeDefinition(constSymbol, TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Public, typeof(System.Object), new System.Type[] { typeof(IIdlEntity) }, false); string constFieldName = "ConstVal"; FieldBuilder constField; if (CanSetConstantValue(constType.GetSeparatedClsType())) { // possible as constant field constField = m_ilEmitHelper.AddFieldWithCustomAttrs(constContainer, constFieldName, constType, FieldAttributes.Static | FieldAttributes.Literal | FieldAttributes.Public); constField.SetConstant(val.GetValueToAssign(constType.GetSeparatedClsType(), constType.GetAssignableFromType())); } else { // not possible as constant -> use a readonly static field instead of a constant constField = m_ilEmitHelper.AddFieldWithCustomAttrs(constContainer, constFieldName, constType, FieldAttributes.Static | FieldAttributes.InitOnly | FieldAttributes.Public); // add static initalizer to assign value ConstructorBuilder staticInit = constContainer.DefineConstructor(MethodAttributes.Private | MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes); ILGenerator constrIl = staticInit.GetILGenerator(); val.EmitLoadValue(constrIl, constType.GetSeparatedClsType(), constType.GetAssignableFromType()); constrIl.Emit(OpCodes.Stsfld, constField); constrIl.Emit(OpCodes.Ret); } // add private default constructor constContainer.DefineDefaultConstructor(MethodAttributes.Private); // create the type m_typeManager.EndTypeDefinition(constSymbol); return null; }