PageRenderTime 57ms CodeModel.GetById 15ms app.highlight 37ms RepoModel.GetById 1ms app.codeStats 0ms

/cpp/src/test/java/com/google/test/metric/cpp/CppParserTest.java

http://testability-explorer.googlecode.com/
Java | 520 lines | 446 code | 58 blank | 16 comment | 0 complexity | a47e9b91f8a5b525eeaffb95688280b4 MD5 | raw file
  1/*
  2 * Copyright 2008 Google Inc.
  3 *
  4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5 * use this file except in compliance with the License. You may obtain a copy of
  6 * the License at
  7 *
  8 * http://www.apache.org/licenses/LICENSE-2.0
  9 *
 10 * Unless required by applicable law or agreed to in writing, software
 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 13 * License for the specific language governing permissions and limitations under
 14 * the License.
 15 */
 16package com.google.test.metric.cpp;
 17
 18import com.google.test.metric.ParameterInfo;
 19import com.google.test.metric.Visibility;
 20import com.google.test.metric.cpp.dom.AssignmentExpression;
 21import com.google.test.metric.cpp.dom.BaseClass;
 22import com.google.test.metric.cpp.dom.BaseClass.AccessSpecifier;
 23import com.google.test.metric.cpp.dom.BreakStatement;
 24import com.google.test.metric.cpp.dom.CaseStatement;
 25import com.google.test.metric.cpp.dom.ClassDeclaration;
 26import com.google.test.metric.cpp.dom.DefaultStatement;
 27import com.google.test.metric.cpp.dom.ElseStatement;
 28import com.google.test.metric.cpp.dom.Expression;
 29import com.google.test.metric.cpp.dom.ExpressionStatement;
 30import com.google.test.metric.cpp.dom.FunctionDeclaration;
 31import com.google.test.metric.cpp.dom.FunctionDefinition;
 32import com.google.test.metric.cpp.dom.FunctionInvocation;
 33import com.google.test.metric.cpp.dom.IfStatement;
 34import com.google.test.metric.cpp.dom.LoopStatement;
 35import com.google.test.metric.cpp.dom.Name;
 36import com.google.test.metric.cpp.dom.Namespace;
 37import com.google.test.metric.cpp.dom.NodeList;
 38import com.google.test.metric.cpp.dom.ReturnStatement;
 39import com.google.test.metric.cpp.dom.SwitchStatement;
 40import com.google.test.metric.cpp.dom.TernaryOperation;
 41import com.google.test.metric.cpp.dom.TranslationUnit;
 42import com.google.test.metric.cpp.dom.VariableDeclaration;
 43
 44import junit.framework.TestCase;
 45
 46import java.util.List;
 47
 48public class CppParserTest extends TestCase {
 49
 50  private TranslationUnit parse(String source, NodeDictionary dict)
 51      throws Exception {
 52    return new Parser().parse(source, dict);
 53  }
 54
 55  private TranslationUnit parse(String source) throws Exception {
 56    return new Parser().parse(source);
 57  }
 58
 59  public void testEmptyClass() throws Exception {
 60    TranslationUnit unit = parse("class A{};");
 61    ClassDeclaration classA = unit.getChild(0);
 62    assertEquals("A", classA.getName());
 63  }
 64
 65  public void testTwoClasses() throws Exception {
 66    TranslationUnit unit = parse("class A{}; class B{};");
 67    ClassDeclaration classA = unit.getChild(0);
 68    assertEquals("A", classA.getName());
 69    ClassDeclaration classB = unit.getChild(1);
 70    assertEquals("B", classB.getName());
 71  }
 72
 73  public void testNestedClass() throws Exception {
 74    TranslationUnit unit = parse("class A{ class B{}; };");
 75    ClassDeclaration classA = unit.getChild(0);
 76    assertEquals("A", classA.getName());
 77    ClassDeclaration classB = classA.getChild(0);
 78    assertEquals("B", classB.getName());
 79  }
 80
 81  public void testUnnamedNamespace() throws Exception {
 82    TranslationUnit unit = parse("namespace {}");
 83    Namespace namespace = unit.getChild(0);
 84    assertNull(namespace.getName());
 85  }
 86
 87  public void testEmptyNamespace() throws Exception {
 88    TranslationUnit unit = parse("namespace A{}");
 89    Namespace namespaceA = unit.getChild(0);
 90    assertEquals("A", namespaceA.getName());
 91  }
 92
 93  public void testTwoNamespaces() throws Exception {
 94    TranslationUnit unit = parse("namespace A{} namespace B{}");
 95    Namespace namespaceA = unit.getChild(0);
 96    assertEquals("A", namespaceA.getName());
 97    Namespace namespaceB = unit.getChild(1);
 98    assertEquals("B", namespaceB.getName());
 99  }
100
101  public void testNestedNamespace() throws Exception {
102    TranslationUnit unit = parse("namespace A{ namespace B{} }");
103    Namespace namespaceA = unit.getChild(0);
104    assertEquals("A", namespaceA.getName());
105    Namespace namespaceB = namespaceA.getChild(0);
106    assertEquals("B", namespaceB.getName());
107  }
108
109  public void testClassInNamespace() throws Exception {
110    TranslationUnit unit = parse("namespace A{ class B{}; }");
111    Namespace namespaceA = unit.getChild(0);
112    assertEquals("A", namespaceA.getName());
113    ClassDeclaration classB = namespaceA.getChild(0);
114    assertEquals("B", classB.getName());
115  }
116
117  public void testGlobalFunctionDeclaration() throws Exception {
118    TranslationUnit unit = parse("void foo();");
119    FunctionDeclaration functionFoo = unit.getChild(0);
120    assertEquals("foo", functionFoo.getName());
121  }
122
123  public void testGlobalVarableDeclaration() throws Exception {
124    TranslationUnit unit = parse("int a = 0, b = 1, c;");
125    VariableDeclaration variableA = unit.getChild(0);
126    assertEquals("a", variableA.getName());
127    VariableDeclaration variableB = unit.getChild(1);
128    assertEquals("b", variableB.getName());
129    VariableDeclaration variableC = unit.getChild(2);
130    assertEquals("c", variableC.getName());
131  }
132
133  public void testFunctionDeclarationInNamespace() throws Exception {
134    TranslationUnit unit = parse("namespace A { void foo(); };");
135    Namespace namespaceA = unit.getChild(0);
136    assertEquals("A", namespaceA.getName());
137    FunctionDeclaration functionFoo = namespaceA.getChild(0);
138    assertEquals("foo", functionFoo.getName());
139  }
140
141  public void testMemberFunctionDeclaration() throws Exception {
142    TranslationUnit unit = parse("class A { void foo(); };");
143    ClassDeclaration classA = unit.getChild(0);
144    assertEquals("A", classA.getName());
145    FunctionDeclaration functionFoo = classA.getChild(0);
146    assertEquals("foo", functionFoo.getName());
147  }
148
149  public void testEmptyGlobalFunction() throws Exception {
150    TranslationUnit unit = parse("void foo() {}");
151    FunctionDefinition functionFoo = unit.getChild(0);
152    assertEquals("foo", functionFoo.getName());
153  }
154
155  public void testEmptyFunctionInNamespace() throws Exception {
156    TranslationUnit unit = parse("namespace A { void foo() {} }");
157    Namespace namespaceA = unit.getChild(0);
158    assertEquals("A", namespaceA.getName());
159    FunctionDefinition functionFoo = namespaceA.getChild(0);
160    assertEquals("foo", functionFoo.getName());
161  }
162
163  public void testEmptyMemberFunction() throws Exception {
164    TranslationUnit unit = parse("class A { void foo() {} };");
165    ClassDeclaration classA = unit.getChild(0);
166    assertEquals("A", classA.getName());
167    FunctionDefinition functionFoo = classA.getChild(0);
168    assertEquals("foo", functionFoo.getName());
169    assertEquals(1, functionFoo.getLine());
170  }
171
172  public void testFunctionLineNumbers() throws Exception {
173    TranslationUnit unit = parse("class A { void foo() {}\n void\n bar() {} };");
174    ClassDeclaration classA = unit.getChild(0);
175    FunctionDefinition functionFoo = classA.getChild(0);
176    assertEquals(1, functionFoo.getLine());
177    FunctionDefinition functionBar = classA.getChild(1);
178    assertEquals(3, functionBar.getLine());
179  }
180
181  public void testSimpleFunction() throws Exception {
182    TranslationUnit unit = parse("int foo() { int a = 0; a = a + 1;\n return a; }");
183    FunctionDefinition functionFoo = unit.getChild(0);
184    assertEquals("foo", functionFoo.getName());
185    ReturnStatement returnStatement = functionFoo.getChild(2);
186    assertNotNull(returnStatement);
187    assertEquals(2, returnStatement.getLineNumber());
188  }
189
190  public void testFunctionWithParameters() throws Exception {
191    TranslationUnit unit = parse("int foo(int a, int b) { return a + b; }");
192    FunctionDefinition functionFoo = unit.getChild(0);
193    assertEquals("foo", functionFoo.getName());
194    ReturnStatement returnStatement = functionFoo.getChild(0);
195    assertNotNull(returnStatement);
196    List<ParameterInfo> parameters = functionFoo.getParameters();
197    assertEquals(2, parameters.size());
198    ParameterInfo parameterA = parameters.get(0);
199    assertEquals("a", parameterA.getName());
200    assertEquals("int", parameterA.getType().toString());
201    ParameterInfo parameterB = parameters.get(1);
202    assertEquals("b", parameterB.getName());
203    assertEquals("int", parameterB.getType().toString());
204  }
205
206  public void testForStatement() throws Exception {
207    TranslationUnit unit = parse("void foo() { for(;;); }");
208    FunctionDefinition functionFoo = unit.getChild(0);
209    LoopStatement forStatement = functionFoo.getChild(0);
210    assertNotNull(forStatement);
211  }
212
213  public void testWhileStatement() throws Exception {
214    TranslationUnit unit = parse("void foo() { while(true); }");
215    FunctionDefinition functionFoo = unit.getChild(0);
216    LoopStatement whileStatement = functionFoo.getChild(0);
217    assertNotNull(whileStatement);
218  }
219
220  public void testDoStatement() throws Exception {
221    TranslationUnit unit = parse("void foo() { do {} while(true); }");
222    FunctionDefinition functionFoo = unit.getChild(0);
223    LoopStatement doStatement = functionFoo.getChild(0);
224    assertNotNull(doStatement);
225  }
226
227  public void testWhileInForStatement() throws Exception {
228    TranslationUnit unit = parse("void foo() { for(;;) while(true); }");
229    FunctionDefinition functionFoo = unit.getChild(0);
230    LoopStatement forStatement = functionFoo.getChild(0);
231    assertNotNull(forStatement);
232    LoopStatement whileStatement = forStatement.getChild(0);
233    assertNotNull(whileStatement);
234  }
235
236  public void testForInDoStatement() throws Exception {
237    TranslationUnit unit = parse("void foo() { do for(;;); while(true); }");
238    FunctionDefinition functionFoo = unit.getChild(0);
239    LoopStatement doStatement = functionFoo.getChild(0);
240    assertNotNull(doStatement);
241    LoopStatement forStatement = doStatement.getChild(0);
242    assertNotNull(forStatement);
243  }
244
245  public void testForInCompoundDoStatement() throws Exception {
246    TranslationUnit unit = parse("void foo() { do { for(;;); } while(true); }");
247    FunctionDefinition functionFoo = unit.getChild(0);
248    LoopStatement doStatement = functionFoo.getChild(0);
249    assertNotNull(doStatement);
250    LoopStatement forStatement = doStatement.getChild(0);
251    assertNotNull(forStatement);
252  }
253
254  public void testForInSeveralCompoundStatements() throws Exception {
255    TranslationUnit unit = parse("void foo() { {{{ for(;;); }}} }");
256    FunctionDefinition functionFoo = unit.getChild(0);
257    LoopStatement forStatement = functionFoo.getChild(0);
258    assertNotNull(forStatement);
259  }
260
261  public void testIfStatement() throws Exception {
262    TranslationUnit unit = parse("void foo() { if (true); }");
263    FunctionDefinition functionFoo = unit.getChild(0);
264    IfStatement ifStatement = functionFoo.getChild(0);
265    assertNotNull(ifStatement);
266  }
267
268  public void testIfElseStatement() throws Exception {
269    TranslationUnit unit = parse("void foo() { if (true); else; }");
270    FunctionDefinition functionFoo = unit.getChild(0);
271    IfStatement ifStatement = functionFoo.getChild(0);
272    assertNotNull(ifStatement);
273    ElseStatement elseStatement = functionFoo.getChild(1);
274    assertNotNull(elseStatement);
275  }
276
277  public void testCompoundIfElseStatement() throws Exception {
278    TranslationUnit unit = parse("void foo() { if (true) {} else {} }");
279    FunctionDefinition functionFoo = unit.getChild(0);
280    IfStatement ifStatement = functionFoo.getChild(0);
281    assertNotNull(ifStatement);
282    ElseStatement elseStatement = functionFoo.getChild(1);
283    assertNotNull(elseStatement);
284  }
285
286  public void testIfElseAndLoopStatements() throws Exception {
287    TranslationUnit unit = parse("void foo() { if (true) { for(;;); } else { while(true); } }");
288    FunctionDefinition functionFoo = unit.getChild(0);
289    IfStatement ifStatement = functionFoo.getChild(0);
290    LoopStatement forStatement = ifStatement.getChild(0);
291    assertNotNull(forStatement);
292    ElseStatement elseStatement = functionFoo.getChild(1);
293    LoopStatement whileStatement = elseStatement.getChild(0);
294    assertNotNull(whileStatement);
295  }
296
297  public void testSwitchStatement() throws Exception {
298    TranslationUnit unit = parse("void foo() { switch (a) { case 1: break; } }");
299    FunctionDefinition functionFoo = unit.getChild(0);
300    SwitchStatement switchStatement = functionFoo.getChild(0);
301    CaseStatement caseStatement = switchStatement.getChild(0);
302    assertNotNull(caseStatement);
303  }
304
305  public void testSwitchStatementWithDefault() throws Exception {
306    TranslationUnit unit = parse("void foo() { switch (a) { case 1: break; default: break; } }");
307    FunctionDefinition functionFoo = unit.getChild(0);
308    SwitchStatement switchStatement = functionFoo.getChild(0);
309    CaseStatement caseStatement = switchStatement.getChild(0);
310    BreakStatement breakStatement = caseStatement.getChild(0);
311    assertNotNull(breakStatement);
312    DefaultStatement defaultStatement = switchStatement.getChild(1);
313    breakStatement = defaultStatement.getChild(0);
314    assertNotNull(breakStatement);
315  }
316
317  public void testTernaryOperator() throws Exception {
318    TranslationUnit unit = parse("int foo(int a, int b) { return a ? 0 : b; }");
319    FunctionDefinition functionFoo = unit.getChild(0);
320    ReturnStatement returnStatement = functionFoo.getChild(0);
321    TernaryOperation ternaryOperation = returnStatement.getExpression(0);
322    assertNotNull(ternaryOperation);
323  }
324
325  public void testNestedTernaryOperator() throws Exception {
326    TranslationUnit unit = parse("int foo(int a, int b) { int c = a ? 0 : (b ? 1 : 2); }");
327    FunctionDefinition functionFoo = unit.getChild(0);
328    VariableDeclaration variableC = functionFoo.getChild(0);
329    TernaryOperation ternaryOperation = variableC.getExpression(0);
330    TernaryOperation nestedTernaryOperation = ternaryOperation.getExpression(1);
331    assertNotNull(nestedTernaryOperation);
332  }
333
334  public void testFunctionCall() throws Exception {
335    TranslationUnit unit = parse("void foo(int) {} void bar(int) { foo(5); }");
336    FunctionDefinition functionBar = unit.getChild(1);
337    ExpressionStatement expressionStatement = functionBar.getChild(0);
338    FunctionInvocation callFoo = expressionStatement.getExpression(0);
339    assertEquals("foo", callFoo.getName());
340  }
341
342  public void testNestedFunctionCall() throws Exception {
343    TranslationUnit unit = parse(
344        "int foo(int a) { return a; }             " +
345        "int bar(int b) { return foo(foo(b)); }   ");
346    FunctionDefinition functionBar = unit.getChild(1);
347    assertEquals("bar", functionBar.getName());
348    ReturnStatement returnStatement = functionBar.getChild(0);
349    FunctionInvocation callFoo = returnStatement.getExpression(0);
350    assertEquals("foo", callFoo.getName());
351    NodeList parameters = callFoo.getParameters();
352    FunctionInvocation callFooAgain = parameters.get(0);
353    assertEquals("foo", callFooAgain.getName());
354    assertEquals(0, callFooAgain.getChildren().size());
355  }
356
357  public void testSequentialFunctionCalls() throws Exception {
358    TranslationUnit unit = parse(
359        "class A { public: void foo() {} };     " +
360        "A bar() { A a; return a; }             " +
361        "void main() { bar().foo(); }           ");
362    FunctionDefinition functionMain = unit.getChild(2);
363    assertEquals("main", functionMain.getName());
364    ExpressionStatement expressionStatement = functionMain.getChild(0);
365    FunctionInvocation callBar = expressionStatement.getExpression(0);
366    assertEquals("bar", callBar.getName());
367    FunctionInvocation callFoo = callBar.getChild(0);
368    assertEquals("foo", callFoo.getName());
369    assertEquals(0, callFoo.getChildren().size());
370  }
371
372  public void testLocalVariable() throws Exception {
373    TranslationUnit unit = parse(
374        "void main() { int a = 0, b = 0; a += 1; }");
375    FunctionDefinition functionMain = unit.getChild(0);
376    assertEquals("main", functionMain.getName());
377    VariableDeclaration variableA = functionMain.getChild(0);
378    assertEquals("a", variableA.getName());
379    VariableDeclaration variableB = functionMain.getChild(1);
380    assertEquals("b", variableB.getName());
381  }
382
383  public void testPrivateAccessSpecifier() throws Exception {
384    TranslationUnit unit = parse(
385        "class A { private: void foo(); };");
386    ClassDeclaration classA = unit.getChild(0);
387    FunctionDeclaration functionFoo = classA.getChild(0);
388    Visibility visibility = functionFoo.getVisibility();
389    assertEquals(Visibility.PRIVATE, visibility);
390  }
391
392  public void testProtectedAccessSpecifier() throws Exception {
393    TranslationUnit unit = parse(
394        "class A { protected: void foo() {} void bar() {} };");
395    ClassDeclaration classA = unit.getChild(0);
396    FunctionDefinition functionFoo = classA.getChild(0);
397    Visibility visibilityFoo = functionFoo.getVisibility();
398    assertEquals(Visibility.PROTECTED, visibilityFoo);
399    FunctionDefinition functionBar = classA.getChild(1);
400    Visibility visibilityBar = functionBar.getVisibility();
401    assertEquals(Visibility.PROTECTED, visibilityBar);
402  }
403
404  public void testLocalAssgnment() throws Exception {
405    TranslationUnit unit = parse(
406        "void main() { int a = 0, b = 1; a = b; }");
407    FunctionDefinition functionMain = unit.getChild(0);
408    VariableDeclaration variableA = functionMain.getChild(0);
409    assertEquals("a", variableA.getName());
410    VariableDeclaration variableB = functionMain.getChild(1);
411    assertEquals("b", variableB.getName());
412    ExpressionStatement statement = functionMain.getChild(2);
413    Expression expression = statement.getExpression(0);
414    assertTrue(expression instanceof AssignmentExpression);
415    AssignmentExpression assignment = (AssignmentExpression) expression;
416    Name leftSide = assignment.getExpression(0);
417    Name rightSide = assignment.getExpression(1);
418    assertEquals("a", leftSide.getIdentifier());
419    assertEquals("b", rightSide.getIdentifier());
420  }
421
422  public void testPointerVariable() throws Exception {
423    TranslationUnit unit = parse(
424      "void main() { int *p = 0, a = 0, *pp = 0; }");
425    FunctionDefinition functionMain = unit.getChild(0);
426    VariableDeclaration variableP = functionMain.getChild(0);
427    assertEquals("p", variableP.getName());
428    assertEquals("int", variableP.getType());
429    assertTrue(variableP.isPointer());
430    VariableDeclaration variableA = functionMain.getChild(1);
431    assertEquals("a", variableA.getName());
432    assertEquals("int", variableA.getType());
433    assertFalse(variableA.isPointer());
434    VariableDeclaration variablePP = functionMain.getChild(2);
435    assertEquals("pp", variablePP.getName());
436    assertEquals("int", variablePP.getType());
437    assertTrue(variablePP.isPointer());
438  }
439
440  public void testReferenceVariable() throws Exception {
441    TranslationUnit unit = parse(
442      "void main() { int a = 0; int& r = a; }");
443    FunctionDefinition functionMain = unit.getChild(0);
444    VariableDeclaration variableA = functionMain.getChild(0);
445    assertEquals("a", variableA.getName());
446    assertEquals("int", variableA.getType());
447    assertFalse(variableA.isPointer());
448    VariableDeclaration variableR = functionMain.getChild(1);
449    assertEquals("r", variableR.getName());
450    assertEquals("int", variableR.getType());
451    assertTrue(variableR.isPointer());
452  }
453
454  public void testClassLoadCppVariables() throws Exception {
455    assertEquals(64, CPPvariables.QI_TYPE.size());
456  }
457
458  public void testInheritance() throws Exception {
459    TranslationUnit unit = parse("class A{}; class B : public A {};");
460    ClassDeclaration classA = unit.getChild(0);
461    ClassDeclaration classB = unit.getChild(1);
462    assertEquals("A", classA.getName());
463    assertEquals("B", classB.getName());
464    ClassDeclaration baseB = classB.getBaseClass(0).getDeclaration();
465    assertEquals("A", baseB.getName());
466    assertEquals(AccessSpecifier.PUBLIC, classB.getBaseClass(0)
467        .getAccessSpecifier());
468  }
469
470  public void testMultipleInheritence() throws Exception {
471    TranslationUnit unit = parse(
472        "class A{}; class B{}; class C : public A, protected B {};");
473    ClassDeclaration classA = unit.getChild(0);
474    ClassDeclaration classB = unit.getChild(1);
475    ClassDeclaration classC = unit.getChild(2);
476    assertEquals("A", classA.getName());
477    assertEquals("B", classB.getName());
478    assertEquals("C", classC.getName());
479
480    BaseClass baseC0 = classC.getBaseClass(0);
481    BaseClass baseC1 = classC.getBaseClass(1);
482
483    assertEquals("A", baseC0.getDeclaration().getName());
484    assertEquals(AccessSpecifier.PUBLIC, baseC0.getAccessSpecifier());
485
486    assertEquals("B", baseC1.getDeclaration().getName());
487    assertEquals(AccessSpecifier.PROTECTED, baseC1.getAccessSpecifier());
488  }
489
490  public void testInheritedClassInSpecifiedNamespace() throws Exception {
491    TranslationUnit unit = parse(
492      "namespace Foo { class A {}; } " +
493      "class B : public Foo::A {};");
494    Namespace namespaceFoo = unit.getChild(0);
495    ClassDeclaration classA = namespaceFoo.getChild(0);
496    ClassDeclaration classB = unit.getChild(1);
497    assertEquals("Foo::A", classA.getQualifiedName());
498    assertEquals("B", classB.getName());
499    ClassDeclaration baseB = classB.getBaseClass(0).getDeclaration();
500    assertEquals("A", baseB.getName());
501    assertEquals(AccessSpecifier.PUBLIC, classB.getBaseClass(0)
502        .getAccessSpecifier());
503  }
504
505  public void testInheritedClassInOtherTranslationUnit() throws Exception {
506    // Build other tree with external declaration.
507    NodeDictionary knownSymbols = new NodeDictionary();
508    ClassDeclaration other = new ClassDeclaration("B");
509    other.setParent(new Namespace("Bar"));
510    knownSymbols.registerNode("Bar::B", other);
511
512    TranslationUnit unit = parse("class A : public Bar::B {};", knownSymbols);
513    ClassDeclaration classA = unit.getChild(0);
514    assertEquals("A", classA.getName());
515
516    ClassDeclaration baseA = classA.getBaseClass(0).getDeclaration();
517    assertEquals("B", baseA.getName());
518    assertEquals("Bar::B", baseA.getQualifiedName());
519  }
520}