Inheritance: Microsoft.JScript.Binding
 internal VariableDeclaration(Context context, Lookup identifier, TypeExpression type, AST initializer, FieldAttributes attributes, CustomAttributeList customAttributes)
   : base(context) {
   if (initializer != null)
     this.context.UpdateWith(initializer.context);
   else if (type != null)
     this.context.UpdateWith(type.context);
   this.identifier = identifier;
   this.type = type;
   this.initializer = initializer;
   ScriptObject current_scope = (ScriptObject)Globals.ScopeStack.Peek();
   while (current_scope is WithObject) //Can only happen at run time and only if there is an eval
     current_scope = current_scope.GetParent();
   String name = this.identifier.ToString();
   if (current_scope is ClassScope){
     if (name == ((ClassScope)current_scope).name){
       identifier.context.HandleError(JSError.CannotUseNameOfClass);
       name = name + " var";
     }
   }else{
     if (attributes != (FieldAttributes)0){
       this.context.HandleError(JSError.NotInsideClass);
       attributes = FieldAttributes.Public;
     }else
       attributes |= FieldAttributes.Public;
   }
   FieldInfo field = ((IActivationObject)current_scope).GetLocalField(name);
   if (field != null){
     if (field.IsLiteral || current_scope is ClassScope || type != null)
       identifier.context.HandleError(JSError.DuplicateName, true);
     this.type = type = null;
   }
   if (current_scope is ActivationObject)
     if (field == null || field is JSVariableField)
       this.field = ((ActivationObject)current_scope).AddFieldOrUseExistingField(this.identifier.ToString(), Missing.Value, attributes);
     else
       this.field = ((ActivationObject)current_scope).AddNewField(this.identifier.ToString(), null, attributes);
   else
     this.field = ((StackFrame)current_scope).AddNewField(this.identifier.ToString(), null, attributes|FieldAttributes.Static);
   this.field.type = type;
   this.field.customAttributes = customAttributes;
   this.field.originalContext = context;
   if (this.field is JSLocalField)
     // emit debug info for the local only if this block of code is in a section that has debug set
     ((JSLocalField)this.field).debugOn = this.identifier.context.document.debugOn;
   this.completion = new Completion();
 }
 internal Constant(Context context, Lookup identifier, TypeExpression type, AST value, FieldAttributes attributes, CustomAttributeList customAttributes)
   : base(context){
   this.attributes = attributes | FieldAttributes.InitOnly;
   this.customAttributes = customAttributes;
   this.completion = new Completion();
   this.identifier = identifier;
   this.name = identifier.ToString();
   this.value = value;
   ScriptObject current_scope = (ScriptObject)Globals.ScopeStack.Peek();
   while (current_scope is WithObject) //Can only happen at run time and only if there is an eval
     current_scope = current_scope.GetParent();
   if (current_scope is ClassScope){
     if (this.name == ((ClassScope)current_scope).name){
       identifier.context.HandleError(JSError.CannotUseNameOfClass);
       this.name = this.name + " const";
     }
     if (attributes == 0) attributes = FieldAttributes.Public;
   }else{
     if (attributes != 0)
       this.context.HandleError(JSError.NotInsideClass);
     attributes = FieldAttributes.Public;
   }
   FieldInfo field = ((IActivationObject)current_scope).GetLocalField(this.name);
   if (field != null){
     identifier.context.HandleError(JSError.DuplicateName, true);
     this.name = this.name + " const";
   }
   if (current_scope is ActivationObject)
     this.field = ((ActivationObject)current_scope).AddNewField(this.identifier.ToString(), value, attributes);
   else
     this.field = ((StackFrame)current_scope).AddNewField(this.identifier.ToString(), value, attributes|FieldAttributes.Static);
   this.field.type = type;
   this.field.customAttributes = customAttributes;
   this.field.originalContext = context;
   if (this.field is JSLocalField)
     // emit debug info for the local only if this block of code is in a section that has debug set
     ((JSLocalField)this.field).debugOn = this.identifier.context.document.debugOn;
 }
Exemple #3
0
 //---------------------------------------------------------------------------------------
 // ParseEnumMember
 //
 //  OptionalEnumMembers:
 //    EnumMember ',' OptionalEnumMembers |
 //    <empty>
 //
 //  EnumMember :
 //    Identifier |
 //    Identifer '=' IntegerLiteral
 //
 //---------------------------------------------------------------------------------------
 private AST ParseEnumMember(){
   AST ast = null;
   Lookup memberName = null;
   AST memberValue = null;
   switch (this.currentToken.token){
     case JSToken.Semicolon:
       GetNextToken();
       return ParseEnumMember();
     case JSToken.Identifier:
       memberName = new Lookup(this.currentToken.Clone());
       Context context = this.currentToken.Clone();
       GetNextToken();
       if (JSToken.Assign == this.currentToken.token){
         GetNextToken();
         memberValue = ParseExpression(true);
       }
       if (JSToken.Comma == this.currentToken.token)
         GetNextToken();
       else if (JSToken.RightCurly != this.currentToken.token)
         ReportError(JSError.NoComma, true);
       return new Constant(context, memberName, null, memberValue, FieldAttributes.Public, null);
     case JSToken.Var:
       // handle common error
       ReportError(JSError.NoVarInEnum, true);
       GetNextToken();
       return ParseEnumMember();
     default:
       ReportError(JSError.SyntaxError, true);
       SkipTokensAndThrow();
       return ast; // will never be executed, but make the C# compiler happy
   }
 }
Exemple #4
0
      private AST ParseFunction(FieldAttributes visibilitySpec,
                                bool inExpression,
                                Context fncCtx,
                                bool isMethod,
                                bool isAbstract,
                                bool isFinal,
                                bool isInterface,
                                CustomAttributeList customAttributes,
                                Call function){
        IdentifierLiteral name = null;
        AST interfaceName = null;
        ArrayList formalParameters = null;
        TypeExpression returnType = null;
        Block body = null;
        bool isGetter = false;
        bool isSetter = false;

        if (function == null){
          GetNextToken();
          if (isMethod)
            if (JSToken.Get == this.currentToken.token){
              isGetter = true;
              GetNextToken();
            }else if (JSToken.Set == this.currentToken.token){
              isSetter = true;
              GetNextToken();
            }

          // get the function name or make an anonymous function if in expression "position"
          if (JSToken.Identifier == this.currentToken.token){
            name = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone());
            GetNextToken();
            if (JSToken.AccessField == this.currentToken.token){
              if (isInterface) // "function IBar.foo()" is illegal in an interface declaration
                ReportError(JSError.SyntaxError, true);
              GetNextToken();
              if (JSToken.Identifier == this.currentToken.token){
                interfaceName = new Lookup(name.context);
                name = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone());
                GetNextToken();
                while (JSToken.AccessField == this.currentToken.token){
                  GetNextToken();
                  if (JSToken.Identifier == this.currentToken.token){
                    interfaceName = new Member(interfaceName.context.CombineWith(this.currentToken), interfaceName,
                      new ConstantWrapper(name.ToString(), name.context));
                    name = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone());
                    GetNextToken();
                  }else
                    ReportError(JSError.NoIdentifier, true);
                }
              }else
                ReportError(JSError.NoIdentifier, true);
            }
          }else{
            string identifier = JSKeyword.CanBeIdentifier(this.currentToken.token);
            if (null != identifier){
              ForceReportInfo(JSError.KeywordUsedAsIdentifier, isMethod);
              name = new IdentifierLiteral(identifier, this.currentToken.Clone());
              GetNextToken();
            }else{
              if (!inExpression){
                identifier = this.currentToken.GetCode();
                ReportError(JSError.NoIdentifier, true);
                GetNextToken();
              }else
                identifier = "";
              name = new IdentifierLiteral(identifier, CurrentPositionContext());
            }
          }
        }else{ // function was passed in, this is an error condition
          name = function.GetName();
        }

        // make a new state and save the old one
        ArrayList blockType = this.blockType;
        this.blockType = new ArrayList(16);
        SimpleHashtable labelTable = this.labelTable;
        this.labelTable = new SimpleHashtable(16);
        FunctionScope fscope = new FunctionScope(Globals.ScopeStack.Peek(), isMethod);
        Globals.ScopeStack.Push(fscope); //Give declarations a place to go while building AST

        try{
          formalParameters = new ArrayList();
          Context paramArrayContext = null;
          if (function == null){
            // get the formal parameters
            if (JSToken.LeftParen != this.currentToken.token)
              ReportError(JSError.NoLeftParen);
            GetNextToken();
            // create the list of arguments and update the context
            while (JSToken.RightParen != this.currentToken.token){
              if (paramArrayContext != null){
                ReportError(JSError.ParamListNotLast, paramArrayContext, true);
                paramArrayContext = null;
              }
              String id = null;
              TypeExpression typeExpr = null;
              this.noSkipTokenSet.Add(NoSkipTokenSet.s_FunctionDeclNoSkipTokenSet);
              try{
                if (JSToken.ParamArray == this.currentToken.token){
                  paramArrayContext = this.currentToken.Clone();
                  GetNextToken();
                }
                if (JSToken.Identifier != this.currentToken.token && (id = JSKeyword.CanBeIdentifier(this.currentToken.token)) == null){
                  if (JSToken.LeftCurly == this.currentToken.token){
                    ReportError(JSError.NoRightParen);
                    break;
                  }else if (JSToken.Comma == this.currentToken.token){
                    // We're missing an argument (or previous argument was malformed and
                    // we skipped to the comma.)  Keep trying to parse the argument list --
                    // we will skip the comma below.
                    ReportError(JSError.SyntaxError, true);
                  }else{
                    ReportError(JSError.SyntaxError, true);
                    SkipTokensAndThrow();
                  }
                }else{
                  if (null == id)
                    id = this.scanner.GetIdentifier();
                  else
                    ForceReportInfo(JSError.KeywordUsedAsIdentifier);
                  Context paramCtx = this.currentToken.Clone();
                  GetNextToken();
                  if (JSToken.Colon == this.currentToken.token){
                    typeExpr = ParseTypeExpression();
                    if (null != typeExpr)
                      paramCtx.UpdateWith(typeExpr.context);
                  }
                  
                  
                  CustomAttributeList custAttrs = null;
                  if (paramArrayContext != null){
                    custAttrs = new CustomAttributeList(paramArrayContext);
                    custAttrs.Append(new CustomAttribute(paramArrayContext, new Lookup("...", paramArrayContext), new ASTList(null)));
                  }
                  formalParameters.Add(new ParameterDeclaration(paramCtx, id, typeExpr, custAttrs));
                }

                // got an arg, it should be either a ',' or ')'
                if (JSToken.RightParen == this.currentToken.token)
                  break;
                else if (JSToken.Comma != this.currentToken.token){
                  // deal with error in some "intelligent" way
                  if (JSToken.LeftCurly == this.currentToken.token){
                    ReportError(JSError.NoRightParen);
                    break;
                  }else{
                    if (JSToken.Identifier == this.currentToken.token && typeExpr == null){
                      // it's possible that the guy was writing the type in C/C++ style (i.e. int x)
                      ReportError(JSError.NoCommaOrTypeDefinitionError);
                    }else
                      ReportError(JSError.NoComma);
                  }
                }
                GetNextToken();
              }catch(RecoveryTokenException exc){
                if (IndexOfToken(NoSkipTokenSet.s_FunctionDeclNoSkipTokenSet, exc) == -1)
                  throw exc;
              }finally{
                this.noSkipTokenSet.Remove(NoSkipTokenSet.s_FunctionDeclNoSkipTokenSet);
              }
            }
            fncCtx.UpdateWith(this.currentToken);
            // if it is a getter/setter must have 0/1 arg only
            if (isGetter && formalParameters.Count != 0){
              ReportError(JSError.BadPropertyDeclaration, true);
              isGetter = false;
            }else if (isSetter && formalParameters.Count != 1){
              ReportError(JSError.BadPropertyDeclaration, true);
              isSetter = false;
            }
            GetNextToken();

            // check the return type
            if (JSToken.Colon == this.currentToken.token){
              if (isSetter)
                ReportError(JSError.SyntaxError);
              this.noSkipTokenSet.Add(NoSkipTokenSet.s_StartBlockNoSkipTokenSet);
              try{
                returnType = ParseTypeExpression();
              }catch(RecoveryTokenException exc){
                if (IndexOfToken(NoSkipTokenSet.s_StartBlockNoSkipTokenSet, exc) == -1){
                  exc._partiallyComputedNode = null;
                  throw exc;
                }else{
                  if (exc._partiallyComputedNode != null)
                    returnType = (TypeExpression)exc._partiallyComputedNode;
                }
              }finally{
                this.noSkipTokenSet.Remove(NoSkipTokenSet.s_StartBlockNoSkipTokenSet);
              }
              if (isSetter)
                returnType = null;
            }
          }else{ // function was passed in, this is an error condition
            function.GetParameters(formalParameters);
          }

          // read the function body of non-abstract functions.

          if (JSToken.LeftCurly != this.currentToken.token && (isAbstract || (isMethod && GuessIfAbstract()))){
            if (!isAbstract){
              isAbstract = true;
              ReportError(JSError.ShouldBeAbstract, fncCtx, true);
            }
            body = new Block(this.currentToken.Clone());
          }else{
            if (JSToken.LeftCurly != this.currentToken.token)
              ReportError(JSError.NoLeftCurly, true);
            else if (isAbstract)
              ReportError(JSError.AbstractWithBody, fncCtx, true);

            this.blockType.Add(BlockType.Block);
            this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockNoSkipTokenSet);
            this.noSkipTokenSet.Add(NoSkipTokenSet.s_StartStatementNoSkipTokenSet);
            try{
              // parse the block locally to get the exact end of function
              body = new Block(this.currentToken.Clone());
              GetNextToken();

              while (JSToken.RightCurly != this.currentToken.token){
                try{
                  body.Append(ParseStatement());
                }catch(RecoveryTokenException exc){
                  if (exc._partiallyComputedNode != null){
                    body.Append(exc._partiallyComputedNode);
                  }
                  if (IndexOfToken(NoSkipTokenSet.s_StartStatementNoSkipTokenSet, exc) == -1)
                    throw exc;
                }
              }

              body.context.UpdateWith(this.currentToken);
              fncCtx.UpdateWith(this.currentToken);
            }catch(RecoveryTokenException exc){
              if (IndexOfToken(NoSkipTokenSet.s_BlockNoSkipTokenSet, exc) == -1){
                Globals.ScopeStack.Pop(); //Pop current scope so that FunctionDeclaration sees proper scope stack
                try{
                  ParameterDeclaration[] foParameters = new ParameterDeclaration[formalParameters.Count]; formalParameters.CopyTo(foParameters);
                  if (inExpression)
                    exc._partiallyComputedNode =
                      new FunctionExpression(fncCtx, name, foParameters, returnType, body, fscope, visibilitySpec);
                  else
                    exc._partiallyComputedNode =
                      new FunctionDeclaration(fncCtx, interfaceName, name, foParameters, returnType, body, fscope, visibilitySpec,
                      isMethod, isGetter, isSetter, isAbstract, isFinal, customAttributes);
                  if (customAttributes != null) customAttributes.SetTarget(exc._partiallyComputedNode);
                }finally{
                  Globals.ScopeStack.Push(fscope); //Push it back so that the next finally can pop it
                }
                throw exc;
              }
            }finally{
              this.blockType.RemoveAt(this.blockType.Count - 1);
              this.noSkipTokenSet.Remove(NoSkipTokenSet.s_StartStatementNoSkipTokenSet);
              this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockNoSkipTokenSet);
            }

            GetNextToken();
          }
        }finally{
          // restore state
          this.blockType = blockType;
          this.labelTable = labelTable;
          Globals.ScopeStack.Pop();
        }

        ParameterDeclaration[] fParameters = new ParameterDeclaration[formalParameters.Count]; formalParameters.CopyTo(fParameters);
        AST func;
        if (inExpression)
          func = new FunctionExpression(fncCtx, name, fParameters, returnType, body, fscope, visibilitySpec);
        else
          func = new FunctionDeclaration(fncCtx, interfaceName, name, fParameters, returnType, body, fscope, visibilitySpec,
                                         isMethod, isGetter, isSetter, isAbstract, isFinal, customAttributes);

        if (customAttributes != null) customAttributes.SetTarget(func);
        return func;

      }
