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;
try {
statement = statement();
blockStatements.add(statement);
+ if (token == TokenNameEOF) {
+ return null;
+ }
if (branchStatement && statement != null) {
// reportSyntaxError("Unreachable code", statement.sourceStart,
// statement.sourceEnd);
}
if (token == TokenNameif || token == TokenNameswitch || token == TokenNamefor || token == TokenNamewhile
|| token == TokenNamedo || token == TokenNameforeach || token == TokenNamecontinue || token == TokenNamebreak
- || token == TokenNamereturn || token == TokenNameexit || token == TokenNameecho || token == TokenNameglobal
- || token == TokenNamestatic || token == TokenNameunset || token == TokenNamefunction || token == TokenNamedeclare
- || token == TokenNametry || token == TokenNamecatch || token == TokenNamethrow || token == TokenNamefinal
- || token == TokenNameabstract || token == TokenNameclass || token == TokenNameinterface) {
+ || token == TokenNamereturn || token == TokenNameexit || token == TokenNameecho || token == TokenNameECHO_INVISIBLE
+ || token == TokenNameglobal || token == TokenNamestatic || token == TokenNameunset || token == TokenNamefunction
+ || token == TokenNamedeclare || token == TokenNametry || token == TokenNamecatch || token == TokenNamethrow
+ || token == TokenNamefinal || token == TokenNameabstract || token == TokenNameclass || token == TokenNameinterface) {
break;
}
// System.out.println(scanner.toStringAction(token));
getNextToken();
}
return statement;
- } else if (token == TokenNameINLINE_HTML) {
- if (scanner.phpExpressionTag) {
- // start of <?= ... ?> block
+ } else if (token == TokenNameECHO_INVISIBLE) {
+ // 0-length token directly after PHP short tag <?=
+ getNextToken();
+ expressionList();
+ if (token == TokenNameSEMICOLON) {
getNextToken();
- expr();
- if (token == TokenNameSEMICOLON) {
- getNextToken();
- }
+ // if (token != TokenNameINLINE_HTML) {
+ // // TODO should this become a configurable warning?
+ // reportSyntaxError("Probably '?>' expected after PHP short tag
+ // expression (only the first expression will be echoed).");
+ // }
+ } else {
if (token != TokenNameINLINE_HTML) {
- throwSyntaxError("Missing '?>' for open PHP expression block ('<?=').");
+ throwSyntaxError("';' expected after PHP short tag '<?=' expression.");
}
- } else {
getNextToken();
}
return statement;
- // } else if (token == TokenNameprint) {
- // getNextToken();
- // expression();
- // if (token == TokenNameSEMICOLON) {
- // getNextToken();
- // } else {
- // if (token != TokenNameStopPHP) {
- // throwSyntaxError("';' expected after 'print' statement.");
- // }
- // getNextToken();
- // }
- // return;
+ } else if (token == TokenNameINLINE_HTML) {
+ getNextToken();
+ return statement;
} else if (token == TokenNameglobal) {
getNextToken();
global_var_list();
// | non_empty_parameter_list ',' optional_class_type T_VARIABLE '='
// static_scalar
char[] typeIdentifier = null;
- if (token == TokenNameIdentifier || token == TokenNameVariable || token == TokenNameAND) {
+ if (token == TokenNameIdentifier || token == TokenNamearray || token == TokenNameVariable || token == TokenNameAND) {
HashSet set = peekVariableSet();
while (true) {
- if (token == TokenNameIdentifier) {
+ if (token == TokenNameIdentifier || token == TokenNamearray) {// feature req. #1254275
typeIdentifier = scanner.getCurrentIdentifierSource();
getNextToken();
}
expr(); // constant();
if (token == TokenNameCOLON || token == TokenNameSEMICOLON) {
getNextToken();
+ if (token == TokenNameRBRACE) {
+ // empty case; assumes that the '}' token belongs to the wrapping
+ // switch statement - #1371992
+ break;
+ }
if (token == TokenNamecase || token == TokenNamedefault) {
// empty case statement ?
continue;
if (token == TokenNameCOLON || token == TokenNameSEMICOLON) {
getNextToken();
if (token == TokenNameRBRACE) {
- // empty default case
+ // empty default case; ; assumes that the '}' token belongs to the
+ // wrapping switch statement - #1371992
break;
}
if (token != TokenNamecase) {
if (Scanner.TRACE) {
System.out.println("TRACE: expr()");
}
- return expr_without_variable(true);
+ return expr_without_variable(true,null);
// }
}
- private Expression expr_without_variable(boolean only_variable) {
+ private Expression expr_without_variable(boolean only_variable, UninitializedVariableHandler initHandler) {
int exprSourceStart = scanner.getCurrentTokenStartPosition();
int exprSourceEnd = scanner.getCurrentTokenEndPosition();
Expression expression = new Expression();
// | 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)) {
+ if (null==initHandler || initHandler.reportError()) {
+ 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) {
// example:
// $var = & new Object();
if (fMethodVariables != null) {
- VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart());
+ VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart);
lhsInfo.reference = classRef;
lhsInfo.typeIdentifier = classRef.token;
fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo);
if (fMethodVariables != null) {
VariableInfo rhsInfo = (VariableInfo) fMethodVariables.get(((FieldReference) rhs).token);
if (rhsInfo != null && rhsInfo.reference != null) {
- VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart());
+ VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart);
lhsInfo.reference = rhsInfo.reference;
lhsInfo.typeIdentifier = rhsInfo.typeIdentifier;
fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo);
if (fMethodVariables != null) {
VariableInfo rhsInfo = (VariableInfo) fMethodVariables.get(((FieldReference) rhs).token);
if (rhsInfo != null && rhsInfo.reference != null) {
- VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart());
+ VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart);
lhsInfo.reference = rhsInfo.reference;
lhsInfo.typeIdentifier = rhsInfo.typeIdentifier;
fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo);
// example:
// $var = new Object();
if (fMethodVariables != null) {
- VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart());
+ VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart);
lhsInfo.reference = (SingleTypeReference) rhs;
lhsInfo.typeIdentifier = ((SingleTypeReference) rhs).token;
fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo);
}
if (rememberedVar == false && lhs != null && lhs instanceof FieldReference) {
if (fMethodVariables != null) {
- VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart());
+ VariableInfo lhsInfo = new VariableInfo(((FieldReference) lhs).sourceStart);
fMethodVariables.put(new String(((FieldReference) lhs).token), lhsInfo);
}
}
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;
}
+ private void non_empty_function_call_parameter_list() {
+ this.non_empty_function_call_parameter_list(null);
+ }
+
// private void function_call_parameter_list() {
// function_call_parameter_list:
// non_empty_function_call_parameter_list { $$ = $1; }
// | /* empty */
// }
- private void non_empty_function_call_parameter_list() {
+ private void non_empty_function_call_parameter_list(String functionName) {
// non_empty_function_call_parameter_list:
// expr_without_variable
// | variable
if (Scanner.TRACE) {
System.out.println("TRACE: non_empty_function_call_parameter_list()");
}
+ UninitializedVariableHandler initHandler = new UninitializedVariableHandler();
+ initHandler.setFunctionName(functionName);
while (true) {
+ initHandler.incrementArgumentCount();
if (token == TokenNameAND) {
getNextToken();
w_variable(true);
// || token == TokenNameDOLLAR) {
// variable();
// } else {
- expr_without_variable(true);
+ expr_without_variable(true, initHandler);
// }
}
if (token != TokenNameCOMMA) {
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;
}
}
getNextToken();
} else if (token == TokenNameLBRACKET) {
- if (ref != null && ref instanceof FieldReference) {
- FieldReference fref = (FieldReference) ref;
- addVariableSet(fref.token);
- }
- ref = null;
+ // To remove "ref = null;" here, is probably better than the patch
+ // commented in #1368081 - axelcl
getNextToken();
if (token != TokenNameRBRACKET) {
expr();
// 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);
+
+ // 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 {
+ String functionName;
+ if (ident == null) {
+ functionName = new String(" ");
+ } else {
+ functionName = new String(ident);
+ }
+ non_empty_function_call_parameter_list(functionName);
+ if (token != TokenNameRPAREN) {
+ throwSyntaxError("')' expected in function call (" + functionName + ").");
+ }
+ getNextToken();
+ }
+ }
if (token == TokenNameMINUS_GREATER) {
ref = null;
getNextToken();