Esempio n. 1
0
/* 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;
    }