diff --git a/core/org.eclipse.cdt.core.tests/.classpath b/core/org.eclipse.cdt.core.tests/.classpath new file mode 100644 index 00000000000..ce3964a9e41 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/.classpath @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/core/org.eclipse.cdt.core.tests/.project b/core/org.eclipse.cdt.core.tests/.project new file mode 100644 index 00000000000..a11a02c7c86 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/.project @@ -0,0 +1,40 @@ + + + org.eclipse.cdt.core.tests + + + org.apache.xerces + org.eclipse.cdt.core + org.eclipse.cdt.core.linux + org.eclipse.cdt.core.qnx + org.eclipse.cdt.core.solaris + org.eclipse.cdt.core.win32 + org.eclipse.core.boot + org.eclipse.core.resources + org.eclipse.core.runtime + org.eclipse.swt + org.eclipse.ui + org.junit + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + + diff --git a/core/org.eclipse.cdt.core.tests/ChangeLog b/core/org.eclipse.cdt.core.tests/ChangeLog new file mode 100644 index 00000000000..0c2ba0c267b --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/ChangeLog @@ -0,0 +1,570 @@ +2003-06-17 Brent Nicolle + Added Interface tests of IStructure.java. + +2003-06-16 Vladimir Hirsl + Added /build, /parser, /failures and /suite directories to the library. + Copied resources from /model/org.eclipse.cdt.core.model.tests.resources + to /model/org/clipse/cdt/core/model/tests/resources/cmodel. + Added class AISResultPrinter to format test results. + Class AutomatedIntegrationSuite now implements IPlatformRunnable. + +2003-06-17 Victor Mozgin + Added DeclaratorsTests.java (invocation in AllCoreTests). + Added DeclaratorsTests.cpp to org.eclipse.cdt.core.model.tests.resources. + +2003-06-14 Victor Mozgin + Moved testBugSingleton192() from LokiFailures to DOMTests. + Added testPointersToMembers() and testPointersToMemberFunctions() to DOMTests. + Added testBug36290() and testBug36931() to DOMTests. + +2003-06-13 John Camelon + Added Class/Base infrastructure to public interfaces & requestor callback. + Moved many internal interfaces to external packages. + Organized imports. + +2003-06-13 Victor Mozgin + Renamed NullParserCallback into NullSourceElementRequester in AutomatedFramework. + +2003-06-13 John Camelon + Merged ParserSymbolTable branch back into HEAD. + +2003-06-12 John Camelon + Get rest of JUnit tests working, will merge back to HEAD branch. + +2003-06-12 John Camelon + Introduction of ASTFactory strategy, some restructuring of packages and interfaces. + +2003-06-11 Victor Mozgin + Old Java TestCase.txt and TestCase2.txt for partioning testing have been replaced with C/C++ files. + Modified AutomatedIntegrationSuite.java so it doesn't produce JUnit warning anymore. + All tests in org.eclipse.cdt.ui.tests should pass now. + +3003-06-11 Peter Graves + Update the test.xml to get the location of org.eclipse.test from a property + if set. If the property is not set, it will default to the old value. + +2003-06-11 Victor Mozgin + Added TortureTest to test CDT C++ parser with GCC testsuites. + GCC testsuites are not included. + +2003-06-10 John Camelon + Futher pursuit of the golden hammer, symbol table integration. + +2003-06-10 Brent Nicolle + Added some Interface tests of (IInclude, IMacro, IStructure). + Made sure all the Test Suites have names in the JUnit hierarchy. + +2003-06-09 John Camelon + First step in replacing IParserCallback with ISourceElementRequestor. + +2003-06-09 Victor Mozgin + Moved testBug36769() from ACEFailedTest.java to DOMTests.java. + Removed ACEFailedTest.java as it is empty now. + Added DOMTests.testBug36769B(). + +2003-06-09 Victor Mozgin + Moved testBug36932() from DOMFailedTest.java to DOMTests.java. + Added DOMTests.testBug36932B() and DOMTests.testBug36932C(). + +2003-06-09 Victor Mozgin + Moved testBug36701() from ScannerFailedTests.java to ScannerTestCase.java. + Renamed it to testBug36701A() and fixed it. + Added ScannerTestCase.testBug36701B(). + +2003-06-07 Victor Mozgin + Moved testBug36766A(), testBug36766B() & testBug36766C() from STLFailedTests.java to DOMTests.java. + Renamed them to testBug36766and36769x(), as they cover both PRs. + Added testBug36766and36769D() - test for templated destructor. + +2003-06-05 John Camelon + Moved testBug23478A() & testBug23478B() from failed tests to TranslationUnitTests.java. + Removed TranslationUnitFailedTests.java as it was empty. + +2003-05-29 Andrew Niefer + Modified tests to support eType & PtrOp changes in core + Added ParserSymbolTableTest::testTemplateParameterAsParent + Added ParserSymbolTableTest::testTemplateInstanceAsParent + Added ParserSymbolTableTest::testTemplateParameterDefaults + Added ParserSymbolTableTest::testTemplateParameterAsFunctionArgument + started ParserSymbolTableTest::incompletetestTemplateSpecialization + +2003-05-26 John Camelon + Rollback PST/Parser integration. + +2003-05-13 Andrew Niefer + Modified ParserSymbolTableTest to use new interface + +2003-05-08 Andrew Niefer + Added ParserSymbolTableTest::testMarkRollback + +2003-05-06 John Camelon + Further integration of SymbolTable into Parser, some refactoring. + +2003-05-05 John Camelon/Andrew Niefer + Added CrossReferenceTests to ParserTestSuite to test symbol-table/DOM interworking. + +2003-05-05 Andrew Niefer + Rewrote ParserSymbolTableTest to reflect structural changes to the symbol table. + +2003-05-01 Andrew Niefer + Updated FractionalAutomatedTest to use threads + Modified ScannerTestCase::testBug36287 + Added ScannerTestCase::testBug37011 + Added ScannerTestCase::testOtherPreprocessorDefines + +2003-04-28 John Camelon + Moved testBug36730() & testBug37019() from DOMFailedTests to DOMTests. + +2003-04-28 Andrew Niefer + Added DOMFailedTest::testBug37019 + Added DOMFailedTest::testBug36932 + Added ScannerFailedTest::testBug37011 + +2003-04-28 John Camelon + Added DOMTests::testOrder(). + +2003-04-28 Peter Graves + * model/org/eclipse/cdt/core/model/tests/BinaryTests: + Updated to remove a few small errors, and deal with some changes + to the core CDT + +2003-04-27 John Camelon + Added testBug36932() to DOMTests. + Moved testBugFunctor758() from LokiFailures to DOMTests. + Moved testBug36704() from DOMFailedTest to DOMTests. + Moved testBug36699() from DOMFailedTest to DOMTests. + Moved testBug36691() from DOMFailedTest to DOMTests. + +2003-04-25 Andrew Niefer + Moved ACEFailedTest::testBug36771 to DOMTests + Moved DOMFailedTest::testBug36714 to DOMTests + Updated ScannerTestCase::testBug36816 + +2003-04-25 John Camelon + Added DOMTests::testBug36852(). + Added DOMTests::testBug36764(). + Moved DOMFailedTests::testBug36702() to DOMTests(). + +2003-04-24 John Camelon + Moved fixed tests from FailedTests to DOMTests. + Added DOMTests::testBug36799(). + Cleaned up tests to reduce amount of code necessary to maintain these things. + +2003-04-24 John Camelon + Moved fixed tests from FailedTests to DOMTests. + Added LokiFailures.java to failed tests directory. + +2003-04-24 Andrew Niefer + Added AutomatedFramework.java + Added FractionalAutomatedTest (which derives from AutomatedFramework) + Refactored AutomatedTest to derive from AutomatdFramework + Added ScannerTestCase.testBug36816 + Added ScannerTestCase.testBug36255 + +2003-04-24 John Camelon + Fixed Java 1.3 compliance issue w/AutomatedTest.java + Fixed False failure in HelloWorld.java. + +2003-04-21 John Camelon + Updated DOMTests::testBug36247(). + Moved testBug36692(), testBug36703(), testBug36708(), testBug36707(), testBug36689() + and testBug36690() from DOMFailedTests to DOMTests and updated them. + +2003-04-20 John Camelon + Added DOMTests::testBug36551(). + Adjusted AutomatedTest to turn on line numbering. + Added DOMFailedTests and 11 failed test cases. + +2003-04-17 Andrew Niefer + Added ScannerTestCase::testBug36695() + Moved ScannerFailedTest::testBug36521 to ScannerTestCase::testBug36521() + Moved ScannerFailedTest::testBug36509 to ScannerTestCase::testBug36509() + Moved ScannerFailedTest::testBug36475 to ScannerTestCase::testBug36475() + Updated ScannerTestCase::testBug36047 + Updated ScannerTestCase::testBug36045 + +2003-04-17 John Camelon + Updated DOMTests::testBug36600(). + Updated LineNumberTest::testDOMLineNos(). + Added DOMTests::testBug36559(). + +2003-04-17 Andrew Niefer + Added AutomatedTest + Added resources.cFiles + Added resources.cppFiles + +2003-04-16 John Camelon + Added DOMTests::testBug36532(). + Added DOMTests::testBug36432(). + Added DOMTests::testBug36594(). + Added DOMTests::testBug36600(). + Added DOMTests::testArrayOfPointerToFunctions(). + +2003-04-15 John Camelon + Added ScannerTestCase::testBug36434(). + Added ScannerTestCase::testMultipleLines(). + Added ParserTestSuite. + Added LineNumberTest. + Updated CModelElementsTests to set the Nature of the C++ project appropriately. + +2003-04-15 Andrew Niefer + Moved ScannerFailedTest::testBug36047 to ScannerTestCase::testBug36047 + Added ScannerFailedTest::testBug36475 + +2003-04-13 John Camelon + Added DOMTests::testPointersToFunctions. + +2003-04-11 John Camelon + Added DOMTests::testBug36247(). + +2003-04-11 Andrew Niefer + Moved ScannerFailedTest::testBug36316 to ScannerTestCase::testBug36316 + Added ScannerFailedTest::testBug36047 + Added ScannerTestCase::testNestedRecursiveDefines + +2003-04-10 John Camelon + Added DOMTests::testBug36237(). + +2003-04-09 John Camelon + Removed all the old Code Model Builder source that was no longer being used (NewModelBuilder.java, etc.). + Moved all the files in parser.util directory to the dom. + Organized imports. + Added DOMTests::testTemplateDeclarationOfMethod(). + Added DOMTests::testBug36250(). + Added DOMTests::testBug36240(). + Added DOMTests::testBug36254(). + +2003-04-09 John Camelon + Updated ScannerTest::testBug36045(). + Added ScannerTest::testBug36287(). + Added DOMTests::testBug36288(). + +2003-04-06 Andrew Niefer + Added ParserSymbolTableTest::testOverloadRanking() + +2003-04-04 Alain Magloire + * src/org/eclipse/cdt/testplugin/util/VerifyDialog.java: + Remove some warnings. + +2003-04-03 John Camelon + Updated ScannerTest::testSimpleIfdef() for bug36019. + Updated ScannerTest::testNumerics() for bug36020. + Added ScannerTest::testBug36045(). + Updated DOMTests::testTemplateDeclaration() for template grammar updates. + +2003-04-01 Andrew Niefer + ParserSymbolTableTest. modifications to using declaration tests to reflect changes in the + symbol table. Also added testUserDefinedConversionSequences() + +2003-04-01 John Camelon + Added testBug35906() to DOMTests. + +2003-03-31 John Camelon + Added testStruct() to DOMTests. + Added test35892()to ScannerTest. + +2003-03-31 Andrew Niefer + In ParserSymbolTableTest, renamed testFunctionResolution_2() to testFunctionResolution_PointersAndBaseClasses(), + and modified to reflect changes in function resolution. + Added testFunctionResolution_TypedefsAndPointers(). + +2003-03-31 John Camelon + Added testWeirdStrings() and testNumerics() to ScannerTestCase. + Added testTemplateSpecialization(), testTemplateDeclaration(), testBug26467(), + testTypedef() and testTemplateInstantiation() to DOMTests. + +2003-03-28 John Camelon + Added testConstructorChain() and testASMDefinition() to DOMTests. + +2003-03-27 Alain Magloire + Changes were done in the Core Model API, the hierarchy is now + ICModel + ICProject + ICContainer + ITranslationUnit + IArchive + IBinary + We adjust the tests. + * model/org/eclipse/cdt/core/model/tests/ArchiveTests.java + * model/org/eclipse/cdt/core/model/tests/BinaryTests.java + * model/org/eclipse/cdt/core/model/tests/TranslationUniTests.java + * model/org/eclipse/cdt/core/model/tests/WorkingCopyTests.java + +2003-03-26 Andrew Niefer + In ParserSymbolTableTest : + updated all tests to reflect TypeInfo changes + Added testFunctionResolution() & testFunctionResolution_2() in + +2003-03-25 John Camelon + Added testDeclSpecifier(), testNamespaceDefinition(), testLinkageSpecification(), + testUsingClauses() and testEnumSpecifier() to DOMTests. + +2003-03-23 John Camelon + Added ptrOperator() test to DOMTests. + Added testFunctionModifiers() test to DOMTests. + Added testArrays() test to DOMTests. + +2003-03-20 Alain Magloire + + Patch from Amer Hoda, tests for the CElement deltas for Translation Units. + * model/org/eclipse/cdt/core/model/tests/ElementDeltaTest.java + * model/org/eclipse/cdt/core/model/tests/resource/WorkingCopyTestStart.h + +2003-03-19 Alain Magloire + Patch from Amer Hoda, introducing a simple test for the core model. + * model/org/eclipse/cdt/core/model/tests/WorkingCopyTests.java + * model/org/eclipse/cdt/core/model/tests/resource/WorkingCopyTestStart.h + +2003-03-18 John Camelon + Updated DOMTests to validate simple case of a function declaration with multiple parameters. + * parser/org/eclipse/cdt/core/parser/tests/DOMTests.java + +2003-03-11 John Camelon + Updated DOMTests for core.internal.parser change of merging DeclarationSpecifier and DeclSpecifier + Organized imports + * parser/org/eclipse/cdt/core/parser/tests/DOMTests.java + * parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java + +2003-03-10 John Camelon + Added macro pasting tests + +2003-03-06 Andrew Niefer + Added tests for exercising Namespaces & using directives in new parser's symbol table + +2003-03-04 Doug Schaefer + This is a pretty big patch, but it is the merge of the NewParser1 branch into the HEAD branch. lder "parser") + JUnit tests for testing various pieces (source folder "parser" in cdt.ui.tests. + +2003-01-29 Peter Graves + + Fixed the warnings when accessing static methods + * src/org/eclipse/cdt/testplugin/util/DialogCheck.java: + * src/org/eclipse/cdt/testplugin/CTestPlugin.java + * src/org/eclipse/cdt/testplugin/TestWorkbench.java + * ChangeLog: make all entries have the same formatting + +2002-12-17 Peter Graves + + * plugin.xml,test.xml: Some simple cleanups to remove refrences to the jdt and + to move closer to automated running + +2002-11-27 Alain Magloire + + * model/org/eclipse/cdt/core/model/tests/CModelTests.java: + Use CoreModel.getDefault(). + +2002-10-30 Alain Magloire + + * model/org/eclipse/cdt/core/model/tests/CModelTests.java (testGetNatureID): + The fields and the methods use in this test was removed from the CoreModel class. + (testHasNature): The method use in this case was refactor in the classes + CProjectNature and CCProjectNature, fix the test. + +2002-10-18 Peter Graves + + src/org/eclipse/cdt/testplugin/CProjectHelper.jada + Cleanup of the CProjectHelper file to remove unused imports, commeted out code etc. + +======= +2003-04-21 Andrew Niefer + Added DOMFailedTests::testBug36713() + Added DOMFailedTests::testBug36714() + Added DOMFailedTests::testBug36717() + Added DOMFailedTests::testBug36730() + +2003-04-21 Andrew Niefer + Added ScannerTestCase::testBug36695() + Moved ScannerFailedTest::testBug36521 to ScannerTestCase::testBug36521() + Moved ScannerFailedTest::testBug36509 to ScannerTestCase::testBug36509() + Moved ScannerFailedTest::testBug36475 to ScannerTestCase::testBug36475() + Updated ScannerTestCase::testBug36047 + Updated ScannerTestCase::testBug36045 + +2003-04-20 John Camelon + Added DOMTests::testBug36551(). + Adjusted AutomatedTest to turn on line numbering. + Added DOMFailedTests and 11 failed test cases. + +2003-04-17 John Camelon + Updated DOMTests::testBug36600(). + Updated LineNumberTest::testDOMLineNos(). + Added DOMTests::testBug36559(). + +2003-04-17 Andrew Niefer + Added AutomatedTest + Added resources.cFiles + Added resources.cppFiles + +2003-04-16 John Camelon + Added DOMTests::testBug36532(). + Added DOMTests::testBug36432(). + Added DOMTests::testBug36594(). + Added DOMTests::testBug36600(). + Added DOMTests::testArrayOfPointerToFunctions(). + +2003-04-15 John Camelon + Added ScannerTestCase::testBug36434(). + Added ScannerTestCase::testMultipleLines(). + Added ParserTestSuite. + Added LineNumberTest. + Updated CModelElementsTests to set the Nature of the C++ project appropriately. + +2003-04-15 Andrew Niefer + Moved ScannerFailedTest::testBug36047 to ScannerTestCase::testBug36047 + Added ScannerFailedTest::testBug36475 + +2003-04-13 John Camelon + Added DOMTests::testPointersToFunctions. + +2003-04-11 John Camelon + Added DOMTests::testBug36247(). + +2003-04-11 Andrew Niefer + Moved ScannerFailedTest::testBug36316 to ScannerTestCase::testBug36316 + Added ScannerFailedTest::testBug36047 + Added ScannerTestCase::testNestedRecursiveDefines + +2003-04-10 John Camelon + Added DOMTests::testBug36237(). + +2003-04-09 John Camelon + Removed all the old Code Model Builder source that was no longer being used (NewModelBuilder.java, etc.). + Moved all the files in parser.util directory to the dom. + Organized imports. + Added DOMTests::testTemplateDeclarationOfMethod(). + Added DOMTests::testBug36250(). + Added DOMTests::testBug36240(). + Added DOMTests::testBug36254(). + +2003-04-09 John Camelon + Updated ScannerTest::testBug36045(). + Added ScannerTest::testBug36287(). + Added DOMTests::testBug36288(). + +2003-04-06 Andrew Niefer + Added ParserSymbolTableTest::testOverloadRanking() + +2003-04-04 Alain Magloire + * src/org/eclipse/cdt/testplugin/util/VerifyDialog.java: + Remove some warnings. + +2003-04-03 John Camelon + Updated ScannerTest::testSimpleIfdef() for bug36019. + Updated ScannerTest::testNumerics() for bug36020. + Added ScannerTest::testBug36045(). + Updated DOMTests::testTemplateDeclaration() for template grammar updates. + +2003-04-01 Andrew Niefer + ParserSymbolTableTest. modifications to using declaration tests to reflect changes in the + symbol table. Also added testUserDefinedConversionSequences() + +2003-04-01 John Camelon + Added testBug35906() to DOMTests. + +2003-03-31 John Camelon + Added testStruct() to DOMTests. + Added test35892()to ScannerTest. + +2003-03-31 Andrew Niefer + In ParserSymbolTableTest, renamed testFunctionResolution_2() to testFunctionResolution_PointersAndBaseClasses(), + and modified to reflect changes in function resolution. + Added testFunctionResolution_TypedefsAndPointers(). + +2003-03-31 John Camelon + Added testWeirdStrings() and testNumerics() to ScannerTestCase. + Added testTemplateSpecialization(), testTemplateDeclaration(), testBug26467(), + testTypedef() and testTemplateInstantiation() to DOMTests. + +2003-03-28 John Camelon + Added testConstructorChain() and testASMDefinition() to DOMTests. + +2003-03-27 Alain Magloire + Changes were done in the Core Model API, the hierarchy is now + ICModel + ICProject + ICContainer + ITranslationUnit + IArchive + IBinary + We adjust the tests. + * model/org/eclipse/cdt/core/model/tests/ArchiveTests.java + * model/org/eclipse/cdt/core/model/tests/BinaryTests.java + * model/org/eclipse/cdt/core/model/tests/TranslationUniTests.java + * model/org/eclipse/cdt/core/model/tests/WorkingCopyTests.java + +2003-03-26 Andrew Niefer + In ParserSymbolTableTest : + updated all tests to reflect TypeInfo changes + Added testFunctionResolution() & testFunctionResolution_2() in + +2003-03-25 John Camelon + Added testDeclSpecifier(), testNamespaceDefinition(), testLinkageSpecification(), + testUsingClauses() and testEnumSpecifier() to DOMTests. + +2003-03-23 John Camelon + Added ptrOperator() test to DOMTests. + Added testFunctionModifiers() test to DOMTests. + Added testArrays() test to DOMTests. + +2003-03-20 Alain Magloire + + Patch from Amer Hoda, tests for the CElement deltas for Translation Units. + * model/org/eclipse/cdt/core/model/tests/ElementDeltaTest.java + * model/org/eclipse/cdt/core/model/tests/resource/WorkingCopyTestStart.h + +2003-03-19 Alain Magloire + Patch from Amer Hoda, introducing a simple test for the core model. + * model/org/eclipse/cdt/core/model/tests/WorkingCopyTests.java + * model/org/eclipse/cdt/core/model/tests/resource/WorkingCopyTestStart.h + +2003-03-18 John Camelon + Updated DOMTests to validate simple case of a function declaration with multiple parameters. + * parser/org/eclipse/cdt/core/parser/tests/DOMTests.java + +2003-03-11 John Camelon + Updated DOMTests for core.internal.parser change of merging DeclarationSpecifier and DeclSpecifier + Organized imports + * parser/org/eclipse/cdt/core/parser/tests/DOMTests.java + * parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java + +2003-03-10 John Camelon + Added macro pasting tests + +2003-03-06 Andrew Niefer + Added tests for exercising Namespaces & using directives in new parser's symbol table + +2003-03-04 Doug Schaefer + This is a pretty big patch, but it is the merge of the NewParser1 branch into the HEAD branch. lder "parser") + JUnit tests for testing various pieces (source folder "parser" in cdt.ui.tests. + +2003-01-29 Peter Graves + + Fixed the warnings when accessing static methods + * src/org/eclipse/cdt/testplugin/util/DialogCheck.java: + * src/org/eclipse/cdt/testplugin/CTestPlugin.java + * src/org/eclipse/cdt/testplugin/TestWorkbench.java + * ChangeLog: make all entries have the same formatting + +2002-12-17 Peter Graves + + * plugin.xml,test.xml: Some simple cleanups to remove refrences to the jdt and + to move closer to automated running + +2002-11-27 Alain Magloire + + * model/org/eclipse/cdt/core/model/tests/CModelTests.java: + Use CoreModel.getDefault(). + +2002-10-30 Alain Magloire + + * model/org/eclipse/cdt/core/model/tests/CModelTests.java (testGetNatureID): + The fields and the methods use in this test was removed from the CoreModel class. + (testHasNature): The method use in this case was refactor in the classes + CProjectNature and CCProjectNature, fix the test. + +2002-10-18 Peter Graves + + src/org/eclipse/cdt/testplugin/CProjectHelper.jada + Cleanup of the CProjectHelper file to remove unused imports, commeted out code etc. + +>>>>>>> 1.36 diff --git a/core/org.eclipse.cdt.core.tests/about.html b/core/org.eclipse.cdt.core.tests/about.html new file mode 100644 index 00000000000..fad1e4a429b --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/about.html @@ -0,0 +1,44 @@ + + + +About + + + +

About This Content

+ +

20th June, 2002

+

License

+

Eclipse.org makes available all content in this plug-in ("Content"). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the +Common Public License Version 1.0 ("CPL"). A copy of the CPL is available at http://www.eclipse.org/legal/cpl-v10.html. +For purposes of the CPL, "Program" will mean the Content.

+ +

Third Party Content

+ +

The Content includes items that may be have been sourced from third parties as follows:

+ +

JUnit 3.7

+

The plug-in is based on software developed by JUnit.org. Your use of JUnit 3.7 in both source and binary code +form contained in the plug-in is subject to the terms and conditions of the IBM Public License 1.0 which is available at +http://oss.software.ibm.com/developerworks/opensource/license10.html. +The source code is located in testresources/junit37-noUI-src.zip.

+ +

i) IBM effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;

+

ii) IBM effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;

+

iii) IBM states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party.

+ +

Contributions

+ +

If this Content is licensed to you under the terms and conditions of the CPL, any Contributions, as defined in the CPL, uploaded, submitted, or otherwise +made available to Eclipse.org, members of Eclipse.org and/or the host of Eclipse.org web site, by you that relate to such +Content are provided under the terms and conditions of the CPL and can be made available to others under the terms of the CPL.

+ +

If this Content is licensed to you under license terms and conditions other than the CPL ("Other License"), any modifications, enhancements and/or +other code and/or documentation ("Modifications") uploaded, submitted, or otherwise made available to Eclipse.org, members of Eclipse.org and/or the +host of Eclipse.org, by you that relate to such Content are provided under terms and conditions of the Other License and can be made available +to others under the terms of the Other License. In addition, with regard to Modifications for which you are the copyright holder, you are also +providing the Modifications under the terms and conditions of the CPL and such Modifications can be made available to others under the terms of +the CPL.

+ + + \ No newline at end of file diff --git a/core/org.eclipse.cdt.core.tests/build.properties b/core/org.eclipse.cdt.core.tests/build.properties new file mode 100644 index 00000000000..b12f9371bcd --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/build.properties @@ -0,0 +1,19 @@ +source.cdtuitests.jar = src/,\ + ui/,\ + core/,\ + model/,\ + build/,\ + parser/,\ + failures/,\ + suite/ +bin.includes = plugin.xml,\ + about.html,\ + plugin.properties,\ + test.xml,\ + resources/ +src.includes = plugin.xml,\ + about.html,\ + plugin.properties,\ + test.xml,\ + resources/ +about.html = diff --git a/core/org.eclipse.cdt.core.tests/build/org/eclipse/cdt/core/build/managed/tests/AllBuildTests.java b/core/org.eclipse.cdt.core.tests/build/org/eclipse/cdt/core/build/managed/tests/AllBuildTests.java new file mode 100644 index 00000000000..21b46572e36 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/build/org/eclipse/cdt/core/build/managed/tests/AllBuildTests.java @@ -0,0 +1,553 @@ +/********************************************************************** + * Copyright (c) 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * 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: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.core.build.managed.tests; + +import java.util.Arrays; +import java.util.List; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.build.managed.BuildException; +import org.eclipse.cdt.core.build.managed.IConfiguration; +import org.eclipse.cdt.core.build.managed.IOption; +import org.eclipse.cdt.core.build.managed.IOptionCategory; +import org.eclipse.cdt.core.build.managed.IResourceBuildInfo; +import org.eclipse.cdt.core.build.managed.ITarget; +import org.eclipse.cdt.core.build.managed.ITool; +import org.eclipse.cdt.core.build.managed.ManagedBuildManager; +import org.eclipse.cdt.internal.core.build.managed.ToolReference; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; + +/** + * + */ +public class AllBuildTests extends TestCase { + private static final boolean boolVal = true; + private static final String testConfigName = "test.config.override"; + private static final String enumVal = "Another Enum"; + private static final String[] listVal = {"_DEBUG", "/usr/include", "libglade.a"}; + private static final String projectName = "BuildTest"; + private static final String rootExt = "toor"; + private static final String stringVal = "-c -Wall"; + private static final String subExt = "bus"; + + public AllBuildTests(String name) { + super(name); + } + + public static Test suite() { + TestSuite suite = new TestSuite(AllBuildTests.class.getName()); + + suite.addTest(new AllBuildTests("testExtensions")); + suite.addTest(new AllBuildTests("testProject")); + suite.addTest(new AllBuildTests("testConfigurations")); + suite.addTest(new AllBuildTests("testTargetArtifacts")); + suite.addTest(new AllBuildTests("cleanup")); + + return suite; + } + + /** + * Navigates through the build info as defined in the extensions + * defined in this plugin + */ + public void testExtensions() throws Exception { + ITarget testRoot = null; + ITarget testSub = null; + + // Note secret null parameter which means just extensions + ITarget[] targets = ManagedBuildManager.getDefinedTargets(null); + + for (int i = 0; i < targets.length; ++i) { + ITarget target = targets[i]; + + if (target.getName().equals("Test Root")) { + testRoot = target; + checkRootTarget(testRoot, "x"); + + } else if (target.getName().equals("Test Sub")) { + testSub = target; + checkSubTarget(testSub); + } + } + + assertNotNull(testRoot); + assertNotNull(testSub); + } + + /** + * Create a new configuration based on one defined in the plugin file. + * Overrides all of the configuration settings. Saves, closes, and reopens + * the project. Then calls a method to check the overridden options. + * + * Tests creating a new configuration. + * Tests setting options. + * Tests persisting overridden options between project sessions. + * + */ + public void testConfigurations() throws CoreException, BuildException { + // Open the test project + IProject project = createProject(projectName); + + // Make sure there is one and only one target with 2 configs + ITarget[] definedTargets = ManagedBuildManager.getTargets(project); + assertEquals(1, definedTargets.length); + ITarget rootTarget = definedTargets[0]; + IConfiguration[] definedConfigs = rootTarget.getConfigurations(); + assertEquals(2, definedConfigs.length); + IConfiguration baseConfig = definedConfigs[0]; + + // Create a new configuration + IConfiguration newConfig = rootTarget.createConfiguration(baseConfig, testConfigName); + assertEquals(3, rootTarget.getConfigurations().length); + + // There is only one tool + ITool[] definedTools = newConfig.getTools(); + assertEquals(1, definedTools.length); + ITool rootTool = definedTools[0]; + + // Override options in the new configuration + IOptionCategory topCategory = rootTool.getTopOptionCategory(); + assertEquals("Root Tool", topCategory.getName()); + IOption[] options = topCategory.getOptions(null); + assertEquals(2, options.length); + ManagedBuildManager.setOption(newConfig, options[0], listVal); + ManagedBuildManager.setOption(newConfig, options[1], boolVal); + + IOptionCategory[] categories = topCategory.getChildCategories(); + assertEquals(1, categories.length); + options = categories[0].getOptions(null); + assertEquals(2, options.length); + ManagedBuildManager.setOption(newConfig, options[0], stringVal); + ManagedBuildManager.setOption(newConfig, options[1], enumVal); + + // Save, close, reopen and test again + ManagedBuildManager.saveBuildInfo(project); + project.close(null); + ManagedBuildManager.removeBuildInfo(project); + project.open(null); + + // Test the values in the new configuration + checkOptionReferences(project); + } + + public void testProject() throws CoreException, BuildException { + // Create new project + IProject project = createProject(projectName); + // There should not be any targets defined for this project yet + assertEquals(0, ManagedBuildManager.getTargets(project).length); + + // Find the base target definition + ITarget targetDef = ManagedBuildManager.getTarget(project, "test.root"); + assertNotNull(targetDef); + + // Create the target for our project that builds a dummy executable + ITarget newTarget = ManagedBuildManager.createTarget(project, targetDef); + assertEquals(newTarget.getName(), targetDef.getName()); + assertFalse(newTarget.equals(targetDef)); + String buildArtifactName = projectName + "." + newTarget.getDefaultExtension(); + newTarget.setBuildArtifact(buildArtifactName); + + ITarget[] targets = ManagedBuildManager.getTargets(project); + assertEquals(1, targets.length); + ITarget target = targets[0]; + assertEquals(target, newTarget); + assertFalse(target.equals(targetDef)); + + // Copy over the configs + IConfiguration defaultConfig = null; + IConfiguration[] configs = targetDef.getConfigurations(); + for (int i = 0; i < configs.length; ++i) { + // Make the first configuration the default + if (i == 0) { + defaultConfig = target.createConfiguration(configs[i], target.getId() + "." + i); + } else { + target.createConfiguration(configs[i], target.getId() + "." + i); + } + } + ManagedBuildManager.setDefaultConfiguration(project, defaultConfig); + checkRootTarget(target, "x"); + + // Override the "String Option in Category" option value + configs = target.getConfigurations(); + ITool[] tools = configs[0].getTools(); + IOptionCategory topCategory = tools[0].getTopOptionCategory(); + IOptionCategory[] categories = topCategory.getChildCategories(); + IOption[] options = categories[0].getOptions(configs[0]); + configs[0].setOption(options[0], "z"); + options = categories[0].getOptions(null); + assertEquals("x", options[0].getStringValue()); + options = categories[0].getOptions(configs[0]); + assertEquals("z", options[0].getStringValue()); + + // Save, close, reopen and test again + ManagedBuildManager.saveBuildInfo(project); + project.close(null); + ManagedBuildManager.removeBuildInfo(project); + project.open(null); + + // Test that the default config was remembered + IResourceBuildInfo info = ManagedBuildManager.getBuildInfo(project); + assertEquals(defaultConfig.getId(), info.getDefaultConfiguration(target).getId()); + + // Get the targets + targets = ManagedBuildManager.getTargets(project); + assertEquals(1, targets.length); + // See if the artifact name is remembered + assertEquals(targets[0].getArtifactName(), buildArtifactName); + // Check the rest of the default information + checkRootTarget(targets[0], "z"); + + // Now test the information the makefile builder needs + checkBuildSettings(project); + } + + /** + * Tests the tool settings through the interface the makefile generator + * uses. + * + * @param project + */ + private void checkBuildSettings(IProject project) { + String ext1 = "foo"; + String ext2 = "bar"; + String badExt = "cpp"; + String expectedOutput = "toor"; + String expectedCmd = "doIt"; + + // Get that interface, Rover. Go get it. That's a good doggie! Good boy. + IResourceBuildInfo info = ManagedBuildManager.getBuildInfo(project); + assertNotNull(info); + assertEquals(info.getBuildArtifactName(), "BuildTest.toor"); + + // There should be a default configuration defined for the project + ITarget buildTarget = info.getDefaultTarget(); + assertNotNull(buildTarget); + assertEquals(buildTarget.getId(), "test.root.1"); + IConfiguration buildConfig = info.getDefaultConfiguration(buildTarget); + assertNotNull(buildConfig); + assertEquals(buildConfig.getId(), "test.root.1.0"); + + // The default target should be the same as the one-and-only target in the project + List targets = info.getTargets(); + assertEquals(targets.size(), 1); + ITarget target = (ITarget) targets.get(0); + assertEquals(target, buildTarget); + + // Check that tool handles resources with extensions foo and bar by building a baz + assertEquals(info.getOutputExtension(ext1), expectedOutput); + assertEquals(info.getOutputExtension(ext2), expectedOutput); + + // Check that it ignores others based on filename extensions + assertNull(info.getOutputExtension(badExt)); + + // Now see what the tool command line invocation is for foo and bar + assertEquals(info.getToolForSource(ext1), expectedCmd); + assertEquals(info.getToolForSource(ext2), expectedCmd); + // Make sure that there is no tool to build files of type foo and bar + assertNull(info.getToolForTarget(ext1)); + assertNull(info.getToolForTarget(ext2)); + + // There is no target that builds toor + assertNull(info.getToolForSource(expectedOutput)); + // but there is one that produces it + assertEquals(info.getToolForTarget(expectedOutput), expectedCmd); + + // Now check the build flags + assertEquals(info.getFlagsForSource(ext1), "-La -Lb z -e1"); + assertEquals(info.getFlagsForSource(ext1), info.getFlagsForSource(ext2)); + + } + + /** + * Tests that overridden options are properly read into build model. + * Test that option values that are not overridden remain the same. + * + * @param project The project to get build model information for. + * @throws BuildException + */ + private void checkOptionReferences(IProject project) throws BuildException { + // Get the targets out of the project + ITarget[] definedTargets = ManagedBuildManager.getTargets(project); + assertEquals(1, definedTargets.length); + ITarget rootTarget = definedTargets[0]; + + // Now get the configs + IConfiguration[] definedConfigs = rootTarget.getConfigurations(); + assertEquals(3, definedConfigs.length); + IConfiguration newConfig = rootTarget.getConfiguration(testConfigName); + assertNotNull(newConfig); + + // Now get the tool options and make sure the values are correct + ITool[] definedTools = newConfig.getTools(); + assertEquals(1, definedTools.length); + ITool rootTool = definedTools[0]; + + // Check that the options in the new config contain overridden values + IOption[] rootOptions = rootTool.getOptions(); + assertEquals(4, rootOptions.length); + // First is the new list + assertEquals("List Option in Top", rootOptions[0].getName()); + assertEquals(IOption.STRING_LIST, rootOptions[0].getValueType()); + String[] list = rootOptions[0].getStringListValue(); + assertEquals(3, list.length); + assertTrue(Arrays.equals(listVal, list)); + assertEquals(rootOptions[0].getCommand(), "-L"); + // Next option is a boolean in top + assertEquals("Boolean Option in Top", rootOptions[1].getName()); + assertEquals(IOption.BOOLEAN, rootOptions[1].getValueType()); + assertEquals(boolVal, rootOptions[1].getBooleanValue()); + assertEquals("-b", rootOptions[1].getCommand()); + // Next option is a string category + assertEquals("String Option in Category", rootOptions[2].getName()); + assertEquals(IOption.STRING, rootOptions[2].getValueType()); + assertEquals(stringVal, rootOptions[2].getStringValue()); + // Final option is an enumerated + assertEquals("Enumerated Option in Category", rootOptions[3].getName()); + assertEquals(IOption.ENUMERATED, rootOptions[3].getValueType()); + String selEnum = rootOptions[3].getSelectedEnum(); + assertEquals(enumVal, selEnum); + String[] enums = rootOptions[3].getApplicableValues(); + assertEquals(2, enums.length); + assertEquals("Default Enum", enums[0]); + assertEquals("Another Enum", enums[1]); + assertEquals("-e1", rootOptions[3].getEnumCommand(enums[0])); + assertEquals("-e2", rootOptions[3].getEnumCommand(enums[1])); + assertEquals("-e2", rootOptions[3].getEnumCommand(selEnum)); + } + + + private void checkRootTarget(ITarget target, String oicValue) throws BuildException { + // Target stuff + assertTrue(target.isTestTarget()); + assertEquals(target.getDefaultExtension(), rootExt); + + // Tools + ITool[] tools = target.getTools(); + // Root Tool + ITool rootTool = tools[0]; + assertEquals("Root Tool", rootTool.getName()); + // 4 Options are defined in the root tool + IOption[] options = rootTool.getOptions(); + assertEquals(4, options.length); + // First option is a 2-element list + assertEquals("List Option in Top", options[0].getName()); + assertEquals(IOption.STRING_LIST, options[0].getValueType()); + String[] valueList = options[0].getStringListValue(); + assertEquals(2, valueList.length); + assertEquals("a", valueList[0]); + assertEquals("b", valueList[1]); + assertEquals(options[0].getCommand(), "-L"); + // Next option is a boolean in top + assertEquals("Boolean Option in Top", options[1].getName()); + assertEquals(IOption.BOOLEAN, options[1].getValueType()); + assertEquals(false, options[1].getBooleanValue()); + assertEquals("-b", options[1].getCommand()); + // Next option is a string category + assertEquals("String Option in Category", options[2].getName()); + assertEquals(IOption.STRING, options[2].getValueType()); + assertEquals("x", options[2].getStringValue()); + // Final option is an enumerated + assertEquals("Enumerated Option in Category", options[3].getName()); + assertEquals(IOption.ENUMERATED, options[3].getValueType()); + assertEquals("Default Enum", options[3].getSelectedEnum()); + valueList = options[3].getApplicableValues(); + assertEquals(2, valueList.length); + assertEquals("Default Enum", valueList[0]); + assertEquals("Another Enum", valueList[1]); + assertEquals("-e1", options[3].getEnumCommand(valueList[0])); + assertEquals("-e2", options[3].getEnumCommand(valueList[1])); + + // Option Categories + IOptionCategory topCategory = rootTool.getTopOptionCategory(); + assertEquals("Root Tool", topCategory.getName()); + options = topCategory.getOptions(null); + assertEquals(2, options.length); + assertEquals("List Option in Top", options[0].getName()); + assertEquals("Boolean Option in Top", options[1].getName()); + IOptionCategory[] categories = topCategory.getChildCategories(); + assertEquals(1, categories.length); + assertEquals("Category", categories[0].getName()); + options = categories[0].getOptions(null); + assertEquals(2, options.length); + assertEquals("String Option in Category", options[0].getName()); + assertEquals("Enumerated Option in Category", options[1].getName()); + + // Configs + IConfiguration[] configs = target.getConfigurations(); + // Root Config + IConfiguration rootConfig = configs[0]; + assertEquals("Root Config", rootConfig.getName()); + // Tools + tools = rootConfig.getTools(); + assertEquals(1, tools.length); + assertEquals("Root Tool", tools[0].getName()); + topCategory = tools[0].getTopOptionCategory(); + options = topCategory.getOptions(configs[0]); + assertEquals(2, options.length); + assertEquals("List Option in Top", options[0].getName()); + valueList = options[0].getStringListValue(); + assertEquals("a", valueList[0]); + assertEquals("b", valueList[1]); + assertEquals("Boolean Option in Top", options[1].getName()); + categories = topCategory.getChildCategories(); + options = categories[0].getOptions(configs[0]); + assertEquals(2, options.length); + assertEquals("String Option in Category", options[0].getName()); + assertEquals(oicValue, options[0].getStringValue()); + assertEquals("Enumerated Option in Category", options[1].getName()); + + // Root Override Config + assertEquals("Root Override Config", configs[1].getName()); + tools = configs[1].getTools(); + assertEquals(1, tools.length); + assertTrue(tools[0] instanceof ToolReference); + assertEquals("Root Tool", tools[0].getName()); + topCategory = tools[0].getTopOptionCategory(); + options = topCategory.getOptions(configs[1]); + assertEquals(2, options.length); + assertEquals("List Option in Top", options[0].getName()); + valueList = options[0].getStringListValue(); + assertEquals("a", valueList[0]); + assertEquals("b", valueList[1]); + assertEquals("Boolean Option in Top", options[1].getName()); + categories = topCategory.getChildCategories(); + options = categories[0].getOptions(configs[1]); + assertEquals(2, options.length); + assertEquals("String Option in Category", options[0].getName()); + assertEquals("y", options[0].getStringValue()); + assertEquals("Enumerated Option in Category", options[1].getName()); + valueList = options[1].getApplicableValues(); + assertEquals(2, valueList.length); + assertEquals("Default Enum", valueList[0]); + assertEquals("Another Enum", valueList[1]); + assertEquals("-e1", options[1].getEnumCommand(valueList[0])); + assertEquals("-e2", options[1].getEnumCommand(valueList[1])); + } + + private void checkSubTarget(ITarget target) { + // Make sure this is a test target + assertTrue(target.isTestTarget()); + // Make sure the build artifact extension is there + assertEquals(target.getDefaultExtension(), subExt); + + // Tools + ITool[] tools = target.getTools(); + // Root Tool + ITool rootTool = tools[0]; + assertEquals("Root Tool", rootTool.getName()); + // Sub Tool + ITool subTool = tools[1]; + assertEquals("Sub Tool", subTool.getName()); + + // Configs + IConfiguration[] configs = target.getConfigurations(); + // Root Config + IConfiguration rootConfig = configs[0]; + assertEquals("Root Config", rootConfig.getName()); + assertEquals("Root Override Config", configs[1].getName()); + // Sub Config + IConfiguration subConfig = configs[2]; + assertEquals("Sub Config", subConfig.getName()); + } + + /** + * Remove all the project information associated with the project used during test. + */ + public void cleanup() { + removeProject(projectName); + } + + /** + * Create a new project named name or return the project in + * the workspace of the same name if it exists. + * + * @param name The name of the project to create or retrieve. + * @return + * @throws CoreException + */ + private IProject createProject(String name) throws CoreException { + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + IProject project = root.getProject(name); + if (!project.exists()) { + project.create(null); + } else { + project.refreshLocal(IResource.DEPTH_INFINITE, null); + } + + if (!project.isOpen()) { + project.open(null); + } + + //CCorePlugin.getDefault().convertProjectToC(project, null, CCorePlugin.PLUGIN_ID + ".make", true); + + return project; + } + + /** + * Remove the IProject with the name specified in the argument from the + * receiver's workspace. + * + * @param name + */ + private void removeProject(String name) { + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + IProject project = root.getProject(name); + if (project.exists()) { + try { + project.delete(true, false, null); + } catch (CoreException e) { + assertTrue(false); + } + } + } + + /** + * Test that the build artifact of a ITarget can be modified + * programmatically. + */ + public void testTargetArtifacts () throws CoreException { + // Open the test project + IProject project = createProject(projectName); + + // Make sure there is one and only one target + ITarget[] definedTargets = ManagedBuildManager.getTargets(project); + assertEquals(1, definedTargets.length); + ITarget rootTarget = definedTargets[0]; + + // Set the build artifact of the target + String ext = rootTarget.getDefaultExtension(); + String name = project.getName() + "." + ext; + rootTarget.setBuildArtifact(name); + + // Save, close, reopen and test again + ManagedBuildManager.saveBuildInfo(project); + project.close(null); + ManagedBuildManager.removeBuildInfo(project); + project.open(null); + + // Make sure there is one and only one target + definedTargets = ManagedBuildManager.getTargets(project); + assertEquals(1, definedTargets.length); + rootTarget = definedTargets[0]; + assertEquals(name, rootTarget.getArtifactName()); + } + + public void testThatAlwaysFails() { + assertTrue(false); + } +} diff --git a/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/model/failedTests/CModelElementsFailedTests.java b/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/model/failedTests/CModelElementsFailedTests.java new file mode 100644 index 00000000000..67d0efcb55a --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/model/failedTests/CModelElementsFailedTests.java @@ -0,0 +1,116 @@ +package org.eclipse.cdt.core.model.failedTests; + +/********************************************************************** + * Copyright (c) 2002,2003 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * Rational Software - Initial API and implementation +***********************************************************************/ + +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.Map; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.CCProjectNature; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.INamespace; +import org.eclipse.cdt.core.model.IStructure; +import org.eclipse.cdt.internal.core.model.CElement; +import org.eclipse.cdt.internal.core.model.TranslationUnit; +import org.eclipse.cdt.testplugin.CProjectHelper; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; + + +/** + * @author vhirsl + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public class CModelElementsFailedTests extends TestCase { + private ICProject fCProject; + private IFile headerFile; + private NullProgressMonitor monitor; + + public static Test suite() { + TestSuite suite= new TestSuite(CModelElementsFailedTests.class.getName()); + suite.addTest(new CModelElementsFailedTests("testBug36379")); + return suite; + } + + public CModelElementsFailedTests(String name) { + super(name); + } + + protected void setUp() throws Exception { + monitor = new NullProgressMonitor(); + String pluginRoot=org.eclipse.core.runtime.Platform.getPlugin("org.eclipse.cdt.core.tests").find(new Path("/")).getFile(); + + fCProject= CProjectHelper.createCProject("TestProject1", "bin"); + headerFile = fCProject.getProject().getFile("CModelElementsTest.h"); + if (!headerFile.exists()) { + try{ + FileInputStream fileIn = new FileInputStream(pluginRoot+ "resources/cfiles/CModelElementsTestStart.h"); + headerFile.create(fileIn,false, monitor); + } catch (CoreException e) { + e.printStackTrace(); + } + } + if (!fCProject.getProject().hasNature(CCProjectNature.CC_NATURE_ID)) { + addNatureToProject(fCProject.getProject(), CCProjectNature.CC_NATURE_ID, null); + } + + CCorePlugin.getDefault().setUseNewParser(true); + } + + private static void addNatureToProject(IProject proj, String natureId, IProgressMonitor monitor) throws CoreException { + IProjectDescription description = proj.getDescription(); + String[] prevNatures= description.getNatureIds(); + String[] newNatures= new String[prevNatures.length + 1]; + System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length); + newNatures[prevNatures.length]= natureId; + description.setNatureIds(newNatures); + proj.setDescription(description, monitor); + } + + protected void tearDown() throws Exception { + CProjectHelper.delete(fCProject); + } + + public void testBug36379() { + TranslationUnit tu = new TranslationUnit(fCProject, headerFile); + // parse the translation unit to get the elements tree + Map newElement = tu.parse(true); // require line numbers + + // tu ---> namespace: MyPackage + ArrayList tuPackages = tu.getChildrenOfType(ICElement.C_NAMESPACE); + INamespace namespace = (INamespace) tuPackages.get(0); + assertEquals(namespace.getElementName(), new String("MyPackage")); + + // MyPackage ---> class: Hello + ArrayList nsClasses = namespace.getChildrenOfType(ICElement.C_CLASS); + IStructure classHello = (IStructure) nsClasses.get(0); + assertEquals(classHello.getElementName(), new String("Hello")); + + // Bug 36379: parser does not provide line number information for nested definitions + assertEquals(0, ((CElement)classHello).getStartLine()); + assertEquals(0, ((CElement)classHello).getEndLine()); + } + +} diff --git a/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/parser/failedTests/DOMFailedTest.java b/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/parser/failedTests/DOMFailedTest.java new file mode 100644 index 00000000000..1bdb96ea75a --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/parser/failedTests/DOMFailedTest.java @@ -0,0 +1,27 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.core.parser.failedTests; + +import org.eclipse.cdt.core.parser.tests.BaseDOMTest; + +/** + * @author jcamelon + */ +public class DOMFailedTest extends BaseDOMTest { + + public DOMFailedTest(String name) { + super(name); + } + + public void testBug36730()throws Exception { + failTest("FUNCTION_MACRO( 1, a )\n int i;"); + } +} diff --git a/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/parser/failedTests/LokiFailures.java b/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/parser/failedTests/LokiFailures.java new file mode 100644 index 00000000000..22a0e21718a --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/parser/failedTests/LokiFailures.java @@ -0,0 +1,40 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.core.parser.failedTests; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; + +import org.eclipse.cdt.core.parser.tests.BaseDOMTest; + +/** + * @author jcamelon + */ +public class LokiFailures extends BaseDOMTest { + + public LokiFailures(String name) { + super(name); + } + + public void testBugTypeManip151() + { + Writer code = new StringWriter(); + try + { + code.write( "template struct SuperSubclass {\n" ); + code.write( "enum { value = (::Loki::Conversion::exists && \n" ); + code.write( "!::Loki::Conversion::sameType) }; };" ); + } catch( IOException ioe ){} + failTest( code.toString() ); + + } +} diff --git a/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/parser/failedTests/STLFailedTests.java b/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/parser/failedTests/STLFailedTests.java new file mode 100644 index 00000000000..9997d3cce10 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/failures/org/eclipse/cdt/core/parser/failedTests/STLFailedTests.java @@ -0,0 +1,35 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.core.parser.failedTests; +import java.io.StringWriter; +import java.io.Writer; + +import org.eclipse.cdt.core.parser.tests.BaseDOMTest; + +/** + * @author hamer + */ +public class STLFailedTests extends BaseDOMTest { + + public STLFailedTests(String name) { + super(name); + } + + public void testBug36805() throws Exception{ + Writer code = new StringWriter(); + code.write("__STL_BEGIN_NAMESPACE\n"); + code.write("template class char_traits\n"); + code.write(": public __char_traits_base<_CharT, _CharT>\n"); + code.write("{};\n"); + failTest(code.toString()); + } + +} diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllCoreTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllCoreTests.java new file mode 100644 index 00000000000..6d536c6355c --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllCoreTests.java @@ -0,0 +1,43 @@ +package org.eclipse.cdt.core.model.tests; +/* + * (c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + */ + + +import junit.framework.Test; +import junit.framework.TestSuite; + + +/** + * + * AllTests.java + * This is the main entry point for running this suite of JUnit tests + * for all tests within the package "org.eclipse.cdt.core.model" + * + * @author Judy N. Green + * @since Jul 19, 2002 + */ +public class AllCoreTests { + + public static void main(String[] args) { + junit.textui.TestRunner.run(suite()); + } + + public static Test suite() { + TestSuite suite = new TestSuite(AllCoreTests.class.getName()); + + // Just add more test cases here as you create them for + // each class being tested + suite.addTest(AllLanguageInterfaceTests.suite()); + suite.addTest(CModelTests.suite()); + suite.addTest(CModelExceptionTest.suite()); + suite.addTest(FlagTests.suite()); + suite.addTest(ArchiveTests.suite()); + suite.addTest(TranslationUnitTests.suite()); + + return suite; + + } +} // End of AllCoreTests.java + diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllLanguageInterfaceTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllLanguageInterfaceTests.java new file mode 100644 index 00000000000..e7e5274bdf3 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/AllLanguageInterfaceTests.java @@ -0,0 +1,35 @@ +/* + * Created on Jun 9, 2003 + * by bnicolle + */ +package org.eclipse.cdt.core.model.tests; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * LanguageInterfaceTests + * lists all parts of the C/C++ language interface objects + * to be tested. + * @author bnicolle + * + */ +public class AllLanguageInterfaceTests { + + /** + * + */ + public static Test suite() { + TestSuite suite = new TestSuite(AllLanguageInterfaceTests.class.getName()); + + // Just add more test cases here as you create them for + // each class being tested + + suite.addTest(IIncludeTests.suite()); + suite.addTest(IMacroTests.suite()); + suite.addTest(IStructureTests.suite()); + return suite; + + } + +} diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ArchiveTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ArchiveTests.java new file mode 100644 index 00000000000..bac3f94d3dc --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ArchiveTests.java @@ -0,0 +1,208 @@ +package org.eclipse.cdt.core.model.tests; + +/* + * (c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + */ + + +import java.io.FileInputStream; +import java.io.FileNotFoundException; + +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.model.IArchive; +import org.eclipse.cdt.core.model.IBinary; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.testplugin.CProjectHelper; +import org.eclipse.cdt.testplugin.util.ExpectedStrings; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; + + + +/** + * @author Peter Graves + * + * This file contains a set of generic tests for the core C model's Archive + * class. There is nothing exotic here, mostly just sanity type tests + * + */ +public class ArchiveTests extends TestCase { + IWorkspace workspace; + IWorkspaceRoot root; + ICProject testProject; + IFile cfile, exefile, libfile, archfile, objfile; + Path cpath, exepath, libpath, archpath, objpath; + NullProgressMonitor monitor; + + + /** + * Constructor for ArchiveTests + * @param name + */ + public ArchiveTests(String name) { + super(name); + /*** + * The assume that they have a working workspace + * and workspace root object to use to create projects/files in, + * so we need to get them setup first. + */ + workspace= ResourcesPlugin.getWorkspace(); + root= workspace.getRoot(); + monitor = new NullProgressMonitor(); + if (workspace==null) + fail("Workspace was not setup"); + if (root==null) + fail("Workspace root was not setup"); + + } + + /** + * Sets up the test fixture. + * + * Called before every test case method. + * + * Example code test the packages in the project + * "com.qnx.tools.ide.cdt.core" + */ + protected void setUp() throws CoreException,FileNotFoundException { + + /*** + * Setup the various files, paths and projects that are needed by the + * tests + */ + String pluginRoot=org.eclipse.core.runtime.Platform.getPlugin("org.eclipse.cdt.core.tests").find(new Path("/")).getFile(); + testProject=CProjectHelper.createCProject("filetest", "none"); + if (testProject==null) + fail("Unable to create project"); + + cfile = testProject.getProject().getFile("exetest.c"); + if (!cfile.exists()) { + cfile.create(new FileInputStream(pluginRoot+"resources/exe/main.c"),false, monitor); + + } + cpath=new Path(workspace.getRoot().getLocation()+"/filetest/main.c"); + + objfile = testProject.getProject().getFile("exetest.o"); + if (!objfile.exists()) { + objfile.create(new FileInputStream(pluginRoot+"resources/exe/x86/o.g/main.o"),false, monitor); + + } + objpath=new Path(workspace.getRoot().getLocation()+"/filetest/main.o"); + + exefile = testProject.getProject().getFile("test_g"); + if (!exefile.exists()) { + exefile.create(new FileInputStream(pluginRoot+"resources/exe/x86/o.g/exe_g"),false, monitor); + + } + exepath=new Path(workspace.getRoot().getLocation()+"/filetest/exe_g"); + + archfile = testProject.getProject().getFile("libtestlib_g.a"); + if (!archfile.exists()) { + archfile.create(new FileInputStream(pluginRoot+"resources/testlib/x86/a.g/libtestlib_g.a"),false, monitor); + + } + libpath=new Path(workspace.getRoot().getLocation()+"/filetest/libtestlib_g.so"); + + libfile = testProject.getProject().getFile("libtestlib_g.so"); + if (!libfile.exists()) { + libfile.create(new FileInputStream(pluginRoot+"resources/testlib/x86/so.g/libtestlib_g.so"),false, monitor); + + } + archpath=new Path(workspace.getRoot().getLocation()+"/filetest/libtestlib_g.a"); + + + } + + /** + * Tears down the test fixture. + * + * Called after every test case method. + */ + protected void tearDown() throws CoreException { + CProjectHelper.delete(testProject); + } + + public static TestSuite suite() { + return new TestSuite(ArchiveTests.class); + } + + public static void main (String[] args){ + junit.textui.TestRunner.run(suite()); + } + + + + public void testGetBinaries() throws CoreException,FileNotFoundException { + IArchive myArchive; + IBinary[] bins; + ICElement[] elements; + ExpectedStrings expBin, expObj[]; + String[] myStrings; + int x; + + + /**** + * Setup the expected strings for the binaries, and the elements within + * the binaries + */ + myStrings=new String[2]; + myStrings[0]="test.o"; + myStrings[1]="test2.o"; + expBin=new ExpectedStrings(myStrings); + + expObj=new ExpectedStrings[2]; + myStrings[0]="func1"; + myStrings[1]="func2"; + expObj[0]=new ExpectedStrings(myStrings); + myStrings[0]="test2func1"; + myStrings[1]="test2func2"; + expObj[1]=new ExpectedStrings(myStrings); + + /*** + * Grab the archive we want to test, and find all the binaries and + * all the elements in all the binaries and make sure we get + * everything we expect. + */ + myArchive=CProjectHelper.findArchive(testProject, "libtestlib_g.a"); + if (myArchive==null) + fail("Could not find archive"); + bins=myArchive.getBinaries(); + for (x=0;x include + checkInclude(tu); + + // tu ---> macro + checkMacro(tu); + + // tu ---> namespace: MyPackage + ArrayList tuPackages = tu.getChildrenOfType(ICElement.C_NAMESPACE); + INamespace namespace = (INamespace) tuPackages.get(0); + assertEquals(namespace.getElementName(), new String("MyPackage")); + checkLineNumbers((CElement)namespace, 8, 130); + checkClass(namespace); + + checkEnums(namespace); + + checkVariables(namespace); + + checkVariableDeclarations(namespace); + + checkFunctions(namespace); + + checkStructs(namespace); + + checkTemplates(namespace); + + checkArrays(tu); + } + + private void checkInclude(IParent tu){ + ArrayList tuIncludes = tu.getChildrenOfType(ICElement.C_INCLUDE); + IInclude inc1 = (IInclude) tuIncludes.get(0); + assertEquals(inc1.getElementName(), new String("stdio.h")); + checkLineNumbers((CElement)inc1, 2, 2); + } + + private void checkMacro(IParent tu){ + ArrayList tuMacros = tu.getChildrenOfType(ICElement.C_MACRO); + IMacro mac1 = (IMacro) tuMacros.get(0); + assertEquals(mac1.getElementName(), new String("PRINT")); + checkLineNumbers((CElement)mac1, 5, 5); + } + + private void checkClass(IParent namespace){ + // MyPackage ---> class: Hello + ArrayList nsClasses = namespace.getChildrenOfType(ICElement.C_CLASS); + IStructure classHello = (IStructure) nsClasses.get(0); + assertEquals(classHello.getElementName(), new String("Hello")); + checkLineNumbers((CElement)classHello, 12, 53); + + // Hello --> field: int x + ArrayList helloFields = classHello.getChildrenOfType(ICElement.C_FIELD); + IField intX = (IField) helloFields.get(0); + assertEquals(intX.getElementName(), new String("x")); + assertEquals(intX.getTypeName(), new String("int")); + checkLineNumbers((CElement)intX, 17, 17); + + int xVisibility = intX.getVisibility(); + if (xVisibility != IMember.V_PROTECTED) + fail("visibility should be protected!"); + + // Hello ---> method: void setX(int X) + ArrayList helloMethods = classHello.getChildrenOfType(ICElement.C_METHOD); + IMethod setX = (IMethod) helloMethods.get(0); + assertEquals(setX.getElementName(), new String("setX")); + assertEquals(setX.getReturnType(), new String("void")); + checkLineNumbers((CElement)setX, 19, 22); + int setXNumOfParam = setX.getNumberOfParameters(); + if(setXNumOfParam != 1) + fail("setX should have one parameter!"); + String[] setXParamTypes = setX.getParameterTypes(); + String firstParamType = setXParamTypes[0]; + assertEquals(firstParamType, new String("int")); + // TODO : check for the inline here + + checkNestedNamespace(classHello); + } + private void checkNestedNamespace(IParent classHello){ + // Hello ---> namespace: MyNestedPackage + ArrayList helloNamespaces = classHello.getChildrenOfType(ICElement.C_NAMESPACE); + INamespace myNestedPackage = (INamespace) helloNamespaces.get(0); + assertEquals(myNestedPackage.getElementName(), new String("MyNestedPackage")); + checkLineNumbers((CElement)myNestedPackage, 25, 52); + + checkParentNestedClass(myNestedPackage); + checkDerivedNestedClass(myNestedPackage); + } + private void checkParentNestedClass(IParent myNestedPackage){ + // MyNestedPackage ---> class: Y + ArrayList nestedClasses = myNestedPackage.getChildrenOfType(ICElement.C_CLASS); + IStructure classY = (IStructure) nestedClasses.get(0); + assertEquals(classY.getElementName(), new String("Y")); + checkLineNumbers((CElement)classY, 28, 35); + + // Y ---> constructor: Y + ArrayList yMethods = classY.getChildrenOfType(ICElement.C_METHOD_DECLARATION); + IMethodDeclaration constructor = (IMethodDeclaration) yMethods.get(0); + assertEquals(constructor.getElementName(), new String("Y")); + assertTrue (constructor.isConstructor()); + checkLineNumbers((CElement)constructor, 32, 32); + + // Y ---> destructor: ~Y + IMethodDeclaration destructor = (IMethodDeclaration) yMethods.get(1); + assertEquals(destructor.getElementName(), new String("~Y")); + assertTrue (destructor.isDestructor()); + checkLineNumbers((CElement)destructor, 34, 34); + // TODO: check for virtual on destructors + + } + + private void checkDerivedNestedClass(IParent myNestedPackage){ + // MyNestedPackage ---> class: X public Y + ArrayList nestedClasses = myNestedPackage.getChildrenOfType(ICElement.C_CLASS); + IStructure classX = (IStructure) nestedClasses.get(1); + assertEquals(classX.getElementName(), new String("X")); + checkLineNumbers((CElement)classX, 38, 51); + // TODO : Check for base classes here + + // X --> field: B b + ArrayList xFieldChildren = classX.getChildrenOfType(ICElement.C_FIELD); + IField bB = (IField) xFieldChildren.get(0); + assertEquals(bB.getElementName(), new String("b")); + assertEquals(bB.getTypeName(), new String("B")); + checkLineNumbers((CElement)bB, 42, 42); + int bVisibility = bB.getVisibility(); + if (bVisibility != IMember.V_PRIVATE) + fail("visibility should be private!"); + + // X ---> constructor chain: X + ArrayList xMethodChildren = classX.getChildrenOfType(ICElement.C_METHOD); + IMethod xconstructor = (IMethod) xMethodChildren.get(0); + assertEquals(xconstructor.getElementName(), new String("X")); + assertTrue (xconstructor.isConstructor()); + checkLineNumbers((CElement)xconstructor, 46, 48); + + // X ---> method declaration: doNothing + ArrayList xMethodDeclarations = classX.getChildrenOfType(ICElement.C_METHOD_DECLARATION); + IMethodDeclaration xDoNothing = (IMethodDeclaration) xMethodDeclarations.get(0); + assertEquals(xDoNothing.getElementName(), new String("doNothing")); + assertEquals(xDoNothing.getReturnType(), new String("int")); + checkLineNumbers((CElement)xDoNothing, 50, 50); + } + + private void checkEnums(IParent namespace){ + // MyPackage ---> enum: Noname + ArrayList nsEnums = namespace.getChildrenOfType(ICElement.C_ENUMERATION); + IEnumeration enum = (IEnumeration) nsEnums.get(0); + assertEquals(enum.getElementName(), new String("")); + checkLineNumbers((CElement)enum, 57, 61); + + // enum ---> enumerator: first + ArrayList enumEnumerators = enum.getChildrenOfType(ICElement.C_ENUMERATOR); + IEnumerator first = (IEnumerator) enumEnumerators.get(0); + assertEquals(first.getElementName(), new String("first")); + // enum ---> enumerator: second + IEnumerator second = (IEnumerator) enumEnumerators.get(1); + assertEquals(second.getElementName(), new String("second")); + // enum ---> enumerator: third + IEnumerator third = (IEnumerator) enumEnumerators.get(2); + assertEquals(third.getElementName(), new String("third")); + + // MyPackage ---> enum: MyEnum + IEnumeration myEnum = (IEnumeration) nsEnums.get(1); + assertEquals(myEnum.getElementName(), new String("MyEnum")); + checkLineNumbers((CElement)myEnum, 64, 67); + + // enum ---> enumerator: first + ArrayList myEnumEnumerators = myEnum.getChildrenOfType(ICElement.C_ENUMERATOR); + IEnumerator f = (IEnumerator) myEnumEnumerators.get(0); + assertEquals(f.getElementName(), new String("f")); + // enum ---> enumerator: second + IEnumerator s = (IEnumerator) myEnumEnumerators.get(1); + assertEquals(s.getElementName(), new String("s")); + // enum ---> enumerator: third + IEnumerator t = (IEnumerator) myEnumEnumerators.get(2); + assertEquals(t.getElementName(), new String("t")); + } + + private void checkVariables(IParent namespace){ + // MyPackage ---> int v + ArrayList nsVars = namespace.getChildrenOfType(ICElement.C_VARIABLE); + IVariable var1 = (IVariable) nsVars.get(0); + assertEquals(var1.getElementName(), new String("v")); + assertEquals(var1.getTypeName(), new String("int")); + checkLineNumbers((CElement)var1, 71, 71); + + // MyPackage ---> unsigned long vuLong + IVariable var2 = (IVariable) nsVars.get(1); + assertEquals(var2.getElementName(), new String("vuLong")); + assertEquals(var2.getTypeName(), new String("unsigned long ")); + checkLineNumbers((CElement)var2, 73, 73); + + // MyPackage ---> unsigned short vuShort + IVariable var3 = (IVariable) nsVars.get(2); + assertEquals(var3.getElementName(), new String("vuShort")); + assertEquals(var3.getTypeName(), new String("unsigned short ")); + checkLineNumbers((CElement)var3, 75, 75); + } + + private void checkVariableDeclarations(IParent namespace){ + // MyPackage ---> extern int evar + ArrayList nsVarDecls = namespace.getChildrenOfType(ICElement.C_VARIABLE_DECLARATION); + IVariableDeclaration vDecl1 = (IVariableDeclaration) nsVarDecls.get(0); + assertEquals(vDecl1.getElementName(), new String("evar")); + assertEquals(vDecl1.getTypeName(), new String("int")); + checkLineNumbers((CElement)vDecl1, 79, 79); + +// // MyPackage ---> function pointer: orig_malloc_hook +// IVariableDeclaration vDecl2 = (IVariableDeclaration) nsVarDecls.get(1); +// assertEquals(vDecl2.getElementName(), new String("orig_malloc_hook")); +// assertEquals(vDecl2.getTypeName(), new String ("void*(*)(const char*, int, size_t)")); +// checkLineNumbers((CElement)vDecl2, 81, 81); + } + + private void checkFunctions(IParent namespace){ + // MyPackage ---> function: void foo() + ArrayList nsFunctionDeclarations = namespace.getChildrenOfType(ICElement.C_FUNCTION_DECLARATION); + IFunctionDeclaration f1 = (IFunctionDeclaration) nsFunctionDeclarations.get(0); + assertEquals(f1.getElementName(), new String("foo")); + assertEquals(f1.getReturnType(), new String("void")); + checkLineNumbers((CElement)f1, 85, 85); + + // MyPackage ---> function: char* foo(int&, char**) + IFunctionDeclaration f2 = (IFunctionDeclaration) nsFunctionDeclarations.get(1); + assertEquals(f2.getElementName(), new String("foo")); + assertEquals(f2.getReturnType(), new String("char*")); + checkLineNumbers((CElement)f2, 87, 88); + int fooNumOfParam = f2.getNumberOfParameters(); + if(fooNumOfParam != 2) + fail("foo should have two parameter!"); + String[] paramTypes = f2.getParameterTypes(); + assertEquals(paramTypes[0], new String("int&")); + assertEquals(paramTypes[1], new String("char**")); + + // MyPackage ---> function: void boo() {} + ArrayList nsFunctions = namespace.getChildrenOfType(ICElement.C_FUNCTION); + IFunction f3 = (IFunction) nsFunctions.get(0); + assertEquals(f3.getElementName(), new String("boo")); + assertEquals(f3.getReturnType(), new String("void")); + checkLineNumbers((CElement)f3, 90, 92); + } + + private void checkStructs(IParent namespace){ + // struct with name + ArrayList nsStructs = namespace.getChildrenOfType(ICElement.C_STRUCT); + IStructure struct1 = (IStructure) nsStructs.get(0); + assertEquals(struct1.getElementName(), new String ("MyStruct")); + checkLineNumbers((CElement)struct1, 95, 97); + ArrayList struct1Fields = struct1.getChildrenOfType(ICElement.C_FIELD); + IField field1 = (IField) struct1Fields.get(0); + assertEquals(field1.getElementName(), new String("sint")); + assertEquals(field1.getTypeName(), new String("int")); + checkLineNumbers((CElement)field1, 96, 96); + + if(field1.getVisibility() != IMember.V_PUBLIC) + fail("field visibility should be public!"); + + // struct no name + IStructure struct2 = (IStructure) nsStructs.get(1); + assertEquals(struct2.getElementName(), new String ("")); + checkLineNumbers((CElement)struct2, 101, 103); + ArrayList struct2Fields = struct2.getChildrenOfType(ICElement.C_FIELD); + IField field2 = (IField) struct2Fields.get(0); + assertEquals(field2.getElementName(), new String("ss")); + assertEquals(field2.getTypeName(), new String("int")); + checkLineNumbers((CElement)field2, 102, 102); + if(field2.getVisibility() != IMember.V_PUBLIC) + fail("field visibility should be public!"); + + // typedefs + ArrayList nsTypeDefs = namespace.getChildrenOfType(ICElement.C_TYPEDEF); + ITypeDef td1 = (ITypeDef) nsTypeDefs.get(0); + assertEquals(td1.getElementName(), new String ("myStruct")); + assertEquals(td1.getTypeName(), new String ("struct MyStruct")); + checkLineNumbers((CElement)td1, 99, 99); + ITypeDef td2 = (ITypeDef) nsTypeDefs.get(1); + assertEquals(td2.getElementName(), new String ("myTypedef")); + assertEquals(td2.getTypeName(), new String ("")); + checkLineNumbers((CElement)td2, 101, 103); + + // union + ArrayList nsUnions = namespace.getChildrenOfType(ICElement.C_UNION); + IStructure u0 = (IStructure) nsUnions.get(0); + assertEquals(u0.getElementName(), new String("U")); + checkLineNumbers((CElement)u0, 105, 107); + ArrayList u0Fields = u0.getChildrenOfType(ICElement.C_FIELD); + IField field3 = (IField) u0Fields.get(0); + assertEquals(field3.getElementName(), new String("U1")); + assertEquals(field3.getTypeName(), new String("int")); + checkLineNumbers((CElement)field3, 106, 106); + if(field3.getVisibility() != IMember.V_PUBLIC) + fail("field visibility should be public!"); + } + + private void checkTemplates(IParent namespace){ + // template function + ArrayList functionTemplates = namespace.getChildrenOfType(ICElement.C_TEMPLATE_FUNCTION); + FunctionTemplate ft = (FunctionTemplate)functionTemplates.get(0); + assertEquals(ft.getElementName(), new String("aTemplatedFunction")); + assertEquals(ft.getTemplateSignature(), new String("aTemplatedFunction(B) : A")); + checkLineNumbers((CElement)ft, 112, 113); + + // template method + ArrayList nsClasses = namespace.getChildrenOfType(ICElement.C_CLASS); + IStructure enclosingClass = (IStructure) nsClasses.get(1); + checkLineNumbers((CElement)enclosingClass, 114, 118); + ArrayList methodTemplates = enclosingClass.getChildrenOfType(ICElement.C_TEMPLATE_METHOD); + MethodTemplate mt = (MethodTemplate)methodTemplates.get(0); + assertEquals(mt.getElementName(), new String("aTemplatedMethod")); + assertEquals(mt.getTemplateSignature(), new String("aTemplatedMethod(B) : A")); + checkLineNumbers((CElement)mt, 118, 119); + assertEquals(mt.getVisibility(), IMember.V_PUBLIC); + + // template class + ArrayList classTemplates = namespace.getChildrenOfType(ICElement.C_TEMPLATE_CLASS); + StructureTemplate ct = (StructureTemplate)classTemplates.get(0); + assertEquals(ct.getElementName(), new String("myarray")); + assertEquals(ct.getTemplateSignature(), new String("myarray")); + checkLineNumbers((CElement)ct, 122, 123); + + // template struct + ArrayList structTemplates = namespace.getChildrenOfType(ICElement.C_TEMPLATE_STRUCT); + StructureTemplate st = (StructureTemplate)structTemplates.get(0); + assertEquals(st.getElementName(), new String("mystruct")); + assertEquals(st.getTemplateSignature(), new String("mystruct")); + checkLineNumbers((CElement)st, 125, 126); + + // template variable + ArrayList variableTemplates = namespace.getChildrenOfType(ICElement.C_TEMPLATE_VARIABLE); + VariableTemplate vt = (VariableTemplate)variableTemplates.get(0); + assertEquals(vt.getElementName(), new String("default_alloc_template<__threads,__inst>::_S_start_free")); + assertEquals(vt.getTemplateSignature(), new String("default_alloc_template<__threads,__inst>::_S_start_free : char*")); + checkLineNumbers((CElement)vt, 128, 129); + } + + private void checkArrays(IParent tu){ + // array variable + ArrayList variables = tu.getChildrenOfType(ICElement.C_VARIABLE); + IVariable arrayVar = (IVariable) variables.get(0); + assertEquals(arrayVar.getElementName(), new String("myArray")); + assertEquals(arrayVar.getTypeName(), new String("int[][]")); + checkLineNumbers((CElement)arrayVar, 133, 133); + + // array parameter in function main + ArrayList functions = tu.getChildrenOfType(ICElement.C_FUNCTION); + IFunction mainFunction = (IFunction) functions.get(0); + assertEquals(mainFunction.getElementName(), new String("main")); + assertEquals(mainFunction.getReturnType(), new String("int")); + checkLineNumbers((CElement)mainFunction, 134, 136); + int NumOfParam = mainFunction.getNumberOfParameters(); + if(NumOfParam != 2) + fail("main should have two parameter!"); + String[] paramTypes = mainFunction.getParameterTypes(); + assertEquals(paramTypes[0], new String("int")); + assertEquals(paramTypes[1], new String("char*[]")); + + } + private void checkLineNumbers(CElement element, int startLine, int endLine){ +// Remove comments when testBug36379() is fixed +// assertEquals(startLine, element.getStartLine()); +// assertEquals(endLine, element.getEndLine()); + } + +} diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelExceptionTest.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelExceptionTest.java new file mode 100644 index 00000000000..19261d83846 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelExceptionTest.java @@ -0,0 +1,113 @@ +package org.eclipse.cdt.core.model.tests; + +/* + * (c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + */ + +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.ICModelStatusConstants; +import org.eclipse.cdt.internal.core.model.CModelStatus; +import org.eclipse.core.runtime.CoreException; + +/** + * + * CModelExceptionTest + * + * @author Judy N. Green + * @since Jul 19, 2002 + */ +public class CModelExceptionTest extends TestCase { + // Shared values setup and torn down + private Throwable throwableException; + private CModelStatus cModelStatus; + private CoreException coreException; + + /** + * Constructor for TestCModelException. + * @param name + */ + public CModelExceptionTest(String name) { + super(name); + } + + /** + * Sets up the test fixture. + * + * Called before every test case method. + * + * Example code test the packages in the project + * "com.qnx.tools.ide.cdt.core" + */ + protected void setUp() { + // create shared resources and setup the test fixture + cModelStatus = new CModelStatus(); + coreException = new CoreException(cModelStatus); + } + + /** + * Tears down the test fixture. + * + * Called after every test case method. + */ + protected void tearDown() { + // release resources here and clean-up + } + + public static TestSuite suite() { + return new TestSuite(CModelExceptionTest.class); + } + + public static void main (String[] args){ + junit.textui.TestRunner.run(suite()); + } + + public void testCreationNoStatus(){ + CModelException testException = new CModelException(coreException); + + // should not be null + assertTrue("TestException is null", (testException != null)); + + // should be the same object inside + assertTrue("Object compare failed", testException.getException() == coreException); + } + public void testCreationWithStatus(){ + CModelException testException = new CModelException(coreException, + ICModelStatusConstants.INDEX_OUT_OF_BOUNDS); + // should not be null + assertTrue("TestException is null", (testException != null)); + + // should not be null + assertTrue("TestException.getStatus() is null", (testException.getStatus() != null)); + + // should have the same status as was set on creation + assertTrue("Object compare failed", testException.getStatus().getCode() == ICModelStatusConstants.INDEX_OUT_OF_BOUNDS); + } + + public void testElementDoesNotExist(){ + CModelException testException = new CModelException(coreException, + ICModelStatusConstants.ELEMENT_DOES_NOT_EXIST); + // should not be null + assertTrue("TestException is null", (testException != null)); + + + // should not exist since this is the value we set on creation + assertTrue("Object unexpectedly exists", testException.doesNotExist()); + } + + public void testElementExists(){ + CModelException testException = new CModelException(coreException, + ICModelStatusConstants.INVALID_CONTENTS); + // should not be null + assertTrue("TestException is null", (testException != null)); + + + // should not exist since this is the value we set on creation + assertTrue("Object unexpectedly does not exist", testException.doesNotExist() == false); + } + + +} diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelTests.java new file mode 100644 index 00000000000..020c97ebc87 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelTests.java @@ -0,0 +1,231 @@ +package org.eclipse.cdt.core.model.tests; + +/* + * (c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + */ + + +import java.io.FileInputStream; +import java.io.FileNotFoundException; + +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.CCProjectNature; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.testplugin.CProjectHelper; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceDescription; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; + + +/** + * @author Peter Graves + * + * This file contains a set of generic tests for the core C model. Nothing + * exotic, but should be a small sanity set of tests. + * + */ +public class CModelTests extends TestCase { + IWorkspace workspace; + IWorkspaceRoot root; + IProject project_c, project_cc; + NullProgressMonitor monitor; + String pluginRoot; + + /** + * Constructor for CModelTests. + * @param name + */ + public CModelTests(String name) { + super(name); + } + + /** + * Sets up the test fixture. + * + * Called before every test case method. + * + * Example code test the packages in the project + * "com.qnx.tools.ide.cdt.core" + */ + protected void setUp() throws CoreException { + /*** + * The test of the tests assume that they have a working workspace + * and workspace root object to use to create projects/files in, + * so we need to get them setup first. + */ + IWorkspaceDescription desc; + workspace= ResourcesPlugin.getWorkspace(); + root= workspace.getRoot(); + monitor = new NullProgressMonitor(); + if (workspace==null) + fail("Workspace was not setup"); + if (root==null) + fail("Workspace root was not setup"); + pluginRoot=org.eclipse.core.runtime.Platform.getPlugin("org.eclipse.cdt.core.tests").find(new Path("/")).getFile(); + desc=workspace.getDescription(); + desc.setAutoBuilding(false); + workspace.setDescription(desc); + + } + + /** + * Tears down the test fixture. + * + * Called after every test case method. + */ + protected void tearDown() { + // release resources here and clean-up + } + + public static TestSuite suite() { + return new TestSuite(CModelTests.class); + } + + public static void main (String[] args){ + junit.textui.TestRunner.run(suite()); + } + + + /*** + * The follow are a simple set of tests to make usre the HasC/CCNature calls + * seem to be sane. + * + * Assumes that the CProjectHelper.createCProject properly creates a C + * project with a C nature, but does not add the CC nature. + * It also assums that the AddCCNature call works + * + * @see CProjectHelper#createCProject + * @see CoreModel#addCCNature + */ + public void testHasNature() throws CoreException { + ICProject testProject; + testProject=CProjectHelper.createCProject("naturetest", "none"); + if (testProject==null) + fail("Unable to create project"); + assertTrue("hasCNature works", CoreModel.getDefault().hasCNature(testProject.getProject())); + assertTrue("hasCCNature works without ccnature", !(CoreModel.getDefault().hasCCNature(testProject.getProject()))); + + + CCProjectNature.addCCNature(testProject.getProject(), monitor); + assertTrue("hasCCNature works", (CoreModel.getDefault().hasCCNature(testProject.getProject()))); + + CCProjectNature.removeCCNature(testProject.getProject(), monitor); + CCProjectNature.removeCNature(testProject.getProject(), monitor); + assertTrue("hasCNature works without cnature", !CoreModel.getDefault().hasCNature(testProject.getProject())); + assertTrue("hasCCNature works without ccnature or cnature", !(CoreModel.getDefault().hasCCNature(testProject.getProject()))); + + } + + /*** + * Simple tests to make sure the models file identification methods seem + * to work as expected. + */ + public void testFileType() throws CoreException,FileNotFoundException { + ICProject testProject; + testProject=CProjectHelper.createCProject("filetest", "none"); + if (testProject==null) + fail("Unable to create project"); + + IFile file = testProject.getProject().getFile("exetest_g"); + if (!file.exists()) { + file.create(new FileInputStream(pluginRoot+"resources/exe/x86/o.g/exe_g"),false, monitor); + + } + /*** + * file should be a binary, executable, not shared or archive + */ + assertTrue("isBinary", CoreModel.getDefault().isBinary(file)); + assertTrue("isExecutable", CoreModel.getDefault().isExecutable(file)); + assertTrue("isSharedLib", !CoreModel.getDefault().isSharedLib(file)); + assertTrue("isArchive", !CoreModel.getDefault().isArchive(file)); + assertTrue("isObject", !CoreModel.getDefault().isObject(file)); + assertTrue("isTranslationUnit", !CoreModel.getDefault().isTranslationUnit(file)); + + + file = testProject.getProject().getFile("exetest.c"); + if (!file.exists()) { + file.create(new FileInputStream(pluginRoot+"resources/exe/main.c"),false, monitor); + + } + /*** + * file should be a translation unit + */ + assertTrue("isBinary", !CoreModel.getDefault().isBinary(file)); + assertTrue("isExecutable", !CoreModel.getDefault().isExecutable(file)); + assertTrue("isSharedLib", !CoreModel.getDefault().isSharedLib(file)); + assertTrue("isArchive", !CoreModel.getDefault().isArchive(file)); + assertTrue("isObject", !CoreModel.getDefault().isObject(file)); + assertTrue("isTranslationUnit", CoreModel.getDefault().isTranslationUnit(file)); + + file = testProject.getProject().getFile("exetest.o"); + if (!file.exists()) { + file.create(new FileInputStream(pluginRoot+"resources/exe/x86/o.g/main.o"),false, monitor); + + } + /*** + * file should be a object file unit + */ + assertTrue("isBinary", CoreModel.getDefault().isBinary(file)); + assertTrue("isExecutable", !CoreModel.getDefault().isExecutable(file)); + assertTrue("isSharedLib", !CoreModel.getDefault().isSharedLib(file)); + assertTrue("isArchive", !CoreModel.getDefault().isArchive(file)); + assertTrue("isObject", CoreModel.getDefault().isObject(file)); + assertTrue("isTranslationUnit", !CoreModel.getDefault().isTranslationUnit(file)); + + file = testProject.getProject().getFile("liblibtest_g.so"); + if (!file.exists()) { + file.create(new FileInputStream(pluginRoot+"resources/testlib/x86/so.g/libtestlib_g.so"),false, monitor); + + } + /*** + * file should be a sharedlib/binary file + */ + assertTrue("isBinary", CoreModel.getDefault().isBinary(file)); + assertTrue("isExecutable", !CoreModel.getDefault().isExecutable(file)); + assertTrue("isSharedLib", CoreModel.getDefault().isSharedLib(file)); + assertTrue("isArchive", !CoreModel.getDefault().isArchive(file)); + assertTrue("isObject", !CoreModel.getDefault().isObject(file)); + assertTrue("isTranslationUnit", !CoreModel.getDefault().isTranslationUnit(file)); + + file = testProject.getProject().getFile("liblibtest_g.a"); + if (!file.exists()) { + file.create(new FileInputStream(pluginRoot+"resources/testlib/x86/a.g/libtestlib_g.a"),false, monitor); + + } else { + fail("Does not exist?"); + } + /*** + * file should be a archive file + */ + assertTrue("isArchive", CoreModel.getDefault().isArchive(file)); + assertTrue("isBinary:", !CoreModel.getDefault().isBinary(file)); + assertTrue("isExecutable", !CoreModel.getDefault().isExecutable(file)); + assertTrue("isSharedLib", !CoreModel.getDefault().isSharedLib(file)); + assertTrue("isArchive", CoreModel.getDefault().isArchive(file)); + assertTrue("isObject", !CoreModel.getDefault().isObject(file)); + assertTrue("isTranslationUnit", !CoreModel.getDefault().isTranslationUnit(file)); + + + testProject.getProject().delete(true,true,monitor); + } + + /**** + * Some simple tests for isValidTranslationUnitName + */ + public void testIsValidTranslationUnitName() throws CoreException { + assertTrue("Invalid C file", !CoreModel.getDefault().isValidTranslationUnitName("notcfile")); + assertTrue("Invalid C file", !CoreModel.getDefault().isValidTranslationUnitName("not.c.file")); + assertTrue("Invalid C file", !CoreModel.getDefault().isValidTranslationUnitName("not.ca")); + assertTrue("Valid C file", CoreModel.getDefault().isValidTranslationUnitName("areal.c")); + } +} diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ElementDeltaTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ElementDeltaTests.java new file mode 100644 index 00000000000..a2260aa5657 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/ElementDeltaTests.java @@ -0,0 +1,286 @@ +package org.eclipse.cdt.core.model.tests; + + +/********************************************************************** + * Copyright (c) 2002,2003 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * Rational Software - Initial API and implementation +***********************************************************************/ + +import java.io.FileInputStream; +import java.util.Iterator; +import java.util.Vector; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.CCProjectNature; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.ElementChangedEvent; +import org.eclipse.cdt.core.model.IBuffer; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICElementDelta; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.IElementChangedListener; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.internal.core.model.CModelManager; +import org.eclipse.cdt.internal.core.model.IWorkingCopy; +import org.eclipse.cdt.internal.core.model.TranslationUnit; +import org.eclipse.cdt.testplugin.CProjectHelper; +import org.eclipse.cdt.testplugin.TestPluginLauncher; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; + +/** + * Class for testing the C Element Delta Builder. + */ +public class ElementDeltaTests extends TestCase implements IElementChangedListener { + private ICProject fCProject; + private IFile headerFile; + private NullProgressMonitor monitor; + private Vector addedElements; + private Vector removedElements; + private Vector changedElements; + + public static void main(String[] args) { + TestPluginLauncher.run(TestPluginLauncher.getLocationFromProperties(), WorkingCopyTests.class, args); + } + + public static Test suite() { + TestSuite suite= new TestSuite(ElementDeltaTests.class.getName()); + suite.addTest(new ElementDeltaTests("testElementDeltas")); + return suite; + } + + public ElementDeltaTests(String name) { + super(name); + } + + protected void setUp() throws Exception { + monitor = new NullProgressMonitor(); + String pluginRoot=org.eclipse.core.runtime.Platform.getPlugin("org.eclipse.cdt.core.tests").find(new Path("/")).getFile(); + + fCProject= CProjectHelper.createCProject("TestProject1", "bin"); + //Path filePath = new Path(ResourcesPlugin.getWorkspace().getRoot().getLocation().toString()+ fCProject.getPath().toString()+ "/WorkingCopyTest.h"); + headerFile = fCProject.getProject().getFile("WorkingCopyTest.h"); + if (!headerFile.exists()) { + try{ + FileInputStream fileIn = new FileInputStream(pluginRoot+ "resources/cfiles/WorkingCopyTestStart.h"); + headerFile.create(fileIn,false, monitor); + } catch (CoreException e) { + e.printStackTrace(); + } + } + if (!fCProject.getProject().hasNature(CCProjectNature.CC_NATURE_ID)) { + addNatureToProject(fCProject.getProject(), CCProjectNature.CC_NATURE_ID, null); + } + + // register with the model manager to listen to delta changes + CModelManager.getDefault().addElementChangedListener(this); + addedElements = new Vector(10); + removedElements = new Vector(10); + changedElements = new Vector(20); + CCorePlugin.getDefault().setUseNewParser(true); + } + private static void addNatureToProject(IProject proj, String natureId, IProgressMonitor monitor) throws CoreException { + IProjectDescription description = proj.getDescription(); + String[] prevNatures= description.getNatureIds(); + String[] newNatures= new String[prevNatures.length + 1]; + System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length); + newNatures[prevNatures.length]= natureId; + description.setNatureIds(newNatures); + proj.setDescription(description, monitor); + } + + protected void tearDown() throws Exception { + CProjectHelper.delete(fCProject); + } + + + public void testElementDeltas() throws Exception { + ITranslationUnit tu = new TranslationUnit(fCProject, headerFile); + assertNotNull (tu); + IWorkingCopy wc = tu.getWorkingCopy(); + assertNotNull (wc); + assertNotNull (wc.getBuffer()); + assertTrue (wc.exists()); + + // add the class Hello + IBuffer wcBuf = wc.getBuffer(); + wcBuf.setContents ("\n class Hello{ \n};"); + wc.reconcile(); + wc.commit(true, monitor); + assertChangedElement(ICElement.C_MODEL, ""); + assertChangedElement(ICElement.C_PROJECT, "TestProject1"); + assertChangedElement(ICElement.C_UNIT, "WorkingCopyTest.h"); + assertAddedElement(ICElement.C_CLASS, "Hello"); + assertRemovedElement(ICElement.C_INCLUDE, "stdio.h"); + assertEmptyDelta(); + + // add the field x + wcBuf.setContents ("\n class Hello{\n int x; \n};"); + wc.reconcile(); + wc.commit(true, monitor); + assertChangedElement(ICElement.C_MODEL, ""); + assertChangedElement(ICElement.C_PROJECT, "TestProject1"); + assertChangedElement(ICElement.C_UNIT, "WorkingCopyTest.h"); + assertChangedElement(ICElement.C_CLASS, "Hello"); + assertAddedElement(ICElement.C_FIELD, "x"); + assertEmptyDelta(); + + // add the method setValue + wcBuf.setContents ("\n class Hello{\n int x; \n void setValue(int val); \n};"); + wc.reconcile(); + wc.commit(true, monitor); + assertChangedElement(ICElement.C_MODEL, ""); + assertChangedElement(ICElement.C_PROJECT, "TestProject1"); + assertChangedElement(ICElement.C_UNIT, "WorkingCopyTest.h"); + assertChangedElement(ICElement.C_CLASS, "Hello"); + assertAddedElement(ICElement.C_METHOD_DECLARATION, "setValue"); + assertEmptyDelta(); + + // rename x to y + // this is not a change, this is add and remove + wcBuf.setContents ("\n class Hello{\n int y; \n void setValue(int val); \n};"); + wc.reconcile(); + wc.commit(true, monitor); + assertChangedElement(ICElement.C_MODEL, ""); + assertChangedElement(ICElement.C_PROJECT, "TestProject1"); + assertChangedElement(ICElement.C_UNIT, "WorkingCopyTest.h"); + assertChangedElement(ICElement.C_CLASS, "Hello"); + assertAddedElement(ICElement.C_FIELD, "y"); + assertRemovedElement(ICElement.C_FIELD, "x"); + assertEmptyDelta(); + + // remove the method + wcBuf.setContents ("\n class Hello{\n String y; \n};"); + wc.reconcile(); + wc.commit(true, monitor); + assertChangedElement(ICElement.C_MODEL, ""); + assertChangedElement(ICElement.C_PROJECT, "TestProject1"); + assertChangedElement(ICElement.C_UNIT, "WorkingCopyTest.h"); + assertChangedElement(ICElement.C_CLASS, "Hello"); + assertChangedElement(ICElement.C_FIELD, "y"); + assertRemovedElement(ICElement.C_METHOD_DECLARATION, "setValue"); + assertEmptyDelta(); + + // remove the field + wcBuf.setContents ("\n class Hello{ \n};"); + wc.reconcile(); + wc.commit(true, monitor); + assertChangedElement(ICElement.C_MODEL, ""); + assertChangedElement(ICElement.C_PROJECT, "TestProject1"); + assertChangedElement(ICElement.C_UNIT, "WorkingCopyTest.h"); + assertChangedElement(ICElement.C_CLASS, "Hello"); + assertRemovedElement(ICElement.C_FIELD, "y"); + assertEmptyDelta(); + + // remove the class + wcBuf.setContents (""); + wc.reconcile(); + wc.commit(true, monitor); + assertChangedElement(ICElement.C_MODEL, ""); + assertChangedElement(ICElement.C_PROJECT, "TestProject1"); + assertChangedElement(ICElement.C_UNIT, "WorkingCopyTest.h"); + assertRemovedElement(ICElement.C_CLASS, "Hello"); + assertEmptyDelta(); + + wc.destroy(); + assertFalse(wc.exists()); + } + + public void assertAddedElement(int elementType, String elementName){ + if(!isElementInList(elementType, elementName, addedElements)) + fail("Element NOT found in Added list"); + } + public void assertRemovedElement(int elementType, String elementName){ + if(!isElementInList(elementType, elementName, removedElements)) + fail("Element NOT found in Removed list"); + } + public void assertChangedElement(int elementType, String elementName){ + if(!isElementInList(elementType, elementName, changedElements)) + fail("Element NOT found in Changed list"); + } + public void assertEmptyDelta() { + assertTrue(addedElements.isEmpty()); + assertTrue(removedElements.isEmpty()); + assertTrue(changedElements.isEmpty()); + } + public boolean isElementInList(int elementType, String elementName, Vector elementList) { + boolean found = false; + Iterator i = elementList.iterator(); + while( i.hasNext()){ + ICElement element = (ICElement)i.next(); + + if ((element.getElementName().equals(elementName)) && + (element.getElementType() == elementType)){ + // return true; + // just to print the whole list + found = true; + // Remove the element + elementList.remove(element); + break; + } + } + //return false; + return found; + } + + public void elementChanged(ElementChangedEvent event){ + try { + addedElements.clear(); + removedElements.clear(); + changedElements.clear(); + + processDelta(event.getDelta()); + } catch(CModelException e) { + } + } + + protected void processDelta(ICElementDelta delta) throws CModelException { + // check the delta elements + int kind= delta.getKind(); + int flags= delta.getFlags(); + ICElement element= delta.getElement(); + + // handle open and closing of a solution or project + if ((flags & ICElementDelta.F_CLOSED) != 0) { + } + if ((flags & ICElementDelta.F_OPENED) != 0) { + } + if (kind == ICElementDelta.REMOVED) { + removedElements.add(element); + } + if (kind == ICElementDelta.ADDED) { + addedElements.add(element); + } + if (kind == ICElementDelta.CHANGED) { + changedElements.add(element); + + if (flags == ICElementDelta.F_MODIFIERS) { + } + if (flags == ICElementDelta.F_CONTENT) { + } + if (flags == ICElementDelta.F_CHILDREN) { + } + } + + ICElementDelta[] affectedChildren= delta.getAffectedChildren(); + for (int i= 0; i < affectedChildren.length; i++) { + processDelta(affectedChildren[i]); + } + } + +} diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/FlagTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/FlagTests.java new file mode 100644 index 00000000000..9da06490c36 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/FlagTests.java @@ -0,0 +1,212 @@ +package org.eclipse.cdt.core.model.tests; + +/* + * (c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + */ + + + +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.model.Flags; +import org.eclipse.cdt.internal.core.model.IConstants; + +/** + * @author Peter Graves + * + * This is a very simple set of sanity tests for the flags class to make sure + * there are no very silly problems in the class. It also verifies that there + * is no overlap in the IConstants. + */ +public class FlagTests extends TestCase { + + int flags[]; + /** + * Constructor for FlagTests. + * @param name + */ + public FlagTests(String name) { + super(name); + } + /** + * Sets up the test fixture. + * + * Called before every test case method. + * + * Example code test the packages in the project + * "com.qnx.tools.ide.cdt.core" + */ + protected void setUp() { + flags=new int[15]; + flags[0]=IConstants.AccPublic; + flags[1]=IConstants.AccPrivate; + flags[2]=IConstants.AccProtected; + flags[3]=IConstants.AccStatic; + flags[4]=IConstants.AccExtern; + flags[5]=IConstants.AccInline; + flags[6]=IConstants.AccVolatile; + flags[7]=IConstants.AccRegister; + flags[8]=IConstants.AccExplicit; + flags[9]=IConstants.AccExport; + flags[10]=IConstants.AccAbstract; + flags[11]=IConstants.AccMutable; + flags[12]=IConstants.AccAuto; + flags[13]=IConstants.AccVirtual; + flags[14]=IConstants.AccTypename; + + } + + /** + * Tears down the test fixture. + * + * Called after every test case method. + */ + protected void tearDown() { + // release resources here and clean-up + } + + public static TestSuite suite() { + return new TestSuite(FlagTests.class); + } + + public static void main (String[] args){ + junit.textui.TestRunner.run(suite()); + } + + public void testIsStatic() + { + int x; + assertTrue("isStatic with a static", Flags.isStatic(IConstants.AccStatic)); + for (x=0;xPreferences>Java>Code Generation>Code and Comments + */ +public abstract class AutomatedFramework extends TestCase { + + public AutomatedFramework() { + super(); + } + + public AutomatedFramework(String name) { + super(name); + } + + protected abstract AutomatedFramework newTest( String name ); + protected abstract void loadProperties() throws Exception; + public abstract void doFile() throws Throwable; + + private void fillSuite( TestSuite suite, File path ){ + File files[] = null; + if( path.isFile() ){ + files = new File[ 1 ]; + files[0] = path; + } + else + files = path.listFiles(); + + File file = null; + String filePath = null; + int i = 0; + try{ + file = files[ i++ ]; + while( file != null ) + { + if( file.isDirectory() ) + fillSuite( suite, file ); + else if( file.isFile() && nameFilter.accept( file.getParentFile(), file.getName() ) ){ + try{ + filePath = file.getCanonicalPath(); + } catch ( Exception e ){ + continue; + } + + if( filePath.endsWith(".cpp") || filePath.endsWith(".hpp") || + filePath.endsWith(".cc") || filePath.endsWith(".CC") || + filePath.endsWith(".C") || + filePath.endsWith(".hxx") || filePath.endsWith(".hh") ) + { + AutomatedTest.natures.put( filePath, "cpp" ); + } else if( filePath.endsWith(".c") ){ + AutomatedTest.natures.put( filePath, "c" ); + } else { + AutomatedTest.natures.put( filePath, AutomatedTest.defaultNature ); + } + + AutomatedTest.fileList.add( file ); + suite.addTest( newTest( file.getName().replace(',', '_') ) ); + } + file = files[ i++ ]; + } + } catch( ArrayIndexOutOfBoundsException e ){ + //done + } + } + + public void reportFailed() { + fail( "Unable to open " + outputFile + "for output of results." ); + } + + public void propertiesFailed() { + fail( "Unable to load properties file." ); + } + + protected void runTest() throws Throwable { + String name = getName(); + + if( name.equals("propertiesFailed") ) + propertiesFailed(); + else if ( name.equals("reportFailed") ) + reportFailed(); + else + doFile(); + } + + public Test createSuite() { + TestSuite suite = new TestSuite(); + + try{ + loadProperties(); + } catch( Exception e ){ + suite.addTest( newTest( "propertiesFailed") ); + } + + if( outputFile != null && !outputFile.equals("") ){ + try{ + + File output = new File( outputFile ); + + if( output.exists() ){ + output.delete(); + } + + output.createNewFile(); + + report = new FileOutputStream( output ); + + } catch( Exception e ) { + suite.addTest( newTest( "reportFailed" ) ); + } + } + + Set keys = testSources.keySet(); + Iterator iter = keys.iterator(); + int size = keys.size(); + String item = null; + for( int i = size; i > 0; i-- ) + { + item = (String) iter.next(); + File file = new File( item ); + if( file.exists() ){ + defaultNature = (String) testSources.get( item ); + fillSuite( suite, file ); + } + } + + return suite; + } + + protected static IParserCallback nullCallback = new NullSourceElementRequestor(); + protected static Properties properties = new Properties(); + protected static String defaultNature; + protected static String outputFile = null; + protected static HashMap testSources = new HashMap(); + protected static HashMap natures = new HashMap(); + protected static LinkedList fileList = new LinkedList(); + private static FilenameFilter nameFilter = new Filter(); + protected static FileOutputStream report = null; + + static private class Filter implements FilenameFilter + { + public boolean accept(File dir, String name) { + if( name.endsWith(".cpp") || + name.endsWith(".c") || + name.endsWith(".cc") || + name.endsWith(".CC") || + name.endsWith(".C") || + name.endsWith(".h") || + name.endsWith(".hh") || + name.endsWith(".hpp") || + name.endsWith(".hxx")) + { + return true; + } + else + return false; + } + } + +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/AutomatedTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/AutomatedTest.java new file mode 100644 index 00000000000..40133029907 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/AutomatedTest.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * Copyright (c) 2001 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Corp. - Rational Software - initial implementation + ******************************************************************************/ + +package org.eclipse.cdt.core.parser.tests; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.NoSuchElementException; +import java.util.StringTokenizer; + +import junit.framework.AssertionFailedError; +import junit.framework.Test; + +import org.eclipse.cdt.core.parser.IParser; +import org.eclipse.cdt.internal.core.parser.Parser; +import org.eclipse.core.runtime.Path; + + + +/** + * @author aniefer + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public class AutomatedTest extends AutomatedFramework { + + public AutomatedTest() { + } + public AutomatedTest(String name){ + super(name); + } + + public void doFile() throws Throwable { + assertNotNull( fileList ); + + File file = null; + IParser parser = null; + + try{ + file = (File)fileList.removeFirst(); + FileInputStream stream = new FileInputStream( file ); + + String filePath = file.getCanonicalPath(); + String nature = (String)natures.get( filePath ); + + boolean cppNature = nature.equalsIgnoreCase("cpp"); + + parser = new Parser( stream, nullCallback, true); + parser.setCppNature( cppNature ); + parser.mapLineNumbers(true); + + assertTrue( parser.parse() ); + } + catch( Throwable e ) + { + String output = null; + if( e instanceof AssertionFailedError ){ + output = file.getCanonicalPath() + ": Parse failed on line "; + output += parser.getLineNumberForOffset(parser.getLastErrorOffset()) + "\n"; + } else { + output = file.getCanonicalPath() + ": " + e.getClass().toString(); + output += " on line " + parser.getLineNumberForOffset(parser.getLastErrorOffset()) + "\n"; + } + if( report != null ){ + report.write( output.getBytes() ); + } + + fail( output ); + } + } + + protected AutomatedFramework newTest( String name ){ + return new AutomatedTest( name ); + } + + public static Test suite() + { + AutomatedFramework frame = new AutomatedTest(); + + return frame.createSuite(); + } + + protected void tearDown () throws Exception { + if( fileList != null && fileList.size() == 0 && report != null ){ + report.flush(); + report.close(); + } + } + + protected void loadProperties() throws Exception{ + String resourcePath = org.eclipse.core.runtime.Platform.getPlugin("org.eclipse.cdt.core.tests").find(new Path("/")).getFile(); + resourcePath += "resources/parser/AutomatedTest"; + + try{ + FileInputStream propertiesIn = new FileInputStream( resourcePath + "/AutomatedTest.properties"); + properties.load( propertiesIn ); + + outputFile = properties.getProperty( "outputFile", "" ); + String sourceInfo = properties.getProperty( "source", "" ); + if( sourceInfo.equals("") ) + throw new FileNotFoundException(); + else{ + StringTokenizer tokenizer = new StringTokenizer( sourceInfo, "," ); + String str = null, val = null; + try{ + while( tokenizer.hasMoreTokens() ){ + str = tokenizer.nextToken().trim(); + val = tokenizer.nextToken().trim(); + + testSources.put( str, val ); + } + } catch ( NoSuchElementException e ){ + //only way to get here is to have a missing val, assume cpp for that str + testSources.put( str, "cpp" ); + } + + } + } catch ( FileNotFoundException e ){ + testSources.put( resourcePath + "/defaultCpp", "cpp" ); + testSources.put( resourcePath + "/defaultC", "c" ); + } + } + +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/BaseDOMTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/BaseDOMTest.java new file mode 100644 index 00000000000..715e37106da --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/BaseDOMTest.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2001 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Corp. - Rational Software - initial implementation + ******************************************************************************/ +package org.eclipse.cdt.core.parser.tests; + +import junit.framework.TestCase; + +import org.eclipse.cdt.core.parser.IParser; +import org.eclipse.cdt.internal.core.dom.DOMBuilder; +import org.eclipse.cdt.internal.core.dom.TranslationUnit; +import org.eclipse.cdt.internal.core.parser.Parser; +import org.eclipse.cdt.internal.core.parser.ParserException; + +/** + * @author jcamelon + * + */ +public class BaseDOMTest extends TestCase { + + public BaseDOMTest( String arg ) + { + super( arg ); + } + + public TranslationUnit parse( String code ) throws Exception + { + return parse( code, true, true ); + } + + public TranslationUnit parse(String code, boolean quickParse, boolean throwOnError ) throws Exception { + DOMBuilder domBuilder = new DOMBuilder(); + IParser parser = new Parser(code, domBuilder, quickParse ); + if( ! parser.parse() ) + if( throwOnError ) throw new ParserException( "Parse failure" ); + else domBuilder.getTranslationUnit().setParseSuccessful( false ); + + return domBuilder.getTranslationUnit(); + } + + public void failTest(String code) { + boolean testPassed = false; + try { + TranslationUnit tu = parse(code); + testPassed = true; + fail( "We should not reach this point"); + } catch (Throwable e) { + if (!(e instanceof ParserException)) + fail("Unexpected Error: " + e.getMessage()); + } + if (testPassed) + fail("The expected error did not occur."); + } + +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/BaseScannerTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/BaseScannerTest.java new file mode 100644 index 00000000000..954d2c208a2 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/BaseScannerTest.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * Copyright (c) 2001 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Corp. - Rational Software - initial implementation + ******************************************************************************/ + +package org.eclipse.cdt.core.parser.tests; + +import java.io.StringReader; + +import junit.framework.TestCase; + +import org.eclipse.cdt.core.parser.IToken; +import org.eclipse.cdt.core.parser.ScannerException; +import org.eclipse.cdt.internal.core.parser.Parser; +import org.eclipse.cdt.internal.core.parser.Scanner; + +/** + * @author jcamelon + * + */ +public class BaseScannerTest extends TestCase { + + protected Scanner scanner; + + public BaseScannerTest( String x ) + { + super(x); + } + + public void initializeScanner(String input) + { + scanner= new Scanner(); + scanner.initialize( new StringReader(input),"TEXT"); + } + + public int fullyTokenize() throws Exception + { + try + { + IToken t= scanner.nextToken(); + while (t != null) + { + if (verbose) + System.out.println("Token t = " + t); + + if ((t.getType()> IToken.tLAST)) + System.out.println("Unknown type for token " + t); + t= scanner.nextToken(); + } + } + catch (Parser.EndOfFile e) + { + } + catch (ScannerException se) + { + throw se; + } + return scanner.getCount(); + } + public void validateIdentifier(String expectedImage) throws ScannerException + { + try { + IToken t= scanner.nextToken(); + assertTrue(t.getType() == IToken.tIDENTIFIER); + assertTrue(t.getImage().equals(expectedImage)); + } catch (Parser.EndOfFile e) { + assertTrue(false); + } + } + + public void validateInteger(String expectedImage) throws ScannerException + { + try { + IToken t= scanner.nextToken(); + assertTrue(t.getType() == IToken.tINTEGER); + assertTrue(t.getImage().equals(expectedImage)); + } catch (Parser.EndOfFile e) { + assertTrue(false); + } + } + + public void validateFloatingPointLiteral(String expectedImage) throws ScannerException + { + try { + IToken t= scanner.nextToken(); + assertTrue(t.getType() == IToken.tFLOATINGPT); + assertTrue(t.getImage().equals(expectedImage)); + } catch (Parser.EndOfFile e) { + assertTrue(false); + } + } + + public void validateChar( char expected )throws ScannerException + { + try { + IToken t= scanner.nextToken(); + assertTrue(t.getType() == IToken.tCHAR ); + Character c = new Character( expected ); + assertEquals( t.getImage(), c.toString() ); + } catch (Parser.EndOfFile e) { + assertTrue(false); + } + } + public void validateChar( String expected ) throws ScannerException + { + try { + IToken t= scanner.nextToken(); + assertTrue(t.getType() == IToken.tCHAR ); + assertEquals( t.getImage(), expected ); + } catch (Parser.EndOfFile e) { + assertTrue(false); + } + } + + public void validateString( String expectedImage ) throws ScannerException + { + validateString( expectedImage, false ); + } + + public void validateString(String expectedImage, boolean lString ) throws ScannerException + { + try { + IToken t= scanner.nextToken(); + if( lString ) + assertTrue(t.getType() == IToken.tLSTRING); + else + assertTrue(t.getType() == IToken.tSTRING); + assertTrue(t.getImage().equals(expectedImage)); + } catch (Parser.EndOfFile e) { + assertTrue(false); + } + } + + public void validateToken(int tokenType) throws ScannerException + { + try { + IToken t= scanner.nextToken(); + assertTrue(t.getType() == tokenType); + } catch (Parser.EndOfFile e) { + assertTrue(false); + } + } + + public void validateBalance(int expected) + { + assertTrue(scanner.getDepth() == expected); + } + + public void validateBalance() + { + assertTrue(scanner.getDepth() == 0); + } + + public void validateEOF() throws ScannerException + { + try { + assertNull(scanner.nextToken()); + } catch (Parser.EndOfFile e) { + } + } + + public void validateDefinition(String name, String value) + { + String definition= null; + definition= (String) scanner.getDefinition(name); + assertNotNull(definition); + assertTrue(definition.trim().equals(value)); + } + + public void validateDefinition(String name, int value) + { + String definition= null; + definition= (String) scanner.getDefinition(name); + assertNotNull(definition); + int intValue= (Integer.valueOf((String) definition)).intValue(); + assertEquals(value, intValue); + } + + public void validateAsUndefined(String name) + { + assertNull(scanner.getDefinition(name)); + } + + public static final String EXCEPTION_THROWN = "Exception thrown "; + + public static final String EXPECTED_FAILURE = "This statement should not be reached " + + "as we sent in bad preprocessor input to the scanner"; + + public static final boolean verbose = false; + + +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/BranchTrackerTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/BranchTrackerTest.java new file mode 100644 index 00000000000..3e1380052bd --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/BranchTrackerTest.java @@ -0,0 +1,200 @@ +package org.eclipse.cdt.core.parser.tests; + +import junit.framework.TestCase; + +import org.eclipse.cdt.core.parser.ScannerException; +import org.eclipse.cdt.internal.core.parser.BranchTracker; + +/** + * @author jcamelon + * + * To change this generated comment edit the template variable "typecomment": + * Window>Preferences>Java>Templates. + * To enable and disable the creation of type comments go to + * Window>Preferences>Java>Code Generation. + */ +public class BranchTrackerTest extends TestCase { + + public BranchTrackerTest( String ignoreMe ) + { + super( ignoreMe ); + } + + public static void assertFalse( boolean input ) + { + assertTrue( input == false ); + } + + public void testIgnore() + { + + BranchTracker bt = new BranchTracker(); + try + { + /* + * #if 0 + * # if 1 + * # elif 1 + * # else + * # endif + * #else + * #endif + */ + + assertFalse( bt.poundif( false ) ); + assertFalse( bt.poundif( true ) ); + assertFalse( bt.poundelif( true ) ); + assertFalse( bt.poundelse() ); + assertFalse( bt.poundendif() ); + assertTrue( bt.poundelse() ); + assertTrue( bt.poundendif() ); + + /* + * #if 0 + * # if 1 + * # elif 1 + * # else + * # endif + * #else + * # if 0 + * # elif 1 + * # elif 0 + * # elif 1 + * # else + * # endif + * #endif + */ + + bt = new BranchTracker(); + assertFalse( bt.poundif( false ) ); + assertFalse( bt.poundif( true )); + assertFalse( bt.poundelif( true ) ); + assertFalse( bt.poundelse() ); + assertFalse( bt.poundendif() ); + assertTrue( bt.poundelse() ); + assertFalse( bt.poundif( false ) ); + assertTrue( bt.poundelif( true ) ); + assertFalse( bt.poundelif( false ) ); + assertFalse( bt.poundelif( true ) ); + assertFalse( bt.poundelse() ); + assertTrue( bt.poundendif() ); + assertTrue( bt.poundendif() ); + assertEquals( 0, bt.getDepth() ); + + /* + * #if 0 + * # if 1 + * # elif 0 + * # elif 1 + * # else + * # endif + * #elif 0 + * # if 0 + * # elif 0 + * # elif 1 + * # else + * # endif + * #elif 1 + * # if 0 + * # elif 0 + * # elif 0 + * # else + * # endif + * #else + * # if 1 + * # elif 0 + * # elif 1 + * # else + * # endif + * #endif + */ + + assertFalse(bt.poundif(false)); + assertFalse(bt.poundif(true)); + assertFalse(bt.poundelif(false)); + assertFalse(bt.poundelif(true)); + assertFalse(bt.poundelse()); + assertFalse( bt.poundendif() ); + assertFalse(bt.poundelif(false)); + assertFalse(bt.poundif(false)); + assertFalse(bt.poundelif(false)); + assertFalse(bt.poundelif(true)); + assertFalse(bt.poundelse()); + assertFalse( bt.poundendif()); + assertTrue(bt.poundelif(true)); + assertFalse(bt.poundif(false)); + assertFalse(bt.poundelif(false)); + assertFalse(bt.poundelif(false)); + assertTrue(bt.poundelse()); + assertTrue( bt.poundendif() ); + assertFalse(bt.poundelse()); + assertFalse(bt.poundif(true)); + assertFalse(bt.poundelif(false)); + assertFalse(bt.poundelif(true)); + assertFalse(bt.poundelse()); + assertFalse( bt.poundendif() ); + assertTrue( bt.poundendif() ); + assertEquals(0, bt.getDepth()); + } catch (ScannerException se) { + fail("Unexpected Scanner exception thrown"); + } + } + + public void testSimpleBranches() + { + try + { + /* + * code sequence is + * #if 1 + * #else + * #endif + */ + BranchTracker bt = new BranchTracker(); + assertTrue( bt.poundif( true ) ); + assertFalse( bt.poundelse() ); + assertTrue( bt.poundendif() ); + + /* + * code sequence is + * #if 1 + * # if 0 + * # elif 0 + * # else + * # endif + * #else + * #endif + */ + bt = new BranchTracker(); + assertTrue( bt.poundif( true )); + assertFalse( bt.poundif( false )); + assertFalse( bt.poundelif( false )); + assertTrue( bt.poundelse()); + assertTrue( bt.poundendif() ); + assertFalse( bt.poundelse() ); + assertTrue( bt.poundendif() ); + + /* + * #if 1 + * #elsif 1 + * #elsif 0 + * #else + * #endif + */ + + bt = new BranchTracker(); + assertTrue( bt.poundif( true ) ); + assertFalse( bt.poundelif( true )); + assertFalse( bt.poundelif( false )); + assertFalse( bt.poundelse()); + assertTrue( bt.poundendif() ); + + + } + catch( ScannerException se ) + { + fail( "Exception" ); + } + } + +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/DOMTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/DOMTests.java new file mode 100644 index 00000000000..a7a0b77fd73 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/DOMTests.java @@ -0,0 +1,2162 @@ +package org.eclipse.cdt.core.parser.tests; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.cdt.core.parser.IToken; +import org.eclipse.cdt.internal.core.dom.ASMDefinition; +import org.eclipse.cdt.internal.core.dom.AccessSpecifier; +import org.eclipse.cdt.internal.core.dom.ArrayQualifier; +import org.eclipse.cdt.internal.core.dom.BaseSpecifier; +import org.eclipse.cdt.internal.core.dom.ClassKey; +import org.eclipse.cdt.internal.core.dom.ClassSpecifier; +import org.eclipse.cdt.internal.core.dom.ConstructorChain; +import org.eclipse.cdt.internal.core.dom.ConstructorChainElement; +import org.eclipse.cdt.internal.core.dom.ConstructorChainElementExpression; +import org.eclipse.cdt.internal.core.dom.DeclSpecifier; +import org.eclipse.cdt.internal.core.dom.Declaration; +import org.eclipse.cdt.internal.core.dom.Declarator; +import org.eclipse.cdt.internal.core.dom.ElaboratedTypeSpecifier; +import org.eclipse.cdt.internal.core.dom.EnumerationSpecifier; +import org.eclipse.cdt.internal.core.dom.EnumeratorDefinition; +import org.eclipse.cdt.internal.core.dom.ExceptionSpecifier; +import org.eclipse.cdt.internal.core.dom.ExplicitTemplateDeclaration; +import org.eclipse.cdt.internal.core.dom.Expression; +import org.eclipse.cdt.internal.core.dom.Inclusion; +import org.eclipse.cdt.internal.core.dom.LinkageSpecification; +import org.eclipse.cdt.internal.core.dom.Macro; +import org.eclipse.cdt.internal.core.dom.NamespaceDefinition; +import org.eclipse.cdt.internal.core.dom.ParameterDeclaration; +import org.eclipse.cdt.internal.core.dom.ParameterDeclarationClause; +import org.eclipse.cdt.internal.core.dom.PointerOperator; +import org.eclipse.cdt.internal.core.dom.SimpleDeclaration; +import org.eclipse.cdt.internal.core.dom.TemplateDeclaration; +import org.eclipse.cdt.internal.core.dom.TemplateParameter; +import org.eclipse.cdt.internal.core.dom.TemplateParameterList; +import org.eclipse.cdt.internal.core.dom.TranslationUnit; +import org.eclipse.cdt.internal.core.dom.UsingDeclaration; +import org.eclipse.cdt.internal.core.dom.UsingDirective; +import org.eclipse.cdt.internal.core.parser.Name; +import org.eclipse.cdt.internal.core.parser.ParserException; +import org.eclipse.cdt.internal.core.parser.Token; + +public class DOMTests extends BaseDOMTest { + + public DOMTests( String arg ) + { + super( arg ); + } + + public void testNamespaceDefinition() throws Exception + { + for( int i = 0; i < 2; ++i ) + { + TranslationUnit translationUnit; + if( i == 0 ) + translationUnit = parse("namespace KingJohn { int x; }"); + else + translationUnit = parse("namespace { int x; }"); + + List declarations = translationUnit.getDeclarations(); + assertEquals( declarations.size(), 1 ); + NamespaceDefinition namespace = (NamespaceDefinition)declarations.get(0); + + if( i == 0 ) + assertEquals( namespace.getName().toString(), "KingJohn" ); + else + assertEquals( namespace.getName(), "" ); + List namespaceDeclarations = namespace.getDeclarations(); + assertEquals( namespaceDeclarations.size(), 1 ); + SimpleDeclaration simpleDec = (SimpleDeclaration)namespaceDeclarations.get(0); + assertEquals( simpleDec.getDeclSpecifier().getType(), DeclSpecifier.t_int ); + List declarators = simpleDec.getDeclarators(); + assertEquals( declarators.size(), 1 ); + Declarator declarator = (Declarator)declarators.get(0); + assertEquals( declarator.getName().toString(), "x"); + } + } + + public void testLinkageSpecification() throws Exception + { + for( int i = 0; i < 2; ++i ) + { + TranslationUnit translationUnit; + if( i == 0 ) + translationUnit = parse("extern \"C\" { int x(void); }"); + else + translationUnit = parse("extern \"ADA\" int x(void);"); + + List declarations = translationUnit.getDeclarations(); + assertEquals( declarations.size(), 1 ); + LinkageSpecification linkage = (LinkageSpecification)declarations.get(0); + if( i == 0 ) + assertEquals( "C", linkage.getLanguageLinkage() ); + else + assertEquals( "ADA", linkage.getLanguageLinkage() ); + + List subDeclarations = linkage.getDeclarations(); + assertEquals( subDeclarations.size(), 1 ); + + SimpleDeclaration simpleDec = (SimpleDeclaration)subDeclarations.get(0); + assertEquals( simpleDec.getDeclSpecifier().getType(), DeclSpecifier.t_int ); + List declarators = simpleDec.getDeclarators(); + assertEquals( declarators.size(), 1 ); + Declarator declarator = (Declarator)declarators.get(0); + assertEquals( declarator.getName().toString(), "x" ); + assertNotNull( declarator.getParms() ); + } + + } + + public void testTemplateSpecialization() throws Exception + { + TranslationUnit tu = parse( "template<> class stream { /* ... */ };"); + assertEquals( tu.getDeclarations().size(), 1 ); + ExplicitTemplateDeclaration explicit = (ExplicitTemplateDeclaration)tu.getDeclarations().get( 0 ); + assertNotNull( explicit ); + assertEquals( explicit.getKind(), ExplicitTemplateDeclaration.k_specialization ); + assertEquals( explicit.getDeclarations().size(), 1 ); + SimpleDeclaration declaration = (SimpleDeclaration)explicit.getDeclarations().get(0); + assertNotNull( declaration ); + ClassSpecifier classSpec = (ClassSpecifier)declaration.getTypeSpecifier(); + assertNotNull( classSpec ); + assertEquals( classSpec.getClassKey(), ClassKey.t_class ); + assertEquals( classSpec.getName().toString(), "stream" ); + assertEquals( declaration.getDeclarators().size(), 0 ); + assertEquals( classSpec.getDeclarations().size(), 0 ); + + } + + public void testTemplateInstantiation() throws Exception + { + TranslationUnit tu = parse( "template class Array;"); + assertEquals( tu.getDeclarations().size(), 1 ); + ExplicitTemplateDeclaration explicit = (ExplicitTemplateDeclaration)tu.getDeclarations().get( 0 ); + assertNotNull( explicit ); + assertEquals( explicit.getKind(), ExplicitTemplateDeclaration.k_instantiation ); + assertEquals( explicit.getDeclarations().size(), 1 ); + SimpleDeclaration declaration = (SimpleDeclaration)explicit.getDeclarations().get(0); + assertNotNull( declaration ); + ElaboratedTypeSpecifier classSpec = (ElaboratedTypeSpecifier)declaration.getTypeSpecifier(); + assertNotNull( classSpec ); + assertEquals( classSpec.getClassKey(), ClassKey.t_class ); + assertEquals( classSpec.getName().toString(), "Array"); + } + + public void testEnumSpecifier() throws Exception + { + Writer code = new StringWriter(); + code.write( "enum { yo, go = 3, away };\n"); + code.write( "enum hasAName { last = 666 };"); + TranslationUnit translationUnit = parse( code.toString() ); + List declarations = translationUnit.getDeclarations(); + assertEquals( declarations.size(), 2 ); + + SimpleDeclaration declaration1 = (SimpleDeclaration)declarations.get(0); + EnumerationSpecifier enumSpecifier = (EnumerationSpecifier)declaration1.getTypeSpecifier(); + assertNull( enumSpecifier.getName() ); + List firstEnumItems = enumSpecifier.getEnumeratorDefinitions(); + assertEquals( 3, firstEnumItems.size()); + EnumeratorDefinition enumDef1_1 = (EnumeratorDefinition)firstEnumItems.get(0); + assertEquals( enumDef1_1.getName().toString(), "yo" ); + assertNull( enumDef1_1.getExpression() ); + + EnumeratorDefinition enumDef1_2 = (EnumeratorDefinition)firstEnumItems.get(1); + assertEquals( enumDef1_2.getName().toString(), "go" ); + assertNotNull( enumDef1_2.getExpression() ); + + EnumeratorDefinition enumDef1_3 = (EnumeratorDefinition)firstEnumItems.get(2); + assertEquals( enumDef1_3.getName().toString(), "away" ); + assertNull( enumDef1_3.getExpression() ); + + SimpleDeclaration declaration2 = (SimpleDeclaration)declarations.get(1); + EnumerationSpecifier enumSpecifier2 = (EnumerationSpecifier)declaration2.getTypeSpecifier(); + assertEquals( enumSpecifier2.getName().toString(), "hasAName" ); + + } + + public void testTypedef() throws Exception + { + TranslationUnit tu = parse( "typedef const struct A * const cpStructA;"); + assertEquals( tu.getDeclarations().size(), 1 ); + SimpleDeclaration declaration = (SimpleDeclaration)tu.getDeclarations().get(0); + assertTrue( declaration.getDeclSpecifier().isTypedef() ); + assertTrue( declaration.getDeclSpecifier().isConst() ); + ElaboratedTypeSpecifier elab = (ElaboratedTypeSpecifier) declaration.getTypeSpecifier(); + assertEquals( elab.getClassKey(), ClassKey.t_struct ); + assertEquals( elab.getName().toString(), "A" ); + List declarators = declaration.getDeclarators(); + assertEquals( declarators.size(), 1 ); + Declarator declarator = (Declarator)declarators.get(0); + assertEquals( declarator.getName().toString(), "cpStructA"); + assertEquals( declarator.getPointerOperators().size(), 1 ); + PointerOperator po = (PointerOperator)declarator.getPointerOperators().get(0); + assertEquals( po.getType(), PointerOperator.t_pointer); + assertTrue( po.isConst() ); + assertFalse( po.isVolatile()); + + } + public void testUsingClauses() throws Exception + { + Writer code = new StringWriter(); + + code.write("using namespace A::B::C;\n"); + code.write("using namespace C;\n"); + code.write("using B::f;\n"); + code.write("using ::f;\n"); + code.write("using typename crap::de::crap;"); + TranslationUnit translationUnit = parse(code.toString()); + + List declarations = translationUnit.getDeclarations(); + assertEquals( declarations.size(), 5 ); + + UsingDirective first, second; + UsingDeclaration third, fourth, fifth; + + first = (UsingDirective) declarations.get(0); + assertEquals( first.getNamespaceName().toString(), "A::B::C" ); + + second = (UsingDirective) declarations.get(1); + assertEquals( second.getNamespaceName().toString(), "C" ); + + third = (UsingDeclaration) declarations.get(2); + assertEquals( third.getMappedName(), "B::f" ); + assertFalse( third.isTypename() ); + + fourth = (UsingDeclaration) declarations.get(3); + assertEquals( fourth.getMappedName(), "::f" ); + assertFalse( fourth.isTypename() ); + + fifth = (UsingDeclaration) declarations.get(4); + assertTrue( fifth.isTypename() ); + assertEquals( fifth.getMappedName(), "crap::de::crap" ); + } + + public void testDeclSpecifier() throws Exception + { + DeclSpecifier d = new DeclSpecifier(); + d.setTypedef( true ); + assertTrue( d.isTypedef() ); + d.setTypedef( false ); + assertFalse( d.isTypedef() ); + d.setAuto(true); + assertTrue( d.isAuto() ); + d.setAuto(false); + assertFalse( d.isAuto()); + d.setRegister(true); + assertTrue( d.isRegister() ); + d.setRegister(false); + assertFalse( d.isRegister() ); + d.setStatic(true); + assertTrue( d.isStatic() ); + d.setStatic(false); + assertFalse( d.isStatic() ); + + d.setExtern(true); + assertTrue( d.isExtern() ); + d.setExtern(false); + assertFalse( d.isExtern() ); + + d.setMutable(true); + assertTrue( d.isMutable() ); + d.setMutable(false); + assertFalse( d.isMutable() ); + + d.setInline(true); + assertTrue( d.isInline() ); + d.setInline(false); + assertFalse( d.isInline() ); + + d.setVirtual(true); + assertTrue( d.isVirtual() ); + d.setVirtual(false); + assertFalse( d.isVirtual() ); + + d.setExplicit(true); + assertTrue( d.isExplicit() ); + d.setExplicit(false); + assertFalse( d.isExplicit() ); + + d.setTypedef(true); + assertTrue( d.isTypedef() ); + d.setTypedef(false); + assertFalse( d.isTypedef() ); + + d.setFriend(true); + assertTrue( d.isFriend()); + d.setFriend(false); + assertFalse( d.isFriend()); + + d.setConst(true); + assertTrue( d.isConst() ); + d.setConst(false); + assertFalse( d.isConst() ); + + d.setVolatile(true); + assertTrue( d.isVolatile() ); + d.setVolatile(false); + assertFalse( d.isVolatile() ); + + d.setUnsigned(true); + assertTrue( d.isUnsigned()); + d.setUnsigned(false); + assertFalse( d.isUnsigned()); + + d.setShort(true); + assertTrue( d.isShort()); + d.setShort(false); + assertFalse( d.isShort()); + + d.setLong(true); + assertTrue( d.isLong() ); + d.setLong(false); + assertFalse( d.isLong() ); + + for( int i = 0; i <= 7; ++i ) + { + d.setType( i ); + for( int j = 0; j <= 7; ++j ) + { + if( j == i ) + assertTrue( d.getType() == j ); + else + assertFalse( d.getType() == j ); + } + } + + } + + /** + * Test code: int x = 5; + * Purpose: to test the simple decaration in it's simplest form. + */ + public void testIntGlobal() throws Exception { + // Parse and get the translation Unit + TranslationUnit translationUnit = parse("int x = 5;"); + + // Get the simple declaration + List declarations = translationUnit.getDeclarations(); + assertEquals(1, declarations.size()); + SimpleDeclaration declaration = (SimpleDeclaration)declarations.get(0); + + // Make sure it is only an int + assertEquals(DeclSpecifier.t_int, declaration.getDeclSpecifier().getDeclSpecifierSeq()); + + // Get the declarator and check its name + List declarators = declaration.getDeclarators(); + assertEquals(1, declarators.size()); + Declarator declarator = (Declarator)declarators.get(0); + Name name = declarator.getName(); + assertEquals("x", name.toString()); + + Expression exp = declarator.getExpression(); + assertNotNull( exp ); + assertEquals( 1, exp.elements().size() ); + Token t = (Token)exp.elements().get(0); + assertEquals( t.getImage(), "5" ); + assertEquals( t.getType(), IToken.tINTEGER); + } + + /** + * Test code: class A { } a; + * Purpose: tests the use of a classSpecifier in + */ + public void testEmptyClass() throws Exception { + // Parse and get the translation unit + Writer code = new StringWriter(); + code.write("class A { } a;"); + TranslationUnit translationUnit = parse(code.toString()); + + // Get the simple declaration + List declarations = translationUnit.getDeclarations(); + assertEquals(1, declarations.size()); + SimpleDeclaration declaration = (SimpleDeclaration)declarations.get(0); + + // Make sure it is a type specifier + assertEquals(0, declaration.getDeclSpecifier().getDeclSpecifierSeq()); + + // Get the class specifier and check its name + ClassSpecifier classSpecifier = (ClassSpecifier)declaration.getTypeSpecifier(); + Name className = classSpecifier.getName(); + assertEquals("A", className.toString()); + + // Get the declarator and check it's name + List declarators = declaration.getDeclarators(); + assertEquals(1, declarators.size()); + Declarator declarator = (Declarator)declarators.get(0); + Name name = declarator.getName(); + assertEquals("a", name.toString()); + } + + /** + * Test code: class A { public: int x; }; + * Purpose: tests a declaration in a class scope. + */ + public void testSimpleClassMember() throws Exception { + // Parse and get the translaton unit + Writer code = new StringWriter(); + code.write("class A { public: int x; };"); + TranslationUnit translationUnit = parse(code.toString()); + + // Get the declaration + List declarations = translationUnit.getDeclarations(); + assertEquals(1, declarations.size()); + SimpleDeclaration declaration = (SimpleDeclaration)declarations.get(0); + + // Make sure there is no declarator + assertEquals(0, declaration.getDeclarators().size()); + + // Make sure it's a type specifier + assertEquals(0, declaration.getDeclSpecifier().getDeclSpecifierSeq()); + + // Get the class specifier and check its name + ClassSpecifier classSpecifier = (ClassSpecifier)declaration.getTypeSpecifier(); + Name className = classSpecifier.getName(); + assertEquals("A", className.toString()); + + // Get the member declaration + declarations = classSpecifier.getDeclarations(); + assertEquals(1, declarations.size()); + declaration = (SimpleDeclaration)declarations.get(0); + + // Make sure it's an int + assertEquals(DeclSpecifier.t_int, declaration.getDeclSpecifier().getDeclSpecifierSeq()); + + // Get the declarator and check it's name + List declarators = declaration.getDeclarators(); + assertEquals(1, declarators.size()); + Declarator declarator = (Declarator)declarators.get(0); + Name name = declarator.getName(); + assertEquals("x", name.toString()); + } + /** + * Test code: class A : public B, private C, virtual protected D { public: int x, y; float a,b,c; } + * Purpose: tests a declaration in a class scope. + */ + public void testSimpleClassMembers() throws Exception { + // Parse and get the translaton unit + Writer code = new StringWriter(); + code.write("class A : public B, private C, virtual protected D { public: int x, y; float a,b,c; };"); + TranslationUnit translationUnit = parse(code.toString()); + + // Get the declaration + List declarations = translationUnit.getDeclarations(); + assertEquals(1, declarations.size()); + SimpleDeclaration declaration = (SimpleDeclaration)declarations.get(0); + + // Make sure there is no declarator + assertEquals(0, declaration.getDeclarators().size()); + + // Make sure it's a type specifier + assertEquals(0, declaration.getDeclSpecifier().getDeclSpecifierSeq()); + + // Get the class specifier and check its name + ClassSpecifier classSpecifier = (ClassSpecifier)declaration.getTypeSpecifier(); + Name className = classSpecifier.getName(); + assertEquals("A", className.toString()); + + List baseClasses = classSpecifier.getBaseSpecifiers(); + assertEquals( 3, baseClasses.size() ); + BaseSpecifier bs = (BaseSpecifier)baseClasses.get( 0 ); + assertEquals( bs.getAccess(), AccessSpecifier.v_public ); + assertEquals( bs.isVirtual(), false ); + assertEquals( bs.getName().toString(), "B" ); + + bs = (BaseSpecifier)baseClasses.get( 1 ); + assertEquals( bs.getAccess(), AccessSpecifier.v_private ); + assertEquals( bs.isVirtual(), false ); + assertEquals( bs.getName().toString(), "C" ); + + bs = (BaseSpecifier)baseClasses.get( 2 ); + assertEquals( bs.getAccess(), AccessSpecifier.v_protected ); + assertEquals( bs.isVirtual(), true ); + assertEquals( bs.getName().toString(), "D" ); + + + // Get the member declaration + declarations = classSpecifier.getDeclarations(); + assertEquals(2, declarations.size()); + declaration = (SimpleDeclaration)declarations.get(0); + + // Make sure it's an int + assertEquals(DeclSpecifier.t_int, declaration.getDeclSpecifier().getDeclSpecifierSeq()); + + // Get the declarator and check it's name + List declarators = declaration.getDeclarators(); + assertEquals(2, declarators.size()); + Declarator declarator = (Declarator)declarators.get(0); + Name name = declarator.getName(); + assertEquals("x", name.toString()); + declarator = (Declarator)declarators.get(1); + name = declarator.getName(); + assertEquals("y", name.toString()); + + declaration = (SimpleDeclaration)declarations.get(1); + // Make sure it's an float + assertEquals(DeclSpecifier.t_float, declaration.getDeclSpecifier().getDeclSpecifierSeq()); + declarators = declaration.getDeclarators(); + assertEquals( 3, declarators.size() ); + name = ((Declarator)declarators.get(0)).getName(); + assertEquals( "a", name.toString() ); + name = ((Declarator)declarators.get(1)).getName(); + assertEquals( "b", name.toString() ); + name = ((Declarator)declarators.get(2)).getName(); + assertEquals( "c", name.toString() ); + + } + + + /** + * Test code: int myFunction( void ); + */ + public void testSimpleFunctionDeclaration() throws Exception + { + // Parse and get the translaton unit + Writer code = new StringWriter(); + code.write("void myFunction( void );"); + TranslationUnit translationUnit = parse(code.toString()); + + // Get the declaration + List declarations = translationUnit.getDeclarations(); + assertEquals(1, declarations.size()); + SimpleDeclaration simpleDeclaration = (SimpleDeclaration)declarations.get(0); + assertEquals( simpleDeclaration.getDeclSpecifier().getType(), DeclSpecifier.t_void ); + List declarators = simpleDeclaration.getDeclarators(); + assertEquals( 1, declarators.size() ); + Declarator functionDeclarator = (Declarator)declarators.get( 0 ); + assertEquals( functionDeclarator.getName().toString(), "myFunction" ); + ParameterDeclarationClause pdc = functionDeclarator.getParms(); + assertNotNull( pdc ); + List parameterDecls = pdc.getDeclarations(); + assertEquals( 1, parameterDecls.size() ); + ParameterDeclaration parm1 = (ParameterDeclaration)parameterDecls.get( 0 ); + assertEquals( DeclSpecifier.t_void, parm1.getDeclSpecifier().getType() ); + List parm1Decls = parm1.getDeclarators(); + assertEquals( 1, parm1Decls.size() ); + Declarator parm1Declarator = (Declarator) parm1Decls.get(0); + assertNull( parm1Declarator.getName() ); + } + + /** + * Test code: bool myFunction( int parm1 = 3 * 4, double parm2 ); + * @throws Exception + */ + public void testFunctionDeclarationWithParameters() throws Exception + { + // Parse and get the translaton unit + Writer code = new StringWriter(); + code.write("bool myFunction( int parm1 = 3 * 4, double parm2 );"); + TranslationUnit translationUnit = parse(code.toString()); + + // Get the declaration + List declarations = translationUnit.getDeclarations(); + assertEquals(1, declarations.size()); + SimpleDeclaration simpleDeclaration = (SimpleDeclaration)declarations.get(0); + assertEquals( simpleDeclaration.getDeclSpecifier().getType(), DeclSpecifier.t_bool ); + List declarators = simpleDeclaration.getDeclarators(); + assertEquals( 1, declarators.size() ); + Declarator functionDeclarator = (Declarator)declarators.get( 0 ); + assertEquals( functionDeclarator.getName().toString(), "myFunction" ); + ParameterDeclarationClause pdc = functionDeclarator.getParms(); + assertNotNull( pdc ); + List parameterDecls = pdc.getDeclarations(); + assertEquals( 2, parameterDecls.size() ); + ParameterDeclaration parm1 = (ParameterDeclaration)parameterDecls.get( 0 ); + assertEquals( DeclSpecifier.t_int, parm1.getDeclSpecifier().getType() ); + List parm1Decls = parm1.getDeclarators(); + assertEquals( 1, parm1Decls.size() ); + Declarator parm1Declarator = (Declarator) parm1Decls.get(0); + assertEquals( "parm1", parm1Declarator.getName().toString() ); + Expression initialValueParm1 = parm1Declarator.getExpression(); + assertEquals( initialValueParm1.elements().size(), 3 ); + Token t1 = (Token)initialValueParm1.elements().get( 0 ); + Token t2 = (Token)initialValueParm1.elements().get( 1 ); + Token t3 = (Token)initialValueParm1.elements().get( 2 ); + assertEquals( t1.getType(), IToken.tINTEGER ); + assertEquals( t1.getImage(), "3" ); + assertEquals( t3.getType(), IToken.tSTAR ); + assertEquals( t2.getType(), IToken.tINTEGER ); + assertEquals( t2.getImage(), "4" ); + + ParameterDeclaration parm2 = (ParameterDeclaration)parameterDecls.get( 1 ); + assertEquals( DeclSpecifier.t_double, parm2.getDeclSpecifier().getType() ); + List parm2Decls = parm2.getDeclarators(); + assertEquals( 1, parm2Decls.size() ); + Declarator parm2Declarator = (Declarator) parm2Decls.get(0); + assertEquals( "parm2", parm2Declarator.getName().toString() ); + + } + + + /** + * Test code: "class A { int floor( double input ), someInt; };" + */ + public void testMultipleDeclarators() throws Exception + { + // Parse and get the translaton unit + Writer code = new StringWriter(); + code.write("class A { int floor( double input ), someInt; };"); + TranslationUnit translationUnit = parse(code.toString()); + + List tudeclarations = translationUnit.getDeclarations(); + assertEquals( 1, tudeclarations.size() ); + SimpleDeclaration classDecl = (SimpleDeclaration)tudeclarations.get(0); + assertEquals( 0, classDecl.getDeclarators().size() ); + ClassSpecifier classSpec = (ClassSpecifier)classDecl.getTypeSpecifier(); + + List classDeclarations = classSpec.getDeclarations(); + assertEquals( classDeclarations.size(), 1 ); + SimpleDeclaration simpleDeclaration = (SimpleDeclaration)classDeclarations.get(0); + assertEquals( simpleDeclaration.getDeclSpecifier().getType(), DeclSpecifier.t_int ); + List simpleDeclarators = simpleDeclaration.getDeclarators(); + assertEquals( simpleDeclarators.size(), 2 ); + Declarator methodDeclarator = (Declarator)simpleDeclarators.get(0); + assertEquals( methodDeclarator.getName().toString(), "floor" ); + ParameterDeclarationClause pdc = methodDeclarator.getParms(); + assertNotNull( pdc ); + List parameterDeclarations = pdc.getDeclarations(); + assertEquals( 1, parameterDeclarations.size() ); + ParameterDeclaration parm1Declaration = (ParameterDeclaration)parameterDeclarations.get(0); + assertEquals( DeclSpecifier.t_double, parm1Declaration.getDeclSpecifier().getType() ); + List parm1Declarators = parm1Declaration.getDeclarators(); + assertEquals( parm1Declarators.size(), 1 ); + Declarator parm1Declarator = (Declarator)parm1Declarators.get(0); + assertEquals( parm1Declarator.getName().toString(), "input" ); + Declarator integerDeclarator = (Declarator)simpleDeclarators.get(1); + assertEquals( integerDeclarator.getName().toString(), "someInt" ); + assertNull( integerDeclarator.getParms() ); + } + + public void testFunctionModifiers() throws Exception + { + Writer code = new StringWriter(); + code.write( "virtual void foo( void ) const throw ( yay, nay, we::dont::care ) = 0;"); + TranslationUnit translationUnit = parse( code.toString() ); + List tudeclarations = translationUnit.getDeclarations(); + assertEquals( 1, tudeclarations.size() ); + SimpleDeclaration decl1 = (SimpleDeclaration)tudeclarations.get(0); + assertEquals( decl1.getDeclSpecifier().getType(), DeclSpecifier.t_void); + assertTrue( decl1.getDeclSpecifier().isVirtual() ); + assertEquals( decl1.getDeclarators().size(), 1 ); + Declarator declarator = (Declarator)decl1.getDeclarators().get(0); + assertEquals( declarator.getName().toString(), "foo"); + assertTrue( declarator.isConst() ); + assertFalse( declarator.isVolatile() ); + ExceptionSpecifier exceptions = declarator.getExceptionSpecifier(); + List typenames = exceptions.getTypeNames(); + assertEquals( typenames.size(), 3 ); + Name n = (Name)typenames.get(0); + assertEquals( n.toString(), "yay"); + n = (Name)typenames.get(1); + assertEquals( n.toString(), "nay"); + n = (Name)typenames.get(2); + assertEquals( n.toString(), "we::dont::care"); + assertTrue( declarator.isPureVirtual() ); + } + + + public void testArrays() throws Exception + { + // Parse and get the translaton unit + Writer code = new StringWriter(); + code.write("int x [5][];"); + TranslationUnit translationUnit = parse( code.toString() ); + List tudeclarations = translationUnit.getDeclarations(); + assertEquals( 1, tudeclarations.size() ); + SimpleDeclaration decl1 = (SimpleDeclaration)tudeclarations.get(0); + assertEquals( decl1.getDeclSpecifier().getType(), DeclSpecifier.t_int); + assertEquals( decl1.getDeclarators().size(), 1 ); + Declarator declarator = (Declarator)decl1.getDeclarators().get(0); + assertEquals( declarator.getName().toString(), "x"); + List arrayQualifiers = declarator.getArrayQualifiers(); + assertEquals( 2, arrayQualifiers.size() ); + ArrayQualifier q1 =(ArrayQualifier)arrayQualifiers.get(0); + assertNotNull( q1.getExpression() ); + List tokens = q1.getExpression().elements(); + assertEquals( tokens.size(), 1 ); + ArrayQualifier q2 =(ArrayQualifier)arrayQualifiers.get(1); + assertNull( q2.getExpression() ); + } + + public void testElaboratedParms() throws Exception + { + TranslationUnit tu = parse( "int x( struct A myA ) { /* junk */ }", true, true); + assertEquals( tu.getDeclarations().size(), 1 ); + SimpleDeclaration declaration = (SimpleDeclaration)tu.getDeclarations().get(0); + assertEquals( declaration.getDeclSpecifier().getType(), DeclSpecifier.t_int ); + assertEquals( declaration.getDeclarators().size(), 1 ); + Declarator declarator = (Declarator)declaration.getDeclarators().get(0); + assertEquals( declarator.getName().toString(), "x" ); + assertTrue( declaration.isFunctionDefinition() ); + assertEquals( declarator.getParms().getDeclarations().size(), 1 ); + ParameterDeclaration parm = (ParameterDeclaration)declarator.getParms().getDeclarations().get(0); + ElaboratedTypeSpecifier typeSpec = (ElaboratedTypeSpecifier)parm.getTypeSpecifier(); + assertEquals( typeSpec.getClassKey(), ClassKey.t_struct ); + assertEquals( typeSpec.getName().toString(), "A" ); + assertEquals( parm.getDeclarators().size(), 1 ); + Declarator subDeclarator = (Declarator)parm.getDeclarators().get(0); + assertEquals( subDeclarator.getName().toString(), "myA" ); + + } + + public void testPreprocessor() throws Exception + { + Writer code = new StringWriter(); + code.write( "#include \n#define DEF VALUE\n"); + TranslationUnit tu = parse( code.toString(), true, true ); + assertEquals( tu.getInclusions().size(), 1 ); + Inclusion i = (Inclusion)tu.getInclusions().get(0); + assertEquals( i.getName(), "stdio.h"); + assertEquals( i.getStartingOffset(), 0 ); + assertEquals( i.getNameLength(), 7 ); + assertEquals( i.getNameOffset(), 10 ); + assertEquals( i.getTotalLength(), 18 ); + + assertEquals( tu.getMacros().size(), 1 ); + Macro m = (Macro)tu.getMacros().get(0); + assertEquals( m.getName(), "DEF" ); + assertEquals( m.getStartingOffset(), 19 ); + assertEquals( m.getNameLength(), 3 ); + assertEquals( m.getNameOffset(), 27 ); + assertEquals( m.getTotalLength(), 18 ); + } + + public void testMemberDeclarations() throws Exception + { + Writer code = new StringWriter(); + code.write( "class A {\n" ); + code.write( "public:\n"); + code.write( " int isPublic;\n" ); + code.write( "private:\n"); + code.write( " int isPrivate;\n" ); + code.write( "protected:\n"); + code.write( " int isProtected;\n" ); + code.write( "};"); + TranslationUnit translationUnit = parse( code.toString() ); + assertEquals( translationUnit.getDeclarations().size(), 1 ); + SimpleDeclaration classDeclaration = (SimpleDeclaration) + translationUnit.getDeclarations().get(0); + assertEquals( classDeclaration.getDeclarators().size(), 0 ); + ClassSpecifier classSpec = (ClassSpecifier)classDeclaration.getTypeSpecifier(); + assertEquals( "A", classSpec.getName().toString() ); + assertEquals( 3, classSpec.getDeclarations().size()); + for( int i = 0; i < 3; ++i ) + { + SimpleDeclaration subDecl = (SimpleDeclaration)classSpec.getDeclarations().get( i ); + int visibility = AccessSpecifier.v_unknown; + + switch( i ) + { + case 0: + visibility = AccessSpecifier.v_public; + break; + case 1: + visibility = AccessSpecifier.v_private; + break; + case 2: + visibility = AccessSpecifier.v_protected; + break; + default: + break; + } + + assertEquals( visibility, subDecl.getAccessSpecifier().getAccess() ); + } + + } + + public void testPointerOperators() throws Exception + { + // Parse and get the translaton unit + Writer code = new StringWriter(); + code.write("int * x = 0, & y, * const * const volatile * z;"); + TranslationUnit translationUnit = parse(code.toString()); + + List tudeclarations = translationUnit.getDeclarations(); + assertEquals( 1, tudeclarations.size() ); + SimpleDeclaration decl1 = (SimpleDeclaration)tudeclarations.get(0); + assertEquals( decl1.getDeclSpecifier().getType(), DeclSpecifier.t_int); + + assertEquals( 3, decl1.getDeclarators().size() ); + + Declarator declarator1 = (Declarator)decl1.getDeclarators().get( 0 ); + assertEquals( declarator1.getName().toString(), "x" ); + Expression initValue1 = declarator1.getExpression(); + assertEquals( initValue1.elements().size(), 1 ); + List ptrOps1 = declarator1.getPointerOperators(); + assertNotNull( ptrOps1 ); + assertEquals( 1, ptrOps1.size() ); + PointerOperator po1 = (PointerOperator)ptrOps1.get(0); + assertNotNull( po1 ); + assertFalse( po1.isConst() ); + assertFalse( po1.isVolatile() ); + assertEquals( po1.getType(), PointerOperator.t_pointer ); + Token t1 = (Token)initValue1.elements().get(0); + assertEquals( t1.getType(), IToken.tINTEGER ); + assertEquals( t1.getImage(), "0"); + + Declarator declarator2 = (Declarator)decl1.getDeclarators().get( 1 ); + assertEquals( declarator2.getName().toString(), "y" ); + assertNull( declarator2.getExpression() ); + List ptrOps2 = declarator2.getPointerOperators(); + assertNotNull( ptrOps2 ); + assertEquals( 1, ptrOps2.size() ); + PointerOperator po2 = (PointerOperator)ptrOps2.get(0); + assertNotNull( po2 ); + assertFalse( po2.isConst() ); + assertFalse( po2.isVolatile() ); + assertEquals( po2.getType(), PointerOperator.t_reference ); + + Declarator declarator3 = (Declarator)decl1.getDeclarators().get( 2 ); + assertEquals( "z", declarator3.getName().toString() ); + List ptrOps3 = declarator3.getPointerOperators(); + assertNotNull( ptrOps3 ); + assertEquals( 3, ptrOps3.size() ); + + //* const + PointerOperator po3 = (PointerOperator)ptrOps3.get(0); + assertNotNull( po3 ); + assertTrue( po3.isConst() ); + assertFalse( po3.isVolatile() ); + assertEquals( po3.getType(), PointerOperator.t_pointer ); + // * const volatile + PointerOperator po4 = (PointerOperator)ptrOps3.get(1); + assertNotNull( po4 ); + assertEquals( po4.getType(), PointerOperator.t_pointer ); + assertTrue( po4.isConst() ); + assertTrue( po4.isVolatile() ); + // * + PointerOperator po5 = (PointerOperator)ptrOps3.get(2); + assertNotNull( po5 ); + assertFalse( po5.isConst() ); + assertFalse( po5.isVolatile() ); + assertEquals( po5.getType(), PointerOperator.t_pointer ); + } + + public void testBug26467() throws Exception + { + StringWriter code = new StringWriter(); + code.write( "struct foo { int fooInt; char fooChar; };\n" ); + code.write( "typedef struct foo fooStruct;\n" ); + code.write( "typedef struct { int anonInt; char anonChar; } anonStruct;\n" ); + + TranslationUnit tu = parse( code.toString() ); + List tuDeclarations = tu.getDeclarations(); + assertEquals( tuDeclarations.size(), 3 ); + + SimpleDeclaration declaration = (SimpleDeclaration)tuDeclarations.get(0); + ClassSpecifier classSpec = (ClassSpecifier)declaration.getTypeSpecifier(); + assertEquals( declaration.getDeclarators().size(), 0 ); + assertEquals( classSpec.getClassKey(), ClassKey.t_struct); + assertEquals( classSpec.getName().toString(), "foo"); + List subDeclarations = classSpec.getDeclarations(); + assertEquals( subDeclarations.size(), 2 ); + SimpleDeclaration subDeclaration = (SimpleDeclaration)subDeclarations.get(0); + assertEquals( subDeclaration.getDeclSpecifier().getType(), DeclSpecifier.t_int); + assertEquals( subDeclaration.getDeclarators().size(), 1 ); + assertEquals( ((Declarator)subDeclaration.getDeclarators().get(0)).getName().toString(), "fooInt" ); + subDeclaration = (SimpleDeclaration)subDeclarations.get(1); + assertEquals( subDeclaration.getDeclSpecifier().getType(), DeclSpecifier.t_char); + assertEquals( subDeclaration.getDeclarators().size(), 1 ); + assertEquals( ((Declarator)subDeclaration.getDeclarators().get(0)).getName().toString(), "fooChar" ); + + declaration = (SimpleDeclaration)tuDeclarations.get(1); + assertEquals( declaration.getDeclSpecifier().isTypedef(), true ); + ElaboratedTypeSpecifier elab = (ElaboratedTypeSpecifier)declaration.getTypeSpecifier(); + assertEquals( elab.getClassKey(), ClassKey.t_struct); + assertEquals( elab.getName().toString(), "foo" ); + assertEquals( declaration.getDeclarators().size(), 1 ); + assertEquals( ((Declarator)declaration.getDeclarators().get(0)).getName().toString(), "fooStruct" ); + + declaration = (SimpleDeclaration)tuDeclarations.get(2); + assertEquals( declaration.getDeclSpecifier().isTypedef(), true ); + classSpec = (ClassSpecifier) declaration.getTypeSpecifier(); + assertEquals( classSpec.getClassKey(), ClassKey.t_struct ); + assertNull( classSpec.getName() ); + subDeclarations = classSpec.getDeclarations(); + assertEquals( subDeclarations.size(), 2 ); + subDeclaration = (SimpleDeclaration)subDeclarations.get(0); + assertEquals( subDeclaration.getDeclSpecifier().getType(), DeclSpecifier.t_int); + assertEquals( subDeclaration.getDeclarators().size(), 1 ); + assertEquals( ((Declarator)subDeclaration.getDeclarators().get(0)).getName().toString(), "anonInt" ); + subDeclaration = (SimpleDeclaration)subDeclarations.get(1); + assertEquals( subDeclaration.getDeclSpecifier().getType(), DeclSpecifier.t_char); + assertEquals( subDeclaration.getDeclarators().size(), 1 ); + assertEquals( ((Declarator)subDeclaration.getDeclarators().get(0)).getName().toString(), "anonChar" ); + assertEquals( declaration.getDeclarators().size(), 1 ); + assertEquals( ((Declarator)declaration.getDeclarators().get(0)).getName().toString(), "anonStruct" ); + } + + public void testASMDefinition() throws Exception + { + TranslationUnit tu = parse( "asm( \"mov ep1 ds2\");" ); + assertEquals( tu.getDeclarations().size(), 1 ); + ASMDefinition asm = (ASMDefinition)tu.getDeclarations().get(0); + assertEquals( asm.getAssemblyCode(), "mov ep1 ds2" ); + } + + public void testConstructorChain() throws Exception + { + TranslationUnit tu = parse( "TrafficLight_Actor::TrafficLight_Actor( RTController * rtg_rts, RTActorRef * rtg_ref ) : RTActor( rtg_rts, rtg_ref ), myId( 0 ) {}", true, true); + List tuDeclarations = tu.getDeclarations(); + assertEquals( tuDeclarations.size(), 1 ); + SimpleDeclaration decl1 = (SimpleDeclaration)tuDeclarations.get(0); + List declarators1 = decl1.getDeclarators(); + assertEquals( declarators1.size(), 1 ); + Declarator declarator1 = (Declarator)declarators1.get(0); + assertEquals( declarator1.getName().toString(), "TrafficLight_Actor::TrafficLight_Actor"); + ConstructorChain chain1 = declarator1.getCtorChain(); + List chainElements1 = chain1.getChainElements(); + assertEquals( chainElements1.size(), 2 ); + ConstructorChainElement element1_1 = (ConstructorChainElement) chainElements1.get(0); + assertEquals( element1_1.getName().toString(), "RTActor"); + List expressions1_1 = element1_1.getExpressionList(); + assertEquals( expressions1_1.size(), 2 ); + ConstructorChainElementExpression expression1_1_1 = (ConstructorChainElementExpression)expressions1_1.get(0); + assertEquals( expression1_1_1.getExpression().elements().size(), 1 ); + Name t1_1_1 = (Name)expression1_1_1.getExpression().elements().get(0); + ConstructorChainElementExpression expression1_1_2 = (ConstructorChainElementExpression)expressions1_1.get(1); + assertEquals( expression1_1_2.getExpression().elements().size(), 1 ); + Name t1_1_2 = (Name)expression1_1_2.getExpression().elements().get(0); + + assertEquals( t1_1_1.toString(), "rtg_rts"); + assertEquals( t1_1_2.toString(), "rtg_ref"); + + ConstructorChainElement element1_2 = (ConstructorChainElement) chainElements1.get(1); + assertEquals( element1_2.getName().toString(), "myId" ); + List expressions1_2 = element1_2.getExpressionList(); + assertEquals( expressions1_2.size(), 1 ); + ConstructorChainElementExpression expression = (ConstructorChainElementExpression) expressions1_2.get(0); + assertEquals( expression.getExpression().elements().size(), 1 ); + Token t = (Token)expression.getExpression().elements().get(0); + assertEquals( t.getImage(), "0"); + assertEquals( t.getType(), IToken.tINTEGER ); + + + + } + +// public void testErrors() +// { +// validateWeEncounterAnError( "void myFunc( int hey, flo );"); +// } + + public void validateWeEncounterAnError( String codeText ) + { + try + { + // Parse and get the translaton unit + Writer code = new StringWriter(); + code.write(codeText); + try + { + TranslationUnit translationUnit = parse(code.toString()); + fail( "We should not reach this line. Failure."); + } catch( ParserException pe ) + { + } + catch( Exception e ) + { + fail( "Unknown exception " + e.getMessage() ); + } + }catch( IOException io ) + { + fail( "IOException thrown"); + } + } + + public void testTemplateDeclarationOfMethod() throws Exception + { + TranslationUnit tu = parse( "template A aTemplatedFunction( B bInstance );"); + assertEquals( tu.getDeclarations().size(), 1 ); + TemplateDeclaration templateDeclaration = (TemplateDeclaration)tu.getDeclarations().get(0); + assertEquals( templateDeclaration.getTemplateParms().getDeclarations().size(), 2 ); + TemplateParameter templateParameter = (TemplateParameter)templateDeclaration.getTemplateParms().getDeclarations().get(0); + assertEquals( templateParameter.getKind(), TemplateParameter.k_class ); + assertEquals( templateParameter.getName().toString(), "A"); + templateParameter = (TemplateParameter)templateDeclaration.getTemplateParms().getDeclarations().get(1); + assertEquals( templateParameter.getKind(), TemplateParameter.k_typename ); + assertEquals( templateParameter.getName().toString(), "B"); + assertEquals( templateParameter.getTypeId().toString(), "C"); + assertEquals( templateDeclaration.getDeclarations().size(), 1 ); + SimpleDeclaration methodDeclaration = (SimpleDeclaration) templateDeclaration.getDeclarations().get(0); + assertEquals( methodDeclaration.getDeclSpecifier().getType(), DeclSpecifier.t_type ); + assertEquals( methodDeclaration.getDeclSpecifier().getTypeName(), "A"); + assertEquals( methodDeclaration.getDeclarators().size(), 1 ); + Declarator declarator = (Declarator)methodDeclaration.getDeclarators().get(0); + assertEquals( declarator.getName().toString(), "aTemplatedFunction" ); + assertEquals( declarator.getParms().getDeclarations().size(), 1 ); + ParameterDeclaration parameterDeclaration = (ParameterDeclaration)declarator.getParms().getDeclarations().get(0); + assertEquals( parameterDeclaration.getDeclSpecifier().getType(), DeclSpecifier.t_type ); + assertEquals( parameterDeclaration.getDeclSpecifier().getTypeName(), "B" ); + assertEquals( parameterDeclaration.getDeclarators().size(), 1 ); + assertEquals( ((Declarator)parameterDeclaration.getDeclarators().get(0)).getName().toString(), "bInstance"); + } + + public void testTemplateDeclarationOfClass() throws Exception { + TranslationUnit tu = parse( "template class, template class AClass> class myarray { /* ... */ };"); + assertEquals( tu.getDeclarations().size(), 1 ); + TemplateDeclaration declaration = (TemplateDeclaration)tu.getDeclarations().get(0); + assertEquals( declaration.getTemplateParms().getDeclarations().size(), 8 ); + TemplateParameter parameter = (TemplateParameter)declaration.getTemplateParms().getDeclarations().get(0); + assertEquals( parameter.getKind(), TemplateParameter.k_class); + assertEquals( parameter.getName().toString(), "T" ); + assertNull( parameter.getTypeId()); + parameter = (TemplateParameter)declaration.getTemplateParms().getDeclarations().get(1); + assertEquals( parameter.getKind(), TemplateParameter.k_typename); + assertEquals( parameter.getName().toString(), "Tibor" ); + assertEquals( parameter.getTypeId().toString(), "junk"); + parameter = (TemplateParameter)declaration.getTemplateParms().getDeclarations().get(2); + assertEquals( parameter.getKind(), TemplateParameter.k_class); + assertNull( parameter.getName() ); + assertNull( parameter.getTypeId()); + parameter = (TemplateParameter)declaration.getTemplateParms().getDeclarations().get(3); + assertEquals( parameter.getKind(), TemplateParameter.k_typename); + assertNull( parameter.getName() ); + assertNull( parameter.getTypeId()); + ParameterDeclaration decl = (ParameterDeclaration)declaration.getTemplateParms().getDeclarations().get(4); + assertEquals( decl.getDeclSpecifier().getType(), DeclSpecifier.t_int ); + assertEquals( 1, decl.getDeclarators().size() ); + assertEquals( "x", ((Declarator)decl.getDeclarators().get(0)).getName().toString() ); + + decl = (ParameterDeclaration)declaration.getTemplateParms().getDeclarations().get(5); + assertEquals( decl.getDeclSpecifier().getType(), DeclSpecifier.t_float ); + assertEquals( 1, decl.getDeclarators().size() ); + assertEquals( "y", ((Declarator)decl.getDeclarators().get(0)).getName().toString() ); + + parameter = (TemplateParameter)declaration.getTemplateParms().getDeclarations().get(6); + assertEquals( parameter.getKind(), TemplateParameter.k_template ); + assertEquals( parameter.getTemplateParms().getDeclarations().size(), 1 ); + assertNull( parameter.getName() ); + TemplateParameter subParameter = (TemplateParameter)parameter.getTemplateParms().getDeclarations().get(0); + assertEquals( subParameter.getKind(), TemplateParameter.k_class ); + assertEquals( subParameter.getName().toString(), "Y" ); + assertNull( subParameter.getTypeId() ); + + parameter = (TemplateParameter)declaration.getTemplateParms().getDeclarations().get(7); + assertEquals( parameter.getKind(), TemplateParameter.k_template ); + assertEquals( parameter.getTemplateParms().getDeclarations().size(), 1 ); + subParameter = (TemplateParameter)parameter.getTemplateParms().getDeclarations().get(0); + assertEquals( subParameter.getKind(), TemplateParameter.k_class ); + assertEquals( subParameter.getName().toString(), "A" ); + assertNull( subParameter.getTypeId() ); + assertEquals( parameter.getName().toString(), "AClass" ); + assertEquals( declaration.getDeclarations().size(), 1 ); + SimpleDeclaration myArray = (SimpleDeclaration)declaration.getDeclarations().get(0); + ClassSpecifier classSpec = (ClassSpecifier)myArray.getTypeSpecifier(); + assertEquals( classSpec.getClassKey(), ClassKey.t_class ); + assertEquals( classSpec.getName().toString(), "myarray"); + assertEquals( 0, classSpec.getDeclarations().size() ); + } + + public void testStruct() throws Exception + { + StringWriter writer = new StringWriter(); + writer.write( "struct mad_bitptr { unsigned char const *byte;\n" ); writer.write( "unsigned short cache;\n unsigned short left;};" ); + TranslationUnit tu = parse( writer.toString() ); + assertEquals( tu.getDeclarations().size(), 1 ); + SimpleDeclaration declaration = (SimpleDeclaration)tu.getDeclarations().get( 0 ); + ClassSpecifier classSpec = (ClassSpecifier)declaration.getTypeSpecifier(); + DeclSpecifier declSpec = declaration.getDeclSpecifier(); + assertEquals( classSpec.getClassKey(), ClassKey.t_struct ); + assertEquals( classSpec.getName().toString(), "mad_bitptr" ); + assertEquals( declaration.getDeclarators().size(), 0 ); + List subDeclarations = classSpec.getDeclarations(); + assertEquals( 3, subDeclarations.size() ); + declaration = (SimpleDeclaration)subDeclarations.get(0); + declSpec = declaration.getDeclSpecifier(); + assertTrue( declSpec.isUnsigned() ); + assertTrue( declSpec.isConst() ); + assertEquals( declSpec.getType(), DeclSpecifier.t_char ); + assertEquals( declaration.getDeclarators().size(), 1 ); + Declarator d = (Declarator)declaration.getDeclarators().get(0); + assertEquals( d.getPointerOperators().size(), 1 ); + PointerOperator po = (PointerOperator)d.getPointerOperators().get(0); + assertEquals( po.getType(), PointerOperator.t_pointer ); + assertFalse( po.isConst() ); + assertFalse(po.isVolatile() ); + assertEquals( d.getName().toString(), "byte" ); + + declaration = (SimpleDeclaration)subDeclarations.get(1); + declSpec = declaration.getDeclSpecifier(); + assertTrue( declSpec.isUnsigned()); + assertTrue( declSpec.isShort()); + assertEquals( declaration.getDeclarators().size(), 1 ); + d = (Declarator)declaration.getDeclarators().get(0); + assertEquals( d.getPointerOperators().size(), 0 ); + assertEquals( d.getName().toString(), "cache" ); + + + declaration = (SimpleDeclaration)subDeclarations.get(2); + declSpec = declaration.getDeclSpecifier(); + assertTrue( declSpec.isUnsigned()); + assertTrue( declSpec.isShort()); + assertEquals( declaration.getDeclarators().size(), 1 ); + d = (Declarator)declaration.getDeclarators().get(0); + assertEquals( d.getPointerOperators().size(), 0 ); + assertEquals( d.getName().toString(), "left" ); + } + + + public void testBug35906() throws Exception + { + StringWriter code = new StringWriter(); + code.write( "void TTest::MTest() {}\n" ); + code.write( "struct TTest::STest *TTest::FTest (int i) {}\n" ); + TranslationUnit tu = parse( code.toString() ); + assertEquals( tu.getDeclarations().size(), 2 ); + SimpleDeclaration declaration = (SimpleDeclaration)tu.getDeclarations().get(0); + assertEquals( declaration.getDeclSpecifier().getType(), DeclSpecifier.t_void ); + assertEquals( declaration.getDeclarators().size(), 1 ); + Declarator d = (Declarator)declaration.getDeclarators().get(0); + assertEquals( d.getName().toString(), "TTest::MTest"); + + declaration = (SimpleDeclaration)tu.getDeclarations().get(1); + ElaboratedTypeSpecifier spec = (ElaboratedTypeSpecifier)declaration.getTypeSpecifier(); + assertEquals( spec.getClassKey(), ClassKey.t_struct ); + assertEquals( spec.getName().toString(), "TTest::STest" ); + } + + public void testBug36073() throws Exception + { + StringWriter writer = new StringWriter(); + writer.write( "class A{\n" ); + writer.write( "int x;\n" ); + writer.write( "public:\n" ); + writer.write( "A(const A&);\n" ); + writer.write( "};\n" ); + writer.write( "A::A(const A&v) : x(v.x) { }\n" ); + TranslationUnit tu = parse( writer.toString() ); + } + + public void testBug36288() throws Exception + { + TranslationUnit tu = parse( "int foo() {}\nlong foo2(){}", true, true); + assertEquals( tu.getDeclarations().size(), 2 ); + for( int i = 0; i < 2; ++i ) + { + SimpleDeclaration declaration = (SimpleDeclaration)tu.getDeclarations().get(i); + assertEquals( declaration.getDeclarators().size(), 1 ); + Declarator d = (Declarator)declaration.getDeclarators().get(0); + assertEquals( d.getName().toString(), ( i == 0 ) ? "foo" : "foo2"); + assertEquals( declaration.getDeclSpecifier().getType(), (i == 0 ) ? DeclSpecifier.t_int : DeclSpecifier.t_type ); + assertEquals( declaration.getDeclSpecifier().isLong(), ( i == 0 ) ? false : true ); + } + } + + public void testBug36250() throws Exception + { + TranslationUnit tu = parse( "int f( int = 0 );"); + assertEquals( tu.getDeclarations().size(), 1 ); + SimpleDeclaration functionDeclaration = (SimpleDeclaration)tu.getDeclarations().get(0); + assertEquals( functionDeclaration.getDeclSpecifier().getType(), DeclSpecifier.t_int ); + assertEquals( functionDeclaration.getDeclarators().size(), 1 ); + Declarator functionDeclarator = (Declarator)functionDeclaration.getDeclarators().get(0); + assertEquals( functionDeclarator.getName().toString(), "f" ); + assertEquals( functionDeclarator.getParms().getDeclarations().size(), 1 ); + ParameterDeclaration parameterDeclaration = (ParameterDeclaration)functionDeclarator.getParms().getDeclarations().get(0); + assertEquals( parameterDeclaration .getDeclSpecifier().getType(), DeclSpecifier.t_int ); + assertEquals( parameterDeclaration .getDeclarators().size(), 1 ); + Declarator parameterDeclarator = (Declarator)parameterDeclaration.getDeclarators().get(0); + assertNull( parameterDeclarator.getName() ); + assertNotNull( parameterDeclarator.getExpression()); + + } + + public void testBug36240() throws Exception + { + TranslationUnit tu = parse( "A & A::operator=( A ){}"); + assertEquals( tu.getDeclarations().size(), 1 ); + SimpleDeclaration functionDeclaration = (SimpleDeclaration)tu.getDeclarations().get(0); + assertEquals( functionDeclaration.getDeclSpecifier().getType(), DeclSpecifier.t_type ); + assertEquals( functionDeclaration.getDeclSpecifier().getTypeName(), "A" ); + assertEquals( functionDeclaration.getDeclarators().size(), 1 ); + Declarator functionDeclarator = (Declarator)functionDeclaration.getDeclarators().get(0); + assertEquals( functionDeclarator.getPointerOperators().size(), 1 ); + PointerOperator po = (PointerOperator)functionDeclarator.getPointerOperators().get(0); + assertEquals( po.getType(), PointerOperator.t_reference ); + assertFalse( po.isConst() || po.isVolatile() ); + assertEquals( functionDeclarator.getName().toString(), "A::operator ="); + assertEquals( functionDeclarator.getParms().getDeclarations().size(), 1 ); + ParameterDeclaration parameterDeclaration = (ParameterDeclaration)functionDeclarator.getParms().getDeclarations().get(0); + assertEquals( parameterDeclaration.getDeclSpecifier().getType(), DeclSpecifier.t_type ); + assertEquals( parameterDeclaration.getDeclSpecifier().getTypeName(), "A"); + assertEquals( parameterDeclaration .getDeclarators().size(), 1 ); + Declarator parameterDeclarator = (Declarator)parameterDeclaration.getDeclarators().get(0); + assertNull( parameterDeclarator.getName() ); + } + + public void testBug36254() throws Exception + { + TranslationUnit tu = parse( "unsigned i;\nvoid f( unsigned p1 = 0 );"); + assertEquals( tu.getDeclarations().size(), 2 ); + SimpleDeclaration declaration = (SimpleDeclaration)tu.getDeclarations().get(0); + assertTrue( declaration.getDeclSpecifier().isUnsigned()); + assertEquals( 1, declaration.getDeclarators().size() ); + assertEquals( "i", ((Declarator)declaration.getDeclarators().get(0)).getName().toString() ); + declaration = (SimpleDeclaration)tu.getDeclarations().get(1); + assertEquals( declaration.getDeclSpecifier().getType(), DeclSpecifier.t_void ); + assertEquals( 1, declaration.getDeclarators().size() ); + Declarator declarator = (Declarator)declaration.getDeclarators().get(0); + assertEquals( declarator.getName().toString(), "f" ); + assertEquals( declarator.getParms().getDeclarations().size(), 1 ); + ParameterDeclaration parmDecl = (ParameterDeclaration)declarator.getParms().getDeclarations().get(0); + assertTrue( parmDecl.getDeclSpecifier().isUnsigned()); + assertEquals( parmDecl.getDeclarators().size(), 1 ); + Declarator parmDeclarator = (Declarator) parmDecl.getDeclarators().get(0); + assertEquals( parmDeclarator.getName().toString(), "p1"); + assertNotNull( parmDeclarator.getExpression()); + } + + public void testBug36237() throws Exception + { + TranslationUnit tu = parse( "A::A():B( (char *)0 ){}", true, true ); + assertEquals( tu.getDeclarations().size(), 1 ); + } + + public void testPointersToFunctions() throws Exception + { + Writer code = new StringWriter(); + code.write( "void (*name)( void );\n"); + code.write( "static void * (*orig_malloc_hook)(const char *file, int line, size_t size);\n"); + + TranslationUnit tu = parse( code.toString() ); + assertEquals( tu.getDeclarations().size(), 2 ); + SimpleDeclaration declaration = (SimpleDeclaration)tu.getDeclarations().get(0); + assertEquals( declaration.getDeclSpecifier().getType(), DeclSpecifier.t_void ); + assertEquals( declaration.getDeclarators().size(), 1); + assertNull( ((Declarator)declaration.getDeclarators().get(0)).getName() ); + assertNotNull( ((Declarator)declaration.getDeclarators().get(0)).getDeclarator() ); + assertEquals( ((Declarator)declaration.getDeclarators().get(0)).getDeclarator().getName().toString(), "name" ); + ParameterDeclarationClause clause = ((Declarator)declaration.getDeclarators().get(0)).getParms(); + assertEquals( clause.getDeclarations().size(), 1 ); + assertEquals( ((ParameterDeclaration)clause.getDeclarations().get(0)).getDeclarators().size(), 1 ); + assertNull( ((Declarator)((ParameterDeclaration)clause.getDeclarations().get(0)).getDeclarators().get(0)).getName() ); + assertEquals( ((ParameterDeclaration)clause.getDeclarations().get(0)).getDeclSpecifier().getType(), DeclSpecifier.t_void ); + + declaration = (SimpleDeclaration)tu.getDeclarations().get(1); + assertEquals( declaration.getDeclSpecifier().getType(), DeclSpecifier.t_void ); + assertTrue( declaration.getDeclSpecifier().isStatic() ); + assertEquals( declaration.getDeclarators().size(), 1); + assertNull( ((Declarator)declaration.getDeclarators().get(0)).getName() ); + assertNotNull( ((Declarator)declaration.getDeclarators().get(0)).getDeclarator() ); + assertEquals( ((Declarator)declaration.getDeclarators().get(0)).getDeclarator().getName().toString(), "orig_malloc_hook" ); + clause = ((Declarator)declaration.getDeclarators().get(0)).getParms(); + assertEquals( clause.getDeclarations().size(), 3 ); + } + + public void testBug36532() throws Exception + { + try + { + TranslationUnit tu = parse( "template class B {};\n" ); + code.write( "template<> class B {};\n" ); + code.write( "}\n" ); + TranslationUnit tu = parse( code.toString() ); + assertEquals( tu.getDeclarations().size(),1); + NamespaceDefinition definition = (NamespaceDefinition)tu.getDeclarations().get(0); + assertEquals( definition.getName().toString(), "myNameSpace"); + assertEquals( definition.getDeclarations().size(), 2 ); + TemplateDeclaration templateDeclaration = (TemplateDeclaration)definition.getDeclarations().get(0); + assertFalse( templateDeclaration.isExported()); + assertEquals( templateDeclaration.getTemplateParms().getDeclarations().size(), 1 ); + TemplateParameter parm = (TemplateParameter)templateDeclaration.getTemplateParms().getDeclarations().get(0); + assertEquals( parm.getKind(), TemplateParameter.k_typename ); + assertEquals( parm.getName().toString(), "T"); + assertEquals( parm.getTypeId().toString(), "short"); + assertEquals( templateDeclaration.getDeclarations().size(), 1 ); + SimpleDeclaration classB = (SimpleDeclaration)templateDeclaration.getDeclarations().get(0); + assertEquals( classB.getDeclarators().size(), 0 ); + assertEquals( ((ClassSpecifier)classB.getTypeSpecifier()).getName().toString(), "B" ); + assertEquals( ((ClassSpecifier)classB.getTypeSpecifier()).getClassKey(), ClassKey.t_class ); + assertEquals( ((ClassSpecifier)classB.getTypeSpecifier()).getDeclarations().size(), 0 ); + + ExplicitTemplateDeclaration etd = (ExplicitTemplateDeclaration)definition.getDeclarations().get(1); + assertEquals( etd.getKind(), ExplicitTemplateDeclaration.k_specialization ); + assertEquals( etd.getDeclarations().size(), 1 ); + classB = (SimpleDeclaration)etd.getDeclarations().get(0); + assertEquals( classB.getDeclarators().size(), 0 ); + assertEquals( ((ClassSpecifier)classB.getTypeSpecifier()).getName().toString(), "B" ); + assertEquals( ((ClassSpecifier)classB.getTypeSpecifier()).getClassKey(), ClassKey.t_class ); + assertEquals( ((ClassSpecifier)classB.getTypeSpecifier()).getDeclarations().size(), 0 ); + + } + + public void testBug36551() throws Exception + { + Writer code = new StringWriter(); + code.write( "class TextFrame {\n" ); + code.write( "BAD_MACRO()\n"); + code.write( "};"); + TranslationUnit tu = parse( code.toString(), true, false ); + assertFalse( tu.isParseSuccessful() ); + assertEquals( tu.getDeclarations().size(), 1 ); + SimpleDeclaration d = (SimpleDeclaration)tu.getDeclarations().get(0); + assertEquals( d.getDeclarators().size(), 0 ); + ClassSpecifier classSpec = (ClassSpecifier)d.getTypeSpecifier(); + assertEquals( classSpec.getClassKey(), ClassKey.t_class ); + assertEquals( classSpec.getName().toString(), "TextFrame"); + assertEquals( classSpec.getDeclarations().size(), 0 ); + + code = new StringWriter(); + code.write( "namespace X { class A }"); + tu = parse( code.toString(), true, false ); + assertFalse( tu.isParseSuccessful() ); + assertEquals( tu.getDeclarations().size(), 1 ); + NamespaceDefinition nd = (NamespaceDefinition)tu.getDeclarations().get(0); + assertEquals( nd.getDeclarations().size(), 0 ); + assertEquals( nd.getName().toString(), "X"); + + code = new StringWriter(); + code.write( "extern \"C\" { JUNK }" ); + tu = parse( code.toString(), true, false ); + assertFalse( tu.isParseSuccessful() ); + assertEquals( tu.getDeclarations().size(), 1 ); + LinkageSpecification ls = (LinkageSpecification)tu.getDeclarations().get(0); + assertEquals( ls.getDeclarations().size(), 0); + assertEquals( ls.getLanguageLinkage(), "C" ); + } + + public void testBug36692() throws Exception { + Writer code = new StringWriter(); + code.write("template \n"); + code.write("void SetLongevity(T* pDynObject, unsigned int longevity,\n"); + code.write("Destroyer d = Private::Deleter::Delete){}\n"); + + TranslationUnit tu = parse(code.toString()); + assertEquals( tu.getDeclarations().size(), 1 ); + TemplateDeclaration template = (TemplateDeclaration)tu.getDeclarations().get(0); + assertFalse( template.isExported() ); + TemplateParameterList list = template.getTemplateParms(); + assertEquals( list.getDeclarations().size(), 2 ); + for( int i = 0; i < 2; ++i ) + { + TemplateParameter parameter = (TemplateParameter)list.getDeclarations().get(i); + assertEquals( parameter.getName().toString(), i == 0 ? "T": "Destroyer"); + assertEquals( parameter.getKind(), TemplateParameter.k_typename ); + } + assertEquals( template.getDeclarations().size(), 1 ); + SimpleDeclaration method = (SimpleDeclaration)template.getDeclarations().get(0); + assertEquals( method.getDeclSpecifier().getType(), DeclSpecifier.t_void ); + assertEquals( method.getDeclarators().size(), 1 ); + assertEquals( method.isFunctionDefinition(), true ); + Declarator declarator = (Declarator)method.getDeclarators().get(0); + assertEquals( declarator.getName().toString(), "SetLongevity"); + ParameterDeclarationClause pdc = declarator.getParms(); + assertEquals( pdc.getDeclarations().size(), 3 ); + for( int i = 0; i < 3; ++i ) + { + ParameterDeclaration parameter = (ParameterDeclaration)pdc.getDeclarations().get(i); + assertEquals( parameter.getDeclarators().size(), 1 ); + Declarator parameterDeclarator = (Declarator)parameter.getDeclarators().get(0); + List pointers = parameterDeclarator.getPointerOperators(); + PointerOperator op = null; + Expression exp = parameterDeclarator.getExpression(); + switch( i ) + { + case 0: + assertEquals( parameterDeclarator.getName().toString(), "pDynObject"); + assertEquals( pointers.size(), 1 ); + op = (PointerOperator)pointers.get(0); + assertFalse( op.isConst()); + assertFalse( op.isVolatile()); + assertEquals( op.getType(), PointerOperator.t_pointer); + assertNull( exp ); + break; + case 1: + assertEquals( parameterDeclarator.getName().toString(), "longevity"); + assertEquals( pointers.size(), 0 ); + assertEquals( parameter.getDeclSpecifier().getType(), DeclSpecifier.t_int ); + assertTrue( parameter.getDeclSpecifier().isUnsigned() ); + assertNull( exp ); + break; + case 2: + assertEquals( parameterDeclarator.getName().toString(), "d"); + assertEquals( pointers.size(), 0 ); + assertNotNull( exp ); + break; + default: + break; + } + } + + } + + public void testBug36708() throws Exception { + TranslationUnit tu = parse("enum { isPointer = PointerTraits::result };"); + assertEquals( tu.getDeclarations().size(), 1 ); + SimpleDeclaration simple = (SimpleDeclaration)tu.getDeclarations().get(0); + assertEquals( simple.getDeclarators().size(), 0 ); + EnumerationSpecifier enum = (EnumerationSpecifier)simple.getTypeSpecifier(); + assertNull( enum.getName() ); + List enumerators = enum.getEnumeratorDefinitions(); + assertEquals( enumerators.size(), 1 ); + EnumeratorDefinition enumerator = (EnumeratorDefinition )enumerators.get(0); + assertEquals( enumerator.getName().toString(), "isPointer"); + assertNotNull( enumerator.getExpression() ); + } + + public void testBug36690() throws Exception { + TranslationUnit tu = parse("Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get())){}"); + assertEquals( tu.getDeclarations().size(), 1 ); + SimpleDeclaration simple = (SimpleDeclaration)tu.getDeclarations().get(0); + assertEquals( simple.getDeclarators().size(), 1 ); + Declarator declarator = (Declarator)simple.getDeclarators().get(0); + ParameterDeclarationClause pdc = declarator.getParms(); + assertEquals( pdc.getDeclarations().size(), 1 ); + ConstructorChain chain = declarator.getCtorChain(); + assertEquals( chain.getChainElements().size(), 1 ); + } + + public void testBug36703() throws Exception { + TranslationUnit tu = parse("const std::type_info& Get() const;"); + assertEquals( tu.getDeclarations().size(), 1 ); + SimpleDeclaration simple = (SimpleDeclaration)tu.getDeclarations().get(0); + assertEquals( simple.getDeclSpecifier().isConst(), true ); + assertEquals( simple.getDeclSpecifier().getType(), DeclSpecifier.t_type); + assertEquals( simple.getDeclSpecifier().getTypeName(), "std::type_info"); + assertEquals( simple.getDeclarators().size(), 1 ); + Declarator declarator = (Declarator)simple.getDeclarators().get(0); + ParameterDeclarationClause pdc = declarator.getParms(); + assertTrue( declarator.isConst() ); + assertEquals( pdc.getDeclarations().size(), 0 ); + assertEquals( declarator.getName().toString(), "Get"); + assertEquals( declarator.getPointerOperators().size(), 1 ); + PointerOperator pointerOperator = (PointerOperator)declarator.getPointerOperators().get(0); + assertFalse( pointerOperator.isConst()); + assertFalse( pointerOperator.isVolatile()); + assertEquals( pointerOperator.getType(), PointerOperator.t_reference); + } + + public void testBug36689() throws Exception { + Writer code = new StringWriter(); + code.write("template\n"); + code.write("<\n"); + code.write("class AbstractFact,\n"); + code.write( + "template class Creator = OpNewFactoryUnit,\n"); + code.write("class TList = typename AbstractFact::ProductList\n"); + code.write(">\n"); + code.write("class ConcreteFactory\n"); + code.write(": public GenLinearHierarchy<\n"); + code.write( + "typename TL::Reverse::Result, Creator, AbstractFact>\n"); + code.write("{\n"); + code.write("public:\n"); + code.write( + "typedef typename AbstractFact::ProductList ProductList;\n"); + code.write("typedef TList ConcreteProductList;\n"); + code.write("};\n"); + TranslationUnit tu = parse(code.toString()); + } + + public void testBug36707() throws Exception { + TranslationUnit tu = + parse("enum { exists = sizeof(typename H::Small) == sizeof((H::Test(H::MakeT()))) };"); + } + + public void testBug36717() throws Exception { + TranslationUnit tu = parse("enum { eA = A::b };"); + } + + public void testBug36693() throws Exception { + TranslationUnit tu = + parse("FixedAllocator::Chunk* FixedAllocator::VicinityFind(void* p){}"); + } + + public void testBug36696() throws Exception { + Writer code = new StringWriter(); + code.write( + "template RefCounted(const RefCounted& rhs)\n"); + code.write( + ": pCount_(reinterpret_cast(rhs).pCount_) {}\n"); + TranslationUnit tu = parse(code.toString()); + } + + public void testBug36713() throws Exception { + Writer code = new StringWriter(); + code.write("A ( * const fPtr) (void *); \n"); + code.write("A (* const fPtr2) ( A * ); \n"); + TranslationUnit tu = parse(code.toString()); + assertEquals( tu.getDeclarations().size(), 2 ); + SimpleDeclaration simple = (SimpleDeclaration)tu.getDeclarations().get(0); + assertEquals( simple.getDeclarators().size(), 1) ; + Declarator top = (Declarator)simple.getDeclarators().get(0); + assertEquals( top.getPointerOperators().size(), 0 ); + assertNotNull( top.getDeclarator() ); + assertEquals( top.getDeclarator().getPointerOperators().size(), 1 ); + PointerOperator po = (PointerOperator)top.getDeclarator().getPointerOperators().get(0); + assertTrue( po.isConst()); + assertFalse( po.isVolatile()); + assertEquals( po.getType(), PointerOperator.t_pointer); + } + + public void testBug36794() throws Exception + { + TranslationUnit tu = parse( "template<> class allocator {};"); + Iterator i = tu.iterateOffsetableElements(); + while( i.hasNext() ) + assertNotNull( i.next() ); + } + + public void testBug36811() throws Exception + { + Writer code = new StringWriter(); + code.write( "using namespace std;\n" ); + code.write( "class Test {};" ); + TranslationUnit tu = parse( code.toString() ); + assertEquals( tu.getDeclarations().size(), 2 ); + Iterator i = tu.iterateOffsetableElements(); + while( i.hasNext() ) + assertNotNull( i.next() ); + } + + public void testBug36799() throws Exception + { + TranslationUnit tu = parse( "static const int __WORD_BIT = int(CHAR_BIT*sizeof(unsigned int));"); + assertEquals( tu.getDeclarations().size(), 1 ); + } + + public void testBug36852() throws Exception + { + Writer code = new StringWriter(); + code.write( "int CBT::senseToAllRect( double id_standardQuot = DOSE, double id_minToleranz =15.0,\n" ); + code.write( "double id_maxToleranz = 15.0, unsigned int iui_minY = 0, \n" ); + code.write( "unsigned int iui_maxY = HEIGHT );\n" ); + TranslationUnit tu = parse( code.toString() ); + } + + public void testBug36764() throws Exception + { + TranslationUnit tu = parse( "struct{ int x : 4; int y : 8; };" ); + assertEquals( tu.getDeclarations().size(), 1 ); + assertEquals( ((ClassSpecifier)((SimpleDeclaration)tu.getDeclarations().get(0)).getTypeSpecifier()).getDeclarations().size(), 2 ); + } + + public void testBug36702() throws Exception + { + Writer code = new StringWriter(); + code.write( "void mad_decoder_init(struct mad_decoder *, void *,\n" ); + code.write( " enum mad_flow (*)(void *, struct mad_stream *),\n" ); + code.write( " enum mad_flow (*)(void *, struct mad_header const *),\n" ); + code.write( " enum mad_flow (*)(void *,\n" ); + code.write( " struct mad_stream const *,\n" ); + code.write( " struct mad_frame *),\n" ); + code.write( " enum mad_flow (*)(void *,\n" ); + code.write( " struct mad_header const *,\n" ); + code.write( " struct mad_pcm *),\n" ); + code.write( " enum mad_flow (*)(void *,\n" ); + code.write( " struct mad_stream *,\n" ); + code.write( " struct mad_frame *),\n" ); + code.write( " enum mad_flow (*)(void *, void *, unsigned int *)\n" ); + code.write( ");\n" ); + + TranslationUnit tu = parse( code.toString() ); + + } + + public void testBug36771() throws Exception { + Writer code = new StringWriter(); + code.write("#include /**/ \"foo.h\"\n"); + + TranslationUnit tu = parse( code.toString(), true, true ); + + List includes = tu.getInclusions(); + + assertEquals( includes.size(), 1 ); + Inclusion include = (Inclusion)includes.get(0); + assertTrue( include.getName().equals("foo.h") ); + } + + public void testBug36714() throws Exception { + Writer code = new StringWriter(); + code.write("unsigned long a = 0UL;\n"); + code.write("unsigned long a2 = 0L; \n"); + + TranslationUnit tu = parse( code.toString() ); + } + + public void testBugFunctor758() throws Exception { + TranslationUnit tu = parse( "template Functor(Fun fun) : spImpl_(new FunctorHandler(fun)){}" ); + } + + public void testBug36932() throws Exception + { + TranslationUnit tu = parse( "A::A(): b( new int( 5 ) ), b( new B ), c( new int ) {}" ); + } + + public void testBug36704() throws Exception { + Writer code = new StringWriter(); + code.write( "template \n" ); + code.write( "struct Length< Typelist >\n" ); + code.write( "{\n" ); + code.write( "enum { value = 1 + Length::value };\n" ); + code.write( "};\n" ); + parse(code.toString()); + } + + public void testBug36699() throws Exception { + Writer code = new StringWriter(); + code.write( + "template < template class ThreadingModel = DEFAULT_THREADING,\n"); + code.write("std::size_t chunkSize = DEFAULT_CHUNK_SIZE,\n"); + code.write( + "std::size_t maxSmallObjectSize = MAX_SMALL_OBJECT_SIZE >\n"); + code.write("class SmallObject : public ThreadingModel<\n"); + code.write( + "SmallObject >\n"); + code.write("{};\n"); + parse(code.toString()); + } + + public void testBug36691() throws Exception { + Writer code = new StringWriter(); + code.write("template \n"); + code.write( + "typename H::template Rebind::Result& Field(H& obj)\n"); + code.write("{ return obj; }\n"); + parse(code.toString()); + } + + public void testOrder() throws Exception + { + Writer code = new StringWriter(); + code.write( "#define __SGI_STL_INTERNAL_ALGOBASE_H\n" ); + code.write( "#include \n" ); + code.write( "template \n" ); + code.write( "inline void swap(_Tp& __a, _Tp& __b) {\n" ); + code.write( "__STL_REQUIRES(_Tp, _Assignable);\n" ); + code.write( "_Tp __tmp = __a;\n" ); + code.write( "__a = __b;\n" ); + code.write( "__b = __tmp;\n" ); + code.write( "}\n" ); + + Iterator i = parse( code.toString(), true, true ).iterateOffsetableElements(); + assertTrue( i.hasNext() ); + assertTrue( i.next() instanceof Macro ); + assertTrue( i.hasNext() ); + assertTrue( i.next() instanceof Inclusion ); + assertTrue( i.hasNext() ); + assertTrue( i.next() instanceof Declaration ); + assertFalse( i.hasNext() ); + } + + public void testBug37019() throws Exception { + parse("static const A a( 1, 0 );"); + } + + public void testBug36766and36769A() throws Exception { + Writer code = new StringWriter(); + code.write("template \n"); + code.write("rope<_CharT, _Alloc>::rope(size_t __n, _CharT __c,\n"); + code.write("const allocator_type& __a): _Base(__a)\n"); + code.write("{}\n"); + parse(code.toString()); + } + + public void testBug36766and36769B() throws Exception { + Writer code = new StringWriter(); + code.write("template\n"); + code.write("bool _Rope_insert_char_consumer<_CharT>::operator()\n"); + code.write("(const _CharT* __leaf, size_t __n)\n"); + code.write("{}\n"); + parse(code.toString()); + } + + public void testBug36766and36769C() throws Exception { + Writer code = new StringWriter(); + code.write("template \n"); + code.write("_Rope_char_ref_proxy<_CharT, _Alloc>&\n"); + code.write( + "_Rope_char_ref_proxy<_CharT, _Alloc>::operator= (_CharT __c)\n"); + code.write("{}\n"); + parse(code.toString()); + } + + public void testBug36766and36769D() throws Exception { + Writer code = new StringWriter(); + code.write("template \n"); + code.write("rope<_CharT, _Alloc>::~rope()\n"); + code.write("{}\n"); + parse(code.toString()); + } + + public void testBug36932A() throws Exception { + parse("A::A( ) : var( new char [ (unsigned)bufSize ] ) {}"); + } + + public void testBug36932B() throws Exception { + parse(" p = new int; "); + parse(" p = new int(5); "); + parse(" p = new int(B); "); + parse(" p = new int(B,C); "); + parse(" p = new int[5]; "); + parse(" p = new int[5][10]; "); + parse(" p = new int[B]; "); + parse(" p = new int[B][C][D]; "); + + parse(" p = new A; "); + parse(" p = new A(5); "); + parse(" p = new A(B); "); + parse(" p = new A(B,C); "); + parse(" p = new A[5]; "); + parse(" p = new A[5][10]; "); + parse(" p = new A[B]; "); + parse(" p = new A[B][C][D]; "); + + parse(" p = new (int); "); + parse(" p = new (int)(5); "); + parse(" p = new (int)(B); "); + parse(" p = new (int)(B,C); "); + parse(" p = new (int)[5]; "); + parse(" p = new (int)[5][10]; "); + parse(" p = new (int)[B]; "); + parse(" p = new (int)[B][C][D]; "); + + parse(" p = new (A); "); + parse(" p = new (A)(5); "); + parse(" p = new (A)(B); "); + parse(" p = new (A)(B,C); "); + parse(" p = new (A)[5]; "); + parse(" p = new (A)[5][10]; "); + parse(" p = new (A)[B]; "); + parse(" p = new (A)[B][C][D]; "); + + parse(" p = new (0) int; "); + parse(" p = new (0) int(5); "); + parse(" p = new (0) int(B); "); + parse(" p = new (0) int(B,C); "); + parse(" p = new (0) int[5]; "); + parse(" p = new (0) int[5][10]; "); + parse(" p = new (0) int[B]; "); + parse(" p = new (0) int[B][C][D]; "); + + parse(" p = new (0) A; "); + parse(" p = new (0) A(5); "); + parse(" p = new (0) A(B); "); + parse(" p = new (0) A(B,C); "); + parse(" p = new (0) A[5]; "); + parse(" p = new (0) A[5][10]; "); + parse(" p = new (0) A[B]; "); + parse(" p = new (0) A[B][C][D]; "); + + parse(" p = new (0) (int); "); + parse(" p = new (0) (int)(5); "); + parse(" p = new (0) (int)(B); "); + parse(" p = new (0) (int)(B,C); "); + parse(" p = new (0) (int)[5]; "); + parse(" p = new (0) (int)[5][10]; "); + parse(" p = new (0) (int)[B]; "); + parse(" p = new (0) (int)[B][C][D]; "); + + parse(" p = new (0) (A); "); + parse(" p = new (0) (A)(5); "); + parse(" p = new (0) (A)(B); "); + parse(" p = new (0) (A)(B,C); "); + parse(" p = new (0) (A)[5]; "); + parse(" p = new (0) (A)[5][10]; "); + parse(" p = new (0) (A)[B]; "); + parse(" p = new (0) (A)[B][C][D]; "); + + parse(" p = new (P) int; "); + parse(" p = new (P) int(5); "); + parse(" p = new (P) int(B); "); + parse(" p = new (P) int(B,C); "); + parse(" p = new (P) int[5]; "); + parse(" p = new (P) int[5][10]; "); + parse(" p = new (P) int[B]; "); + parse(" p = new (P) int[B][C][D]; "); + + parse(" p = new (P) A; "); + parse(" p = new (P) A(5); "); + parse(" p = new (P) A(B); "); + parse(" p = new (P) A(B,C); "); + parse(" p = new (P) A[5]; "); + parse(" p = new (P) A[5][10]; "); + parse(" p = new (P) A[B]; "); + parse(" p = new (P) A[B][C][D]; "); + + parse(" p = new (P) (int); "); + parse(" p = new (P) (int)(5); "); + parse(" p = new (P) (int)(B); "); + parse(" p = new (P) (int)(B,C); "); + parse(" p = new (P) (int)[5]; "); + parse(" p = new (P) (int)[5][10]; "); + parse(" p = new (P) (int)[B]; "); + parse(" p = new (P) (int)[B][C][D]; "); + + parse(" p = new (P) (A); "); + parse(" p = new (P) (A)(5); "); + parse(" p = new (P) (A)(B); "); + parse(" p = new (P) (A)(B,C); "); + parse(" p = new (P) (A)[5]; "); + parse(" p = new (P) (A)[5][10]; "); + parse(" p = new (P) (A)[B]; "); + parse(" p = new (P) (A)[B][C][D]; "); + } + + public void testBug36932C() throws Exception { + parse("X::X( ) : var( new int ) {}"); + parse("X::X( ) : var( new int(5) ) {}"); + parse("X::X( ) : var( new int(B) ) {}"); + parse("X::X( ) : var( new int(B,C) ) {}"); + parse("X::X( ) : var( new int[5] ) {}"); + parse("X::X( ) : var( new int[5][10] ) {}"); + parse("X::X( ) : var( new int[B] ) {}"); + parse("X::X( ) : var( new int[B][C][D] ) {}"); + + parse("X::X( ) : var( new A ) {}"); + parse("X::X( ) : var( new A(5) ) {}"); + parse("X::X( ) : var( new A(B) ) {}"); + parse("X::X( ) : var( new A(B,C) ) {}"); + parse("X::X( ) : var( new A[5] ) {}"); + parse("X::X( ) : var( new A[5][10] ) {}"); + parse("X::X( ) : var( new A[B] ) {}"); + parse("X::X( ) : var( new A[B][C][D] ) {}"); + + parse("X::X( ) : var( new (int) ) {}"); + parse("X::X( ) : var( new (int)(5) ) {}"); + parse("X::X( ) : var( new (int)(B) ) {}"); + parse("X::X( ) : var( new (int)(B,C) ) {}"); + parse("X::X( ) : var( new (int)[5] ) {}"); + parse("X::X( ) : var( new (int)[5][10] ) {}"); + parse("X::X( ) : var( new (int)[B] ) {}"); + parse("X::X( ) : var( new (int)[B][C][D] ) {}"); + + parse("X::X( ) : var( new (A) ) {}"); + parse("X::X( ) : var( new (A)(5) ) {}"); + parse("X::X( ) : var( new (A)(B) ) {}"); + parse("X::X( ) : var( new (A)(B,C) ) {}"); + parse("X::X( ) : var( new (A)[5] ) {}"); + parse("X::X( ) : var( new (A)[5][10] ) {}"); + parse("X::X( ) : var( new (A)[B] ) {}"); + parse("X::X( ) : var( new (A)[B][C][D] ) {}"); + + parse("X::X( ) : var( new (0) int ) {}"); + parse("X::X( ) : var( new (0) int(5) ) {}"); + parse("X::X( ) : var( new (0) int(B) ) {}"); + parse("X::X( ) : var( new (0) int(B,C) ) {}"); + parse("X::X( ) : var( new (0) int[5] ) {}"); + parse("X::X( ) : var( new (0) int[5][10] ) {}"); + parse("X::X( ) : var( new (0) int[B] ) {}"); + parse("X::X( ) : var( new (0) int[B][C][D] ) {}"); + + parse("X::X( ) : var( new (0) A ) {}"); + parse("X::X( ) : var( new (0) A(5) ) {}"); + parse("X::X( ) : var( new (0) A(B) ) {}"); + parse("X::X( ) : var( new (0) A(B,C) ) {}"); + parse("X::X( ) : var( new (0) A[5] ) {}"); + parse("X::X( ) : var( new (0) A[5][10] ) {}"); + parse("X::X( ) : var( new (0) A[B] ) {}"); + parse("X::X( ) : var( new (0) A[B][C][D] ) {}"); + + parse("X::X( ) : var( new (0) (int) ) {}"); + parse("X::X( ) : var( new (0) (int)(5) ) {}"); + parse("X::X( ) : var( new (0) (int)(B) ) {}"); + parse("X::X( ) : var( new (0) (int)(B,C) ) {}"); + parse("X::X( ) : var( new (0) (int)[5] ) {}"); + parse("X::X( ) : var( new (0) (int)[5][10] ) {}"); + parse("X::X( ) : var( new (0) (int)[B] ) {}"); + parse("X::X( ) : var( new (0) (int)[B][C][D] ) {}"); + + parse("X::X( ) : var( new (0) (A) ) {}"); + parse("X::X( ) : var( new (0) (A)(5) ) {}"); + parse("X::X( ) : var( new (0) (A)(B) ) {}"); + parse("X::X( ) : var( new (0) (A)(B,C) ) {}"); + parse("X::X( ) : var( new (0) (A)[5] ) {}"); + parse("X::X( ) : var( new (0) (A)[5][10] ) {}"); + parse("X::X( ) : var( new (0) (A)[B] ) {}"); + parse("X::X( ) : var( new (0) (A)[B][C][D] ) {}"); + + parse("X::X( ) : var( new (P) int ) {}"); + parse("X::X( ) : var( new (P) int(5) ) {}"); + parse("X::X( ) : var( new (P) int(B) ) {}"); + parse("X::X( ) : var( new (P) int(B,C) ) {}"); + parse("X::X( ) : var( new (P) int[5] ) {}"); + parse("X::X( ) : var( new (P) int[5][10] ) {}"); + parse("X::X( ) : var( new (P) int[B] ) {}"); + parse("X::X( ) : var( new (P) int[B][C][D] ) {}"); + + parse("X::X( ) : var( new (P) A ) {}"); + parse("X::X( ) : var( new (P) A(5) ) {}"); + parse("X::X( ) : var( new (P) A(B) ) {}"); + parse("X::X( ) : var( new (P) A(B,C) ) {}"); + parse("X::X( ) : var( new (P) A[5] ) {}"); + parse("X::X( ) : var( new (P) A[5][10] ) {}"); + parse("X::X( ) : var( new (P) A[B] ) {}"); + parse("X::X( ) : var( new (P) A[B][C][D] ) {}"); + + parse("X::X( ) : var( new (P) (int) ) {}"); + parse("X::X( ) : var( new (P) (int)(5) ) {}"); + parse("X::X( ) : var( new (P) (int)(B) ) {}"); + parse("X::X( ) : var( new (P) (int)(B,C) ) {}"); + parse("X::X( ) : var( new (P) (int)[5] ) {}"); + parse("X::X( ) : var( new (P) (int)[5][10] ) {}"); + parse("X::X( ) : var( new (P) (int)[B] ) {}"); + parse("X::X( ) : var( new (P) (int)[B][C][D] ) {}"); + + parse("X::X( ) : var( new (P) (A) ) {}"); + parse("X::X( ) : var( new (P) (A)(5) ) {}"); + parse("X::X( ) : var( new (P) (A)(B) ) {}"); + parse("X::X( ) : var( new (P) (A)(B,C) ) {}"); + parse("X::X( ) : var( new (P) (A)[5] ) {}"); + parse("X::X( ) : var( new (P) (A)[5][10] ) {}"); + parse("X::X( ) : var( new (P) (A)[B] ) {}"); + parse("X::X( ) : var( new (P) (A)[B][C][D] ) {}"); + } + + public void testBug36769A() throws Exception { + Writer code = new StringWriter(); + code.write("template cls::operator op &() const {}\n"); + code.write("template cls::cls() {}\n"); + code.write("template cls::~cls() {}\n"); + + parse( code.toString()); + } + + public void testBug36769B() throws Exception { + parse("class X { operator int(); } \n"); + parse("class X { operator int*(); } \n"); + parse("class X { operator int&(); } \n"); + parse("class X { operator A(); } \n"); + parse("class X { operator A*(); } \n"); + parse("class X { operator A&(); } \n"); + + parse("X::operator int() { } \n"); + parse("X::operator int*() { } \n"); + parse("X::operator int&() { } \n"); + parse("X::operator A() { } \n"); + parse("X::operator A*() { } \n"); + parse("X::operator A&() { } \n"); + + parse("template class X { operator int(); } \n"); + parse("template class X { operator int*(); } \n"); + parse("template class X { operator int&(); } \n"); + parse("template class X { operator A(); } \n"); + parse("template class X { operator A*(); } \n"); + parse("template class X { operator A&(); } \n"); + + parse("template X::operator int() { } \n"); + parse("template X::operator int*() { } \n"); + parse("template X::operator int&() { } \n"); + parse("template X::operator A() { } \n"); + parse("template X::operator A*() { } \n"); + parse("template X::operator A&() { } \n"); + } + + public void testBugSingleton192() throws Exception { + parse("int Test::* pMember_;" ); + } + + public void testPointersToMembers() throws Exception { + // Parse and get the translaton unit + TranslationUnit translationUnit = parse("int A::* x = 0;"); + + List tudeclarations = translationUnit.getDeclarations(); + assertEquals(1, tudeclarations.size()); + SimpleDeclaration decl1 = (SimpleDeclaration) tudeclarations.get(0); + assertEquals(decl1.getDeclSpecifier().getType(), DeclSpecifier.t_int); + + assertEquals(1, decl1.getDeclarators().size()); + + Declarator declarator1 = (Declarator) decl1.getDeclarators().get(0); + assertEquals(declarator1.getName().toString(), "x"); + Expression initValue1 = declarator1.getExpression(); + assertEquals(initValue1.elements().size(), 1); + List ptrOps1 = declarator1.getPointerOperators(); + assertNotNull(ptrOps1); + assertEquals(1, ptrOps1.size()); + PointerOperator po1 = (PointerOperator) ptrOps1.get(0); + assertNotNull(po1); + assertFalse(po1.isConst()); + assertFalse(po1.isVolatile()); + assertEquals(po1.getType(), PointerOperator.t_pointer_to_member); + assertEquals(po1.getNameSpecifier().toString(), "A::"); + } + + public void testPointersToMemberFunctions() throws Exception + { + TranslationUnit tu = parse("void (A::*name)(void);"); + assertEquals( tu.getDeclarations().size(), 1 ); + SimpleDeclaration declaration = (SimpleDeclaration)tu.getDeclarations().get(0); + assertEquals( declaration.getDeclSpecifier().getType(), DeclSpecifier.t_void ); + assertEquals( declaration.getDeclarators().size(), 1); + assertNull( ((Declarator)declaration.getDeclarators().get(0)).getName() ); + assertNotNull( ((Declarator)declaration.getDeclarators().get(0)).getDeclarator() ); + assertEquals( ((Declarator)declaration.getDeclarators().get(0)).getDeclarator().getName().toString(), "name" ); + ParameterDeclarationClause clause = ((Declarator)declaration.getDeclarators().get(0)).getParms(); + assertEquals( clause.getDeclarations().size(), 1 ); + assertEquals( ((ParameterDeclaration)clause.getDeclarations().get(0)).getDeclarators().size(), 1 ); + assertNull( ((Declarator)((ParameterDeclaration)clause.getDeclarations().get(0)).getDeclarators().get(0)).getName() ); + assertEquals( ((ParameterDeclaration)clause.getDeclarations().get(0)).getDeclSpecifier().getType(), DeclSpecifier.t_void ); + + List ptrOps1 = ((Declarator)declaration.getDeclarators().get(0)).getDeclarator().getPointerOperators(); + assertNotNull(ptrOps1); + assertEquals(1, ptrOps1.size()); + PointerOperator po1 = (PointerOperator) ptrOps1.get(0); + assertNotNull(po1); + assertFalse(po1.isConst()); + assertFalse(po1.isVolatile()); + assertEquals(po1.getType(), PointerOperator.t_pointer_to_member); + assertEquals(po1.getNameSpecifier().toString(), "A::"); + } + + public void testBug36290() throws Exception { + parse("typedef void ( A:: * pFunction ) ( void ); "); + parse("typedef void (boo) ( void ); "); + parse("typedef void boo (void); "); + } + + public void testBug36931() throws Exception { + parse("A::nested::nested(){}; "); + parse("int A::nested::foo() {} "); + parse("int A::nested::operator+() {} "); + parse("A::nested::operator int() {} "); + parse("static const int A::nested::i = 1; "); + + parse("template A::nested::nested(){}; "); + parse("template int A::nested::foo() {} "); + parse("template int A::nested::operator+() {} "); + parse("template A::nested::operator int() {} "); + } + +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ExprEvalTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ExprEvalTest.java new file mode 100644 index 00000000000..19a192d510d --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ExprEvalTest.java @@ -0,0 +1,42 @@ +package org.eclipse.cdt.core.parser.tests; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.parser.IParser; +import org.eclipse.cdt.internal.core.parser.ExpressionEvaluator; +import org.eclipse.cdt.internal.core.parser.Parser; + +public class ExprEvalTest extends TestCase { + + public static Test suite() { + return new TestSuite(ExprEvalTest.class); + } + + public ExprEvalTest(String name) { + super(name); + } + + public void runTest(String code, int expectedValue) throws Exception { + ExpressionEvaluator evaluator = new ExpressionEvaluator(); + IParser parser = new Parser(code, evaluator); + parser.expression(null); + assertEquals(expectedValue, ((Integer)evaluator.getResult()).intValue()); + } + + public void testInteger() throws Exception { + runTest("5;", 5); + } + + public void testRelational() throws Exception { + runTest("1 < 2;", 1); + runTest("2 < 1;", 0); + runTest("2 == 1 + 1;", 1); + runTest("2 != 1 + 1;", 0); + } + + public void testBracketed() throws Exception { + runTest("2 * (3 + 4);", 14); + } +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/FractionalAutomatedTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/FractionalAutomatedTest.java new file mode 100644 index 00000000000..8420c4d7862 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/FractionalAutomatedTest.java @@ -0,0 +1,252 @@ +/******************************************************************************* + * Copyright (c) 2001 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Corp. - Rational Software - initial implementation + ******************************************************************************/ +package org.eclipse.cdt.core.parser.tests; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.StringWriter; +import java.util.NoSuchElementException; +import java.util.StringTokenizer; + +import junit.framework.Test; + +import org.eclipse.cdt.internal.core.parser.Parser; +import org.eclipse.core.runtime.Path; + +/** + * @author aniefer + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public class FractionalAutomatedTest extends AutomatedFramework { + + public FractionalAutomatedTest() { + super(); + } + + public FractionalAutomatedTest(String name) { + super(name); + } + + protected AutomatedFramework newTest( String name ){ + return new FractionalAutomatedTest( name ); + } + protected void loadProperties() throws Exception{ + String resourcePath = org.eclipse.core.runtime.Platform.getPlugin("org.eclipse.cdt.core.tests").find(new Path("/")).getFile(); + resourcePath += "resources/parser/AutomatedTest"; + + try{ + FileInputStream propertiesIn = new FileInputStream( resourcePath + "/FractionalAutomatedTest.properties"); + properties.load( propertiesIn ); + + outputFile = properties.getProperty( "outputFile", "" ); + String sourceInfo = properties.getProperty( "source", "" ); + + stepSize = Integer.parseInt( properties.getProperty( "stepSize", "50" ) ); + windowSize = Integer.parseInt( properties.getProperty( "windowSize", "200" ) ); + timeOut = Integer.parseInt( properties.getProperty( "timeOut", "5000" )); + outputDir = properties.getProperty( "outDir", "" ); + + if( sourceInfo.equals("") ) + throw new FileNotFoundException(); + else{ + StringTokenizer tokenizer = new StringTokenizer( sourceInfo, "," ); + String str = null, val = null; + try{ + while( tokenizer.hasMoreTokens() ){ + str = tokenizer.nextToken().trim(); + val = tokenizer.nextToken().trim(); + + testSources.put( str, val ); + } + } catch ( NoSuchElementException e ){ + //only way to get here is to have a missing val, assume cpp for that str + testSources.put( str, "cpp" ); + } + + } + } catch ( FileNotFoundException e ){ + testSources.put( resourcePath + "/defaultCpp", "cpp" ); + testSources.put( resourcePath + "/defaultC", "c" ); + } + } + + public static Test suite() + { + AutomatedFramework frame = new FractionalAutomatedTest(); + + return frame.createSuite(); + } + + static private String outputFile( String code ) { + if( outputDir == null || outputDir.equals("") ) + return ""; + + File output = new File( outputDir ); + + try{ + if( output.exists() ){ + if( output.isFile() ){ + output.delete(); + output.createNewFile(); + FileOutputStream stream = new FileOutputStream( output ); + stream.write( code.getBytes() ); + stream.flush(); + stream.close(); + return outputDir; + } + } else { + output.mkdir(); + } + File file = new File( outputDir + "/" + failures++ + ".tmp" ); + if( file.exists() ) + file.delete(); + file.createNewFile(); + FileOutputStream stream = new FileOutputStream( file ); + stream.write( code.getBytes() ); + stream.flush(); + stream.close(); + + return file.getCanonicalPath(); + + } catch ( Exception e ) + {} + return ""; + } + + static public void reportHang( String code, String file ){ + String output = outputFile( code.toString() ); + if( output.equals("") ) + output = "Parser hang while parsing " + file + "\n"; + else + output = "Parser hang while parsing " + output + "\n"; + + if( report != null ){ + try{ + report.write( output.getBytes() ); + } catch ( IOException e ) {} + } + + fail( output ); + } + + static public void reportException( String code, String file, String exception ){ + String output = outputFile( code.toString() ); + + if( output.equals("") ) + output = exception.getClass().toString() + " encountered in " + file + "\n"; + else + output = exception.getClass().toString() + " encountered in " + output + "\n"; + + if( report != null ){ + try{ + report.write( output.getBytes() ); + } catch ( IOException e ) {} + } + + fail( output ); + } + + public void doFile() throws Throwable { + assertNotNull( fileList ); + + File file = (File)fileList.removeFirst(); + FileInputStream stream = new FileInputStream( file ); + + String filePath = file.getCanonicalPath(); + String nature = (String)natures.get( filePath ); + + boolean cppNature = nature.equalsIgnoreCase("cpp"); + + StringWriter code = new StringWriter(); + + ParseThread thread = new ParseThread(); + + byte b[] = new byte[stepSize]; + int n = stream.read( b ); + while( n != -1 ){ + code.write( new String( b ) ); + + thread.code = code.toString(); + thread.cppNature = cppNature; + thread.start(); + thread.join( timeOut ); + + if( thread.isAlive() ){ + //Use deprecated Thread.stop() for now + //alternative is to create a callback which could stop the parse on a flag + //by throwing something, but that has the disadvantage of being unable to + //stop any loops that don't involve callbacks. + thread.stop(); + reportHang( code.toString(), filePath ); + } else if( thread.result != null ) { + reportException( code.toString(), filePath, thread.result ); + } + + n = stream.read( b ); + } + + String fullCode = code.toString(); + String windowedCode = null; + int length = fullCode.length(); + int curPos = 0; + + while( curPos + windowSize < length){ + windowedCode = fullCode.substring( 0, curPos ); + windowedCode += "\n" + fullCode.substring( curPos + windowSize, length ); + + thread.code = windowedCode; + thread.cppNature = cppNature; + thread.file = filePath; + thread.start(); + thread.join( timeOut ); + + if( thread.isAlive() ) + { + thread.stop(); + reportHang( windowedCode, filePath ); + } else if( thread.result != null ) { + reportException( windowedCode, filePath, thread.result ); + } + + curPos += stepSize; + } + } + + static class ParseThread extends Thread{ + public String code; + public boolean cppNature; + public String file; + public String result; + + public void run(){ + try{ + result = null; + Parser parser = new Parser( code, nullCallback, true); + parser.setCppNature( cppNature ); + parser.mapLineNumbers(true); + parser.parse(); + } catch ( Exception e ){ + result = e.getClass().toString(); + } + } + } + + static protected int stepSize = 50; + static protected int windowSize = 200; + static protected int timeOut = 5000; + static protected String outputDir = null; + static protected int failures = 0; +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/LineNumberTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/LineNumberTest.java new file mode 100644 index 00000000000..9c4d37e5e91 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/LineNumberTest.java @@ -0,0 +1,156 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.core.parser.tests; + +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.Reader; +import java.io.StringReader; +import java.util.List; + +import junit.framework.TestCase; + +import org.eclipse.cdt.core.parser.IParser; +import org.eclipse.cdt.core.parser.IToken; +import org.eclipse.cdt.internal.core.dom.ClassSpecifier; +import org.eclipse.cdt.internal.core.dom.DOMBuilder; +import org.eclipse.cdt.internal.core.dom.EnumerationSpecifier; +import org.eclipse.cdt.internal.core.dom.IOffsetable; +import org.eclipse.cdt.internal.core.dom.NamespaceDefinition; +import org.eclipse.cdt.internal.core.dom.SimpleDeclaration; +import org.eclipse.cdt.internal.core.dom.TemplateDeclaration; +import org.eclipse.cdt.internal.core.parser.Parser; +import org.eclipse.cdt.internal.core.parser.Scanner; +import org.eclipse.core.runtime.Path; + +/** + * @author jcamelon + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public class LineNumberTest extends TestCase { + + public LineNumberTest( String arg ) + { + super( arg ); + } + private InputStream fileIn; + + protected void setUp() throws Exception { + String fileName =org.eclipse.core.runtime.Platform.getPlugin("org.eclipse.cdt.core.tests").find(new Path("/")).getFile() + "resources/parser/LineNumberTest.h"; + fileIn = new FileInputStream(fileName); + } + + public void testLineNos() throws Exception + { + Scanner scanner = new Scanner(); + Reader reader = new StringReader( "int x = 3;\n foo\nfire\nfoe "); + scanner.initialize( reader, "string"); + scanner.mapLineNumbers(true); + IToken t = scanner.nextToken(); + assertEquals( t.getType(), IToken.t_int ); + assertEquals( scanner.getLineNumberForOffset(t.getOffset()), 1 ); + t = scanner.nextToken(); + assertEquals( t.getImage(), "x"); + assertEquals( scanner.getLineNumberForOffset(t.getOffset()), 1 ); + t = scanner.nextToken(); + assertEquals( t.getType(), IToken.tASSIGN ); + assertEquals( scanner.getLineNumberForOffset(t.getOffset()), 1 ); + t = scanner.nextToken(); + assertEquals( t.getImage(), "3" ); + assertEquals( scanner.getLineNumberForOffset(t.getOffset()), 1 ); + t = scanner.nextToken(); + assertEquals( t.getType(), IToken.tSEMI); + assertEquals( scanner.getLineNumberForOffset(t.getOffset()), 1 ); + for( int i = 2; i < 5; ++i ) + { + t = scanner.nextToken(); + assertEquals( t.getType(), IToken.tIDENTIFIER); + assertEquals( scanner.getLineNumberForOffset(t.getOffset()), i ); + } + + try { + t = scanner.nextToken(); + fail( "EOF"); + } + catch (Parser.EndOfFile e) { + assertEquals( scanner.getLineNumberForOffset(29), 4 ); + } + + } + + public void testDOMLineNos() throws Exception + { + DOMBuilder domBuilder = new DOMBuilder(); + IParser parser = new Parser( fileIn, domBuilder, true ); + parser.mapLineNumbers(true); + if( ! parser.parse() ) fail( "Parse of file failed"); + + List macros = domBuilder.getTranslationUnit().getMacros(); + List inclusions = domBuilder.getTranslationUnit().getInclusions(); + List declarations = domBuilder.getTranslationUnit().getDeclarations(); + + assertEquals( 3, macros.size() ); + assertEquals( 1, inclusions.size() ); + assertEquals( declarations.size(), 4 ); + validateLineNumbers( (IOffsetable)inclusions.get(0), 2, 2 ); + validateLineNumbers( (IOffsetable)macros.get(0), 5, 5 ); + validateLineNumbers( (IOffsetable)macros.get(1), 6, 6 ); + validateLineNumbers( (IOffsetable)macros.get(2), 30, 31 ); + + NamespaceDefinition namespaceDecl = (NamespaceDefinition)declarations.get(0); + validateLineNumbers( namespaceDecl, 8, 22 ); + List namespaceMembers = namespaceDecl.getDeclarations(); + assertEquals( namespaceMembers.size(), 1 ); + ClassSpecifier Hello = (ClassSpecifier)((SimpleDeclaration)namespaceMembers.get(0)).getTypeSpecifier(); + validateLineNumbers( Hello, 10, 21); + List classMembers = Hello.getDeclarations(); + assertEquals( classMembers.size(), 3 ); + for( int i = 0; i < 3; ++i ) + { + SimpleDeclaration memberDeclaration = (SimpleDeclaration)Hello.getDeclarations().get(i); + switch( i ) + { + case 0: + validateLineNumbers(memberDeclaration, 13, 13 ); + break; + case 1: + validateLineNumbers(memberDeclaration, 15, 15 ); + break; + case 2: + validateLineNumbers(memberDeclaration, 18, 20 ); + break; + default: + break; + } + } + + validateLineNumbers( (SimpleDeclaration)declarations.get(1), 25, 27); + validateLineNumbers( (TemplateDeclaration)declarations.get(2), 34, 35); + SimpleDeclaration d = (SimpleDeclaration)declarations.get(3); + validateLineNumbers( d, 38, 43); + validateLineNumbers( ((EnumerationSpecifier)d.getTypeSpecifier()), 38, 43); + + } + + protected void tearDown() throws Exception { + if( fileIn != null ) fileIn.close(); + } + + protected void validateLineNumbers( IOffsetable offsetable, int top, int bottom ) + { + assertNotNull( offsetable ); + assertEquals( offsetable.getTopLine(), top ); + assertEquals( offsetable.getBottomLine(), bottom ); + } +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java new file mode 100644 index 00000000000..edad17dd945 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserSymbolTableTest.java @@ -0,0 +1,2335 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * Rational Software - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.core.parser.tests; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; + +import junit.framework.TestCase; + +import org.eclipse.cdt.core.parser.ast.AccessVisibility; +import org.eclipse.cdt.internal.core.parser.ast.full.ASTCompilationUnit; +import org.eclipse.cdt.internal.core.parser.ast.full.IASTFCompilationUnit; +import org.eclipse.cdt.internal.core.parser.pst.IContainerSymbol; +import org.eclipse.cdt.internal.core.parser.pst.IDerivableContainerSymbol; +import org.eclipse.cdt.internal.core.parser.pst.IParameterizedSymbol; +import org.eclipse.cdt.internal.core.parser.pst.ISymbol; +import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable; +import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTableException; +import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Declaration; +import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.Mark; +import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.TemplateInstance; +import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.TypeInfo; +import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable.TypeInfo.PtrOp; + + + +/** + * @author aniefer + * + * To change this generated comment edit the template variable "typecomment": + * Window>Preferences>Java>Templates. + * To enable and disable the creation of type comments go to + * Window>Preferences>Java>Code Generation. + */ +public class ParserSymbolTableTest extends TestCase { + + public ParserSymbolTable table = null; + + public ParserSymbolTableTest( String arg ) + { + super( arg ); + } + + public ParserSymbolTable newTable(){ + table = new ParserSymbolTable(); + return table; + } + + /** + * testSimpleAdd. + * Add a declaration to the table and confirm it is there. + * + * @throws Exception + */ + public void testSimpleAdd() throws Exception{ + newTable(); //create the symbol table + + ISymbol x = table.newSymbol( "x" ); + IContainerSymbol compUnit = table.getCompilationUnit(); + compUnit.addSymbol( x ); + + Map declarations = compUnit.getContainedSymbols(); + assertEquals( 1, declarations.size() ); + + Iterator iter = declarations.values().iterator(); + ISymbol contained = (ISymbol) iter.next(); + + assertEquals( false, iter.hasNext() ); + assertEquals( x, contained ); + assertEquals( contained.getName(), "x" ); + } + + /** + * testSimpleLookup + * Add a declaration to the table, then look it up. + * @throws Exception + */ + public void testSimpleLookup() throws Exception{ + newTable(); //new symbol table + + ISymbol x = table.new Declaration( "x" ); + table.getCompilationUnit().addSymbol( x ); + + ISymbol look = table.getCompilationUnit().Lookup( "x" ); + + assertEquals( x, look ); + } + + public void testLookupNonExistant() throws Exception{ + newTable(); + + ISymbol look = table.getCompilationUnit().Lookup("boo"); + assertEquals( look, null ); + } + + public void testSimpleSetGetObject() throws Exception{ + newTable(); + + IContainerSymbol x = table.new Declaration("x"); + + IASTFCompilationUnit obj = new ASTCompilationUnit( x ); + x.setASTNode( obj ); + + table.getCompilationUnit().addSymbol( x ); + + ISymbol look = table.getCompilationUnit().Lookup( "x" ); + + assertEquals( look.getASTNode(), obj ); + } + + /** + * testHide + * test that a declaration in a scope hides declarations in containing + * scopes + * @throws Exception + */ + public void testHide() throws Exception{ + newTable(); + + ISymbol firstX = table.newSymbol("x"); + table.getCompilationUnit().addSymbol( firstX ); + + IDerivableContainerSymbol firstClass = table.newDerivableContainerSymbol("class"); + firstClass.setType( ParserSymbolTable.TypeInfo.t_class ); + table.getCompilationUnit().addSymbol( firstClass ); + + ISymbol look = firstClass.Lookup( "x" ); + assertEquals( look, firstX ); + + ISymbol secondX = table.newSymbol("x"); + firstClass.addSymbol( secondX ); + + look = firstClass.Lookup( "x" ); + assertEquals( look, secondX ); + + look = table.getCompilationUnit().Lookup( "x" ); + assertEquals( look, firstX ); + } + + /** + * testContainingScopeLookup + * test lookup of something declared in the containing scope + * @throws Exception + */ + public void testContainingScopeLookup() throws Exception{ + newTable(); + + ISymbol x = table.newSymbol("x"); + table.getCompilationUnit().addSymbol( x ); + + IDerivableContainerSymbol decl = table.newDerivableContainerSymbol("class"); + decl.setType( ParserSymbolTable.TypeInfo.t_class ); + table.getCompilationUnit().addSymbol( decl ); + + ISymbol look = decl.Lookup( "x" ); + + assertEquals( x, look ); + } + + /** + * testParentLookup + * test lookup of a variable declaration in the parent + * + * @throws Exception + */ + public void testParentLookup() throws Exception{ + newTable(); + + IDerivableContainerSymbol parent = table.newDerivableContainerSymbol("parent"); + parent.setType( ParserSymbolTable.TypeInfo.t_class ); + + IDerivableContainerSymbol class1 = table.newDerivableContainerSymbol("class"); + class1.setType( ParserSymbolTable.TypeInfo.t_class ); + class1.addParent( parent ); + + ISymbol decl = table.new Declaration("x"); + parent.addSymbol( decl ); + + table.getCompilationUnit().addSymbol( parent ); + table.getCompilationUnit().addSymbol( class1 ); + + ISymbol look = class1.Lookup( "x" ); + assertEquals( look, decl ); + } + + /** + * testAmbiguousParentLookup + * calls testParentLookup + * + * tests that if a variable is declared in two parents that the lookup + * returns an ambiguous result. + * + * @throws Exception + */ + public void testAmbiguousParentLookup() throws Exception{ + testParentLookup(); + + IDerivableContainerSymbol parent2 = table.newDerivableContainerSymbol("parent2"); + table.getCompilationUnit().addSymbol( parent2 ); + + IDerivableContainerSymbol class1 = (IDerivableContainerSymbol) table.getCompilationUnit().Lookup( "class" ); + class1.addParent( parent2 ); + + ISymbol decl = table.new Declaration("x"); + parent2.addSymbol( decl ); + + try{ + class1.Lookup( "x" ); + assertTrue( false ); + } + catch ( ParserSymbolTableException e ){ + assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous ); + } + } + + /** + * + * @throws Exception + * test for circular inheritance + */ + public void testCircularParentLookup() throws Exception{ + newTable(); + + IDerivableContainerSymbol a = table.newDerivableContainerSymbol("a"); + table.getCompilationUnit().addSymbol( a ); + + IDerivableContainerSymbol b = table.newDerivableContainerSymbol("b"); + b.addParent( a ); + table.getCompilationUnit().addSymbol( b ); + + a.addParent( b ); + + try{ + ISymbol look = a.Lookup("foo"); + assertTrue( false ); + } catch ( ParserSymbolTableException e) { + assertEquals( e.reason, ParserSymbolTableException.r_CircularInheritance ); + } + + } + /** + * testVirtualParentLookup + * + * @throws Exception + * tests lookup of name in virtual baseclass C + * + * C + * / \ + * A B + * \ / + * class + */ + public void testVirtualParentLookup() throws Exception{ + newTable(); + + IDerivableContainerSymbol decl = table.newDerivableContainerSymbol("class"); + IDerivableContainerSymbol c = table.newDerivableContainerSymbol("C"); + + IDerivableContainerSymbol a = table.newDerivableContainerSymbol("A"); + a.addParent( c, true, AccessVisibility.v_public ); + + IDerivableContainerSymbol b = table.newDerivableContainerSymbol("B"); + b.addParent( c, true, AccessVisibility.v_public ); + + decl.addParent( a ); + decl.addParent( b ); + + IContainerSymbol compUnit = table.getCompilationUnit(); + compUnit.addSymbol( c ); + + ISymbol x = table.new Declaration( "x" ); + c.addSymbol( x ); + + compUnit.addSymbol( decl ); + compUnit.addSymbol( a ); + compUnit.addSymbol( b ); + + ISymbol look = decl.Lookup( "x" ); + + assertEquals( look, x ); + } + + /** + * testAmbiguousVirtualParentLookup + * @throws Exception + * + * tests lookup of name in base class C in the following hierarchy + * C C + * / \ | + * A B D + * \ / / + * class + */ + public void testAmbiguousVirtualParentLookup() throws Exception{ + testVirtualParentLookup(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + IDerivableContainerSymbol cls = (IDerivableContainerSymbol) compUnit.Lookup("class"); + IDerivableContainerSymbol c = (IDerivableContainerSymbol) compUnit.Lookup("C"); + IDerivableContainerSymbol d = table.newDerivableContainerSymbol("D"); + + d.addParent( c ); + cls.addParent( d ); + + compUnit.addSymbol( d ); + + try{ + cls.Lookup( "x" ); + assertTrue( false ); + } + catch( ParserSymbolTableException e){ + assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous ); + } + } + + /** + * testStaticEnumParentLookup + * + * @throws Exception + * + * D D + * | | + * B C + * \ / + * A + * + * Things defined in D are not ambiguous if they are static or an enum + */ + public void testStaticEnumParentLookup() throws Exception{ + newTable(); + + IDerivableContainerSymbol a = table.newDerivableContainerSymbol("a" ); + IDerivableContainerSymbol b = table.newDerivableContainerSymbol( "b" ); + IDerivableContainerSymbol c = table.newDerivableContainerSymbol( "c" ); + IDerivableContainerSymbol d = table.newDerivableContainerSymbol( "d" ); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + compUnit.addSymbol( a ); + compUnit.addSymbol( b ); + compUnit.addSymbol( c ); + compUnit.addSymbol( d ); + + IContainerSymbol enum = table.new Declaration("enum"); + enum.setType( ParserSymbolTable.TypeInfo.t_enumeration ); + + ISymbol enumerator = table.new Declaration( "enumerator" ); + enumerator.setType( ParserSymbolTable.TypeInfo.t_enumerator ); + + ISymbol stat = table.new Declaration("static"); + stat.getTypeInfo().setBit( true, ParserSymbolTable.TypeInfo.isStatic ); + + ISymbol x = table.new Declaration("x"); + + d.addSymbol( enum ); + d.addSymbol( stat ); + d.addSymbol( x ); + + enum.addSymbol( enumerator ); + + a.addParent( b ); + a.addParent( c ); + b.addParent( d ); + c.addParent( d ); + + try{ + a.Lookup( "enumerator" ); + assertTrue( true ); + } + catch ( ParserSymbolTableException e){ + assertTrue( false ); + } + + try{ + a.Lookup( "static" ); + assertTrue( true ); + } + catch ( ParserSymbolTableException e){ + assertTrue( false ); + } + + try{ + a.Lookup( "x" ); + assertTrue( false ); + } + catch ( ParserSymbolTableException e){ + assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous ); + } + } + + /** + * testElaboratedLookup + * @throws Exception + * test lookup of hidden names using elaborated type spec + */ + public void testElaboratedLookup() throws Exception{ + newTable(); + + IDerivableContainerSymbol cls = table.newDerivableContainerSymbol( "class" ); + cls.setType( ParserSymbolTable.TypeInfo.t_class ); + + IDerivableContainerSymbol struct = table.newDerivableContainerSymbol("struct"); + struct.setType( ParserSymbolTable.TypeInfo.t_struct ); + + IContainerSymbol union = table.newContainerSymbol("union"); + union.setType( ParserSymbolTable.TypeInfo.t_union ); + + IDerivableContainerSymbol hideCls = table.newDerivableContainerSymbol( "class" ); + IDerivableContainerSymbol hideStruct = table.newDerivableContainerSymbol("struct"); + IContainerSymbol hideUnion = table.newContainerSymbol("union"); + + IDerivableContainerSymbol a = table.newDerivableContainerSymbol("a"); + IDerivableContainerSymbol b = table.newDerivableContainerSymbol("b"); + + a.addSymbol(hideCls); + a.addSymbol(hideStruct); + a.addSymbol(hideUnion); + + a.addParent( b ); + + b.addSymbol(cls); + b.addSymbol(struct); + b.addSymbol(union); + + table.getCompilationUnit().addSymbol( a ); + table.getCompilationUnit().addSymbol( b ); + + ISymbol look = a.ElaboratedLookup( ParserSymbolTable.TypeInfo.t_class, "class" ); + assertEquals( look, cls ); + look = a.ElaboratedLookup( ParserSymbolTable.TypeInfo.t_struct, "struct" ); + assertEquals( look, struct ); + look = a.ElaboratedLookup( ParserSymbolTable.TypeInfo.t_union, "union" ); + assertEquals( look, union ); + } + + /** + * testDeclarationType + * @throws Exception + * test the use of ParserSymbolTable.Declaration type in the scenario + * A a; + * a.member <=...>; + * where A was previously declared + */ + public void testDeclarationType() throws Exception{ + newTable(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + //pre-condition + IContainerSymbol A = table.newContainerSymbol("A"); + compUnit.addSymbol(A); + + ISymbol member = table.newSymbol("member"); + A.addSymbol(member); + + //at time of "A a;" + ISymbol look = compUnit.Lookup("A"); + assertEquals( look, A ); + ISymbol a = table.newSymbol("a"); + a.setTypeSymbol( look ); + compUnit.addSymbol( a ); + + //later "a.member" + look = compUnit.Lookup("a"); + assertEquals( look, a ); + IContainerSymbol type = (IContainerSymbol) look.getTypeSymbol(); + assertEquals( type, A ); + + look = type.Lookup("member"); + assertEquals( look, member ); + } + + /** + * + * @throws Exception + * + * struct stat { + * //... + * } + * int stat( struct stat* ); + * void f() + * { + * struct stat *ps; + * stat(ps); + * } + */ + public void testFunctionHidesClass() throws Exception{ + newTable(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + IDerivableContainerSymbol struct = table.newDerivableContainerSymbol("stat"); + struct.setType( ParserSymbolTable.TypeInfo.t_struct ); + compUnit.addSymbol( struct ); + + IParameterizedSymbol function = table.newParameterizedSymbol( "stat" ); + function.setType( ParserSymbolTable.TypeInfo.t_function ); + compUnit.addSymbol( function ); + + IParameterizedSymbol f = table.newParameterizedSymbol("f"); + f.setType( ParserSymbolTable.TypeInfo.t_function ); + compUnit.addSymbol( f ); + + ISymbol look = f.ElaboratedLookup( ParserSymbolTable.TypeInfo.t_struct, "stat" ); + assertEquals( look, struct ); + + look = f.Lookup( "stat" ); + assertEquals( look, function ); + } + + /** + * + * @throws Exception + * + * namespace A { + * int i; + * namespace B { + * namespace C{ + * int i; + * } + * using namespace A::B::C; + * void f1() { + * i = 5; //OK, C::i visible and hides A::i + * } + * } + * namespace D{ + * using namespace B; + * using namespace C; + * void f2(){ + * i = 5; //ambiguous, B::C and A::i + * } + * } + * void f3() { + * i = 5; //uses A::i + * } + * } + * void f4(){ + * i = 5; //no i is visible here + * } + * + */ + public void testUsingDirectives_1() throws Exception{ + newTable(); + + IContainerSymbol nsA = table.newContainerSymbol("A"); + nsA.setType( ParserSymbolTable.TypeInfo.t_namespace ); + table.getCompilationUnit().addSymbol( nsA ); + + ISymbol nsA_i = table.newSymbol("i"); + nsA.addSymbol( nsA_i ); + + IContainerSymbol nsB = table.newContainerSymbol("B"); + nsB.setType( ParserSymbolTable.TypeInfo.t_namespace ); + nsA.addSymbol( nsB ); + + IContainerSymbol nsC = table.newContainerSymbol("C"); + nsC.setType( ParserSymbolTable.TypeInfo.t_namespace ); + nsB.addSymbol( nsC ); + + ISymbol nsC_i = table.newSymbol("i"); + nsC.addSymbol( nsC_i ); + + ISymbol look = nsB.Lookup("C"); + assertEquals( look, nsC ); + nsB.addUsingDirective( nsC ); + + IParameterizedSymbol f1 = table.newParameterizedSymbol("f"); + f1.setType( ParserSymbolTable.TypeInfo.t_function ); + + nsB.addSymbol( f1 ); + + look = f1.Lookup( "i" ); + assertEquals( look, nsC_i ); //C::i visible and hides A::i + + IContainerSymbol nsD = table.newContainerSymbol("D"); + nsD.setType( ParserSymbolTable.TypeInfo.t_namespace ); + nsA.addSymbol( nsD ); + + look = nsD.Lookup("B"); + assertEquals( look, nsB ); + nsD.addUsingDirective( nsB ); + + look = nsD.Lookup("C"); + assertEquals( look, nsC ); + nsD.addUsingDirective( nsC ); + + IParameterizedSymbol f2 = table.newParameterizedSymbol( "f2" ); + f2.setType( ParserSymbolTable.TypeInfo.t_function ); + nsD.addSymbol( f2 ); + + try + { + look = f2.Lookup( "i" ); + assertTrue( false ); + } + catch ( ParserSymbolTableException e ) + { + //ambiguous B::C::i and A::i + assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous ); + } + + IParameterizedSymbol f3 = table.newParameterizedSymbol("f3"); + f3.setType( ParserSymbolTable.TypeInfo.t_function ); + nsA.addSymbol( f3 ); + + look = f3.Lookup("i"); + assertEquals( look, nsA_i ); //uses A::i + + IParameterizedSymbol f4 = table.newParameterizedSymbol("f4"); + f4.setType( ParserSymbolTable.TypeInfo.t_function ); + table.getCompilationUnit().addSymbol( f4 ); + + look = f4.Lookup("i"); + assertEquals( look, null );//neither i is visible here. + } + /** + * + * @throws Exception + * + * namespace M { + * int i; + * } + * namespace N { + * int i; + * using namespace M; + * } + * + * void f() { + * using namespace N; + * i = 7; //error, both M::i and N::i are visible + * N::i = 5; //ok, i directly declared in N, using M not + * considered (since this is a qualified lookup) + * } + * + */ + public void testTransitiveUsingDirective() throws Exception + { + newTable(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + IContainerSymbol nsM = table.newContainerSymbol( "M" ); + nsM.setType( ParserSymbolTable.TypeInfo.t_namespace ); + + compUnit.addSymbol( nsM ); + + ISymbol nsM_i = table.newSymbol("i"); + nsM.addSymbol( nsM_i ); + + IContainerSymbol nsN = table.newContainerSymbol( "N" ); + nsN.setType( ParserSymbolTable.TypeInfo.t_namespace ); + + compUnit.addSymbol( nsN ); + + ISymbol nsN_i = table.newSymbol("i"); + nsN.addSymbol( nsN_i ); + nsN.addUsingDirective( nsM ); + + IParameterizedSymbol f = table.newParameterizedSymbol("f"); + compUnit.addSymbol( f ); + + f.addUsingDirective( nsN ); + + ISymbol look = null; + try + { + look = f.Lookup( "i" ); + assertTrue( false ); + } + catch ( ParserSymbolTableException e ) + { + //ambiguous, both M::i and N::i are visible. + assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous ); + } + + look = f.LookupNestedNameSpecifier("N"); + look = ((IContainerSymbol) look).QualifiedLookup("i"); //ok + assertEquals( look, nsN_i ); + } + + /** + * + * @throws Exception + * The same declaration found more than once is not an ambiguity + * namespace A{ + * int a; + * } + * namespace B{ + * using namespace A; + * } + * namespace C{ + * using namespace A; + * } + * + * namespace BC{ + * using namespace B; + * using namespace C; + * } + * + * void f(){ + * BC::a++; //ok + * } + */ + public void testUsing_SameDeclarationTwice() throws Exception + { + newTable(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + IContainerSymbol nsA = table.newContainerSymbol("A"); + nsA.setType( ParserSymbolTable.TypeInfo.t_namespace ); + compUnit.addSymbol( nsA ); + + ISymbol a = table.newSymbol("a"); + nsA.addSymbol( a ); + + IContainerSymbol nsB = table.newContainerSymbol("B"); + nsB.setType( ParserSymbolTable.TypeInfo.t_namespace ); + compUnit.addSymbol( nsB ); + nsB.addUsingDirective( nsA ); + + IContainerSymbol nsC = table.newContainerSymbol("C"); + nsC.setType( ParserSymbolTable.TypeInfo.t_namespace ); + compUnit.addSymbol( nsC ); + nsC.addUsingDirective( nsA ); + + IContainerSymbol nsBC = table.newContainerSymbol("BC"); + nsBC.setType( ParserSymbolTable.TypeInfo.t_namespace ); + compUnit.addSymbol( nsBC ); + nsBC.addUsingDirective( nsB ); + nsBC.addUsingDirective( nsC ); + + IParameterizedSymbol f = table.newParameterizedSymbol("f"); + f.setType(ParserSymbolTable.TypeInfo.t_function); + compUnit.addSymbol( f ); + + ISymbol look = f.LookupNestedNameSpecifier("BC"); + assertEquals( look, nsBC ); + look = ((IContainerSymbol)look).QualifiedLookup("a"); + assertEquals( look, a ); + } + + /** + * + * @throws Exception + * + * namespace B { + * int b; + * } + * namespace A { + * using namespace B; + * int a; + * } + * namespace B { + * using namespace A; + * } + * + * void f(){ + * A::a++; //ok + * A::b++; //ok + * B::a++; //ok + * B::b++; //ok + * } + */ + public void testUsing_SearchedOnce() throws Exception + { + newTable(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + IContainerSymbol nsB = table.newContainerSymbol( "B" ); + nsB.setType( ParserSymbolTable.TypeInfo.t_namespace ); + compUnit.addSymbol( nsB ); + + ISymbol b = table.newSymbol("b"); + nsB.addSymbol( b ); + + IContainerSymbol nsA = table.newContainerSymbol( "A" ); + nsA.setType( ParserSymbolTable.TypeInfo.t_namespace ); + compUnit.addSymbol( nsA ); + + nsA.addUsingDirective( nsB ); + + ISymbol a = table.newSymbol("a"); + nsA.addSymbol( a ); + + nsB.addUsingDirective( nsA ); + + IParameterizedSymbol f = table.newParameterizedSymbol("f"); + compUnit.addSymbol(f); + + IContainerSymbol lookA = f.LookupNestedNameSpecifier("A"); + ISymbol look = lookA.QualifiedLookup("a"); + assertEquals( look, a ); + + look = lookA.QualifiedLookup("b"); + assertEquals( look, b ); + + IContainerSymbol lookB = f.LookupNestedNameSpecifier("B"); + look = lookB.QualifiedLookup("a"); + assertEquals( look, a ); + + look = lookB.QualifiedLookup("b"); + assertEquals( look, b ); + } + + /** + * we pass if we don't go into an infinite loop. + * TBD: we need a mechanism to detect failure of this + * test instead of just looping forever. + * + * @throws Exception + * + * namespace A{ + * } + * namespace B{ + * using namespace A; + * } + * namespace A{ + * using namespace B; + * } + * void f(){ + * using namespace A; + * using namespace B; + * i = 1; //not declared anywhere. + * } + */ + public void testUsing_SearchedOnce_2() throws Exception + { + newTable(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + IContainerSymbol nsA = table.newContainerSymbol( "A" ); + nsA.setType( ParserSymbolTable.TypeInfo.t_namespace ); + compUnit.addSymbol( nsA ); + + IContainerSymbol nsB = table.newContainerSymbol( "B" ); + nsB.setType( ParserSymbolTable.TypeInfo.t_namespace ); + compUnit.addSymbol( nsB ); + nsB.addUsingDirective( nsA ); + + nsA.addUsingDirective( nsB ); + + IParameterizedSymbol f = table.newParameterizedSymbol("f"); + compUnit.addSymbol(f); + f.addUsingDirective(nsA); + f.addUsingDirective(nsB); + + ISymbol look = f.Lookup("i"); + assertEquals( look, null ); + } + + /** + * During lookup of a qualified namespace member name, if the lookup finds + * more than one declaration of the member, non-type names hide class or + * enumeration names if and only if the declarations are from the same + * namespace + * @throws Exception + * + * namespace A { + * struct x { }; + * int x; + * int y; + * } + * namespace B { + * struct y { }; + * } + * + * namespace C { + * using namespace A; + * using namespace B; + * + * int i = C::x; //ok, finds A::x + * int j = C::y; //ambiguous, A::y or B::y + * } + */ + public void testNamespaceMemberHiding() throws Exception{ + newTable(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + IContainerSymbol nsA = table.newContainerSymbol("A"); + nsA.setType( ParserSymbolTable.TypeInfo.t_namespace ); + + compUnit.addSymbol( nsA ); + + IContainerSymbol structX = table.newContainerSymbol("x"); + structX.setType( ParserSymbolTable.TypeInfo.t_struct ); + nsA.addSymbol( structX ); + + ISymbol intX = table.newSymbol("x"); + intX.setType( ParserSymbolTable.TypeInfo.t_int ); + nsA.addSymbol( intX ); + + ISymbol intY = table.newSymbol("y"); + intY.setType( ParserSymbolTable.TypeInfo.t_int ); + nsA.addSymbol( intY ); + + IContainerSymbol nsB = table.newContainerSymbol("B"); + nsB.setType( ParserSymbolTable.TypeInfo.t_namespace ); + + compUnit.addSymbol( nsB ); + IContainerSymbol structY = table.newContainerSymbol("y"); + structY.setType( ParserSymbolTable.TypeInfo.t_struct ); + nsB.addSymbol( structY ); + + IContainerSymbol nsC = table.newContainerSymbol("C"); + nsC.setType( ParserSymbolTable.TypeInfo.t_namespace); + compUnit.addSymbol( nsC ); + + ISymbol look = nsC.Lookup("A"); + assertEquals( look, nsA ); + nsC.addUsingDirective( nsA ); + + look = nsC.Lookup("B"); + assertEquals( look, nsB ); + nsC.addUsingDirective( nsB ); + + //lookup C::x + look = nsC.LookupNestedNameSpecifier("C"); + assertEquals( look, nsC ); + look = ((IContainerSymbol)look).QualifiedLookup( "x" ); + assertEquals( look, intX ); + + //lookup C::y + look = nsC.LookupNestedNameSpecifier("C"); + assertEquals( look, nsC ); + + try{ + look = ((IContainerSymbol)look).QualifiedLookup( "y" ); + assertTrue(false); + } catch ( ParserSymbolTableException e ) { + assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous ); + } + } + + /** + * In a definition for a namespace member in which the declarator-id is a + * qualified-id, given that the qualified-id for the namespace member has + * the form "nested-name-specifier unqualified-id", the unqualified-id shall + * name a member of the namespace designated by the nested-name-specifier. + * + * namespace A{ + * namespace B{ + * void f1(int); + * } + * using namespace B; + * } + * void A::f1(int) { ... } //ill-formed, f1 is not a member of A + */ + public void testLookupMemberForDefinition() throws Exception{ + newTable(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + IContainerSymbol nsA = table.newContainerSymbol( "A" ); + nsA.setType( ParserSymbolTable.TypeInfo.t_namespace ); + compUnit.addSymbol( nsA ); + + IContainerSymbol nsB = table.newContainerSymbol( "B" ); + nsB.setType( ParserSymbolTable.TypeInfo.t_namespace ); + nsA.addSymbol( nsB ); + + IParameterizedSymbol f1 = table.newParameterizedSymbol("f1"); + f1.setType( ParserSymbolTable.TypeInfo.t_function ); + nsB.addSymbol( f1 ); + + nsA.addUsingDirective( nsB ); + + IContainerSymbol lookA = compUnit.LookupNestedNameSpecifier( "A" ); + assertEquals( nsA, lookA ); + + ISymbol look = lookA.LookupMemberForDefinition( "f1" ); + assertEquals( look, null ); + + //but notice if you wanted to do A::f1 as a function call, it is ok + look = lookA.QualifiedLookup( "f1" ); + assertEquals( look, f1 ); + } + + /** + * testUsingDeclaration + * @throws Exception + * 7.3.3-4 A using-declaration used as a member-declaration shall refer to a + * member of a base-class of the class being defined, shall refer to a + * member of an anonymous union that is a member of a base class of the + * class being defined or shall refer to an enumerator for an enumeration + * type that is a member of a base class of the class being defined + * + * struct B { + * void f( char ); + * enum E { e }; + * union { int x; }; + * }; + * class C { + * int g(); + * } + * struct D : B { + * using B::f; //ok, B is a base class of D + * using B::e; //ok, e is an enumerator in base class B + * using B::x; //ok, x is an union member of base class B + * using C::g; //error, C isn't a base class of D + * } + */ + public void testUsingDeclaration() throws Exception{ + newTable(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + IDerivableContainerSymbol B = table.newDerivableContainerSymbol("B"); + B.setType( ParserSymbolTable.TypeInfo.t_struct ); + compUnit.addSymbol( B ); + + IParameterizedSymbol f = table.newParameterizedSymbol("f"); + f.setType( ParserSymbolTable.TypeInfo.t_function ); + B.addSymbol( f ); + + IContainerSymbol E = table.newContainerSymbol( "E" ); + E.setType( ParserSymbolTable.TypeInfo.t_enumeration ); + B.addSymbol( E ); + + ISymbol e = table.newSymbol( "e" ); + e.setType( ParserSymbolTable.TypeInfo.t_enumerator ); + E.addSymbol( e ); + + /** + * TBD: Anonymous unions are not yet implemented + */ + + IDerivableContainerSymbol C = table.newDerivableContainerSymbol( "C" ); + C.setType( ParserSymbolTable.TypeInfo.t_class ); + compUnit.addSymbol( C ); + + IParameterizedSymbol g = table.newParameterizedSymbol( "g" ); + g.setType( ParserSymbolTable.TypeInfo.t_function ); + C.addSymbol( g ); + + IDerivableContainerSymbol D = table.newDerivableContainerSymbol( "D" ); + D.setType( ParserSymbolTable.TypeInfo.t_struct ); + ISymbol look = compUnit.Lookup( "B" ); + assertEquals( look, B ); + D.addParent( B ); + + compUnit.addSymbol( D ); + + IContainerSymbol lookB = D.LookupNestedNameSpecifier("B"); + assertEquals( lookB, B ); + + D.addUsingDeclaration( "f", lookB ); + D.addUsingDeclaration( "e", lookB ); + + //TBD anonymous union + //D.addUsingDeclaration( "x", lookB ); + + look = D.LookupNestedNameSpecifier("C"); + assertEquals( look, C ); + + try{ + D.addUsingDeclaration( "g", C ); + assertTrue( false ); + } + catch ( ParserSymbolTableException exception ){ + assertTrue( true ); + } + } + + /** + * testUsingDeclaration_2 + * @throws Exception + * 7.3.3-9 The entity declared by a using-declaration shall be known in the + * context using it according to its definition at the point of the using- + * declaration. Definitions added to the namespace after the using- + * declaration are not considered when a use of the name is made. + * + * namespace A { + * void f(int); + * } + * using A::f; + * + * namespace A { + * void f(char); + * } + * void foo(){ + * f('a'); //calls f( int ) + * } + * void bar(){ + * using A::f; + * f('a'); //calls f( char ); + * } + */ + public void testUsingDeclaration_2() throws Exception{ + newTable(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + ParserSymbolTable.Declaration A = table.new Declaration( "A" ); + A.setType( ParserSymbolTable.TypeInfo.t_namespace ); + compUnit.addSymbol( A ); + + ParserSymbolTable.Declaration f1 = table.new Declaration( "f" ); + f1.setType( ParserSymbolTable.TypeInfo.t_function ); + f1.setReturnType( table.newSymbol( "", TypeInfo.t_void ) ); + f1.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, null, false ); + A.addSymbol( f1 ); + + ISymbol look = compUnit.LookupNestedNameSpecifier("A"); + assertEquals( look, A ); + + IParameterizedSymbol usingF = (IParameterizedSymbol) compUnit.addUsingDeclaration( "f", A ); + + look = compUnit.Lookup("A"); + assertEquals( look, A ); + + IParameterizedSymbol f2 = table.newParameterizedSymbol("f"); + f2.setType( ParserSymbolTable.TypeInfo.t_function ); + f2.setReturnType( table.newSymbol( "", TypeInfo.t_void ) ); + f2.addParameter( ParserSymbolTable.TypeInfo.t_char, 0, null, false ); + + A.addSymbol( f2 ); + + IParameterizedSymbol foo = table.newParameterizedSymbol("foo"); + foo.setType( ParserSymbolTable.TypeInfo.t_function ); + compUnit.addSymbol( foo ); + + LinkedList paramList = new LinkedList(); + ParserSymbolTable.TypeInfo param = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_char, 0, null ); + paramList.add( param ); + + look = foo.UnqualifiedFunctionLookup( "f", paramList ); + assertEquals( look, usingF ); + assertTrue( usingF.hasSameParameters( f1 ) ); + + IParameterizedSymbol bar = table.newParameterizedSymbol( "bar" ); + bar.setType( ParserSymbolTable.TypeInfo.t_function ); + bar.addParameter( ParserSymbolTable.TypeInfo.t_char, 0, null, false ); + compUnit.addSymbol( bar ); + + look = bar.LookupNestedNameSpecifier( "A" ); + assertEquals( look, A ); + bar.addUsingDeclaration( "f", A ); + + look = bar.UnqualifiedFunctionLookup( "f", paramList ); + assertTrue( look != null ); + assertTrue( ((IParameterizedSymbol) look).hasSameParameters( f2 ) ); + } + + /** + * testThisPointer + * @throws Exception + * In the body of a nonstatic member function... the type of this of a class + * X is X*. If the member function is declared const, the type of this is + * const X*, if the member function is declared volatile, the type of this + * is volatile X*.... + */ + public void testThisPointer() throws Exception{ + newTable(); + + IContainerSymbol cls = table.newContainerSymbol("class"); + cls.setType( ParserSymbolTable.TypeInfo.t_class ); + + IParameterizedSymbol fn = table.newParameterizedSymbol("function"); + fn.setType( ParserSymbolTable.TypeInfo.t_function ); + fn.getTypeInfo().addPtrOperator( new PtrOp( PtrOp.t_undef, true, false ) ); + //fn.setCVQualifier( ParserSymbolTable.TypeInfo.cvConst ); + + table.getCompilationUnit().addSymbol( cls ); + cls.addSymbol( fn ); + + ISymbol look = fn.Lookup("this"); + assertTrue( look != null ); + + assertEquals( look.getType(), ParserSymbolTable.TypeInfo.t_type ); + assertEquals( look.getTypeSymbol(), cls ); + assertEquals( ((PtrOp)look.getPtrOperators().getFirst()).getType(), TypeInfo.PtrOp.t_pointer ); + assertTrue( ((PtrOp)look.getPtrOperators().getFirst()).isConst() ); + assertEquals( look.getContainingSymbol(), fn ); + } + + /** + * testEnumerator + * @throws Exception + * Following the closing brace of an enum-specifier, each enumerator has the + * type of its enumeration. + * The enum-name and each enumerator declared by an enum-specifier is + * declared in the scope that immediately contains the enum-specifier + */ + public void testEnumerator() throws Exception{ + newTable(); + + IContainerSymbol cls = table.newContainerSymbol("class"); + cls.setType( ParserSymbolTable.TypeInfo.t_class ); + + IContainerSymbol enumeration = table.newContainerSymbol("enumeration"); + enumeration.setType( ParserSymbolTable.TypeInfo.t_enumeration ); + + table.getCompilationUnit().addSymbol( cls ); + cls.addSymbol( enumeration ); + + ISymbol enumerator = table.newSymbol( "enumerator" ); + enumerator.setType( ParserSymbolTable.TypeInfo.t_enumerator ); + enumeration.addSymbol( enumerator ); + + ISymbol look = cls.Lookup( "enumerator" ); + assertEquals( look, enumerator ); + assertEquals( look.getContainingSymbol(), cls ); + assertEquals( look.getTypeSymbol(), enumeration ); + } + + /** + * + * @throws Exception + * + * namespace NS{ + * class T {}; + * void f( T ); + * } + * NS::T parm; + * int main(){ + * f( parm ); //ok, calls NS::f + * } + */ + public void testArgumentDependentLookup() throws Exception{ + newTable(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + IContainerSymbol NS = table.newContainerSymbol("NS"); + NS.setType( ParserSymbolTable.TypeInfo.t_namespace ); + + compUnit.addSymbol( NS ); + + IDerivableContainerSymbol T = table.newDerivableContainerSymbol("T"); + T.setType( ParserSymbolTable.TypeInfo.t_class ); + + NS.addSymbol( T ); + + IParameterizedSymbol f = table.newParameterizedSymbol("f"); + f.setType( ParserSymbolTable.TypeInfo.t_function ); + f.setReturnType( table.newSymbol( "", TypeInfo.t_void ) ); + + ISymbol look = NS.Lookup( "T" ); + assertEquals( look, T ); + f.addParameter( look, null, false ); + + NS.addSymbol( f ); + + look = compUnit.LookupNestedNameSpecifier( "NS" ); + assertEquals( look, NS ); + look = NS.QualifiedLookup( "T" ); + assertEquals( look, T ); + + ISymbol param = table.newSymbol("parm"); + param.setType( ParserSymbolTable.TypeInfo.t_type ); + param.setTypeSymbol( look ); + compUnit.addSymbol( param ); + + IParameterizedSymbol main = table.newParameterizedSymbol("main"); + main.setType( ParserSymbolTable.TypeInfo.t_function ); + main.setReturnType( table.newSymbol( "", TypeInfo.t_int ) ); + compUnit.addSymbol( main ); + + LinkedList paramList = new LinkedList(); + look = main.Lookup( "parm" ); + assertEquals( look, param ); + ParserSymbolTable.TypeInfo p = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, 0, look ); + paramList.add( p ); + + look = main.UnqualifiedFunctionLookup( "f", paramList ); + assertEquals( look, f ); + } + + /** + * testArgumentDependentLookup_2 + * @throws Exception + * in the following, NS2 is an associated namespace of class B which is an + * associated namespace of class A, so we should find f in NS2, we should + * not find f in NS1 because usings are ignored for associated scopes. + * + * + * namespace NS1{ + * void f( void * ){}; + * } + * namespace NS2{ + * using namespace NS1; + * class B {}; + * void f( void * ){}; + * } + * + * class A : public NS2::B {}; + * + * A a; + * f( &a ); + * + */ + public void testArgumentDependentLookup_2() throws Exception{ + newTable(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + IContainerSymbol NS1 = table.newContainerSymbol( "NS1" ); + NS1.setType( ParserSymbolTable.TypeInfo.t_namespace ); + + compUnit.addSymbol( NS1 ); + + ParserSymbolTable.Declaration f1 = table.new Declaration( "f" ); + f1.setType( ParserSymbolTable.TypeInfo.t_function ); + f1.setReturnType( table.newSymbol( "", TypeInfo.t_void ) ); + f1.addParameter( ParserSymbolTable.TypeInfo.t_void, 0, new PtrOp( PtrOp.t_pointer ), false ); + NS1.addSymbol( f1 ); + + IContainerSymbol NS2 = table.newContainerSymbol( "NS2" ); + NS2.setType( ParserSymbolTable.TypeInfo.t_namespace ); + + compUnit.addSymbol( NS2 ); + + ISymbol look = NS2.Lookup( "NS1" ); + assertEquals( look, NS1 ); + NS2.addUsingDirective( NS1 ); + + IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B" ); + B.setType( ParserSymbolTable.TypeInfo.t_class ); + NS2.addSymbol( B ); + + IParameterizedSymbol f2 = table.newParameterizedSymbol( "f" ); + f2.setType( ParserSymbolTable.TypeInfo.t_function ); + f2.setReturnType( table.newSymbol( "", TypeInfo.t_void ) ); + f2.addParameter( ParserSymbolTable.TypeInfo.t_void, 0, new PtrOp( PtrOp.t_pointer ), false ); + NS2.addSymbol( f2 ); + + IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A" ); + A.setType( ParserSymbolTable.TypeInfo.t_class ); + look = compUnit.LookupNestedNameSpecifier( "NS2" ); + assertEquals( look, NS2 ); + + look = NS2.QualifiedLookup( "B" ); + assertEquals( look, B ); + A.addParent( B ); + + compUnit.addSymbol( A ); + + look = compUnit.Lookup( "A" ); + assertEquals( look, A ); + ISymbol a = table.newSymbol( "a" ); + a.setType( ParserSymbolTable.TypeInfo.t_type ); + a.setTypeSymbol( look ); + compUnit.addSymbol( a ); + + LinkedList paramList = new LinkedList(); + look = compUnit.Lookup( "a" ); + assertEquals( look, a ); + ParserSymbolTable.TypeInfo param = new ParserSymbolTable.TypeInfo( look.getType(), 0, look, new PtrOp( PtrOp.t_reference ), false ); + paramList.add( param ); + + look = compUnit.UnqualifiedFunctionLookup( "f", paramList ); + assertEquals( look, f2 ); + } + + /** + * testFunctionOverloading + * @throws Exception + * Note that this test has been contrived to not strain the resolution as + * that aspect is not yet complete. + * + * class C + * { + * void foo( int i ); + * void foo( int i, char c ); + * void foo( int i, char c, C * ptr ); + * } + * + * C * c = new C; + * c->foo( 1 ); + * c->foo( 1, 'a' ); + * c->foo( 1, 'a', c ); + * + */ + + public void testFunctionOverloading() throws Exception{ + newTable(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + IDerivableContainerSymbol C = table.newDerivableContainerSymbol( "C" ); + C.setType( ParserSymbolTable.TypeInfo.t_class ); + compUnit.addSymbol(C); + + IParameterizedSymbol f1 = table.newParameterizedSymbol("foo"); + f1.setType( ParserSymbolTable.TypeInfo.t_function ); + f1.setReturnType( table.newSymbol( "", TypeInfo.t_void ) ); + f1.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, null, false ); + C.addSymbol( f1 ); + + IParameterizedSymbol f2 = table.newParameterizedSymbol("foo"); + f2.setType( ParserSymbolTable.TypeInfo.t_function ); + f2.setReturnType( table.newSymbol( "", TypeInfo.t_void ) ); + f2.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, null, false ); + f2.addParameter( ParserSymbolTable.TypeInfo.t_char, 0, null, false ); + C.addSymbol( f2 ); + + IParameterizedSymbol f3 = table.newParameterizedSymbol("foo"); + f3.setType( ParserSymbolTable.TypeInfo.t_function ); + f3.setReturnType( table.newSymbol( "", TypeInfo.t_void ) ); + f3.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, null, false ); + f3.addParameter( ParserSymbolTable.TypeInfo.t_char, 0, null, false ); + f3.addParameter( C, new PtrOp( PtrOp.t_pointer ), false ); + C.addSymbol( f3 ); + + ISymbol look = compUnit.Lookup("C"); + assertEquals( look, C ); + + ISymbol c = table.newSymbol("c"); + c.setType( ParserSymbolTable.TypeInfo.t_type ); + c.setTypeSymbol( look ); + c.addPtrOperator( new PtrOp( PtrOp.t_pointer, false, false ) ); + compUnit.addSymbol( c ); + + look = compUnit.Lookup( "c" ); + assertEquals( look, c ); + assertEquals( look.getTypeSymbol(), C ); + + LinkedList paramList = new LinkedList(); + + ParserSymbolTable.TypeInfo p1 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_int, 0, null ); + ParserSymbolTable.TypeInfo p2 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_char, 0, null ); + ParserSymbolTable.TypeInfo p3 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, 0, c ); + + paramList.add( p1 ); + look = C.MemberFunctionLookup( "foo", paramList ); + assertEquals( look, f1 ); + + paramList.add( p2 ); + look = C.MemberFunctionLookup( "foo", paramList ); + assertEquals( look, f2 ); + + paramList.add( p3 ); + look = C.MemberFunctionLookup( "foo", paramList ); + assertEquals( look, f3 ); + } + + /** + * + * @throws Exception + * test basic function resolution + * + * void f( int i ); + * void f( char c = 'c' ); + * + * f( 1 ); //calls f( int ); + * f( 'b' ); //calls f( char ); + * f(); //calls f( char ); + */ + public void testFunctionResolution() throws Exception{ + newTable(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + IParameterizedSymbol f1 = table.newParameterizedSymbol("f"); + f1.setType( ParserSymbolTable.TypeInfo.t_function ); + f1.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, null, false ); + compUnit.addSymbol( f1 ); + + IParameterizedSymbol f2 = table.newParameterizedSymbol("f"); + f2.setType( ParserSymbolTable.TypeInfo.t_function ); + f2.addParameter( ParserSymbolTable.TypeInfo.t_char, 0, null, true ); + compUnit.addSymbol( f2 ); + + LinkedList paramList = new LinkedList(); + ParserSymbolTable.TypeInfo p1 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_int, 0, null ); + paramList.add( p1 ); + + ISymbol look = compUnit.UnqualifiedFunctionLookup( "f", paramList ); + assertEquals( look, f1 ); + + paramList.clear(); + ParserSymbolTable.TypeInfo p2 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_char, 0, null ); + paramList.add( p2 ); + look = compUnit.UnqualifiedFunctionLookup( "f", paramList ); + assertEquals( look, f2 ); + + paramList.clear(); + ParserSymbolTable.TypeInfo p3 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_bool, 0, null ); + paramList.add( p3 ); + look = compUnit.UnqualifiedFunctionLookup( "f", paramList ); + assertEquals( look, f1 ); + + look = compUnit.UnqualifiedFunctionLookup( "f", null ); + assertEquals( look, f2 ); + } + + /** + * + * @throws Exception + * + * class A { }; + * class B : public A {}; + * class C : public B {}; + * + * void f ( A * ); + * void f ( B * ); + * + * A* a = new A(); + * C* c = new C(); + * + * f( a ); //calls f( A * ); + * f( c ); //calls f( B * ); + */ + public void testFunctionResolution_PointersAndBaseClasses() throws Exception{ + newTable(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A" ); + A.setType( ParserSymbolTable.TypeInfo.t_class ); + compUnit.addSymbol( A ); + + IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B" ); + B.setType( ParserSymbolTable.TypeInfo.t_class ); + B.addParent( A ); + compUnit.addSymbol( B ); + + IDerivableContainerSymbol C = table.newDerivableContainerSymbol( "C" ); + C.setType( ParserSymbolTable.TypeInfo.t_class ); + C.addParent( B ); + compUnit.addSymbol( C ); + + IParameterizedSymbol f1 = table.newParameterizedSymbol( "f" ); + f1.setType( ParserSymbolTable.TypeInfo.t_function ); + f1.addParameter( A, new PtrOp( PtrOp.t_pointer ), false ); + compUnit.addSymbol( f1 ); + + IParameterizedSymbol f2 = table.newParameterizedSymbol( "f" ); + f2.setType( ParserSymbolTable.TypeInfo.t_function ); + f2.addParameter( B, new PtrOp( PtrOp.t_pointer ), false ); + compUnit.addSymbol( f2 ); + + ISymbol a = table.newSymbol( "a" ); + a.setType( ParserSymbolTable.TypeInfo.t_type ); + a.setTypeSymbol( A ); + a.addPtrOperator( new PtrOp( PtrOp.t_pointer, false, false ) ); + + ISymbol c = table.newSymbol( "c" ); + c.setType( ParserSymbolTable.TypeInfo.t_type ); + c.setTypeSymbol( C ); + c.addPtrOperator( new PtrOp( PtrOp.t_pointer, false, false ) ); + + LinkedList paramList = new LinkedList(); + ParserSymbolTable.TypeInfo p1 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, 0, a ); + paramList.add( p1 ); + ISymbol look = compUnit.UnqualifiedFunctionLookup( "f", paramList ); + assertEquals( look, f1 ); + + paramList.clear(); + ParserSymbolTable.TypeInfo p2 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, 0, c ); + paramList.add( p2 ); + look = compUnit.UnqualifiedFunctionLookup( "f", paramList ); + assertEquals( look, f2 ); + } + + /** + * + * @throws Exception + * + * class A {}; + * typedef A * B; + * + * void f( A * ); + * void f( A ); + * + * A a; + * B b; + * A [] array; + * + * f( a ); //calls f( A ); + * f( &a ); //calls f( A * ); + * f( b ); //calls f( A * ); + * f( *b ); //calls f( A ); + * f( array ); //calls f( A * ); + */ + public void testFunctionResolution_TypedefsAndPointers() throws Exception{ + newTable(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A" ); + A.setType( ParserSymbolTable.TypeInfo.t_class ); + compUnit.addSymbol( A ); + + ISymbol B = table.newSymbol( "B" ); + B.setType( ParserSymbolTable.TypeInfo.t_type ); + B.setTypeSymbol( A ); + B.addPtrOperator( new PtrOp( PtrOp.t_pointer, false, false ) ); + compUnit.addSymbol( B ); + + IParameterizedSymbol f1 = table.newParameterizedSymbol( "f" ); + f1.setType( ParserSymbolTable.TypeInfo.t_function ); + f1.addParameter( A, new PtrOp( PtrOp.t_pointer ), false ); + compUnit.addSymbol( f1 ); + + IParameterizedSymbol f2 = table.newParameterizedSymbol( "f" ); + f2.setType( ParserSymbolTable.TypeInfo.t_function ); + f2.addParameter( A, null, false ); + compUnit.addSymbol( f2 ); + + ISymbol a = table.newSymbol( "a" ); + a.setType( ParserSymbolTable.TypeInfo.t_type ); + a.setTypeSymbol( A ); + compUnit.addSymbol( a ); + + ISymbol b = table.newSymbol( "b" ); + b.setType( ParserSymbolTable.TypeInfo.t_type ); + b.setTypeSymbol( B ); + compUnit.addSymbol( b ); + + ISymbol array = table.newSymbol( "array" ); + array.setType( ParserSymbolTable.TypeInfo.t_type ); + array.setTypeSymbol( A ); + array.addPtrOperator( new PtrOp( PtrOp.t_array, false, false ) ); + + LinkedList paramList = new LinkedList(); + ParserSymbolTable.TypeInfo p = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, 0, a ); + paramList.add( p ); + + ISymbol look = compUnit.UnqualifiedFunctionLookup( "f", paramList ); + assertEquals( look, f2 ); + + p.addPtrOperator( new PtrOp( PtrOp.t_reference, false, false ) ); + look = compUnit.UnqualifiedFunctionLookup( "f", paramList ); + assertEquals( look, f1 ); + + p.setTypeSymbol( b ); + p.getPtrOperators().clear(); + look = compUnit.UnqualifiedFunctionLookup( "f", paramList ); + assertEquals( look, f1 ); + + p.addPtrOperator( new PtrOp( PtrOp.t_pointer, false, false ) ); + look = compUnit.UnqualifiedFunctionLookup( "f", paramList ); + assertEquals( look, f2 ); + + p.setTypeSymbol( array ); + p.getPtrOperators().clear(); + look = compUnit.UnqualifiedFunctionLookup( "f", paramList ); + assertEquals( look, f1 ); + + } + + /** + * + * @throws Exception + * + * class A {}; + * + * class B + * { + * B( A a ){ }; + * }; + * + * void f( B b ){}; + * + * A a; + * f( a ); + */ + public void testUserDefinedConversionSequences() throws Exception{ + newTable(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A" ); + A.setType( ParserSymbolTable.TypeInfo.t_class ); + compUnit.addSymbol( A ); + + IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B" ); + B.setType( ParserSymbolTable.TypeInfo.t_class ); + compUnit.addSymbol( B ); + + //12.1-1 "Constructors do not have names" + IParameterizedSymbol constructor = table.newParameterizedSymbol(""); + constructor.setType( ParserSymbolTable.TypeInfo.t_function ); + constructor.addParameter( A, null, false ); + B.addSymbol( constructor ); + + IParameterizedSymbol f = table.newParameterizedSymbol( "f" ); + f.setType( ParserSymbolTable.TypeInfo.t_function ); + f.addParameter( B, null, false ); + compUnit.addSymbol( f ); + + ISymbol a = table.newSymbol( "a" ); + a.setType( ParserSymbolTable.TypeInfo.t_type ); + a.setTypeSymbol( A ); + compUnit.addSymbol( a ); + + LinkedList paramList = new LinkedList(); + ParserSymbolTable.TypeInfo p = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, 0, a ); + paramList.add( p ); + + ISymbol look = compUnit.UnqualifiedFunctionLookup( "f", paramList ); + assertEquals( look, f ); + } + + /** + * + * @throws Exception + * + * void f( const int *, short ); + * void f( int *, int ); + * + * int i; + * short s; + * + * void main() { + * f( &i, s ); //ambiguous because &i->int* is better than &i->const int * + * //but s-> short is better than s->int + * f( &i, 1L ); //calls f(int *, int) because &i->int* is better than &i->const int * + * //and 1L->short and 1L->int are indistinguishable + * f( &i, 'c' ); //calls f( int*, int) because &i->int * is better than &i->const int * + * //and c->int is better than c->short + * f( (const)&i, 1L ); //calls f(const int *, short ) because const &i->int* is better than &i->int * + * //and 1L->short and 1L->int are indistinguishable + * } + */ + public void testOverloadRanking() throws Exception{ + newTable(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + IParameterizedSymbol f1 = table.newParameterizedSymbol( "f" ); + f1.setType( ParserSymbolTable.TypeInfo.t_function ); + f1.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, new PtrOp( PtrOp.t_pointer, true, false ), false ); + f1.addParameter( ParserSymbolTable.TypeInfo.t_int, ParserSymbolTable.TypeInfo.isShort, null, false ); + + compUnit.addSymbol( f1 ); + + IParameterizedSymbol f2 = table.newParameterizedSymbol( "f" ); + f2.setType( ParserSymbolTable.TypeInfo.t_function ); + f2.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, new PtrOp( PtrOp.t_pointer ), false ); + f2.addParameter( ParserSymbolTable.TypeInfo.t_int, 0, null, false ); + compUnit.addSymbol( f2 ); + + ISymbol i = table.newSymbol( "i" ); + i.setType( ParserSymbolTable.TypeInfo.t_int ); + compUnit.addSymbol( i ); + + ISymbol s = table.newSymbol( "s" ); + s.setType( ParserSymbolTable.TypeInfo.t_int ); + s.getTypeInfo().setBit( true, ParserSymbolTable.TypeInfo.isShort ); + compUnit.addSymbol( s ); + + IParameterizedSymbol main = table.newParameterizedSymbol( "main" ); + main.setType( ParserSymbolTable.TypeInfo.t_function ); + compUnit.addSymbol( main ); + + LinkedList params = new LinkedList(); + ParserSymbolTable.TypeInfo p1 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, 0, i, new PtrOp( PtrOp.t_reference ), false ); + ParserSymbolTable.TypeInfo p2 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, 0, s ); + params.add( p1 ); + params.add( p2 ); + + ISymbol look = null; + + try{ + look = main.UnqualifiedFunctionLookup( "f", params ); + assertTrue( false ); + } catch ( ParserSymbolTableException e ){ + assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous ); + } + + params.clear(); + ParserSymbolTable.TypeInfo p3 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_int, ParserSymbolTable.TypeInfo.isLong, null ); + params.add( p1 ); + params.add( p3 ); + look = main.UnqualifiedFunctionLookup( "f", params ); + assertEquals( look, f2 ); + + params.clear(); + ParserSymbolTable.TypeInfo p4 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_char, 0, null ); + params.add( p1 ); + params.add( p4 ); + look = main.UnqualifiedFunctionLookup( "f", params ); + assertEquals( look, f2 ); + + params.clear(); + ((PtrOp)p1.getPtrOperators().getFirst()).setConst( true ); + params.add( p1 ); + params.add( p3 ); + look = main.UnqualifiedFunctionLookup( "f", params ); + assertEquals( look, f1 ); + + } + + /** + * + * @throws Exception + * + * class B; + * class A { A( B& ); }; + * class B { operator A(); }; + * + * void f(A){} + * + * B b; + * f( b ); //ambiguous because b->A via constructor or conversion + * + * class C { C( B& ); }; + * + * void f(C){} + * + * f( b ); //ambiguous because b->C via constructor and b->a via constructor/conversion + * + * void f(B){} + * + * f( b ); //calls f(B) + */ + + public void testUserDefinedConversionByOperator() throws Exception{ + newTable(); + + IContainerSymbol compUnit = table.getCompilationUnit(); + + IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B" ); + B.setType( ParserSymbolTable.TypeInfo.t_class ); + + compUnit.addSymbol( B ); + + IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A" ); + A.setType( ParserSymbolTable.TypeInfo.t_class ); + compUnit.addSymbol( A ); + + IParameterizedSymbol constructA = table.newParameterizedSymbol( "" ); + constructA.setType( ParserSymbolTable.TypeInfo.t_function ); + constructA.addParameter( B, new PtrOp( PtrOp.t_reference ), false ); + A.addSymbol( constructA ); + + IParameterizedSymbol operator = table.newParameterizedSymbol( "operator A" ); + operator.setType( ParserSymbolTable.TypeInfo.t_function ); + B.addSymbol( operator ); + + IParameterizedSymbol f1 = table.newParameterizedSymbol( "f" ); + f1.setType( ParserSymbolTable.TypeInfo.t_function ); + f1.addParameter( A, null, false ); + compUnit.addSymbol( f1 ); + + ISymbol b = table.newSymbol( "b" ); + b.setType( ParserSymbolTable.TypeInfo.t_type ); + b.setTypeSymbol( B ); + + LinkedList params = new LinkedList(); + ParserSymbolTable.TypeInfo p1 = new ParserSymbolTable.TypeInfo( ParserSymbolTable.TypeInfo.t_type, 0, b ); + params.add( p1 ); + + ISymbol look = null; + + try{ + look = compUnit.UnqualifiedFunctionLookup( "f", params ); + assertTrue( false ); + } catch( ParserSymbolTableException e ){ + assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous ); + } + + IDerivableContainerSymbol C = table.newDerivableContainerSymbol("C"); + C.setType( ParserSymbolTable.TypeInfo.t_class ); + compUnit.addSymbol( C ); + + IParameterizedSymbol constructC = table.newParameterizedSymbol(""); + constructC.setType( ParserSymbolTable.TypeInfo.t_function ); + constructC.addParameter( B, new PtrOp( PtrOp.t_reference ), false ); + C.addSymbol( constructC ); + + IParameterizedSymbol f2 = table.newParameterizedSymbol( "f" ); + f2.setType( ParserSymbolTable.TypeInfo.t_function ); + f2.addParameter( C, null, false ); + compUnit.addSymbol( f2 ); + + try{ + look = compUnit.UnqualifiedFunctionLookup( "f", params ); + assertTrue( false ); + } catch( ParserSymbolTableException e ){ + assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous ); + } + + IParameterizedSymbol f3 = table.newParameterizedSymbol( "f" ); + f3.setType( ParserSymbolTable.TypeInfo.t_function ); + f3.addParameter( B, null, false ); + compUnit.addSymbol( f3 ); + + look = compUnit.UnqualifiedFunctionLookup( "f", params ); + assertEquals( look, f3 ); + } + + public void testMarkRollback() throws Exception{ + newTable(); + + IDerivableContainerSymbol A = table.newDerivableContainerSymbol("A"); + A.setType( TypeInfo.t_class ); + table.getCompilationUnit().addSymbol( A ); + + Mark mark = table.setMark(); + + ISymbol f = table.newSymbol("f"); + A.addSymbol( f ); + + ISymbol look = A.Lookup("f"); + assertEquals( look, f ); + + assertTrue( table.rollBack( mark ) ); + + look = A.Lookup("f"); + assertEquals( look, null ); + + IDerivableContainerSymbol B = table.newDerivableContainerSymbol("B"); + B.setType( TypeInfo.t_class ); + + mark = table.setMark(); + table.getCompilationUnit().addSymbol( B ); + Mark mark2 = table.setMark(); + A.addParent( B ); + Mark mark3 = table.setMark(); + + IParameterizedSymbol C = table.newParameterizedSymbol("C"); + C.addParameter( TypeInfo.t_class, 0, null, false ); + + assertEquals( C.getParameterList().size(), 1 ); + table.rollBack( mark3 ); + assertEquals( C.getParameterList().size(), 0 ); + assertEquals( A.getParents().size(), 1 ); + table.rollBack( mark2 ); + assertEquals( A.getParents().size(), 0 ); + + assertFalse( table.commit( mark2 ) ); + assertFalse( table.rollBack( mark2 ) ); + + B.setType( TypeInfo.t_namespace ); + + mark = table.setMark(); + A.addUsingDirective( B ); + assertEquals( A.getUsingDirectives().size(), 1 ); + table.rollBack( mark ); + assertEquals( A.getUsingDirectives().size(), 0 ); + } + + /** + * + * @throws Exception + * + * template < class T > class A : public T {}; + * + * class B + * { + * int i; + * } + * + * A a; + * a.i; //finds B::i; + */ + public void testTemplateParameterAsParent() throws Exception{ + newTable(); + + IParameterizedSymbol template = table.newParameterizedSymbol( "A", TypeInfo.t_template ); + ISymbol param = table.newSymbol( "T", TypeInfo.t_undef ); + template.addParameter( param ); + + IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class ); + template.addSymbol( A ); + A.addParent( param ); + + table.getCompilationUnit().addSymbol( template ); + + IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class ); + ISymbol i = table.newSymbol( "i", TypeInfo.t_int ); + B.addSymbol( i ); + + TypeInfo type = new TypeInfo( TypeInfo.t_class, 0, B ); + LinkedList args = new LinkedList(); + args.add( type ); + + ParserSymbolTable.TemplateInstance instance = table.getCompilationUnit().TemplateLookup( "A", args ); + assertEquals( instance.getInstantiatedSymbol(), A ); + + ISymbol a = table.newSymbol( "a", TypeInfo.t_type ); + a.setTypeSymbol( instance ); + + table.getCompilationUnit().addSymbol( a ); + + ISymbol look = table.getCompilationUnit().Lookup( "a" ); + + assertEquals( look, a ); + + ISymbol symbol = a.getTypeSymbol(); + assertEquals( symbol, instance ); + + look = ((IContainerSymbol)instance.getInstantiatedSymbol()).Lookup( "i" ); + assertEquals( look, i ); + } + + /** + * + * @throws Exception + * + * template < class T > class A { T t; } + * class B : public A< int > { } + * + * B b; + * b.t; //finds A::t, will be type int + */ + public void testTemplateInstanceAsParent() throws Exception{ + newTable(); + + IParameterizedSymbol template = table.newParameterizedSymbol( "A", TypeInfo.t_template ); + ISymbol param = table.newSymbol( "T", TypeInfo.t_undef ); + template.addParameter( param ); + + IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class ); + ISymbol t = table.newSymbol( "t", TypeInfo.t_type ); + + ISymbol look = template.Lookup( "T" ); + assertEquals( look, param ); + + t.setTypeSymbol( param ); + + template.addSymbol( A ); + A.addSymbol( t ); + table.getCompilationUnit().addSymbol( template ); + + IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class ); + + TypeInfo type = new TypeInfo( TypeInfo.t_int, 0 , null ); + LinkedList args = new LinkedList(); + args.add( type ); + + look = table.getCompilationUnit().TemplateLookup( "A", args ); + assertTrue( look instanceof ParserSymbolTable.TemplateInstance ); + + B.addParent( look ); + table.getCompilationUnit().addSymbol( B ); + + ISymbol b = table.newSymbol( "b", TypeInfo.t_type ); + b.setTypeSymbol( B ); + table.getCompilationUnit().addSymbol( b ); + + look = table.getCompilationUnit().Lookup( "b" ); + assertEquals( look, b ); + + look = ((IDerivableContainerSymbol) b.getTypeSymbol()).Lookup( "t" ); + assertTrue( look instanceof TemplateInstance ); + + TemplateInstance instance = (TemplateInstance) look; + assertEquals( instance.getInstantiatedSymbol(), t ); + assertTrue( instance.isType( TypeInfo.t_int ) ); + + } + + /** + * The scope of a template-parameter extends from its point of declaration + * until the end of its template. In particular, a template parameter can be used + * in the declaration of a subsequent template-parameter and its default arguments. + * @throws Exception + * + * template< class T, class U = T > class X + * { + * T t; + * U u; + * }; + * + * X< char > x; + * x.t; + * x.u; + */ + public void testTemplateParameterDefaults() throws Exception{ + newTable(); + + IParameterizedSymbol template = table.newParameterizedSymbol( "X", TypeInfo.t_template ); + + ISymbol paramT = table.newSymbol( "T", TypeInfo.t_undef ); + template.addParameter( paramT ); + + ISymbol look = template.Lookup( "T" ); + assertEquals( look, paramT ); + ISymbol paramU = table.newSymbol( "U", TypeInfo.t_undef ); + paramU.getTypeInfo().setDefault( new TypeInfo( TypeInfo.t_type, 0, look ) ); + template.addParameter( paramU ); + + IDerivableContainerSymbol X = table.newDerivableContainerSymbol( "X", TypeInfo.t_class ); + template.addSymbol( X ); + + look = X.Lookup( "T" ); + assertEquals( look, paramT ); + ISymbol t = table.newSymbol( "t", TypeInfo.t_type ); + t.setTypeSymbol( look ); + X.addSymbol( t ); + + look = X.Lookup( "U" ); + assertEquals( look, paramU ); + ISymbol u = table.newSymbol( "u", TypeInfo.t_type ); + u.setTypeSymbol( look ); + X.addSymbol( u ); + + table.getCompilationUnit().addSymbol( template ); + + TypeInfo type = new TypeInfo( TypeInfo.t_char, 0, null ); + LinkedList args = new LinkedList(); + args.add( type ); + look = table.getCompilationUnit().TemplateLookup( "X", args ); + assertTrue( look instanceof TemplateInstance ); + + TemplateInstance instance = (TemplateInstance) look; + look = ((IDerivableContainerSymbol) instance.getInstantiatedSymbol()).Lookup( "t" ); + + assertTrue( look instanceof TemplateInstance ); + assertTrue( ((TemplateInstance) look).isType( TypeInfo.t_char ) ); + + look = ((IDerivableContainerSymbol) instance.getInstantiatedSymbol()).Lookup( "u" ); + assertTrue( look instanceof TemplateInstance ); + assertTrue( ((TemplateInstance) look).isType( TypeInfo.t_char ) ); + } + + /** + * + * @throws Exception + * template < class T > class A { + * T t; + * }; + * class B {}; + * void f( char c ) {} + * void f( A b ) { ... } + * void f( int i ) {} + * + * A a; + * f( a ); //calls f( A ) + * + */ + public void testTemplateParameterAsFunctionArgument() throws Exception{ + newTable(); + + IParameterizedSymbol template = table.newParameterizedSymbol( "A", TypeInfo.t_template ); + ISymbol paramT = table.newSymbol( "T", TypeInfo.t_undef ); + template.addParameter( paramT ); + + IDerivableContainerSymbol A = table.newDerivableContainerSymbol( "A", TypeInfo.t_class ); + template.addSymbol( A ); + + ISymbol t = table.newSymbol( "t", TypeInfo.t_type ); + t.setTypeSymbol( paramT ); + A.addSymbol( t ); + + table.getCompilationUnit().addSymbol( template ); + + IDerivableContainerSymbol B = table.newDerivableContainerSymbol( "B", TypeInfo.t_class ); + table.getCompilationUnit().addSymbol( B ); + + IParameterizedSymbol temp = (IParameterizedSymbol) table.getCompilationUnit().Lookup( "A" ); + assertEquals( temp, template ); + + LinkedList args = new LinkedList(); + TypeInfo arg = new TypeInfo( TypeInfo.t_type, 0, B ); + args.add( arg ); + + IParameterizedSymbol f1 = table.newParameterizedSymbol( "f", TypeInfo.t_function ); + f1.addParameter( TypeInfo.t_char, 0, null, false ); + table.getCompilationUnit().addSymbol( f1 ); + + IParameterizedSymbol f2 = table.newParameterizedSymbol( "f", TypeInfo.t_function ); + f2.addParameter( temp.instantiate( args ), null, false ); + table.getCompilationUnit().addSymbol( f2 ); + + IParameterizedSymbol f3 = table.newParameterizedSymbol( "f", TypeInfo.t_function ); + f3.addParameter( TypeInfo.t_int, 0, null, false ); + table.getCompilationUnit().addSymbol( f3 ); + + ISymbol a = table.newSymbol( "a", TypeInfo.t_type ); + a.setTypeSymbol( temp.instantiate( args ) ); + table.getCompilationUnit().addSymbol( a ); + + LinkedList params = new LinkedList(); + params.add( new TypeInfo( TypeInfo.t_type, 0, a ) ); + + ISymbol look = table.getCompilationUnit().UnqualifiedFunctionLookup( "f", params ); + assertEquals( look, f2 ); + + } + + /** + * + * template < class T1, class T2, int I > class A {} //#1 + * template < class T, int I > class A < T, T*, I > {} //#2 + * template < class T1, class T2, int I > class A < T1*, T2, I > {} //#3 + * template < class T > class A < int, T*, 5 > {} //#4 + * template < class T1, class T2, int I > class A < T1, T2*, I > {} //#5 + * + * A a1; //uses #1 + * A a2; //uses #2, T is int, I is 1 + * A a3; //uses #4, T is char + * A a4; //uses #5, T is int, T2 is char, I is1 + * A a5; //ambiguous, matches #3 & #5. + * + * @throws Exception + */ + public void incompletetestTemplateSpecialization() throws Exception{ + newTable(); + + IDerivableContainerSymbol cls1 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class ); + IDerivableContainerSymbol cls2 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class ); + IDerivableContainerSymbol cls3 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class ); + IDerivableContainerSymbol cls4 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class ); + IDerivableContainerSymbol cls5 = table.newDerivableContainerSymbol( "A", TypeInfo.t_class ); + + IParameterizedSymbol template1 = table.newParameterizedSymbol( "A", TypeInfo.t_template ); + ISymbol T1p1 = table.newSymbol( "T1", TypeInfo.t_undef ); + ISymbol T1p2 = table.newSymbol( "T2", TypeInfo.t_undef ); + ISymbol T1p3 = table.newSymbol( "I", TypeInfo.t_int ); + template1.addParameter( T1p1 ); + template1.addParameter( T1p2 ); + template1.addParameter( T1p3 ); + template1.addSymbol( cls1 ); + table.getCompilationUnit().addSymbol( template1 ); + + IParameterizedSymbol template2 = table.newParameterizedSymbol( "A", TypeInfo.t_template ); + ISymbol T2p1 = table.newSymbol( "T", TypeInfo.t_undef ); + ISymbol T2p2 = table.newSymbol( "I", TypeInfo.t_int ); + template2.addParameter( T2p1 ); + template2.addParameter( T2p2 ); + ISymbol T2a1 = table.newSymbol( "T", TypeInfo.t_undef ); + ISymbol T2a2 = table.newSymbol( "T", TypeInfo.t_undef ); + T2a2.addPtrOperator( new PtrOp( PtrOp.t_pointer ) ); + ISymbol T2a3 = table.newSymbol( "I", TypeInfo.t_int ); + template2.addArgument( T2a1 ); + template2.addArgument( T2a2 ); + template2.addArgument( T2a3 ); + template2.addSymbol( cls2 ); + template1.addSpecialization( template2 ); + + IParameterizedSymbol template3 = table.newParameterizedSymbol( "A", TypeInfo.t_template ); + ISymbol T3p1 = table.newSymbol( "T1", TypeInfo.t_undef ); + ISymbol T3p2 = table.newSymbol( "T2", TypeInfo.t_undef ); + ISymbol T3p3 = table.newSymbol( "I", TypeInfo.t_int ); + template3.addParameter( T3p1 ); + template3.addParameter( T3p2 ); + template3.addParameter( T3p3 ); + ISymbol T3a1 = table.newSymbol( "T1", TypeInfo.t_undef ); + T3a1.addPtrOperator( new PtrOp( PtrOp.t_pointer ) ); + ISymbol T3a2 = table.newSymbol( "T2", TypeInfo.t_undef ); + ISymbol T3a3 = table.newSymbol( "I", TypeInfo.t_int ); + template3.addArgument( T3a1 ); + template3.addArgument( T3a2 ); + template3.addArgument( T3a3 ); + template3.addSymbol( cls3 ); + template1.addSpecialization( template3 ); + + IParameterizedSymbol template4 = table.newParameterizedSymbol( "A", TypeInfo.t_template ); + ISymbol T4p1 = table.newSymbol( "T", TypeInfo.t_undef ); + template4.addParameter( T4p1 ); + + ISymbol T4a1 = table.newSymbol( "", TypeInfo.t_int ); + ISymbol T4a2 = table.newSymbol( "T", TypeInfo.t_undef ); + T4a2.addPtrOperator( new PtrOp( PtrOp.t_pointer ) ); + ISymbol T4a3 = table.newSymbol( "", TypeInfo.t_int ); + T4a3.getTypeInfo().setDefault( new Integer(5) ); + template4.addArgument( T4a1 ); + template4.addArgument( T4a2 ); + template4.addArgument( T4a3 ); + template4.addSymbol( cls4 ); + template1.addSpecialization( template4 ); + + IParameterizedSymbol template5 = table.newParameterizedSymbol( "A", TypeInfo.t_template ); + ISymbol T5p1 = table.newSymbol( "T1", TypeInfo.t_undef ); + ISymbol T5p2 = table.newSymbol( "T2", TypeInfo.t_undef ); + ISymbol T5p3 = table.newSymbol( "I", TypeInfo.t_int ); + template5.addParameter( T5p1 ); + template5.addParameter( T5p2 ); + template5.addParameter( T5p3 ); + ISymbol T5a1 = table.newSymbol( "T1", TypeInfo.t_undef ); + ISymbol T5a2 = table.newSymbol( "T2", TypeInfo.t_undef ); + T5a1.addPtrOperator( new PtrOp( PtrOp.t_pointer ) ); + ISymbol T5a3 = table.newSymbol( "I", TypeInfo.t_int ); + template5.addArgument( T5a1 ); + template5.addArgument( T5a2 ); + template5.addArgument( T5a3 ); + template5.addSymbol( cls5 ); + template1.addSpecialization( template5 ); + + IParameterizedSymbol a = (IParameterizedSymbol) table.getCompilationUnit().Lookup( "A" ); + + LinkedList args = new LinkedList(); + + args.add( new TypeInfo( TypeInfo.t_int, 0, null ) ); + args.add( new TypeInfo( TypeInfo.t_int, 0, null ) ); + args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(1) ) ); + + TemplateInstance a1 = a.instantiate( args ); + assertEquals( a1.getInstantiatedSymbol(), cls1 ); + + args.clear(); + args.add( new TypeInfo( TypeInfo.t_int, 0, null ) ); + args.add( new TypeInfo( TypeInfo.t_int, 0, null, new PtrOp( PtrOp.t_pointer ), false ) ); + args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(1) ) ); + + TemplateInstance a2 = a.instantiate( args ); + assertEquals( a2.getInstantiatedSymbol(), cls2 ); + + args.clear(); + args.add( new TypeInfo( TypeInfo.t_int, 0, null ) ); + args.add( new TypeInfo( TypeInfo.t_char, 0, null, new PtrOp( PtrOp.t_pointer ), false ) ); + args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(5) ) ); + TemplateInstance a3 = a.instantiate( args ); + assertEquals( a3.getInstantiatedSymbol(), cls4 ); + + args.clear(); + args.add( new TypeInfo( TypeInfo.t_int, 0, null ) ); + args.add( new TypeInfo( TypeInfo.t_char, 0, null, new PtrOp( PtrOp.t_pointer ), false ) ); + args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(1) ) ); + TemplateInstance a4 = a.instantiate( args ); + assertEquals( a4.getInstantiatedSymbol(), cls5 ); + + args.clear(); + args.add( new TypeInfo( TypeInfo.t_int, 0, null, new PtrOp( PtrOp.t_pointer ), false ) ); + args.add( new TypeInfo( TypeInfo.t_int, 0, null, new PtrOp( PtrOp.t_pointer ), false ) ); + args.add( new TypeInfo( TypeInfo.t_int, 0, null, null, new Integer(2) ) ); + + try{ + TemplateInstance a5 = a.instantiate( args ); + } catch ( ParserSymbolTableException e ){ + assertEquals( e.reason, ParserSymbolTableException.r_Ambiguous ); + } + } +} + diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java new file mode 100644 index 00000000000..6b8bb5ebb6c --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java @@ -0,0 +1,38 @@ +/********************************************************************** + * Copyright (c) 2002,2003 Rational Software Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Rational Software - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.core.parser.tests; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.model.tests.CModelElementsTests; + +/** + * @author jcamelon + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public class ParserTestSuite extends TestCase { + public static Test suite() { + TestSuite suite= new TestSuite(ParserTestSuite.class.getName()); + suite.addTestSuite(BranchTrackerTest.class); + suite.addTestSuite(ScannerTestCase.class); + suite.addTestSuite(ExprEvalTest.class); + suite.addTestSuite(DOMTests.class); + suite.addTestSuite(ParserSymbolTableTest.class); + suite.addTestSuite(CModelElementsTests.class); + return suite; + } + + +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ScannerTestCase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ScannerTestCase.java new file mode 100644 index 00000000000..1cbbd467746 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ScannerTestCase.java @@ -0,0 +1,1404 @@ +package org.eclipse.cdt.core.parser.tests; + +import java.io.StringWriter; +import java.io.Writer; +import java.util.List; + +import org.eclipse.cdt.core.parser.IMacroDescriptor; +import org.eclipse.cdt.core.parser.IToken; +import org.eclipse.cdt.core.parser.ScannerException; +import org.eclipse.cdt.internal.core.parser.Parser; +import org.eclipse.cdt.internal.core.parser.Token; + +/** + * @author jcamelon + * + * To change this generated comment edit the template variable "typecomment": + * Window>Preferences>Java>Templates. + * To enable and disable the creation of type comments go to + * Window>Preferences>Java>Code Generation. + */ +public class ScannerTestCase extends BaseScannerTest +{ + public class TableRow + { + private int[] values; + private int length; + + public TableRow(int[] v) + { + length= v.length; + values= new int[length]; + System.arraycopy(v, 0, values, 0, length); + } + + public String toString() + { + StringBuffer s= new StringBuffer(); + for (int i= 0; i < length; ++i) + { + s.append("var").append(i).append("=").append(values[i]).append(" "); + } + return s.toString(); + } + + public String symbolName(int index) + { + return "DEFINITION" + index; + } + + public int symbolValue(int index) + { + return new Long(Math.round(Math.pow(index, index))).intValue(); + } + + public String generateCode() + { + if (length < 2) + { + return "Array must have at least 2 elements"; + } + int numberOfElsifs= length - 1; + StringBuffer buffer= new StringBuffer(); + buffer.append("#if ").append(values[0]).append("\n#\tdefine "); + buffer.append(symbolName(0)).append(" ").append(symbolValue(0)); + for (int i= 0; i < numberOfElsifs; ++i) + buffer + .append("\n#elif ") + .append(values[1 + i]) + .append("\n#\tdefine ") + .append(symbolName(i + 1)) + .append(" ") + .append(symbolValue(i + 1)); + buffer + .append("\n#else \n#\tdefine ") + .append(symbolName(length)) + .append(" ") + .append(symbolValue(length)) + .append("\n#endif"); + return buffer.toString(); + } + + public int selectWinner() + { + for (int i= 0; i < values.length; ++i) + { + if (values[i] != 0) + { + return i; + } + } + return length; + } + /** + * Returns the length. + * @return int + */ + public int getLength() + { + return length; + } + + } + + public class TruthTable + { + private int numberOfVariables; + private int numberOfRows; + public TableRow[] rows; + + public TruthTable(int n) + { + numberOfVariables= n; + numberOfRows= new Long(Math.round(Math.pow(2, n))).intValue(); + + rows= new TableRow[numberOfRows]; + for (int i= 0; i < numberOfRows; ++i) + { + String Z= Integer.toBinaryString(i); + + int[] input= new int[numberOfVariables]; + for (int j= 0; j < numberOfVariables; ++j) + { + int padding= numberOfVariables - Z.length(); + int k= 0; + for (; k < padding; ++k) + { + input[k]= 0; + } + for (int l= 0; l < Z.length(); ++l) + { + char c= Z.charAt(l); + int value= Character.digit(c, 10); + input[k++]= value; + } + } + rows[i]= new TableRow(input); + } + } + /** + * Returns the numberOfRows. + * @return int + */ + public int getNumberOfRows() + { + return numberOfRows; + } + + } + + public final static boolean doIncludeStdio= false; + public final static boolean doIncludeWindowsH= false; + public final static boolean doIncludeWinUserH= false; + + public final static int SIZEOF_TRUTHTABLE = 10; + + + public void testWeirdStrings() + { + try + { + initializeScanner( "Living Life L\"LONG\""); + validateIdentifier( "Living" ); + validateIdentifier( "Life" ); + validateString("LONG", true); + validateEOF(); + } + catch( ScannerException se ) + { + fail(EXCEPTION_THROWN + se.toString()); + } + + } + + + public void testNumerics() + { + try + { + initializeScanner("3.0 0.9 .5 3. 4E5 2.01E-03 ..."); + validateFloatingPointLiteral( "3.0"); + validateFloatingPointLiteral( "0.9"); + validateFloatingPointLiteral( ".5"); + validateFloatingPointLiteral( "3."); + validateFloatingPointLiteral( "4E5"); + validateFloatingPointLiteral( "2.01E-03" ); + validateToken( IToken.tELIPSE ); + validateEOF(); + } + catch( ScannerException se ) + { + fail(EXCEPTION_THROWN + se.toString()); + } + + } + + + /** + * Constructor for ScannerTestCase. + * @param name + */ + public ScannerTestCase(String name) + { + super(name); + } + + public void testPreprocessorDefines() + { + try + { + initializeScanner("#define SIMPLE_NUMERIC 5\nint x = SIMPLE_NUMERIC"); + validateToken(IToken.t_int); + validateDefinition("SIMPLE_NUMERIC", "5"); + validateIdentifier("x"); + validateToken(IToken.tASSIGN); + validateInteger("5"); + validateEOF(); + + initializeScanner("#define SIMPLE_STRING \"This is a simple string.\"\n\nconst char * myVariable = SIMPLE_STRING;"); + validateToken(IToken.t_const); + validateDefinition("SIMPLE_STRING", "\"This is a simple string.\""); + validateToken(IToken.t_char); + validateToken(IToken.tSTAR); + validateIdentifier("myVariable"); + validateToken(IToken.tASSIGN); + validateString("This is a simple string."); + validateToken(IToken.tSEMI); + validateEOF(); + + initializeScanner("#define FOOL 5 \n int tryAFOOL = FOOL + FOOL;"); + + validateToken(IToken.t_int); + validateIdentifier("tryAFOOL"); + validateToken(IToken.tASSIGN); + validateInteger("5"); + validateToken(IToken.tPLUS); + validateInteger("5"); + validateToken(IToken.tSEMI); + validateEOF(); + + initializeScanner("#define FOOL 5 \n int FOOLer = FOOL;"); + + validateToken(IToken.t_int); + validateIdentifier("FOOLer"); + validateToken(IToken.tASSIGN); + validateInteger("5"); + validateToken(IToken.tSEMI); + validateEOF(); + + // the case we were failing against in ctype.h + // this is a definition, not a macro! + initializeScanner("#define _ALPHA (0x0100|_UPPER|_LOWER)"); + validateEOF(); + validateDefinition("_ALPHA", "(0x0100|_UPPER|_LOWER)"); + + // test for comments after the macro + initializeScanner("#define NO_COMMENT// ignore me"); + validateEOF(); + validateDefinition("NO_COMMENT", ""); + + initializeScanner("#define NO_COMMENT/* ignore me*/"); + validateEOF(); + validateDefinition("NO_COMMENT", ""); + + initializeScanner("#define ANSWER 42 // i think"); + validateEOF(); + validateDefinition("ANSWER", "42"); + + initializeScanner("#define ANSWER 42 /* i think */"); + validateEOF(); + validateDefinition("ANSWER", "42"); + + initializeScanner("#define MULTILINE 3 /* comment \n that goes more than one line */"); + validateEOF(); + validateDefinition("MULTILINE", "3"); + + initializeScanner("#define MULTICOMMENT X /* comment1 */ + Y /* comment 2 */"); + validateEOF(); + validateDefinition("MULTICOMMENT", "X + Y"); + + for (int i= 0; i < 7; ++i) + { + switch (i) + { + case 0 : + initializeScanner("#define SIMPLE_STRING This is a simple string.\n"); + break; + case 1 : + initializeScanner("# define SIMPLE_NUMERIC 5\n"); + break; + case 2 : + initializeScanner("# define SIMPLE_NUMERIC 5\n"); + break; + case 3 : + initializeScanner("#define SIMPLE_STRING \"This is a simple string.\"\n"); + break; + case 4 : + initializeScanner("#define SIMPLE_STRING This is a simple string.\n"); + break; + case 5 : + initializeScanner("#define FLAKE\n\nFLAKE"); + break; + case 6 : + initializeScanner("#define SIMPLE_STRING This is a simple string.\\\n Continue please."); + break; + } + validateEOF(); + + switch (i) + { + case 0 : + validateDefinition( + "SIMPLE_STRING", + "This is a simple string."); + break; + case 1 : + validateDefinition("SIMPLE_NUMERIC", "5"); + break; + case 2 : + validateDefinition("SIMPLE_NUMERIC", "5"); + break; + case 3 : + validateDefinition( + "SIMPLE_STRING", + "\"This is a simple string.\""); + break; + case 4 : + validateDefinition( + "SIMPLE_STRING", + "This is a simple string."); + break; + case 5 : + validateDefinition("FLAKE", ""); + break; + case 6 : + validateDefinition( + "SIMPLE_STRING", + "This is a simple string. Continue please."); + } + } + } + catch (Exception e) + { + fail(EXCEPTION_THROWN + e.toString()); + } + } + + public void prepareForWindowsRH() + { + scanner.addIncludePath( + "C:\\Program Files\\Microsoft Visual Studio\\VC98\\Include"); + scanner.addDefinition("_WIN32_WINNT", "0x0300"); + scanner.addDefinition("WINVER", "0x0400"); + scanner.addDefinition("_WIN32_WINDOWS", "0x0300"); + scanner.addDefinition("_MSC_VER", "1200"); + } + + public void prepareForWindowsH() + { + scanner.addIncludePath( + "C:\\Program Files\\Microsoft Visual Studio\\VC98\\Include"); + scanner.addDefinition("_MSC_VER", "1200"); + scanner.addDefinition("__cplusplus", "1"); + scanner.addDefinition("__STDC__", "1"); + scanner.addDefinition("_WIN32", ""); + scanner.addDefinition( "__midl", "1000" ); + scanner.addDefinition("_WIN32_WINNT", "0x0300"); + scanner.addDefinition("WINVER", "0x0400"); + scanner.addDefinition( "_M_IX86", "300"); + scanner.addDefinition( "_INTEGRAL_MAX_BITS", "64"); + } + + public void prepareForStdio() + { + scanner.addIncludePath( + "C:\\Program Files\\Microsoft Visual Studio\\VC98\\Include"); + scanner.addDefinition("_MSC_VER", "1100"); + scanner.addDefinition("__STDC__", "1"); + scanner.addDefinition("_INTEGRAL_MAX_BITS", "64"); + scanner.addDefinition("_WIN32", ""); + scanner.addDefinition( "_M_IX86", "300"); + } + + public void testConcatenation() + { + try + { + initializeScanner("#define F1 3\n#define F2 F1##F1\nint x=F2;"); + validateToken(IToken.t_int); + validateDefinition("F1", "3"); + validateDefinition( "F2", "F1##F1"); + validateIdentifier("x"); + validateToken(IToken.tASSIGN); + validateInteger("33"); + validateToken(IToken.tSEMI); + validateEOF(); + + initializeScanner("#define PREFIX RT_\n#define RUN PREFIX##Run"); + validateEOF(); + validateDefinition( "PREFIX", "RT_" ); + validateDefinition( "RUN", "PREFIX##Run" ); + } + catch (Exception e) + { + fail(EXCEPTION_THROWN + e.toString()); + } + + try + { + initializeScanner( "#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name\n DECLARE_HANDLE( joe )" ); + validateToken( IToken.t_struct ); + validateIdentifier( "joe__"); + validateToken( IToken.tLBRACE); + validateToken( IToken.t_int ); + validateIdentifier( "unused"); + validateToken( IToken.tSEMI ); + validateToken( IToken.tRBRACE ); + validateToken( IToken.tSEMI ); + validateToken( IToken.t_typedef ); + validateToken( IToken.t_struct ); + validateIdentifier( "joe__" ); + validateToken( IToken.tSTAR ); + validateIdentifier( "joe"); + validateEOF(); + } + catch( Exception e ) + { + fail(EXCEPTION_THROWN + e.toString()); + } + } + + public void testSimpleIfdef() + { + try + { + + initializeScanner("#define SYMBOL 5\n#ifdef SYMBOL\nint counter(SYMBOL);\n#endif"); + + validateToken(IToken.t_int); + validateIdentifier("counter"); + validateToken(IToken.tLPAREN); + validateInteger("5"); + validateToken(IToken.tRPAREN); + validateToken(IToken.tSEMI); + validateEOF(); + + initializeScanner("#define SYMBOL 5\n#ifndef SYMBOL\nint counter(SYMBOL);\n#endif"); + validateEOF(); + + initializeScanner("#ifndef DEFINED\n#define DEFINED 100\n#endif\nint count = DEFINED;"); + validateToken(IToken.t_int); + validateDefinition("DEFINED", "100"); + + validateIdentifier("count"); + validateToken(IToken.tASSIGN); + validateInteger("100"); + validateToken(IToken.tSEMI); + validateEOF(); + + initializeScanner("#ifndef DEFINED\n#define DEFINED 100\n#endif\nint count = DEFINED;"); + scanner.addDefinition("DEFINED", "101"); + + validateDefinition("DEFINED", "101"); + validateToken(IToken.t_int); + validateIdentifier("count"); + validateToken(IToken.tASSIGN); + validateInteger("101"); + validateToken(IToken.tSEMI); + validateEOF(); + + initializeScanner( "/* NB: This is #if 0'd out */"); + validateEOF(); + + } + catch (Exception e) + { + fail(EXCEPTION_THROWN + e.toString()); + } + } + + public void testMultipleLines() throws Exception + { + Writer code = new StringWriter(); + code.write( "#define COMPLEX_MACRO 33 \\\n"); + code.write( " + 44\n\nCOMPLEX_MACRO"); + initializeScanner( code.toString() ); + validateInteger( "33" ); + validateToken( IToken.tPLUS ); + validateInteger( "44" ); + } + + public void testSlightlyComplexIfdefStructure() + { + try + { + initializeScanner("#ifndef BASE\n#define BASE 10\n#endif\n#ifndef BASE\n#error BASE is defined\n#endif"); + validateEOF(); + validateBalance(); + } + catch (Exception e) + { + fail(EXCEPTION_THROWN + e.toString()); + } + + try + { + initializeScanner("#ifndef ONE\n#define ONE 1\n#ifdef TWO\n#define THREE ONE + TWO\n#endif\n#endif\nint three(THREE);"); + + validateToken(IToken.t_int); + validateDefinition("ONE", "1"); + validateAsUndefined("TWO"); + validateAsUndefined("THREE"); + validateIdentifier("three"); + validateToken(IToken.tLPAREN); + validateIdentifier("THREE"); + validateToken(IToken.tRPAREN); + validateToken(IToken.tSEMI); + validateEOF(); + validateBalance(); + + initializeScanner("#ifndef ONE\n#define ONE 1\n#ifdef TWO\n#define THREE ONE + TWO\n#endif\n#endif\nint three(THREE);"); + scanner.addDefinition("TWO", "2"); + validateToken(IToken.t_int); + validateDefinition("ONE", "1"); + validateDefinition("TWO", "2"); + validateDefinition("THREE", "ONE + TWO"); + + validateIdentifier("three"); + validateToken(IToken.tLPAREN); + validateInteger("1"); + validateToken(IToken.tPLUS); + validateInteger("2"); + validateToken(IToken.tRPAREN); + validateToken(IToken.tSEMI); + validateEOF(); + validateBalance(); + + initializeScanner("#ifndef FOO\n#define FOO 4\n#else\n#undef FOO\n#define FOO 6\n#endif"); + validateEOF(); + validateBalance(); + validateDefinition("FOO", "4"); + + initializeScanner("#ifndef FOO\n#define FOO 4\n#else\n#undef FOO\n#define FOO 6\n#endif"); + scanner.addDefinition("FOO", "2"); + validateEOF(); + validateBalance(); + validateDefinition("FOO", "6"); + + initializeScanner("#ifndef ONE\n# define ONE 1\n# ifndef TWO\n# define TWO ONE + ONE \n# else\n# undef TWO\n# define TWO 2 \n# endif\n#else\n# ifndef TWO\n# define TWO ONE + ONE \n# else\n# undef TWO\n# define TWO 2 \n# endif\n#endif\n"); + validateEOF(); + validateBalance(); + validateDefinition("ONE", "1"); + validateDefinition("TWO", "ONE + ONE"); + + initializeScanner("#ifndef ONE\n# define ONE 1\n# ifndef TWO\n# define TWO ONE + ONE \n# else\n# undef TWO\n# define TWO 2 \n# endif\n#else\n# ifndef TWO\n# define TWO ONE + ONE \n# else\n# undef TWO\n# define TWO 2 \n# endif\n#endif\n"); + scanner.addDefinition("ONE", "one"); + validateEOF(); + validateBalance(); + validateDefinition("ONE", "one"); + validateDefinition("TWO", "ONE + ONE"); + + initializeScanner("#ifndef ONE\n# define ONE 1\n# ifndef TWO\n# define TWO ONE + ONE \n# else\n# undef TWO\n# define TWO 2 \n# endif\n#else\n# ifndef TWO\n# define TWO ONE + ONE \n# else\n# undef TWO\n# define TWO 2 \n# endif\n#endif\n"); + scanner.addDefinition("ONE", "one"); + scanner.addDefinition("TWO", "two"); + validateEOF(); + validateBalance(); + + validateDefinition("ONE", "one"); + validateDefinition("TWO", "2"); + + initializeScanner("#ifndef ONE\n# define ONE 1\n# ifndef TWO\n# define TWO ONE + ONE \n# else\n# undef TWO\n# define TWO 2 \n# endif\n#else\n# ifndef TWO\n# define TWO ONE + ONE \n# else\n# undef TWO\n# define TWO 2 \n# endif\n#endif\n"); + scanner.addDefinition("TWO", "two"); + validateEOF(); + validateBalance(); + + validateDefinition("ONE", "1"); + validateDefinition("TWO", "2"); + + } + catch (Exception e) + { + fail(EXCEPTION_THROWN + e.toString()); + } + } + + public void testIfs() + { + try + { + initializeScanner("#if 0\n#error NEVER\n#endif\n"); + validateEOF(); + validateBalance(); + + initializeScanner("#define X 5\n#define Y 7\n#if (X < Y)\n#define Z X + Y\n#endif"); + validateEOF(); + validateBalance(); + validateDefinition("X", "5"); + validateDefinition("Y", "7"); + validateDefinition("Z", "X + Y"); + + initializeScanner("#if T < 20\n#define Z T + 1\n#endif"); + scanner.addDefinition("X", "5"); + scanner.addDefinition("Y", "7"); + scanner.addDefinition("T", "X + Y"); + validateEOF(); + validateBalance(); + validateDefinition("X", "5"); + validateDefinition("Y", "7"); + validateDefinition("T", "X + Y"); + validateDefinition("Z", "T + 1"); + + } + catch (Exception e) + { + fail(EXCEPTION_THROWN + e.toString()); + } + + try + { + initializeScanner("#if ( 10 / 5 ) != 2\n#error 10/5 seems to not equal 2 anymore\n#endif\n"); + validateEOF(); + validateBalance(); + } + catch (Exception e) + { + fail(EXCEPTION_THROWN + e.toString()); + } + + try + { + initializeScanner("#ifndef FIVE \n#define FIVE 5\n#endif \n#ifndef TEN\n#define TEN 2 * FIVE\n#endif\n#if TEN != 10\n#define MISTAKE 1\n#error Five does not equal 10\n#endif\n"); + scanner.addDefinition("FIVE", "55"); + validateEOF(); + fail(EXPECTED_FAILURE); + } + catch (ScannerException se) + { + validateBalance(1); + validateDefinition("FIVE", "55"); + validateDefinition("TEN", "2 * FIVE"); + validateDefinition("MISTAKE", "1"); + } + catch (Exception e) + { + fail(EXCEPTION_THROWN + e.toString()); + } + + try + { + initializeScanner("#if ((( FOUR / TWO ) * THREE )< FIVE )\n#error 6 is not less than 5 \n#endif\n#if ( ( FIVE * ONE ) != (( (FOUR) + ONE ) * ONE ) )\n#error 5 should equal 5\n#endif \n"); + + scanner.addDefinition("ONE", "1"); + scanner.addDefinition("TWO", "(ONE + ONE)"); + scanner.addDefinition("THREE", "(TWO + ONE)"); + scanner.addDefinition("FOUR", "(TWO * TWO)"); + scanner.addDefinition("FIVE", "(THREE + TWO)"); + + validateEOF(); + validateBalance(); + validateDefinition("ONE", "1"); + validateDefinition("TWO", "(ONE + ONE)"); + validateDefinition("THREE", "(TWO + ONE)"); + validateDefinition("FOUR", "(TWO * TWO)"); + validateDefinition("FIVE", "(THREE + TWO)"); + + TruthTable table= new TruthTable(SIZEOF_TRUTHTABLE); + int numberOfRows= table.getNumberOfRows(); + TableRow[] rows= table.rows; + + for (int i= 0; i < numberOfRows; ++i) + { + TableRow row= rows[i]; + String code= row.generateCode(); + if (verbose) + System.out.println("\n\nRow " + i + " has code\n" + code); + initializeScanner(code); + validateEOF(); + validateBalance(); + validateAllDefinitions(row); + } + } + catch (Exception e) + { + fail(EXCEPTION_THROWN + e.toString()); + } + + try + { + initializeScanner("#if ! 0\n#error Correct!\n#endif"); + IToken t= scanner.nextToken(); + fail(EXPECTED_FAILURE); + } + catch (ScannerException se) + { + validateBalance(1); + assertTrue(se.getMessage().equals("#error Correct!")); + } + catch (Exception e) + { + fail(EXCEPTION_THROWN + e.toString()); + } + } + + public void testPreprocessorMacros() + { + try + { + initializeScanner("#define GO(x) x+1\nint y(5);\ny = GO(y);"); + validateToken(IToken.t_int); + validateIdentifier("y"); + validateToken(IToken.tLPAREN); + validateInteger("5"); + validateToken(IToken.tRPAREN); + validateToken(IToken.tSEMI); + + IMacroDescriptor descriptor= + (IMacroDescriptor) scanner.getDefinition("GO"); + List parms= descriptor.getParameters(); + assertNotNull(parms); + assertTrue(parms.size() == 1); + String parm1= (String) parms.get(0); + assertTrue(parm1.equals("x")); + List expansion= descriptor.getTokenizedExpansion(); + assertNotNull(parms); + assertTrue(expansion.size() == 3); + assertTrue(((Token) expansion.get(0)).type == IToken.tIDENTIFIER); + assertTrue(((Token) expansion.get(0)).image.equals("x")); + assertTrue(((Token) expansion.get(1)).type == IToken.tPLUS); + assertTrue(((Token) expansion.get(2)).type == IToken.tINTEGER); + assertTrue(((Token) expansion.get(2)).image.equals("1")); + + validateIdentifier("y"); + validateToken(IToken.tASSIGN); + validateIdentifier("y"); + validateToken(IToken.tPLUS); + validateInteger("1"); + validateToken(IToken.tSEMI); + validateEOF(); + validateBalance(); + + initializeScanner( + "#define ONE 1\n" + + "#define SUM(a,b,c,d,e,f,g) ( a + b + c + d + e + f + g )\n" + + "int daSum = SUM(ONE,3,5,7,9,11,13);"); + validateToken(IToken.t_int); + validateIdentifier("daSum"); + validateToken(IToken.tASSIGN); + validateToken(IToken.tLPAREN); + validateInteger("1"); + validateToken(IToken.tPLUS); + validateInteger("3"); + validateToken(IToken.tPLUS); + validateInteger("5"); + validateToken(IToken.tPLUS); + validateInteger("7"); + validateToken(IToken.tPLUS); + validateInteger("9"); + validateToken(IToken.tPLUS); + validateInteger("11"); + validateToken(IToken.tPLUS); + validateInteger("13"); + validateToken(IToken.tRPAREN); + validateToken(IToken.tSEMI); + validateEOF(); + + IMacroDescriptor macro= (IMacroDescriptor) scanner.getDefinition("SUM"); + List params= macro.getParameters(); + assertNotNull(params); + assertTrue(params.size() == 7); + + List tokens= macro.getTokenizedExpansion(); + assertNotNull(tokens); + assertTrue(tokens.size() == 15); + + initializeScanner("#define LOG( format, var1) printf( format, var1 )\nLOG( \"My name is %s\", \"Bogdan\" );\n"); + validateIdentifier("printf"); + validateToken(IToken.tLPAREN); + validateString("My name is %s"); + validateToken(IToken.tCOMMA); + validateString("Bogdan"); + validateToken(IToken.tRPAREN); + validateToken(IToken.tSEMI); + validateEOF(); + + initializeScanner("#define INCR( x ) ++x\nint y(2);\nINCR(y);"); + validateToken(IToken.t_int); + validateIdentifier("y"); + validateToken(IToken.tLPAREN); + validateInteger("2"); + validateToken(IToken.tRPAREN); + validateToken(IToken.tSEMI); + validateToken(IToken.tINCR); + validateIdentifier("y"); + validateToken(IToken.tSEMI); + validateEOF(); + + initializeScanner("#define CHECK_AND_SET( x, y, z ) if( x ) { \\\n y = z; \\\n }\n\nCHECK_AND_SET( 1, balance, 5000 );\nCHECK_AND_SET( confused(), you, dumb );"); + validateToken(IToken.t_if); + validateToken(IToken.tLPAREN); + validateInteger("1"); + validateToken(IToken.tRPAREN); + validateToken(IToken.tLBRACE); + validateIdentifier("balance"); + validateToken(IToken.tASSIGN); + validateInteger("5000"); + validateToken(IToken.tSEMI); + validateToken(IToken.tRBRACE); + validateToken(IToken.tSEMI); + + validateToken(IToken.t_if); + validateToken(IToken.tLPAREN); + validateIdentifier("confused"); + validateToken(IToken.tLPAREN); + validateToken(IToken.tRPAREN); + validateToken(IToken.tRPAREN); + validateToken(IToken.tLBRACE); + validateIdentifier("you"); + validateToken(IToken.tASSIGN); + validateIdentifier("dumb"); + validateToken(IToken.tSEMI); + validateToken(IToken.tRBRACE); + validateToken(IToken.tSEMI); + validateEOF(); + + initializeScanner("#define ON 7\n#if defined(ON)\nint itsOn = ON;\n#endif"); + validateToken(IToken.t_int); + validateBalance(1); + validateIdentifier("itsOn"); + validateToken(IToken.tASSIGN); + validateInteger("7"); + validateToken(IToken.tSEMI); + validateEOF(); + validateBalance(); + + initializeScanner("#if defined( NOTHING ) \nint x = NOTHING;\n#endif"); + validateEOF(); + validateBalance(); + + + + + + } + catch (Exception e) + { + fail(EXCEPTION_THROWN + e.toString()); + } + } + + public void testQuickScan() throws Parser.EndOfFile + { + try + { + initializeScanner( "#if X + 5 < 7\n int found = 1;\n#endif" ); + scanner.setQuickScan( true ); + validateToken( IToken.t_int ); + validateIdentifier( "found" ); + validateToken( IToken.tASSIGN ); + validateInteger( "1"); + validateToken( IToken.tSEMI ); + validateEOF(); + + } + catch( ScannerException se ) + { + fail( EXCEPTION_THROWN + se.getMessage() ); + } + + try + { + initializeScanner( "#if 0\n int error = 666;\n#endif" ); + scanner.setQuickScan( true ); + validateEOF(); + } + catch( ScannerException se ) + { + fail( EXCEPTION_THROWN + se.getMessage() ); + } + + } + + public void testInclusions() + { + try + { + if (doIncludeStdio) + { + initializeScanner("#include "); + prepareForStdio(); + int count= fullyTokenize(); + if (verbose) + System.out.println( + "For stdio.h, Scanner produced " + count + " tokens"); + validateBalance(); + + initializeScanner("#include \\\n<\\\nstdio.h \\\n>"); + prepareForStdio(); + count= fullyTokenize(); + if (verbose) + System.out.println( + "For stdio.h, Scanner produced " + count + " tokens"); + } + + if (doIncludeWindowsH) + { + initializeScanner("#include "); + prepareForWindowsH(); + int count= fullyTokenize(); + if (verbose) + System.out.println( + "For Windows.h, Scanner produced " + + scanner.getCount() + + " tokens"); + validateBalance(); + } + + if (doIncludeWinUserH) + { + initializeScanner("#include "); + prepareForWindowsRH(); + validateEOF(); + validateBalance(); + if (verbose) + System.out.println( + "For WinUser.rh, Scanner produced " + + scanner.getCount() + + " tokens"); + } + } + catch (Exception e) + { + fail(EXCEPTION_THROWN + e.toString()); + } + + } + + public void testOtherPreprocessorCommands() + { + try + { + initializeScanner("#\n#\t\n#define MAX_SIZE 1024\n#\n# "); + validateEOF(); + validateDefinition("MAX_SIZE", "1024"); + } + catch (Exception e) + { + fail(EXCEPTION_THROWN + e.toString()); + } + + for (int i= 0; i < 4; ++i) + { + switch (i) + { + case 0 : + initializeScanner("# ape"); + break; + case 1 : + initializeScanner("# #"); + break; + case 2 : + initializeScanner("# 32"); + break; + case 3 : + initializeScanner("# defines"); + break; + } + + try + { + validateEOF(); + fail(EXPECTED_FAILURE); + } + catch (ScannerException se) + { + validateBalance(); + } + catch (Exception e) + { + fail(EXCEPTION_THROWN + e.toString()); + } + } + + } + + public void validateAllDefinitions(TableRow row) + { + int winner= row.selectWinner(); + int rowLength= row.getLength(); + for (int i= 0; i <= rowLength; ++i) + { + if (i == winner) + validateDefinition(row.symbolName(i), row.symbolValue(i)); + else + validateAsUndefined(row.symbolName(i)); + } + } + + public void testBug36287() throws Exception + { + initializeScanner( "X::X( const X & rtg_arg ) : U( rtg_arg ) , Z( rtg_arg.Z ) , er( rtg_arg.er ){}" ); + validateIdentifier("X"); + validateToken( IToken.tCOLONCOLON); + validateIdentifier("X"); + validateToken( IToken.tLPAREN ); + validateToken( IToken.t_const ); + validateIdentifier("X"); + validateToken( IToken.tAMPER ); + validateIdentifier( "rtg_arg"); + validateToken( IToken.tRPAREN ); + validateToken( IToken.tCOLON ); + validateIdentifier( "U"); + validateToken( IToken.tLPAREN ); + validateIdentifier( "rtg_arg"); + validateToken( IToken.tRPAREN ); + validateToken( IToken.tCOMMA ); + validateIdentifier( "Z"); + validateToken( IToken.tLPAREN ); + validateIdentifier( "rtg_arg"); + validateToken( IToken.tDOT ); + validateIdentifier( "Z"); + validateToken( IToken.tRPAREN ); + validateToken( IToken.tCOMMA ); + validateIdentifier( "er"); + validateToken( IToken.tLPAREN ); + validateIdentifier( "rtg_arg"); + validateToken( IToken.tDOT ); + validateIdentifier( "er"); + validateToken( IToken.tRPAREN ); + validateToken( IToken.tLBRACE); + validateToken( IToken.tRBRACE); + validateEOF(); + + initializeScanner( "foo.*bar"); + validateIdentifier("foo"); + validateToken( IToken.tDOTSTAR ); + validateIdentifier("bar"); + validateEOF(); + + initializeScanner( "foo...bar"); + validateIdentifier("foo"); + validateToken( IToken.tELIPSE ); + validateIdentifier("bar"); + validateEOF(); + } + + public void testBug35892() + { + try + { + initializeScanner( "'c'" ); + validateChar( 'c' ); + validateEOF(); + } + catch( ScannerException se ) + { + fail( EXCEPTION_THROWN + se.getMessage() ); + } + } + + public void testBug36045() throws Exception + { + StringBuffer buffer = new StringBuffer(); + buffer.append( '"' ); + buffer.append( '\\'); + buffer.append( '"'); + buffer.append( '"'); + + buffer.append( '"'); + buffer.append( '\\'); + buffer.append( '\\'); + buffer.append( '"'); + buffer.append( "\n\n"); + initializeScanner( buffer.toString()); + validateString( "\\\"\\\\"); + } + + public void testConditionalWithBraces() + { + try + { + for( int i = 0; i < 4; ++i ) + { + initializeScanner( "int foobar(int a) { if(a == 0) {\n#ifdef THIS\n} else {}\n#elif THAT\n} else {}\n#endif\nreturn 0;}" ); + switch( i ) + { + case 0: + scanner.addDefinition( "THIS", "1"); + scanner.addDefinition( "THAT", "1" ); + break; + case 1: + scanner.addDefinition( "THIS", "1"); + scanner.addDefinition( "THAT", "0" ); + break; + case 2: + scanner.addDefinition( "THAT", "1" ); + break; + case 3: + scanner.addDefinition( "THAT", "0" ); + break; + } + + validateToken( IToken.t_int ); + validateIdentifier( "foobar"); + validateToken( IToken.tLPAREN ); + validateToken( IToken.t_int ); + validateIdentifier( "a" ); + validateToken( IToken.tRPAREN ); + validateToken( IToken.tLBRACE ); + validateToken( IToken.t_if ); + validateToken( IToken.tLPAREN ); + validateIdentifier( "a" ); + validateToken( IToken.tEQUAL ); + validateInteger( "0" ); + validateToken( IToken.tRPAREN ); + validateToken( IToken.tLBRACE ); + + if( i <= 1 ) + { + validateToken( IToken.tRBRACE ); + validateToken( IToken.t_else ); + validateToken( IToken.tLBRACE ); + validateToken( IToken.tRBRACE ); + } + + if( i == 2 ) + { + validateToken( IToken.tRBRACE ); + validateToken( IToken.t_else ); + validateToken( IToken.tLBRACE ); + validateToken( IToken.tRBRACE ); + } + + validateToken( IToken.t_return ); + validateInteger( "0"); + validateToken( IToken.tSEMI ); + validateToken( IToken.tRBRACE ); + validateEOF(); + } + } catch( ScannerException se ) + { + fail(EXCEPTION_THROWN + se.toString()); + } + } + + public void testNestedRecursiveDefines() throws Exception + { + initializeScanner( "#define C B A\n#define B C C\n#define A B\nA" ); + + validateIdentifier("B"); + validateDefinition("A", "B"); + validateDefinition("B", "C C"); + validateDefinition("C", "B A"); + validateIdentifier("A"); + validateIdentifier("B"); + validateIdentifier("A"); + validateEOF(); + } + + public void testBug36316() throws Exception + { + initializeScanner( "#define A B->A\nA" ); + + validateIdentifier("B"); + validateDefinition("A", "B->A"); + validateToken(IToken.tARROW); + validateIdentifier("A"); + validateEOF(); + } + + public void testBug36434() throws Exception + { + initializeScanner( "#define X(Y)"); + validateEOF(); + IMacroDescriptor macro = (IMacroDescriptor)scanner.getDefinition( "X" ); + assertNotNull( macro ); + assertEquals( macro.getParameters().size(), 1 ); + assertEquals( (String)macro.getParameters().get(0), "Y" ); + assertEquals( macro.getTokenizedExpansion().size(), 0 ); + } + + public void testBug36047() throws Exception + { + StringWriter writer = new StringWriter(); + writer.write( "# define MAD_VERSION_STRINGIZE(str) #str\n" ); + writer.write( "# define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num)\n" ); + writer.write( "# define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) \".\" \\\n" ); + writer.write( " MAD_VERSION_STRING(MAD_VERSION_MINOR) \".\" \\\n" ); + writer.write( " MAD_VERSION_STRING(MAD_VERSION_PATCH) \".\" \\\n" ); + writer.write( " MAD_VERSION_STRING(MAD_VERSION_EXTRA)\n" ); + writer.write( "# define MAD_VERSION_MAJOR 2\n" ); + writer.write( "# define MAD_VERSION_MINOR 1\n" ); + writer.write( "# define MAD_VERSION_PATCH 3\n" ); + writer.write( "# define MAD_VERSION_EXTRA boo\n" ); + writer.write( "MAD_VERSION\n" ); + initializeScanner( writer.toString() ); + + validateString( "2.1.3.boo" ); + + validateEOF(); + } + + public void testBug36475() throws Exception + { + StringWriter writer = new StringWriter(); + writer.write( " \"A\" \"B\" \"C\" " ); + + initializeScanner( writer.toString() ); + + validateString( "ABC" ); + validateEOF(); + } + + public void testBug36509() throws Exception + { + StringWriter writer = new StringWriter(); + writer.write("#define debug(s, t) printf(\"x\" # s \"= %d, x\" # t \"= %s\", \\\n"); + writer.write(" x ## s, x ## t) \n"); + writer.write("debug(1, 2);"); + + initializeScanner( writer.toString() ); + //printf("x1=%d, x2= %s", x1, x2); + validateIdentifier( "printf" ); + validateToken( IToken.tLPAREN ); + validateString("x1= %d, x2= %s"); + validateToken(IToken.tCOMMA); + validateIdentifier("x1"); + validateToken(IToken.tCOMMA); + validateIdentifier("x2"); + validateToken(IToken.tRPAREN); + validateToken(IToken.tSEMI); + validateEOF(); + } + + public void testBug36695() throws Exception + { + StringWriter writer = new StringWriter(); + writer.write("\'\\4\' \'\\n\'"); + initializeScanner( writer.toString() ); + + validateChar( "\\4" ); + validateChar( "\\n" ); + validateEOF(); + } + + public void testBug36521() throws Exception + { + StringWriter writer = new StringWriter(); + writer.write("#define str(s) # s\n"); + writer.write("fputs(str(strncmp(\"abc\\0d\", \"abc\", \'\\4\')\n"); + writer.write(" == 0), s);\n"); + + initializeScanner( writer.toString() ); + validateIdentifier("fputs"); + validateToken(IToken.tLPAREN); + validateString("strncmp ( \\\"abc\\\\0d\\\" , \\\"abc\\\" , '\\\\4' ) == 0"); + validateToken(IToken.tCOMMA); + validateIdentifier("s"); + validateToken(IToken.tRPAREN); + validateToken(IToken.tSEMI); + } + + public void testBug36770() throws Exception + { + StringWriter writer = new StringWriter(); + writer.write( "#define A 0\n" ); + writer.write( "#if ( A == 1 )\n"); + writer.write( "# define foo 1\n"); + writer.write( "#else\n"); + writer.write( "# define foo 2\n"); + writer.write( "#endif\n"); + writer.write( "foo\n"); + + initializeScanner( writer.toString() ); + validateInteger( "2" ); + validateEOF(); + } + + public void testBug36816() throws Exception + { + initializeScanner( "#include \"foo.h" ); + try{ + validateEOF(); + } catch ( ScannerException e ){ + assertTrue( e.getMessage().equals( "Ill-formed #include: reached end of line before \"" )); + } + + initializeScanner( "#include " )); + } + initializeScanner( "#define FOO(A" ); + try{ + validateEOF(); + } catch( ScannerException e ){ + assertTrue( e.getMessage().equals( "Unexpected newline in macro formal parameter list.")); + } + initializeScanner( "#define FOO(A \\ B" ); + try{ + validateEOF(); + } catch( ScannerException e ){ + assertTrue( e.getMessage().equals( "Unexpected '\\' in macro formal parameter list.")); + } + + initializeScanner( "#define FOO(A,\\\nB) 1\n FOO(foo" ); + try{ + validateInteger("1"); + } catch( ScannerException e ){ + assertTrue( e.getMessage().equals( "Improper use of macro FOO" ) ); + } + } + + public void testBug36255() throws Exception + { + StringWriter writer = new StringWriter(); + writer.write( "#if defined ( A ) \n" ); + writer.write( " #if defined ( B ) && ( B != 0 ) \n" ); + writer.write( " boo\n" ); + writer.write( " #endif /*B*/\n" ); + writer.write( "#endif /*A*/" ); + + initializeScanner( writer.toString() ); + validateEOF(); + } + + public void testBug37011() throws Exception{ + StringWriter writer = new StringWriter(); + writer.write( "#define A \"//\""); + + initializeScanner( writer.toString() ); + + validateEOF(); + validateDefinition("A", "\"//\""); + } + + public void testOtherPreprocessorDefines() throws Exception{ + StringWriter writer = new StringWriter(); + writer.write( "#define A a//boo\n" ); + writer.write( "#define B a /*boo*/ a\n" ); + writer.write( "#define C a \" //boo \"\n" ); + writer.write( "#define D a \\\"//boo\n" ); + writer.write( "#define E a \\n \"\\\"\"\n" ); + writer.write( "#define F a\\\n b\n" ); + writer.write( "#define G a '\"'//boo\n" ); + writer.write( "#define H a '\\'//b'\"/*bo\\o*/\" b\n" ); + + initializeScanner( writer.toString() ); + + validateEOF(); + + validateDefinition("A", "a"); + validateDefinition("B", "a a"); + validateDefinition("C", "a \" //boo \""); + validateDefinition("D", "a \\\""); + validateDefinition("E", "a \\n \"\\\"\""); + validateDefinition("F", "a b"); + validateDefinition("G", "a '\"'"); + validateDefinition("H", "a '\\'//b'\"/*bo\\o*/\" b"); + } + + public void testBug38065() throws Exception + { + initializeScanner( "Foo\\\nBar" ); + + validateIdentifier("FooBar"); + validateEOF(); + + try { + initializeScanner( "Foo\\Bar" ); + + validateIdentifier("Foo"); + validateIdentifier("Bar"); + validateEOF(); + + } catch (ScannerException se) { + // if Scanner.throwExceptionOnBadCharacterRead == true + // we might end up with valid ScannerException "Invalid character ..." + // for '\' + assertTrue(se.getMessage().equals("Invalid character '\\' read @ offset 5 of file TEXT")); + } + } + + public void testBug36701A() throws Exception + { + StringWriter writer = new StringWriter(); + writer.write("#define str(s) # s\n"); + writer.write("str( @ \\n )\n"); + + initializeScanner(writer.toString()); + validateString("@ \\\\n"); + validateEOF(); + } + + public void testBug36701B() throws Exception + { + StringWriter writer = new StringWriter(); + writer.write("#define str(s) # s\n"); + writer.write("str( @ /*ff*/ \\n hh \"aa\" )\n"); + + initializeScanner(writer.toString()); + validateString("@ \\\\n hh \\\"aa\\\""); + validateEOF(); + } +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/TortureTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/TortureTest.java new file mode 100644 index 00000000000..3950b534a8c --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/TortureTest.java @@ -0,0 +1,216 @@ +/******************************************************************************* + * Copyright (c) 2001 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: + * IBM Corp. - Rational Software - initial implementation + ******************************************************************************/ +package org.eclipse.cdt.core.parser.tests; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.StringWriter; +import java.util.NoSuchElementException; +import java.util.StringTokenizer; + +import junit.framework.AssertionFailedError; +import junit.framework.Test; + +import org.eclipse.cdt.core.parser.IParser; +import org.eclipse.cdt.internal.core.dom.DOMBuilder; +import org.eclipse.cdt.internal.core.parser.Parser; +import org.eclipse.core.runtime.Path; + + +/** + * @author vmozgin + * + * Automated parser test framework, to use with GCC testsuites + */ +public class TortureTest extends FractionalAutomatedTest { + + static protected boolean isEnabled = false; + static protected boolean quickParse = true; + + public TortureTest () { + super(); + } + + public TortureTest (String name) { + super(name); + } + + protected AutomatedFramework newTest (String name){ + return new TortureTest (name); + } + + protected void loadProperties() throws Exception{ + String resourcePath = org.eclipse.core.runtime.Platform.getPlugin("org.eclipse.cdt.core.tests").find(new Path("/")).getFile(); + resourcePath += "resources/parser/TortureTest"; + + try { + FileInputStream propertiesIn = new FileInputStream(resourcePath + "/TortureTest.properties"); + properties.load (propertiesIn); + + isEnabled = properties.getProperty("enabled", "false").equalsIgnoreCase("true"); + quickParse = properties.getProperty("quickParse", "true").equalsIgnoreCase("true"); + + String sourceInfo = properties.getProperty("source", ""); + + stepSize = Integer.parseInt(properties.getProperty("stepSize", "25000")); + outputFile = properties.getProperty("outputFile", ""); + timeOut = Integer.parseInt(properties.getProperty("timeOut", "60000")); + outputDir = properties.getProperty("outDir", ""); + + if (sourceInfo.equals("")) + throw new FileNotFoundException(); + else { + StringTokenizer tokenizer = new StringTokenizer(sourceInfo, ","); + String str = null, val = null; + try { + while (tokenizer.hasMoreTokens()) { + str = tokenizer.nextToken().trim(); + val = tokenizer.nextToken().trim(); + + testSources.put(str, val); + } + } catch (NoSuchElementException e){ + //only way to get here is to have a missing val, assume cpp for that str + testSources.put(str, "cpp"); + } + + } + } catch (FileNotFoundException e){ + testSources.put(resourcePath + "/default", "cpp"); + } + + if (!isEnabled) testSources.clear(); + } + + + public static Test suite() + { + AutomatedFramework frame = new TortureTest(); + return frame.createSuite(); + } + + + static protected void reportException (Throwable e, String file, IParser parser){ + String output = null; + int lineNumber = -1; + + try { + lineNumber = parser.getLineNumberForOffset(parser.getLastErrorOffset()); + } catch (Exception ex) {} + + if (e instanceof AssertionFailedError) { + output = file + ": Parse failed on line "; + output += lineNumber + "\n"; + } else { + output = file + ": " + e.getClass().toString(); + output += " on line " + lineNumber + "\n"; + } + try { + if (report != null) { + report.write(output.getBytes()); + } + } catch (IOException ex) {} + + fail(output); + } + + + static protected boolean isExpectedToPass (String testCode) + { + // Process some DejaGNU instructions + if (testCode.indexOf("{ dg-do run") >= 0) return true; + if (testCode.indexOf("{ dg-do link") >= 0) return true; + if (testCode.indexOf("{ dg-error") >= 0) return false; + if (testCode.indexOf("// ERROR") >= 0) return false; + if (testCode.indexOf("- ERROR") >= 0) return false; + if (testCode.indexOf("// XFAIL") >= 0) return false; + if (testCode.indexOf("{ xfail") >= 0) return false; + if (testCode.indexOf("{ dg-preprocess") >= 0) return false; + + return true; + } + + + public void doFile() throws Throwable { + assertNotNull (fileList); + + File file = (File)fileList.removeFirst(); + FileInputStream stream = new FileInputStream(file); + + String filePath = file.getCanonicalPath(); + String nature = (String)natures.get(filePath); + + StringWriter code = new StringWriter(); + + byte b[] = new byte[stepSize]; + int n = stream.read(b); + while( n != -1 ){ + code.write(new String(b)); + n = stream.read(b); + } + + String testCode = code.toString(); + + if (isExpectedToPass(testCode)) { + ParseThread thread = new ParseThread(); + + thread.quickParse = quickParse; + thread.code = testCode; + thread.cppNature = nature.equalsIgnoreCase("cpp"); + thread.file = filePath; + + thread.start(); + thread.join(timeOut); + + if (thread.isAlive()) { + thread.stop(); + reportHang(testCode, filePath); + } else if (thread.result != null) { + reportException(thread.result, filePath, thread.parser); + } + } else { + // gcc probably didn't expect this test to pass. + // It doesn't mean that it should pass CDT parser, + // as it is more relaxed + // Result - 'inconclusive', but we report 'pass' + assertTrue(true); + } + } + + + + static class ParseThread extends Thread { + public String code; + public boolean cppNature; + public String file; + public Throwable result = null; + public IParser parser = null; + public boolean quickParse = true; + + public void run(){ + try { + DOMBuilder domBuilder = new DOMBuilder(); + parser = new Parser(code.toString(), domBuilder, quickParse); + + parser.setCppNature(cppNature); + parser.mapLineNumbers(true); + + assertTrue(parser.parse()); + } + catch( Throwable e ) + { + result = e; + } + } + } +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/XMLDumper.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/XMLDumper.java new file mode 100644 index 00000000000..0221d0d25c0 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/XMLDumper.java @@ -0,0 +1,138 @@ +package org.eclipse.cdt.core.parser.tests; + +import java.io.IOException; +import java.io.StringWriter; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.HashMap; + +import org.apache.xerces.dom.DocumentImpl; +import org.apache.xml.serialize.OutputFormat; +import org.apache.xml.serialize.XMLSerializer; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * This class implements a utility that will walk through an object + * and it's children and create an XML file for it. + */ +public class XMLDumper { + + public static class Test { + private String msg = "hi"; + + public String getMsg() { + return msg; + } + + public Test self = this; + } + + public static void main(String [] args) { + Test test = new Test(); + XMLDumper dumper = new XMLDumper(test); + Document document = dumper.getDocument(); + + OutputFormat format = new OutputFormat( document ); //Serialize DOM + StringWriter stringOut = new StringWriter(); //Writer will be a String + XMLSerializer serial = new XMLSerializer( stringOut, format ); + + try { + serial.asDOMSerializer(); // As a DOM Serializer + serial.serialize( document.getDocumentElement() ); + System.out.println( "STRXML = " + stringOut.toString() ); //Spit out DOM as a String + } catch (IOException e) { + System.out.println(e); + } + + } + + private int id = 0; + private HashMap map = new HashMap(); + private Document document = new DocumentImpl(); + + public Document getDocument() { + return document; + } + + public XMLDumper(Object obj) { + document.appendChild(createObject(obj)); + } + + private Element createObject(Object obj) { + Class cls = obj.getClass(); + String clsName = cls.getName(); + clsName = clsName.replace('$', '.'); + + Element element = document.createElement(clsName); + map.put(obj, new Integer(id)); + element.setAttribute("id",String.valueOf(id++)); + + Field [] fields = cls.getDeclaredFields(); + for (int i = 0; i < fields.length; ++i) { + Field field = fields[i]; + int modifiers = field.getModifiers(); + + // Skip over static fields + if (Modifier.isStatic(modifiers)) + continue; + + // Skip fields that start with an underscore + if (field.getName().charAt(0) == '_') + continue; + + Object value = null; + + String fieldName = field.getName(); + if (Modifier.isPublic(modifiers)) { + try { + value = field.get(obj); + } catch (Exception e) { + value = e; + } + } else { + String methodName = "get" + + fieldName.substring(0, 1).toUpperCase() + + fieldName.substring(1); + + Method method = null; + try { + method = cls.getMethod(methodName, null); + } catch (NoSuchMethodException e) { + continue; + } + + try { + value = method.invoke(obj, null); + } catch (Exception e) { + value = e; + } + } + + Element fieldElement = document.createElement(fieldName); + element.appendChild(fieldElement); + + if (value == null) + return element; + + Class type = field.getType(); + if (String.class.isAssignableFrom(type)) + fieldElement.appendChild(document.createTextNode((String)value)); + else if (Integer.class.isAssignableFrom(type)) + fieldElement.appendChild(document.createTextNode(((Integer)value).toString())); + else if (Exception.class.isAssignableFrom(type)) + fieldElement.appendChild(document.createTextNode(value.toString())); + else { + Object v = map.get(value); + if (v != null) + fieldElement.setAttribute("refid", v.toString()); + else + fieldElement.appendChild(createObject(value)); + } + + } + + return element; + } +} diff --git a/core/org.eclipse.cdt.core.tests/plugin.xml b/core/org.eclipse.cdt.core.tests/plugin.xml new file mode 100644 index 00000000000..52623d5209b --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/plugin.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/org.eclipse.cdt.core.tests/resources/cfiles/CModelElementsTestStart.h b/core/org.eclipse.cdt.core.tests/resources/cfiles/CModelElementsTestStart.h new file mode 100644 index 00000000000..4e29ffba657 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/cfiles/CModelElementsTestStart.h @@ -0,0 +1,138 @@ +// include +#include + +// macro +#define PRINT(string,msg) printf(string, msg) + +//namespace +namespace MyPackage +{ + // check class + // class + class Hello + { + // protected visibility + protected: + // field + int x; + // method + inline void setX(int X) + { + x = X; + }; + // check nested pachage + // nested namespace + namespace MyNestedPackage { + // check parent nested class + // nested class + class Y + { // public visibility + public: + // constructor + Y(); + // virtual destructor + virtual ~Y(); + }; + // check derived nested class + // derived class + class X : public Y { + // private visibility + private: + // private field + B b; + + public: + // constructor chain + X(int x) : yy(x) { + cout << "In consturctor\n"; + } + // method declaration + int doNothing(); + }; + } + }; + + // check enums + // enum without name + enum { + first, + second, + third + } + ; + // enum with name + enum MyEnum { + f, + s, + t }; + + // check variables + // variable + int v; + // unsigned long variable + unsigned long vuLong; + // unsigned short variable + unsigned short vuShort; + + // check variable declarations + // variable declaration + extern int evar; + // function pointer + static void * (*orig_malloc_hook)(const char *file, int line, size_t size); + + // check functions + // simple function declaration + void foo(); + // function declaration with parameters + char* foo(int& x, + char**y); + // simple function definition + void boo(){ + int g = 0; + }; + // check Structs + // struct + struct MyStruct{ + int sint; + }; + // typedef and elaborated types + typedef struct MyStruct myStruct; + // typedef + typedef struct{ + int ss; + } myTypedef; + // unions + union U{ + int U1; + }; + + + // check templates + // template function + template + A aTemplatedFunction( B bInstance ); + // template method + class enclosing { + // public visibility + public: + template + A aTemplatedMethod( B bInstance ); + }; + // template class + template + class myarray { /* */ }; + // template struct + template + struct mystruct { /* */ }; + // template variable + template + char* default_alloc_template<__threads, __inst>::_S_start_free = 0; +}; + // check arrays + // arrays + int myArray [5][]; + int main(int argc, char * argv[]) + { + } + + diff --git a/core/org.eclipse.cdt.core.tests/resources/cfiles/TranslationUnits.c b/core/org.eclipse.cdt.core.tests/resources/cfiles/TranslationUnits.c new file mode 100644 index 00000000000..b4f8bf60115 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/cfiles/TranslationUnits.c @@ -0,0 +1,68 @@ +/* + * (c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + */ +/******** + * This is a sample C file that will be used in testing the TranslationUnit + * class. It has a specific structure that will be looked for within the + * test case. + * This file is only ment to contain various C elements, and may not compile + * into a running application (but should be valid C) + */ + +#include +#include + +/* A function prototype */ +int func2p(void); + +/* A global variable */ +int globalvar; + +/* A enumeration */ +enum myenum {ENUM_A=1, ENUM_B=2, ENUM_C=3, ENUM_D=4}; + +/* A structure. This also includes a typedef around the strcture def + * which at the time of writing was not picked up. + */ +typedef struct mystruct { + int a; + char b; + long c; +} mystruct_t; + +/* A union */ +union myunion { + int x; + char y; + long z; +}; + +/* A typedef */ +typedef struct mystruct mytype; + + +/* A couple functions */ + +void * func1(void) +{ + return(NULL); +} + + +int func2(void) +{ + return(0); +} + +int main(int argc, char ** argv) +{ + int var1; + printf("Hello world\n"); +} + + +void func3() +{ + printf("This is not really here\n"); +} diff --git a/core/org.eclipse.cdt.core.tests/resources/cfiles/WorkingCopyTestStart.h b/core/org.eclipse.cdt.core.tests/resources/cfiles/WorkingCopyTestStart.h new file mode 100644 index 00000000000..10b222ccb50 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/cfiles/WorkingCopyTestStart.h @@ -0,0 +1,2 @@ +#include + diff --git a/core/org.eclipse.cdt.core.tests/resources/cmodel/IIncludeTest.h b/core/org.eclipse.cdt.core.tests/resources/cmodel/IIncludeTest.h new file mode 100644 index 00000000000..7083fa8d77d --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/cmodel/IIncludeTest.h @@ -0,0 +1,42 @@ +// include +#include +#include "whatever.h" +#include +#include +#include "Program Files/space.h" +#include "../up1dir.h" +#include "./samedir.h" +#include "different_extension1.hpp" +#include "different_extension2.hh" +#include "different_extension3.x" +#include +# include "whitespace_after_hash" + #include "whitespace_before_hash" + +// failure cases: +#include garbage +#include "resync_after_bad_parse_1" +#include +#include "resync_after_bad_parse_2" +#include "one" "two" "three" +#include "resync_after_bad_parse_3" + +// from the Spec: + +// from [C, 6.10.p8] +// should fail +#define EMPTY +EMPTY #include "invalid.h" + +// from [C, 6.10.2.p8]: +// should equal #include "myInclude1.h" +#define MYINCFILE "myInclude1.h" +#include MYINCFILE + +// from [C, 6.10.3.5.p6]: +// should equal #include "vers2.h" +#define INCFILE(x) vers ## x +#define xstr(x) str(x) +#define str(x) #x +#include xstr(INCFILE(2)).h + diff --git a/core/org.eclipse.cdt.core.tests/resources/cmodel/IMacroTest.h b/core/org.eclipse.cdt.core.tests/resources/cmodel/IMacroTest.h new file mode 100644 index 00000000000..a5bf320efab --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/cmodel/IMacroTest.h @@ -0,0 +1,4 @@ +// macro +#define SINGLETON +#define NUMBER 1 +#define PRINT(string,msg) printf(string, msg) diff --git a/core/org.eclipse.cdt.core.tests/resources/cmodel/IStructure.c b/core/org.eclipse.cdt.core.tests/resources/cmodel/IStructure.c new file mode 100644 index 00000000000..c46b043df41 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/cmodel/IStructure.c @@ -0,0 +1,88 @@ +// IStructure +struct testStruct1 { + char m_field1; + char* m_field2; + unsigned char m_field3; + int m_field4; + unsigned m_field5; + void* m_field6; + + void method1(); + struct testStruct1 method2( char* in_field2, int in_field4 ) {} + // this is very C++: + testStruct1( char* in_field2, int in_field4 ) {} + ~testStruct1() {} +}; + +struct testStruct2 { +}; + +struct testStruct3 { +} aTestStruct3; + +// no semicolon, parser should recover +struct testStruct4NoSemicolon { +} + +// forward declaration +struct testStruct5; + +// variable declaration using predefined struct. +struct testStruct6 aTestStruct6; + +struct { + int x; +} testAnonymousStructObject1; + +struct { + int x; +} testAnonymousStructObject2= {1}; + +// to resync the parser if necessary +struct testStruct7 { +}; + +// an inner struct +struct testStruct8 { + struct testStruct9Inner { + int x; + }; + struct testStruct10Inner { + int y; + struct testStruct11Inner { + int z; + }; + }; +}; + +union testUnion1 { + char m_field1; + char* m_field2; + unsigned char m_field3; + int m_field4; + unsigned m_field5; + void* m_field6; +}; + +class testClass1 { +}; + +class testClass2NoSemicolon { +} + +class testClass3 { +}; + +class testClass4Abstract { + void aNonVirtual(); + virtual void aVirtual(); + virtual void aPureVirtual()=0; +}; + +class testClass5 +: public testClass1, protected testClass3, private testClass4Abstract { +}; + +// to resync the parser if necessary +class testClass6 { +}; diff --git a/core/org.eclipse.cdt.core.tests/resources/cmodel/IStructureTemplate.cpp b/core/org.eclipse.cdt.core.tests/resources/cmodel/IStructureTemplate.cpp new file mode 100644 index 00000000000..fb283bc2847 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/cmodel/IStructureTemplate.cpp @@ -0,0 +1,15 @@ +int z; + +template class nonVector { + public: + int x; + int y; + + T* head; + vector() { head =new T(); } + int length() { return 1; } + T& first() { return *head; } + const T& first() const { return *head; } +}; + + diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/Makefile b/core/org.eclipse.cdt.core.tests/resources/exe/Makefile new file mode 100644 index 00000000000..0e22650c04c --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/Makefile @@ -0,0 +1,8 @@ +LIST=VARIANT +ifndef QRECURSE +QRECURSE=recurse.mk +ifdef QCONFIG +QRDIR=$(dir $(QCONFIG)) +endif +endif +include $(QRDIR)$(QRECURSE) diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/common.mk b/core/org.eclipse.cdt.core.tests/resources/exe/common.mk new file mode 100644 index 00000000000..6e21c521623 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/common.mk @@ -0,0 +1,7 @@ +ifndef QCONFIG +QCONFIG=qconfig.mk +endif +include $(QCONFIG) +USEFILE= +LIBS+=socket +include $(MKFILES_ROOT)/qtargets.mk diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/main.c b/core/org.eclipse.cdt.core.tests/resources/exe/main.c new file mode 100644 index 00000000000..62952639754 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/main.c @@ -0,0 +1,7 @@ +#include + +int main() +{ + printf("Hello there\n"); + return(0); +} diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/ppc/Makefile b/core/org.eclipse.cdt.core.tests/resources/exe/ppc/Makefile new file mode 100644 index 00000000000..0e22650c04c --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/ppc/Makefile @@ -0,0 +1,8 @@ +LIST=VARIANT +ifndef QRECURSE +QRECURSE=recurse.mk +ifdef QCONFIG +QRDIR=$(dir $(QCONFIG)) +endif +endif +include $(QRDIR)$(QRECURSE) diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/ppc/be.g/Makefile b/core/org.eclipse.cdt.core.tests/resources/exe/ppc/be.g/Makefile new file mode 100644 index 00000000000..2c760893e32 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/ppc/be.g/Makefile @@ -0,0 +1 @@ +include ../../common.mk diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/ppc/be.g/exe_g b/core/org.eclipse.cdt.core.tests/resources/exe/ppc/be.g/exe_g new file mode 100644 index 00000000000..1c54db11d20 Binary files /dev/null and b/core/org.eclipse.cdt.core.tests/resources/exe/ppc/be.g/exe_g differ diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/ppc/be.g/main.o b/core/org.eclipse.cdt.core.tests/resources/exe/ppc/be.g/main.o new file mode 100644 index 00000000000..41e9e97110e Binary files /dev/null and b/core/org.eclipse.cdt.core.tests/resources/exe/ppc/be.g/main.o differ diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/ppc/be.g/test.o b/core/org.eclipse.cdt.core.tests/resources/exe/ppc/be.g/test.o new file mode 100644 index 00000000000..9a35dfb2cf9 Binary files /dev/null and b/core/org.eclipse.cdt.core.tests/resources/exe/ppc/be.g/test.o differ diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/ppc/be.g/test2.o b/core/org.eclipse.cdt.core.tests/resources/exe/ppc/be.g/test2.o new file mode 100644 index 00000000000..bae3191b475 Binary files /dev/null and b/core/org.eclipse.cdt.core.tests/resources/exe/ppc/be.g/test2.o differ diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/test.c b/core/org.eclipse.cdt.core.tests/resources/exe/test.c new file mode 100644 index 00000000000..23baffafb31 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/test.c @@ -0,0 +1,14 @@ +#include + + +int func1 (void) +{ + printf("This is func1\n"); + return(1); +} + +char * func2(void) +{ + printf("This is func2\n"); + return(0); +} diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/test2.c b/core/org.eclipse.cdt.core.tests/resources/exe/test2.c new file mode 100644 index 00000000000..7b26241b059 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/test2.c @@ -0,0 +1,13 @@ +#include + +int test2func1(void) +{ + printf("This is a function in the second object\n"); + return(1); +} + +int test2func2(void) +{ + printf("This is another function in the second object\n"); + return(2); +} diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/x86/Makefile b/core/org.eclipse.cdt.core.tests/resources/exe/x86/Makefile new file mode 100644 index 00000000000..0e22650c04c --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/x86/Makefile @@ -0,0 +1,8 @@ +LIST=VARIANT +ifndef QRECURSE +QRECURSE=recurse.mk +ifdef QCONFIG +QRDIR=$(dir $(QCONFIG)) +endif +endif +include $(QRDIR)$(QRECURSE) diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/x86/o.g/Makefile b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o.g/Makefile new file mode 100644 index 00000000000..2c760893e32 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o.g/Makefile @@ -0,0 +1 @@ +include ../../common.mk diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/x86/o.g/exe_g b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o.g/exe_g new file mode 100644 index 00000000000..465e16de33d Binary files /dev/null and b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o.g/exe_g differ diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/x86/o.g/main.o b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o.g/main.o new file mode 100644 index 00000000000..8c61c21f50d Binary files /dev/null and b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o.g/main.o differ diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/x86/o.g/test.o b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o.g/test.o new file mode 100644 index 00000000000..5f956885cbf Binary files /dev/null and b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o.g/test.o differ diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/x86/o.g/test2.o b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o.g/test2.o new file mode 100644 index 00000000000..aa8de348603 Binary files /dev/null and b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o.g/test2.o differ diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/x86/o/Makefile b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o/Makefile new file mode 100644 index 00000000000..2c760893e32 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o/Makefile @@ -0,0 +1 @@ +include ../../common.mk diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/x86/o/exe b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o/exe new file mode 100644 index 00000000000..d13631162d7 Binary files /dev/null and b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o/exe differ diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/x86/o/main.o b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o/main.o new file mode 100644 index 00000000000..a5c78c1ca4e Binary files /dev/null and b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o/main.o differ diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/x86/o/test.o b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o/test.o new file mode 100644 index 00000000000..357c3985ea1 Binary files /dev/null and b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o/test.o differ diff --git a/core/org.eclipse.cdt.core.tests/resources/exe/x86/o/test2.o b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o/test2.o new file mode 100644 index 00000000000..52e88a7397b Binary files /dev/null and b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o/test2.o differ diff --git a/core/org.eclipse.cdt.core.tests/resources/exebig/Makefile b/core/org.eclipse.cdt.core.tests/resources/exebig/Makefile new file mode 100644 index 00000000000..0e22650c04c --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exebig/Makefile @@ -0,0 +1,8 @@ +LIST=VARIANT +ifndef QRECURSE +QRECURSE=recurse.mk +ifdef QCONFIG +QRDIR=$(dir $(QCONFIG)) +endif +endif +include $(QRDIR)$(QRECURSE) diff --git a/core/org.eclipse.cdt.core.tests/resources/exebig/common.mk b/core/org.eclipse.cdt.core.tests/resources/exebig/common.mk new file mode 100644 index 00000000000..80c1e67f6f8 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exebig/common.mk @@ -0,0 +1,7 @@ +ifndef QCONFIG +QCONFIG=qconfig.mk +endif +include $(QCONFIG) +USEFILE= + +include $(MKFILES_ROOT)/qtargets.mk diff --git a/core/org.eclipse.cdt.core.tests/resources/exebig/main.c b/core/org.eclipse.cdt.core.tests/resources/exebig/main.c new file mode 100644 index 00000000000..ce93b899e09 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exebig/main.c @@ -0,0 +1,8 @@ +#include +int bigArray[100]; +int x[10]={1,2,3,4,5,6,7,8,9,0}; +int main() +{ + printf("Hello there\n"); + return(0); +} diff --git a/core/org.eclipse.cdt.core.tests/resources/exebig/x86/Makefile b/core/org.eclipse.cdt.core.tests/resources/exebig/x86/Makefile new file mode 100644 index 00000000000..0e22650c04c --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exebig/x86/Makefile @@ -0,0 +1,8 @@ +LIST=VARIANT +ifndef QRECURSE +QRECURSE=recurse.mk +ifdef QCONFIG +QRDIR=$(dir $(QCONFIG)) +endif +endif +include $(QRDIR)$(QRECURSE) diff --git a/core/org.eclipse.cdt.core.tests/resources/exebig/x86/o.g/Makefile b/core/org.eclipse.cdt.core.tests/resources/exebig/x86/o.g/Makefile new file mode 100644 index 00000000000..2c760893e32 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exebig/x86/o.g/Makefile @@ -0,0 +1 @@ +include ../../common.mk diff --git a/core/org.eclipse.cdt.core.tests/resources/exebig/x86/o.g/exebig_g b/core/org.eclipse.cdt.core.tests/resources/exebig/x86/o.g/exebig_g new file mode 100644 index 00000000000..3aacf6267c5 Binary files /dev/null and b/core/org.eclipse.cdt.core.tests/resources/exebig/x86/o.g/exebig_g differ diff --git a/core/org.eclipse.cdt.core.tests/resources/exebig/x86/o.g/main.o b/core/org.eclipse.cdt.core.tests/resources/exebig/x86/o.g/main.o new file mode 100644 index 00000000000..e7d818de524 Binary files /dev/null and b/core/org.eclipse.cdt.core.tests/resources/exebig/x86/o.g/main.o differ diff --git a/core/org.eclipse.cdt.core.tests/resources/parser/AutomatedTest/AutomatedTest.properties b/core/org.eclipse.cdt.core.tests/resources/parser/AutomatedTest/AutomatedTest.properties new file mode 100644 index 00000000000..9ebeb85d2dc --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/parser/AutomatedTest/AutomatedTest.properties @@ -0,0 +1,13 @@ +# Format of this property file is: +# outputFile = +# source = , +# Multiple source properties may be concatenated. +# By default, no outputFile is produced. +# By default, the test will use: +# source = ./defaultC, c +# source = ./defaultCpp, cpp + +#outputFile = Z:\\CDT\\reportRTS.txt +#source = Z:/V651/Release/C++/TargetRTS, cpp + +#source = D:/temp/test, cpp diff --git a/core/org.eclipse.cdt.core.tests/resources/parser/AutomatedTest/FractionalAutomatedTest.properties b/core/org.eclipse.cdt.core.tests/resources/parser/AutomatedTest/FractionalAutomatedTest.properties new file mode 100644 index 00000000000..45ccd56ab5b --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/parser/AutomatedTest/FractionalAutomatedTest.properties @@ -0,0 +1,17 @@ +# Format of this property file is: +# outputFile = +# source = , +# Multiple source properties may be concatenated. +# By default, no outputFile is produced. +# By default, the test will use: +# source = ./defaultC, c +# source = ./defaultCpp, cpp +# +# outputFile = Z:\\CDT\\reportFrac.txt +#source = Z:/V651/Release/C++/TargetRTS, cpp +#source = D:/temp/test, cpp +#source = Z:/CDT/test/include, cpp \ +# Z:/CDT/test/src, cpp +#source = D:\\ACE+TAO\\ACE_wrappers, cpp +# source = D:\\ACE+TAO\\ACE_wrappers\\ace\\config-psos-diab-mips.h, cpp +# outDir = Z:\\CDT\\temp diff --git a/core/org.eclipse.cdt.core.tests/resources/parser/AutomatedTest/defaultC/Simple.c b/core/org.eclipse.cdt.core.tests/resources/parser/AutomatedTest/defaultC/Simple.c new file mode 100644 index 00000000000..e7d2a2e016f --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/parser/AutomatedTest/defaultC/Simple.c @@ -0,0 +1,43 @@ +#include + +const SimpleStruct simpleStruct = +{ + 1 + , "mySimple" + , 0.1232 +}; + +#define SIZEOF( A, B ) sizeof( A.B ) + +const OtherStruct array[] = +{ + { +#if FOO + "foo" +#else + "bar" +#endif + , SIZEOF( simpleStruct, num ) + , &t_int + , 0 + } + , { + "name" + , SIZEOF( simpleStruct, floatnum ) + , &t_float + , 1 + } +}; + + +void SimpleStruct_construct( struct SimpleStruct * const this ) +{ + this->num = 1; + this->name = "boo"; + this->floatNum = 1.5; +} + +int ConnectParams_doSomething( const struct SimpleStruct * const this ) +{ + return 1; +} diff --git a/core/org.eclipse.cdt.core.tests/resources/parser/AutomatedTest/defaultC/Simple.h b/core/org.eclipse.cdt.core.tests/resources/parser/AutomatedTest/defaultC/Simple.h new file mode 100644 index 00000000000..96e8ef0a741 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/parser/AutomatedTest/defaultC/Simple.h @@ -0,0 +1,17 @@ +#ifndef SIMPLE_H +#define SIMPLE_H + +struct SimpleStruct +{ + int num; + char name[ ]; + float floatNum; +}; + + +void SimpleStruct_construct( struct SimpleStruct * const this ); + +int SimpleStruct_doSomething( const struct SimpleStruct * const this ); + +#endif /* SIMPLE_H */ + diff --git a/core/org.eclipse.cdt.core.tests/resources/parser/AutomatedTest/defaultCpp/Simple.cpp b/core/org.eclipse.cdt.core.tests/resources/parser/AutomatedTest/defaultCpp/Simple.cpp new file mode 100644 index 00000000000..4b4055ade2d --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/parser/AutomatedTest/defaultCpp/Simple.cpp @@ -0,0 +1,37 @@ +#include + +#include + +#define NULL (void *)0 + +SimpleClass::SimpleClass( void ) +{ + init( NULL ); +} + +SimpleClass::~SimpleClass( void ) +{ +} + +SimpleClass::SimpleClass( const SimpleClass & arg ) +{ + //TODO: copy constructor +} + +SimpleClass & SimpleClass::operator=( const SimpleClass & arg ) +{ + if( this != &arg ) + { + } + return *this; +} + + +void SimpleClass::init( void * foo) +{ +} + +InnerStruct & SimpleClass::getInner( void ) +{ + return inner; +} diff --git a/core/org.eclipse.cdt.core.tests/resources/parser/AutomatedTest/defaultCpp/Simple.h b/core/org.eclipse.cdt.core.tests/resources/parser/AutomatedTest/defaultCpp/Simple.h new file mode 100644 index 00000000000..e22c5eefbd0 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/parser/AutomatedTest/defaultCpp/Simple.h @@ -0,0 +1,32 @@ +#ifndef SIMPLE_H +#define SIMPLE_H + +class OtherClass; + +class SimpleClass +{ +public: + SimpleClass( void ); + SimpleClass( const SimpleClass & arg ); + + virtual ~SimpleClass( void ); + + SimpleClass & operator=( const SimpleClass & arg ); + +private: + struct InnerStruct + { + inline InnerStruct( int a ){ _a = a; } + inline ~InnerStruct( void ){} + unsigned int _a; + }; + + InnerStruct inner; + + void init( void * ); + +public: + InnerStruct & getInner( void ); +}; + +#endif /* SIMPLE_H */ diff --git a/core/org.eclipse.cdt.core.tests/resources/parser/LineNumberTest.h b/core/org.eclipse.cdt.core.tests/resources/parser/LineNumberTest.h new file mode 100644 index 00000000000..16b506364f0 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/parser/LineNumberTest.h @@ -0,0 +1,43 @@ +// inclusion begins and ends on line 2 +#include + +// simple macro begins and ends on line 5; ANOTHER on line 6 +#define SIMPLE_MACRO simple +#define ANOTHER +// namespace begins on line 7, ends on line 22 +namespace MyPackage{ + // class specification begins on line 10, ends on line 21 + class Hello{ + protected: + // simple declaration begins and ends on line 13 + int x; + // simple declaration begins and ends on line 15 + void setX(int X); + public: + // simple declaration begins on line 18 and ends on line 20 + Hello( void ) : x + ( 5 ) { + } + }; +} + +// simple declaration begins on line 25 and ends on line 27 +int * + y = + 0; + +// complex macro begins on line 30 and ends on line 31 +#define COMPLEX_MACRO 33 \ + + 44 + +// template declaration begins on line 34 and ends on line 35 +template + A createA( void ); + +// enumeration begins on line 38 and ends on line 43 +enum { + one, // enumerator begins and ends on line 39 + two, // enumerator begins and ends on line 40 + three // enumerator begins on line 41, ends on line 42 + = 4 +}; \ No newline at end of file diff --git a/core/org.eclipse.cdt.core.tests/resources/parser/TortureTest/ReadMe-TortureText.txt b/core/org.eclipse.cdt.core.tests/resources/parser/TortureTest/ReadMe-TortureText.txt new file mode 100644 index 00000000000..87c1c0884f1 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/parser/TortureTest/ReadMe-TortureText.txt @@ -0,0 +1,31 @@ +Usage: +By default, torture testing is disabled. To enable it, create a 'TortureTest.properties' in 'org.eclipse.cdt.ui.tests\parser\org\eclipse\cdt\core\parser\resources'. + +If you don't have GCC testsuites, it does nothing. Then go and grab your latest version of GCC testsuites +(for instance, ftp://ftp.fu-berlin.de/unix/gnu/gcc/gcc-3.3/gcc-testsuite-3.3.tar.gz). +Unpack testsuites under + + org.eclipse.cdt.core.tests/resources/parser/TortureTest/default + +or elsewhere, but then you'll need to create a 'TortureTest.properties'. +That's it, you can run TortureTest in JUnit Plugin mode. Don't run all ui.tests with torture-test enabled, as apparently it is included several times (anyone knows why?) +, and it's A LOT of test cases. + +You can copy the rest of the file to create a TortureTest.properties and uncomment out/edit the default values as specified here. + +# By default, torture testing is disabled +# Uncomment to enable +#enabled=true + +# Default location is org.eclipse.cdt.core.tests/resources/parser/TortureTest/default +#source=/your/gcc/testsuite/installation/directory + +# Chunks for reading files +#stepSize=25000 + +# Timeout for individual cases, ms +# Need a large enough value, as some files are non-trivial +#timeOut=60000 + +# Quick parse, or not +#quickParse=true diff --git a/core/org.eclipse.cdt.core.tests/resources/parser/TortureTest/TortureTest.properties b/core/org.eclipse.cdt.core.tests/resources/parser/TortureTest/TortureTest.properties new file mode 100644 index 00000000000..01f12c04957 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/parser/TortureTest/TortureTest.properties @@ -0,0 +1,31 @@ +#Usage: +#By default, torture testing is disabled. To enable it, create a 'TortureTest.properties' in 'org.eclipse.cdt.ui.tests\parser\org\eclipse\cdt\core\parser\resources'. +# +#If you don't have GCC testsuites, it does nothing. Then go and grab your latest version of GCC testsuites +#(for instance, ftp://ftp.fu-berlin.de/unix/gnu/gcc/gcc-3.3/gcc-testsuite-3.3.tar.gz). +#Unpack testsuites under +# +# org.eclipse.cdt.core.tests/resources/parser/TortureTest/default +# +#or elsewhere, but then you'll need to create a 'TortureTest.properties'. +#That's it, you can run TortureTest in JUnit Plugin mode. Don't run all ui.tests with torture-test enabled, as apparently it is included several times (anyone knows why?) +#, and it's A LOT of test cases. +# +#You can copy the rest of the file to create a TortureTest.properties and uncomment out/edit the default values as specified here. +# +# By default, torture testing is disabled +# Uncomment to enable +enabled=true + +# Default location is org.eclipse.cdt.core.tests/resources/parser/TortureTest/default +#source=/your/gcc/testsuite/installation/directory + +# Chunks for reading files +#stepSize=25000 + +# Timeout for individual cases, ms +# Need a large enough value, as some files are non-trivial +#timeOut=60000 + +# Quick parse, or not +#quickParse=true diff --git a/core/org.eclipse.cdt.core.tests/resources/testlib/Makefile b/core/org.eclipse.cdt.core.tests/resources/testlib/Makefile new file mode 100644 index 00000000000..0e22650c04c --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/testlib/Makefile @@ -0,0 +1,8 @@ +LIST=VARIANT +ifndef QRECURSE +QRECURSE=recurse.mk +ifdef QCONFIG +QRDIR=$(dir $(QCONFIG)) +endif +endif +include $(QRDIR)$(QRECURSE) diff --git a/core/org.eclipse.cdt.core.tests/resources/testlib/common.mk b/core/org.eclipse.cdt.core.tests/resources/testlib/common.mk new file mode 100644 index 00000000000..dd99ed569bc --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/testlib/common.mk @@ -0,0 +1,6 @@ +ifndef QCONFIG +QCONFIG=qconfig.mk +endif +include $(QCONFIG) + +include $(MKFILES_ROOT)/qtargets.mk diff --git a/core/org.eclipse.cdt.core.tests/resources/testlib/test.c b/core/org.eclipse.cdt.core.tests/resources/testlib/test.c new file mode 100644 index 00000000000..23baffafb31 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/testlib/test.c @@ -0,0 +1,14 @@ +#include + + +int func1 (void) +{ + printf("This is func1\n"); + return(1); +} + +char * func2(void) +{ + printf("This is func2\n"); + return(0); +} diff --git a/core/org.eclipse.cdt.core.tests/resources/testlib/test2.c b/core/org.eclipse.cdt.core.tests/resources/testlib/test2.c new file mode 100644 index 00000000000..7b26241b059 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/testlib/test2.c @@ -0,0 +1,13 @@ +#include + +int test2func1(void) +{ + printf("This is a function in the second object\n"); + return(1); +} + +int test2func2(void) +{ + printf("This is another function in the second object\n"); + return(2); +} diff --git a/core/org.eclipse.cdt.core.tests/resources/testlib/x86/Makefile b/core/org.eclipse.cdt.core.tests/resources/testlib/x86/Makefile new file mode 100644 index 00000000000..0e22650c04c --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/testlib/x86/Makefile @@ -0,0 +1,8 @@ +LIST=VARIANT +ifndef QRECURSE +QRECURSE=recurse.mk +ifdef QCONFIG +QRDIR=$(dir $(QCONFIG)) +endif +endif +include $(QRDIR)$(QRECURSE) diff --git a/core/org.eclipse.cdt.core.tests/resources/testlib/x86/a.g/Makefile b/core/org.eclipse.cdt.core.tests/resources/testlib/x86/a.g/Makefile new file mode 100644 index 00000000000..2c760893e32 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/testlib/x86/a.g/Makefile @@ -0,0 +1 @@ +include ../../common.mk diff --git a/core/org.eclipse.cdt.core.tests/resources/testlib/x86/a.g/test.o b/core/org.eclipse.cdt.core.tests/resources/testlib/x86/a.g/test.o new file mode 100644 index 00000000000..a12942b1527 Binary files /dev/null and b/core/org.eclipse.cdt.core.tests/resources/testlib/x86/a.g/test.o differ diff --git a/core/org.eclipse.cdt.core.tests/resources/testlib/x86/a.g/test2.o b/core/org.eclipse.cdt.core.tests/resources/testlib/x86/a.g/test2.o new file mode 100644 index 00000000000..87e730cd7c5 Binary files /dev/null and b/core/org.eclipse.cdt.core.tests/resources/testlib/x86/a.g/test2.o differ diff --git a/core/org.eclipse.cdt.core.tests/resources/testlib/x86/so.g/Makefile b/core/org.eclipse.cdt.core.tests/resources/testlib/x86/so.g/Makefile new file mode 100644 index 00000000000..2c760893e32 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/testlib/x86/so.g/Makefile @@ -0,0 +1 @@ +include ../../common.mk diff --git a/core/org.eclipse.cdt.core.tests/resources/testlib/x86/so.g/test.o b/core/org.eclipse.cdt.core.tests/resources/testlib/x86/so.g/test.o new file mode 100644 index 00000000000..c9009cb22dc Binary files /dev/null and b/core/org.eclipse.cdt.core.tests/resources/testlib/x86/so.g/test.o differ diff --git a/core/org.eclipse.cdt.core.tests/resources/testlib/x86/so.g/test2.o b/core/org.eclipse.cdt.core.tests/resources/testlib/x86/so.g/test2.o new file mode 100644 index 00000000000..a13bcd826b8 Binary files /dev/null and b/core/org.eclipse.cdt.core.tests/resources/testlib/x86/so.g/test2.o differ diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AISResultPrinter.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AISResultPrinter.java new file mode 100644 index 00000000000..ad73bc20531 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AISResultPrinter.java @@ -0,0 +1,53 @@ +/* + * Created on Jun 5, 2003 + * + * To change the template for this generated file go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +package org.eclipse.cdt.core.suite; + +import java.io.PrintStream; + +import junit.framework.AssertionFailedError; +import junit.framework.Test; +import junit.textui.ResultPrinter; + +/** + * @author vhirsl + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public class AISResultPrinter extends ResultPrinter { + + /** + * @param writer + */ + public AISResultPrinter(PrintStream writer) { + super(writer); + } + + /* (non-Javadoc) + * @see junit.framework.TestListener#addFailure(junit.framework.Test, junit.framework.AssertionFailedError) + */ + public void addFailure(Test test, AssertionFailedError t) { + super.addFailure(test, t); + getWriter().print("---> "); + } + + /* (non-Javadoc) + * @see junit.framework.TestListener#addError(junit.framework.Test, java.lang.Throwable) + */ + public void addError(Test test, Throwable t) { + super.addError(test, t); + getWriter().print("---> "); + } + + /* (non-Javadoc) + * @see junit.framework.TestListener#startTest(junit.framework.Test) + */ + public void startTest(Test test) { + getWriter().print("."); + } + +} diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java new file mode 100644 index 00000000000..8d195362b4f --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java @@ -0,0 +1,306 @@ +/* + * Created on May 16, 2003 + * + * To change the template for this generated file go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +package org.eclipse.cdt.core.suite; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import junit.framework.TestResult; +import junit.framework.TestListener; +import junit.framework.AssertionFailedError; +import junit.textui.TestRunner; + +import java.text.DecimalFormat; +import java.util.ArrayList; + +import org.eclipse.core.boot.IPlatformRunnable; + +import org.eclipse.cdt.core.build.managed.tests.AllBuildTests; +import org.eclipse.cdt.core.model.tests.AllCoreTests; +import org.eclipse.cdt.core.model.tests.BinaryTests; +import org.eclipse.cdt.core.model.tests.ElementDeltaTests; +import org.eclipse.cdt.core.model.tests.WorkingCopyTests; +import org.eclipse.cdt.core.parser.failedTests.*; +import org.eclipse.cdt.core.parser.tests.ParserTestSuite; +import org.eclipse.cdt.core.model.failedTests.*; + +/** + * @author vhirsl + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ +public class AutomatedIntegrationSuite extends TestSuite + implements TestListener, IPlatformRunnable { + + private TestResult testResult = null; + private String currentTestName; + // success tests + private int numberOfSuccessTests = 0; + private int numberOfFailedSuccessTests = 0; + // failed tests for open bug reports + private int numberOfFailedTests = 0; + private int numberOfFailedFailedTests = 0; + // switching to failed tests + private boolean failedTests = false; + private boolean skipTest = false; + + + public AutomatedIntegrationSuite() {} + + public AutomatedIntegrationSuite(Class theClass, String name) { + super(theClass, name); + } + + public AutomatedIntegrationSuite(Class theClass) { + super(theClass); + } + + public AutomatedIntegrationSuite(String name) { + super(name); + } + + public static Test suite() { + final AutomatedIntegrationSuite suite = new AutomatedIntegrationSuite(); + + // First test to trigger report generation + suite.addTest(suite.new GenerateReport("startSuccessTests")); + + // Add all success tests + suite.addTest(AllBuildTests.suite()); + suite.addTest(ParserTestSuite.suite()); + suite.addTest(AllCoreTests.suite()); + suite.addTest(BinaryTests.suite()); + suite.addTest(ElementDeltaTests.suite()); + suite.addTest(WorkingCopyTests.suite()); + + // Last test to trigger report generation + suite.addTest(suite.new GenerateReport("startFailedTests")); + + // Add all failed tests + suite.addTestSuite(DOMFailedTest.class); + suite.addTestSuite(LokiFailures.class); + suite.addTestSuite(STLFailedTests.class); + suite.addTestSuite(CModelElementsFailedTests.class); + + // Last test to trigger report generation + suite.addTest(suite.new GenerateReport("generateReport")); + + return suite; + } + + /** + * Runs the tests and collects their result in a TestResult. + * Overloaded method + */ + public void run(TestResult result) { + // To get counts from the result + testResult = result; + // Add oneself as a listener + result.addListener(this); + // Call a base class method + super.run(result); + // Remove a listener + result.removeListener(this); + } + + + /** + * An error occurred. + */ + public void addError(Test test, Throwable t) { +// System.out.println("Error : " + test); +// System.out.println("\tReason : " + t); +// System.out.println("\tStack trace : "); +// t.printStackTrace(System.out); + } + /** + * A failure occurred. + */ + public void addFailure(Test test, AssertionFailedError t) { + if (failedTests) { + ++numberOfFailedFailedTests; + } + else { + ++numberOfFailedSuccessTests; + } +// System.out.println("Failure : " + test); +// System.out.println("\tReason : " + t); +// System.out.println("\tStackTrace : "); +// t.printStackTrace(System.out); + } + /** + * A test ended. + */ + public void endTest(Test test) { + if (currentTestName == null) { + System.out.println("Internal error - endTest: currentTestName == null"); + } + else { + if (skipTest) { + skipTest = false; + } + else { + if (failedTests) { + ++numberOfFailedTests; + // System.out.println(test); + } + else { + ++numberOfSuccessTests; + } + System.out.println(test); + } + currentTestName = null; + } + } + /** + * A test started. + */ + public void startTest(Test test) { + if (currentTestName != null) { + System.out.println("Internal error - startTest: currentTestName != null"); + } + else { + currentTestName = test.toString(); + } + } + + /* + * generateReport + * + * @author vhirsl + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ + protected void generateReport() { + int numberOfRuns = testResult.runCount(); + int numberOfFailures = testResult.failureCount(); + int numberOfErrors = testResult.errorCount(); + + System.out.println(); + System.out.println("*** Generating report: ***"); + System.out.println(); + System.out.println("\tNumber of runs: " + numberOfRuns); + System.out.println("\tNumber of failures: " + numberOfFailures); + System.out.println("\tNumber of errors: " + numberOfErrors); + float successRate = (numberOfRuns-numberOfFailures-numberOfErrors)/(float)numberOfRuns; + DecimalFormat df = new DecimalFormat("##.##%"); + System.out.println("Sanity success rate : " + df.format(successRate)); + System.out.println("\tNumber of success tests: " + numberOfSuccessTests); + System.out.println("\tNumber of failed tests: " + numberOfFailedTests); + successRate = numberOfSuccessTests/(float)(numberOfSuccessTests+numberOfFailedTests); + System.out.println("Expected success test rate : " + df.format(successRate)); + successRate = (numberOfSuccessTests-numberOfFailedSuccessTests)/ + (float)(numberOfSuccessTests+numberOfFailedTests-numberOfFailedFailedTests); + System.out.print("Observed success test rate : " + df.format(successRate)); + System.out.println(" (failed success tests = " + numberOfFailedSuccessTests + ", failed failed tests = " + numberOfFailedFailedTests + ")"); + System.out.println(); + } + + private void startSuccessTests() { + failedTests = false; + System.out.println(); + System.out.println("*** Starting success tests ***"); + System.out.println(); + } + + private void startFailedTests() { + failedTests = true; + System.out.println(); + System.out.println("*** Starting failed tests ***"); + System.out.println(); + } + + /* + * Public inner class to invoke generateReport + * + * @author vhirsl + * + * To change the template for this generated type comment go to + * Window>Preferences>Java>Code Generation>Code and Comments + */ + public class GenerateReport extends TestCase { + public GenerateReport(String name) { + super(name); + } + public GenerateReport(){} + + public void generateReport() { + // skip this one + AutomatedIntegrationSuite.this.skipTest = true; + + // Calls a method of the outer class + AutomatedIntegrationSuite.this.generateReport(); + } + + public void startSuccessTests() { + // skip this one + AutomatedIntegrationSuite.this.skipTest = true; + + // Calls a method of the outer class + AutomatedIntegrationSuite.this.startSuccessTests(); + } + + public void startFailedTests() { + // skip this one + AutomatedIntegrationSuite.this.skipTest = true; + + // Calls a method of the outer class + AutomatedIntegrationSuite.this.startFailedTests(); + } + + /* (non-Javadoc) + * @see junit.framework.Test#countTestCases() + * We don't want these test cases to be counted + */ + public int countTestCases() { + return 0; + } + } + + /* (non-Javadoc) + * @see org.eclipse.core.boot.IPlatformRunnable#run(java.lang.Object) + */ + public Object run(Object args) throws Exception { + // Used when started from as a regression test suite after the build + TestRunner testRunner = new TestRunner(new AISResultPrinter(System.out)); + TestResult testResult = testRunner.doRun(suite()); + + return prepareReport(testResult); + } + + protected ArrayList prepareReport(TestResult testResult) { + // TestRunner.run(suite()); + ArrayList efMessages = new ArrayList(); + int errorCount = testResult.errorCount(); + int failureCount = testResult.failureCount(); + if (errorCount > 0) { + String em = new String("There "); + em += (errorCount == 1)?"is ":"are "; + em += Integer.toString(errorCount); + em += " error"; + em += (errorCount == 1)?"!":"s!"; + efMessages.add(em); + } + if (failureCount > 0) { + String fm = new String("There "); + fm += (failureCount == 1)?"is ":"are "; + fm += Integer.toString(failureCount); + fm += " failure"; + fm += (failureCount == 1)?"!":"s!"; + efMessages.add(fm); + } + if (efMessages.isEmpty()) { + efMessages.add(new String("Regression test run SUCCESSFUL!")); + } + else { + efMessages.add(new String("Please see raw test suite output for details.")); + } + return efMessages; + } +} diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/CElementDecorator.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/CElementDecorator.java new file mode 100644 index 00000000000..b6b239f11a9 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/CElementDecorator.java @@ -0,0 +1,30 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package org.eclipse.cdt.testplugin; + +import org.eclipse.swt.graphics.Image; + +import org.eclipse.jface.viewers.ILabelDecorator; +import org.eclipse.jface.viewers.LabelProvider; + +/** + * Allows to test decorators for Java elements + */ +public class CElementDecorator extends LabelProvider implements ILabelDecorator { + + /* + * @see ILabelDecorator#decorateImage(Image, Object) + */ + public Image decorateImage(Image image, Object element) { + return null; + } + + /* + * @see ILabelDecorator#decorateText(String, Object) + */ + public String decorateText(String text, Object element) { + return text + "*"; + } +} diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/CProjectHelper.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/CProjectHelper.java new file mode 100644 index 00000000000..de65ed2ed8d --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/CProjectHelper.java @@ -0,0 +1,244 @@ +package org.eclipse.cdt.testplugin; + +import java.lang.reflect.InvocationTargetException; +import java.util.zip.ZipFile; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.CProjectNature; +import org.eclipse.cdt.core.model.IArchiveContainer; +import org.eclipse.cdt.core.model.IBinaryContainer; +import org.eclipse.cdt.core.model.ICContainer; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.ITranslationUnit; + +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.IArchive; +import org.eclipse.cdt.core.model.IBinary; +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IProjectDescription; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.ui.dialogs.IOverwriteQuery; +import org.eclipse.ui.wizards.datatransfer.ImportOperation; +import org.eclipse.ui.wizards.datatransfer.ZipFileStructureProvider; + +/** + * Helper methods to set up a ICProject. + */ +public class CProjectHelper { + + /** + * Creates a ICProject. + */ + public static ICProject createCProject(String projectName, String binFolderName) throws CoreException { + IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot(); + IProject project= root.getProject(projectName); + if (!project.exists()) { + project.create(null); + } else { + project.refreshLocal(IResource.DEPTH_INFINITE, null); + } + + if (!project.isOpen()) { + project.open(null); + } + + + if (!project.hasNature(CProjectNature.C_NATURE_ID)) { + addNatureToProject(project, CProjectNature.C_NATURE_ID, null); + } + + ICProject cproject = CCorePlugin.getDefault().getCoreModel().create(project); + + return cproject; + } + + /** + * Removes a ICProject. + */ + public static void delete(ICProject cproject) throws CoreException { + cproject.getProject().delete(true, true, null); + } + + + /** + * Adds a source container to a ICProject. + */ + public static ICContainer addSourceContainer(ICProject cproject, String containerName) throws CoreException { + IProject project= cproject.getProject(); + IContainer container= null; + if (containerName == null || containerName.length() == 0) { + container= project; + } else { + IFolder folder= project.getFolder(containerName); + if (!folder.exists()) { + folder.create(false, true, null); + } + container= folder; + } + + return (ICContainer)container; + } + + /** + * Adds a source container to a ICProject and imports all files contained + * in the given Zip file. + */ + public static ICContainer addSourceContainerWithImport(ICProject cproject, String containerName, ZipFile zipFile) throws InvocationTargetException, CoreException { + ICContainer root= addSourceContainer(cproject, containerName); + importFilesFromZip(zipFile, root.getPath(), null); + return root; + } + + /** + * Removes a source folder from a ICProject. + */ + public static void removeSourceContainer(ICProject cproject, String containerName) throws CoreException { + IFolder folder= cproject.getProject().getFolder(containerName); + folder.delete(true, null); + } + + + + /** + * Attempts to find an archive with the given name in the workspace + */ + public static IArchive findArchive(ICProject testProject,String name) { + int x; + IArchive[] myArchives; + IArchiveContainer archCont; + /*** + * Since ArchiveContainer.getArchives does not wait until + * all the archives in the project have been parsed before + * returning the list, we have to do a sync ArchiveContainer.getChildren + * first to make sure we find all the archives. + */ + archCont=testProject.getArchiveContainer(); + + myArchives=archCont.getArchives(); + if (myArchives.length<1) + return(null); + for (x=0;x + *
+ * -application <id>: the identifier of the application to run + *
+ *
+ * -boot <location>: the location, expressed as a URL, of the platform's boot.jar + *
+ *
+ * -consolelog : enables log to the console. Handy when combined with -debug + *
+ *
+ * -data <location>: sets the workspace location and the default location for projects + *
+ *
+ * -debug [options file]: turns on debug mode for the platform and optionally specifies a location + * for the .options file. This file indicates what debug points are available for a + * plug-in and whether or not they are enabled. If a location is not specified, the platform searches + * for the .options file under the install directory + *
+ *
+ * -dev [entries]: turns on dev mode and optionally specifies comma-separated class path entries + * which are added to the class path of each plug-in + *
+ *
+ * -keyring <location>: the location of the authorization database on disk. This argument + * has to be used together with the -password argument + *
+ *
+ * -password <passwd>: the password for the authorization database + *
+ *
+ * -plugins <location>: The arg is a URL pointing to a file which specs the plugin + * path for the platform. The file is in property file format where the keys are user-defined + * names and the values are comma separated lists of either explicit paths to plugin.xml + * files or directories containing plugins. (e.g., .../eclipse/plugins). + *
+ *
+ * -ws <window system>: sets the window system value + *
+ * + */ +public class Main { + /** + * Indicates whether this instance is running in debug mode. + */ + protected boolean debug = false; + + /** + * The location of the launcher to run. + */ + protected String bootLocation = null; + + /** + * The identifier of the application to run. + */ + protected String application; + + /** + * The path for finding find plugins. + */ + protected URL pluginPathLocation; + + /** + * The boot path location. + */ + protected String location; + + /** + * Indicates whether items for UNinstallation should be looked for. + */ + protected boolean uninstall = false; + + /** + * The item to be uninstalled. + */ + protected String uninstallCookie; + + /** + * The class path entries. + */ + protected String devClassPath = null; + + /** + * Indicates whether this instance is running in development mode. + */ + protected boolean inDevelopmentMode = false; + + // static token describing how to take down the splash screen + private static String endSplash = null; + + // constants + private static final String APPLICATION = "-application"; + private static final String BOOT = "-boot"; + private static final String DEBUG = "-debug"; + private static final String DEV = "-dev"; + private static final String ENDSPLASH = "-endsplash"; + private static final String UNINSTALL = "-uninstall"; + private static final String PI_BOOT = "org.eclipse.core.boot"; + private static final String BOOTLOADER = "org.eclipse.core.boot.BootLoader"; + private static final String UPDATELOADER = "org.eclipse.core.internal.boot.LaunchInfo"; + + // The project containing the boot loader code. This is used to construct + // the correct class path for running in VAJ and VAME. + private static final String PROJECT_NAME = "Eclipse Core Boot"; + + private static boolean inVAJ; + static { + try { + Class.forName("com.ibm.uvm.lang.ProjectClassLoader"); + inVAJ = true; + } catch (Exception e) { + inVAJ = false; + } + } + private static boolean inVAME; + static { + try { + Class.forName("com.ibm.eclipse.core.VAME"); + inVAME = true; + } catch (Exception e) { + inVAME = false; + } + } + +/** + * Executes the launch. + * + * @return the result of performing the launch + * @param args command-line arguments + * @exception Exception thrown if a problem occurs during the launch + */ +protected Object basicRun(String[] args) throws Exception { + Class clazz = getBootLoader(bootLocation); + Method method = clazz.getDeclaredMethod("run", new Class[] { String.class, URL.class, String.class, String[].class }); + try { + return method.invoke(clazz, new Object[] { application, pluginPathLocation, location, args }); + } catch (InvocationTargetException e) { + if (e.getTargetException() instanceof Error) + throw (Error) e.getTargetException(); + else + throw e; + } +} + +/** + * Returns the result of converting a list of comma-separated tokens into an array + * + * @return the array of string tokens + * @param prop the initial comma-separated string + */ +private String[] getArrayFromList(String prop) { + if (prop == null || prop.trim().equals("")) + return new String[0]; + Vector list = new Vector(); + StringTokenizer tokens = new StringTokenizer(prop, ","); + while (tokens.hasMoreTokens()) { + String token = tokens.nextToken().trim(); + if (!token.equals("")) + list.addElement(token); + } + return list.isEmpty() ? new String[0] : (String[]) list.toArray(new String[0]); +} +/** + * Creates and returns a platform BootLoader which can be used to start + * up and run the platform. The given base, if not null, + * is the location of the boot loader code. If the value is null + * then the boot loader is located relative to this class. + * + * @return the new boot loader + * @param base the location of the boot loader + */ +public Class getBootLoader(String base) throws Exception { + URLClassLoader loader = new URLClassLoader(getBootPath(base), null); + return loader.loadClass(BOOTLOADER); +} +/** + * Returns the URL-based class path describing where the boot classes + * are located when running in development mode. + * + * @return the url-based class path + * @param base the base location + * @exception MalformedURLException if a problem occurs computing the class path + */ +protected URL[] getDevPath(URL base) throws MalformedURLException { + URL url; + String devBase = base.toExternalForm(); + if (!inDevelopmentMode) { + url = new URL(devBase + "boot.jar"); + return new URL[] {url}; + } + String[] locations = getArrayFromList(devClassPath); + ArrayList result = new ArrayList(locations.length); + for (int i = 0; i < locations.length; i++) { + String spec = devBase + locations[i]; + char lastChar = spec.charAt(spec.length() - 1); + if ((spec.endsWith(".jar") || (lastChar == '/' || lastChar == '\\'))) + url = new URL (spec); + else + url = new URL(spec + "/"); + //make sure URL exists before adding to path + if (new java.io.File(url.getFile()).exists()) + result.add(url); + } + url = new URL(devBase + "boot.jar"); + if (new java.io.File(url.getFile()).exists()) + result.add(url); + return (URL[])result.toArray(new URL[result.size()]); +} + +/** + * Returns the URL-based class path describing where the boot classes are located. + * + * @return the url-based class path + * @param base the base location + * @exception MalformedURLException if a problem occurs computing the class path + */ +protected URL[] getBootPath(String base) throws MalformedURLException { + URL url = null; + // if the given location is not null, assume it is correct and use it. + if (base != null) { + url = new URL(base); + if (debug) + System.out.println("Boot URL: " + url.toExternalForm()); + return new URL[] {url}; + } + // Create a URL based on the location of this class' code. + // strip off jar file and/or last directory to get + // to the directory containing projects. + URL[] result = null; + url = getClass().getProtectionDomain().getCodeSource().getLocation(); + String path = url.getFile(); + if (path.endsWith(".jar")) + path = path.substring(0, path.lastIndexOf("/")); + else + if (path.endsWith("/")) + path = path.substring(0, path.length() - 1); + if (inVAJ || inVAME) { + int ix = path.lastIndexOf("/"); + path = path.substring(0, ix + 1); + path = path + PROJECT_NAME + "/"; + url = new URL(url.getProtocol(), url.getHost(), url.getPort(), path); + result = new URL[] {url}; + } else { + path = searchForPlugins(path); + path = searchForBoot(path); + // add on any dev path elements + url = new URL(url.getProtocol(), url.getHost(), url.getPort(), path); + result = getDevPath(url); + } + if (debug) { + System.out.println("Boot URL:"); + for (int i = 0; i < result.length; i++) + System.out.println(" " + result[i].toExternalForm()); + } + return result; +} + +/** + * Searches for a plugins root starting at a given location. If one is + * found then this location is returned; otherwise an empty string is + * returned. + * + * @return the location where plugins were found, or an empty string + * @param start the location to begin searching at + */ +protected String searchForPlugins(String start) { + File path = new File(start); + while (path != null) { + File test = new File(path, "plugins"); + if (test.exists()) + return test.toString(); + path = path.getParentFile(); + path = (path == null || path.length() == 1) ? null : path; + } + return ""; +} +/** + * Searches for a boot directory starting at a given location. If one + * is found then this location is returned; otherwise an empty string + * is returned. + * + * @return the location where plugins were found, or an empty string + * @param start the location to begin searching at + */ +protected String searchForBoot(String start) { + FileFilter filter = new FileFilter() { + public boolean accept(File candidate) { + return candidate.getName().startsWith(PI_BOOT); + } + }; + File[] boots = new File(start).listFiles(filter); + String result = null; + String maxVersion = null; + for (int i = 0; i < boots.length; i++) { + String name = boots[i].getName(); + int index = name.lastIndexOf('_'); + if (index == -1) { + result = boots[i].getAbsolutePath(); + i = boots.length; + } else { + if (index > 0) { + String version = name.substring(index + 1); + if (maxVersion == null) { + result = boots[i].getAbsolutePath(); + maxVersion = version; + } else + if (maxVersion.compareTo(version) == -1) { + result = boots[i].getAbsolutePath(); + maxVersion = version; + } + } + } + } + if (result == null) + throw new RuntimeException("Could not find bootstrap code. Check location of boot plug-in or specify -boot."); + return result.replace(File.separatorChar, '/') + "/"; +} +/** + * Returns the update loader for the given boot path. + * + * @return the update loader + * @param base the boot path base + * @exception Exception thrown is a problem occurs determining this loader + */ +public Class getUpdateLoader(String base) throws Exception { + URLClassLoader loader = new URLClassLoader(getBootPath(base), null); + return loader.loadClass(UPDATELOADER); +} +/** + * Runs the platform with the given arguments. The arguments must identify + * an application to run (e.g., -application com.example.application). + * After running the application System.exit(N) is executed. + * The value of N is derived from the value returned from running the application. + * If the application's return value is an Integer, N is this value. + * In all other cases, N = 0. + *

+ * Clients wishing to run the platform without a following System.exit + * call should use run(). + * + * @see #run + * + * @param args the command line arguments + */ +public static void main(String[] args) { + Object result = null; + try { + result = new Main().run(args); + } catch (Throwable e) { + // try and take down the splash screen. + endSplash(); + System.out.println("Exception launching the Eclipse Platform:"); + e.printStackTrace(); + } + int exitCode = result instanceof Integer ? ((Integer) result).intValue() : 0; + System.exit(exitCode); +} +/** + * Tears down the currently-displayed splash screen. + */ +public static void endSplash() { + if (endSplash == null) + return; + try { + Runtime.getRuntime().exec(endSplash); + } catch (Exception e) { + } +} + +/** + * Runs this launcher with the arguments specified in the given string. + * + * @param argString the arguments string + * @exception Exception thrown if a problem occurs during launching + */ +public static void main(String argString) throws Exception { + Vector list = new Vector(5); + for (StringTokenizer tokens = new StringTokenizer(argString, " "); tokens.hasMoreElements();) + list.addElement((String) tokens.nextElement()); + main((String[]) list.toArray(new String[list.size()])); +} + +/** + * Processes the command line arguments + * + * @return the arguments to pass through to the launched application + * @param args the command line arguments + */ +protected String[] processCommandLine(String[] args) throws Exception { + int[] configArgs = new int[100]; + configArgs[0] = -1; // need to initialize the first element to something that could not be an index. + int configArgIndex = 0; + for (int i = 0; i < args.length; i++) { + boolean found = false; + // check for args without parameters (i.e., a flag arg) + // check if debug should be enabled for the entire platform + if (args[i].equalsIgnoreCase(DEBUG)) { + debug = true; + // passed thru this arg (i.e., do not set found = true + continue; + } + + // check if development mode should be enabled for the entire platform + // If this is the last arg or there is a following arg (i.e., arg+1 has a leading -), + // simply enable development mode. Otherwise, assume that that the following arg is + // actually some additional development time class path entries. This will be processed below. + if (args[i].equalsIgnoreCase(DEV) && ((i + 1 == args.length) || ((i + 1 < args.length) && (args[i + 1].startsWith("-"))))) { + inDevelopmentMode = true; + // do not mark the arg as found so it will be passed through + continue; + } + + // done checking for args. Remember where an arg was found + if (found) { + configArgs[configArgIndex++] = i; + continue; + } + // check for args with parameters. If we are at the last argument or if the next one + // has a '-' as the first character, then we can't have an arg with a parm so continue. + if (i == args.length - 1 || args[i + 1].startsWith("-")) + continue; + String arg = args[++i]; + + // look for the laucher to run + if (args[i - 1].equalsIgnoreCase(BOOT)) { + bootLocation = arg; + found = true; + } + + // look for the development mode and class path entries. + if (args[i - 1].equalsIgnoreCase(DEV)) { + inDevelopmentMode = true; + devClassPath = arg; + continue; + } + + // look for the application to run + if (args[i - 1].equalsIgnoreCase(APPLICATION)) { + application = arg; + found = true; + } + + // look for token to use to end the splash screen + if (args[i - 1].equalsIgnoreCase(ENDSPLASH)) { + endSplash = arg; + continue; + } + + // look for items to uninstall + if (args[i - 1].equalsIgnoreCase(UNINSTALL)) { + uninstall = true; + uninstallCookie = arg; + found = true; + } + + // done checking for args. Remember where an arg was found + if (found) { + configArgs[configArgIndex++] = i - 1; + configArgs[configArgIndex++] = i; + } + } + // remove all the arguments consumed by this argument parsing + if (configArgIndex == 0) + return args; + String[] passThruArgs = new String[args.length - configArgIndex]; + configArgIndex = 0; + int j = 0; + for (int i = 0; i < args.length; i++) { + if (i == configArgs[configArgIndex]) + configArgIndex++; + else + passThruArgs[j++] = args[i]; + } + return passThruArgs; +} +/** + * Runs the application to be launched. + * + * @return the return value from the launched application + * @param args the arguments to pass to the application + * @exception thrown if a problem occurs during launching + */ +public Object run(String[] args) throws Exception { + String[] passThruArgs = processCommandLine(args); + if (uninstall) + return updateRun(UNINSTALL, uninstallCookie, passThruArgs); + else + return basicRun(passThruArgs); +} +/** + * Performs an update run. + * + * @return the return value from the update loader + * @param flag flag to give to the update loader + * @param value value to give to the update loader + * @param args arguments to give to the update loader. + * @exception Exception thrown if a problem occurs during execution + */ +protected Object updateRun(String flag, String value, String[] args) throws Exception { + Class clazz = getUpdateLoader(bootLocation); + Method method = clazz.getDeclaredMethod("run", new Class[] { String.class, String.class, String.class, String[].class }); + try { + return method.invoke(clazz, new Object[] { flag, value, location, args }); + } catch (InvocationTargetException e) { + if (e.getTargetException() instanceof Error) + throw (Error) e.getTargetException(); + else + throw e; + } +} +} diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/NewMain.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/NewMain.java new file mode 100644 index 00000000000..66161e7a7bf --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/NewMain.java @@ -0,0 +1,73 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package org.eclipse.cdt.testplugin; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URL; +import java.util.Properties; +import java.util.StringTokenizer; +import java.util.Vector; + +/** + * Application is responsible for calling core launch api + */ + +public class NewMain extends Main { + private static final String DEFAULT_APPLICATION= "org.eclipse.ui.workbench"; + + + public NewMain(String application, String location, URL pluginPathLocation, String bootLocation, boolean debug) throws IOException { + this.application= application; + this.location= location; + this.pluginPathLocation= pluginPathLocation; + this.bootLocation= bootLocation; + } + + public static void main(String[] args) { + try { + String location= getLocationFromProperties("platform"); + new NewMain(DEFAULT_APPLICATION, location, null, null, true).run(args); + } catch (Throwable e) { + System.out.println("Exception launching the Eclipse Platform UI:"); + e.printStackTrace(); + } + System.exit(0); + } + + + /** + * Run this launcher with the arguments specified in the given string. + * This is a short cut method for people running the launcher from + * a scrapbook (i.e., swip-and-doit facility). + */ + public static void main(String argString) throws Exception { + Vector list= new Vector(5); + for (StringTokenizer tokens= new StringTokenizer(argString, " "); tokens.hasMoreElements();) + list.addElement((String) tokens.nextElement()); + main((String[]) list.toArray(new String[list.size()])); + } + + public static String getLocationFromProperties(String key) { + Properties properties= new Properties(); + try { + FileInputStream fis= new FileInputStream(getSettingsFile()); + properties.load(fis); + return properties.getProperty(key); + } catch (IOException e) { + } + return null; + } + + private static File getSettingsFile() { + String home= System.getProperty("user.home"); + if (home == null) { + System.out.println("Home dir not defined"); + return null; + } + return new File(home, "eclipse-workspaces.properties"); + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/TestPluginLauncher.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/TestPluginLauncher.java new file mode 100644 index 00000000000..4ee939df6b5 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/TestPluginLauncher.java @@ -0,0 +1,57 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package org.eclipse.cdt.testplugin; + +import java.net.URL; + +/** + * Helper class to launch a test + */ +public class TestPluginLauncher { + + public static final String APP_NAME= "org.eclipse.jdt.ui.tests.app"; + + public static void run(String location, Class testCase, String[] args) { + run(APP_NAME, location, testCase, args); + } + + public static void run(String application, String location, Class testCase, String[] args) { + try { + String bootLocation= getBootLocation(); + int nArgs= args.length; + String[] newArgs= new String[4 + nArgs]; + newArgs[0]= testCase.getName(); + for (int i= 0; i < nArgs; i++) { + newArgs[1 + i]= args[i]; + } + newArgs[1 + nArgs]= "-dev"; + newArgs[1 + nArgs + 1]= "bin"; + newArgs[1 + nArgs + 2]= "-debug"; + NewMain newMain= new NewMain(application, location, null, bootLocation, false); + newMain.run(newArgs); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static String getLocationFromProperties(String key) { + return NewMain.getLocationFromProperties(key); + } + + public static String getLocationFromProperties() { + return NewMain.getLocationFromProperties("tests"); + } + + public static String getBootLocation() { + URL url= TestPluginLauncher.class.getResource("TestPluginLauncher.class"); + String s= url.toString(); + int index= s.indexOf("/org.eclipse.jdt.ui.tests"); + if (index == -1) + throw new IllegalArgumentException(); + s= s.substring(0, index); + s= s + "/org.eclipse.core.boot/boot.jar"; + return s; + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/TestWorkbench.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/TestWorkbench.java new file mode 100644 index 00000000000..0222d528e3d --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/TestWorkbench.java @@ -0,0 +1,79 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package org.eclipse.cdt.testplugin; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import junit.framework.Test; +import junit.framework.TestSuite; +import junit.textui.TestRunner; + +import org.eclipse.core.runtime.IPath; + +import org.eclipse.swt.widgets.Display; + +import org.eclipse.ui.internal.Workbench; + +public class TestWorkbench extends Workbench { + + /** + * Run an event loop for the workbench. + */ + protected void runEventLoop() { + // Dispatch all events. + Display display = Display.getCurrent(); + while (true) { + try { + if (!display.readAndDispatch()) + break; + } catch (Throwable e) { + break; + } + } + IPath location= CTestPlugin.getWorkspace().getRoot().getLocation(); + System.out.println("Workspace-location: " + location.toString()); + + + try { + String[] args= getCommandLineArgs(); + if (args.length > 0) { + Test test= getTest(args[0]); + TestRunner.run(test); + } else { + System.out.println("TestWorkbench: Argument must be class name"); + } + } catch (Exception e) { + e.printStackTrace(); + } + + + // Close the workbench. + close(); + } + + public Test getTest(String className) throws Exception { + Class testClass= getClass().getClassLoader().loadClass(className); + + Method suiteMethod= null; + try { + suiteMethod= testClass.getMethod(TestRunner.SUITE_METHODNAME, new Class[0]); + } catch (Exception e) { + // try to extract a test suite automatically + return new TestSuite(testClass); + } + try { + return (Test) suiteMethod.invoke(null, new Class[0]); // static method + } catch (InvocationTargetException e) { + System.out.println("Failed to invoke suite():" + e.getTargetException().toString()); + } catch (IllegalAccessException e) { + System.out.println("Failed to invoke suite():" + e.toString()); + } + return null; + + } + + +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/AccessibilityTestPass.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/AccessibilityTestPass.java new file mode 100644 index 00000000000..2a6e8fe44bd --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/AccessibilityTestPass.java @@ -0,0 +1,66 @@ +package org.eclipse.cdt.testplugin.util; + + +import java.util.ArrayList; + + +public class AccessibilityTestPass implements IDialogTestPass { + private static final int CHECKLIST_SIZE = 5; + + /** + * @see IDialogTestPass#title() + */ + public String title() { + return "Test Pass: Accessibility"; + } + /** + * @see IDialogTestPass#description() + */ + public String description() { + return "Verify the accessibility of the dialogs."; + } + /** + * @see IDialogTestPass#label() + */ + public String label() { + return "&Accessibility"; + } + /** + * @see IDialogTestPass#checkListTexts() + */ + public ArrayList checkListTexts() { + ArrayList list = new ArrayList(CHECKLIST_SIZE); + list.add("&1) all widgets are accessible by tabbing."); + list.add("&2) forwards and backwards tabbing is in a logical order"); + list.add("&3) all the widgets with labels have an appropriate mnemonic."); + list.add("&4) there are no duplicate mnemonics."); + list.add("&5) selectable widgets can be selected using the spacebar."); + return list; + } + /** + * @see IDialogTestPass#failureTexts() + * Size of the return array must be the same size as the checkListTexts' + * ArrayList. + */ + public String[] failureTexts() { + String[] failureText = new String[CHECKLIST_SIZE]; + failureText[0] = "Some widgets aren't accessible by tabbing."; + failureText[1] = "Tabbing order is illogical."; + failureText[2] = "Missing or inappropriate mnemonics."; + failureText[3] = "Duplicate mnemonics."; + failureText[4] = "Some widgets cannot be selected using the spacebar."; + return failureText; + } + /** + * @see IDialogTestPass#queryText() + */ + public String queryText() { + return "Is the accessibility of the dialog acceptable?"; + } + /** + * @see IDialogTestPass#getID() + */ + public int getID() { + return VerifyDialog.TEST_ACCESS; + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/DialogCheck.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/DialogCheck.java new file mode 100644 index 00000000000..a365df68d8f --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/DialogCheck.java @@ -0,0 +1,225 @@ +package org.eclipse.cdt.testplugin.util; + + +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ + + +import junit.framework.Assert; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; + +import org.eclipse.ui.internal.WorkbenchPlugin; + + +/** + * A DialogCheck is used test a dialog in + * various ways. + *

+ * For interactive tests use assertDialog. + * For automated tests use assert DialogTexts. + *

+ */ +public class DialogCheck { + private DialogCheck() { + } + private static VerifyDialog _verifyDialog; + + + /** + * Asserts that a given dialog is not null and that it passes + * certain visual tests. These tests will be verified manually + * by the tester using an input dialog. Use this assert method + * to verify a dialog's sizing, initial focus, or accessiblity. + * To ensure that both the input dialog and the test dialog are + * accessible by the tester, the getShell() method should be used + * when creating the test dialog. + * + * Example usage: + * Dialog dialog = new AboutDialog( DialogCheck.getShell() ); + * DialogCheck.assertDialog(dialog, this); + * + * @param dialog the test dialog to be verified. + * @param assert this is the test case object, assertions will be + * executed on this object. + */ + public static void assertDialog(Dialog dialog, Assert assert) { + Assert.assertNotNull(dialog); + if (_verifyDialog.getShell() == null) { + //force the creation of the verify dialog + getShell(); + } + if (_verifyDialog.open(dialog) == IDialogConstants.NO_ID) { + Assert.assertTrue(_verifyDialog.getFailureText(), false); + } + } + + + /** + * Automated test that checks all the labels and buttons of a dialog + * to make sure there is enough room to display all the text. Any + * text that wraps is only approximated and is currently not accurate. + * + * @param dialog the test dialog to be verified. + * @param assert this is the test case object, assertions will be + * executed on this object. + */ + public static void assertDialogTexts(Dialog dialog, Assert assert) { + Assert.assertNotNull(dialog); + dialog.setBlockOnOpen(false); + dialog.open(); + Shell shell = dialog.getShell(); + verifyCompositeText(shell, assert); + dialog.close(); + } + + + /** + * This method should be called when creating dialogs to test. This + * ensures that the dialog's parent shell will be that of the + * verification dialog. + * + * @return Shell The shell of the verification dialog to be used as + * the parent shell of the test dialog. + */ + public static Shell getShell() { + Shell shell = + WorkbenchPlugin + .getDefault() + .getWorkbench() + .getActiveWorkbenchWindow() + .getShell(); + _verifyDialog = new VerifyDialog(shell); + _verifyDialog.create(); + return _verifyDialog.getShell(); + } + + + /* + * Looks at all the child widgets of a given composite and + * verifies the text on all labels and widgets. + * @param composite The composite to look through + * @param assert The object to invoke assertions on. + */ + private static void verifyCompositeText(Composite composite, Assert assert) { + Control children[] = composite.getChildren(); + for (int i = 0; i < children.length; i++) { + try { + //verify the text if the child is a button + verifyButtonText((Button) children[i], assert); + } catch (ClassCastException exNotButton) { + try { + //child is not a button, maybe a label + verifyLabelText((Label) children[i], assert); + } catch (ClassCastException exNotLabel) { + try { + //child is not a label, make a recursive call if it is a composite + verifyCompositeText((Composite) children[i], assert); + } catch (ClassCastException exNotComposite) { + //the child is not a button, label, or composite - ignore it. + } + } + } + } + } + + /* + * Verifies that a given button is large enough to display its text. + * @param button The button to verify, + * @param assert The object to invoke assertions on. + */ + private static void verifyButtonText(Button button, Assert assert) { + String widget = button.toString(); + Point size = button.getSize(); + + + //compute the size with no line wrapping + Point preferred = button.computeSize(SWT.DEFAULT, SWT.DEFAULT); + //if (size.y/preferred.y) == X, then label spans X lines, so divide + //the calculated value of preferred.x by X + if (preferred.y * size.y > 0) { + preferred.y /= countLines(button.getText()); //check for '\n\' + if (size.y / preferred.y > 1) { + preferred.x /= (size.y / preferred.y); + } + } + + + String message = + new StringBuffer("Warning: ") + .append(widget) + .append("\n\tActual Width -> ") + .append(size.x) + .append("\n\tRecommended Width -> ") + .append(preferred.x) + .toString(); + if (preferred.x > size.x) { + //close the dialog + button.getShell().dispose(); + Assert.assertTrue(message.toString(), false); + } + } + + /* + * Verifies that a given label is large enough to display its text. + * @param label The label to verify, + * @param assert The object to invoke assertions on. + */ + private static void verifyLabelText(Label label, Assert assert) { + String widget = label.toString(); + Point size = label.getSize(); + + + //compute the size with no line wrapping + Point preferred = label.computeSize(SWT.DEFAULT, SWT.DEFAULT); + //if (size.y/preferred.y) == X, then label spans X lines, so divide + //the calculated value of preferred.x by X + if (preferred.y * size.y > 0) { + preferred.y /= countLines(label.getText()); + if (size.y / preferred.y > 1) { + preferred.x /= (size.y / preferred.y); + } + } + String message = + new StringBuffer("Warning: ") + .append(widget) + .append("\n\tActual Width -> ") + .append(size.x) + .append("\n\tRecommended Width -> ") + .append(preferred.x) + .toString(); + if (preferred.x > size.x) { + //close the dialog + label.getShell().dispose(); + Assert.assertTrue(message.toString(), false); + } + } + + /* + * Counts the number of lines in a given String. + * For example, if a string contains one (1) newline character, + * a value of two (2) would be returned. + * @param text The string to look through. + * @return int the number of lines in text. + */ + private static int countLines(String text) { + int newLines = 1; + for (int i = 0; i < text.length(); i++) { + if (text.charAt(i) == '\n') { + newLines++; + } + } + return newLines; + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/ExpectedStrings.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/ExpectedStrings.java new file mode 100644 index 00000000000..d7cc8c48187 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/ExpectedStrings.java @@ -0,0 +1,96 @@ +package org.eclipse.cdt.testplugin.util; + + +import java.util.Stack; +/** + * @author Peter Graves + * + * This utility class maintains a list of strings, and as a tests finds strings + * in a structure/list, it will maintain a list of unfound/extra strings. + */ +public class ExpectedStrings { + + public String [] expStrings; + private boolean[] foundStrings; + private Stack extraStrings; /* A stack of the unecpected strings we + * recieved + */ + private boolean extra; + + /** + * Constructor for ExpectedStrings. + */ + public ExpectedStrings() { + } + /** + * Constructor for ExpectedStrings that accepts a list of strings that + * we expect to get. + */ + public ExpectedStrings(String[] values) { + int x; + expStrings=new String[values.length]; + for (x=0;x= 0) ) { + TEST_TYPE = TEST_SIZING; + } + _failureText = ""; + _dialogTests[0] = new SizingTestPass(); + _dialogTests[1] = new FocusTestPass(); + _dialogTests[2] = new AccessibilityTestPass(); + } + + /* (non-Javadoc) + * Method declared on Window. + */ + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText("Dialog Verification"); + setShellStyle(SWT.NONE); + } + /* (non-Javadoc) + * Method declared on Dialog. + */ + protected void createButtonsForButtonBar(Composite parent) { + _yesButton = createButton(parent, IDialogConstants.YES_ID, IDialogConstants.YES_LABEL, true); + _noButton = createButton(parent, IDialogConstants.NO_ID, IDialogConstants.NO_LABEL, false); + } + /* (non-Javadoc) + * Method declared on Dialog. + */ + protected void buttonPressed(int buttonId) { + if (IDialogConstants.YES_ID == buttonId) { + setReturnCode(IDialogConstants.YES_ID); + if (_testDialog.getShell() != null) { + _testDialog.close(); + } + close(); + } else if (IDialogConstants.NO_ID == buttonId) { + handleFailure(); + } + } + /* (non-Javadoc) + * Method declared on Dialog. + */ + protected Control createDialogArea(Composite parent) { + // top level composite + Composite parentComposite = (Composite)super.createDialogArea(parent); + + + // create a composite with standard margins and spacing + Composite composite = new Composite(parentComposite, SWT.NONE); + composite.setSize(SIZING_WIDTH, SWT.DEFAULT); + GridLayout layout = new GridLayout(); + layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); + layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); + layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); + layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); + composite.setLayout(layout); + composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + + + createTestSelectionGroup(composite); + createCheckListGroup(composite); + + + _queryLabel = new Label(composite, SWT.NONE); + _queryLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + initializeTest(); + return composite; + } + /* + * Group for selecting type of test. + */ + private void createTestSelectionGroup(Composite parent) { + Group group = new Group(parent, SWT.SHADOW_NONE); + group.setText("Testing:"); + group.setLayout( new GridLayout() ); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + group.setLayoutData(data); + + for (int i = 0; i < _dialogTests.length; i++) { + Button radio = new Button(group, SWT.RADIO); + radio.setText( _dialogTests[i].label() ); + final int testID = _dialogTests[i].getID(); + radio.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + TEST_TYPE = testID; + initializeTest(); + _yesButton.setEnabled(true); + } + }); + if ( TEST_TYPE == _dialogTests[i].getID() ) { + radio.setSelection(true); + } + } + } + /* + * Initializes the checklist with empty checks. + */ + private void createCheckListGroup(Composite parent) { + Group group = new Group(parent, SWT.SHADOW_NONE); + group.setText("Verify that:"); + group.setLayout( new GridLayout() ); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + group.setLayoutData(data); + + int checkListSize = 0; + for (int i = 0; i < _dialogTests.length; i++) { + int size = _dialogTests[i].checkListTexts().size(); + if (size > checkListSize) { + checkListSize = size; + } + } + _checkList = new Button[checkListSize]; + SelectionAdapter selectionAdapter = new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + checkYesEnable(); + } + }; + for (int i = 0; i < checkListSize; i++) { + _checkList[i] = new Button(group, SWT.CHECK); + _checkList[i].addSelectionListener(selectionAdapter); + data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); + data.grabExcessHorizontalSpace = true; + _checkList[i].setLayoutData(data); + } + } + /* + * Disables the yes button if any of the items in the checklist + * are unchecked. Enables the yes button otherwise. + */ + void checkYesEnable() { + boolean enable = true; + for (int i = 0; i < _checkList.length; i++) { + if ( !_checkList[i].getSelection() ) { + enable = false; + } + } + _yesButton.setEnabled(enable); + } + /* + * Initializes the checklist, banner texts, and query label + */ + void initializeTest() { + IDialogTestPass test = _dialogTests[TEST_TYPE]; + setTitle( test.title() ); + setMessage( test.description() ); + Iterator iterator = test.checkListTexts().iterator(); + for (int i = 0; i < _checkList.length; i++) { + if ( iterator.hasNext() ) { + _checkList[i].setText( iterator.next().toString() ); + _checkList[i].setVisible(true); + _checkList[i].update(); + } else { + _checkList[i].setVisible(false); + _checkList[i].update(); + } + _checkList[i].setSelection(true); + } + _queryLabel.setText( test.queryText() ); + } + public String getFailureText() { + return _failureText; + } + /* + * Can't open the verification dialog without a specified + * test dialog, this simply returns a failure and prevents + * opening. Should use open(Dialog) instead. + * + */ + public int open() { + _failureText = "Testing dialog is required, use VerifyDialog::open(Dialog)"; + return IDialogConstants.NO_ID; + } + /* + * Opens the verification dialog to test the specified dialog. + */ + public int open(Dialog testDialog) { + if (getShell() == null) { + create(); + } + getShell().setLocation(0, 0); + getShell().setSize(Math.max(SIZING_WIDTH, getShell().getSize().x), getShell().getSize().y); + _testDialog = testDialog; + if (_testDialog.getShell() == null) { + _testDialog.create(); + } + _testDialogSize = _testDialog.getShell().getSize(); + openNewTestDialog(); + + return super.open(); + } + /* + * Opens the dialog to be verified. + */ + private void openNewTestDialog() { + if (_testDialog.getShell() == null) { + _testDialog.create(); + } + _testDialog.setBlockOnOpen(false); + _testDialog.getShell().setLocation(getShell().getSize().x + 1, 0); + _testDialog.getShell().setSize(_testDialogSize); + _testDialog.getShell().addShellListener(new ShellAdapter() { + public void shellClosed(ShellEvent e) { + e.doit = false; + } + + }); + _testDialog.open(); + } + /* + * The test dialog failed, open the failure dialog. + */ + private void handleFailure() { + IDialogTestPass test = _dialogTests[TEST_TYPE]; + StringBuffer text = new StringBuffer(); + String label = test.label(); + label = label.substring(0, label.indexOf("&")) + + label.substring(label.indexOf("&") + 1); + text.append(label). + append(" failed on the "). + append(SWT.getPlatform()). + append(" platform:\n"); + + String failureMessages[] = test.failureTexts(); + for (int i = 0; i < test.checkListTexts().size(); i++) { + if ( !_checkList[i].getSelection() ) { + text.append("- ").append(failureMessages[i]).append("\n"); + } + } + FailureDialog dialog = new FailureDialog( getShell() ); + dialog.create(); + //String temp = text.toString(); + dialog.setText( text.toString() ); + if (dialog.open() == IDialogConstants.OK_ID) { + _failureText = dialog.toString(); + setReturnCode(IDialogConstants.NO_ID); + if (_testDialog.getShell() != null) { + _testDialog.close(); + } + close(); + } + } + /* + * In case the shell was closed by a means other than + * the NO button. + */ + protected void handleShellCloseEvent() { + handleFailure(); + } +} + + diff --git a/core/org.eclipse.cdt.core.tests/test.xml b/core/org.eclipse.cdt.core.tests/test.xml new file mode 100644 index 00000000000..ebc2be247da --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/test.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +