Skip to content
Browse files

Expression callback was not receiving Call Arguments correctly

  • Loading branch information...
1 parent 6d26c2e commit b17671578adf64467e30b04b2b46983728b00b45 @robertop committed Jun 1, 2012
View
1 include/pelet/ParserTypeClass.h
@@ -568,6 +568,7 @@ class PELET_API ExpressionClass : public StatementClass {
void Clear();
void Copy(const ExpressionClass& src);
+ void Copy(const VariableClass& variable);
UnicodeString FirstValue() const;
View
12 src/ParserObserverClass.cpp
@@ -725,6 +725,12 @@ pelet::VariableClass* pelet::ObserverQuadClass::VariableMakeFunctionCall(pelet::
pelet::ExpressionClass* singleExpr = (pelet::ExpressionClass*) callArguments->At(i);
newVar->CallArguments.push_back(*singleExpr);
}
+ else if (pelet::StatementClass::VARIABLE == type) {
+ pelet::VariableClass* var = (pelet::VariableClass*) callArguments->At(i);
+ pelet::ExpressionClass singleExpr(var->Scope);
+ singleExpr.Copy(*var);
+ newVar->CallArguments.push_back(singleExpr);
+ }
}
AllAstItems.push_back(newVar);
return newVar;
@@ -1390,11 +1396,7 @@ pelet::TraitUseClass* pelet::ObserverQuadClass::TraitUseStart(pelet::QualifiedNa
}
pelet::ExpressionClass* pelet::ObserverQuadClass::ExpressionMakeFromVariable(pelet::VariableClass* variableValue) {
pelet::ExpressionClass* expr = new pelet::ExpressionClass(Scope);
- expr->ExpressionType = pelet::ExpressionClass::VARIABLE;
- expr->ChainList = variableValue->ChainList;
- expr->CallArguments = variableValue->CallArguments;
- expr->LineNumber = variableValue->LineNumber;
- expr->Comment = variableValue->Comment;
+ expr->Copy(*variableValue);
AllAstItems.push_back(expr);
return expr;
}
View
13 src/ParserTypeClass.cpp
@@ -521,6 +521,19 @@ void pelet::ExpressionClass::Copy(const pelet::ExpressionClass& src) {
LineNumber = src.LineNumber;
}
+void pelet::ExpressionClass::Copy(const pelet::VariableClass& variable) {
+ Comment = variable.Comment;
+ Scope = variable.Scope;
+ CallArguments = variable.CallArguments;
+ ChainList = variable.ChainList;
+ ArrayKeys.clear();
+ if (!variable.ArrayKey.isEmpty()) {
+ ArrayKeys.push_back(variable.ArrayKey);
+ }
+ ExpressionType = pelet::ExpressionClass::VARIABLE;
+ LineNumber = variable.LineNumber;
+}
+
UnicodeString pelet::ExpressionClass::FirstValue() const {
UnicodeString str;
if (!ChainList.empty()) {
View
44 tests/Parser53TestClass.cpp
@@ -848,6 +848,50 @@ TEST_FIXTURE(Parser53TestClass, NamespaceVariables) {
CHECK_UNISTR_EQUALS("\\Second\\Child\\MyClass", Observer.VariableExpressionChainList[7]);
}
+TEST_FIXTURE(Parser53TestClass, ExpressionObserver) {
+ Parser.SetExpressionObserver(&Observer);
+ UnicodeString code = _U(
+ "myFunct('one', $arr); \n"
+ "anotherFunc(myFunct('three', $four), myFunct(array('key_one' => 1)));\n"
+ );
+
+ CHECK(Parser.ScanString(code, LintResults));
+ CHECK_VECTOR_SIZE(2, Observer.Expressions);
+ CHECK_VECTOR_SIZE(1, Observer.Expressions[0].ChainList);
+
+ // the first line
+ pelet::ExpressionClass expr = Observer.Expressions[0];
+ CHECK_UNISTR_EQUALS("myFunct()", expr.ChainList[0]);
+ CHECK_VECTOR_SIZE(2, Observer.Expressions[0].CallArguments);
+ CHECK_EQUAL(pelet::ExpressionClass::SCALAR, expr.CallArguments[0].ExpressionType);
+ CHECK_UNISTR_EQUALS("one", expr.CallArguments[0].ChainList[0]);
+ CHECK_EQUAL(pelet::ExpressionClass::VARIABLE, expr.CallArguments[1].ExpressionType);
+ CHECK_UNISTR_EQUALS("$arr", expr.CallArguments[1].ChainList[0]);
+
+ // the second line big expression here....
+ expr = Observer.Expressions[1];
+ // 1. the outermost expression (call to anotherFunc)
+ CHECK_EQUAL(pelet::ExpressionClass::VARIABLE, expr.ExpressionType);
+ CHECK_UNISTR_EQUALS("anotherFunc()", expr.ChainList[0]);
+ CHECK_VECTOR_SIZE(2, expr.CallArguments);
+
+ // 2. the first arg to anotherFunc (call to myFunct with 2 arguments)
+ pelet::ExpressionClass arg1 = expr.CallArguments[0];
+ CHECK_UNISTR_EQUALS("myFunct()", arg1.ChainList[0]);
+ CHECK_VECTOR_SIZE(2, arg1.CallArguments);
+ CHECK_UNISTR_EQUALS("three", arg1.CallArguments[0].ChainList[0]);
+ CHECK_UNISTR_EQUALS("$four", arg1.CallArguments[1].ChainList[0]);
+
+
+ // 3. second arg to anotherFunc (call with 1 argument)
+ pelet::ExpressionClass arg2 = expr.CallArguments[1];
+ CHECK_UNISTR_EQUALS("myFunct()", arg2.ChainList[0]);
+ CHECK_VECTOR_SIZE(1, arg2.CallArguments);
+ CHECK_EQUAL(pelet::ExpressionClass::ARRAY, arg2.CallArguments[0].ExpressionType);
+ CHECK_VECTOR_SIZE(1, arg2.CallArguments[0].ArrayKeys);
+ CHECK_UNISTR_EQUALS("key_one", arg2.CallArguments[0].ArrayKeys[0]);
+}
+
TEST_FIXTURE(Parser53TestClass, LintFileShouldReturnTrueOnValidFile) {
std::string file = TestProjectDir + "test.php";
CHECK(Parser.LintFile(file, LintResults));
View
44 tests/Parser54TestClass.cpp
@@ -1089,6 +1089,50 @@ TEST_FIXTURE(Parser54TestClass, NamespaceVariables) {
CHECK_UNISTR_EQUALS("\\Second\\Child\\MyClass", Observer.VariableExpressionChainList[7]);
}
+TEST_FIXTURE(Parser54TestClass, ExpressionObserver) {
+ Parser.SetExpressionObserver(&Observer);
+ UnicodeString code = _U(
+ "myFunct('one', $arr); \n"
+ "anotherFunc(myFunct('three', $four), myFunct(array('key_one' => 1)));\n"
+ );
+
+ CHECK(Parser.ScanString(code, LintResults));
+ CHECK_VECTOR_SIZE(2, Observer.Expressions);
+ CHECK_VECTOR_SIZE(1, Observer.Expressions[0].ChainList);
+
+ // the first line
+ pelet::ExpressionClass expr = Observer.Expressions[0];
+ CHECK_UNISTR_EQUALS("myFunct()", expr.ChainList[0]);
+ CHECK_VECTOR_SIZE(2, Observer.Expressions[0].CallArguments);
+ CHECK_EQUAL(pelet::ExpressionClass::SCALAR, expr.CallArguments[0].ExpressionType);
+ CHECK_UNISTR_EQUALS("one", expr.CallArguments[0].ChainList[0]);
+ CHECK_EQUAL(pelet::ExpressionClass::VARIABLE, expr.CallArguments[1].ExpressionType);
+ CHECK_UNISTR_EQUALS("$arr", expr.CallArguments[1].ChainList[0]);
+
+ // the second line big expression here....
+ expr = Observer.Expressions[1];
+ // 1. the outermost expression (call to anotherFunc)
+ CHECK_EQUAL(pelet::ExpressionClass::VARIABLE, expr.ExpressionType);
+ CHECK_UNISTR_EQUALS("anotherFunc()", expr.ChainList[0]);
+ CHECK_VECTOR_SIZE(2, expr.CallArguments);
+
+ // 2. the first arg to anotherFunc (call to myFunct with 2 arguments)
+ pelet::ExpressionClass arg1 = expr.CallArguments[0];
+ CHECK_UNISTR_EQUALS("myFunct()", arg1.ChainList[0]);
+ CHECK_VECTOR_SIZE(2, arg1.CallArguments);
+ CHECK_UNISTR_EQUALS("three", arg1.CallArguments[0].ChainList[0]);
+ CHECK_UNISTR_EQUALS("$four", arg1.CallArguments[1].ChainList[0]);
+
+
+ // 3. second arg to anotherFunc (call with 1 argument)
+ pelet::ExpressionClass arg2 = expr.CallArguments[1];
+ CHECK_UNISTR_EQUALS("myFunct()", arg2.ChainList[0]);
+ CHECK_VECTOR_SIZE(1, arg2.CallArguments);
+ CHECK_EQUAL(pelet::ExpressionClass::ARRAY, arg2.CallArguments[0].ExpressionType);
+ CHECK_VECTOR_SIZE(1, arg2.CallArguments[0].ArrayKeys);
+ CHECK_UNISTR_EQUALS("key_one", arg2.CallArguments[0].ArrayKeys[0]);
+}
+
TEST_FIXTURE(Parser54TestClass, LintFileShouldReturnTrueOnValidFile) {
std::string file = TestProjectDir + "test.php";
CHECK(Parser.LintFile(file, LintResults));
View
7 tests/TestObserverClass.cpp
@@ -151,4 +151,9 @@ void TestObserverClass::TraitInsteadOfFound(const UnicodeString& namespaceName,
for (size_t i = 0; i < insteadOfList.size(); ++i) {
TraitInsteadOf.push_back(insteadOfList[i]);
}
-}
+}
+
+void TestObserverClass::ExpressionFound(const pelet::ExpressionClass& expression) {
+ Expressions.push_back(expression);
+}
+
View
6 tests/TestObserverClass.h
@@ -34,7 +34,8 @@
*/
class TestObserverClass :
public pelet::ClassObserverClass, public pelet::ClassMemberObserverClass,
- public pelet::FunctionObserverClass, public pelet::VariableObserverClass {
+ public pelet::FunctionObserverClass, public pelet::VariableObserverClass,
+ public pelet::ExpressionObserverClass {
public:
@@ -59,6 +60,7 @@ class TestObserverClass :
MethodStartingPos, MethodEndingPos,
FunctionStartingPos, FunctionEndingPos;
std::vector<int> ClassLineNumber, MethodLineNumber, PropertyLineNumber, FunctionLineNumber, IncludeLineNumber;
+ std::vector<pelet::ExpressionClass> Expressions;
void ClassFound(const UnicodeString& namespaceName, const UnicodeString& className, const UnicodeString& signature,
const UnicodeString& comment, const int lineNumber);
@@ -99,6 +101,8 @@ class TestObserverClass :
void TraitInsteadOfFound(const UnicodeString& namespaceName, const UnicodeString& className, const UnicodeString& traitUsedClassName,
const UnicodeString& traitMethodName, const std::vector<UnicodeString>& insteadOfList);
+
+ void ExpressionFound(const pelet::ExpressionClass& expression);
};
#endif

0 comments on commit b176715

Please sign in to comment.
Something went wrong with that request. Please try again.