X-Git-Url: http://secure.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java index b7a1353..4dcd0f8 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/Parser.java @@ -14,6 +14,33 @@ import java.util.HashSet; import net.sourceforge.phpdt.core.compiler.CharOperation; import net.sourceforge.phpdt.core.compiler.ITerminalSymbols; import net.sourceforge.phpdt.core.compiler.InvalidInputException; +import net.sourceforge.phpdt.internal.compiler.ast.AND_AND_Expression; +import net.sourceforge.phpdt.internal.compiler.ast.ASTNode; +import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.BinaryExpression; +import net.sourceforge.phpdt.internal.compiler.ast.Block; +import net.sourceforge.phpdt.internal.compiler.ast.BreakStatement; +import net.sourceforge.phpdt.internal.compiler.ast.CompilationUnitDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.ConditionalExpression; +import net.sourceforge.phpdt.internal.compiler.ast.ContinueStatement; +import net.sourceforge.phpdt.internal.compiler.ast.EqualExpression; +import net.sourceforge.phpdt.internal.compiler.ast.Expression; +import net.sourceforge.phpdt.internal.compiler.ast.FieldDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.FieldReference; +import net.sourceforge.phpdt.internal.compiler.ast.IfStatement; +import net.sourceforge.phpdt.internal.compiler.ast.ImportReference; +import net.sourceforge.phpdt.internal.compiler.ast.InstanceOfExpression; +import net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.OR_OR_Expression; +import net.sourceforge.phpdt.internal.compiler.ast.OperatorIds; +import net.sourceforge.phpdt.internal.compiler.ast.ReturnStatement; +import net.sourceforge.phpdt.internal.compiler.ast.SingleTypeReference; +import net.sourceforge.phpdt.internal.compiler.ast.Statement; +import net.sourceforge.phpdt.internal.compiler.ast.StringLiteral; +import net.sourceforge.phpdt.internal.compiler.ast.StringLiteralDQ; +import net.sourceforge.phpdt.internal.compiler.ast.StringLiteralSQ; +import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.TypeReference; import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions; import net.sourceforge.phpdt.internal.compiler.impl.ReferenceContext; import net.sourceforge.phpdt.internal.compiler.lookup.CompilerModifiers; @@ -23,33 +50,6 @@ import net.sourceforge.phpdt.internal.compiler.problem.ProblemSeverities; import net.sourceforge.phpdt.internal.compiler.util.Util; import net.sourceforge.phpdt.internal.ui.util.PHPFileUtil; import net.sourceforge.phpeclipse.builder.IdentifierIndexManager; -import net.sourceforge.phpeclipse.internal.compiler.ast.AND_AND_Expression; -import net.sourceforge.phpeclipse.internal.compiler.ast.ASTNode; -import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration; -import net.sourceforge.phpeclipse.internal.compiler.ast.BinaryExpression; -import net.sourceforge.phpeclipse.internal.compiler.ast.Block; -import net.sourceforge.phpeclipse.internal.compiler.ast.BreakStatement; -import net.sourceforge.phpeclipse.internal.compiler.ast.CompilationUnitDeclaration; -import net.sourceforge.phpeclipse.internal.compiler.ast.ConditionalExpression; -import net.sourceforge.phpeclipse.internal.compiler.ast.ContinueStatement; -import net.sourceforge.phpeclipse.internal.compiler.ast.EqualExpression; -import net.sourceforge.phpeclipse.internal.compiler.ast.Expression; -import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration; -import net.sourceforge.phpeclipse.internal.compiler.ast.FieldReference; -import net.sourceforge.phpeclipse.internal.compiler.ast.IfStatement; -import net.sourceforge.phpeclipse.internal.compiler.ast.ImportReference; -import net.sourceforge.phpeclipse.internal.compiler.ast.InstanceOfExpression; -import net.sourceforge.phpeclipse.internal.compiler.ast.MethodDeclaration; -import net.sourceforge.phpeclipse.internal.compiler.ast.OR_OR_Expression; -import net.sourceforge.phpeclipse.internal.compiler.ast.OperatorIds; -import net.sourceforge.phpeclipse.internal.compiler.ast.ReturnStatement; -import net.sourceforge.phpeclipse.internal.compiler.ast.SingleTypeReference; -import net.sourceforge.phpeclipse.internal.compiler.ast.Statement; -import net.sourceforge.phpeclipse.internal.compiler.ast.StringLiteral; -import net.sourceforge.phpeclipse.internal.compiler.ast.StringLiteralDQ; -import net.sourceforge.phpeclipse.internal.compiler.ast.StringLiteralSQ; -import net.sourceforge.phpeclipse.internal.compiler.ast.TypeDeclaration; -import net.sourceforge.phpeclipse.internal.compiler.ast.TypeReference; import net.sourceforge.phpeclipse.ui.overlaypages.ProjectPrefUtil; import org.eclipse.core.resources.IFile; @@ -422,6 +422,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI try { statement = statement(); blockStatements.add(statement); + if (token == TokenNameEOF) { + return null; + } if (branchStatement && statement != null) { // reportSyntaxError("Unreachable code", statement.sourceStart, // statement.sourceEnd); @@ -2502,37 +2505,33 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // | rw_variable T_INC // | rw_variable T_DEC case TokenNameIdentifier: - char[] ident = scanner.getCurrentTokenSource(); - Expression lhsIdentifier = identifier(true, true); - if (lhsIdentifier != null) { - expression = lhsIdentifier; - } - if (token == TokenNameEQUAL || token == TokenNamePLUS_EQUAL - || token == TokenNameMINUS_EQUAL || token == TokenNameMULTIPLY_EQUAL || token == TokenNameDIVIDE_EQUAL - || token == TokenNameDOT_EQUAL || token == TokenNameREMAINDER_EQUAL || token == TokenNameAND_EQUAL - || token == TokenNameOR_EQUAL || token == TokenNameXOR_EQUAL || token == TokenNameRIGHT_SHIFT_EQUAL - || token == TokenNameLEFT_SHIFT_EQUAL) { - String error = "Assignment operator '"+scanner.toStringAction(token)+"' not allowed after identifier '"+new String(ident)+"' (use 'define(...)' to define constants)."; - throwSyntaxError(error); - } - break; case TokenNameVariable: case TokenNameDOLLAR: + Expression lhs = null; boolean rememberedVar = false; - Expression lhs = variable(true, true); - if (lhs != null && lhs instanceof FieldReference && token != TokenNameEQUAL && token != TokenNamePLUS_EQUAL - && token != TokenNameMINUS_EQUAL && token != TokenNameMULTIPLY_EQUAL && token != TokenNameDIVIDE_EQUAL - && token != TokenNameDOT_EQUAL && token != TokenNameREMAINDER_EQUAL && token != TokenNameAND_EQUAL - && token != TokenNameOR_EQUAL && token != TokenNameXOR_EQUAL && token != TokenNameRIGHT_SHIFT_EQUAL - && token != TokenNameLEFT_SHIFT_EQUAL) { - FieldReference ref = (FieldReference) lhs; - if (!containsVariableSet(ref.token)) { - problemReporter.uninitializedLocalVariable(new String(ref.token), ref.sourceStart(), ref.sourceEnd(), referenceContext, - compilationUnit.compilationResult); - addVariableSet(ref.token); + if (token == TokenNameIdentifier) { + lhs = identifier(true, true); + if (lhs != null) { + expression = lhs; + } + } else { + lhs = variable(true, true); + if (lhs != null) { + expression = lhs; + } + if (lhs != null && lhs instanceof FieldReference && token != TokenNameEQUAL && token != TokenNamePLUS_EQUAL + && token != TokenNameMINUS_EQUAL && token != TokenNameMULTIPLY_EQUAL && token != TokenNameDIVIDE_EQUAL + && token != TokenNameDOT_EQUAL && token != TokenNameREMAINDER_EQUAL && token != TokenNameAND_EQUAL + && token != TokenNameOR_EQUAL && token != TokenNameXOR_EQUAL && token != TokenNameRIGHT_SHIFT_EQUAL + && token != TokenNameLEFT_SHIFT_EQUAL) { + FieldReference ref = (FieldReference) lhs; + if (!containsVariableSet(ref.token)) { + problemReporter.uninitializedLocalVariable(new String(ref.token), ref.sourceStart(), ref.sourceEnd(), + referenceContext, compilationUnit.compilationResult); + addVariableSet(ref.token); + } } } - switch (token) { case TokenNameEQUAL: if (lhs != null && lhs instanceof FieldReference) { @@ -2788,7 +2787,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (Scanner.TRACE) { System.out.println("TRACE: dynamic_class_name_reference()"); } - base_variable(); + base_variable(true); if (token == TokenNameMINUS_GREATER) { getNextToken(); object_property(); @@ -3014,26 +3013,24 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } } } - // TODO is this ok ? - return ref; - // throwSyntaxError("'(' expected in function call."); - } - getNextToken(); - if (token == TokenNameRPAREN) { + } else { getNextToken(); - return ref; - } - non_empty_function_call_parameter_list(); - if (token != TokenNameRPAREN) { - String functionName; - if (ident == null) { - functionName = new String(" "); - } else { - functionName = new String(ident); + if (token == TokenNameRPAREN) { + getNextToken(); + return ref; + } + non_empty_function_call_parameter_list(); + if (token != TokenNameRPAREN) { + String functionName; + if (ident == null) { + functionName = new String(" "); + } else { + functionName = new String(ident); + } + throwSyntaxError("')' expected in function call (" + functionName + ")."); } - throwSyntaxError("')' expected in function call (" + functionName + ")."); + getNextToken(); } - getNextToken(); return ref; } @@ -3106,7 +3103,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI return function_call(lefthandside, ignoreVar); } - private Expression base_variable() { + private Expression base_variable(boolean lefthandside) { // base_variable: // reference_variable // | simple_indirect_reference reference_variable @@ -3121,7 +3118,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI while (token == TokenNameDOLLAR) { getNextToken(); } - reference_variable(false, false); + reference_variable(lefthandside, false); } return ref; } @@ -3349,7 +3346,113 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // base_variable_with_function_calls T_OBJECT_OPERATOR // object_property method_or_not variable_properties // | base_variable_with_function_calls - return base_variable_with_function_calls(lefthandside, ignoreVar); + + // Expression ref = function_call(lefthandside, ignoreVar); + + // function_call: + // T_STRING '(' function_call_parameter_list ')' + // | class_constant '(' function_call_parameter_list ')' + // | static_member '(' function_call_parameter_list ')' + // | variable_without_objects '(' function_call_parameter_list ')' + char[] defineName = null; + char[] ident = null; + int startPos = 0; + int endPos = 0; + Expression ref = null; + if (Scanner.TRACE) { + System.out.println("TRACE: function_call()"); + } + if (token == TokenNameIdentifier) { + ident = scanner.getCurrentIdentifierSource(); + defineName = ident; + startPos = scanner.getCurrentTokenStartPosition(); + endPos = scanner.getCurrentTokenEndPosition(); + getNextToken(); + + if (token == TokenNameEQUAL || token == TokenNamePLUS_EQUAL || token == TokenNameMINUS_EQUAL + || token == TokenNameMULTIPLY_EQUAL || token == TokenNameDIVIDE_EQUAL || token == TokenNameDOT_EQUAL + || token == TokenNameREMAINDER_EQUAL || token == TokenNameAND_EQUAL || token == TokenNameOR_EQUAL + || token == TokenNameXOR_EQUAL || token == TokenNameRIGHT_SHIFT_EQUAL || token == TokenNameLEFT_SHIFT_EQUAL) { + String error = "Assignment operator '" + scanner.toStringAction(token) + "' not allowed after identifier '" + + new String(ident) + "' (use 'define(...)' to define constants)."; + reportSyntaxError(error); + } + + switch (token) { + case TokenNamePAAMAYIM_NEKUDOTAYIM: + // static member: + defineName = null; + getNextToken(); + if (token == TokenNameIdentifier) { + // class _constant + getNextToken(); + } else { + // static member: + variable_without_objects(true, false); + } + break; + } + } else { + ref = variable_without_objects(lefthandside, ignoreVar); + } + if (token != TokenNameLPAREN) { + if (defineName != null) { + // does this identifier contain only uppercase characters? + if (defineName.length == 3) { + if (defineName[0] == 'd' && defineName[1] == 'i' && defineName[2] == 'e') { + defineName = null; + } + } else if (defineName.length == 4) { + if (defineName[0] == 't' && defineName[1] == 'r' && defineName[2] == 'u' && defineName[3] == 'e') { + defineName = null; + } else if (defineName[0] == 'n' && defineName[1] == 'u' && defineName[2] == 'l' && defineName[3] == 'l') { + defineName = null; + } + } else if (defineName.length == 5) { + if (defineName[0] == 'f' && defineName[1] == 'a' && defineName[2] == 'l' && defineName[3] == 's' && defineName[4] == 'e') { + defineName = null; + } + } + if (defineName != null) { + for (int i = 0; i < defineName.length; i++) { + if (Character.isLowerCase(defineName[i])) { + problemReporter.phpUppercaseIdentifierWarning(startPos, endPos, referenceContext, compilationUnit.compilationResult); + break; + } + } + } + } + // TODO is this ok ? + // return ref; + // throwSyntaxError("'(' expected in function call."); + } else { + getNextToken(); + + if (token == TokenNameRPAREN) { + getNextToken(); + ref = null; + } else { + non_empty_function_call_parameter_list(); + if (token != TokenNameRPAREN) { + String functionName; + if (ident == null) { + functionName = new String(" "); + } else { + functionName = new String(ident); + } + throwSyntaxError("')' expected in function call (" + functionName + ")."); + } + getNextToken(); + } + } + if (token == TokenNameMINUS_GREATER) { + ref = null; + getNextToken(); + object_property(); + method_or_not(); + variable_properties(); + } + return ref; } private void method_or_not() {