1) Fixed issue #714: PHP Parser bug with $this->oR.
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / parser / Parser.java
index 70a2d12..caa1d10 100644 (file)
@@ -862,16 +862,35 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                        case RETURN:
                                expression = null;
                                getNextToken();
+/*
+                               if (token == TokenName.VARIABLE) {
+                                       getNextToken ();
+
+                                       if (token == TokenName.PAAMAYIM_NEKUDOTAYIM) {
+                                               getNextToken ();
+
+                                               if (token != TokenName.IDENTIFIER) {
+                                                       throwSyntaxError("identifier expected after '::'.");
+                                               }
+                                               else {
+                                                       getNextToken ();
+                                               }
+                                       }
+                               }
+*/
                                if (token != TokenName.SEMICOLON) {
                                        expression = expr();
                                }
+
                                if (token == TokenName.SEMICOLON) {
                                        sourceEnd = scanner.getCurrentTokenEndPosition();
                                        getNextToken();
-                               } else {
+                               }
+                               else {
                                        if (token != TokenName.INLINE_HTML) {
                                                throwSyntaxError("';' expected after 'return'.");
                                        }
+
                                        sourceEnd = scanner.getCurrentTokenEndPosition();
                                        getNextToken();
                                }
@@ -1100,16 +1119,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                        case CLASS:
                        case INTERFACE:
                                try {
-                                       TypeDeclaration typeDecl = new TypeDeclaration(
-                                                       this.compilationUnit.compilationResult);
-                                       typeDecl.declarationSourceStart = scanner
-                                                       .getCurrentTokenStartPosition();
-                                       typeDecl.declarationSourceEnd = scanner
-                                                       .getCurrentTokenEndPosition();
+                                       TypeDeclaration typeDecl = new TypeDeclaration (this.compilationUnit.compilationResult);
+                                       typeDecl.declarationSourceStart = scanner.getCurrentTokenStartPosition();
+                                       typeDecl.declarationSourceEnd = scanner.getCurrentTokenEndPosition();
                                        typeDecl.name = new char[] { ' ' };
                                        // default super class
-                                       typeDecl.superclass = new SingleTypeReference(
-                                                       TypeConstants.OBJECT, 0);
+                                       typeDecl.superclass = new SingleTypeReference(TypeConstants.OBJECT, 0);
                                        compilationUnit.types.add(typeDecl);
                                        pushOnAstStack(typeDecl);
                                        unticked_class_declaration_statement(typeDecl);
@@ -1119,6 +1134,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                                        astLengthPtr--;
                                }
                                return statement;
