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 a048341..7035759 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 @@ -2,7 +2,7 @@ * Copyright (c) 2002 www.phpeclipse.de All rights reserved. This program and the accompanying material are made available under the * terms of the Common Public License v1.0 which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html - * + * * Contributors: www.phpeclipse.de **********************************************************************************************************************************/ package net.sourceforge.phpdt.internal.compiler.parser; @@ -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; @@ -99,7 +99,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI /** * ClassDeclaration Constructor. - * + * * @param s * @param sess * Description of Parameter @@ -142,7 +142,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI /** * This method will throw the SyntaxError. It will add the good lines and * columns to the Error - * + * * @param error * the error message * @throws SyntaxError @@ -163,7 +163,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI /** * This method will throw the SyntaxError. It will add the good lines and * columns to the Error - * + * * @param error * the error message * @throws SyntaxError @@ -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); @@ -1803,7 +1806,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI new_elseif_list(iState); } finally { HashSet set = removeIfVariableSet(); - if (assignedVariableSet != null) { + if (assignedVariableSet != null && set != null) { assignedVariableSet.addAll(set); } } @@ -1816,7 +1819,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (assignedVariableSet != null) { HashSet topSet = peekVariableSet(); if (topSet != null) { - topSet.addAll(set); + if (set != null) { + topSet.addAll(set); + } topSet.addAll(assignedVariableSet); } } @@ -1852,7 +1857,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI elseif_list(iState); } finally { HashSet set = removeIfVariableSet(); - if (assignedVariableSet != null) { + if (assignedVariableSet != null && set != null) { assignedVariableSet.addAll(set); } } @@ -1865,7 +1870,9 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI if (assignedVariableSet != null) { HashSet topSet = peekVariableSet(); if (topSet != null) { - topSet.addAll(set); + if (set != null) { + topSet.addAll(set); + } topSet.addAll(assignedVariableSet); } } @@ -2500,21 +2507,31 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI case TokenNameIdentifier: 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) { @@ -3326,6 +3343,120 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI } } + private Expression identifier(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 = 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() { // method_or_not: // '(' function_call_parameter_list ')' @@ -3672,7 +3803,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI /** * Parse and check the include file name - * + * * @param includeToken */ private void checkFileName(int includeToken) { @@ -3971,7 +4102,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI // /* remember current scanner position */ // int startPos = scanner.startPosition; // int currentPos = scanner.currentPosition; - // + // // this.checkAndReportBracketAnomalies(problemReporter()); // /* reset scanner where it was */ // scanner.startPosition = startPos; @@ -4557,7 +4688,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI "$_SESSION", "$_SERVER" }; /** - * + * */ private void pushFunctionVariableSet() { HashSet set = new HashSet(); @@ -4596,7 +4727,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI /** * add the current identifier source to the set of assigned variables - * + * * @param set */ private void addVariableSet(HashSet set) { @@ -4607,7 +4738,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI /** * add the current identifier source to the set of assigned variables - * + * */ private void addVariableSet() { HashSet set = peekVariableSet(); @@ -4618,7 +4749,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI /** * add the current identifier source to the set of assigned variables - * + * */ private void addVariableSet(char[] token) { HashSet set = peekVariableSet(); @@ -4631,7 +4762,7 @@ public class Parser implements ITerminalSymbols, CompilerModifiers, ParserBasicI * check if the current identifier source is in the set of assigned * variables Returns true, if no set is defined for the current scanner * position - * + * */ private boolean containsVariableSet() { return containsVariableSet(scanner.getCurrentTokenSource());