Exemple #5
0
      //---------------------------------------------------------------------------------------
      // ParseQualifiedIdentifier
      //
      //  QualifiedIdentifier :
      //    'double' | 'float' | 'int' | 'long' | Scope Identifier
      //
      //  Scope
      //    <empty> |
      //    Identifier '.' Scope
      //
      // The argument error is passed by the caller and it is used in error situation
      // to provide better error information. The caller knows in which context this
      // qualified identifier is parsed (i.e. var x : QualifiedIdentifier vs.
      // import QualifiedIdentifier)
      // On error condition this method may return null. Regardless of its return value, though,
      // this method will always be pointing to the next token and no error token will be set.
      //---------------------------------------------------------------------------------------
      private AST ParseQualifiedIdentifier(JSError error){
        GetNextToken();
        AST qualid = null;
        string identifier = null;
        Context idContext = this.currentToken.Clone();
        if (JSToken.Identifier != this.currentToken.token){
          identifier = JSKeyword.CanBeIdentifier(this.currentToken.token);
          if (null != identifier){
            switch (this.currentToken.token){
              case JSToken.Boolean :
              case JSToken.Byte :
              case JSToken.Char :
              case JSToken.Double :
              case JSToken.Float :
              case JSToken.Int :
              case JSToken.Long :
              case JSToken.Short :
              case JSToken.Void :
                break;
              default:
                ForceReportInfo(JSError.KeywordUsedAsIdentifier);
                break;
            }
            qualid = new Lookup(identifier, idContext);
          }else{
            ReportError(error, true);
            SkipTokensAndThrow(); // this will always throw
          }
        }else{
          qualid = new Lookup(this.scanner.GetIdentifier(), idContext);
        }
        GetNextToken();
        if (JSToken.AccessField == this.currentToken.token)
          qualid = ParseScopeSequence(qualid, error);

        return qualid;
      }
Exemple #6
0
      //---------------------------------------------------------------------------------------
      // ParseTryStatement
      //
      //  TryStatement :
      //    'try' Block CatchList Finally
      //
      //  CatchList :
      //    <empty> |
      //    CatchList Catch
      //
      //  Catch :
      //    'catch' '(' Identifier Type ')' Block
      //
      //  Finally :
      //    <empty> |
      //    'finally' Block
      //---------------------------------------------------------------------------------------
      private AST ParseTryStatement(){
        Context tryCtx = this.currentToken.Clone();
        Context tryEndContext = null;
        AST body = null;
        AST id = null;
        AST handler = null;
        AST finally_block = null;
        RecoveryTokenException excInFinally = null;
        TypeExpression type = null;
        this.blockType.Add(BlockType.Block);
        try{
          bool catchOrFinally = false;
          bool foundCatchAll = false;
          GetNextToken();
          if (JSToken.LeftCurly != this.currentToken.token)
            ReportError(JSError.NoLeftCurly);
          this.noSkipTokenSet.Add(NoSkipTokenSet.s_NoTrySkipTokenSet);
          try{
            body = ParseBlock(out tryEndContext);
          }catch(RecoveryTokenException exc){
            if (IndexOfToken(NoSkipTokenSet.s_NoTrySkipTokenSet, exc) == -1)
              // do nothing and just return the containing block, if any
              throw exc;
            else
              body = exc._partiallyComputedNode;
          }finally{
            this.noSkipTokenSet.Remove(NoSkipTokenSet.s_NoTrySkipTokenSet);
          }
          while (JSToken.Catch == this.currentToken.token){
            this.noSkipTokenSet.Add(NoSkipTokenSet.s_NoTrySkipTokenSet);
            try{
              if (handler != null){
                body = new Try(tryCtx, body, id, type, handler, null, false, tryEndContext);
                id = null;
                type = null;
                handler = null;
              }
              catchOrFinally = true;
              GetNextToken();
              if (JSToken.LeftParen != this.currentToken.token)
                ReportError(JSError.NoLeftParen);
              GetNextToken();
              if (JSToken.Identifier != this.currentToken.token){
                string identifier = JSKeyword.CanBeIdentifier(this.currentToken.token);
                if (null != identifier){
                  ForceReportInfo(JSError.KeywordUsedAsIdentifier);
                  id = new Lookup(identifier, this.currentToken.Clone());
                }else{
                  ReportError(JSError.NoIdentifier);
                  id = new Lookup("##Exc##" + s_cDummyName++, CurrentPositionContext());
                }
              }else
                id = new Lookup(this.scanner.GetIdentifier(), this.currentToken.Clone());
              GetNextToken();
              this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet);
              try{
                if (JSToken.Colon == this.currentToken.token)
                  type = ParseTypeExpression();
                else{
                  if (foundCatchAll) //no point in having another
                    ForceReportInfo(id.context, JSError.UnreachableCatch);
                  foundCatchAll = true;
                }
                if (JSToken.RightParen != this.currentToken.token)
                  ReportError(JSError.NoRightParen);
                GetNextToken();
              }catch(RecoveryTokenException exc){
                if (IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exc) == -1){
                  exc._partiallyComputedNode = null;
                  // rethrow
                  throw exc;
                }else{
                  type = (TypeExpression)exc._partiallyComputedNode;
                  if (this.currentToken.token == JSToken.RightParen)
                    GetNextToken();
                }
              }finally{
                this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet);
              }
              if (JSToken.LeftCurly != this.currentToken.token)
                ReportError(JSError.NoLeftCurly);
              handler = ParseBlock();
              tryCtx.UpdateWith(handler.context);
            }catch(RecoveryTokenException exc){
              if (exc._partiallyComputedNode == null)
                handler = new Block(CurrentPositionContext());
              else
                handler = exc._partiallyComputedNode;
              if (IndexOfToken(NoSkipTokenSet.s_NoTrySkipTokenSet, exc) == -1){
                Debug.Assert((type == null) ? exc._partiallyComputedNode == null : true);
                if (type != null)
                  exc._partiallyComputedNode = new Try(tryCtx, body, id, type, handler, null, false, tryEndContext);
                throw exc;
              }
            }finally{
              this.noSkipTokenSet.Remove(NoSkipTokenSet.s_NoTrySkipTokenSet);
            }
          }

          try{
            if (JSToken.Finally == this.currentToken.token){
              GetNextToken();
              this.blockType.Add(BlockType.Finally);
              try{
                finally_block = ParseBlock();
                catchOrFinally = true;
              }finally{
                this.blockType.RemoveAt(this.blockType.Count - 1);
              }
              tryCtx.UpdateWith(finally_block.context);
            }
          }catch(RecoveryTokenException exc){
            excInFinally = exc; // thrown later so we can execute code below
          }

          if (!catchOrFinally){
            ReportError(JSError.NoCatch, true);
            finally_block = new Block(CurrentPositionContext()); // make a dummy empty block
          }
        }finally{
          this.blockType.RemoveAt(this.blockType.Count - 1);
        }

        bool isFinallyEscaped = false;
        if (this.finallyEscaped > 0){
          this.finallyEscaped--;
          isFinallyEscaped = true;
        }
        if (excInFinally != null){
          excInFinally._partiallyComputedNode = new Try(tryCtx, body, id, type, handler, finally_block, isFinallyEscaped, tryEndContext);
          throw excInFinally;
        }else
          return new Try(tryCtx, body, id, type, handler, finally_block, isFinallyEscaped, tryEndContext);
      }
Exemple #7
0
      //---------------------------------------------------------------------------------------
      // ParseIdentifierInitializer
      //
      //  Does the real work of parsing a single variable declaration.
      //  inToken is JSToken.In whenever the potential expression that initialize a variable
      //  cannot contain an 'in', as in the for statement. inToken is JSToken.None otherwise
      //---------------------------------------------------------------------------------------
      private AST ParseIdentifierInitializer(JSToken inToken,
                                                              FieldAttributes visibility,
                                                              CustomAttributeList customAttributes,
                                                              JSToken kind){
        Lookup id = null;
        TypeExpression typeExpr = null;
        AST assignmentExpr = null;
        RecoveryTokenException except = null;

        GetNextToken();
        if (JSToken.Identifier != this.currentToken.token){
          String identifier = JSKeyword.CanBeIdentifier(this.currentToken.token);
          if (null != identifier){
            ForceReportInfo(JSError.KeywordUsedAsIdentifier);
            id = new Lookup(identifier, this.currentToken.Clone());
          }else{
            // make up an identifier and keep going; life goes on...
            ReportError(JSError.NoIdentifier);
            id = new Lookup("#_Missing Identifier_#" + s_cDummyName++, CurrentPositionContext());
          }
        }else
          id = new Lookup(this.scanner.GetIdentifier(), this.currentToken.Clone());
        GetNextToken();
        Context context = id.context.Clone();

        this.noSkipTokenSet.Add(NoSkipTokenSet.s_VariableDeclNoSkipTokenSet);
        try{
          if (JSToken.Colon == this.currentToken.token){
            try{
              typeExpr = ParseTypeExpression();
            }catch(RecoveryTokenException exc){
              typeExpr = (TypeExpression)exc._partiallyComputedNode;
              throw exc;
            }finally{
              if (null != typeExpr)
                context.UpdateWith(typeExpr.context);
            }
          }
              
          if (JSToken.Assign == this.currentToken.token || JSToken.Equal == this.currentToken.token){
            if (JSToken.Equal == this.currentToken.token)
              ReportError(JSError.NoEqual, true);
            GetNextToken();
            try{
              assignmentExpr = ParseExpression(true, inToken);
            }catch(RecoveryTokenException exc){
              assignmentExpr = exc._partiallyComputedNode;
              throw exc;
            }finally{
              if (null != assignmentExpr)
                context.UpdateWith(assignmentExpr.context);
            }
          }
        }catch(RecoveryTokenException exc){
          // If the exception is in the vardecl no-skip set then we successfully
          // recovered to the end of the declaration and can just return
          // normally.  Otherwise we re-throw after constructing the partial result.  
          if (IndexOfToken(NoSkipTokenSet.s_VariableDeclNoSkipTokenSet, exc) == -1)
            except = exc;
        }finally{
          this.noSkipTokenSet.Remove(NoSkipTokenSet.s_VariableDeclNoSkipTokenSet);
        }

        AST result = null;
        if (JSToken.Var == kind)
          result = new VariableDeclaration(context, id, typeExpr, assignmentExpr, visibility, customAttributes);
        else{
          if (assignmentExpr == null)
            ForceReportInfo(JSError.NoEqual);
          result = new Constant(context, id, typeExpr, assignmentExpr, visibility, customAttributes);
        }
        if (customAttributes != null)
          customAttributes.SetTarget(result);
        if (null != except){
          except._partiallyComputedNode = result;
          throw except;
        }
        return result;
      }
        private AST ParseLeftHandSideExpression(bool isMinus, ref bool canBeAttribute, bool warnForKeyword)
        {
            AST expression = null;
            Context context;
            ASTList list2;
            Context context2;
            ASTList list3;
            string str6;
            bool flag = false;
            ArrayList newContexts = null;
            while (JSToken.New == this.currentToken.token)
            {
                if (newContexts == null)
                {
                    newContexts = new ArrayList(4);
                }
                newContexts.Add(this.currentToken.Clone());
                this.GetNextToken();
            }
            JSToken token = this.currentToken.token;
            if (token <= JSToken.Divide)
            {
                switch (token)
                {
                    case JSToken.Function:
                        canBeAttribute = false;
                        expression = this.ParseFunction(FieldAttributes.PrivateScope, true, this.currentToken.Clone(), false, false, false, false, null);
                        flag = true;
                        goto Label_0956;

                    case JSToken.LeftCurly:
                    {
                        AST ast2;
                        canBeAttribute = false;
                        context2 = this.currentToken.Clone();
                        this.GetNextToken();
                        list3 = new ASTList(this.currentToken.Clone());
                        if (JSToken.RightCurly == this.currentToken.token)
                        {
                            goto Label_0830;
                        }
                    Label_05C9:
                        ast2 = null;
                        AST elem = null;
                        if (JSToken.Identifier == this.currentToken.token)
                        {
                            ast2 = new ConstantWrapper(this.scanner.GetIdentifier(), this.currentToken.Clone());
                        }
                        else if (JSToken.StringLiteral == this.currentToken.token)
                        {
                            ast2 = new ConstantWrapper(this.scanner.GetStringLiteral(), this.currentToken.Clone());
                        }
                        else if ((JSToken.IntegerLiteral == this.currentToken.token) || (JSToken.NumericLiteral == this.currentToken.token))
                        {
                            ast2 = new ConstantWrapper(Microsoft.JScript.Convert.ToNumber(this.currentToken.GetCode(), true, true, Microsoft.JScript.Missing.Value), this.currentToken.Clone());
                            ((ConstantWrapper) ast2).isNumericLiteral = true;
                        }
                        else
                        {
                            this.ReportError(JSError.NoMemberIdentifier);
                            ast2 = new IdentifierLiteral("_#Missing_Field#_" + s_cDummyName++, this.CurrentPositionContext());
                        }
                        ASTList list4 = new ASTList(ast2.context.Clone());
                        this.GetNextToken();
                        this.noSkipTokenSet.Add(NoSkipTokenSet.s_ObjectInitNoSkipTokenSet);
                        try
                        {
                            try
                            {
                                if (JSToken.Colon != this.currentToken.token)
                                {
                                    this.ReportError(JSError.NoColon, true);
                                    elem = this.ParseExpression(true);
                                }
                                else
                                {
                                    this.GetNextToken();
                                    elem = this.ParseExpression(true);
                                }
                                list4.Append(ast2);
                                list4.Append(elem);
                                list3.Append(list4);
                                if (JSToken.RightCurly == this.currentToken.token)
                                {
                                    goto Label_0830;
                                }
                                if (JSToken.Comma == this.currentToken.token)
                                {
                                    this.GetNextToken();
                                }
                                else
                                {
                                    if (this.scanner.GotEndOfLine())
                                    {
                                        this.ReportError(JSError.NoRightCurly);
                                    }
                                    else
                                    {
                                        this.ReportError(JSError.NoComma, true);
                                    }
                                    this.SkipTokensAndThrow();
                                }
                            }
                            catch (RecoveryTokenException exception4)
                            {
                                if (exception4._partiallyComputedNode != null)
                                {
                                    elem = exception4._partiallyComputedNode;
                                    list4.Append(ast2);
                                    list4.Append(elem);
                                    list3.Append(list4);
                                }
                                if (this.IndexOfToken(NoSkipTokenSet.s_ObjectInitNoSkipTokenSet, exception4) == -1)
                                {
                                    exception4._partiallyComputedNode = new ObjectLiteral(context2, list3);
                                    throw exception4;
                                }
                                if (JSToken.Comma == this.currentToken.token)
                                {
                                    this.GetNextToken();
                                }
                                if (JSToken.RightCurly == this.currentToken.token)
                                {
                                    goto Label_0830;
                                }
                            }
                            goto Label_05C9;
                        }
                        finally
                        {
                            this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ObjectInitNoSkipTokenSet);
                        }
                        goto Label_0830;
                    }
                    case JSToken.Null:
                        canBeAttribute = false;
                        expression = new NullLiteral(this.currentToken.Clone());
                        goto Label_0956;

                    case JSToken.True:
                        canBeAttribute = false;
                        expression = new ConstantWrapper(true, this.currentToken.Clone());
                        goto Label_0956;

                    case JSToken.False:
                        canBeAttribute = false;
                        expression = new ConstantWrapper(false, this.currentToken.Clone());
                        goto Label_0956;

                    case JSToken.This:
                        canBeAttribute = false;
                        expression = new ThisLiteral(this.currentToken.Clone(), false);
                        goto Label_0956;

                    case JSToken.Identifier:
                        expression = new Lookup(this.scanner.GetIdentifier(), this.currentToken.Clone());
                        goto Label_0956;

                    case JSToken.StringLiteral:
                        canBeAttribute = false;
                        expression = new ConstantWrapper(this.scanner.GetStringLiteral(), this.currentToken.Clone());
                        goto Label_0956;

                    case JSToken.IntegerLiteral:
                    {
                        canBeAttribute = false;
                        object obj2 = Microsoft.JScript.Convert.LiteralToNumber(this.currentToken.GetCode(), this.currentToken);
                        if (obj2 == null)
                        {
                            obj2 = 0;
                        }
                        expression = new ConstantWrapper(obj2, this.currentToken.Clone());
                        ((ConstantWrapper) expression).isNumericLiteral = true;
                        goto Label_0956;
                    }
                    case JSToken.NumericLiteral:
                    {
                        canBeAttribute = false;
                        string str = isMinus ? ("-" + this.currentToken.GetCode()) : this.currentToken.GetCode();
                        expression = new ConstantWrapper(Microsoft.JScript.Convert.ToNumber(str, false, false, Microsoft.JScript.Missing.Value), this.currentToken.Clone());
                        ((ConstantWrapper) expression).isNumericLiteral = true;
                        goto Label_0956;
                    }
                    case JSToken.LeftParen:
                        canBeAttribute = false;
                        this.GetNextToken();
                        this.noSkipTokenSet.Add(NoSkipTokenSet.s_ParenExpressionNoSkipToken);
                        try
                        {
                            expression = this.ParseExpression();
                            if (JSToken.RightParen != this.currentToken.token)
                            {
                                this.ReportError(JSError.NoRightParen);
                            }
                        }
                        catch (RecoveryTokenException exception)
                        {
                            if (this.IndexOfToken(NoSkipTokenSet.s_ParenExpressionNoSkipToken, exception) == -1)
                            {
                                throw exception;
                            }
                            expression = exception._partiallyComputedNode;
                        }
                        finally
                        {
                            this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ParenExpressionNoSkipToken);
                        }
                        if (expression == null)
                        {
                            this.SkipTokensAndThrow();
                        }
                        goto Label_0956;

                    case JSToken.LeftBracket:
                        canBeAttribute = false;
                        context = this.currentToken.Clone();
                        list2 = new ASTList(this.currentToken.Clone());
                        this.GetNextToken();
                        if ((this.currentToken.token != JSToken.Identifier) || (this.scanner.PeekToken() != JSToken.Colon))
                        {
                            goto Label_0561;
                        }
                        this.noSkipTokenSet.Add(NoSkipTokenSet.s_BracketToken);
                        try
                        {
                            try
                            {
                                if (this.currentToken.GetCode() == "assembly")
                                {
                                    this.GetNextToken();
                                    this.GetNextToken();
                                    return new AssemblyCustomAttributeList(this.ParseCustomAttributeList());
                                }
                                this.ReportError(JSError.ExpectedAssembly);
                                this.SkipTokensAndThrow();
                            }
                            catch (RecoveryTokenException exception2)
                            {
                                exception2._partiallyComputedNode = new Block(context);
                                return exception2._partiallyComputedNode;
                            }
                            goto Label_0561;
                        }
                        finally
                        {
                            if (this.currentToken.token == JSToken.RightBracket)
                            {
                                this.errorToken = null;
                                this.GetNextToken();
                            }
                            this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BracketToken);
                        }
                        goto Label_046D;

                    case JSToken.Divide:
                    {
                        canBeAttribute = false;
                        string pattern = this.scanner.ScanRegExp();
                        if (pattern == null)
                        {
                            break;
                        }
                        bool flag2 = false;
                        try
                        {
                            new Regex(pattern, RegexOptions.ECMAScript);
                        }
                        catch (ArgumentException)
                        {
                            pattern = "";
                            flag2 = true;
                        }
                        string flags = this.scanner.ScanRegExpFlags();
                        if (flags == null)
                        {
                            expression = new RegExpLiteral(pattern, null, this.currentToken.Clone());
                        }
                        else
                        {
                            try
                            {
                                expression = new RegExpLiteral(pattern, flags, this.currentToken.Clone());
                            }
                            catch (JScriptException)
                            {
                                expression = new RegExpLiteral(pattern, null, this.currentToken.Clone());
                                flag2 = true;
                            }
                        }
                        if (flag2)
                        {
                            this.ReportError(JSError.RegExpSyntax, true);
                        }
                        goto Label_0956;
                    }
                }
                goto Label_0881;
            }
            if (token != JSToken.Super)
            {
                if (token == JSToken.PreProcessorConstant)
                {
                    canBeAttribute = false;
                    expression = new ConstantWrapper(this.scanner.GetPreProcessorValue(), this.currentToken.Clone());
                    goto Label_0956;
                }
                goto Label_0881;
            }
            canBeAttribute = false;
            expression = new ThisLiteral(this.currentToken.Clone(), true);
            goto Label_0956;
        Label_046D:
            if (JSToken.Comma != this.currentToken.token)
            {
                this.noSkipTokenSet.Add(NoSkipTokenSet.s_ArrayInitNoSkipTokenSet);
                try
                {
                    list2.Append(this.ParseExpression(true));
                    if (JSToken.Comma != this.currentToken.token)
                    {
                        if (JSToken.RightBracket != this.currentToken.token)
                        {
                            this.ReportError(JSError.NoRightBracket);
                        }
                        goto Label_0573;
                    }
                }
                catch (RecoveryTokenException exception3)
                {
                    if (exception3._partiallyComputedNode != null)
                    {
                        list2.Append(exception3._partiallyComputedNode);
                    }
                    if (this.IndexOfToken(NoSkipTokenSet.s_ArrayInitNoSkipTokenSet, exception3) == -1)
                    {
                        context.UpdateWith(this.CurrentPositionContext());
                        exception3._partiallyComputedNode = new ArrayLiteral(context, list2);
                        throw exception3;
                    }
                    if (JSToken.RightBracket == this.currentToken.token)
                    {
                        goto Label_0573;
                    }
                }
                finally
                {
                    this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ArrayInitNoSkipTokenSet);
                }
            }
            else
            {
                list2.Append(new ConstantWrapper(Microsoft.JScript.Missing.Value, this.currentToken.Clone()));
            }
            this.GetNextToken();
        Label_0561:
            if (JSToken.RightBracket != this.currentToken.token)
            {
                goto Label_046D;
            }
        Label_0573:
            context.UpdateWith(this.currentToken);
            expression = new ArrayLiteral(context, list2);
            goto Label_0956;
        Label_0830:
            list3.context.UpdateWith(this.currentToken);
            context2.UpdateWith(this.currentToken);
            expression = new ObjectLiteral(context2, list3);
            goto Label_0956;
        Label_0881:
            str6 = JSKeyword.CanBeIdentifier(this.currentToken.token);
            if (str6 == null)
            {
                if (this.currentToken.token == JSToken.BitwiseAnd)
                {
                    this.ReportError(JSError.WrongUseOfAddressOf);
                    this.errorToken = null;
                    this.GetNextToken();
                    return this.ParseLeftHandSideExpression(isMinus, ref canBeAttribute, warnForKeyword);
                }
                this.ReportError(JSError.ExpressionExpected);
                this.SkipTokensAndThrow();
                goto Label_0956;
            }
            if (warnForKeyword)
            {
                switch (this.currentToken.token)
                {
                    case JSToken.Boolean:
                    case JSToken.Byte:
                    case JSToken.Char:
                    case JSToken.Double:
                    case JSToken.Float:
                    case JSToken.Int:
                    case JSToken.Long:
                    case JSToken.Short:
                    case JSToken.Void:
                        goto Label_08FC;
                }
                this.ForceReportInfo(JSError.KeywordUsedAsIdentifier);
            }
        Label_08FC:
            canBeAttribute = false;
            expression = new Lookup(str6, this.currentToken.Clone());
        Label_0956:
            if (!flag)
            {
                this.GetNextToken();
            }
            return this.MemberExpression(expression, newContexts, ref canBeAttribute);
        }
        internal VariableDeclaration(Context context, Lookup identifier, TypeExpression type, AST initializer, FieldAttributes attributes, CustomAttributeList customAttributes)
            : base(context)
        {
            if (initializer != null)
            {
                this.context.UpdateWith(initializer.context);
            }
            else if (type != null)
            {
                this.context.UpdateWith(type.context);
            }
            this.identifier  = identifier;
            this.type        = type;
            this.initializer = initializer;
            ScriptObject current_scope = (ScriptObject)Globals.ScopeStack.Peek();

            while (current_scope is WithObject) //Can only happen at run time and only if there is an eval
            {
                current_scope = current_scope.GetParent();
            }
            String name = this.identifier.ToString();

            if (current_scope is ClassScope)
            {
                if (name == ((ClassScope)current_scope).name)
                {
                    identifier.context.HandleError(JSError.CannotUseNameOfClass);
                    name = name + " var";
                }
            }
            else
            {
                if (attributes != (FieldAttributes)0)
                {
                    this.context.HandleError(JSError.NotInsideClass);
                    attributes = FieldAttributes.Public;
                }
                else
                {
                    attributes |= FieldAttributes.Public;
                }
            }
            FieldInfo field = ((IActivationObject)current_scope).GetLocalField(name);

            if (field != null)
            {
                if (field.IsLiteral || current_scope is ClassScope || type != null)
                {
                    identifier.context.HandleError(JSError.DuplicateName, true);
                }
                this.type = type = null;
            }
            if (current_scope is ActivationObject)
            {
                if (field == null || field is JSVariableField)
                {
                    this.field = ((ActivationObject)current_scope).AddFieldOrUseExistingField(this.identifier.ToString(), Missing.Value, attributes);
                }
                else
                {
                    this.field = ((ActivationObject)current_scope).AddNewField(this.identifier.ToString(), null, attributes);
                }
            }
            else
            {
                this.field = ((StackFrame)current_scope).AddNewField(this.identifier.ToString(), null, attributes | FieldAttributes.Static);
            }
            this.field.type             = type;
            this.field.customAttributes = customAttributes;
            this.field.originalContext  = context;
            if (this.field is JSLocalField)
            {
                // emit debug info for the local only if this block of code is in a section that has debug set
                ((JSLocalField)this.field).debugOn = this.identifier.context.document.debugOn;
            }
            this.completion = new Completion();
        }