+
                        case LBRACE:
                                getNextToken();
                                if (token != TokenName.RBRACE) {
@@ -1147,12 +1163,22 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                                }
                                else {
                                        if (token == TokenName.RBRACE) {
-                                               reportSyntaxError("';' expected after expression (Found token: "
+                                               reportSyntaxError ("';' expected after expression (Found token: "
                                                                + scanner.toStringAction(token) + ")");
                                        }
                                        else {
-                                               if (token != TokenName.INLINE_HTML && token != TokenName.EOF) {
-                                                       throwSyntaxError("';' expected after expression (Found token: "
+                                               if (token == TokenName.PAAMAYIM_NEKUDOTAYIM) {
+                                                       getNextToken ();
+
+                                                       if (token != TokenName.IDENTIFIER) {
+                                                               throwSyntaxError("identifier expected after '::'.");
+                                                       }
+                                                       else {
+                                                               getNextToken ();
+                                                       }
+                                               }
+                                               else if (token != TokenName.INLINE_HTML && token != TokenName.EOF) {
+                                                       throwSyntaxError ("';' expected after expression (Found token: "
                                                                        + scanner.toStringAction(token) + ")");
                                                }
                                                getNextToken();
@@ -1917,16 +1943,16 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                if (token == TokenName.OP_AND) {
                        getNextToken();
                }
-               
+
                methodDecl.sourceStart = scanner.getCurrentTokenStartPosition();
                methodDecl.sourceEnd = scanner.getCurrentTokenEndPosition();
-               
+
                if (Scanner.isIdentifierOrKeyword (token) ||
                    token == TokenName.LPAREN) {
-                   
+
                    if (token == TokenName.LPAREN) {
                        methodDecl.selector = scanner.getCurrentIdentifierSource();
-                   
+
                 if (token.compareTo (TokenName.KEYWORD) > 0) {
                     problemReporter.phpKeywordWarning (new String[] {scanner.toStringAction(token) },
                                                        scanner.getCurrentTokenStartPosition(),
@@ -1937,7 +1963,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                    }
                    else {
                        methodDecl.selector = scanner.getCurrentIdentifierSource();
-                       
+
                        if (token.compareTo (TokenName.KEYWORD) > 0) {
                            problemReporter.phpKeywordWarning (new String[] {scanner.toStringAction(token) },
                                                                               scanner.getCurrentTokenStartPosition(),
@@ -1945,10 +1971,10 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                                                                               referenceContext,
                                                                               compilationUnit.compilationResult);
                        }
-                       
+
                        getNextToken();
                    }
-                   
+
                        if (token == TokenName.LPAREN) {
                                getNextToken();
                        }
@@ -1956,15 +1982,15 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                                methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
                                throwSyntaxError("'(' expected in function declaration.");
                        }
-                       
+
                        if (token != TokenName.RPAREN) {
                                parameter_list(methodDecl);
                        }
-                       
+
                        if (token != TokenName.RPAREN) {
                                methodDecl.sourceEnd = scanner.getCurrentTokenStartPosition() - 1;
                                throwSyntaxError("')' expected in function declaration.");
-                       } 
+                       }
                        else {
                                methodDecl.bodyStart = scanner.getCurrentTokenEndPosition() + 1;
                                getNextToken();
@@ -2545,7 +2571,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
         * @param only_variable
         * @param initHandler
         */
-       private Expression expr_without_variable (boolean only_variable, 
+       private Expression expr_without_variable (boolean only_variable,
                                                  UninitializedVariableHandler initHandler,
                                                  boolean bColonAllowed) {
                int exprSourceStart    = scanner.getCurrentTokenStartPosition();
@@ -2895,11 +2921,13 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
 
                                        if (token == TokenName.IDENTIFIER) {
                                                lhs = identifier(true, true, bColonAllowed);
+
                                                if (lhs != null) {
                                                        expression = lhs;
                                                }
-                                       } else {
-                                               lhs = variable(true, true);
+                                       }
+                                       else {
+                                               lhs = variable (true, true);
 
                                                if (lhs != null) {
                                                        expression = lhs;
@@ -2991,7 +3019,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                                                                }
                                                        } else {
                                                                Expression rhs = expr_without_variable (only_variable, initHandler, bColonAllowed);
-                                                               
+
                                                                if (lhs != null && lhs instanceof FieldReference) {
                                                                        if (rhs != null && rhs instanceof FieldReference) {
                                                                                // example:
@@ -3031,13 +3059,13 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                                                        if (rememberedVar == false && lhs != null
                                                                        && lhs instanceof FieldReference) {
                                                                if (fMethodVariables != null) {
-                                                                       VariableInfo lhsInfo = new VariableInfo(
-                                                                                       ((FieldReference) lhs).sourceStart);
-                                                                       fMethodVariables.put(new String(
-                                                                                       ((FieldReference) lhs).token), lhsInfo);
+                                                                       VariableInfo lhsInfo = new VariableInfo (((FieldReference) lhs).sourceStart);
+                                                                       fMethodVariables.put (new String (((FieldReference) lhs).token), lhsInfo);
                                                                }
                                                        }
                                                        break;
+                                                       
+                                               case TERNARY_SHORT:
                                                case PLUS_EQUAL:
                                                case MINUS_EQUAL:
                                                case MULTIPLY_EQUAL:
@@ -3235,13 +3263,19 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                                        case INSTANCEOF:
                                                getNextToken();
                                                TypeReference classRef = class_name_reference();
-                                               
+
                                                if (classRef != null) {
                                                        expression = new InstanceOfExpression (expression, classRef, OperatorIds.INSTANCEOF);
                                                        expression.sourceStart = exprSourceStart;
                                                        expression.sourceEnd = scanner.getCurrentTokenEndPosition();
                                                }
                                                break;
+
+                                       case TERNARY_SHORT:
+                                               getNextToken();
+                                               expression = new EqualExpression(expression, expr_without_variable (only_variable, initHandler, bColonAllowed), OperatorIds.TERNARY_SHORT);
+                                               break;
+                                               
                                        case QUESTION:
                                                getNextToken();
                                                Expression valueIfTrue = expr_without_variable (true, null, true);
@@ -3251,8 +3285,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                                                getNextToken();
                                                Expression valueIfFalse = expr();
 
-                                               expression = new ConditionalExpression(expression,
-                                                               valueIfTrue, valueIfFalse);
+                                               expression = new ConditionalExpression (expression, valueIfTrue, valueIfFalse);
                                                break;
                                        default:
                                                return expression;
@@ -3649,34 +3682,49 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                variable_without_objects(false, false);
        }
 
-       private Expression base_variable_with_function_calls(boolean lefthandside,
-                       boolean ignoreVar) {
-               // base_variable_with_function_calls:
-               // base_variable
-               // | function_call
+       /**
+        * base_variable_with_function_calls:
+        * base_variable | function_call
+        *  
+        * @param lefthandside
+        * @param ignoreVar
+        * @return
+        */
+       private Expression base_variable_with_function_calls (boolean lefthandside, boolean ignoreVar) {
                if (Scanner.TRACE) {
                        System.out.println("TRACE: base_variable_with_function_calls()");
                }
+               
                return function_call(lefthandside, ignoreVar);
        }
 
-       private Expression base_variable(boolean lefthandside) {
-               // base_variable:
-               // reference_variable
-               // | simple_indirect_reference reference_variable
-               // | static_member
+       /**
+        * base_variable:
+        * reference_variable
+        * | simple_indirect_reference reference_variable
+        * | static_member
+        * 
+        * @param lefthandside
+        * @return
+        */
+       private Expression base_variable (boolean lefthandside) {
                Expression ref = null;
+               
                if (Scanner.TRACE) {
-                       System.out.println("TRACE: base_variable()");
+                       System.out.println ("TRACE: base_variable()");
                }
+               
                if (token == TokenName.IDENTIFIER) {
-                       static_member();
-               } else {
+                       static_member ();
+               } 
+               else {
                        while (token == TokenName.DOLLAR) {
-                               getNextToken();
+                               getNextToken ();
                        }
-                       reference_variable(lefthandside, false);
+                       
+                       reference_variable (lefthandside, false);
                }
+               
                return ref;
        }
 
@@ -3685,8 +3733,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
        // // '$'
        // //| simple_indirect_reference '$'
        // }
-       private Expression reference_variable(boolean lefthandside,
-                       boolean ignoreVar) {
+       private Expression reference_variable (boolean lefthandside, boolean ignoreVar) {
                // reference_variable:
                // reference_variable '[' dim_offset ']'
                // | reference_variable '{' expr '}'
@@ -3725,51 +3772,59 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                return ref;
        }
 
-       private Expression compound_variable(boolean lefthandside, boolean ignoreVar) {
+       private Expression compound_variable (boolean lefthandside, boolean ignoreVar) {
                // compound_variable:
                // T_VARIABLE
                // | '$' '{' expr '}'
                if (Scanner.TRACE) {
                        System.out.println("TRACE: compound_variable()");
                }
+               
                if (token == TokenName.VARIABLE) {
                        if (!lefthandside) {
                                if (!containsVariableSet()) {
                                        // reportSyntaxError("The local variable " + new
                                        // String(scanner.getCurrentIdentifierSource())
                                        // + " may not have been initialized");
-                                       problemReporter.uninitializedLocalVariable(new String(
-                                                       scanner.getCurrentIdentifierSource()), scanner
-                                                       .getCurrentTokenStartPosition(), scanner
-                                                       .getCurrentTokenEndPosition(), referenceContext,
-                                                       compilationUnit.compilationResult);
+                                       problemReporter.uninitializedLocalVariable (
+                                                       new String (scanner.getCurrentIdentifierSource()), 
+                                                                   scanner.getCurrentTokenStartPosition(),
+                                                                   scanner.getCurrentTokenEndPosition(), 
+                                                                   referenceContext,
+                                                                   compilationUnit.compilationResult);
                                }
                        } else {
                                if (!ignoreVar) {
                                        addVariableSet();
                                }
                        }
-                       FieldReference ref = new FieldReference(scanner
-                                       .getCurrentIdentifierSource(), scanner
-                                       .getCurrentTokenStartPosition());
+                       
+                       FieldReference ref = new FieldReference (scanner.getCurrentIdentifierSource(), 
+                                                                                                        scanner.getCurrentTokenStartPosition());
                        getNextToken();
                        return ref;
-               } else {
+               } 
+               else {
                        // because of simple_indirect_reference
                        while (token == TokenName.DOLLAR) {
                                getNextToken();
                        }
+                       
                        if (token != TokenName.LBRACE) {
                                reportSyntaxError("'{' expected after compound variable token '$'.");
                                return null;
                        }
+                       
                        getNextToken();
                        expr();
+                       
                        if (token != TokenName.RBRACE) {
                                throwSyntaxError("'}' expected after compound variable token '$'.");
                        }
+                       
                        getNextToken();
                }
+               
                return null;
        } // private void dim_offset() { // // dim_offset: // // /* empty */
 
@@ -3783,9 +3838,12 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                if (Scanner.TRACE) {
                        System.out.println("TRACE: object_property()");
                }
-               if (token == TokenName.VARIABLE || token == TokenName.DOLLAR) {
-                       variable_without_objects(false, false);
-               } else {
+               
+               if ((token == TokenName.VARIABLE) || 
+                       (token == TokenName.DOLLAR)) {
+                       variable_without_objects (false, false);
+               } 
+               else {
                        object_dim_list();
                }
        }
@@ -3798,27 +3856,37 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                if (Scanner.TRACE) {
                        System.out.println("TRACE: object_dim_list()");
                }
+               
                variable_name();
+               
                while (true) {
                        if (token == TokenName.LBRACE) {
                                getNextToken();
                                expr();
+                               
                                if (token != TokenName.RBRACE) {
                                        throwSyntaxError("'}' expected in object_dim_list.");
                                }
+                               
                                getNextToken();
-                       } else if (token == TokenName.LBRACKET) {
+                       } 
+                       else if (token == TokenName.LBRACKET) {
                                getNextToken();
+                               
                                if (token == TokenName.RBRACKET) {
                                        getNextToken();
                                        continue;
                                }
+                               
                                expr();
+                               
                                if (token != TokenName.RBRACKET) {
                                        throwSyntaxError("']' expected in object_dim_list.");
                                }
+                               
                                getNextToken();
-                       } else {
+                       } 
+                       else {
                                break;
                        }
                }
@@ -3831,20 +3899,32 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                if (Scanner.TRACE) {
                        System.out.println("TRACE: variable_name()");
                }
-               if (token == TokenName.IDENTIFIER || token.compareTo (TokenName.KEYWORD) > 0) {
+               
+               if ((token == TokenName.IDENTIFIER) || 
+                        (token.compareTo (TokenName.KEYWORD) > 0)) {
                        if (token.compareTo (TokenName.KEYWORD) > 0) {
                                // TODO show a warning "Keyword used as variable" ?
                        }
+                       
                        getNextToken();
-               } else {
+               } 
+               else if ((token == TokenName.OP_AND_OLD) ||                     // If the found token is e.g $var->and
+                                (token == TokenName.OP_OR_OLD)  ||                     // or is $var->or 
+                                (token == TokenName.OP_XOR_OLD)) {                     // or is $var->xor
+                       getNextToken ();                                                                // get the next token. Maybe we should issue an warning?
+               }
+               else {
                        if (token != TokenName.LBRACE) {
                                throwSyntaxError("'{' expected in variable name.");
                        }
+                       
                        getNextToken();
                        expr();
+                       
                        if (token != TokenName.RBRACE) {
                                throwSyntaxError("'}' expected in variable name.");
                        }
+                       
                        getNextToken();
                }
        }
@@ -3861,20 +3941,32 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                variable(false, false);
        }
 
-       private Expression variable(boolean lefthandside, boolean ignoreVar) {
-               // variable:
-               // base_variable_with_function_calls T_OBJECT_OPERATOR
-               // object_property method_or_not variable_properties
-               // | base_variable_with_function_calls
-               Expression ref = base_variable_with_function_calls(lefthandside,
-                               ignoreVar);
-               if (token == TokenName.MINUS_GREATER) {
-                       ref = null;
+       /**
+        * 
+        * variable:
+        * base_variable_with_function_calls T_OBJECT_OPERATOR
+        * object_property method_or_not variable_properties
+        * | base_variable_with_function_calls
+        * 
+        * @param lefthandside
+        * @param ignoreVar
+        * @return
+        */
+       private Expression variable (boolean lefthandside, boolean ignoreVar) {
+               Expression ref = base_variable_with_function_calls (lefthandside, ignoreVar);
+               
+               if ((token == TokenName.MINUS_GREATER) ||
+                   (token == TokenName.PAAMAYIM_NEKUDOTAYIM))  {
+/* I don't know why ref was set to null, but if it is null, the variable will neither be added to the set of variable,
+ * nor would it be checked for beeing unitialized. So I don't set it to null!
+ */
+//                     ref = null;
                        getNextToken();
                        object_property();
                        method_or_not();
                        variable_properties();
                }
+               
                return ref;
        }
 
@@ -3893,11 +3985,13 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                if (Scanner.TRACE) {
                        System.out.println("TRACE: variable_property()");
                }
+               
                if (token == TokenName.MINUS_GREATER) {
                        getNextToken();
                        object_property();
                        method_or_not();
-               } else {
+               } 
+               else {
                        throwSyntaxError("'->' expected in variable_property.");
                }
        }
@@ -4080,9 +4174,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers,
                        method_or_not();
                        variable_properties();
                }
-               
+
                // A colon is only allowed here if it is an expression read after a '?'
-               
+
                if ((token == TokenName.COLON) &&
                    (!bColonAllowed)) {
                    throwSyntaxError ("No ':' allowed");