Exemplo n.º 1
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 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);
        }