Exemple #10
0
      private AST ParseLeftHandSideExpression(bool isMinus, ref bool canBeAttribute, bool warnForKeyword){
        AST ast = null;
        bool isFunction = false;
        ArrayList newContexts = null;

        // new expression
        while (JSToken.New == this.currentToken.token){
          if (null == newContexts)
            newContexts = new ArrayList(4);
          newContexts.Add(this.currentToken.Clone());
          GetNextToken();
        }

        JSToken token = this.currentToken.token;
        switch (token){
          // primary expression
          case JSToken.Identifier:
            ast = new Lookup(this.scanner.GetIdentifier(), this.currentToken.Clone());
            break;

          case JSToken.This:
            canBeAttribute = false;
            ast = new ThisLiteral(this.currentToken.Clone(), false);
            break;

          case JSToken.Super:
            canBeAttribute = false;
            ast = new ThisLiteral(this.currentToken.Clone(), true);
            break;

          case JSToken.StringLiteral:
            canBeAttribute = false;
            ast = new ConstantWrapper(this.scanner.GetStringLiteral(), this.currentToken.Clone());
            break;

          case JSToken.IntegerLiteral:
            {canBeAttribute = false;
            String number = this.currentToken.GetCode();
            Object n = Convert.LiteralToNumber(number, this.currentToken);
            if (n == null)
              n = 0;
            ast = new ConstantWrapper(n, this.currentToken.Clone());
            ((ConstantWrapper)ast).isNumericLiteral = true;
            break;}

          case JSToken.NumericLiteral:
            {canBeAttribute = false;
            String number = (isMinus) ? "-" + this.currentToken.GetCode() : this.currentToken.GetCode();
            double d = Convert.ToNumber(number, false, false, Missing.Value);
            ast = new ConstantWrapper(d, this.currentToken.Clone());
            ((ConstantWrapper)ast).isNumericLiteral = true;
            break;}

          case JSToken.True:
            canBeAttribute = false;
            ast = new ConstantWrapper(true, this.currentToken.Clone());
            break;

          case JSToken.False:
            canBeAttribute = false;
            ast = new ConstantWrapper(false, this.currentToken.Clone());
            break;

          case JSToken.Null:
            canBeAttribute = false;
            ast = new NullLiteral(this.currentToken.Clone());
            break;

          case JSToken.PreProcessorConstant:
            canBeAttribute = false;
            ast = new ConstantWrapper(this.scanner.GetPreProcessorValue(), this.currentToken.Clone());
            break;

          case JSToken.Divide:
            canBeAttribute = false;
            // could it be a regexp?
            String source = this.scanner.ScanRegExp();
            if (source != null){
              bool badRegExp = false;
              try {
                new Regex(source, RegexOptions.ECMAScript);
              } catch (System.ArgumentException) {
                // Replace the invalid source with the trivial regular expression.
                source = "";
                badRegExp = true;
              }
              String flags = this.scanner.ScanRegExpFlags();
              if (flags == null)
                ast = new RegExpLiteral(source, null, this.currentToken.Clone());
              else
                try{
                  ast = new RegExpLiteral(source, flags, this.currentToken.Clone());
                }catch (JScriptException){
                  // The flags are invalid, so use null instead.
                  ast = new RegExpLiteral(source, null, this.currentToken.Clone());
                  badRegExp = true;
                }
              if (badRegExp){
                ReportError(JSError.RegExpSyntax, true);
              }
              break;
            }
            goto default;

          // expression
          case JSToken.LeftParen:
            canBeAttribute = false;
            GetNextToken();
            this.noSkipTokenSet.Add(NoSkipTokenSet.s_ParenExpressionNoSkipToken);
            try{
              ast = ParseExpression();
              if (JSToken.RightParen != this.currentToken.token)
                ReportError(JSError.NoRightParen);
            }catch(RecoveryTokenException exc){
              if (IndexOfToken(NoSkipTokenSet.s_ParenExpressionNoSkipToken, exc) == -1)
                throw exc;
              else
                ast = exc._partiallyComputedNode;
            }finally{
              this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ParenExpressionNoSkipToken);
            }
            if (ast == null) //this can only happen when catching the exception and nothing was sent up by the caller
              SkipTokensAndThrow();
            break;

          // array initializer
          case JSToken.LeftBracket:
            canBeAttribute = false;
            Context listCtx = this.currentToken.Clone();
            ASTList list = new ASTList(this.currentToken.Clone());
            GetNextToken();
            if (this.currentToken.token == JSToken.Identifier && this.scanner.PeekToken() == JSToken.Colon){
              this.noSkipTokenSet.Add(NoSkipTokenSet.s_BracketToken);
              try{
                if (this.currentToken.GetCode() == "assembly"){
                  GetNextToken(); GetNextToken();
                  return new AssemblyCustomAttributeList(this.ParseCustomAttributeList());
                }else{
                  ReportError(JSError.ExpectedAssembly);
                  SkipTokensAndThrow();
                }
              }catch(RecoveryTokenException exc){
                exc._partiallyComputedNode = new Block(listCtx);                
                return exc._partiallyComputedNode;
              }finally{
                if (this.currentToken.token == JSToken.RightBracket){
                  this.errorToken = null;
                  GetNextToken();
                }
                this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BracketToken);
              }
            }
            while (JSToken.RightBracket != this.currentToken.token){
              if (JSToken.Comma != this.currentToken.token){
                this.noSkipTokenSet.Add(NoSkipTokenSet.s_ArrayInitNoSkipTokenSet);
                try{
                  list.Append(ParseExpression(true));
                  if (JSToken.Comma != this.currentToken.token){
                    if (JSToken.RightBracket != this.currentToken.token)
                      ReportError(JSError.NoRightBracket);
                    break;
                  }
                }catch(RecoveryTokenException exc){
                  if (exc._partiallyComputedNode != null)
                    list.Append(exc._partiallyComputedNode);
                  if (IndexOfToken(NoSkipTokenSet.s_ArrayInitNoSkipTokenSet, exc) == -1){
                    listCtx.UpdateWith(CurrentPositionContext());
                    exc._partiallyComputedNode = new ArrayLiteral(listCtx, list);
                    throw exc;
                  }else{
                    if (JSToken.RightBracket == this.currentToken.token)
                      break;
                  }
                }finally{
                  this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ArrayInitNoSkipTokenSet);
                }
              }else{
                list.Append(new ConstantWrapper(Missing.Value, this.currentToken.Clone()));
              }
              GetNextToken();
            }
            listCtx.UpdateWith(this.currentToken);
            ast = new ArrayLiteral(listCtx, list);
            break;

          // object initializer
          case JSToken.LeftCurly:
            canBeAttribute = false;
            Context objCtx = this.currentToken.Clone();
            GetNextToken();
            ASTList fields = new ASTList(this.currentToken.Clone());
            if (JSToken.RightCurly != this.currentToken.token){
              for (;;){
                AST field = null;
                AST value = null;

                if (JSToken.Identifier == this.currentToken.token)
                  field = new ConstantWrapper(this.scanner.GetIdentifier(), this.currentToken.Clone());
                else if (JSToken.StringLiteral == this.currentToken.token)
                  field = new ConstantWrapper(this.scanner.GetStringLiteral(), this.currentToken.Clone());
                else if (JSToken.IntegerLiteral == this.currentToken.token || JSToken.NumericLiteral == this.currentToken.token ){
                  String numberString = this.currentToken.GetCode();
                  double dValue = Convert.ToNumber(numberString, true, true, Missing.Value);
                  field = new ConstantWrapper(dValue, this.currentToken.Clone());
                  ((ConstantWrapper)field).isNumericLiteral = true;
                }else{
                  ReportError(JSError.NoMemberIdentifier);
                  field = new IdentifierLiteral("_#Missing_Field#_" + s_cDummyName++, CurrentPositionContext());
                }
                ASTList pair = new ASTList(field.context.Clone());
                GetNextToken();

                this.noSkipTokenSet.Add(NoSkipTokenSet.s_ObjectInitNoSkipTokenSet);
                try{
                  // get the value
                  if (JSToken.Colon != this.currentToken.token){
                    ReportError(JSError.NoColon, true);
                    value = ParseExpression(true);
                  }else{
                    GetNextToken();
                    value = ParseExpression(true);
                  }

                  // put the pair into the list of fields
                  pair.Append(field);
                  pair.Append(value);
                  fields.Append(pair);

                  if (JSToken.RightCurly == this.currentToken.token)
                    break;
                  else{
                    if (JSToken.Comma == this.currentToken.token)
                      GetNextToken();
                    else{
                      if (this.scanner.GotEndOfLine()){
                        ReportError(JSError.NoRightCurly);
                      }else
                        ReportError(JSError.NoComma, true);
                      SkipTokensAndThrow();
                    }
                  }
                }catch(RecoveryTokenException exc){
                  if (exc._partiallyComputedNode != null){
                    // the problem was in ParseExpression trying to determine value
                    value = exc._partiallyComputedNode;
                    pair.Append(field);
                    pair.Append(value);
                    fields.Append(pair);
                  }
                  if (IndexOfToken(NoSkipTokenSet.s_ObjectInitNoSkipTokenSet, exc) == -1){
                    exc._partiallyComputedNode = new ObjectLiteral(objCtx, fields);
                    throw exc;
                  }else{
                    if (JSToken.Comma == this.currentToken.token)
                      GetNextToken();
                    if (JSToken.RightCurly == this.currentToken.token)
                      break;
                  }
                }finally{
                  this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ObjectInitNoSkipTokenSet);
                }
              }
            }
            fields.context.UpdateWith(this.currentToken);
            objCtx.UpdateWith(this.currentToken);
            ast = new ObjectLiteral(objCtx, fields);
            break;

          // function expression
          case JSToken.Function:
            canBeAttribute = false;
            ast = ParseFunction((FieldAttributes)0, true, this.currentToken.Clone(), false, false, false, false, null);
            isFunction = true;
            break;

          default:
            string identifier = JSKeyword.CanBeIdentifier(this.currentToken.token);
            if (null != identifier){
              if (warnForKeyword){
                switch (this.currentToken.token){
                  case JSToken.Boolean :
                  case JSToken.Byte :
                  case JSToken.Char :
                  case JSToken.Double :
                  case JSToken.Float :
                  case JSToken.Int :
                  case JSToken.Long :
                  case JSToken.Short :
                  case JSToken.Void :
                    break;
                  default:
                    ForceReportInfo(JSError.KeywordUsedAsIdentifier);
                    break;
                }
              }
              canBeAttribute = false;
              ast = new Lookup(identifier, this.currentToken.Clone());
            }else if (this.currentToken.token == JSToken.BitwiseAnd){ //& expr used outside of a parameter list
              ReportError(JSError.WrongUseOfAddressOf);
              this.errorToken = null;
              GetNextToken();
              return this.ParseLeftHandSideExpression(isMinus, ref canBeAttribute, warnForKeyword);
            }else{
              ReportError(JSError.ExpressionExpected);
              SkipTokensAndThrow();
            }
            break;
        }

        // can be a CallExpression, that is, followed by '.' or '(' or '['
        if (!isFunction)
          GetNextToken();

        return MemberExpression(ast, newContexts, ref canBeAttribute);
      }
 private AST ParseTryStatement()
 {
     Context context = this.currentToken.Clone();
     Context closingBraceContext = null;
     AST body = null;
     AST identifier = null;
     AST handler = null;
     AST ast4 = null;
     RecoveryTokenException exception = null;
     TypeExpression type = null;
     this.blockType.Add(BlockType.Block);
     try
     {
         bool flag = false;
         bool flag2 = false;
         this.GetNextToken();
         if (JSToken.LeftCurly != this.currentToken.token)
         {
             this.ReportError(JSError.NoLeftCurly);
         }
         this.noSkipTokenSet.Add(NoSkipTokenSet.s_NoTrySkipTokenSet);
         try
         {
             try
             {
                 body = this.ParseBlock(out closingBraceContext);
             }
             catch (RecoveryTokenException exception2)
             {
                 if (this.IndexOfToken(NoSkipTokenSet.s_NoTrySkipTokenSet, exception2) == -1)
                 {
                     throw exception2;
                 }
                 body = exception2._partiallyComputedNode;
             }
             goto Label_02E5;
         }
         finally
         {
             this.noSkipTokenSet.Remove(NoSkipTokenSet.s_NoTrySkipTokenSet);
         }
     Label_00A6:
         this.noSkipTokenSet.Add(NoSkipTokenSet.s_NoTrySkipTokenSet);
         try
         {
             if (handler != null)
             {
                 body = new Try(context, body, identifier, type, handler, null, false, closingBraceContext);
                 identifier = null;
                 type = null;
                 handler = null;
             }
             flag = true;
             this.GetNextToken();
             if (JSToken.LeftParen != this.currentToken.token)
             {
                 this.ReportError(JSError.NoLeftParen);
             }
             this.GetNextToken();
             if (JSToken.Identifier != this.currentToken.token)
             {
                 string name = JSKeyword.CanBeIdentifier(this.currentToken.token);
                 if (name != null)
                 {
                     this.ForceReportInfo(JSError.KeywordUsedAsIdentifier);
                     identifier = new Lookup(name, this.currentToken.Clone());
                 }
                 else
                 {
                     this.ReportError(JSError.NoIdentifier);
                     identifier = new Lookup("##Exc##" + s_cDummyName++, this.CurrentPositionContext());
                 }
             }
             else
             {
                 identifier = new Lookup(this.scanner.GetIdentifier(), this.currentToken.Clone());
             }
             this.GetNextToken();
             this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet);
             try
             {
                 if (JSToken.Colon == this.currentToken.token)
                 {
                     type = this.ParseTypeExpression();
                 }
                 else
                 {
                     if (flag2)
                     {
                         this.ForceReportInfo(identifier.context, JSError.UnreachableCatch);
                     }
                     flag2 = true;
                 }
                 if (JSToken.RightParen != this.currentToken.token)
                 {
                     this.ReportError(JSError.NoRightParen);
                 }
                 this.GetNextToken();
             }
             catch (RecoveryTokenException exception3)
             {
                 if (this.IndexOfToken(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet, exception3) == -1)
                 {
                     exception3._partiallyComputedNode = null;
                     throw exception3;
                 }
                 type = (TypeExpression) exception3._partiallyComputedNode;
                 if (this.currentToken.token == JSToken.RightParen)
                 {
                     this.GetNextToken();
                 }
             }
             finally
             {
                 this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockConditionNoSkipTokenSet);
             }
             if (JSToken.LeftCurly != this.currentToken.token)
             {
                 this.ReportError(JSError.NoLeftCurly);
             }
             handler = this.ParseBlock();
             context.UpdateWith(handler.context);
         }
         catch (RecoveryTokenException exception4)
         {
             if (exception4._partiallyComputedNode == null)
             {
                 handler = new Block(this.CurrentPositionContext());
             }
             else
             {
                 handler = exception4._partiallyComputedNode;
             }
             if (this.IndexOfToken(NoSkipTokenSet.s_NoTrySkipTokenSet, exception4) == -1)
             {
                 if (type != null)
                 {
                     exception4._partiallyComputedNode = new Try(context, body, identifier, type, handler, null, false, closingBraceContext);
                 }
                 throw exception4;
             }
         }
         finally
         {
             this.noSkipTokenSet.Remove(NoSkipTokenSet.s_NoTrySkipTokenSet);
         }
     Label_02E5:
         if (JSToken.Catch == this.currentToken.token)
         {
             goto Label_00A6;
         }
         try
         {
             if (JSToken.Finally == this.currentToken.token)
             {
                 this.GetNextToken();
                 this.blockType.Add(BlockType.Finally);
                 try
                 {
                     ast4 = this.ParseBlock();
                     flag = true;
                 }
                 finally
                 {
                     this.blockType.RemoveAt(this.blockType.Count - 1);
                 }
                 context.UpdateWith(ast4.context);
             }
         }
         catch (RecoveryTokenException exception5)
         {
             exception = exception5;
         }
         if (!flag)
         {
             this.ReportError(JSError.NoCatch, true);
             ast4 = new Block(this.CurrentPositionContext());
         }
     }
     finally
     {
         this.blockType.RemoveAt(this.blockType.Count - 1);
     }
     bool finallyHasControlFlowOutOfIt = false;
     if (this.finallyEscaped > 0)
     {
         this.finallyEscaped--;
         finallyHasControlFlowOutOfIt = true;
     }
     if (exception != null)
     {
         exception._partiallyComputedNode = new Try(context, body, identifier, type, handler, ast4, finallyHasControlFlowOutOfIt, closingBraceContext);
         throw exception;
     }
     return new Try(context, body, identifier, type, handler, ast4, finallyHasControlFlowOutOfIt, closingBraceContext);
 }
        private AST ParseAttributes(AST statement, bool unambiguousContext, bool isInsideClass, out bool parsedOK)
        {
            JSToken none;
            bool flag;
            bool flag2;
            AST ast = statement;
            ArrayList list = new ArrayList();
            ArrayList list2 = new ArrayList();
            ArrayList list3 = new ArrayList();
            AST ast2 = null;
            ArrayList list4 = new ArrayList();
            Context context = null;
            Context context2 = null;
            Context context3 = null;
            int num = 0;
            if (unambiguousContext)
            {
                num = 2;
            }
            FieldAttributes privateScope = FieldAttributes.PrivateScope;
            FieldAttributes family = FieldAttributes.PrivateScope;
            Context enumCtx = null;
            if (statement != null)
            {
                ast2 = statement;
                list4.Add(statement);
                list.Add(this.CurrentPositionContext());
                enumCtx = statement.context.Clone();
                num = 1;
            }
            else
            {
                enumCtx = this.currentToken.Clone();
            }
            parsedOK = true;
        Label_0078:
            none = JSToken.None;
            switch (this.currentToken.token)
            {
                case JSToken.Boolean:
                case JSToken.Byte:
                case JSToken.Char:
                case JSToken.Double:
                case JSToken.Float:
                case JSToken.Int:
                case JSToken.Long:
                case JSToken.Short:
                case JSToken.Void:
                    parsedOK = false;
                    ast2 = new Lookup(this.currentToken);
                    none = JSToken.None;
                    list4.Add(ast2);
                    this.GetNextToken();
                    goto Label_0A12;

                case JSToken.Enum:
                {
                    int num8 = 0;
                    int num9 = list3.Count;
                    while (num8 < num9)
                    {
                        this.ReportError((JSError) list3[num8], (Context) list3[num8 + 1], true);
                        num8 += 2;
                    }
                    enumCtx.UpdateWith(this.currentToken);
                    if (context != null)
                    {
                        this.ReportError(JSError.IllegalVisibility, context, true);
                    }
                    if (context3 != null)
                    {
                        this.ReportError(JSError.IllegalVisibility, context3, true);
                    }
                    if (context2 != null)
                    {
                        this.ReportError(JSError.IllegalVisibility, context2, true);
                    }
                    return this.ParseEnum(privateScope, enumCtx, this.FromASTListToCustomAttributeList(list4));
                }
                case JSToken.Interface:
                    if (context != null)
                    {
                        this.ReportError(JSError.IllegalVisibility, context, true);
                        context = null;
                    }
                    if (context3 != null)
                    {
                        this.ReportError(JSError.IllegalVisibility, context3, true);
                        context3 = null;
                    }
                    if (context2 != null)
                    {
                        this.ReportError(JSError.IllegalVisibility, context2, true);
                        context2 = null;
                    }
                    break;

                case JSToken.Internal:
                case JSToken.Abstract:
                case JSToken.Public:
                case JSToken.Static:
                case JSToken.Private:
                case JSToken.Protected:
                case JSToken.Final:
                    none = this.currentToken.token;
                    goto Label_042A;

                case JSToken.Var:
                case JSToken.Const:
                {
                    int num2 = 0;
                    int num3 = list3.Count;
                    while (num2 < num3)
                    {
                        this.ReportError((JSError) list3[num2], (Context) list3[num2 + 1], true);
                        num2 += 2;
                    }
                    if (context != null)
                    {
                        this.ReportError(JSError.IllegalVisibility, context, true);
                    }
                    if (context3 != null)
                    {
                        this.ReportError(JSError.IllegalVisibility, context3, true);
                    }
                    enumCtx.UpdateWith(this.currentToken);
                    return this.ParseVariableStatement(privateScope, this.FromASTListToCustomAttributeList(list4), this.currentToken.token);
                }
                case JSToken.Class:
                    break;

                case JSToken.Function:
                {
                    int num4 = 0;
                    int num5 = list3.Count;
                    while (num4 < num5)
                    {
                        this.ReportError((JSError) list3[num4], (Context) list3[num4 + 1], true);
                        num4 += 2;
                    }
                    enumCtx.UpdateWith(this.currentToken);
                    if (context2 != null)
                    {
                        if (context != null)
                        {
                            context2.HandleError(JSError.AbstractCannotBeStatic);
                            context2 = null;
                        }
                        else if (context3 != null)
                        {
                            context3.HandleError(JSError.StaticIsAlreadyFinal);
                            context3 = null;
                        }
                    }
                    if (context != null)
                    {
                        if (context3 != null)
                        {
                            context3.HandleError(JSError.FinalPrecludesAbstract);
                            context3 = null;
                        }
                        if (family == FieldAttributes.Private)
                        {
                            context.HandleError(JSError.AbstractCannotBePrivate);
                            family = FieldAttributes.Family;
                        }
                    }
                    return this.ParseFunction(privateScope, false, enumCtx, isInsideClass, context != null, context3 != null, false, this.FromASTListToCustomAttributeList(list4));
                }
                case JSToken.Identifier:
                    goto Label_042A;

                default:
                    goto Label_047E;
            }
            int num6 = 0;
            int count = list3.Count;
            while (num6 < count)
            {
                this.ReportError((JSError) list3[num6], (Context) list3[num6 + 1], true);
                num6 += 2;
            }
            enumCtx.UpdateWith(this.currentToken);
            if ((context3 != null) && (context != null))
            {
                context3.HandleError(JSError.FinalPrecludesAbstract);
            }
            return this.ParseClass(privateScope, context2 != null, enumCtx, context != null, context3 != null, this.FromASTListToCustomAttributeList(list4));
        Label_042A:
            flag2 = true;
            statement = this.ParseUnaryExpression(out flag, ref flag2, false, none == JSToken.None);
            ast2 = statement;
            if (none != JSToken.None)
            {
                if (statement is Lookup)
                {
                    goto Label_07ED;
                }
                if (num != 2)
                {
                    list2.Add(this.currentToken.Clone());
                }
            }
            none = JSToken.None;
            if (flag2)
            {
                list4.Add(statement);
                goto Label_0A12;
            }
        Label_047E:
            parsedOK = false;
            if (num != 2)
            {
                if ((ast != statement) || (statement == null))
                {
                    statement = ast2;
                    int num10 = 0;
                    int num11 = list2.Count;
                    while (num10 < num11)
                    {
                        this.ForceReportInfo((Context) list2[num10], JSError.KeywordUsedAsIdentifier);
                        num10++;
                    }
                    int num12 = 0;
                    int num13 = list.Count;
                    while (num12 < num13)
                    {
                        if (!this.currentToken.Equals((Context) list[num12]))
                        {
                            this.ReportError(JSError.NoSemicolon, (Context) list[num12], true);
                        }
                        num12++;
                    }
                }
                return statement;
            }
            if (list4.Count > 0)
            {
                AST ast3 = (AST) list4[list4.Count - 1];
                if (ast3 is Lookup)
                {
                    if ((JSToken.Semicolon == this.currentToken.token) || (JSToken.Colon == this.currentToken.token))
                    {
                        this.ReportError(JSError.BadVariableDeclaration, ast3.context.Clone());
                        this.SkipTokensAndThrow();
                    }
                }
                else if ((ast3 is Call) && ((Call) ast3).CanBeFunctionDeclaration())
                {
                    if ((JSToken.Colon == this.currentToken.token) || (JSToken.LeftCurly == this.currentToken.token))
                    {
                        this.ReportError(JSError.BadFunctionDeclaration, ast3.context.Clone(), true);
                        if (JSToken.Colon == this.currentToken.token)
                        {
                            this.noSkipTokenSet.Add(NoSkipTokenSet.s_StartBlockNoSkipTokenSet);
                            try
                            {
                                this.SkipTokensAndThrow();
                            }
                            catch (RecoveryTokenException)
                            {
                            }
                            finally
                            {
                                this.noSkipTokenSet.Remove(NoSkipTokenSet.s_StartBlockNoSkipTokenSet);
                            }
                        }
                        this.errorToken = null;
                        if (JSToken.LeftCurly == this.currentToken.token)
                        {
                            FunctionScope item = new FunctionScope(this.Globals.ScopeStack.Peek(), isInsideClass);
                            this.Globals.ScopeStack.Push(item);
                            try
                            {
                                this.ParseBlock();
                            }
                            finally
                            {
                                this.Globals.ScopeStack.Pop();
                            }
                            this.SkipTokensAndThrow();
                        }
                    }
                    else
                    {
                        this.ReportError(JSError.SyntaxError, ast3.context.Clone());
                    }
                    this.SkipTokensAndThrow();
                }
            }
            if ((JSToken.LeftCurly == this.currentToken.token) && isInsideClass)
            {
                int num14 = 0;
                int num15 = list3.Count;
                while (num14 < num15)
                {
                    this.ReportError((JSError) list3[num14], (Context) list3[num14 + 1]);
                    num14 += 2;
                }
                if (context2 == null)
                {
                    this.ReportError(JSError.StaticMissingInStaticInit, this.CurrentPositionContext());
                }
                string name = ((ClassScope) this.Globals.ScopeStack.Peek()).name;
                bool flag3 = true;
                foreach (object obj2 in list4)
                {
                    flag3 = false;
                    if (((context2 == null) || !(obj2 is Lookup)) || ((obj2.ToString() != name) || (((Lookup) obj2).context.StartColumn <= context2.StartColumn)))
                    {
                        this.ReportError(JSError.SyntaxError, ((AST) obj2).context);
                    }
                }
                if (flag3)
                {
                    this.ReportError(JSError.NoIdentifier, this.CurrentPositionContext());
                }
                this.errorToken = null;
                parsedOK = true;
                return this.ParseStaticInitializer(enumCtx);
            }
            this.ReportError(JSError.MissingConstructForAttributes, enumCtx.CombineWith(this.currentToken));
            this.SkipTokensAndThrow();
        Label_07ED:
            switch (none)
            {
                case JSToken.Internal:
                    family = FieldAttributes.Assembly;
                    break;

                case JSToken.Abstract:
                    if (context == null)
                    {
                        context = statement.context.Clone();
                    }
                    else
                    {
                        list3.Add(JSError.SyntaxError);
                        list3.Add(statement.context.Clone());
                    }
                    goto Label_0A12;

                case JSToken.Public:
                    family = FieldAttributes.Public;
                    break;

                case JSToken.Static:
                    if (!isInsideClass)
                    {
                        list3.Add(JSError.NotInsideClass);
                        list3.Add(statement.context.Clone());
                        break;
                    }
                    family = FieldAttributes.Static;
                    if (context2 == null)
                    {
                        context2 = statement.context.Clone();
                        break;
                    }
                    list3.Add(JSError.SyntaxError);
                    list3.Add(statement.context.Clone());
                    break;

                case JSToken.Private:
                    if (!isInsideClass)
                    {
                        list3.Add(JSError.NotInsideClass);
                        list3.Add(statement.context.Clone());
                        break;
                    }
                    family = FieldAttributes.Private;
                    break;

                case JSToken.Protected:
                    if (!isInsideClass)
                    {
                        list3.Add(JSError.NotInsideClass);
                        list3.Add(statement.context.Clone());
                        break;
                    }
                    family = FieldAttributes.Family;
                    break;

                case JSToken.Final:
                    if (context3 == null)
                    {
                        context3 = statement.context.Clone();
                    }
                    else
                    {
                        list3.Add(JSError.SyntaxError);
                        list3.Add(statement.context.Clone());
                    }
                    goto Label_0A12;
            }
            if (((privateScope & FieldAttributes.FieldAccessMask) == family) && (family != FieldAttributes.PrivateScope))
            {
                list3.Add(JSError.DupVisibility);
                list3.Add(statement.context.Clone());
            }
            else if (((privateScope & FieldAttributes.FieldAccessMask) > FieldAttributes.PrivateScope) && ((family & FieldAttributes.FieldAccessMask) > FieldAttributes.PrivateScope))
            {
                if (((family == FieldAttributes.Family) && ((privateScope & FieldAttributes.FieldAccessMask) == FieldAttributes.Assembly)) || ((family == FieldAttributes.Assembly) && ((privateScope & FieldAttributes.FieldAccessMask) == FieldAttributes.Family)))
                {
                    privateScope &= ~FieldAttributes.FieldAccessMask;
                    privateScope |= FieldAttributes.FamORAssem;
                }
                else
                {
                    list3.Add(JSError.IncompatibleVisibility);
                    list3.Add(statement.context.Clone());
                }
            }
            else
            {
                privateScope |= family;
                enumCtx.UpdateWith(statement.context);
            }
        Label_0A12:
            if (num != 2)
            {
                if (this.scanner.GotEndOfLine())
                {
                    num = 0;
                }
                else
                {
                    num++;
                    list.Add(this.currentToken.Clone());
                }
            }
            goto Label_0078;
        }
        private AST ParseQualifiedIdentifier(JSError error)
        {
            this.GetNextToken();
            AST qualid = null;
            string name = null;
            Context context = this.currentToken.Clone();
            if (JSToken.Identifier == this.currentToken.token)
            {
                qualid = new Lookup(this.scanner.GetIdentifier(), context);
            }
            else
            {
                name = JSKeyword.CanBeIdentifier(this.currentToken.token);
                if (name == null)
                {
                    this.ReportError(error, true);
                    this.SkipTokensAndThrow();
                }
                else
                {
                    switch (this.currentToken.token)
                    {
                        case JSToken.Boolean:
                        case JSToken.Byte:
                        case JSToken.Char:
                        case JSToken.Double:
                        case JSToken.Float:
                        case JSToken.Int:
                        case JSToken.Long:
                        case JSToken.Short:
                        case JSToken.Void:
                            break;

                        default:
                            this.ForceReportInfo(JSError.KeywordUsedAsIdentifier);
                            break;
                    }
                    qualid = new Lookup(name, context);
                }
            }
            this.GetNextToken();
            if (JSToken.AccessField == this.currentToken.token)
            {
                qualid = this.ParseScopeSequence(qualid, error);
            }
            return qualid;
        }
        private AST ParsePackage(Context packageContext)
        {
            AST ast4;
            this.GetNextToken();
            AST expression = null;
            bool flag = this.scanner.GotEndOfLine();
            if (JSToken.Identifier != this.currentToken.token)
            {
                if (JSScanner.CanParseAsExpression(this.currentToken.token))
                {
                    bool flag2;
                    this.ReportError(JSError.KeywordUsedAsIdentifier, packageContext.Clone(), true);
                    expression = new Lookup("package", packageContext);
                    expression = this.MemberExpression(expression, null);
                    expression = this.ParsePostfixExpression(expression, out flag2);
                    expression = this.ParseExpression(expression, false, flag2, JSToken.None);
                    return new Expression(expression.context.Clone(), expression);
                }
                if (flag)
                {
                    this.ReportError(JSError.KeywordUsedAsIdentifier, packageContext.Clone(), true);
                    return new Lookup("package", packageContext);
                }
                if ((JSToken.Increment == this.currentToken.token) || (JSToken.Decrement == this.currentToken.token))
                {
                    bool flag3;
                    this.ReportError(JSError.KeywordUsedAsIdentifier, packageContext.Clone(), true);
                    expression = new Lookup("package", packageContext);
                    expression = this.ParsePostfixExpression(expression, out flag3);
                    expression = this.ParseExpression(expression, false, false, JSToken.None);
                    return new Expression(expression.context.Clone(), expression);
                }
            }
            else
            {
                this.errorToken = this.currentToken;
                expression = this.ParseQualifiedIdentifier(JSError.NoIdentifier);
            }
            Context context = null;
            if ((JSToken.LeftCurly != this.currentToken.token) && (expression == null))
            {
                context = this.currentToken.Clone();
                this.GetNextToken();
            }
            if (JSToken.LeftCurly == this.currentToken.token)
            {
                if (expression == null)
                {
                    if (context == null)
                    {
                        context = this.currentToken.Clone();
                    }
                    this.ReportError(JSError.NoIdentifier, context, true);
                }
            }
            else if (expression == null)
            {
                this.ReportError(JSError.SyntaxError, packageContext);
                if (JSScanner.CanStartStatement(context.token))
                {
                    this.currentToken = context;
                    return this.ParseStatement();
                }
                if (JSScanner.CanStartStatement(this.currentToken.token))
                {
                    this.errorToken = null;
                    return this.ParseStatement();
                }
                this.ReportError(JSError.SyntaxError);
                this.SkipTokensAndThrow();
            }
            else
            {
                if (flag)
                {
                    bool flag4;
                    this.ReportError(JSError.KeywordUsedAsIdentifier, packageContext.Clone(), true);
                    Block block = new Block(packageContext.Clone());
                    block.Append(new Lookup("package", packageContext));
                    expression = this.MemberExpression(expression, null);
                    expression = this.ParsePostfixExpression(expression, out flag4);
                    expression = this.ParseExpression(expression, false, true, JSToken.None);
                    block.Append(new Expression(expression.context.Clone(), expression));
                    block.context.UpdateWith(expression.context);
                    return block;
                }
                this.ReportError(JSError.NoLeftCurly);
            }
            PackageScope item = new PackageScope(this.Globals.ScopeStack.Peek());
            this.Globals.ScopeStack.Push(item);
            try
            {
                string name = (expression != null) ? expression.ToString() : "anonymous package";
                item.name = name;
                packageContext.UpdateWith(this.currentToken);
                ASTList classList = new ASTList(packageContext);
                this.GetNextToken();
                this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockNoSkipTokenSet);
                this.noSkipTokenSet.Add(NoSkipTokenSet.s_PackageBodyNoSkipTokenSet);
                try
                {
                    while (this.currentToken.token != JSToken.RightCurly)
                    {
                        AST statement = null;
                        try
                        {
                            switch (this.currentToken.token)
                            {
                                case JSToken.Identifier:
                                {
                                    bool flag6;
                                    bool canBeAttribute = true;
                                    statement = this.ParseUnaryExpression(out flag6, ref canBeAttribute, false);
                                    if (canBeAttribute)
                                    {
                                        bool flag8;
                                        statement = this.ParseAttributes(statement, true, false, out flag8);
                                        if (flag8 && (statement is Class))
                                        {
                                            classList.Append(statement);
                                            continue;
                                        }
                                    }
                                    this.ReportError(JSError.OnlyClassesAllowed, statement.context.Clone(), true);
                                    this.SkipTokensAndThrow();
                                    continue;
                                }
                                case JSToken.Interface:
                                case JSToken.Class:
                                {
                                    classList.Append(this.ParseClass(FieldAttributes.PrivateScope, false, this.currentToken.Clone(), false, false, null));
                                    continue;
                                }
                                case JSToken.Enum:
                                {
                                    classList.Append(this.ParseEnum(FieldAttributes.PrivateScope, this.currentToken.Clone(), null));
                                    continue;
                                }
                                case JSToken.Import:
                                {
                                    this.ReportError(JSError.InvalidImport, true);
                                    try
                                    {
                                        this.ParseImportStatement();
                                    }
                                    catch (RecoveryTokenException)
                                    {
                                    }
                                    continue;
                                }
                                case JSToken.Package:
                                {
                                    Context context2 = this.currentToken.Clone();
                                    if (this.ParsePackage(context2) is Package)
                                    {
                                        this.ReportError(JSError.PackageInWrongContext, context2, true);
                                    }
                                    continue;
                                }
                                case JSToken.Internal:
                                case JSToken.Abstract:
                                case JSToken.Public:
                                case JSToken.Static:
                                case JSToken.Private:
                                case JSToken.Protected:
                                case JSToken.Final:
                                {
                                    bool flag5;
                                    statement = this.ParseAttributes(null, true, false, out flag5);
                                    if (!flag5 || !(statement is Class))
                                    {
                                        break;
                                    }
                                    classList.Append(statement);
                                    continue;
                                }
                                case JSToken.Semicolon:
                                {
                                    this.GetNextToken();
                                    continue;
                                }
                                case JSToken.EndOfFile:
                                    this.EOFError(JSError.ErrEOF);
                                    throw new EndOfFile();

                                default:
                                    goto Label_04D9;
                            }
                            this.ReportError(JSError.OnlyClassesAllowed, statement.context.Clone(), true);
                            this.SkipTokensAndThrow();
                            continue;
                        Label_04D9:
                            this.ReportError(JSError.OnlyClassesAllowed, (statement != null) ? statement.context.Clone() : this.CurrentPositionContext(), true);
                            this.SkipTokensAndThrow();
                            continue;
                        }
                        catch (RecoveryTokenException exception)
                        {
                            if ((exception._partiallyComputedNode != null) && (exception._partiallyComputedNode is Class))
                            {
                                classList.Append((Class) exception._partiallyComputedNode);
                                exception._partiallyComputedNode = null;
                            }
                            if (this.IndexOfToken(NoSkipTokenSet.s_PackageBodyNoSkipTokenSet, exception) == -1)
                            {
                                throw exception;
                            }
                            continue;
                        }
                    }
                }
                catch (RecoveryTokenException exception2)
                {
                    if (this.IndexOfToken(NoSkipTokenSet.s_BlockNoSkipTokenSet, exception2) == -1)
                    {
                        this.ReportError(JSError.NoRightCurly, this.CurrentPositionContext());
                        exception2._partiallyComputedNode = new Package(name, expression, classList, packageContext);
                        throw exception2;
                    }
                }
                finally
                {
                    this.noSkipTokenSet.Remove(NoSkipTokenSet.s_PackageBodyNoSkipTokenSet);
                    this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockNoSkipTokenSet);
                }
                this.GetNextToken();
                ast4 = new Package(name, expression, classList, packageContext);
            }
            finally
            {
                this.Globals.ScopeStack.Pop();
            }
            return ast4;
        }
 internal string[] ParseNamedBreakpoint(out int argNumber)
 {
     argNumber = 0;
     AST ast = this.ParseQualifiedIdentifier(JSError.SyntaxError);
     if (ast == null)
     {
         return null;
     }
     string[] strArray = new string[4];
     strArray[0] = ast.ToString();
     if (JSToken.LeftParen == this.currentToken.token)
     {
         string name = null;
         string str2 = null;
         AST qualid = null;
         strArray[1] = "";
         this.GetNextToken();
         while (JSToken.RightParen != this.currentToken.token)
         {
             string[] strArray2;
             name = null;
             if ((JSToken.Identifier != this.currentToken.token) && ((name = JSKeyword.CanBeIdentifier(this.currentToken.token)) == null))
             {
                 return null;
             }
             if (name == null)
             {
                 name = this.scanner.GetIdentifier();
             }
             qualid = new Lookup(name, this.currentToken.Clone());
             this.GetNextToken();
             if (JSToken.AccessField == this.currentToken.token)
             {
                 str2 = this.ParseScopeSequence(qualid, JSError.SyntaxError).ToString();
                 while (JSToken.LeftBracket == this.currentToken.token)
                 {
                     this.GetNextToken();
                     if (JSToken.RightBracket != this.currentToken.token)
                     {
                         return null;
                     }
                     str2 = str2 + "[]";
                     this.GetNextToken();
                 }
             }
             else
             {
                 if (JSToken.Colon == this.currentToken.token)
                 {
                     this.GetNextToken();
                     if (JSToken.RightParen == this.currentToken.token)
                     {
                         return null;
                     }
                     continue;
                 }
                 str2 = qualid.ToString();
             }
             (strArray2 = strArray)[1] = strArray2[1] + str2 + " ";
             argNumber++;
             if (JSToken.Comma == this.currentToken.token)
             {
                 this.GetNextToken();
                 if (JSToken.RightParen == this.currentToken.token)
                 {
                     return null;
                 }
             }
         }
         this.GetNextToken();
         if (JSToken.Colon == this.currentToken.token)
         {
             this.GetNextToken();
             name = null;
             if ((JSToken.Identifier != this.currentToken.token) && ((name = JSKeyword.CanBeIdentifier(this.currentToken.token)) == null))
             {
                 return null;
             }
             if (name == null)
             {
                 name = this.scanner.GetIdentifier();
             }
             qualid = new Lookup(name, this.currentToken.Clone());
             this.GetNextToken();
             if (JSToken.AccessField == this.currentToken.token)
             {
                 qualid = this.ParseScopeSequence(qualid, JSError.SyntaxError);
                 strArray[2] = qualid.ToString();
                 while (JSToken.LeftBracket == this.currentToken.token)
                 {
                     string[] strArray3;
                     this.GetNextToken();
                     if (JSToken.RightBracket != this.currentToken.token)
                     {
                         return null;
                     }
                     (strArray3 = strArray)[2] = strArray3[2] + "[]";
                     this.GetNextToken();
                 }
             }
             else
             {
                 strArray[2] = qualid.ToString();
             }
         }
     }
     if (JSToken.FirstBinaryOp == this.currentToken.token)
     {
         this.GetNextToken();
         if (JSToken.IntegerLiteral != this.currentToken.token)
         {
             return null;
         }
         strArray[3] = this.currentToken.GetCode();
         this.GetNextToken();
     }
     if (this.currentToken.token != JSToken.EndOfFile)
     {
         return null;
     }
     return strArray;
 }
