diff options
116 files changed, 15764 insertions, 0 deletions
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 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="model"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="src" path="/org.junit"/> + <classpathentry kind="src" path="/org.eclipse.cdt.core"/> + <classpathentry kind="src" path="/org.eclipse.core.resources"/> + <classpathentry kind="src" path="/org.eclipse.core.runtime"/> + <classpathentry kind="src" path="suite"/> + <classpathentry kind="src" path="/org.eclipse.core.boot"/> + <classpathentry kind="src" path="build"/> + <classpathentry kind="src" path="parser"/> + <classpathentry kind="src" path="/org.apache.xerces"/> + <classpathentry kind="src" path="failures"/> + <classpathentry kind="src" path="/org.eclipse.swt"/> + <classpathentry kind="src" path="/org.eclipse.ui"/> + <classpathentry kind="output" path="bin"/> +</classpath> 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 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.cdt.core.tests</name> + <comment></comment> + <projects> + <project>org.apache.xerces</project> + <project>org.eclipse.cdt.core</project> + <project>org.eclipse.cdt.core.linux</project> + <project>org.eclipse.cdt.core.qnx</project> + <project>org.eclipse.cdt.core.solaris</project> + <project>org.eclipse.cdt.core.win32</project> + <project>org.eclipse.core.boot</project> + <project>org.eclipse.core.resources</project> + <project>org.eclipse.core.runtime</project> + <project>org.eclipse.swt</project> + <project>org.eclipse.ui</project> + <project>org.junit</project> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.pde.PluginNature</nature> + </natures> +</projectDescription> 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 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> +<html> +<head> +<title>About</title> +<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1"> +</head> +<body lang="EN-US"> +<h2>About This Content</h2> + +<p>20th June, 2002</p> +<h3>License</h3> +<p>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 <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>. +For purposes of the CPL, "Program" will mean the Content.</p> + +<h3>Third Party Content</h3> + +<p>The Content includes items that may be have been sourced from third parties as follows:</p> + +<p><b>JUnit 3.7</b></p> +<p>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 +<a href="http://oss.software.ibm.com/developerworks/opensource/license10.html">http://oss.software.ibm.com/developerworks/opensource/license10.html</a>. +The source code is located in testresources/junit37-noUI-src.zip.</p> + +<p>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;</p> +<p>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;</p> +<p>iii) IBM states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party.</p> + +<h3>Contributions</h3> + +<p>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.</p> + +<p>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.</p> + +</body> +</html>
\ 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 <code>name</code> 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 <code>IProject</code> 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 <code>ITarget</code> 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 <class T, class U> struct SuperSubclass {\n" ); + code.write( "enum { value = (::Loki::Conversion<const volatile U*, const volatile T*>::exists && \n" ); + code.write( "!::Loki::Conversion<const volatile T*, const volatile void*>::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 _CharT> 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<bins.length;x++) { + expBin.foundString(bins[x].getElementName()); + elements=bins[x].getChildren(); + for (int i=0;i<elements.length;i++) { + expObj[x].foundString(elements[i].getElementName()); + } + } + + assertTrue(expBin.getMissingString(), expBin.gotAll()); + assertTrue(expBin.getExtraString(), !expBin.gotExtra()); + for (x=0;x<expObj.length;x++) { + assertTrue("Binary " + expBin.expStrings[x] + " " +expObj[x].getMissingString(), expObj[x].gotAll()); + assertTrue("Binary " + expBin.expStrings[x] + " " + expObj[x].getExtraString(), !expObj[x].gotExtra()); + } + } + /*** + * Simple sanity test to make sure Archive.isArchive returns true + * + */ + public void testIsArchive() throws CoreException,FileNotFoundException { + IArchive myArchive; + myArchive=CProjectHelper.findArchive(testProject, "libtestlib_g.a"); + + assertTrue("A archive", myArchive != null); + myArchive=null; + + + } + +} diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/BinaryTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/BinaryTests.java new file mode 100644 index 00000000000..186cf8d0180 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/BinaryTests.java @@ -0,0 +1,420 @@ +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.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 Binary + * class. There is nothing exotic here, mostly just sanity type tests + * + */ +public class BinaryTests extends TestCase { + IWorkspace workspace; + IWorkspaceRoot root; + ICProject testProject; + IFile cfile, exefile, libfile, archfile, objfile, bigexe, ppcexefile, ndexe; + Path cpath, exepath, libpath, archpath, objpath; + NullProgressMonitor monitor; + + + + /** + * Constructor for BinaryTests + * @param name + */ + public BinaryTests(String name) { + super(name); + + } + + /** + * @see java.lang.Object#finalize() + */ + protected void finalize() throws Throwable { + super.finalize(); + + /** + * Make sure we leave the workspace clean for the next set of tests + */ + CProjectHelper.delete(testProject); + + + } + + + /** + * 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 { + String pluginRoot; + /*** + * 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. + */ + 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"); + + + /*** + * Setup the various files, paths and projects that are needed by the + * tests + */ + + testProject=CProjectHelper.createCProject("filetest", "none"); + if (testProject==null) + fail("Unable to create project"); + + pluginRoot=org.eclipse.core.runtime.Platform.getPlugin("org.eclipse.cdt.core.tests").find(new Path("/")).getFile(); + + 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/exetest.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"); + ppcexefile = testProject.getProject().getFile("ppctest_g"); + if (!ppcexefile.exists()) { + ppcexefile.create(new FileInputStream(pluginRoot+"resources/exe/ppc/be.g/exe_g"),false, monitor); + + } + ndexe = testProject.getProject().getFile("exetest"); + if (!ndexe.exists()) { + ndexe.create(new FileInputStream(pluginRoot+"resources/exe/x86/o/exe"),false, monitor); + + } + + + + bigexe = testProject.getProject().getFile("exebig_g"); + if (!bigexe.exists()) { + bigexe.create(new FileInputStream(pluginRoot+"resources/exebig/x86/o.g/exebig_g"),false, monitor); + + } + + 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, InterruptedException { + /* Let everything settle down before we try to delete the project. + */ + + Thread.sleep(500); + CProjectHelper.delete(testProject); + + } + + public static TestSuite suite() { + return new TestSuite(BinaryTests.class); + } + + public static void main (String[] args){ + junit.textui.TestRunner.run(suite()); + } + + + + /**** + * Simple tests to make sure we can get all of a binarys children + */ + public void testGetChildren() throws CoreException,FileNotFoundException { + IBinary myBinary; + ICElement[] elements; + ExpectedStrings expSyms; + String[] myStrings = {"atexit", "exit", "_init_libc", "printf", + "test.c", "_init","main.c", "_start", "test2.c", "_btext"}; + + expSyms=new ExpectedStrings(myStrings); + + /*** + * Grab the IBinary we want to test, and find all the elements in all + * the binarie and make sure we get everything we expect. + */ + myBinary=CProjectHelper.findBinary(testProject, "test_g"); + elements=myBinary.getChildren(); + for (int i=0;i<elements.length;i++) { + expSyms.foundString(elements[i].getElementName()); + } + + assertTrue(expSyms.getMissingString(), expSyms.gotAll()); + assertTrue(expSyms.getExtraString(), !expSyms.gotExtra()); + } + + /*** + * A quick check to make sure the getBSS function works as expected. + */ + public void testGetBss(){ + IBinary bigBinary,littleBinary; + bigBinary=CProjectHelper.findBinary(testProject, "exebig_g"); + littleBinary=CProjectHelper.findBinary(testProject, "test_g"); + + assertTrue("Expected 432, Got: " + bigBinary.getBSS(), bigBinary.getBSS()==432); + assertTrue("Expected 4, Got: " + littleBinary.getBSS(), littleBinary.getBSS()==4); + } + /*** + * A quick check to make sure the getBSS function works as expected. + */ + public void testGetData(){ + IBinary bigBinary,littleBinary; + bigBinary=CProjectHelper.findBinary(testProject, "exebig_g"); + littleBinary=CProjectHelper.findBinary(testProject, "test_g"); + /* These two test used to fail due to pr 23602 */ + assertTrue("Expected 256 Got: " + bigBinary.getData(), bigBinary.getData()==256); + assertTrue("Expected 196, Got: " + littleBinary.getData(), littleBinary.getData()==196); + } + + /*** + * A very small set of tests to make usre Binary.getCPU() seems to return + * something sane for the most common exe type (x86) and one other (ppc) + * This is not a in depth test at all. + */ + public void testGetCpu() { + IBinary myBinary; + myBinary=CProjectHelper.findBinary(testProject, "exebig_g"); + + assertTrue("Expected: x86 Got: " + myBinary.getCPU(),myBinary.getCPU().equals("x86")); + myBinary=CProjectHelper.findBinary(testProject, ppcexefile.getLocation().lastSegment()); + assertTrue("Expected: ppc Got: " + myBinary.getCPU(),myBinary.getCPU().equals("ppc")); + + } + + /**** + * A set of simple tests to make sute getNeededSharedLibs seems to be sane + */ + public void testGetNeededSharedLibs() { + IBinary myBinary; + String[] exelibs={"libsocket.so.2", "libc.so.2"}; + String[] bigexelibs={"libc.so.2"}; + String[] gotlibs; + ExpectedStrings exp; + int x; + + exp=new ExpectedStrings(exelibs); + myBinary=CProjectHelper.findBinary(testProject, "test_g"); + gotlibs=myBinary.getNeededSharedLibs(); + for (x=0;x<gotlibs.length;x++) { + exp.foundString(gotlibs[x]); + } + assertTrue(exp.getMissingString(), exp.gotAll()); + assertTrue(exp.getExtraString(), !exp.gotExtra()); + + exp=new ExpectedStrings(bigexelibs); + myBinary=CProjectHelper.findBinary(testProject,"exebig_g"); + gotlibs=myBinary.getNeededSharedLibs(); + for (x=0;x<gotlibs.length;x++) { + exp.foundString(gotlibs[x]); + } + assertTrue(exp.getMissingString(), exp.gotAll()); + assertTrue(exp.getExtraString(), !exp.gotExtra()); + + exp=new ExpectedStrings(bigexelibs); + myBinary=CProjectHelper.findBinary(testProject, "libtestlib_g.so"); + gotlibs=myBinary.getNeededSharedLibs(); + for (x=0;x<gotlibs.length;x++) { + exp.foundString(gotlibs[x]); + } + assertTrue(exp.getMissingString(), exp.gotAll()); + assertTrue(exp.getExtraString(), !exp.gotExtra()); + + } + + /**** + * Simple tests for the getSoname method; + */ + public void testGetSoname() { + IBinary myBinary; + String name; + myBinary=CProjectHelper.findBinary(testProject, "test_g"); + assertTrue(myBinary.getSoname().equals("")); + + myBinary=CProjectHelper.findBinary(testProject, "libtestlib_g.so"); + name=myBinary.getSoname(); + assertNotNull(name); + assertTrue("Expected: libtestlib_g.so.1 Got: " + name, + name.equals("libtestlib_g.so.1")); + + } + + /*** + * Simple tests for getText + */ + public void testGetText() { + IBinary bigBinary,littleBinary; + bigBinary=CProjectHelper.findBinary(testProject, bigexe.getLocation().lastSegment()); + littleBinary=CProjectHelper.findBinary(testProject, exefile.getLocation().lastSegment()); + /* These two asserts used to fail due to pr 23602 */ + assertTrue("Expected 886, Got: " + bigBinary.getText(), bigBinary.getText()==886); + assertTrue("Expected 1223, Got: " + littleBinary.getText(), littleBinary.getText()==1223); + } + + /*** + * Simple tests for the hadDebug call + */ + public void testHasDebug() { + IBinary myBinary; + myBinary = CProjectHelper.findBinary(testProject, "test_g"); + assertTrue(myBinary.hasDebug()); + myBinary = CProjectHelper.findBinary(testProject, "libtestlib_g.so"); + assertTrue(myBinary.hasDebug()); + myBinary = CProjectHelper.findBinary(testProject, "exetest"); + assertTrue(!myBinary.hasDebug()); + } + + /*** + * Sanity - isBinary and isReadonly should always return true; + */ + public void testisBinRead() { + IBinary myBinary; + myBinary =CProjectHelper.findBinary(testProject, "test_g"); + assertTrue(myBinary != null); + assertTrue(myBinary.isReadOnly()); + + } + + /*** + * Quick tests to make sure isObject works as expected. + */ + public void testIsObject() { + IBinary myBinary; + myBinary=CProjectHelper.findObject(testProject, "exetest.o"); + assertTrue(myBinary.isObject()); + + + myBinary= CProjectHelper.findBinary(testProject, "test_g"); + assertTrue(!myBinary.isObject()); + + myBinary= CProjectHelper.findBinary(testProject, "libtestlib_g.so"); + assertTrue(!myBinary.isObject()); + + myBinary= CProjectHelper.findBinary(testProject, "exetest"); + assertTrue(!myBinary.isObject()); + + } + + /*** + * Quick tests to make sure isSharedLib works as expected. + */ + public void testIsSharedLib() { + IBinary myBinary; + + myBinary=CProjectHelper.findObject(testProject, "exetest.o"); + assertTrue(!myBinary.isSharedLib()); + + myBinary= CProjectHelper.findBinary(testProject, "libtestlib_g.so"); + assertTrue(myBinary.isSharedLib()); + + myBinary= CProjectHelper.findBinary(testProject, "test_g"); + assertTrue(!myBinary.isSharedLib()); + + + myBinary= CProjectHelper.findBinary(testProject, "exetest"); + assertTrue(!myBinary.isSharedLib()); + + } + + /*** + * Quick tests to make sure isExecutable works as expected. + */ + public void testIsExecutable() throws InterruptedException { + IBinary myBinary; + myBinary=CProjectHelper.findObject(testProject, "exetest.o"); + assertTrue(!myBinary.isExecutable()); + + myBinary=CProjectHelper.findBinary(testProject, "test_g"); + assertTrue(myBinary.isExecutable()); + + myBinary= CProjectHelper.findBinary(testProject, "libtestlib_g.so"); + assertTrue(!myBinary.isExecutable()); + + + myBinary= CProjectHelper.findBinary(testProject, "exetest"); + assertTrue(myBinary.isExecutable()); + + } + + /*** + * Simple sanity test to make sure Binary.isBinary returns true + * + */ + public void testIsBinary() throws CoreException,FileNotFoundException,Exception { + IBinary myBinary; + + myBinary=CProjectHelper.findBinary(testProject, "exebig_g"); + assertTrue("A Binary", myBinary != null); + } + + + + +} diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelElementsTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelElementsTests.java new file mode 100644 index 00000000000..c9e69e96092 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/CModelElementsTests.java @@ -0,0 +1,473 @@ +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.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.IEnumeration; +import org.eclipse.cdt.core.model.IEnumerator; +import org.eclipse.cdt.core.model.IField; +import org.eclipse.cdt.core.model.IFunction; +import org.eclipse.cdt.core.model.IFunctionDeclaration; +import org.eclipse.cdt.core.model.IInclude; +import org.eclipse.cdt.core.model.IMacro; +import org.eclipse.cdt.core.model.IMember; +import org.eclipse.cdt.core.model.IMethod; +import org.eclipse.cdt.core.model.IMethodDeclaration; +import org.eclipse.cdt.core.model.INamespace; +import org.eclipse.cdt.core.model.IParent; +import org.eclipse.cdt.core.model.IStructure; +import org.eclipse.cdt.core.model.ITypeDef; +import org.eclipse.cdt.core.model.IVariable; +import org.eclipse.cdt.core.model.IVariableDeclaration; +import org.eclipse.cdt.internal.core.model.CElement; +import org.eclipse.cdt.internal.core.model.StructureTemplate; +import org.eclipse.cdt.internal.core.model.FunctionTemplate; +import org.eclipse.cdt.internal.core.model.MethodTemplate; +import org.eclipse.cdt.internal.core.model.TranslationUnit; +import org.eclipse.cdt.internal.core.model.VariableTemplate; +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; + +public class CModelElementsTests extends TestCase { + private ICProject fCProject; + private IFile headerFile; + private NullProgressMonitor monitor; + + public static Test suite() { + TestSuite suite= new TestSuite(CModelElementsTests.class.getName()); + suite.addTest(new CModelElementsTests("testCModelElements")); + return suite; + } + + public CModelElementsTests(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 testCModelElements(){ + TranslationUnit tu = new TranslationUnit(fCProject, headerFile); + // parse the translation unit to get the elements tree + Map newElement = tu.parse(true); // require line numbers + + // tu ---> 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<A, B>(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<A, B>(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<T, Tibor>")); + 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<T, Tibor>")); + 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<bool, int> : 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;x<flags.length;x++) { + if (flags[x]!=IConstants.AccStatic) + assertTrue("isStatic with a non-static", !Flags.isStatic(flags[x])); + } + } + + public void testIsAbstract() + { + int x; + assertTrue("isAbstract with a abstract", Flags.isAbstract(IConstants.AccAbstract)); + for (x=0;x<flags.length;x++) { + if (flags[x]!=IConstants.AccAbstract) + assertTrue("isAbstract with a non-abstract", !Flags.isAbstract(flags[x])); + } + } + + public void testIsExplicit() + { + int x; + assertTrue("isExplicit with a explicit", Flags.isExplicit(IConstants.AccExplicit)); + for (x=0;x<flags.length;x++) { + if (flags[x]!=IConstants.AccExplicit) + assertTrue("isExplicit with a non-explicit", !Flags.isExplicit(flags[x])); + } + } + + public void testIsExport() + { + int x; + assertTrue("isExport with a Export", Flags.isExport(IConstants.AccExport)); + for (x=0;x<flags.length;x++) { + if (flags[x]!=IConstants.AccExport) + assertTrue("isExport with a non-Export", !Flags.isExport(flags[x])); + } + } + public void testIsExtern() + { + int x; + assertTrue("isExtern with a Extern", Flags.isExtern(IConstants.AccExtern)); + for (x=0;x<flags.length;x++) { + if (flags[x]!=IConstants.AccExtern) + assertTrue("isExtern with a non-Extern", !Flags.isExtern(flags[x])); + } + } + + public void testIsInline() + { + int x; + assertTrue("isInline with a Inline", Flags.isInline(IConstants.AccInline)); + for (x=0;x<flags.length;x++) { + if (flags[x]!=IConstants.AccInline) + assertTrue("isInline with a non-Inline", !Flags.isInline(flags[x])); + } + } + + public void testIsMutable() + { + int x; + assertTrue("isMutable with a Mutable", Flags.isMutable(IConstants.AccMutable)); + for (x=0;x<flags.length;x++) { + if (flags[x]!=IConstants.AccMutable) + assertTrue("isMutable with a non-Mutable", !Flags.isMutable(flags[x])); + } + } + + public void testIsPrivate() + { + int x; + assertTrue("isPrivate with a Private", Flags.isPrivate(IConstants.AccPrivate)); + for (x=0;x<flags.length;x++) { + if (flags[x]!=IConstants.AccPrivate) + assertTrue("isPrivate with a non-Private", !Flags.isPrivate(flags[x])); + } + } + + public void testIsPublic() + { + int x; + assertTrue("isPublic with a Public", Flags.isPublic(IConstants.AccPublic)); + for (x=0;x<flags.length;x++) { + if (flags[x]!=IConstants.AccPublic) + assertTrue("isPublic with a non-Public", !Flags.isPublic(flags[x])); + } + } + + public void testIsProtected() + { + int x; + assertTrue("isProtected with a Protected", Flags.isProtected(IConstants.AccProtected)); + for (x=0;x<flags.length;x++) { + if (flags[x]!=IConstants.AccProtected) + assertTrue("isProtected with a non-Protected", !Flags.isProtected(flags[x])); + } + } + + public void testIsRegister() + { + int x; + assertTrue("isRegister with a Register", Flags.isRegister(IConstants.AccRegister)); + for (x=0;x<flags.length;x++) { + if (flags[x]!=IConstants.AccRegister) + assertTrue("isRegister with a non-Register", !Flags.isRegister(flags[x])); + } + } + + public void testIsVirtual() + { + int x; + assertTrue("isVirtual with a Virtual", Flags.isVirtual(IConstants.AccVirtual)); + for (x=0;x<flags.length;x++) { + if (flags[x]!=IConstants.AccVirtual) + assertTrue("isVirtual with a non-Virtual", !Flags.isVirtual(flags[x])); + } + } + + public void testIsVolatile() + { + int x; + assertTrue("isVolatile with a Volatile", Flags.isVolatile(IConstants.AccVolatile)); + for (x=0;x<flags.length;x++) { + if (flags[x]!=IConstants.AccVolatile) + assertTrue("isVolatile with a non-Volatile", !Flags.isVolatile(flags[x])); + } + } + + + + + + +} diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IIncludeTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IIncludeTests.java new file mode 100644 index 00000000000..156bb121cb1 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IIncludeTests.java @@ -0,0 +1,116 @@ +/* + * Created on Jun 4, 2003 + * by bnicolle + */ +package org.eclipse.cdt.core.model.tests; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.IInclude; +import org.eclipse.cdt.core.model.tests.IntegratedCModelTest; + +/** + * @author bnicolle + * + */ +public class IIncludeTests extends IntegratedCModelTest { + + /** + * @param string + */ + public IIncludeTests(String string) { + super( string ); + } + + /** + * @see org.eclipse.cdt.internal.core.model.IntegratedCModelTest + */ + public String getSourcefileSubdir() { + return "resources/cmodel/"; + } + + /** + * @see org.eclipse.cdt.internal.core.model.IntegratedCModelTest + */ + public String getSourcefileResource() { + return "IIncludeTest.h"; + } + + /** + * @returns a test suite named after this class + * containing all its public members named "test*" + */ + public static Test suite() { + TestSuite suite= new TestSuite(IIncludeTests.class); + return suite; + } + + public void testGetIncludeName() + { + ITranslationUnit tu = getTU(); + IInclude[] theIncludes = null; + try { + theIncludes = tu.getIncludes(); + } + catch( CModelException c ) + { + assertNotNull("CModelException thrown",c); + } + + String getIncludeNameList[] = new String[] { + new String("stdio.h"), + new String("whatever.h"), + new String("src/slash.h"), + new String("src\\backslash.h"), // that's a single backslash, escaped + new String("Program Files/space.h"), + new String("../up1dir.h"), + new String("./samedir.h"), + new String("different_extension1.hpp"), + new String("different_extension2.hh"), + new String("different_extension3.x"), + new String("no_extension"), + new String("whitespace_after_hash"), + new String("whitespace_before_hash"), + new String("resync_after_bad_parse_1"), + new String("resync_after_bad_parse_2"), + new String("one"), // C-spec does not allow this, but that's OK for our present purposes + new String("resync_after_bad_parse_3"), + new String("invalid.h"), // C-spec does not allow this, but that's OK for our present purposes + // TODO: expect new String("MYINCFILE"), + // TODO: expect new String("xstr(INCFILE(2)).h") + }; + assertEquals( getIncludeNameList.length, theIncludes.length ); + for( int i=0; i<getIncludeNameList.length; i++ ) + { + IInclude inc1 = theIncludes[i]; + + assertEquals( getIncludeNameList[i], inc1.getIncludeName() ); + } +// checkLineNumbers((CElement)inc1, 2, 2); + } + + public void testIsStandard() + { + ITranslationUnit tu = getTU(); + IInclude[] theIncludes = null; + try { + theIncludes = tu.getIncludes(); + } + catch( CModelException c ) + { + assertNotNull("CModelException thrown",c); + } + boolean isStandardList[] = new boolean[] { + true, false + }; + for( int i=0; i<isStandardList.length; i++ ) + { + IInclude inc1 = theIncludes[i]; + assertEquals( isStandardList[i], inc1.isStandard() ); + } + } +} + diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IMacroTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IMacroTests.java new file mode 100644 index 00000000000..f4d1d67d5d0 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IMacroTests.java @@ -0,0 +1,106 @@ +/* + * Created on Jun 6, 2003 + * by bnicolle + */ +package org.eclipse.cdt.core.model.tests; + +import org.eclipse.cdt.core.model.IMacro; +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.util.ArrayList; + +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.core.model.tests.IntegratedCModelTest; + +/** + * IMacroTest - Class for testing IMacro + * + * @author bnicolle + * + */ +public class IMacroTests extends IntegratedCModelTest { + /** + * @returns a test suite named after this class + * containing all its public members named "test*" + */ + public static Test suite() { + TestSuite suite= new TestSuite( IMacroTests.class.getName() ); + suite.addTest( new IMacroTests("testGetElementName")); + // TODO Bug# 38740: suite.addTest( new IMacroTest("testGetIdentifierList")); + // TODO Bug# 38740: suite.addTest( new IMacroTest("testGetTokenSequence")); + return suite; + } + + /** + * @param name + */ + public IMacroTests(String name) { + super(name); + } + + /** + * @see org.eclipse.cdt.internal.core.model.IntegratedCModelTest + */ + public String getSourcefileSubdir() { + return "resources/cmodel/"; + } + + /** + * @see org.eclipse.cdt.internal.core.model.IntegratedCModelTest + */ + public String getSourcefileResource() { + return "IMacroTest.h"; + } + + public void testGetElementName() { + ITranslationUnit tu = getTU(); + ArrayList arrayElements = tu.getChildrenOfType( ITranslationUnit.C_MACRO ); + + String expectedList[] = new String[] { + "SINGLETON", + "NUMBER", + "PRINT" + }; + assertEquals( expectedList.length, arrayElements.size() ); + for( int i=0; i<expectedList.length; i++ ) + { + IMacro iMacro = (IMacro) arrayElements.get(i); + assertEquals( expectedList[i], iMacro.getElementName() ); + } + } + + public void testGetIdentifierList() { + ITranslationUnit tu = getTU(); + ArrayList arrayElements = tu.getChildrenOfType( ITranslationUnit.C_MACRO ); + + String expectedList[] = new String[] { + "", + "", + "string,msg" + }; + assertEquals( expectedList.length, arrayElements.size() ); + for( int i=0; i<expectedList.length; i++ ) + { + IMacro iMacro = (IMacro) arrayElements.get(i); + assertEquals( expectedList[i], iMacro.getIdentifierList() ); + } + } + + public void testGetTokenSequence() { + ITranslationUnit tu = getTU(); + ArrayList arrayElements = tu.getChildrenOfType( ITranslationUnit.C_MACRO ); + + String expectedList[] = new String[] { + "", + "1", + "printf(string, msg)" + }; + assertEquals( expectedList.length, arrayElements.size() ); + for( int i=0; i<expectedList.length; i++ ) + { + IMacro iMacro = (IMacro) arrayElements.get(i); + assertEquals( expectedList[i], iMacro.getTokenSequence() ); + } + } +} diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IStructureTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IStructureTests.java new file mode 100644 index 00000000000..7eb0034209d --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IStructureTests.java @@ -0,0 +1,422 @@ +/* + * Created on Jun 9, 2003 + * by bnicolle + */ +package org.eclipse.cdt.core.model.tests; + +import org.eclipse.cdt.core.model.*; + +import junit.framework.*; + +import java.util.ArrayList; + +/** + * @author bnicolle + * + */ +public class IStructureTests extends IntegratedCModelTest { + /** + * @param name + */ + public IStructureTests(String name) { + super(name); + } + + /** + * @see org.eclipse.cdt.internal.core.model.IntegratedCModelTest + */ + public String getSourcefileSubdir() { + return "resources/cmodel/"; + } + + /** + * @see org.eclipse.cdt.internal.core.model.IntegratedCModelTest + */ + public String getSourcefileResource() { + return "IStructure.c"; + } + + /** + * @returns a test suite named after this class + * containing all its public members named "test*" + */ + public static Test suite() { + TestSuite suite= new TestSuite( IStructureTests.class.getName() ); + + // TODO check C-only behaviour using C_NATURE vs CC_NATURE + + // Interface tests: + suite.addTest( new IStructureTests("testGetChildrenOfTypeStruct")); + suite.addTest( new IStructureTests("testGetChildrenOfTypeClass")); // C++ only + // TODO Bug# 38985: suite.addTest( new IStructureTests("testGetFields")); + suite.addTest( new IStructureTests("testGetFieldsHack")); + // TODO Bug# 38985: suite.addTest( new IStructureTests("testGetField")); + // TODO Bug# 38985: suite.addTest( new IStructureTests("testGetMethods")); // C++ only + suite.addTest( new IStructureTests("testGetMethodsHack")); // C++ only + // TODO Bug# 38985: suite.addTest( new IStructureTests("testGetMethod")); // C++ only + suite.addTest( new IStructureTests("testIsStruct")); + suite.addTest( new IStructureTests("testIsClass")); // C++ only + suite.addTest( new IStructureTests("testIsUnion")); + // TODO Bug# 38985: suite.addTest( new IStructureTests("testIsAbstract")); // C++ only + // TODO Bug# 38985: suite.addTest( new IStructureTests("testGetBaseTypes")); // C++ only + // TODO Bug# 38985: suite.addTest( new IStructureTests("testGetAccessControl")); // C++ only + + // Language Specification tests: + suite.addTest( new IStructureTests("testAnonymousStructObject")); + suite.addTest( new IStructureTests("testInnerStruct")); + + return suite; + } + + public void testGetChildrenOfTypeStruct() { + ITranslationUnit tu = getTU(); + ArrayList arrayStructs = tu.getChildrenOfType(ICElement.C_STRUCT); + String[] myExpectedStructs = { + "testStruct1", "testStruct2", "testStruct3", + /* 2 anonymous structs */ "", "", "testStruct7", + "testStruct8" + }; + assertEquals(myExpectedStructs.length,arrayStructs.size()); + for(int i=0; i<myExpectedStructs.length; i++) { + IStructure myIStruct = (IStructure) arrayStructs.get(i); + assertNotNull( "Failed on "+i, myIStruct); + assertEquals(myExpectedStructs[i], myIStruct.getElementName()); + } + } + public void testGetChildrenOfTypeClass() { + ITranslationUnit tu = getTU(); + ArrayList arrayClasses = tu.getChildrenOfType(ICElement.C_CLASS); + String[] myExpectedClasses = { + "testClass1", "testClass3", "testClass4Abstract", + "testClass5", "testClass6" }; + assertEquals(myExpectedClasses.length,arrayClasses.size()); + for(int i=0; i<myExpectedClasses.length; i++) { + IStructure myIStruct = (IStructure) arrayClasses.get(i); + assertNotNull( "Failed on "+i, myIStruct); + assertEquals(myExpectedClasses[i], myIStruct.getElementName()); + } + } + + public void testGetFields() { + ITranslationUnit tu = getTU(); + ArrayList myArrayStructs = tu.getChildrenOfType(ICElement.C_STRUCT); + IStructure myIStruct = (IStructure) myArrayStructs.get(0); + IField[] myArrayIField = myIStruct.getFields(); + String[] myExpectedFields = { + "m_field1","m_field2","m_field3", + "m_field4","m_field5","m_field6", + }; + assertEquals(myExpectedFields.length, myArrayIField.length); + for(int i=0; i<myArrayIField.length; i++) { + assertNotNull( "Failed on "+i, myArrayIField[i]); + assertEquals("Failed on "+i, + myExpectedFields[i], myArrayIField[i].getElementName()); + } + } + + // TODO Bug# 38985: remove testGetFieldsHack() + public void testGetFieldsHack() { + ITranslationUnit tu = getTU(); + ArrayList myArrayStructs = tu.getChildrenOfType(ICElement.C_STRUCT); + IStructure myIStruct = (IStructure) myArrayStructs.get(0); + String[] myExpectedFields = { + "m_field1","m_field2","m_field3", + "m_field4","m_field5","m_field6", + }; + ArrayList myArrayIField = myIStruct.getChildrenOfType(ICElement.C_FIELD); + assertEquals(myExpectedFields.length, myArrayIField.size()); + for(int i=0; i<myArrayIField.size(); i++) { + IField myIField = (IField) myArrayIField.get(i); + assertNotNull( "Failed on "+i, myIField ); + assertEquals("Failed on "+i, + myExpectedFields[i], myIField.getElementName()); + } + } + public void testGetField() { + ITranslationUnit tu = getTU(); + ArrayList myArrayStructs = tu.getChildrenOfType(ICElement.C_STRUCT); + IStructure myIStruct = (IStructure) myArrayStructs.get(0); + String[] myExpectedFields = { + "m_field1","m_field2","m_field3", + "m_field4","m_field5","m_field6", + }; + for(int i=0; i<myExpectedFields.length; i++) { + IField myIField = myIStruct.getField( myExpectedFields[i] ); + assertNotNull( "Failed on "+i, myIField); + } + + String[] myUnexpectedFields = { + "m_field7","m_field8","m_field9", + }; + for(int i=0; i<myUnexpectedFields.length; i++) { + IField myIField = myIStruct.getField( myUnexpectedFields[i] ); + assertNull( "Failed on "+i, myIField); + } + } + public void testGetMethods() { + ITranslationUnit tu = getTU(); + ArrayList myArrayStructs = tu.getChildrenOfType(ICElement.C_STRUCT); + IStructure myIStruct = (IStructure) myArrayStructs.get(0); + IMethod[] myArrayIMethod = myIStruct.getMethods(); + String[] myExpectedMethods = { + "method1","method2","testStruct1","~testStruct1" + }; + assertEquals(myExpectedMethods.length, myArrayIMethod.length); + for(int i=0; i<myArrayIMethod.length; i++) { + assertNotNull( "Failed on "+i, myArrayIMethod[i]); + assertEquals("Failed on "+i, + myExpectedMethods[i], myArrayIMethod[i].getElementName()); + } + } + // TODO Bug# 38985: remove testGetMethodsHack() + public void testGetMethodsHack() { + ITranslationUnit tu = getTU(); + ArrayList myArrayStructs = tu.getChildrenOfType(ICElement.C_STRUCT); + IStructure myIStruct = (IStructure) myArrayStructs.get(0); + ArrayList myArrayIMethod = myIStruct.getChildrenOfType(ICElement.C_METHOD_DECLARATION); + myArrayIMethod.addAll( myIStruct.getChildrenOfType(ICElement.C_METHOD) ); + String[] myExpectedMethods = { + "method1","method2","testStruct1","~testStruct1" + }; + assertEquals(myExpectedMethods.length, myArrayIMethod.size()); + for(int i=0; i<myArrayIMethod.size(); i++) { + IMethodDeclaration myIMethod = (IMethodDeclaration) myArrayIMethod.get(i); + assertNotNull( "Failed on "+i, myIMethod); + assertEquals("Failed on "+i, + myExpectedMethods[i], myIMethod.getElementName()); + } + } + public void testGetMethod() { + ITranslationUnit tu = getTU(); + ArrayList myArrayStructs = tu.getChildrenOfType(ICElement.C_STRUCT); + IStructure myIStruct = (IStructure) myArrayStructs.get(0); + String[] myExpectedMethods = { + "method1","method2","testStruct1","~testStruct1" + }; + for(int i=0; i<myExpectedMethods.length; i++) { + IMethod myIMethod = myIStruct.getMethod( myExpectedMethods[i] ); + assertNotNull( "Failed on "+i, myIMethod); + } + + String[] myUnexpectedMethods = { + "method7","method8","method9", + }; + for(int i=0; i<myUnexpectedMethods.length; i++) { + IMethod myIMethod = myIStruct.getMethod( myUnexpectedMethods[i] ); + assertNull( "Failed on "+i, myIMethod); + } + } + + public void testIsUnion() { + ITranslationUnit tu = getTU(); + ICElement myElementUnion = null; + ICElement myElementNonUnion = null; + try { + myElementUnion = tu.getElement("testUnion1"); + myElementNonUnion = tu.getElement("testStruct1"); + } + catch( CModelException c ) + { + assertNotNull("CModelException thrown",c); + } + assertNotNull( myElementUnion ); + assertTrue( myElementUnion.getElementType()==ICElement.C_UNION ); + IStructure myStructUnion = (IStructure) myElementUnion; + assertNotNull( myStructUnion ); + assertTrue( myStructUnion.isUnion() ); + + assertNotNull( myElementNonUnion ); + assertTrue( myElementNonUnion.getElementType()!=ICElement.C_UNION ); + IStructure myStructNonUnion = (IStructure) myElementNonUnion; + assertNotNull( myStructNonUnion ); + assertFalse( myStructNonUnion.isUnion() ); + } + public void testIsStruct() { + ITranslationUnit tu = getTU(); + ICElement myElementStruct = null; + ICElement myElementNonStruct = null; + try { + myElementStruct = tu.getElement("testStruct1"); + myElementNonStruct = tu.getElement("testClass1"); + } + catch( CModelException c ) + { + assertNotNull("CModelException thrown",c); + } + assertNotNull( myElementStruct ); + assertTrue( myElementStruct.getElementType()==ICElement.C_STRUCT ); + IStructure myStructStruct = (IStructure) myElementStruct; + assertNotNull( myStructStruct ); + assertTrue( myStructStruct.isStruct() ); + + assertNotNull( myElementNonStruct ); + assertTrue( myElementNonStruct.getElementType()!=ICElement.C_STRUCT ); + IStructure myStructNonStruct = (IStructure) myElementNonStruct; + assertNotNull( myStructNonStruct ); + assertFalse( myStructNonStruct.isStruct() ); + } + + public void testIsClass() { + ITranslationUnit tu = getTU(); + ICElement myElementClass = null; + ICElement myElementNonClass = null; + try { + myElementClass = tu.getElement("testClass1"); + myElementNonClass = tu.getElement("testStruct1"); + } + catch( CModelException c ) + { + assertNotNull("CModelException thrown",c); + } + assertNotNull( myElementClass ); + assertTrue( myElementClass.getElementType()==ICElement.C_CLASS ); + IStructure myStructClass = (IStructure) myElementClass; + assertNotNull( myStructClass ); + assertTrue( myStructClass.isClass() ); + + assertNotNull( myElementNonClass ); + assertTrue( myElementNonClass.getElementType()!=ICElement.C_CLASS ); + IStructure myStructNonClass = (IStructure) myElementNonClass; + assertNotNull( myStructNonClass ); + assertFalse( myStructNonClass.isClass() ); + } + + public void testIsAbstract() { + ITranslationUnit tu = getTU(); + ICElement myElementAbstract = null; + ICElement myElementNonAbstract = null; + try { + myElementAbstract = tu.getElement("testClass4Abstract"); + myElementNonAbstract = tu.getElement("testClass1"); + } + catch( CModelException c ) + { + assertNotNull("CModelException thrown",c); + } + assertNotNull( myElementAbstract ); + assertTrue( myElementAbstract.getElementType()==ICElement.C_CLASS ); + IStructure myStructAbstract = (IStructure) myElementAbstract; + assertNotNull( myStructAbstract ); + assertTrue( myStructAbstract.isAbstract() ); + + assertNotNull( myElementNonAbstract ); + assertTrue( myElementNonAbstract.getElementType()!=ICElement.C_CLASS ); + IStructure myStructNonAbstract = (IStructure) myElementNonAbstract; + assertNotNull( myStructNonAbstract ); + assertFalse( myStructNonAbstract.isAbstract() ); + } + + // IInheritance + public void testGetBaseTypes() { + ITranslationUnit tu = getTU(); + ICElement myElementDerived = null; + IStructure[] myBaseTypes = null; + try { + myElementDerived = tu.getElement("testClass5"); // throws + assertNotNull( myElementDerived ); + assertTrue( myElementDerived.getElementType()==ICElement.C_CLASS ); + IStructure myStructDerived = (IStructure) myElementDerived; + assertNotNull( myStructDerived ); + myBaseTypes = myStructDerived.getBaseTypes(); // throws + } + catch( CModelException c ) + { + assertNotNull("CModelException thrown",c); + } + + String[] myExpectedBaseTypes = { + "testClass1","testClass3","testClass4" + }; + assertEquals( myExpectedBaseTypes.length, myBaseTypes.length ); + for(int i=0; i<myBaseTypes.length; i++) { + assertEquals( "Failed on "+i, myExpectedBaseTypes[i], myBaseTypes[i].getElementName() ); + } + } + + // tests IInheritance.getAccessControl(int), + // not IDeclaration.getAccessControl() + public void testGetAccessControl() { + ITranslationUnit tu = getTU(); + ICElement myElementDerived = null; + IStructure[] myBaseTypes = null; + try { + myElementDerived = tu.getElement("testClass5"); // throws + assertNotNull( myElementDerived ); + assertTrue( myElementDerived.getElementType()==ICElement.C_CLASS ); + IStructure myStructDerived = (IStructure) myElementDerived; + assertNotNull( myStructDerived ); + myBaseTypes = myStructDerived.getBaseTypes(); // throws + + int[] myExpectedAccessControl = { + // TODO #38986: expect appropriate access control tags + ICElement.CPP_PUBLIC, + org.eclipse.cdt.core.index.TagFlags.T_PROTECTED, + ICElement.CPP_PRIVATE + }; + assertEquals( myExpectedAccessControl.length, myBaseTypes.length ); + for(int i=0; i<myBaseTypes.length; i++) { + int myAccessControl = myStructDerived.getAccessControl(i); // throws + assertEquals( "Failed on "+i, myExpectedAccessControl[i], myAccessControl ); + } + } + catch( CModelException c ) + { + assertNotNull("CModelException thrown",c); + } + } + + // getStructureInfo + public void testGetStructureInfo() { + } + + // TODO: Not tested; Bug# 38958. public void testGetInitializer() + // TODO: Not tested; Bug# 38958. public void testGetTypeName() + // TODO: Not tested; Bug# 38958. public void testIsConst() + // TODO: Not tested; Bug# 38958. public void testIsStatic() + // TODO: Not tested; Bug# 38958. public void testIsVolatile() + // TODO: Not tested; Bug# 38958. public void testGetAccessControl_Void() + + // + // Language Specification Tests + // + + public void testAnonymousStructObject() { + ITranslationUnit tu = getTU(); + ICElement myElement = null; + try { + myElement = tu.getElement("testAnonymousStructObject1"); + } + catch( CModelException c ) + { + assertNotNull("CModelException thrown",c); + } + assertNotNull( myElement ); + assertEquals( ICElement.C_VARIABLE, myElement.getElementType() ); + } + + public void testInnerStruct() { + ITranslationUnit tu = getTU(); + ICElement myElement = null; + try { + myElement = tu.getElement("testStruct8"); + } + catch( CModelException c ) + { + assertNotNull("CModelException thrown",c); + } + assertNotNull( myElement ); + IStructure myIStruct = (IStructure) myElement; + assertNotNull( myIStruct ); + + String[] myExpectedInnerStructs = { + "testStruct9Inner", "testStruct10Inner" + }; + ArrayList myInnerStructs = myIStruct.getChildrenOfType(ICElement.C_STRUCT); + assertEquals( myExpectedInnerStructs.length, myInnerStructs.size() ); + for(int i=0; i<myExpectedInnerStructs.length; i++) { + IStructure myInnerStruct = (IStructure) myInnerStructs.get(i); + assertNotNull( "Failed on "+i, myInnerStruct ); + assertEquals( "Failed on "+i, myExpectedInnerStructs[i], myInnerStruct.getElementName() ); + } + } +} diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IntegratedCModelTest.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IntegratedCModelTest.java new file mode 100644 index 00000000000..d9ae14b3ce5 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/IntegratedCModelTest.java @@ -0,0 +1,104 @@ +/* + * Created on Jun 3, 2003 + * by bnicolle + */ +package org.eclipse.cdt.core.model.tests; + +import junit.framework.TestCase; + +import java.io.FileInputStream; +import java.util.Map; + +import org.eclipse.cdt.testplugin.CProjectHelper; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.ITranslationUnit; +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; +import org.eclipse.cdt.core.CCProjectNature; +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.internal.core.model.TranslationUnit; + +/** + * @author bnicolle + * + */ +public abstract class IntegratedCModelTest extends TestCase { + + private ICProject fCProject; + private IFile sourceFile; + private NullProgressMonitor monitor; + + /** + * + */ + public IntegratedCModelTest() { + super(); + } + + /** + * @param name + */ + public IntegratedCModelTest(String name) { + super(name); + } + + /** + * @return the subdirectory (from the plugin root) containing the required + * test sourcefile (plus a trailing slash) + */ + abstract public String getSourcefileSubdir(); + + /** + * @return the name of the test source-file + */ + abstract public String getSourcefileResource(); + + public 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"); + + sourceFile = fCProject.getProject().getFile( getSourcefileResource() ); + if (!sourceFile.exists()) { + try{ + FileInputStream fileIn = new FileInputStream(pluginRoot+ getSourcefileSubdir() + getSourcefileResource() ); + sourceFile.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); + } + + protected void tearDown() throws Exception { + CProjectHelper.delete(fCProject); + } + + 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 ITranslationUnit getTU() { + TranslationUnit tu = new TranslationUnit(fCProject, sourceFile); + // parse the translation unit to get the elements tree + Map newElement = tu.parse(false); // FALSE=require line numbers + return tu; + } +} diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/TranslationUnitTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/TranslationUnitTests.java new file mode 100644 index 00000000000..d695051e644 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/TranslationUnitTests.java @@ -0,0 +1,362 @@ +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 java.util.Stack; + +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.IInclude; +import org.eclipse.cdt.core.model.ITranslationUnit; +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.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's TranslationUnit + * class. There is nothing exotic here, mostly just sanity type tests + * + */ +public class TranslationUnitTests extends TestCase { + IWorkspace workspace; + IWorkspaceRoot root; + ICProject testProject; + IFile cfile, exefile, libfile, archfile, objfile; + Path cpath, exepath, libpath, archpath, objpath; + NullProgressMonitor monitor; + + /* This is a list of elements in the test .c file. It will be used + * in a number of places in the tests + */ + String[] expectedStringList= {"stdio.h", "unistd.h", "func2p", + "globalvar", "myenum", "mystruct", "mystruct_t", "myunion", "mytype", + "func1", "func2", "main", "func3"}; + int[] expectedLines={ 12,14,17,20,23,28,32,35,42,47,53,58,65}; + /* This is a list of that the types of the above list of elements is + * expected to be. + */ + int[] expectedTypes= { ICElement.C_INCLUDE, ICElement.C_INCLUDE, + ICElement.C_FUNCTION_DECLARATION, ICElement.C_VARIABLE, + ICElement.C_ENUMERATION, ICElement.C_STRUCT, ICElement.C_TYPEDEF, + ICElement.C_UNION, ICElement.C_TYPEDEF, ICElement.C_FUNCTION, + ICElement.C_FUNCTION, ICElement.C_FUNCTION,ICElement.C_FUNCTION}; + + + /** + * Constructor for TranslationUnitTests + * @param name + */ + public TranslationUnitTests(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,FileNotFoundException { + /*** + * The rest 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; + String pluginRoot=org.eclipse.core.runtime.Platform.getPlugin("org.eclipse.cdt.core.tests").find(new Path("/")).getFile(); + 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"); + + desc=workspace.getDescription(); + desc.setAutoBuilding(false); + workspace.setDescription(desc); + + /*** + * Setup the various files, paths and projects that are needed by the + * tests + */ + + 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/cfiles/TranslationUnits.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 { + // release resources here and clean-up + testProject.getProject().delete(true,true,monitor); + } + + public static TestSuite suite() { + TestSuite suite= new TestSuite(TranslationUnitTests.class.getName()); + suite.addTest(new TranslationUnitTests("testIsTranslationUnit")); + suite.addTest(new TranslationUnitTests("testGetChildren")); + suite.addTest(new TranslationUnitTests("testGetElement")); + suite.addTest(new TranslationUnitTests("testBug23478A")); + suite.addTest(new TranslationUnitTests("testBug23478B")); + // TODO: suite.addTest(new TranslationUnitTests("testGetElementAtLine")); + return suite; + } + + public static void main (String[] args){ + junit.textui.TestRunner.run(suite()); + } + + + + + /*** + * Simple sanity test to make sure TranslationUnit.isTranslationUnit returns true + * + */ + public void testIsTranslationUnit() throws CoreException,FileNotFoundException { + ITranslationUnit myTranslationUnit; + + myTranslationUnit=CProjectHelper.findTranslationUnit(testProject,"exetest.c"); + assertTrue("A TranslationUnit", myTranslationUnit != null); + + } + + /*** + * Simple sanity tests to make sure TranslationUnit.getChildren seems to + * basicly work + */ + public void testGetChildren() { + ITranslationUnit myTranslationUnit; + ICElement[] elements; + int x; + + ExpectedStrings expectedString=new ExpectedStrings(expectedStringList); + + myTranslationUnit=CProjectHelper.findTranslationUnit(testProject,"exetest.c"); + + + if (myTranslationUnit.hasChildren()) { + elements=myTranslationUnit.getChildren(); + for (x=0;x<elements.length;x++) { + expectedString.foundString(elements[x].getElementName()); + } + } + assertTrue("PR:23603 " +expectedString.getMissingString(),expectedString.gotAll()); + assertTrue(expectedString.getExtraString(),!expectedString.gotExtra()); + + } + + /*** + * Simple sanity tests for the getElement() call + */ + public void testGetElement() throws CModelException { + ITranslationUnit myTranslationUnit; + ICElement myElement; + Stack missing=new Stack(); + int x; + myTranslationUnit=CProjectHelper.findTranslationUnit(testProject,"exetest.c"); + + for (x=0;x<expectedStringList.length;x++) { + myElement=myTranslationUnit.getElement(expectedStringList[x]); + if (myElement==null) + missing.push(expectedStringList[x]); + else { + assertTrue("Expected:" + expectedStringList[x] + " Got:" + myElement.getElementName(), + expectedStringList[x].equals(myElement.getElementName())); + } + + } + if (!missing.empty()) { + String output=new String("PR:23603 Could not get elements: "); + while (!missing.empty()) + output+=missing.pop() + " "; + assertTrue(output, false); + } + + } + + /*** + * Simple sanity tests for the getInclude call + */ + public void testBug23478A() { + IInclude myInclude; + int x; + String includes[]={"stdio.h", "unistd.h"}; + ITranslationUnit myTranslationUnit=CProjectHelper.findTranslationUnit(testProject,"exetest.c"); + + for (x=0; x < includes.length; x++) { + myInclude=myTranslationUnit.getInclude(includes[x]); + if (myInclude==null) + fail("Unable to get include: " + includes[x]); + else { + // Failed test: Include.getIncludeName() always returns ""; + // assertTrue + assertTrue("PR:23478 Expected:"+ new String("") +" Got:"+ myInclude.getIncludeName(), includes[x].equals(myInclude.getIncludeName())); + } + } + + + } + /*** + * Simple sanity tests for the getIncludes call + */ + public void testBug23478B() throws CModelException { + IInclude myIncludes[]; + String includes[]={"stdio.h", "unistd.h"}; + ExpectedStrings myExp= new ExpectedStrings(includes); + int x; + ITranslationUnit myTranslationUnit=CProjectHelper.findTranslationUnit(testProject,"exetest.c"); + + myIncludes=myTranslationUnit.getIncludes(); + for (x=0; x < myIncludes.length; x++) { + myExp.foundString(myIncludes[x].getIncludeName()); + } + // Failed test: Include.getIncludeName() always returns ""; + // assertTrue + assertTrue(myExp.getMissingString(), myExp.gotAll()); + assertTrue(myExp.getExtraString(), !myExp.gotExtra()); + } + + + + /*** + * Simple sanity tests for the getElementAtLine() call + */ + public void testGetElementAtLine() throws CoreException { + ITranslationUnit myTranslationUnit; + ICElement myElement; + Stack missing=new Stack(); + int x; + myTranslationUnit=CProjectHelper.findTranslationUnit(testProject,"exetest.c"); + + for (x=0;x<expectedStringList.length;x++) { + myElement=myTranslationUnit.getElementAtLine(expectedLines[x]); + if (myElement==null) + missing.push(expectedStringList[x]); + else { + if (expectedStringList[x].equals("mystruct_t")) { + assertTrue("PR:23603 expected:" + expectedStringList[x] + " Got:" + myElement.getElementName(), + expectedStringList[x].equals(myElement.getElementName())); + } else { + assertTrue("Expected:" + expectedStringList[x] + " Got:" + myElement.getElementName(), + expectedStringList[x].equals(myElement.getElementName())); + } + + } + + } + if (!missing.empty()) { + String output=new String("PR: 23603 Could not get elements: "); + while (!missing.empty()) + output+=missing.pop() + " "; + assertTrue(output, false); + } + + } + /*** + * Simple sanity tests for the getInclude call + */ +/* Reintroduce this test when Bug# 23478 is fixed + public void testGetInclude() { + IInclude myInclude; + int x; + String includes[]={"stdio.h", "unistd.h"}; + ITranslationUnit myTranslationUnit=CProjectHelper.findTranslationUnit(testProject,"exetest.c"); + + for (x=0;x<includes.length;x++) { + myInclude=myTranslationUnit.getInclude(includes[x]); + if (myInclude==null) + fail("Unable to get include: " + includes[x]); + else + assertTrue("PR:23478 Expected:"+includes[x] +" Got:"+ myInclude.getIncludeName(), includes[x].equals(myInclude.getIncludeName())); + } + + + } +*/ + /*** + * Simple sanity tests for the getIncludes call + */ +/* Reintroduce this test when Bug# 23478 is fixed + public void testGetIncludes() throws CModelException { + IInclude myIncludes[]; + String includes[]={"stdio.h", "unistd.h"}; + ExpectedStrings myExp= new ExpectedStrings(includes); + int x; + ITranslationUnit myTranslationUnit=CProjectHelper.findTranslationUnit(testProject,"exetest.c"); + fail("PR:23478 Unable to test because we can't get the name of an include file"); + + myIncludes=myTranslationUnit.getIncludes(); + for (x=0;x<myIncludes.length;x++) { + myExp.foundString(myIncludes[x].getIncludeName()); + } + assertTrue(myExp.getMissingString(), myExp.gotAll()); + assertTrue(myExp.getExtraString(), !myExp.gotExtra()); + } +*/ +} diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/WorkingCopyTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/WorkingCopyTests.java new file mode 100644 index 00000000000..0cd5d0a88a5 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/model/tests/WorkingCopyTests.java @@ -0,0 +1,125 @@ +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 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.IBuffer; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.ITranslationUnit; +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; + +/** + * Contains unit test cases for Working Copies. Run using JUnit Plugin Test + * configuration launcher. + */ +public class WorkingCopyTests extends TestCase { + private ICProject fCProject; + private IFile headerFile; + private NullProgressMonitor monitor; + + public static void main(String[] args) { + TestPluginLauncher.run(TestPluginLauncher.getLocationFromProperties(), WorkingCopyTests.class, args); + } + + public static Test suite() { + TestSuite suite= new TestSuite(WorkingCopyTests.class.getName()); + suite.addTest(new WorkingCopyTests("testWorkingCopy")); + //suite.addTest(new WorkingCopyTests("testHashing")); + return suite; + } + + public WorkingCopyTests(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); + } + + 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 testWorkingCopy() throws Exception { + ITranslationUnit tu = new TranslationUnit(fCProject, headerFile); + // CreateWorkingCopy + assertNotNull (tu); + IWorkingCopy wc = tu.getWorkingCopy(); + assertNotNull (wc); + assertNotNull (wc.getBuffer()); + assertTrue (wc.exists()); + + // ModifyWorkingCopy + IBuffer wcBuf = wc.getBuffer(); + wcBuf.append("\n class Hello{ int x; };"); + if (tu.getBuffer().getContents().equals(wc.getBuffer().getContents() ) ) + fail("Buffers should NOT be equal at this point!"); + + // ReconcileWorkingCopy + wc.reconcile(); + + // CommitWorkingCopy + wc.commit(true, monitor); + + if(!tu.getBuffer().getContents().equals(wc.getBuffer().getContents())) + fail("Buffers should be equal at this point!"); + + // DestroyWorkingCopy + wc.destroy(); + assertFalse(wc.exists()); + } +}
\ No newline at end of file diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/AutomatedFramework.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/AutomatedFramework.java new file mode 100644 index 00000000000..30dcd0c49d0 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/AutomatedFramework.java @@ -0,0 +1,190 @@ +/******************************************************************************* + * 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.FileOutputStream; +import java.io.FilenameFilter; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Properties; +import java.util.Set; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.parser.IParserCallback; +import org.eclipse.cdt.internal.core.parser.NullSourceElementRequestor; + +/** + * @author aniefer + * + * To change the template for this generated type comment go to + * Window>Preferences>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<char> { /* ... */ };"); + 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<char>" ); + assertEquals( declaration.getDeclarators().size(), 0 ); + assertEquals( classSpec.getDeclarations().size(), 0 ); + + } + + public void testTemplateInstantiation() throws Exception + { + TranslationUnit tu = parse( "template class Array<char>;"); + 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<char>"); + } + + 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 <stdio.h>\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<class A, typename B=C> 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 T, typename Tibor = junk, class, typename, int x, float y,template <class Y> class, template<class A> 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<int f() {\n" ); + fail( "We should not make it this far"); + } + catch( ParserException pe ) + { + } + catch( Exception e ) + { + fail( "We should have gotten a ParserException rather than" + e); + } + } + + public void testBug36432() throws Exception + { + Writer code = new StringWriter(); + code.write( "#define CMD_GET \"g\"\n" ); + code.write( "#define CMD_ACTION \"a\"\n" ); + code.write( "#define CMD_QUIT \"q\"\n" ); + code.write( "static const memevent_cmd_func memevent_cmd_funcs[sizeof memevent_cmds - 1] = {\n"); + code.write( "memevent_get,\n"); + code.write( "memevent_action,\n"); + code.write( "memevent_quit,\n"); + code.write( "};\n"); + TranslationUnit tu = parse( code.toString() ); + assertEquals( tu.getDeclarations().size(), 1 ); + } + + public void testBug36594() throws Exception + { + TranslationUnit tu = parse( "const int n = sizeof(A) / sizeof(B);"); + assertEquals( tu.getDeclarations().size(), 1 ); + } + + public void testArrayOfPointerToFunctions() throws Exception + { + TranslationUnit tu = parse( "unsigned char (*main_data)[MAD_BUFFER_MDLEN];"); + } + + public void testBug36600() throws Exception + { + TranslationUnit tu = parse( "enum mad_flow (*input_func)(void *, struct mad_stream *);"); + assertEquals( tu.getDeclarations().size(), 1 ); + SimpleDeclaration simple = (SimpleDeclaration)tu.getDeclarations().get(0); + ElaboratedTypeSpecifier elab = (ElaboratedTypeSpecifier)simple.getTypeSpecifier(); + assertEquals( elab.getClassKey(), ClassKey.t_enum ); + assertEquals( elab.getName().toString(), "mad_flow"); + assertEquals( simple.getDeclarators().size(), 1 ); + Declarator declarator = (Declarator)simple.getDeclarators().get(0); + assertNull( declarator.getName() ); + assertNotNull( declarator.getDeclarator() ); + + tu = parse( "enum mad_layer layer;"); + assertEquals( tu.getDeclarations().size(), 1); + SimpleDeclaration declaration = (SimpleDeclaration)tu.getDeclarations().get(0); + elab = (ElaboratedTypeSpecifier)declaration.getTypeSpecifier(); + assertEquals( elab.getClassKey(), ClassKey.t_enum); + assertEquals( elab.getName().toString(), "mad_layer"); + assertEquals( declaration.getDeclarators().size(), 1); + assertEquals( ((Declarator)declaration.getDeclarators().get(0)).getName().toString(), "layer" ); + + } + + public void testBug36247() throws Exception + { + Writer code = new StringWriter(); + code.write( "class A {\n" ); + code.write( "INLINE_DEF int f ();\n" ); + code.write( "INLINE_DEF A g ();" ); + code.write( "INLINE_DEF A * h ();" ); + code.write( "INLINE_DEF A & unlock( void );"); + code.write( "};" ); + TranslationUnit tu = parse(code.toString()); + assertEquals( tu.getDeclarations().size(),1 ); + SimpleDeclaration classDeclaration = (SimpleDeclaration)tu.getDeclarations().get(0); + assertEquals( classDeclaration.getDeclarators().size(), 0 ); + assertEquals( classDeclaration.getDeclSpecifier().getType(), DeclSpecifier.t_type ); + ClassSpecifier classSpec = (ClassSpecifier)classDeclaration.getTypeSpecifier(); + PointerOperator po =null; + int number = 4; + assertEquals( classSpec.getDeclarations().size(), number ); + for( int i = 0; i < number; ++i ) + { + SimpleDeclaration subDeclaration = (SimpleDeclaration)classSpec.getDeclarations().get(i); + assertEquals( subDeclaration.getDeclarators().size(), 1 ); + Declarator functionDeclarator = (Declarator)subDeclaration.getDeclarators().get(0); + assertNotNull( functionDeclarator.getParms()); + if( i == 3) + assertEquals( 1, functionDeclarator.getParms().getDeclarations().size() ); + else + assertEquals( 0, functionDeclarator.getParms().getDeclarations().size() ); + List pointerOperators = functionDeclarator.getPointerOperators(); + switch( i ) + { + case 0: + assertEquals( subDeclaration.getDeclSpecifier().getType(), DeclSpecifier.t_int ); + assertEquals( functionDeclarator.getName().toString(), "f" ); + assertEquals( pointerOperators.size(), 0 ); + break; + case 1: + assertEquals( subDeclaration.getDeclSpecifier().getType(), DeclSpecifier.t_type ); + assertEquals( subDeclaration.getDeclSpecifier().getTypeName(), "A"); + assertEquals( functionDeclarator.getName().toString(), "g" ); + assertEquals( pointerOperators.size(), 0 ); + break; + case 2: + assertEquals( subDeclaration.getDeclSpecifier().getType(), DeclSpecifier.t_type ); + assertEquals( subDeclaration.getDeclSpecifier().getTypeName(), "A"); + assertEquals( functionDeclarator.getName().toString(), "h" ); + assertEquals( pointerOperators.size(), 1 ); + po = (PointerOperator)pointerOperators.get(0); + assertFalse( po.isConst() ); + assertFalse( po.isVolatile() ); + assertEquals( po.getType(), PointerOperator.t_pointer ); + break; + case 3: + assertEquals( subDeclaration.getDeclSpecifier().getType(), DeclSpecifier.t_type ); + assertEquals( subDeclaration.getDeclSpecifier().getTypeName(), "A"); + assertEquals( functionDeclarator.getName().toString(), "unlock" ); + assertEquals( pointerOperators.size(), 1 ); + po = (PointerOperator)pointerOperators.get(0); + assertFalse( po.isConst() ); + assertFalse( po.isVolatile() ); + assertEquals( po.getType(), PointerOperator.t_reference ); + default: + break; + } + + } + + } + + + public void testBug36559() throws Exception + { + Writer code = new StringWriter(); + code.write( "namespace myNameSpace {\n" ); + code.write( "template<typename T=short> class B {};\n" ); + code.write( "template<> class B<int> {};\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<int>" ); + 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 <typename T, typename Destroyer>\n"); + code.write("void SetLongevity(T* pDynObject, unsigned int longevity,\n"); + code.write("Destroyer d = Private::Deleter<T>::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<T>::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, class> 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<TList>::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 <typename P1> RefCounted(const RefCounted<P1>& rhs)\n"); + code.write( + ": pCount_(reinterpret_cast<const RefCounted&>(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<void> {};"); + 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 <typename Fun> Functor(Fun fun) : spImpl_(new FunctorHandler<Functor, Fun>(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 <class T, class U>\n" ); + code.write( "struct Length< Typelist<T, U> >\n" ); + code.write( "{\n" ); + code.write( "enum { value = 1 + Length<U>::value };\n" ); + code.write( "};\n" ); + parse(code.toString()); + } + + public void testBug36699() throws Exception { + Writer code = new StringWriter(); + code.write( + "template < template <class> 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<ThreadingModel, chunkSize, maxSmallObjectSize> >\n"); + code.write("{};\n"); + parse(code.toString()); + } + + public void testBug36691() throws Exception { + Writer code = new StringWriter(); + code.write("template <class T, class H>\n"); + code.write( + "typename H::template Rebind<T>::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 <string.h>\n" ); + code.write( "template <class _Tp>\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 <class _CharT, class _Alloc>\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<class _CharT>\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 <class _CharT, class _Alloc>\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 <class _CharT, class _Alloc>\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 <class A, B> cls<A, C>::operator op &() const {}\n"); + code.write("template <class A, B> cls<A, C>::cls() {}\n"); + code.write("template <class A, B> cls<A, C>::~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 A,B> class X<A,C> { operator int(); } \n"); + parse("template <class A,B> class X<A,C> { operator int*(); } \n"); + parse("template <class A,B> class X<A,C> { operator int&(); } \n"); + parse("template <class A,B> class X<A,C> { operator A(); } \n"); + parse("template <class A,B> class X<A,C> { operator A*(); } \n"); + parse("template <class A,B> class X<A,C> { operator A&(); } \n"); + + parse("template <class A,B> X<A,C>::operator int() { } \n"); + parse("template <class A,B> X<A,C>::operator int*() { } \n"); + parse("template <class A,B> X<A,C>::operator int&() { } \n"); + parse("template <class A,B> X<A,C>::operator A() { } \n"); + parse("template <class A,B> X<A,C>::operator A*() { } \n"); + parse("template <class A,B> X<A,C>::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 <class B,C> A<B>::nested::nested(){}; "); + parse("template <class B,C> int A::nested<B,D>::foo() {} "); + parse("template <class B,C> int A<B,C>::nested<C,B>::operator+() {} "); + parse("template <class B,C> 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<B> 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> b ) { ... } + * void f( int i ) {} + * + * A<B> a; + * f( a ); //calls f( A<B> ) + * + */ + 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 <int, int, 1> a1; //uses #1 + * A <int, int*, 1> a2; //uses #2, T is int, I is 1 + * A <int, char*, 5> a3; //uses #4, T is char + * A <int, char*, 1> a4; //uses #5, T is int, T2 is char, I is1 + * A <int*, int*, 2> 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 <stdio.h>"); + 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 <Windows.h>"); + prepareForWindowsH(); + int count= fullyTokenize(); + if (verbose) + System.out.println( + "For Windows.h, Scanner produced " + + scanner.getCount() + + " tokens"); + validateBalance(); + } + + if (doIncludeWinUserH) + { + initializeScanner("#include <WinUser.rh>"); + 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 <foo.h" ); + try{ + validateEOF(); + } catch ( ScannerException e ){ + assertTrue( e.getMessage().equals( "Ill-formed #include: reached end of line before >" )); + } + 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 @@ +<?xml version="1.0" encoding="UTF-8"?> +<plugin + id="org.eclipse.cdt.core.tests" + name="org.eclipse.cdt.core.tests" + version="1.2.0.5" + class="org.eclipse.cdt.testplugin.CTestPlugin"> + + <runtime> + <library name="cdtcoretests.jar"> + <export name="*"/> + </library> + </runtime> + <requires> + <import plugin="org.apache.xerces"/> + <import plugin="org.eclipse.core.resources"/> + <import plugin="org.eclipse.core.runtime"/> + <import plugin="org.eclipse.cdt.core"/> + <import plugin="org.eclipse.cdt.ui"/> + <import plugin="org.eclipse.swt"/> + <import plugin="org.eclipse.ui"/> + <import plugin="org.junit"/> + </requires> + + + <extension + id="buildTest" + name="Tools for Build Test" + point="org.eclipse.cdt.core.ManagedBuildInfo"> + <target + isTest="true" + name="Test Root" + defaultExtension="toor" + isAbstract="false" + id="test.root"> + <tool + sources="foo,bar" + name="Root Tool" + outputs="toor" + command="doIt" + id="root.tool"> + <optionCategory + owner="root.tool" + name="Category" + id="category"> + </optionCategory> + <option + name="List Option in Top" + command="-L" + valueType="stringList" + id="list.option"> + <optionValue + value="a"> + </optionValue> + <optionValue + value="b"> + </optionValue> + </option> + <option + defaultValue="false" + name="Boolean Option in Top" + command="-b" + valueType="boolean" + id="boolean.option"> + </option> + <option + defaultValue="x" + name="String Option in Category" + category="category" + valueType="string" + id="string.option"> + </option> + <option + name="Enumerated Option in Category" + category="category" + valueType="enumerated" + id="enumerated.option"> + <optionEnum + name="Default Enum" + isDefault="true" + command="-e1" + id="default.enum.option"> + </optionEnum> + <optionEnum + name="Another Enum" + command="-e2" + id="another.enum.option"> + </optionEnum> + </option> + </tool> + <configuration + name="Root Config" + id="root.config"> + </configuration> + <configuration + name="Root Override Config" + id="root.override.config"> + <toolRef + id="root.tool"> + <optionRef + defaultValue="y" + id="string.option"> + </optionRef> + <optionRef + defaultValue="true" + id="boolean.option"> + </optionRef> + </toolRef> + </configuration> + </target> + <target + isTest="true" + name="Test Sub" + parent="test.root" + defaultExtension="bus" + isAbstract="false" + id="test.sub"> + <configuration + name="Sub Config" + id="sub.config"> + </configuration> + <tool + name="Sub Tool" + id="tool.sub"> + </tool> + </target> + </extension> + +</plugin> 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 <stdio.h>
+
+// 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<class A, typename B=C>
+ A aTemplatedFunction( B bInstance );
+ // template method
+ class enclosing {
+ // public visibility
+ public:
+ template<class A, typename B=C>
+ A aTemplatedMethod( B bInstance );
+ };
+ // template class
+ template<class T, typename Tibor = junk>
+ class myarray { /* */ };
+ // template struct
+ template<class T, typename Tibor = junk>
+ struct mystruct { /* */ };
+ // template variable
+ template <bool __threads, int __inst>
+ 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 <stdio.h>
+#include <unistd.h>
+
+/* 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 <stdio.h> + 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 <stdio.h>
+#include "whatever.h"
+#include <src/slash.h>
+#include <src\backslash.h>
+#include "Program Files/space.h"
+#include "../up1dir.h"
+#include "./samedir.h"
+#include "different_extension1.hpp"
+#include "different_extension2.hh"
+#include "different_extension3.x"
+#include <no_extension>
+# 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<T> class nonVector {
+ public:
+ int x;
+ int y;
+
+ T* head;
+ vector<T>() { 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 <stdio.h> + +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 Binary files differnew file mode 100644 index 00000000000..1c54db11d20 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/ppc/be.g/exe_g 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 Binary files differnew file mode 100644 index 00000000000..41e9e97110e --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/ppc/be.g/main.o 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 Binary files differnew file mode 100644 index 00000000000..9a35dfb2cf9 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/ppc/be.g/test.o 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 Binary files differnew file mode 100644 index 00000000000..bae3191b475 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/ppc/be.g/test2.o 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 <stdio.h> + + +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 <stdio.h> + +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 Binary files differnew file mode 100644 index 00000000000..465e16de33d --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o.g/exe_g 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 Binary files differnew file mode 100644 index 00000000000..8c61c21f50d --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o.g/main.o 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 Binary files differnew file mode 100644 index 00000000000..5f956885cbf --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o.g/test.o 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 Binary files differnew file mode 100644 index 00000000000..aa8de348603 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o.g/test2.o 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 Binary files differnew file mode 100644 index 00000000000..d13631162d7 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o/exe 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 Binary files differnew file mode 100644 index 00000000000..a5c78c1ca4e --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o/main.o 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 Binary files differnew file mode 100644 index 00000000000..357c3985ea1 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o/test.o 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 Binary files differnew file mode 100644 index 00000000000..52e88a7397b --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exe/x86/o/test2.o 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 <stdio.h> +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 Binary files differnew file mode 100644 index 00000000000..3aacf6267c5 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exebig/x86/o.g/exebig_g 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 Binary files differnew file mode 100644 index 00000000000..e7d818de524 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/exebig/x86/o.g/main.o 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 = <path for report> +# source = <path to top of project>, <c or cpp> +# 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 = <path for report> +# source = <path to top of project>, <c or cpp> +# 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 <Simple.h>
+
+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 <Simple.h>
+
+#include <iostream>
+
+#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 <stdio.h>
+
+// 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 <class A >
+ 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 <stdio.h> + + +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 <stdio.h> + +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 Binary files differnew file mode 100644 index 00000000000..a12942b1527 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/testlib/x86/a.g/test.o 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 Binary files differnew file mode 100644 index 00000000000..87e730cd7c5 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/testlib/x86/a.g/test2.o 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 Binary files differnew file mode 100644 index 00000000000..c9009cb22dc --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/testlib/x86/so.g/test.o 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 Binary files differnew file mode 100644 index 00000000000..a13bcd826b8 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/resources/testlib/x86/so.g/test2.o 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<myArchives.length;x++) { + if (myArchives[x].getElementName().equals(name)) + return(myArchives[x]); + + } + return(null); + } + /** + * Attempts to find a binary with the given name in the workspace + */ + public static IBinary findBinary(ICProject testProject,String name) { + IBinaryContainer binCont; + int x; + IBinary[] myBinaries; + binCont=testProject.getBinaryContainer(); + + myBinaries=binCont.getBinaries(); + if (myBinaries.length<1) + return(null); + for (x=0;x<myBinaries.length;x++) { + if (myBinaries[x].getElementName().equals(name)) + return(myBinaries[x]); + + + } + return(null); + } + + /** + * Attempts to find an object with the given name in the workspace + */ + public static IBinary findObject(ICProject testProject,String name) { + int x; + ICElement[] myElements; + myElements=testProject.getChildren(); + if (myElements.length<1) + return(null); + for (x=0;x<myElements.length;x++) { + if (myElements[x].getElementName().equals(name)) + if (myElements[x] instanceof ICElement) { + if (myElements[x] instanceof IBinary) { + return((IBinary) myElements[x]); + } + } + } + return(null); + } + /** + * Attempts to find a TranslationUnit with the given name in the workspace + */ + public static ITranslationUnit findTranslationUnit(ICProject testProject,String name) { + int x; + ICElement[] myElements; + myElements=testProject.getChildren(); + if (myElements.length<1) + return(null); + for (x=0;x<myElements.length;x++) { + if (myElements[x].getElementName().equals(name)) + if (myElements[x] instanceof ICElement) { + if (myElements[x] instanceof ITranslationUnit) { + return((ITranslationUnit) myElements[x]); + } + } + } + return(null); + } + + + + /** + * Attempts to find an element with the given name in the workspace + */ + public static ICElement findElement(ICProject testProject,String name) { + int x; + ICElement[] myElements; + myElements=testProject.getChildren(); + if (myElements.length<1) + return(null); + for (x=0;x<myElements.length;x++) { + if (myElements[x].getElementName().equals(name)) + if (myElements[x] instanceof ICElement) { + return((ICElement) myElements[x]); + } + + + } + return(null); + } + + 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); + } + + private static void importFilesFromZip(ZipFile srcZipFile, IPath destPath, IProgressMonitor monitor) throws InvocationTargetException { + ZipFileStructureProvider structureProvider= new ZipFileStructureProvider(srcZipFile); + try { + ImportOperation op= new ImportOperation(destPath, structureProvider.getRoot(), structureProvider, new ImportOverwriteQuery()); + op.run(monitor); + } catch (InterruptedException e) { + // should not happen + } + } + + private static class ImportOverwriteQuery implements IOverwriteQuery { + public String queryOverwrite(String file) { + return ALL; + } + } + + +} + diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/CTestPlugin.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/CTestPlugin.java new file mode 100644 index 00000000000..98b399254c8 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/CTestPlugin.java @@ -0,0 +1,58 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package org.eclipse.cdt.testplugin; + +import java.io.File; +import java.io.IOException; +import java.net.URL; + +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceDescription; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IPluginDescriptor; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Plugin; + + +public class CTestPlugin extends Plugin { + + private static CTestPlugin fgDefault; + + public CTestPlugin(IPluginDescriptor descriptor) { + super(descriptor); + fgDefault= this; + } + + public static CTestPlugin getDefault() { + return fgDefault; + } + + public static IWorkspace getWorkspace() { + return ResourcesPlugin.getWorkspace(); + } + + public static void enableAutobuild(boolean enable) throws CoreException { + // disable auto build + IWorkspace workspace= CTestPlugin.getWorkspace(); + IWorkspaceDescription desc= workspace.getDescription(); + desc.setAutoBuilding(enable); + workspace.setDescription(desc); + } + + public File getFileInPlugin(IPath path) { + try { + URL installURL= new URL(getDescriptor().getInstallURL(), path.toString()); + URL localURL= Platform.asLocalURL(installURL); + return new File(localURL.getFile()); + } catch (IOException e) { + return null; + } + } + + + +}
\ No newline at end of file diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/CTestSetup.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/CTestSetup.java new file mode 100644 index 00000000000..2843c2703b7 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/CTestSetup.java @@ -0,0 +1,31 @@ +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ +package org.eclipse.cdt.testplugin; + +import junit.extensions.TestSetup; +import junit.framework.Test; + + + +public class CTestSetup extends TestSetup { + + /** + * @deprecated + * Not needed anymore. No added value + */ + public CTestSetup(Test test) { + super(test); + } + + protected void setUp() throws Exception { + } + + protected void tearDown() throws Exception { + } + + + + +}
\ No newline at end of file diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/Main.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/Main.java new file mode 100644 index 00000000000..a6d6af47ca0 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/Main.java @@ -0,0 +1,528 @@ +package org.eclipse.cdt.testplugin; + +// copied from startup.jar. planned to be removed soon + + +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ + +import java.net.*; +import java.lang.reflect.*; +import java.io.*; +import java.util.*; +/** + * Startup class for Eclipse. Creates a class loader using + * supplied URL of platform installation, loads and calls + * the Eclipse Boot Loader. The startup arguments are as follows: + * <dl> + * <dd> + * -application <id>: the identifier of the application to run + * </dd> + * <dd> + * -boot <location>: the location, expressed as a URL, of the platform's boot.jar + * </dd> + * <dd> + * -consolelog : enables log to the console. Handy when combined with -debug + * </dd> + * <dd> + * -data <location>: sets the workspace location and the default location for projects + * </dd> + * <dd> + * -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 + * </dd> + * <dd> + * -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 + * </dd> + * <dd> + * -keyring <location>: the location of the authorization database on disk. This argument + * has to be used together with the -password argument + * </dd> + * <dd> + * -password <passwd>: the password for the authorization database + * </dd> + * <dd> + * -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). + * </dd> + * <dd> + * -ws <window system>: sets the window system value + * </dd> + * </dl> + */ +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 <code>BootLoader</code> which can be used to start + * up and run the platform. The given base, if not <code>null</code>, + * is the location of the boot loader code. If the value is <code>null</code> + * 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 <code>URL</code>-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 <code>URL</code>-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., <code>-application com.example.application</code>). + * After running the application <code>System.exit(N)</code> is executed. + * The value of N is derived from the value returned from running the application. + * If the application's return value is an <code>Integer</code>, N is this value. + * In all other cases, N = 0. + * <p> + * Clients wishing to run the platform without a following <code>System.exit</code> + * call should use <code>run()</code>. + * + * @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 <code>DialogCheck</code> is used test a dialog in + * various ways. + * <p> + * For interactive tests use <code>assertDialog</code>. + * For automated tests use <code>assert DialogTexts</code>. + * </p> + */ +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: + * <code>Dialog dialog = new AboutDialog( DialogCheck.getShell() ); + * DialogCheck.assertDialog(dialog, this);</code> + * + * @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<values.length;x++) { + expStrings[x]=new String(values[x]); + } + foundStrings=new boolean[values.length]; + for (x=0;x<values.length;x++) { + foundStrings[x]=false; + } + extraStrings=new Stack(); + extra=false; + } + + public int foundString(String current) { + int x; + for (x=0;x<expStrings.length;x++) { + if (current.equals(expStrings[x])) { + foundStrings[x]=true; + return(0); + } + } + /* If we arrive here, the strings was not found, so this is + * and extra string + */ + + extraStrings.push(new String(current)); + extra=true; + return(1); + } + public int getNum(String name) { + int x; + for (x=0;x<expStrings.length;x++) { + if (name.equals(expStrings[x])) + return(x); + } + return(-1); + } + public boolean gotAll() { + int x; + for (x=0;x<expStrings.length;x++) { + if (foundStrings[x]==false) + return(false); + } + return(true); + } + public boolean gotExtra() { + return(extra); + } + public String getMissingString() { + int x; + String missing = new String("Missing elements: "); + for (x=0;x<expStrings.length;x++) { + if (foundStrings[x]==false) + missing+=expStrings[x]; + missing+=" "; + } + return(missing); + } + public String getExtraString() { + String extra= new String("Extra elements: "); + while (!extraStrings.empty()) { + extra+=extraStrings.pop(); + extra+=" "; + } + return(extra); + } +} diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/ExpectedStringsTests.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/ExpectedStringsTests.java new file mode 100644 index 00000000000..30d67776b34 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/ExpectedStringsTests.java @@ -0,0 +1,114 @@ +package org.eclipse.cdt.testplugin.util; + +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * @author Peter Graves + * + *Some simple tests to make sure our ExtraStrings class seems to work. + */ +public class ExpectedStringsTests extends TestCase { + + /** + * Constructor for ExpectedStringsTests. + * @param name + */ + public ExpectedStringsTests(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() { + + + } + + /** + * 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(ExpectedStringsTests.class); + } + + public static void main (String[] args){ + junit.textui.TestRunner.run(suite()); + } + + public void testGotAll() { + ExpectedStrings myExp; + String[] strings= {"stringOne", "stringTwo", "stringThree" }; + + myExp=new ExpectedStrings(strings); + assertTrue("No found strings", !myExp.gotAll()); + myExp.foundString("stringOne"); + assertTrue("1 found strings", !myExp.gotAll()); + myExp.foundString("stringTwo"); + assertTrue("2 found strings", !myExp.gotAll()); + myExp.foundString("stringThree"); + assertTrue("All found strings", myExp.gotAll()); + + + } + public void testGotExtra () { + ExpectedStrings myExp; + String[] strings= {"stringOne", "stringTwo", "stringThree" }; + + myExp=new ExpectedStrings(strings); + assertTrue("No found strings", !myExp.gotExtra()); + myExp.foundString("stringOne"); + assertTrue("1 found strings", !myExp.gotExtra()); + myExp.foundString("stringTwo"); + assertTrue("2 found strings", !myExp.gotExtra()); + myExp.foundString("stringThree"); + assertTrue("All found strings", !myExp.gotExtra()); + myExp.foundString("Somerandomestring"); + assertTrue("Extra String", myExp.gotExtra()); + + } + + public void testGetMissingString() + { + ExpectedStrings myExp; + String[] strings= {"stringOne", "stringTwo", "stringThree" }; + + myExp=new ExpectedStrings(strings); + assertNotNull(myExp.getMissingString()); + myExp.foundString("stringOne"); + assertNotNull(myExp.getMissingString()); + myExp.foundString("stringTwo"); + assertNotNull(myExp.getMissingString()); + myExp.foundString("stringThree"); + assertNotNull(myExp.getMissingString()); + + } + + public void testGetExtraString() + { + ExpectedStrings myExp; + String[] strings= {"stringOne", "stringTwo", "stringThree" }; + + myExp=new ExpectedStrings(strings); + assertNotNull(myExp.getExtraString()); + myExp.foundString("stringOnenot"); + assertNotNull(myExp.getMissingString()); + myExp.foundString("stringTwonot"); + assertNotNull(myExp.getMissingString()); + + } + + + +} diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/FailureDialog.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/FailureDialog.java new file mode 100644 index 00000000000..dbe98db5652 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/FailureDialog.java @@ -0,0 +1,107 @@ +package org.eclipse.cdt.testplugin.util; + + +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +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.swt.widgets.Text; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.resource.JFaceResources; + + +/* + * A dialog for collecting notes from the tester regarding + * the failure of a test. + */ +public class FailureDialog extends Dialog { + private Text _text; + private String _log; + private int SIZING_TEXT_WIDTH = 400; + private int SIZING_TEXT_HEIGHT = 200; + + /** + * Constructor for FailureDialog + */ + public FailureDialog(Shell parentShell) { + super(parentShell); + } + /* (non-Javadoc) + * Method declared on Window. + */ + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText("Dialog Test Failed"); + } + /* (non-Javadoc) + * Method declared on Dialog. + */ + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.OK_ID, "&OK", true); + createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); + } + /* (non-Javadoc) + * Method declared on Dialog. + */ + protected Control createDialogArea(Composite parent) { + // page group + Composite composite = (Composite)super.createDialogArea(parent); + composite.setSize( composite.computeSize(SWT.DEFAULT, SWT.DEFAULT) ); + + Label label = new Label(composite, SWT.WRAP); + label.setText("&Enter a note regarding the failure:"); + + _text = new Text(composite, SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL); + _text.setFont( JFaceResources.getFontRegistry().get(JFaceResources.TEXT_FONT) ); + GridData data = new GridData(GridData.FILL_BOTH); + data.widthHint = SIZING_TEXT_WIDTH; + data.heightHint = SIZING_TEXT_HEIGHT; + _text.setLayoutData(data); + + return composite; + } + /* (non-Javadoc) + * Method declared on Dialog. + */ + protected void okPressed() { + _log = _text.getText(); + super.okPressed(); + } + /* + * @return String the text contained in the input area of + * the dialog. + */ + String getText() { + if (_log == null) { + return "Empty entry."; + } else { + return _log; + } + } + /* + * Sets the text of the input area. This should only be + * called to set the initial text so only call before invoking + * open(). + */ + void setText(String text) { + _text.setText(text); + } + /* + * Returns a string representation of this class which + * the text contained in the input area of the dialog. + */ + public String toString() { + return getText(); + } +} + + diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/FocusTestPass.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/FocusTestPass.java new file mode 100644 index 00000000000..0f83e03c1c2 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/FocusTestPass.java @@ -0,0 +1,68 @@ +package org.eclipse.cdt.testplugin.util; + + +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ + +import java.util.ArrayList; + + +/* + * This test pass verifies the initial focus of a dialog + * when it is given focus. + */ +public class FocusTestPass implements IDialogTestPass { + private static final int CHECKLIST_SIZE = 1; + + + /** + * @see IDialogTestPass#title() + */ + public String title() { + return "Test Pass: Initial Focus"; + } + /** + * @see IDialogTestPass#description() + */ + public String description() { + return "Verify the initial focus of the dialogs."; + } + /** + * @see IDialogTestPass#label() + */ + public String label() { + return "&Initial Focus"; + } + /** + * @see IDialogTestPass#checkListTexts() + */ + public ArrayList checkListTexts() { + ArrayList list = new ArrayList(CHECKLIST_SIZE); + list.add("&1) the initial focus is appropriate."); + 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] = "The initial focus is inappropriate."; + return failureText; + } + /** + * @see IDialogTestPass#queryText() + */ + public String queryText() { + return "Is the initial focus of the dialog correct?"; + } + /** + * @see IDialogTestPass#getID() + */ + public int getID() { + return VerifyDialog.TEST_FOCUS; + } +}
\ No newline at end of file diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/IDialogTestPass.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/IDialogTestPass.java new file mode 100644 index 00000000000..be34fbadf8c --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/IDialogTestPass.java @@ -0,0 +1,48 @@ +package org.eclipse.cdt.testplugin.util; + + +import java.util.ArrayList; + + +/* + * Interface to describe a visual test pass for a dialog test. + */ +public interface IDialogTestPass { + /* + * @return String The title of the test pass. + */ + public String title(); + /* + * @return String The description of the test pass. + */ + public String description(); + /* + * @return String The label of the test pass to be used + * in a selection list. The return includes an '&' + * if a mnemonic is desired. + */ + public String label(); + /* + * @return ArrayList A list of items to appear in a checklist. + * The items in the list must be Strings and should include an + * '&' if a mnemonic is desired. + */ + public ArrayList checkListTexts(); + /* + * @return String[] Associated failure messages that correspond + * to the checklist items. The size of this array should be the + * same size as the checklist. + */ + public String[] failureTexts(); + /* + * @return String The test that corresponds to the test pass to + * which the tester will respond with a 'yes' or 'no'. + */ + public String queryText(); + /* + * @return int A unique number that identifies the test pass. + */ + public int getID(); +} + + diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/SizingTestPass.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/SizingTestPass.java new file mode 100644 index 00000000000..dc471637e66 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/SizingTestPass.java @@ -0,0 +1,76 @@ +package org.eclipse.cdt.testplugin.util; + + +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ + +import java.util.ArrayList; + + +/* + * This test pass verifies visually the sizing of the dialog and its + * widgets. + */ +class SizingTestPass implements IDialogTestPass { + private static final int CHECKLIST_SIZE = 5; + + + /** + * @see IDialogTestPass#title() + */ + public String title() { + return "Test Pass: Sizing and Display"; + } + /** + * @see IDialogTestPass#description() + */ + public String description() { + return "Verify the sizing and display of the dialogs and widgets."; + } + /** + * @see IDialogTestPass#label() + */ + public String label() { + return "&Sizing and Display"; + } + /** + * @see IDialogTestPass#checkListTexts() + */ + public ArrayList checkListTexts() { + ArrayList list = new ArrayList(CHECKLIST_SIZE); + list.add("&1) the correct dialog displays."); + list.add("&2) the dialog is an appropriate size for the required resolution (1024x768)."); + list.add("&3) the texts are correct and not cut off."); + list.add("&4) all strings have been externalized properly."); + list.add("&5) all the widgets are viewable and not cut off."); + 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] = "The wrong dialog displayed."; + failureText[1] = "The dialog is too large for the required resolution."; + failureText[2] = "Text labels are wrong or cut off."; + failureText[3] = "Some strings have not been externalized properly."; + failureText[4] = "Some widgets are cut off."; + return failureText; + } + /** + * @see IDialogTestPass#queryText() + */ + public String queryText() { + return "Is the sizing and display of the dialog correct?"; + } + /** + * @see IDialogTestPass#getID() + */ + public int getID() { + return VerifyDialog.TEST_SIZING; + } +}
\ No newline at end of file diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/VerifyDialog.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/VerifyDialog.java new file mode 100644 index 00000000000..2f8abd10143 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/testplugin/util/VerifyDialog.java @@ -0,0 +1,305 @@ +package org.eclipse.cdt.testplugin.util; + + +import java.util.Iterator; + + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.TitleAreaDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.ShellAdapter; +import org.eclipse.swt.events.ShellEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; + + +/* + * This dialog is intended to verify a dialogs in a testing + * environment. The tester can test for sizing, initial focus, + * or accessibility. + */ +public class VerifyDialog extends TitleAreaDialog { + private int SIZING_WIDTH = 400; + + static int TEST_TYPE; + public static final int TEST_SIZING = 0; + public static final int TEST_FOCUS = 1; + public static final int TEST_ACCESS = 2; + private IDialogTestPass _dialogTests[] = new IDialogTestPass[3]; + + + private Dialog _testDialog; //the dialog to test + private Point _testDialogSize; + + private Label _queryLabel; + Button _yesButton; + private Button _noButton; + private Button _checkList[]; + private String _failureText; + + /* + * Create an instance of the verification dialog. + */ + public VerifyDialog(Shell parent) { + super(parent); + if ( !(TEST_TYPE <= 2) && !(TEST_TYPE >= 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 @@ +<?xml version="1.0"?> + +<project name="testsuite" default="run" basedir="."> + <!-- The property ${eclipse-home} should be passed into this script --> + <!-- Set a meaningful default value for when it is not. --> + <property name="eclipse-home" value="${basedir}"/> + + <!-- This is the default name of the org.eclipse.test plugin. --> + <!-- We need to be able to override this for the case where the --> + <!-- org.eclipse.test plugin was build as part of a feature and --> + <!-- will have a name similar to org.eclipse.test_2.1.0 --> + <property name="org.eclipse.test" value="org.eclipse.test"/> + <!-- sets the properties eclipse-home, and library-file --> + <property name="plugin-name" value="org.eclipse.cdt.core.tests"/> + <property name="library-file" + value="${eclipse-home}/plugins/${org.eclipse.test}/library.xml"/> + + <!-- This target holds all initialization code that needs to be done for --> + <!-- all tests that are to be run. Initialization for individual tests --> + <!-- should be done within the body of the suite target. --> + <target name="init"> + <tstamp/> + <delete> + <fileset dir="${eclipse-home}" includes="org*.xml"/> + </delete> + </target> + + <!-- This target defines the tests that need to be run. --> + <target name="suite"> + <property name="cdt-folder" + value="${eclipse-home}/cdt_folder"/> + <delete dir="${cdt-folder}" quiet="true"/> + <ant target="core-test" antfile="${library-file}" dir="${eclipse-home}"> + <property name="data-dir" value="${cdt-folder}"/> + <property name="plugin-name" value="${plugin-name}"/> + <property name="classname" + value="org.eclipse.cdt.core.model.tests.AllCoreTests"/> + </ant> + </target> + + <!-- This target holds code to cleanup the testing environment after --> + <!-- after all of the tests have been run. You can use this target to --> + <!-- delete temporary files that have been created. --> + <target name="cleanup"> + </target> + + <!-- This target runs the test suite. Any actions that need to happen --> + <!-- after all the tests have been run should go here. --> + <target name="run" depends="init,suite,cleanup"> + <ant target="collect" antfile="${library-file}" dir="${eclipse-home}"> + <property name="includes" value="org*.xml"/> + <property name="output-file" value="${plugin-name}.xml"/> + </ant> + </target> + +</project> |