* 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;
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;
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;
/**
* ClassDeclaration Constructor.
- *
+ *
* @param s
* @param sess
* Description of Parameter
/**
* This method will throw the SyntaxError. It will add the good lines and
* columns to the Error
- *
+ *
* @param error
* the error message
* @throws SyntaxError
/**
* This method will throw the SyntaxError. It will add the good lines and
* columns to the Error
- *
+ *
* @param error
* the error message
* @throws SyntaxError
try {
statement = statement();
blockStatements.add(statement);
+ if (token == TokenNameEOF) {
+ return null;
+ }
if (branchStatement && statement != null) {
// reportSyntaxError("Unreachable code", statement.sourceStart,
// statement.sourceEnd);
new_elseif_list(iState);
} finally {
HashSet set = removeIfVariableSet();
- if (assignedVariableSet != null) {
+ if (assignedVariableSet != null && set != null) {
assignedVariableSet.addAll(set);
}
}
if (assignedVariableSet != null) {
HashSet topSet = peekVariableSet();
if (topSet != null) {
- topSet.addAll(set);
+ if (set != null) {
+ topSet.addAll(set);
+ }
topSet.addAll(assignedVariableSet);
}
}
elseif_list(iState);
} finally {
HashSet set = removeIfVariableSet();
- if (assignedVariableSet != null) {
+ if (assignedVariableSet != null && set != null) {
assignedVariableSet.addAll(set);
}
}
if (assignedVariableSet != null) {
HashSet topSet = peekVariableSet();
if (topSet != null) {
- topSet.addAll(set);
+ if (set != null) {
+ topSet.addAll(set);
+ }
topSet.addAll(assignedVariableSet);
}
}
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) {
if (Scanner.TRACE) {
System.out.println("TRACE: dynamic_class_name_reference()");
}
- base_variable();
+ base_variable(true);
if (token == TokenNameMINUS_GREATER) {
getNextToken();
object_property();
}
}
}
- // 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;
}
return function_call(lefthandside, ignoreVar);
}
- private Expression base_variable() {
+ private Expression base_variable(boolean lefthandside) {
// base_variable:
// reference_variable
// | simple_indirect_reference reference_variable
while (token == TokenNameDOLLAR) {
getNextToken();
}
- reference_variable(false, false);
+ reference_variable(lefthandside, false);
}
return ref;
}
}
}
+ 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 ')'
/**
* Parse and check the include file name
- *
+ *
* @param includeToken
*/
private void checkFileName(int includeToken) {
// /* remember current scanner position */
// int startPos = scanner.startPosition;
// int currentPos = scanner.currentPosition;
- //
+ //
// this.checkAndReportBracketAnomalies(problemReporter());
// /* reset scanner where it was */
// scanner.startPosition = startPos;
"$_SESSION", "$_SERVER" };
/**
- *
+ *
*/
private void pushFunctionVariableSet() {
HashSet set = new HashSet();
/**
* add the current identifier source to the <i>set of assigned variables </i>
- *
+ *
* @param set
*/
private void addVariableSet(HashSet set) {
/**
* add the current identifier source to the <i>set of assigned variables </i>
- *
+ *
*/
private void addVariableSet() {
HashSet set = peekVariableSet();
/**
* add the current identifier source to the <i>set of assigned variables </i>
- *
+ *
*/
private void addVariableSet(char[] token) {
HashSet set = peekVariableSet();
* check if the current identifier source is in the <i>set of assigned
* variables </i> Returns true, if no set is defined for the current scanner
* position
- *
+ *
*/
private boolean containsVariableSet() {
return containsVariableSet(scanner.getCurrentTokenSource());