Exemple #16
0
      //---------------------------------------------------------------------------------------
      // ParseNamedBreakpoint
      //
      //  Used by the debugger to parsed a named breakpoint, that is a name of a function with
      //  possible arguments and optionally followed by an il offset
      //---------------------------------------------------------------------------------------
      internal String[] ParseNamedBreakpoint(out int argNumber){
        argNumber = 0;

        // parse the function name
        AST function = ParseQualifiedIdentifier(JSError.SyntaxError);
        if (function != null){
          String[] parsedFunction = new String[4];
          parsedFunction[0] = function.ToString();

          if (JSToken.LeftParen == this.currentToken.token){
            String id = null;
            String typeString = null;
            AST qualid = null;

            parsedFunction[1] = "";

            GetNextToken();
            // parse the formal parameters
            while (JSToken.RightParen != this.currentToken.token){
              id = null;
              if (JSToken.Identifier != this.currentToken.token && (id = JSKeyword.CanBeIdentifier(this.currentToken.token)) == null){
                return null;
              }else{
                if (null == id)
                  id = this.scanner.GetIdentifier();
                qualid = new Lookup(id, this.currentToken.Clone());
                GetNextToken();
                if (JSToken.AccessField == this.currentToken.token){
                  qualid = ParseScopeSequence(qualid, JSError.SyntaxError);
                  typeString = qualid.ToString();
                  while (JSToken.LeftBracket == this.currentToken.token){
                    GetNextToken();
                    if (JSToken.RightBracket != this.currentToken.token)
                      return null;
                    typeString += "[]";
                    GetNextToken();
                  }
                }else if (JSToken.Colon == this.currentToken.token){
                  GetNextToken();
                  if (JSToken.RightParen == this.currentToken.token)
                    return null;
                  continue;
                }else{
                  typeString = qualid.ToString();
                }
                parsedFunction[1] += typeString + " ";
              }
              argNumber++;

              if (JSToken.Comma == this.currentToken.token){
                GetNextToken();
                if (JSToken.RightParen == this.currentToken.token)
                  return null;
              }
            }

            GetNextToken();

            // parse a return value if any
            if (JSToken.Colon == this.currentToken.token){
              GetNextToken();
              id = null;
              if (JSToken.Identifier != this.currentToken.token && (id = JSKeyword.CanBeIdentifier(this.currentToken.token)) == null){
                return null;
              }else{
                if (null == id)
                  id = this.scanner.GetIdentifier();
                qualid = new Lookup(id, this.currentToken.Clone());
                GetNextToken();
                if (JSToken.AccessField == this.currentToken.token){
                  qualid = ParseScopeSequence(qualid, JSError.SyntaxError);
                  parsedFunction[2] = qualid.ToString();
                  while (JSToken.LeftBracket == this.currentToken.token){
                    GetNextToken();
                    if (JSToken.RightBracket != this.currentToken.token)
                      return null;
                    parsedFunction[2] += "[]";
                    GetNextToken();
                  }
                }else{
                  parsedFunction[2] = qualid.ToString();
                }
              }
            }

          }

          if (JSToken.Plus == this.currentToken.token){
            GetNextToken();
            if (JSToken.IntegerLiteral != this.currentToken.token)
              return null;
            parsedFunction[3] = this.currentToken.GetCode();
            GetNextToken();
          }

          if (JSToken.EndOfFile != this.currentToken.token)
            return null; // some extra crap
          return parsedFunction;
        }
        return null;
      }
        internal bool IsExpandoAttribute() //Use only before partial evaluation has been done
        {
            Lookup id = this.ctor as Lookup;

            return(id != null && id.Name == "expando");
        }
Exemple #18
0
      //---------------------------------------------------------------------------------------
      // ParsePackage
      //
      //  Package :
      //    'package' QualifiedIdentifier '{' ClassList '}'
      //
      //  ClassList :
      //    <empty> |
      //    Class ClassList |
      //    Attributes Class ClassList |
      //    Attributes Enum ClassList
      //---------------------------------------------------------------------------------------
      // Because 'package' is not a reserved word in JS5 we have to deal with an ambiguity
      // in the grammar. A source sequence like the following
      // package
      // x
      // { }
      // can be legally parsed in two ways:
      // Identifier Identifier Block or
      // Package
      // we give Package priority in this situation.
      // Here is how we deal with some possible cases:
      // 1- ** package <no line break> QualifiedIdentifier ** is parsed unambiguously as a package production regardless of what comes after Identifier
      // 2- ** package <no line break> NotOneOf(Operator | '[' | '.' | '(' | Identifier) '{' ** is parsed as a package production with an error
      // 3- ** package <line break> '{' ** is parsed as a package (anonymous) with an error
      // 4- ** package <line break> Not(Identifier) ** is never parsed as a package
      private AST ParsePackage(Context packageContext){
        GetNextToken();
        AST qualid = null;
        bool gotLineBreak = this.scanner.GotEndOfLine();

        // erroneous package production
        if (JSToken.Identifier != this.currentToken.token){
          if (JSScanner.CanParseAsExpression(this.currentToken.token)){
            // it's an expression. Report a warning. package and this.currentToken can be an expression (i.e. 'package +')
            ReportError(JSError.KeywordUsedAsIdentifier, packageContext.Clone(), true);
            qualid = new Lookup("package", packageContext);
            // get the member expression
            qualid = MemberExpression(qualid, null);
            bool isLeftHandSide;
            qualid = ParsePostfixExpression(qualid, out isLeftHandSide);
            qualid = ParseExpression(qualid, false, isLeftHandSide, JSToken.None);
            return new Expression(qualid.context.Clone(), qualid);
          }else if (!gotLineBreak){
            if (JSToken.Increment == this.currentToken.token || JSToken.Decrement == this.currentToken.token){
              // it's a postfix expression. Report a warning
              ReportError(JSError.KeywordUsedAsIdentifier, packageContext.Clone(), true);
              bool dummy;
              qualid = new Lookup("package", packageContext);
              qualid = ParsePostfixExpression(qualid, out dummy);
              qualid = ParseExpression(qualid, false, false, JSToken.None);
              return new Expression(qualid.context.Clone(), qualid);
            }
          }else{
            // it's an expression. Report a warning which, as a side effect, will make the current token be the next token fetched
            ReportError(JSError.KeywordUsedAsIdentifier, packageContext.Clone(), true);
            return new Lookup("package", packageContext);
          }
        }else{
          // it is an identifier, parse it as a qualified identifier
          this.errorToken = this.currentToken; // this will make GetNextToken() in ParseQualifiedIdentifier() return this.currentToken
          qualid = ParseQualifiedIdentifier(JSError.NoIdentifier);
        }

        // if we are here we have:
        // ** package QualifiedIdentifier ** or
        // ** package SomeNonSenseToken **, that is a token that does not make an expression

        Context nonSenseToken = null;
        if (JSToken.LeftCurly != this.currentToken.token && qualid == null){
          // we want to peek and see whether the next token is a LeftCurly
          nonSenseToken = this.currentToken.Clone();
          GetNextToken();
        }

        if (JSToken.LeftCurly == this.currentToken.token){
          // sounds like a package, possibly with an error. If qualid is not null is actually a good package, otherwise we treat it
          // as an anonymous package and keep going.
          if (qualid == null){
            if (nonSenseToken == null)
              nonSenseToken = this.currentToken.Clone();
            ReportError(JSError.NoIdentifier, nonSenseToken, true);
          }
        }else{
          if (qualid == null){
            // this is pretty screwy, let's ignore the package keyword for a start
            ReportError(JSError.SyntaxError, packageContext);
            if (JSScanner.CanStartStatement(nonSenseToken.token)){
              // this is tricky we assign nonSenseToken to this.currentToken and call ParseStatement, because we know it is a statement start token.
              // The parser should then call GetNextToken() which will return the this.currentToken that is assigned to this.errorToken
              this.currentToken = nonSenseToken;
              return ParseStatement();
            }else{
              //ReportError(JSError.SyntaxError, nonSenseToken);
              if (JSScanner.CanStartStatement(this.currentToken.token)){
                this.errorToken = null;
                return ParseStatement();
              }else{
                ReportError(JSError.SyntaxError);
                SkipTokensAndThrow();
              }
            }
          }else{
            if (gotLineBreak){
              // we are here with the following: 'package' <line break> QalifiedIdentifier' however we do not have a left curly.
              // if the token in our hand can start an expression we go with two expressions, otherwise we accept it as a package
              //if (JSScanner.CanParseAsExpression(this.currentToken.token)){
                ReportError(JSError.KeywordUsedAsIdentifier, packageContext.Clone(), true);
                Block block = new Block(packageContext.Clone());
                block.Append(new Lookup("package", packageContext));
                qualid = MemberExpression(qualid, null);
                bool isLeftHandSide;
                qualid = ParsePostfixExpression(qualid, out isLeftHandSide);
                qualid = ParseExpression(qualid, false, true, JSToken.None);
                block.Append(new Expression(qualid.context.Clone(), qualid));
                block.context.UpdateWith(qualid.context);
                return block;
              //}
            }
            // the package production rule is entered regardless of the presence of a left curly.
            ReportError(JSError.NoLeftCurly);
          }
        }

        PackageScope pscope = new PackageScope(Globals.ScopeStack.Peek());
        Globals.ScopeStack.Push(pscope); //Give declarations a place to go while building AST
        try{
          string name = (qualid != null) ? qualid.ToString() : "anonymous package";
          pscope.name = name;
          packageContext.UpdateWith(this.currentToken);
          ASTList classList = new ASTList(packageContext);

          GetNextToken();
          this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockNoSkipTokenSet);
          this.noSkipTokenSet.Add(NoSkipTokenSet.s_PackageBodyNoSkipTokenSet);
          try{
            while (this.currentToken.token != JSToken.RightCurly){
              AST ast = null;
              try{
                switch (this.currentToken.token){

                  case JSToken.Interface:
                  case JSToken.Class:
                    classList.Append(ParseClass((FieldAttributes)0, false, this.currentToken.Clone(), false, false, null));
                    break;

                  case JSToken.Enum:
                    classList.Append(ParseEnum((FieldAttributes)0, this.currentToken.Clone(), null));
                    break;
                  case JSToken.Internal:
                  case JSToken.Public:
                  case JSToken.Static:
                  case JSToken.Private:
                  case JSToken.Protected:
                  case JSToken.Abstract:
                  case JSToken.Final:
                    bool parsedOK;
                    ast = ParseAttributes(null, true, false, out parsedOK);
                    if (parsedOK){
                      if (ast is Class){
                        classList.Append(ast);
                        break;
                      }
                    }
                    ReportError(JSError.OnlyClassesAllowed, ast.context.Clone(), true);
                    SkipTokensAndThrow();
                    break;

                  case JSToken.Identifier:
                    bool bAssign, canBeAttribute = true;
                    ast = ParseUnaryExpression(out bAssign, ref canBeAttribute, false);
                    if (canBeAttribute){
                      bool parsed;
                      ast = ParseAttributes(ast, true, false, out parsed);
                      if (parsed){
                        if (ast is Class){
                          classList.Append(ast);
                          break;
                        }
                      }
                    }
                    ReportError(JSError.OnlyClassesAllowed, ast.context.Clone(), true);
                    SkipTokensAndThrow();
                    break;

                  case JSToken.EndOfFile:
                    EOFError(JSError.ErrEOF);
                    throw new EndOfFile(); // abort parsing, get back to the main parse routine

                  case JSToken.Semicolon: // ignore any spurious semicolon
                    GetNextToken();
                    break;
                  case JSToken.Import:
                    // handle common error of using import in package
                    ReportError(JSError.InvalidImport, true);
                    try{
                      ParseImportStatement();
                    }catch(RecoveryTokenException){
                    }
                    break;
                  case JSToken.Package:
                    // handle common error of using package in package
                    Context nestedPackageContext = this.currentToken.Clone();
                    AST statement = ParsePackage(nestedPackageContext);
                    if (statement is Package)
                      ReportError(JSError.PackageInWrongContext, nestedPackageContext, true);
                    break;
                  default:
                    ReportError(JSError.OnlyClassesAllowed, (ast != null) ? ast.context.Clone() : CurrentPositionContext(), true);
                    SkipTokensAndThrow();
                    break;
                }
              }catch(RecoveryTokenException exc){
                if (exc._partiallyComputedNode != null && exc._partiallyComputedNode is Class){
                  classList.Append((Class)exc._partiallyComputedNode);
                  exc._partiallyComputedNode = null;
                }
                if (IndexOfToken(NoSkipTokenSet.s_PackageBodyNoSkipTokenSet, exc) == -1)
                  throw exc;
              }
            }
          }catch(RecoveryTokenException exc){
            if (IndexOfToken(NoSkipTokenSet.s_BlockNoSkipTokenSet, exc) == -1){
              ReportError(JSError.NoRightCurly, CurrentPositionContext());
              exc._partiallyComputedNode = new Package(name, qualid, classList, packageContext);
              throw exc;
            }
          }finally{
            this.noSkipTokenSet.Remove(NoSkipTokenSet.s_PackageBodyNoSkipTokenSet);
            this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockNoSkipTokenSet);
          }
          GetNextToken();
          return new Package(name, qualid, classList, packageContext);
        }finally{
          Globals.ScopeStack.Pop();
        }
      }
 internal override AST PartiallyEvaluate(){
   AST id = this.identifier = (Lookup)this.identifier.PartiallyEvaluateAsReference();
   if (this.type != null)
     this.field.type = this.type = (TypeExpression)this.type.PartiallyEvaluate();
   else if (this.initializer == null && !(this.field is JSLocalField) &&
   this.field.value is Missing){
     id.context.HandleError(JSError.VariableLeftUninitialized);
     this.field.type = this.type = new TypeExpression(new ConstantWrapper(Typeob.Object, id.context));
   }
   if (this.initializer != null){
     if (this.field.IsStatic){
       ScriptObject scope = this.Engine.ScriptObjectStackTop();
       ClassScope cscope = null;
       while (scope != null && (cscope = scope as ClassScope) == null) scope = scope.GetParent();
       if (cscope != null) cscope.inStaticInitializerCode = true;
       this.initializer = this.initializer.PartiallyEvaluate();
       if (cscope != null) cscope.inStaticInitializerCode = false;
     }else
       this.initializer = this.initializer.PartiallyEvaluate();
     id.SetPartialValue(this.initializer);
   }
   // deal with custom attributes
   if (this.field != null && this.field.customAttributes != null)
     this.field.customAttributes.PartiallyEvaluate();
   return this;
 }
Exemple #20
0
      //---------------------------------------------------------------------------------------
      // ParseAttributes
      //
      //  Package :
      //    Attributes 'package' QualifiedIdentifier '{' ClassList '}'
      //    AttributesStart 'package' QualifiedIdentifier '{' ClassList '}'
      //
      //  Class :
      //    Attributes 'class' Identifier ['extends' QualifiedIdentifier] '{' ClassBody '}'
      //    AttributesStart 'class' Identifier ['extends' QualifiedIdentifier] '{' ClassBody '}'
      //
      //  FunctionDeclaration :
      //    Attributes 'function' Identifier '(' [FormalParameterList] ')' [':' TypeExpression] '{' FunctionBody '}'
      //    AttributesStart 'function' Identifier '(' [FormalParameterList] ')' [':' TypeExpression] '{' FunctionBody '}'
      //
      //  VariableStatement :
      //    Attributes 'var' VariableDeclarationList
      //    AttributesStart 'var' VariableDeclarationList
      //
      //  Attributes :
      //    AttributesStart AttributesNext |
      //    Modifier [AttributeNext]
      //
      //  AttributesStart :
      //    QualifiedIdentifier /no LineTerminator here/ |
      //    QualifiedIdentifier Arguments /no LineTerminator here/
      //
      //  AttributesNext :
      //    QualifiedIdentifier [AttributesNext] |
      //    QualifiedIdentifier Arguments [AttributesNext] |
      //    Modifier [AttributesNext]
      //
      //  Modifier :
      //    'private' |
      //    'public' |
      //    'protected' |
      //    'internal' |
      //    'package' | //This is going away
      //    'static' |
      //    'abstract'
      //
      //
      // Parse the list of attributes and the statement those attributes refer to.
      // It comes back with one of the following: package, class, function, variable declaration.
      // When in error it may return other AST constructs depending on the context.
      // The input is a possible attribute in the form of 'QualifiedIdentifier' or a sequence
      // 'QualifiedIdentifier Arguments' or null when the first attribute was a Modifier.
      // The whole sequence may be an error in the first place, so we want to keep
      // things such that we can always parse the supposed list of attributes as an ast list
      //---------------------------------------------------------------------------------------

      AST ParseAttributes(AST statement, bool unambiguousContext, bool isInsideClass, out bool parsedOK){

        // used later to verify whether anything at all has been processed
        AST inputAST = statement;

        // keep two list of errors. One holds the 'missing ;' errors that would result in the token
        // stream being parsed as a list of expressions, the other is the list of attributes errors
        // that would result from the token stream being parsed as a list of attributes. We need both because
        // we don't know until the end which is which
        ArrayList semicolonErrors = new ArrayList();

        // keep track of the modifiers context in case they'll have to be parsed as identifiers, we give the warning out
        ArrayList modifiersAsIdentifier = new ArrayList();

        // this list has two elements for each error, the first (even position - 0 based) is the error type
        // the second is the context
        ArrayList attributesErrors = new ArrayList();

        // keep the last ast node parsed. Used if we have to "revert" to the expression list production.
        // We just return the last ast processed, after all is an error condition
        AST lastAST = null;

        // keep the list of attributes
        ArrayList attributes = new ArrayList();

        // hold the context for the 'abstract' keyword and it is used as a flag for its presence
        Context abstractContext = null;
        // hold the context for the 'static' keyword and it is used as a flag for its presence
        Context staticContext = null;
        // hold the context for the 'final' keyword and it is used as a flag for its presence
        Context finalContext = null;

        // keep the number of consecutive token no separated by end of line. Once that number
        // reaches 2 the token stream is parsed *only* as a sequence of attributes
        int TokenCountNoEOL = 0;
        if (unambiguousContext)
          TokenCountNoEOL = 2;

        FieldAttributes visibilitySpec = (FieldAttributes)0, currVis = (FieldAttributes)0;

        Context statementContext = null;
        // null when coming from a visibility modifier
        if (statement != null){
          lastAST = statement;
          attributes.Add(statement);
          semicolonErrors.Add(CurrentPositionContext());
          statementContext = statement.context.Clone();
          TokenCountNoEOL = 1;
        }else{
          statementContext = this.currentToken.Clone();
        }

        parsedOK = true;
        while (true){
          JSToken attributeToken = JSToken.None;
          switch (this.currentToken.token){
            case JSToken.Public:
            case JSToken.Static:
            case JSToken.Private:
            case JSToken.Protected:
            case JSToken.Abstract:
            case JSToken.Final:
            case JSToken.Internal:
              attributeToken = this.currentToken.token;
              goto case JSToken.Identifier;
            case JSToken.Var:
            case JSToken.Const:
              for (int i = 0, n = attributesErrors.Count; i < n; i += 2)
                ReportError((JSError)attributesErrors[i], (Context)attributesErrors[i + 1], true);
              if (abstractContext != null)
                ReportError(JSError.IllegalVisibility, abstractContext, true);
              if (finalContext != null)
                ReportError(JSError.IllegalVisibility, finalContext, true);
              statementContext.UpdateWith(this.currentToken);
              return ParseVariableStatement(visibilitySpec, FromASTListToCustomAttributeList(attributes), this.currentToken.token);
            case JSToken.Function:
              for (int i = 0, n = attributesErrors.Count; i < n; i += 2)
                ReportError((JSError)attributesErrors[i], (Context)attributesErrors[i + 1], true);
              statementContext.UpdateWith(this.currentToken);
              if (staticContext != null)
                if (abstractContext != null){
                  staticContext.HandleError(JSError.AbstractCannotBeStatic);
                  staticContext = null;
                }else if (finalContext != null){
                  finalContext.HandleError(JSError.StaticIsAlreadyFinal);
                  finalContext = null;
                }
              if (abstractContext != null){
                if (finalContext != null){
                  finalContext.HandleError(JSError.FinalPrecludesAbstract);
                  finalContext = null;
                }
                if (currVis == FieldAttributes.Private){
                  abstractContext.HandleError(JSError.AbstractCannotBePrivate);
                  currVis = FieldAttributes.Family;
                }
              }
              return ParseFunction(visibilitySpec, false, statementContext, isInsideClass,
                                   abstractContext != null, finalContext != null, false, FromASTListToCustomAttributeList(attributes));
            case JSToken.Interface:
              if (abstractContext != null){
                ReportError(JSError.IllegalVisibility, abstractContext, true);
                abstractContext = null;
              }
              if (finalContext != null){
                ReportError(JSError.IllegalVisibility, finalContext, true);
                finalContext = null;
              }
              if (staticContext != null){
                ReportError(JSError.IllegalVisibility, staticContext, true);
                staticContext = null;
              }
              goto case JSToken.Class;
            case JSToken.Class:
              for (int i = 0, n = attributesErrors.Count; i < n; i += 2)
                ReportError((JSError)attributesErrors[i], (Context)attributesErrors[i + 1], true);
              statementContext.UpdateWith(this.currentToken);
              if (finalContext != null && abstractContext != null)
                finalContext.HandleError(JSError.FinalPrecludesAbstract);
              return ParseClass(visibilitySpec, staticContext != null, statementContext,
                                abstractContext != null, finalContext != null, FromASTListToCustomAttributeList(attributes));
            case JSToken.Enum:
              for (int i = 0, n = attributesErrors.Count; i < n; i += 2)
                ReportError((JSError)attributesErrors[i], (Context)attributesErrors[i + 1], true);
              statementContext.UpdateWith(this.currentToken);
              if (abstractContext != null)
                ReportError(JSError.IllegalVisibility, abstractContext, true);
              if (finalContext != null)
                ReportError(JSError.IllegalVisibility, finalContext, true);
              if (staticContext != null)
                ReportError(JSError.IllegalVisibility, staticContext, true);
              return ParseEnum(visibilitySpec, statementContext, FromASTListToCustomAttributeList(attributes));
            case JSToken.Void:
            case JSToken.Boolean:
            case JSToken.Byte:
            case JSToken.Char:
            case JSToken.Double:
            case JSToken.Float:
            case JSToken.Int:
            case JSToken.Long:
            case JSToken.Short: {
              
              // The user has some sequence like "public int foo()", which
              // is probably a C-style function declaration.  Save that away,
              // keep parsing and see if this ends in what looks like a function
              // or variable declaration. 

              parsedOK = false;
              lastAST = new Lookup(this.currentToken);
              attributeToken = JSToken.None;
              attributes.Add(lastAST);
              GetNextToken();
              goto continueLoop;
            }
            case JSToken.Identifier: {
              bool bAssign, canBeAttribute = true;
              statement = ParseUnaryExpression(out bAssign, ref canBeAttribute, false, attributeToken == JSToken.None);
              lastAST = statement;
              if (attributeToken != JSToken.None){
                if (statement is Lookup)
                  break;
                else{
                  if (TokenCountNoEOL != 2)
                    modifiersAsIdentifier.Add(this.currentToken.Clone());
                }
              }
              attributeToken = JSToken.None;
              if (canBeAttribute){
                attributes.Add(statement);
                goto continueLoop;
              }else
                goto default;
            }
            // the following cases are somewhat interesting because they can be determined by a user missing
            // the keyword 'var' or 'function', as, for instance, when coming from C/C++/C# code
            default:
              parsedOK = false;
              if (TokenCountNoEOL != 2){
                if (inputAST != statement || statement == null){
                  Debug.Assert(lastAST != null);
                  // only return the last statement
                  statement = lastAST;
                  // output the semicolon errors
                  for (int i = 0, n = modifiersAsIdentifier.Count; i < n; i++)
                    ForceReportInfo((Context)modifiersAsIdentifier[i], JSError.KeywordUsedAsIdentifier);
                  for (int i = 0, n = semicolonErrors.Count; i < n; i++)
                    if (!this.currentToken.Equals((Context)semicolonErrors[i]))
                      ReportError(JSError.NoSemicolon, (Context)semicolonErrors[i], true);
                }
                return statement;
              }else{
                if (attributes.Count > 0){
                  // check for possible common mistakes
                  AST ast = (AST)attributes[attributes.Count - 1];
                  if (ast is Lookup){
                    if (JSToken.Semicolon == this.currentToken.token
                        || JSToken.Colon == this.currentToken.token){
                      ReportError(JSError.BadVariableDeclaration, ast.context.Clone());
                      SkipTokensAndThrow();
                    }
                  }else if (ast is Call && ((Call)ast).CanBeFunctionDeclaration()){
                    if (JSToken.Colon == this.currentToken.token
                        || JSToken.LeftCurly == this.currentToken.token){
                      ReportError(JSError.BadFunctionDeclaration, ast.context.Clone(), true);
                      if (JSToken.Colon == this.currentToken.token){
                        this.noSkipTokenSet.Add(NoSkipTokenSet.s_StartBlockNoSkipTokenSet);
                        try{
                          SkipTokensAndThrow();
                        }catch(RecoveryTokenException){
                        }finally{
                          this.noSkipTokenSet.Remove(NoSkipTokenSet.s_StartBlockNoSkipTokenSet);
                        }
                      }
                      this.errorToken = null;
                      if (JSToken.LeftCurly == this.currentToken.token){
                        FunctionScope fscope = new FunctionScope(Globals.ScopeStack.Peek(), isInsideClass);
                        Globals.ScopeStack.Push(fscope);
                        try{
                          ParseBlock();
                        }finally{
                          Globals.ScopeStack.Pop();
                        }
                        SkipTokensAndThrow();
                      }
                    }
                    else
                      ReportError(JSError.SyntaxError, ast.context.Clone());
                    SkipTokensAndThrow();
                  }
                }

                if (JSToken.LeftCurly == this.currentToken.token){
                  if (isInsideClass){
                    // parse it like a static initializer

                    // flush all the possible attribute errors
                    for (int i = 0, n = attributesErrors.Count; i < n; i += 2)
                      ReportError((JSError)attributesErrors[i], (Context)attributesErrors[i + 1]);
                    if (staticContext == null)
                      ReportError(JSError.StaticMissingInStaticInit, CurrentPositionContext());
                    String className = ((ClassScope)Globals.ScopeStack.Peek()).name;
                    bool reportNoIdentifier = true;
                    foreach (Object attr in attributes){
                      reportNoIdentifier = false;
                      if (staticContext != null && attr is Lookup && attr.ToString() == className &&
                          ((Lookup)attr).context.StartColumn > staticContext.StartColumn)
                        continue;
                      ReportError(JSError.SyntaxError, ((AST)attr).context);
                    }
                    if (reportNoIdentifier)
                      ReportError(JSError.NoIdentifier, CurrentPositionContext());

                    this.errorToken = null; // we want to go to next token regardless of whether or not we had an error
                    // return a static initializer
                    parsedOK = true;
                    return ParseStaticInitializer(statementContext);
                  }
                }

                //mark them all as errors
                ReportError(JSError.MissingConstructForAttributes, statementContext.CombineWith(this.currentToken));
              }

              SkipTokensAndThrow();
              break;
          }

          switch (attributeToken){
            case JSToken.Public:
              currVis = FieldAttributes.Public;
              break;
            case JSToken.Static:
              if (isInsideClass){
                currVis = FieldAttributes.Static;
                if (staticContext != null){
                  attributesErrors.Add(JSError.SyntaxError);
                  attributesErrors.Add(statement.context.Clone());
                }else
                  staticContext = statement.context.Clone();
              }else{
                attributesErrors.Add(JSError.NotInsideClass);
                attributesErrors.Add(statement.context.Clone());
              }
              break;
            case JSToken.Private:
              if (isInsideClass)
                currVis = FieldAttributes.Private;
              else{
                attributesErrors.Add(JSError.NotInsideClass);
                attributesErrors.Add(statement.context.Clone());
              }
              break;
            case JSToken.Protected:
              if (isInsideClass){
                currVis = FieldAttributes.Family;
              }else{
                attributesErrors.Add(JSError.NotInsideClass);
                attributesErrors.Add(statement.context.Clone());
              }
              break;
            case JSToken.Abstract:
              if (abstractContext != null){
                attributesErrors.Add(JSError.SyntaxError);
                attributesErrors.Add(statement.context.Clone());
              }else
                abstractContext = statement.context.Clone();
              goto continueLoop;
            case JSToken.Final:
              if (finalContext != null){
                attributesErrors.Add(JSError.SyntaxError);
                attributesErrors.Add(statement.context.Clone());
              }else
                finalContext = statement.context.Clone();
              goto continueLoop;
            case JSToken.Internal:
              currVis = FieldAttributes.Assembly;
              break;
            default:
              break;
          }
          // come here only after a visibility Modifer
          if ((visibilitySpec & FieldAttributes.FieldAccessMask) == currVis && currVis != (FieldAttributes)0){
            attributesErrors.Add(JSError.DupVisibility);
            attributesErrors.Add(statement.context.Clone());
          }else if ((visibilitySpec & FieldAttributes.FieldAccessMask) > (FieldAttributes)0 && (currVis & FieldAttributes.FieldAccessMask) > (FieldAttributes)0){
            if ((currVis == FieldAttributes.Family && (visibilitySpec & FieldAttributes.FieldAccessMask) ==  FieldAttributes.Assembly) ||
                (currVis == FieldAttributes.Assembly && (visibilitySpec & FieldAttributes.FieldAccessMask) ==  FieldAttributes.Family)){
              visibilitySpec &= ~FieldAttributes.FieldAccessMask;
              visibilitySpec |= FieldAttributes.FamORAssem;
            }else{
              attributesErrors.Add(JSError.IncompatibleVisibility);
              attributesErrors.Add(statement.context.Clone());
            }
          }else{
            visibilitySpec |= currVis;
            statementContext.UpdateWith(statement.context);
          }
        continueLoop:
          if (TokenCountNoEOL != 2){
            if (this.scanner.GotEndOfLine()){
              TokenCountNoEOL = 0;
            }else{
              TokenCountNoEOL++;
              semicolonErrors.Add(this.currentToken.Clone());
            }
          }
        }
      }
 private AST ParseFunction(FieldAttributes visibilitySpec, bool inExpression, Context fncCtx, bool isMethod, bool isAbstract, bool isFinal, bool isInterface, CustomAttributeList customAttributes, Call function)
 {
     AST ast2;
     if (this.demandFullTrustOnFunctionCreation)
     {
         new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
     }
     IdentifierLiteral id = null;
     AST rootObject = null;
     ArrayList parameters = null;
     TypeExpression expression = null;
     Block body = null;
     bool isGetter = false;
     bool isSetter = false;
     if (function == null)
     {
         this.GetNextToken();
         if (isMethod)
         {
             if (JSToken.Get == this.currentToken.token)
             {
                 isGetter = true;
                 this.GetNextToken();
             }
             else if (JSToken.Set == this.currentToken.token)
             {
                 isSetter = true;
                 this.GetNextToken();
             }
         }
         if (JSToken.Identifier == this.currentToken.token)
         {
             id = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone());
             this.GetNextToken();
             if (JSToken.AccessField == this.currentToken.token)
             {
                 if (isInterface)
                 {
                     this.ReportError(JSError.SyntaxError, true);
                 }
                 this.GetNextToken();
                 if (JSToken.Identifier == this.currentToken.token)
                 {
                     rootObject = new Lookup(id.context);
                     id = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone());
                     this.GetNextToken();
                     while (JSToken.AccessField == this.currentToken.token)
                     {
                         this.GetNextToken();
                         if (JSToken.Identifier == this.currentToken.token)
                         {
                             rootObject = new Member(rootObject.context.CombineWith(this.currentToken), rootObject, new ConstantWrapper(id.ToString(), id.context));
                             id = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone());
                             this.GetNextToken();
                         }
                         else
                         {
                             this.ReportError(JSError.NoIdentifier, true);
                         }
                     }
                 }
                 else
                 {
                     this.ReportError(JSError.NoIdentifier, true);
                 }
             }
         }
         else
         {
             string identifier = JSKeyword.CanBeIdentifier(this.currentToken.token);
             if (identifier != null)
             {
                 this.ForceReportInfo(JSError.KeywordUsedAsIdentifier, isMethod);
                 id = new IdentifierLiteral(identifier, this.currentToken.Clone());
                 this.GetNextToken();
             }
             else
             {
                 if (!inExpression)
                 {
                     identifier = this.currentToken.GetCode();
                     this.ReportError(JSError.NoIdentifier, true);
                     this.GetNextToken();
                 }
                 else
                 {
                     identifier = "";
                 }
                 id = new IdentifierLiteral(identifier, this.CurrentPositionContext());
             }
         }
     }
     else
     {
         id = function.GetName();
     }
     ArrayList blockType = this.blockType;
     this.blockType = new ArrayList(0x10);
     SimpleHashtable labelTable = this.labelTable;
     this.labelTable = new SimpleHashtable(0x10);
     FunctionScope item = new FunctionScope(this.Globals.ScopeStack.Peek(), isMethod);
     this.Globals.ScopeStack.Push(item);
     try
     {
         parameters = new ArrayList();
         Context context = null;
         if (function == null)
         {
             if (JSToken.LeftParen != this.currentToken.token)
             {
                 this.ReportError(JSError.NoLeftParen);
             }
             this.GetNextToken();
             while (JSToken.RightParen != this.currentToken.token)
             {
                 if (context != null)
                 {
                     this.ReportError(JSError.ParamListNotLast, context, true);
                     context = null;
                 }
                 string str2 = null;
                 TypeExpression type = null;
                 this.noSkipTokenSet.Add(NoSkipTokenSet.s_FunctionDeclNoSkipTokenSet);
                 try
                 {
                     try
                     {
                         if (JSToken.ParamArray == this.currentToken.token)
                         {
                             context = this.currentToken.Clone();
                             this.GetNextToken();
                         }
                         if ((JSToken.Identifier != this.currentToken.token) && ((str2 = JSKeyword.CanBeIdentifier(this.currentToken.token)) == null))
                         {
                             if (JSToken.LeftCurly == this.currentToken.token)
                             {
                                 this.ReportError(JSError.NoRightParen);
                                 break;
                             }
                             if (JSToken.Comma == this.currentToken.token)
                             {
                                 this.ReportError(JSError.SyntaxError, true);
                             }
                             else
                             {
                                 this.ReportError(JSError.SyntaxError, true);
                                 this.SkipTokensAndThrow();
                             }
                         }
                         else
                         {
                             if (str2 == null)
                             {
                                 str2 = this.scanner.GetIdentifier();
                             }
                             else
                             {
                                 this.ForceReportInfo(JSError.KeywordUsedAsIdentifier);
                             }
                             Context context2 = this.currentToken.Clone();
                             this.GetNextToken();
                             if (JSToken.Colon == this.currentToken.token)
                             {
                                 type = this.ParseTypeExpression();
                                 if (type != null)
                                 {
                                     context2.UpdateWith(type.context);
                                 }
                             }
                             CustomAttributeList list3 = null;
                             if (context != null)
                             {
                                 list3 = new CustomAttributeList(context);
                                 list3.Append(new Microsoft.JScript.CustomAttribute(context, new Lookup("...", context), new ASTList(null)));
                             }
                             parameters.Add(new ParameterDeclaration(context2, str2, type, list3));
                         }
                         if (JSToken.RightParen == this.currentToken.token)
                         {
                             break;
                         }
                         if (JSToken.Comma != this.currentToken.token)
                         {
                             if (JSToken.LeftCurly == this.currentToken.token)
                             {
                                 this.ReportError(JSError.NoRightParen);
                                 break;
                             }
                             if ((JSToken.Identifier == this.currentToken.token) && (type == null))
                             {
                                 this.ReportError(JSError.NoCommaOrTypeDefinitionError);
                             }
                             else
                             {
                                 this.ReportError(JSError.NoComma);
                             }
                         }
                         this.GetNextToken();
                     }
                     catch (RecoveryTokenException exception)
                     {
                         if (this.IndexOfToken(NoSkipTokenSet.s_FunctionDeclNoSkipTokenSet, exception) == -1)
                         {
                             throw exception;
                         }
                     }
                     continue;
                 }
                 finally
                 {
                     this.noSkipTokenSet.Remove(NoSkipTokenSet.s_FunctionDeclNoSkipTokenSet);
                 }
             }
             fncCtx.UpdateWith(this.currentToken);
             if (isGetter && (parameters.Count != 0))
             {
                 this.ReportError(JSError.BadPropertyDeclaration, true);
                 isGetter = false;
             }
             else if (isSetter && (parameters.Count != 1))
             {
                 this.ReportError(JSError.BadPropertyDeclaration, true);
                 isSetter = false;
             }
             this.GetNextToken();
             if (JSToken.Colon == this.currentToken.token)
             {
                 if (isSetter)
                 {
                     this.ReportError(JSError.SyntaxError);
                 }
                 this.noSkipTokenSet.Add(NoSkipTokenSet.s_StartBlockNoSkipTokenSet);
                 try
                 {
                     expression = this.ParseTypeExpression();
                 }
                 catch (RecoveryTokenException exception2)
                 {
                     if (this.IndexOfToken(NoSkipTokenSet.s_StartBlockNoSkipTokenSet, exception2) == -1)
                     {
                         exception2._partiallyComputedNode = null;
                         throw exception2;
                     }
                     if (exception2._partiallyComputedNode != null)
                     {
                         expression = (TypeExpression) exception2._partiallyComputedNode;
                     }
                 }
                 finally
                 {
                     this.noSkipTokenSet.Remove(NoSkipTokenSet.s_StartBlockNoSkipTokenSet);
                 }
                 if (isSetter)
                 {
                     expression = null;
                 }
             }
         }
         else
         {
             function.GetParameters(parameters);
         }
         if ((JSToken.LeftCurly != this.currentToken.token) && (isAbstract || (isMethod && this.GuessIfAbstract())))
         {
             if (!isAbstract)
             {
                 isAbstract = true;
                 this.ReportError(JSError.ShouldBeAbstract, fncCtx, true);
             }
             body = new Block(this.currentToken.Clone());
         }
         else
         {
             if (JSToken.LeftCurly != this.currentToken.token)
             {
                 this.ReportError(JSError.NoLeftCurly, true);
             }
             else if (isAbstract)
             {
                 this.ReportError(JSError.AbstractWithBody, fncCtx, true);
             }
             this.blockType.Add(BlockType.Block);
             this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockNoSkipTokenSet);
             this.noSkipTokenSet.Add(NoSkipTokenSet.s_StartStatementNoSkipTokenSet);
             try
             {
                 body = new Block(this.currentToken.Clone());
                 this.GetNextToken();
                 while (JSToken.RightCurly != this.currentToken.token)
                 {
                     try
                     {
                         body.Append(this.ParseStatement());
                         continue;
                     }
                     catch (RecoveryTokenException exception3)
                     {
                         if (exception3._partiallyComputedNode != null)
                         {
                             body.Append(exception3._partiallyComputedNode);
                         }
                         if (this.IndexOfToken(NoSkipTokenSet.s_StartStatementNoSkipTokenSet, exception3) == -1)
                         {
                             throw exception3;
                         }
                         continue;
                     }
                 }
                 body.context.UpdateWith(this.currentToken);
                 fncCtx.UpdateWith(this.currentToken);
             }
             catch (RecoveryTokenException exception4)
             {
                 if (this.IndexOfToken(NoSkipTokenSet.s_BlockNoSkipTokenSet, exception4) == -1)
                 {
                     this.Globals.ScopeStack.Pop();
                     try
                     {
                         ParameterDeclaration[] declarationArray = new ParameterDeclaration[parameters.Count];
                         parameters.CopyTo(declarationArray);
                         if (inExpression)
                         {
                             exception4._partiallyComputedNode = new FunctionExpression(fncCtx, id, declarationArray, expression, body, item, visibilitySpec);
                         }
                         else
                         {
                             exception4._partiallyComputedNode = new FunctionDeclaration(fncCtx, rootObject, id, declarationArray, expression, body, item, visibilitySpec, isMethod, isGetter, isSetter, isAbstract, isFinal, customAttributes);
                         }
                         if (customAttributes != null)
                         {
                             customAttributes.SetTarget(exception4._partiallyComputedNode);
                         }
                     }
                     finally
                     {
                         this.Globals.ScopeStack.Push(item);
                     }
                     throw exception4;
                 }
             }
             finally
             {
                 this.blockType.RemoveAt(this.blockType.Count - 1);
                 this.noSkipTokenSet.Remove(NoSkipTokenSet.s_StartStatementNoSkipTokenSet);
                 this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockNoSkipTokenSet);
             }
             this.GetNextToken();
         }
     }
     finally
     {
         this.blockType = blockType;
         this.labelTable = labelTable;
         this.Globals.ScopeStack.Pop();
     }
     ParameterDeclaration[] array = new ParameterDeclaration[parameters.Count];
     parameters.CopyTo(array);
     if (inExpression)
     {
         ast2 = new FunctionExpression(fncCtx, id, array, expression, body, item, visibilitySpec);
     }
     else
     {
         ast2 = new FunctionDeclaration(fncCtx, rootObject, id, array, expression, body, item, visibilitySpec, isMethod, isGetter, isSetter, isAbstract, isFinal, customAttributes);
     }
     if (customAttributes != null)
     {
         customAttributes.SetTarget(ast2);
     }
     return ast2;
 }
 internal override AST PartiallyEvaluate()
 {
     AST ast = this.identifier = (Lookup) this.identifier.PartiallyEvaluateAsReference();
     if (this.type != null)
     {
         this.field.type = this.type = (TypeExpression) this.type.PartiallyEvaluate();
     }
     else if (((this.initializer == null) && !(this.field is JSLocalField)) && (this.field.value is Microsoft.JScript.Missing))
     {
         ast.context.HandleError(JSError.VariableLeftUninitialized);
         this.field.type = this.type = new TypeExpression(new ConstantWrapper(Typeob.Object, ast.context));
     }
     if (this.initializer != null)
     {
         if (this.field.IsStatic)
         {
             ScriptObject parent = base.Engine.ScriptObjectStackTop();
             ClassScope scope = null;
             while ((parent != null) && ((scope = parent as ClassScope) == null))
             {
                 parent = parent.GetParent();
             }
             if (scope != null)
             {
                 scope.inStaticInitializerCode = true;
             }
             this.initializer = this.initializer.PartiallyEvaluate();
             if (scope != null)
             {
                 scope.inStaticInitializerCode = false;
             }
         }
         else
         {
             this.initializer = this.initializer.PartiallyEvaluate();
         }
         ast.SetPartialValue(this.initializer);
     }
     if ((this.field != null) && (this.field.customAttributes != null))
     {
         this.field.customAttributes.PartiallyEvaluate();
     }
     return this;
 }
 private AST ParseIdentifierInitializer(JSToken inToken, FieldAttributes visibility, CustomAttributeList customAttributes, JSToken kind)
 {
     Lookup identifier = null;
     TypeExpression type = null;
     AST initializer = null;
     RecoveryTokenException exception = null;
     this.GetNextToken();
     if (JSToken.Identifier != this.currentToken.token)
     {
         string name = JSKeyword.CanBeIdentifier(this.currentToken.token);
         if (name != null)
         {
             this.ForceReportInfo(JSError.KeywordUsedAsIdentifier);
             identifier = new Lookup(name, this.currentToken.Clone());
         }
         else
         {
             this.ReportError(JSError.NoIdentifier);
             identifier = new Lookup("#_Missing Identifier_#" + s_cDummyName++, this.CurrentPositionContext());
         }
     }
     else
     {
         identifier = new Lookup(this.scanner.GetIdentifier(), this.currentToken.Clone());
     }
     this.GetNextToken();
     Context context = identifier.context.Clone();
     this.noSkipTokenSet.Add(NoSkipTokenSet.s_VariableDeclNoSkipTokenSet);
     try
     {
         if (JSToken.Colon == this.currentToken.token)
         {
             try
             {
                 type = this.ParseTypeExpression();
             }
             catch (RecoveryTokenException exception2)
             {
                 type = (TypeExpression) exception2._partiallyComputedNode;
                 throw exception2;
             }
             finally
             {
                 if (type != null)
                 {
                     context.UpdateWith(type.context);
                 }
             }
         }
         if ((JSToken.Assign == this.currentToken.token) || (JSToken.Equal == this.currentToken.token))
         {
             if (JSToken.Equal == this.currentToken.token)
             {
                 this.ReportError(JSError.NoEqual, true);
             }
             this.GetNextToken();
             try
             {
                 initializer = this.ParseExpression(true, inToken);
             }
             catch (RecoveryTokenException exception3)
             {
                 initializer = exception3._partiallyComputedNode;
                 throw exception3;
             }
             finally
             {
                 if (initializer != null)
                 {
                     context.UpdateWith(initializer.context);
                 }
             }
         }
     }
     catch (RecoveryTokenException exception4)
     {
         if (this.IndexOfToken(NoSkipTokenSet.s_VariableDeclNoSkipTokenSet, exception4) == -1)
         {
             exception = exception4;
         }
     }
     finally
     {
         this.noSkipTokenSet.Remove(NoSkipTokenSet.s_VariableDeclNoSkipTokenSet);
     }
     AST target = null;
     if (JSToken.Var == kind)
     {
         target = new VariableDeclaration(context, identifier, type, initializer, visibility, customAttributes);
     }
     else
     {
         if (initializer == null)
         {
             this.ForceReportInfo(JSError.NoEqual);
         }
         target = new Constant(context, identifier, type, initializer, visibility, customAttributes);
     }
     if (customAttributes != null)
     {
         customAttributes.SetTarget(target);
     }
     if (exception != null)
     {
         exception._partiallyComputedNode = target;
         throw exception;
     }
     return target;
 }
 internal VariableDeclaration(Context context, Lookup identifier, TypeExpression type, AST initializer, FieldAttributes attributes, CustomAttributeList customAttributes) : base(context)
 {
     if (initializer != null)
     {
         base.context.UpdateWith(initializer.context);
     }
     else if (type != null)
     {
         base.context.UpdateWith(type.context);
     }
     this.identifier = identifier;
     this.type = type;
     this.initializer = initializer;
     ScriptObject parent = base.Globals.ScopeStack.Peek();
     while (parent is WithObject)
     {
         parent = parent.GetParent();
     }
     string name = this.identifier.ToString();
     if (parent is ClassScope)
     {
         if (name == ((ClassScope) parent).name)
         {
             identifier.context.HandleError(JSError.CannotUseNameOfClass);
             name = name + " var";
         }
     }
     else if (attributes != FieldAttributes.PrivateScope)
     {
         base.context.HandleError(JSError.NotInsideClass);
         attributes = FieldAttributes.Public;
     }
     else
     {
         attributes |= FieldAttributes.Public;
     }
     FieldInfo localField = ((IActivationObject) parent).GetLocalField(name);
     if (localField != null)
     {
         if ((localField.IsLiteral || (parent is ClassScope)) || (type != null))
         {
             identifier.context.HandleError(JSError.DuplicateName, true);
         }
         this.type = (TypeExpression) (type = null);
     }
     if (parent is ActivationObject)
     {
         if ((localField == null) || (localField is JSVariableField))
         {
             this.field = ((ActivationObject) parent).AddFieldOrUseExistingField(this.identifier.ToString(), Microsoft.JScript.Missing.Value, attributes);
         }
         else
         {
             this.field = ((ActivationObject) parent).AddNewField(this.identifier.ToString(), null, attributes);
         }
     }
     else
     {
         this.field = ((StackFrame) parent).AddNewField(this.identifier.ToString(), null, attributes | FieldAttributes.Static);
     }
     this.field.type = type;
     this.field.customAttributes = customAttributes;
     this.field.originalContext = context;
     if (this.field is JSLocalField)
     {
         ((JSLocalField) this.field).debugOn = this.identifier.context.document.debugOn;
     }
     this.completion = new Completion();
 }
 private AST ParseEnumMember()
 {
     AST ast = null;
     Lookup identifier = null;
     AST ast2 = null;
     JSToken token = this.currentToken.token;
     if (token == JSToken.Var)
     {
         this.ReportError(JSError.NoVarInEnum, true);
         this.GetNextToken();
         return this.ParseEnumMember();
     }
     if (token != JSToken.Semicolon)
     {
         if (token == JSToken.Identifier)
         {
             identifier = new Lookup(this.currentToken.Clone());
             Context context = this.currentToken.Clone();
             this.GetNextToken();
             if (JSToken.Assign == this.currentToken.token)
             {
                 this.GetNextToken();
                 ast2 = this.ParseExpression(true);
             }
             if (JSToken.Comma == this.currentToken.token)
             {
                 this.GetNextToken();
             }
             else if (JSToken.RightCurly != this.currentToken.token)
             {
                 this.ReportError(JSError.NoComma, true);
             }
             return new Constant(context, identifier, null, ast2, FieldAttributes.Public, null);
         }
         this.ReportError(JSError.SyntaxError, true);
         this.SkipTokensAndThrow();
         return ast;
     }
     this.GetNextToken();
     return this.ParseEnumMember();
 }